Add polymer 1.0 to npm_modules
BUG=
R=jrobbins@google.com
Review URL: https://codereview.chromium.org/1205703007.
diff --git a/polymer_1.0.4/bower.json b/polymer_1.0.4/bower.json
new file mode 100644
index 0000000..1294da4
--- /dev/null
+++ b/polymer_1.0.4/bower.json
@@ -0,0 +1,13 @@
+{
+ "name": "chrome-infra",
+ "dependencies": {
+ "iron-elements": "PolymerElements/iron-elements#~1.0.1",
+ "paper-elements": "PolymerElements/paper-elements#~1.0.1",
+ "gold-elements": "PolymerElements/gold-elements#~1.0.1",
+ "platinum-elements": "PolymerElements/platinum-elements#~1.0.1",
+ "neon-elements": "PolymerElements/neon-elements#~1.0.0",
+ "google-web-components": "GoogleWebComponents/google-web-components#~1.0.1",
+ "polymer": "Polymer/polymer#~1.0.4",
+ "app-router": "~2.6.1"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/app-router/.bower.json b/polymer_1.0.4/bower_components/app-router/.bower.json
new file mode 100644
index 0000000..b826f4c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/app-router/.bower.json
@@ -0,0 +1,42 @@
+{
+ "name": "app-router",
+ "version": "2.6.1",
+ "authors": [
+ "Erik Ringsmuth <erik.ringsmuth@gmail.com>"
+ ],
+ "description": "Router for Web Components.",
+ "keywords": [
+ "web-components",
+ "router",
+ "polymer",
+ "x-tag"
+ ],
+ "main": "app-router.html",
+ "license": "MIT",
+ "homepage": "https://github.com/erikringsmuth/app-router",
+ "ignore": [
+ "**/.*",
+ "bower_components",
+ "node_modules",
+ "tests",
+ "tmp",
+ "gulpfile.js",
+ "package.json"
+ ],
+ "devDependencies": {
+ "polymer": "~0.5.4",
+ "webcomponentsjs": "~0.5.4",
+ "core-elements": "Polymer/core-elements#~0.5.4",
+ "pushstate-anchor": "~0.3.0"
+ },
+ "_release": "2.6.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v2.6.1",
+ "commit": "c01f7757fddb11523e4273b77ce63a071feb01fd"
+ },
+ "_source": "git://github.com/erikringsmuth/app-router.git",
+ "_target": "~2.6.1",
+ "_originalSource": "app-router",
+ "_direct": true
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/app-router/LICENSE.md b/polymer_1.0.4/bower_components/app-router/LICENSE.md
new file mode 100644
index 0000000..773d537
--- /dev/null
+++ b/polymer_1.0.4/bower_components/app-router/LICENSE.md
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Erik Ringsmuth
+
+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.
diff --git a/polymer_1.0.4/bower_components/app-router/README.md b/polymer_1.0.4/bower_components/app-router/README.md
new file mode 100644
index 0000000..a6eead7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/app-router/README.md
@@ -0,0 +1,217 @@
+## Router for Web Components
+> Works with [Polymer](https://www.polymer-project.org/), [X-Tag](http://www.x-tags.org/), and natively.
+>
+> [erikringsmuth.github.io/app-router](https://erikringsmuth.github.io/app-router/)
+
+Manage page state. Lazy-load content. Data-bind path variables and query parameters. Use multiple layouts. Navigate with `hashchange` and HTML5 `pushState`. Animate transitions using `core-animated-pages`.
+
+[Download](https://github.com/erikringsmuth/app-router/archive/master.zip) or run `bower install app-router --save`.
+
+## Configuration
+
+Define how URLs map to pages.
+
+```html
+<!doctype html>
+<html>
+ <head>
+ <title>App Router</title>
+ <link rel="import" href="/bower_components/app-router/app-router.html">
+ </head>
+ <body>
+ <app-router>
+ <!-- matches an exact path -->
+ <app-route path="/home" import="/pages/home-page.html"></app-route>
+
+ <!-- matches using a wildcard -->
+ <app-route path="/customer/*" import="/pages/customer-page.html"></app-route>
+
+ <!-- matches using a path variable -->
+ <app-route path="/order/:id" import="/pages/order-page.html"></app-route>
+
+ <!-- matches a pattern like '/word/number' -->
+ <app-route path="/^\/\w+\/\d+$/i" regex import="/pages/regex-page.html"></app-route>
+
+ <!-- matches everything else -->
+ <app-route path="*" import="/pages/not-found-page.html"></app-route>
+ </app-router>
+ </body>
+</html>
+```
+
+## Navigation
+
+Click links or call `router.go()`.
+
+```html
+<!-- hashchange -->
+<a href="#/home">Home</a>
+
+<!-- pushState() -->
+<a is="pushstate-anchor" href="/home">Home</a>
+
+<!-- router.go(path, options) -->
+<script>
+ document.querySelector('app-router').go('/home');
+</script>
+```
+
+The router listens to `popstate` and `hashchange` events. Changing the URL will find the first `app-route` that matches, load the element or template, and replace the current view.
+
+#### hashchange
+Clicking `<a href="#/home">Home</a>` will fire a `hashchange` event and tell the router to load the first route that matches `/home`. You don't need to handle the event in your Javascript. Hash paths `#/home` match routes without the hash `<app-route path="/home">`.
+
+#### pushState
+You can use the [pushstate-anchor](https://github.com/erikringsmuth/pushstate-anchor) or [html5-history-anchor](https://github.com/erikringsmuth/html5-history-anchor) to extend `<a>` tags with the HTML5 history API.
+
+```html
+<a is="pushstate-anchor" href="/home">Home</a>
+```
+
+This will call `pushState()` and dispatch a `popstate` event.
+
+#### go(path, options)
+You can call the router from Javascript to navigate imperatively.
+
+```js
+document.querySelector('app-router').go('/home');
+// or
+document.querySelector('app-router').go('/home', {replace: true});
+```
+
+If you use `go(path, options)` you should also set the mode to `hash` or `pushstate` on the router.
+
+```html
+<app-router mode="auto|pushstate|hash">
+ <!-- app-routes -->
+</app-router>
+```
+
+## Data Binding
+Path variables and query parameters automatically attach to the element's attributes.
+
+``` html
+<!-- url -->
+<a is="pushstate-anchor" href="/order/123?sort=ascending">Order 123</a>
+
+<!-- route -->
+<app-route path="/order/:orderId" import="/pages/order-page.html"></app-route>
+
+<!-- will bind 123 to the page's `orderId` attribute and "ascending" to the `sort` attribute -->
+<order-page orderId="123" sort="ascending"></order-page>
+```
+
+If you're using Polymer, you can also bind path variables and query parameters to templates.
+```html
+<app-route path="/order/:orderId">
+ <template>
+ <p>Your order number is {{orderId}}</p>
+ </template>
+</app-route>
+```
+
+See it in action [here](https://erikringsmuth.github.io/app-router/#/databinding/1337?queryParam1=Routing%20with%20Web%20Components!).
+
+## <app-route> options
+
+#### import a custom element
+Lazy-load a custom element.
+
+```html
+<app-route path="/customer/:customerId" import="/pages/customer-page.html" [element="customer-page"]></app-route>
+```
+
+You only need to set the `element` attribute if the element's name is different than the file name.
+
+#### pre-loaded custom element
+Include the `element="element-name"` attribute on the route to use a pre-loaded custom element. This is how you use bundled (vulcanized) custom elements.
+
+```html
+<head>
+ <link rel="import" href="/pages/page-bundle.html">
+</head>
+<app-router>
+ <app-route path="/customer/:customerId" element="customer-page"></app-route>
+</app-router>
+```
+
+#### import template
+You can import a `<template>` instead of a custom element. Just include the `template` attribute.
+
+```html
+<app-route path="/example" import="/pages/template-page.html" template></app-route>
+```
+
+#### inline template
+Finally, you can in-line a `<template>` like this.
+
+```html
+<app-route path="/example">
+ <template>
+ <p>Inline template FTW!</p>
+ </template>
+</app-route>
+```
+
+#### regular expressions
+Include the `regex` attribute to match on a regular expression. The format is the same as a JavaScript regular expression.
+
+```html
+<!-- matches a pattern like '/word/number' -->
+<app-route path="/^\/\w+\/\d+$/i" regex import="/pages/regex-page.html"></app-route>
+```
+
+#### redirect
+A route can redirect to another path.
+
+```html
+<app-router mode="pushstate">
+ <app-route path="/home" import="/pages/home-page.html"></app-route>
+ <app-route path="*" redirect="/home"></app-route>
+</app-router>
+```
+
+When you use `redirect` you should also set `mode="hash|pushstate"` on the `app-router`.
+
+## <app-router> options
+
+#### mode
+One set of routes will match regular paths `/` and hash paths `#/`. You can force a specific mode with `mode="auto|hash|pushstate"`.
+
+```html
+<app-router mode="pushstate">
+ <!-- always ignore the hash and match on the path -->
+</app-router>
+```
+
+When left in `auto`, redirects and `go(path, options)` will use hash paths.
+
+#### trailing slashes
+By default `/home` and `/home/` are treated as separate routes. You can configure the router to ignore trailing slashes with `trailingSlash="ignore"`.
+```html
+<app-router trailingSlash="ignore">
+ <!-- matches '/home' and '/home/' -->
+ <app-route path="/home" import="/pages/home-page.html"></app-route>
+</app-router>
+```
+
+## Demo Site & Example Setup
+Check out the `app-router` in action at [erikringsmuth.github.io/app-router](https://erikringsmuth.github.io/app-router/).
+
+You can download an example setup here https://github.com/erikringsmuth/app-router-examples to get running locally.
+
+Examples showing `app-router` and `flatiron-director` versus no router https://github.com/erikringsmuth/polymer-router-demos.
+
+## Breaking Changes
+Check the [change log](https://github.com/erikringsmuth/app-router/blob/master/changelog.md) for breaking changes in major versions.
+
+## Build, Test, and Debug [](https://travis-ci.org/erikringsmuth/app-router)
+Source files are under the `src` folder. The build process writes to the root directory. The easiest way to debug is to include the source script rather than the minified HTML import.
+```html
+<script src="/bower_components/app-router/src/app-router.js"></script>
+```
+
+To build:
+- Run `bower install` and `npm install` to install dev dependencies
+- Lint, test, build, and minify code with `gulp`
+- Manually run functional tests in the browser by starting a static content server (node `http-server` or `python -m SimpleHTTPServer`) and open [http://localhost:8080/tests/functional-tests/](http://localhost:8080/tests/functional-tests/)
diff --git a/polymer_1.0.4/bower_components/app-router/app-router.csp.html b/polymer_1.0.4/bower_components/app-router/app-router.csp.html
new file mode 100644
index 0000000..335fc32
--- /dev/null
+++ b/polymer_1.0.4/bower_components/app-router/app-router.csp.html
@@ -0,0 +1,2 @@
+<!-- Copyright (C) 2015 Erik Ringsmuth - MIT license -->
+<script src="app-router.js"></script>
diff --git a/polymer_1.0.4/bower_components/app-router/app-router.html b/polymer_1.0.4/bower_components/app-router/app-router.html
new file mode 100644
index 0000000..1f31905
--- /dev/null
+++ b/polymer_1.0.4/bower_components/app-router/app-router.html
@@ -0,0 +1,4 @@
+<!-- Copyright (C) 2015 Erik Ringsmuth - MIT license -->
+<script type="text/javascript">
+!function(t,e){function a(t,a,i){var r=e.createEvent("CustomEvent");return r.initCustomEvent(t,!1,!0,a),i.dispatchEvent(r)}function i(e){var i=m.parseUrl(t.location.href,e.getAttribute("mode"));if(i.hash!==A.hash&&i.path===A.path&&i.search===A.search&&i.isHashPath===A.isHashPath)return g(i.hash),void 0;A=i;var n={path:i.path};if(a("state-change",n,e)){for(var s=e.firstElementChild;s;){if("APP-ROUTE"===s.tagName&&m.testRoute(s.getAttribute("path"),i.path,e.getAttribute("trailingSlash"),s.hasAttribute("regex")))return r(e,s,i),void 0;s=s.nextSibling}a("not-found",n,e)}}function r(t,e,i){if(e.hasAttribute("redirect"))return t.go(e.getAttribute("redirect"),{replace:!0}),void 0;if(e!==t.activeRoute||"noop"!==e.getAttribute("onUrlChange")){var r={path:i.path,route:e,oldRoute:t.activeRoute};a("activate-route-start",r,t)&&a("activate-route-start",r,e)&&(t.loadingRoute=e,e===t.activeRoute&&"updateModel"===e.getAttribute("onUrlChange")?n(t,e,i,r):e.hasAttribute("import")?s(t,e.getAttribute("import"),e,i,r):e.hasAttribute("element")?u(t,e.getAttribute("element"),e,i,r):e.firstElementChild&&"TEMPLATE"===e.firstElementChild.tagName&&(e.isInlineTemplate=!0,h(t,e.firstElementChild,e,i,r)))}}function n(t,e,i,r){var n=l(t,e,i,r);e.hasAttribute("template")||e.isInlineTemplate?c(e.lastElementChild.templateInstance.model,n):c(e.firstElementChild,n),a("activate-route-end",r,t),a("activate-route-end",r,r.route)}function s(t,a,i,r,n){function s(){u.loaded=!0,o(t,u,a,i,r,n)}var u;b.hasOwnProperty(a)?(u=b[a],u.loaded?o(t,u,a,i,r,n):u.addEventListener("load",s)):(u=e.createElement("link"),u.setAttribute("rel","import"),u.setAttribute("href",a),u.setAttribute("async","async"),u.addEventListener("load",s),u.loaded=!1,e.head.appendChild(u),b[a]=u)}function o(t,e,a,i,r,n){if(i.importLink=e,i===t.loadingRoute)if(i.hasAttribute("template")){var s,o=i.getAttribute("template");s=o?e.import.getElementById(o):e.import.querySelector("template"),h(t,s,i,r,n)}else u(t,i.getAttribute("element")||a.split("/").slice(-1)[0].replace(".html",""),i,r,n)}function u(t,a,i,r,n){var s=e.createElement(a),o=l(t,i,r,n);c(s,o),p(t,s,r,n)}function h(t,a,i,r,n){var s;if("createInstance"in a){var o=l(t,i,r,n);s=a.createInstance(o)}else s=e.importNode(a.content,!0);p(t,s,r,n)}function l(t,e,i,r){var n=m.routeArguments(e.getAttribute("path"),i.path,i.search,e.hasAttribute("regex"),"auto"===t.getAttribute("typecast"));return(e.hasAttribute("bindRouter")||t.hasAttribute("bindRouter"))&&(n.router=t),r.model=n,a("before-data-binding",r,t),a("before-data-binding",r,r.route),r.model}function c(t,e){for(var a in e)e.hasOwnProperty(a)&&(t[a]=e[a])}function p(t,e,i,r){d(t.previousRoute),t.previousRoute=t.activeRoute,t.activeRoute=t.loadingRoute,t.loadingRoute=null,t.previousRoute&&t.previousRoute.removeAttribute("active"),t.activeRoute.setAttribute("active","active"),t.hasAttribute("core-animated-pages")&&r.route!==r.oldRoute||d(t.previousRoute),t.activeRoute.appendChild(e),t.hasAttribute("core-animated-pages")&&(t.coreAnimatedPages.selected=t.activeRoute.getAttribute("path")),i.hash&&!t.hasAttribute("core-animated-pages")&&g(i.hash),a("activate-route-end",r,t),a("activate-route-end",r,r.route)}function d(t){if(t){var e=t.firstChild;for(t.isInlineTemplate&&(e=t.querySelector("template").nextSibling);e;){var a=e;e=e.nextSibling,t.removeChild(a)}}}function g(t){t&&setTimeout(function(){var a=e.querySelector("html /deep/ "+t)||e.querySelector('html /deep/ [name="'+t.substring(1)+'"]');a&&a.scrollIntoView&&a.scrollIntoView(!0)},0)}function v(t,e,a,i,r){var n=t[e],s=a[i];if("**"===n&&e===t.length-1)return!0;if("undefined"==typeof n||"undefined"==typeof s)return n===s;if(n===s||"*"===n||":"===n.charAt(0))return":"===n.charAt(0)&&"undefined"!=typeof r&&(r[n.substring(1)]=a[i]),v(t,e+1,a,i+1,r);if("**"===n)for(var o=i;o<a.length;o++)if(v(t,e+1,a,o,r))return!0;return!1}var m={},b={},f="ActiveXObject"in t,A={},E=Object.create(HTMLElement.prototype);E.util=m,e.registerElement("app-route",{prototype:Object.create(HTMLElement.prototype)}),E.attachedCallback=function(){"manual"!==this.getAttribute("init")&&this.init()},E.init=function(){var a=this;a.isInitialized||(a.isInitialized=!0,a.hasAttribute("trailingSlash")||a.setAttribute("trailingSlash","strict"),a.hasAttribute("mode")||a.setAttribute("mode","auto"),a.hasAttribute("typecast")||a.setAttribute("typecast","auto"),a.hasAttribute("core-animated-pages")&&(a.createShadowRoot(),a.coreAnimatedPages=e.createElement("core-animated-pages"),a.coreAnimatedPages.appendChild(e.createElement("content")),a.coreAnimatedPages.style.position="static",a.coreAnimatedPages.setAttribute("valueattr","path"),a.coreAnimatedPages.setAttribute("transitions",a.getAttribute("transitions")),a.shadowRoot.appendChild(a.coreAnimatedPages),a.coreAnimatedPages.addEventListener("core-animated-pages-transition-end",function(){a.previousRoute&&!a.previousRoute.hasAttribute("active")&&d(a.previousRoute)})),a.stateChangeHandler=i.bind(null,a),t.addEventListener("popstate",a.stateChangeHandler,!1),f&&t.addEventListener("hashchange",a.stateChangeHandler,!1),i(a))},E.detachedCallback=function(){t.removeEventListener("popstate",this.stateChangeHandler,!1),f&&t.removeEventListener("hashchange",this.stateChangeHandler,!1)},E.go=function(a,i){"pushstate"!==this.getAttribute("mode")&&(a="hashbang"===this.getAttribute("mode")?"#!"+a:"#"+a),i&&i.replace===!0?t.history.replaceState(null,null,a):t.history.pushState(null,null,a);try{var r=new PopStateEvent("popstate",{bubbles:!1,cancelable:!1,state:{}});"dispatchEvent_"in t?t.dispatchEvent_(r):t.dispatchEvent(r)}catch(n){var s=e.createEvent("CustomEvent");s.initCustomEvent("popstate",!1,!1,{state:{}}),t.dispatchEvent(s)}},m.parseUrl=function(t,a){var i={isHashPath:"hash"===a};if("function"==typeof URL){var r=new URL(t);i.path=r.pathname,i.hash=r.hash,i.search=r.search}else{var n=e.createElement("a");n.href=t,i.path=n.pathname,"/"!==i.path.charAt(0)&&(i.path="/"+i.path),i.hash=n.hash,i.search=n.search}if("pushstate"!==a&&("#/"===i.hash.substring(0,2)?(i.isHashPath=!0,i.path=i.hash.substring(1)):"#!/"===i.hash.substring(0,3)?(i.isHashPath=!0,i.path=i.hash.substring(2)):i.isHashPath&&(i.path=0===i.hash.length?"/":i.hash.substring(1)),i.isHashPath)){i.hash="";var s=i.path.indexOf("#");-1!==s&&(i.hash=i.path.substring(s),i.path=i.path.substring(0,s));var o=i.path.indexOf("?");-1!==o&&(i.search=i.path.substring(o),i.path=i.path.substring(0,o))}return i},m.testRoute=function(t,e,a,i){return"ignore"===a&&("/"===e.slice(-1)&&(e=e.slice(0,-1)),"/"!==t.slice(-1)||i||(t=t.slice(0,-1))),i?m.testRegExString(t,e):t===e||"*"===t?!0:("/"!==t.charAt(0)&&(t="/**/"+t),v(t.split("/"),1,e.split("/"),1))},m.routeArguments=function(t,e,a,i,r){var n={};i||("/"!==t.charAt(0)&&(t="/**/"+t),v(t.split("/"),1,e.split("/"),1,n));var s=a.substring(1).split("&");1===s.length&&""===s[0]&&(s=[]);for(var o=0;o<s.length;o++){var u=s[o],h=u.split("=");n[h[0]]=h.splice(1,h.length-1).join("=")}if(r)for(var l in n)n[l]=m.typecast(n[l]);return n},m.typecast=function(t){return"true"===t?!0:"false"===t?!1:isNaN(t)||""===t||"0"===t.charAt(0)?decodeURIComponent(t):+t},m.testRegExString=function(t,e){if("/"!==t.charAt(0))return!1;t=t.slice(1);var a="";if("/"===t.slice(-1))t=t.slice(0,-1);else{if("/i"!==t.slice(-2))return!1;t=t.slice(0,-2),a="i"}return new RegExp(t,a).test(e)},e.registerElement("app-router",{prototype:E})}(window,document);
+</script>
diff --git a/polymer_1.0.4/bower_components/app-router/app-router.js b/polymer_1.0.4/bower_components/app-router/app-router.js
new file mode 100644
index 0000000..0676214
--- /dev/null
+++ b/polymer_1.0.4/bower_components/app-router/app-router.js
@@ -0,0 +1,2 @@
+// @license Copyright (C) 2015 Erik Ringsmuth - MIT license
+!function(t,e){function a(t,a,i){var r=e.createEvent("CustomEvent");return r.initCustomEvent(t,!1,!0,a),i.dispatchEvent(r)}function i(e){var i=m.parseUrl(t.location.href,e.getAttribute("mode"));if(i.hash!==A.hash&&i.path===A.path&&i.search===A.search&&i.isHashPath===A.isHashPath)return g(i.hash),void 0;A=i;var n={path:i.path};if(a("state-change",n,e)){for(var s=e.firstElementChild;s;){if("APP-ROUTE"===s.tagName&&m.testRoute(s.getAttribute("path"),i.path,e.getAttribute("trailingSlash"),s.hasAttribute("regex")))return r(e,s,i),void 0;s=s.nextSibling}a("not-found",n,e)}}function r(t,e,i){if(e.hasAttribute("redirect"))return t.go(e.getAttribute("redirect"),{replace:!0}),void 0;if(e!==t.activeRoute||"noop"!==e.getAttribute("onUrlChange")){var r={path:i.path,route:e,oldRoute:t.activeRoute};a("activate-route-start",r,t)&&a("activate-route-start",r,e)&&(t.loadingRoute=e,e===t.activeRoute&&"updateModel"===e.getAttribute("onUrlChange")?n(t,e,i,r):e.hasAttribute("import")?s(t,e.getAttribute("import"),e,i,r):e.hasAttribute("element")?u(t,e.getAttribute("element"),e,i,r):e.firstElementChild&&"TEMPLATE"===e.firstElementChild.tagName&&(e.isInlineTemplate=!0,h(t,e.firstElementChild,e,i,r)))}}function n(t,e,i,r){var n=l(t,e,i,r);e.hasAttribute("template")||e.isInlineTemplate?c(e.lastElementChild.templateInstance.model,n):c(e.firstElementChild,n),a("activate-route-end",r,t),a("activate-route-end",r,r.route)}function s(t,a,i,r,n){function s(){u.loaded=!0,o(t,u,a,i,r,n)}var u;b.hasOwnProperty(a)?(u=b[a],u.loaded?o(t,u,a,i,r,n):u.addEventListener("load",s)):(u=e.createElement("link"),u.setAttribute("rel","import"),u.setAttribute("href",a),u.setAttribute("async","async"),u.addEventListener("load",s),u.loaded=!1,e.head.appendChild(u),b[a]=u)}function o(t,e,a,i,r,n){if(i.importLink=e,i===t.loadingRoute)if(i.hasAttribute("template")){var s,o=i.getAttribute("template");s=o?e.import.getElementById(o):e.import.querySelector("template"),h(t,s,i,r,n)}else u(t,i.getAttribute("element")||a.split("/").slice(-1)[0].replace(".html",""),i,r,n)}function u(t,a,i,r,n){var s=e.createElement(a),o=l(t,i,r,n);c(s,o),p(t,s,r,n)}function h(t,a,i,r,n){var s;if("createInstance"in a){var o=l(t,i,r,n);s=a.createInstance(o)}else s=e.importNode(a.content,!0);p(t,s,r,n)}function l(t,e,i,r){var n=m.routeArguments(e.getAttribute("path"),i.path,i.search,e.hasAttribute("regex"),"auto"===t.getAttribute("typecast"));return(e.hasAttribute("bindRouter")||t.hasAttribute("bindRouter"))&&(n.router=t),r.model=n,a("before-data-binding",r,t),a("before-data-binding",r,r.route),r.model}function c(t,e){for(var a in e)e.hasOwnProperty(a)&&(t[a]=e[a])}function p(t,e,i,r){d(t.previousRoute),t.previousRoute=t.activeRoute,t.activeRoute=t.loadingRoute,t.loadingRoute=null,t.previousRoute&&t.previousRoute.removeAttribute("active"),t.activeRoute.setAttribute("active","active"),t.hasAttribute("core-animated-pages")&&r.route!==r.oldRoute||d(t.previousRoute),t.activeRoute.appendChild(e),t.hasAttribute("core-animated-pages")&&(t.coreAnimatedPages.selected=t.activeRoute.getAttribute("path")),i.hash&&!t.hasAttribute("core-animated-pages")&&g(i.hash),a("activate-route-end",r,t),a("activate-route-end",r,r.route)}function d(t){if(t){var e=t.firstChild;for(t.isInlineTemplate&&(e=t.querySelector("template").nextSibling);e;){var a=e;e=e.nextSibling,t.removeChild(a)}}}function g(t){t&&setTimeout(function(){var a=e.querySelector("html /deep/ "+t)||e.querySelector('html /deep/ [name="'+t.substring(1)+'"]');a&&a.scrollIntoView&&a.scrollIntoView(!0)},0)}function v(t,e,a,i,r){var n=t[e],s=a[i];if("**"===n&&e===t.length-1)return!0;if("undefined"==typeof n||"undefined"==typeof s)return n===s;if(n===s||"*"===n||":"===n.charAt(0))return":"===n.charAt(0)&&"undefined"!=typeof r&&(r[n.substring(1)]=a[i]),v(t,e+1,a,i+1,r);if("**"===n)for(var o=i;o<a.length;o++)if(v(t,e+1,a,o,r))return!0;return!1}var m={},b={},f="ActiveXObject"in t,A={},E=Object.create(HTMLElement.prototype);E.util=m,e.registerElement("app-route",{prototype:Object.create(HTMLElement.prototype)}),E.attachedCallback=function(){"manual"!==this.getAttribute("init")&&this.init()},E.init=function(){var a=this;a.isInitialized||(a.isInitialized=!0,a.hasAttribute("trailingSlash")||a.setAttribute("trailingSlash","strict"),a.hasAttribute("mode")||a.setAttribute("mode","auto"),a.hasAttribute("typecast")||a.setAttribute("typecast","auto"),a.hasAttribute("core-animated-pages")&&(a.createShadowRoot(),a.coreAnimatedPages=e.createElement("core-animated-pages"),a.coreAnimatedPages.appendChild(e.createElement("content")),a.coreAnimatedPages.style.position="static",a.coreAnimatedPages.setAttribute("valueattr","path"),a.coreAnimatedPages.setAttribute("transitions",a.getAttribute("transitions")),a.shadowRoot.appendChild(a.coreAnimatedPages),a.coreAnimatedPages.addEventListener("core-animated-pages-transition-end",function(){a.previousRoute&&!a.previousRoute.hasAttribute("active")&&d(a.previousRoute)})),a.stateChangeHandler=i.bind(null,a),t.addEventListener("popstate",a.stateChangeHandler,!1),f&&t.addEventListener("hashchange",a.stateChangeHandler,!1),i(a))},E.detachedCallback=function(){t.removeEventListener("popstate",this.stateChangeHandler,!1),f&&t.removeEventListener("hashchange",this.stateChangeHandler,!1)},E.go=function(a,i){"pushstate"!==this.getAttribute("mode")&&(a="hashbang"===this.getAttribute("mode")?"#!"+a:"#"+a),i&&i.replace===!0?t.history.replaceState(null,null,a):t.history.pushState(null,null,a);try{var r=new PopStateEvent("popstate",{bubbles:!1,cancelable:!1,state:{}});"dispatchEvent_"in t?t.dispatchEvent_(r):t.dispatchEvent(r)}catch(n){var s=e.createEvent("CustomEvent");s.initCustomEvent("popstate",!1,!1,{state:{}}),t.dispatchEvent(s)}},m.parseUrl=function(t,a){var i={isHashPath:"hash"===a};if("function"==typeof URL){var r=new URL(t);i.path=r.pathname,i.hash=r.hash,i.search=r.search}else{var n=e.createElement("a");n.href=t,i.path=n.pathname,"/"!==i.path.charAt(0)&&(i.path="/"+i.path),i.hash=n.hash,i.search=n.search}if("pushstate"!==a&&("#/"===i.hash.substring(0,2)?(i.isHashPath=!0,i.path=i.hash.substring(1)):"#!/"===i.hash.substring(0,3)?(i.isHashPath=!0,i.path=i.hash.substring(2)):i.isHashPath&&(i.path=0===i.hash.length?"/":i.hash.substring(1)),i.isHashPath)){i.hash="";var s=i.path.indexOf("#");-1!==s&&(i.hash=i.path.substring(s),i.path=i.path.substring(0,s));var o=i.path.indexOf("?");-1!==o&&(i.search=i.path.substring(o),i.path=i.path.substring(0,o))}return i},m.testRoute=function(t,e,a,i){return"ignore"===a&&("/"===e.slice(-1)&&(e=e.slice(0,-1)),"/"!==t.slice(-1)||i||(t=t.slice(0,-1))),i?m.testRegExString(t,e):t===e||"*"===t?!0:("/"!==t.charAt(0)&&(t="/**/"+t),v(t.split("/"),1,e.split("/"),1))},m.routeArguments=function(t,e,a,i,r){var n={};i||("/"!==t.charAt(0)&&(t="/**/"+t),v(t.split("/"),1,e.split("/"),1,n));var s=a.substring(1).split("&");1===s.length&&""===s[0]&&(s=[]);for(var o=0;o<s.length;o++){var u=s[o],h=u.split("=");n[h[0]]=h.splice(1,h.length-1).join("=")}if(r)for(var l in n)n[l]=m.typecast(n[l]);return n},m.typecast=function(t){return"true"===t?!0:"false"===t?!1:isNaN(t)||""===t||"0"===t.charAt(0)?decodeURIComponent(t):+t},m.testRegExString=function(t,e){if("/"!==t.charAt(0))return!1;t=t.slice(1);var a="";if("/"===t.slice(-1))t=t.slice(0,-1);else{if("/i"!==t.slice(-2))return!1;t=t.slice(0,-2),a="i"}return new RegExp(t,a).test(e)},e.registerElement("app-router",{prototype:E})}(window,document);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/app-router/bower.json b/polymer_1.0.4/bower_components/app-router/bower.json
new file mode 100644
index 0000000..c95b486
--- /dev/null
+++ b/polymer_1.0.4/bower_components/app-router/bower.json
@@ -0,0 +1,32 @@
+{
+ "name": "app-router",
+ "version": "2.6.1",
+ "authors": [
+ "Erik Ringsmuth <erik.ringsmuth@gmail.com>"
+ ],
+ "description": "Router for Web Components.",
+ "keywords": [
+ "web-components",
+ "router",
+ "polymer",
+ "x-tag"
+ ],
+ "main": "app-router.html",
+ "license": "MIT",
+ "homepage": "https://github.com/erikringsmuth/app-router",
+ "ignore": [
+ "**/.*",
+ "bower_components",
+ "node_modules",
+ "tests",
+ "tmp",
+ "gulpfile.js",
+ "package.json"
+ ],
+ "devDependencies": {
+ "polymer": "~0.5.4",
+ "webcomponentsjs": "~0.5.4",
+ "core-elements": "Polymer/core-elements#~0.5.4",
+ "pushstate-anchor": "~0.3.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/app-router/changelog.md b/polymer_1.0.4/bower_components/app-router/changelog.md
new file mode 100644
index 0000000..5f4814a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/app-router/changelog.md
@@ -0,0 +1,96 @@
+## app-router change log
+
+#### master
+- Adding `hashbang` mode in addition to the existing `auto`, `hash`, and `pushstate`.
+- Fixed URL change bug when only changing the hash.
+
+#### 2.6.0
+- Adding ability to bundle templates and select by ID `<app-route path="/home" import="pages/bundled-templates.html" template="homepage"></app-route>`.
+- Adding `async` flag to `<app-route>` HTML imports. By default HTML imports block rendering of the page. The router waits for the link's `load` event to fire before using the imported document so this will speed up rendering when navigating between routes.
+
+#### 2.5.0
+- Adding `onUrlChange="reload|updateModel|noop"` attribute to `<app-route>`. This is useful when you have nested routers and you only want to change the inner most route.
+
+#### v2.4.2
+- Fixing bug where navigating multiple times before any page finishes importing will lose the reference to the currently loaded route (`previousRoute`) before it is removed from the DOM.
+- Adding `route.importLink` reference.
+
+#### v2.4.1
+- Fixed bug where navigating to the same link twice with `core-animated-pages` would remove the page after 5 seconds.
+
+#### v2.4.0
+- Adding globstar `**` support.
+- Adding relative paths `users/:userId` which is the same as `/**/users/:userId`.
+
+#### v2.3.2
+- Fixed bug where calling `router.go('/path')` on the current path wouldn't reload the page.
+- Switched `router.go('/path')` to fire a `popstate` event instead of directly calling `stateChange()` in order to support multiple routers on the same page.
+
+#### v2.3.1
+- Fixing bug where `router.go('/path')` would replace state instead of push state.
+
+#### v2.3.0
+- Adding `typecast="auto|string"` option on the `app-router`. Path variables and query parameters are typecast to numbers, booleans, and unescaped strings by default. Now you can get the raw string with `typecast="string"`.
+- Optimized hash fragment changes so that if only the hash fragment changes it will scroll to the fragment and not reload the entire page.
+
+#### v2.2.1
+- Fixing bug where the `before-data-binding` event wasn't using the updated model if the entire model was replaced.
+
+#### v2.2.0
+- Added ability to scroll to hash fragment on navigation. For example, `http://example.com/#/page1#middle` will now scroll to an element with `id="middle"` or `name="middle"`.
+
+#### v2.1.0
+- Added data binding to `<template>` tags when Polymer (`TemplateBinding.js`) is present.
+- Added `bindRouter` attribute to pass the router to the `app-route`'s page.
+- Added `before-data-binding` event to add properties to a model before it's bound to the route's custom element or template.
+- Fixed a `core-animated-pages` bug where multiple URLs matched the same `app-route` (ex: `path="/page/:num"` and paths `/page/1`, `/page/2`).
+
+#### v2.0.4
+- The move from `platform.js` to `webcomponents.js` removed the `URL()` constructor polyfill. The v2.0.3 fix created a bug in Safari when parsing the URL. This fixes Safari.
+
+#### v2.0.3
+- The move from `platform.js` to `webcomponents.js` removed the `URL()` constructor polyfill https://github.com/Polymer/webcomponentsjs/issues/53. IE doesn't support the `URL()` constructor yet so this fix is adding URL parse support for IE.
+
+#### v2.0.2
+- Fixing [issue 19](https://github.com/erikringsmuth/app-router/issues/19) using best effort approach. Use `template.createInstance()` if Polymer is loaded, otherwise use `document.importNode()`.
+
+#### v2.0.1
+- Fixing bug where multiple `<app-route>`s had an `active` attribute.
+
+#### v2.0.0
+New features
+
+- Added support for `<core-animated-pages>`. Example: set up the router like `<app-router core-animated-pages transitions="hero-transition cross-fade">` then include the `hero` and `cross-fade` attributes on the elements you want transitioned.
+
+Breaking changes
+
+- Previously the active route's content was under an `<active-route>` element. Now the content for the route is under it's `<app-route>` element. This changed to support `<core-animated-pages>`.
+- The `<active-route>` element and `router.activeRouteContent` have been removed.
+- Removed the `shadow` attribute from the `<app-router>`. This was applied to the `<active-route>` element which no longer exists.
+
+#### v1.0.0
+Breaking changes
+
+- `pathType="auto|hash|regular"` has been replaced with `mode="auto|hash|pushstate"` for redirects, `router.go(path, options)`, and testing routes.
+
+New features
+
+- Added support for redirects with `<app-route path="..." redirect="/other/path"></app-route>`.
+- Added `router.go(path, options)`. Example: `document.querySelector('app-router').go('/home', {replace: true})`.
+- Note: If you're using redirects or `go()` you should specify the mode with `<app-router mode="pushstate|hash"></app-router>`. Leaving the mode as `auto` (the default) will change the hash, even if you wanted it to change the real path with pushstate.
+
+#### v0.9.0
+- Refactor `parseUrl()` to use the native `URL()` constructor and return additional information about the hash path.
+- Cleaned up `testRoute()` and `routeArguments()` with additional information from `parseUrl()`.
+- Moved utility functions to `AppRouter.util`.
+
+#### v0.8.1
+- Fixed bug where the regular path was being used when `pathType="hash"` was set on the router.
+
+#### v0.8.0
+- `template` no longer required on inline template routes.
+- Only use `app-route`s that are direct children of the router by replacing `querySelector()` with `firstElementChild` and iterating with `nextSibling`.
+- Took internal functions off the public API and simplified parameters.
+
+#### v0.7.0
+- Added the `pathType` attribute to the router. The options are `auto`, `hash`, and `regular`.
diff --git a/polymer_1.0.4/bower_components/app-router/preview.png b/polymer_1.0.4/bower_components/app-router/preview.png
new file mode 100644
index 0000000..d18770f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/app-router/preview.png
Binary files differ
diff --git a/polymer_1.0.4/bower_components/app-router/src/app-router.html b/polymer_1.0.4/bower_components/app-router/src/app-router.html
new file mode 100644
index 0000000..ec1bd60
--- /dev/null
+++ b/polymer_1.0.4/bower_components/app-router/src/app-router.html
@@ -0,0 +1,2 @@
+<!-- Copyright (C) 2015 Erik Ringsmuth - MIT license -->
+<script type="text/javascript" src="app-router.js"></script>
diff --git a/polymer_1.0.4/bower_components/app-router/src/app-router.js b/polymer_1.0.4/bower_components/app-router/src/app-router.js
new file mode 100644
index 0000000..b41e973
--- /dev/null
+++ b/polymer_1.0.4/bower_components/app-router/src/app-router.js
@@ -0,0 +1,702 @@
+// @license Copyright (C) 2015 Erik Ringsmuth - MIT license
+(function(window, document) {
+ var utilities = {};
+ var importedURIs = {};
+ var isIE = 'ActiveXObject' in window;
+ var previousUrl = {};
+
+ // <app-router
+ // init="auto|manual"
+ // mode="auto|hash|hashbang|pushstate"
+ // trailingSlash="strict|ignore"
+ // typecast="auto|string"
+ // bindRouter
+ // ></app-router>
+ var AppRouter = Object.create(HTMLElement.prototype);
+ AppRouter.util = utilities;
+
+ // <app-route
+ // path="/path"
+ // import="/page/cust-el.html"
+ // element[="cust-el"]
+ // template[="template-id"]
+ // regex
+ // redirect="/path"
+ // onUrlChange="reload|updateModel|noop"
+ // bindRouter
+ // ></app-route>
+ document.registerElement('app-route', {
+ prototype: Object.create(HTMLElement.prototype)
+ });
+
+ // Initial set up when attached
+ AppRouter.attachedCallback = function() {
+ // init="auto|manual"
+ if(this.getAttribute('init') !== 'manual') {
+ this.init();
+ }
+ };
+
+ // Initialize the router
+ AppRouter.init = function() {
+ var router = this;
+ if (router.isInitialized) {
+ return;
+ }
+ router.isInitialized = true;
+
+ // trailingSlash="strict|ignore"
+ if (!router.hasAttribute('trailingSlash')) {
+ router.setAttribute('trailingSlash', 'strict');
+ }
+
+ // mode="auto|hash|hashbang|pushstate"
+ if (!router.hasAttribute('mode')) {
+ router.setAttribute('mode', 'auto');
+ }
+
+ // typecast="auto|string"
+ if (!router.hasAttribute('typecast')) {
+ router.setAttribute('typecast', 'auto');
+ }
+
+ // <app-router core-animated-pages transitions="hero-transition cross-fade">
+ if (router.hasAttribute('core-animated-pages')) {
+ // use shadow DOM to wrap the <app-route> elements in a <core-animated-pages> element
+ // <app-router>
+ // # shadowRoot
+ // <core-animated-pages>
+ // # content in the light DOM
+ // <app-route element="home-page">
+ // <home-page>
+ // </home-page>
+ // </app-route>
+ // </core-animated-pages>
+ // </app-router>
+ router.createShadowRoot();
+ router.coreAnimatedPages = document.createElement('core-animated-pages');
+ router.coreAnimatedPages.appendChild(document.createElement('content'));
+
+ // don't know why it needs to be static, but absolute doesn't display the page
+ router.coreAnimatedPages.style.position = 'static';
+
+ // toggle the selected page using selected="path" instead of selected="integer"
+ router.coreAnimatedPages.setAttribute('valueattr', 'path');
+
+ // pass the transitions attribute from <app-router core-animated-pages transitions="hero-transition cross-fade">
+ // to <core-animated-pages transitions="hero-transition cross-fade">
+ router.coreAnimatedPages.setAttribute('transitions', router.getAttribute('transitions'));
+
+ // set the shadow DOM's content
+ router.shadowRoot.appendChild(router.coreAnimatedPages);
+
+ // when a transition finishes, remove the previous route's content. there is a temporary overlap where both
+ // the new and old route's content is in the DOM to animate the transition.
+ router.coreAnimatedPages.addEventListener('core-animated-pages-transition-end', function() {
+ // with core-animated-pages, navigating to the same route twice quickly will set the new route to both the
+ // activeRoute and the previousRoute before the animation finishes. we don't want to delete the route content
+ // if it's actually the active route.
+ if (router.previousRoute && !router.previousRoute.hasAttribute('active')) {
+ deactivateRoute(router.previousRoute);
+ }
+ });
+ }
+
+ // listen for URL change events
+ router.stateChangeHandler = stateChange.bind(null, router);
+ window.addEventListener('popstate', router.stateChangeHandler, false);
+ if (isIE) {
+ // IE bug. A hashchange is supposed to trigger a popstate event, making popstate the only event you
+ // need to listen to. That's not the case in IE so we make another event listener for it.
+ window.addEventListener('hashchange', router.stateChangeHandler, false);
+ }
+
+ // load the web component for the current route
+ stateChange(router);
+ };
+
+ // clean up global event listeners
+ AppRouter.detachedCallback = function() {
+ window.removeEventListener('popstate', this.stateChangeHandler, false);
+ if (isIE) {
+ window.removeEventListener('hashchange', this.stateChangeHandler, false);
+ }
+ };
+
+ // go(path, options) Navigate to the path
+ //
+ // options = {
+ // replace: true
+ // }
+ AppRouter.go = function(path, options) {
+ if (this.getAttribute('mode') !== 'pushstate') {
+ // mode == auto, hash or hashbang
+ if (this.getAttribute('mode') === 'hashbang') {
+ path = '#!' + path;
+ } else {
+ path = '#' + path;
+ }
+ }
+ if (options && options.replace === true) {
+ window.history.replaceState(null, null, path);
+ } else {
+ window.history.pushState(null, null, path);
+ }
+
+ // dispatch a popstate event
+ try {
+ var popstateEvent = new PopStateEvent('popstate', {
+ bubbles: false,
+ cancelable: false,
+ state: {}
+ });
+
+ if ('dispatchEvent_' in window) {
+ // FireFox with polyfill
+ window.dispatchEvent_(popstateEvent);
+ } else {
+ // normal
+ window.dispatchEvent(popstateEvent);
+ }
+ } catch(error) {
+ // Internet Exploder
+ var fallbackEvent = document.createEvent('CustomEvent');
+ fallbackEvent.initCustomEvent('popstate', false, false, { state: {} });
+ window.dispatchEvent(fallbackEvent);
+ }
+ };
+
+ // fire(type, detail, node) - Fire a new CustomEvent(type, detail) on the node
+ //
+ // listen with document.querySelector('app-router').addEventListener(type, function(event) {
+ // event.detail, event.preventDefault()
+ // })
+ function fire(type, detail, node) {
+ // create a CustomEvent the old way for IE9/10 support
+ var event = document.createEvent('CustomEvent');
+
+ // initCustomEvent(type, bubbles, cancelable, detail)
+ event.initCustomEvent(type, false, true, detail);
+
+ // returns false when event.preventDefault() is called, true otherwise
+ return node.dispatchEvent(event);
+ }
+
+ // Find the first <app-route> that matches the current URL and change the active route
+ function stateChange(router) {
+ var url = utilities.parseUrl(window.location.href, router.getAttribute('mode'));
+
+ // don't load a new route if only the hash fragment changed
+ if (url.hash !== previousUrl.hash && url.path === previousUrl.path && url.search === previousUrl.search && url.isHashPath === previousUrl.isHashPath) {
+ scrollToHash(url.hash);
+ previousUrl = url;
+ return;
+ }
+ previousUrl = url;
+
+ // fire a state-change event on the app-router and return early if the user called event.preventDefault()
+ var eventDetail = {
+ path: url.path
+ };
+ if (!fire('state-change', eventDetail, router)) {
+ return;
+ }
+
+ // find the first matching route
+ var route = router.firstElementChild;
+ while (route) {
+ if (route.tagName === 'APP-ROUTE' && utilities.testRoute(route.getAttribute('path'), url.path, router.getAttribute('trailingSlash'), route.hasAttribute('regex'))) {
+ activateRoute(router, route, url);
+ return;
+ }
+ route = route.nextSibling;
+ }
+
+ fire('not-found', eventDetail, router);
+ }
+
+ // Activate the route
+ function activateRoute(router, route, url) {
+ if (route.hasAttribute('redirect')) {
+ router.go(route.getAttribute('redirect'), {replace: true});
+ return;
+ }
+
+ // if we're on the same route and `onUrlChange="noop"` then don't reload the route or update the model
+ if (route === router.activeRoute && route.getAttribute('onUrlChange') === 'noop') {
+ return;
+ }
+
+ var eventDetail = {
+ path: url.path,
+ route: route,
+ oldRoute: router.activeRoute
+ };
+ if (!fire('activate-route-start', eventDetail, router)) {
+ return;
+ }
+ if (!fire('activate-route-start', eventDetail, route)) {
+ return;
+ }
+
+ // keep track of the route currently being loaded
+ router.loadingRoute = route;
+
+ // if we're on the same route and `onUrlChange="updateModel"` then update the model but don't replace the page content
+ if (route === router.activeRoute && route.getAttribute('onUrlChange') === 'updateModel') {
+ updateModelAndActivate(router, route, url, eventDetail);
+ }
+ // import custom element or template
+ else if (route.hasAttribute('import')) {
+ importAndActivate(router, route.getAttribute('import'), route, url, eventDetail);
+ }
+ // pre-loaded custom element
+ else if (route.hasAttribute('element')) {
+ activateCustomElement(router, route.getAttribute('element'), route, url, eventDetail);
+ }
+ // inline template
+ else if (route.firstElementChild && route.firstElementChild.tagName === 'TEMPLATE') {
+ // mark the route as an inline template so we know how to clean it up when we remove the route's content
+ route.isInlineTemplate = true;
+ activateTemplate(router, route.firstElementChild, route, url, eventDetail);
+ }
+ }
+
+ // If we are only hiding and showing the route, update the model and activate the route
+ function updateModelAndActivate(router, route, url, eventDetail) {
+ var model = createModel(router, route, url, eventDetail);
+
+ if (route.hasAttribute('template') || route.isInlineTemplate) {
+ // update the template model
+ setObjectProperties(route.lastElementChild.templateInstance.model, model);
+ } else {
+ // update the custom element model
+ setObjectProperties(route.firstElementChild, model);
+ }
+
+ fire('activate-route-end', eventDetail, router);
+ fire('activate-route-end', eventDetail, eventDetail.route);
+ }
+
+ // Import and activate a custom element or template
+ function importAndActivate(router, importUri, route, url, eventDetail) {
+ var importLink;
+ function importLoadedCallback() {
+ importLink.loaded = true;
+ activateImport(router, importLink, importUri, route, url, eventDetail);
+ }
+
+ if (!importedURIs.hasOwnProperty(importUri)) {
+ // hasn't been imported yet
+ importLink = document.createElement('link');
+ importLink.setAttribute('rel', 'import');
+ importLink.setAttribute('href', importUri);
+ importLink.setAttribute('async', 'async');
+ importLink.addEventListener('load', importLoadedCallback);
+ importLink.loaded = false;
+ document.head.appendChild(importLink);
+ importedURIs[importUri] = importLink;
+ } else {
+ // previously imported. this is an async operation and may not be complete yet.
+ importLink = importedURIs[importUri];
+ if (!importLink.loaded) {
+ importLink.addEventListener('load', importLoadedCallback);
+ } else {
+ activateImport(router, importLink, importUri, route, url, eventDetail);
+ }
+ }
+ }
+
+ // Activate the imported custom element or template
+ function activateImport(router, importLink, importUri, route, url, eventDetail) {
+ // allow referencing the route's import link in the activate-route-end callback
+ route.importLink = importLink;
+
+ // make sure the user didn't navigate to a different route while it loaded
+ if (route === router.loadingRoute) {
+ if (route.hasAttribute('template')) {
+ // template
+ var templateId = route.getAttribute('template');
+ var template;
+ if (templateId) {
+ template = importLink.import.getElementById(templateId);
+ } else {
+ template = importLink.import.querySelector('template');
+ }
+ activateTemplate(router, template, route, url, eventDetail);
+ } else {
+ // custom element
+ activateCustomElement(router, route.getAttribute('element') || importUri.split('/').slice(-1)[0].replace('.html', ''), route, url, eventDetail);
+ }
+ }
+ }
+
+ // Data bind the custom element then activate it
+ function activateCustomElement(router, elementName, route, url, eventDetail) {
+ var customElement = document.createElement(elementName);
+ var model = createModel(router, route, url, eventDetail);
+ setObjectProperties(customElement, model);
+ activateElement(router, customElement, url, eventDetail);
+ }
+
+ // Create an instance of the template
+ function activateTemplate(router, template, route, url, eventDetail) {
+ var templateInstance;
+ if ('createInstance' in template) {
+ // template.createInstance(model) is a Polymer method that binds a model to a template and also fixes
+ // https://github.com/erikringsmuth/app-router/issues/19
+ var model = createModel(router, route, url, eventDetail);
+ templateInstance = template.createInstance(model);
+ } else {
+ templateInstance = document.importNode(template.content, true);
+ }
+ activateElement(router, templateInstance, url, eventDetail);
+ }
+
+ // Create the route's model
+ function createModel(router, route, url, eventDetail) {
+ var model = utilities.routeArguments(route.getAttribute('path'), url.path, url.search, route.hasAttribute('regex'), router.getAttribute('typecast') === 'auto');
+ if (route.hasAttribute('bindRouter') || router.hasAttribute('bindRouter')) {
+ model.router = router;
+ }
+ eventDetail.model = model;
+ fire('before-data-binding', eventDetail, router);
+ fire('before-data-binding', eventDetail, eventDetail.route);
+ return eventDetail.model;
+ }
+
+ // Copy properties from one object to another
+ function setObjectProperties(object, model) {
+ for (var property in model) {
+ if (model.hasOwnProperty(property)) {
+ object[property] = model[property];
+ }
+ }
+ }
+
+ // Replace the active route's content with the new element
+ function activateElement(router, element, url, eventDetail) {
+ // when using core-animated-pages, the router doesn't remove the previousRoute's content right away. if you
+ // navigate between 3 routes quickly (ex: /a -> /b -> /c) you might set previousRoute to '/b' before '/a' is
+ // removed from the DOM. this verifies old content is removed before switching the reference to previousRoute.
+ deactivateRoute(router.previousRoute);
+
+ // update references to the activeRoute, previousRoute, and loadingRoute
+ router.previousRoute = router.activeRoute;
+ router.activeRoute = router.loadingRoute;
+ router.loadingRoute = null;
+ if (router.previousRoute) {
+ router.previousRoute.removeAttribute('active');
+ }
+ router.activeRoute.setAttribute('active', 'active');
+
+ // remove the old route's content before loading the new route. core-animated-pages temporarily needs the old and
+ // new route in the DOM at the same time to animate the transition, otherwise we can remove the old route's content
+ // right away. there is one exception for core-animated-pages where the route we're navigating to matches the same
+ // route (ex: path="/article/:id" navigating from /article/0 to /article/1). in this case we have to simply replace
+ // the route's content instead of animating a transition.
+ if (!router.hasAttribute('core-animated-pages') || eventDetail.route === eventDetail.oldRoute) {
+ deactivateRoute(router.previousRoute);
+ }
+
+ // add the new content
+ router.activeRoute.appendChild(element);
+
+ // animate the transition if core-animated-pages are being used
+ if (router.hasAttribute('core-animated-pages')) {
+ router.coreAnimatedPages.selected = router.activeRoute.getAttribute('path');
+ // the 'core-animated-pages-transition-end' event handler in init() will call deactivateRoute() on the previousRoute
+ }
+
+ // scroll to the URL hash if it's present
+ if (url.hash && !router.hasAttribute('core-animated-pages')) {
+ scrollToHash(url.hash);
+ }
+
+ fire('activate-route-end', eventDetail, router);
+ fire('activate-route-end', eventDetail, eventDetail.route);
+ }
+
+ // Remove the route's content
+ function deactivateRoute(route) {
+ if (route) {
+ // remove the route content
+ var node = route.firstChild;
+
+ // don't remove an inline <template>
+ if (route.isInlineTemplate) {
+ node = route.querySelector('template').nextSibling;
+ }
+
+ while (node) {
+ var nodeToRemove = node;
+ node = node.nextSibling;
+ route.removeChild(nodeToRemove);
+ }
+ }
+ }
+
+ // scroll to the element with id="hash" or name="hash"
+ function scrollToHash(hash) {
+ if (!hash) return;
+
+ // wait for the browser's scrolling to finish before we scroll to the hash
+ // ex: http://example.com/#/page1#middle
+ // the browser will scroll to an element with id or name `/page1#middle` when the page finishes loading. if it doesn't exist
+ // it will scroll to the top of the page. let the browser finish the current event loop and scroll to the top of the page
+ // before we scroll to the element with id or name `middle`.
+ setTimeout(function() {
+ var hashElement = document.querySelector('html /deep/ ' + hash) || document.querySelector('html /deep/ [name="' + hash.substring(1) + '"]');
+ if (hashElement && hashElement.scrollIntoView) {
+ hashElement.scrollIntoView(true);
+ }
+ }, 0);
+ }
+
+ // parseUrl(location, mode) - Augment the native URL() constructor to get info about hash paths
+ //
+ // Example parseUrl('http://domain.com/other/path?queryParam3=false#/example/path?queryParam1=true&queryParam2=example%20string#middle', 'auto')
+ //
+ // returns {
+ // path: '/example/path',
+ // hash: '#middle'
+ // search: '?queryParam1=true&queryParam2=example%20string',
+ // isHashPath: true
+ // }
+ //
+ // Note: The location must be a fully qualified URL with a protocol like 'http(s)://'
+ utilities.parseUrl = function(location, mode) {
+ var url = {
+ isHashPath: mode === 'hash'
+ };
+
+ if (typeof URL === 'function') {
+ // browsers that support `new URL()`
+ var nativeUrl = new URL(location);
+ url.path = nativeUrl.pathname;
+ url.hash = nativeUrl.hash;
+ url.search = nativeUrl.search;
+ } else {
+ // IE
+ var anchor = document.createElement('a');
+ anchor.href = location;
+ url.path = anchor.pathname;
+ if (url.path.charAt(0) !== '/') {
+ url.path = '/' + url.path;
+ }
+ url.hash = anchor.hash;
+ url.search = anchor.search;
+ }
+
+ if (mode !== 'pushstate') {
+ // auto or hash
+
+ // check for a hash path
+ if (url.hash.substring(0, 2) === '#/') {
+ // hash path
+ url.isHashPath = true;
+ url.path = url.hash.substring(1);
+ } else if (url.hash.substring(0, 3) === '#!/') {
+ // hashbang path
+ url.isHashPath = true;
+ url.path = url.hash.substring(2);
+ } else if (url.isHashPath) {
+ // still use the hash if mode="hash"
+ if (url.hash.length === 0) {
+ url.path = '/';
+ } else {
+ url.path = url.hash.substring(1);
+ }
+ }
+
+ if (url.isHashPath) {
+ url.hash = '';
+
+ // hash paths might have an additional hash in the hash path for scrolling to a specific part of the page #/hash/path#elementId
+ var secondHashIndex = url.path.indexOf('#');
+ if (secondHashIndex !== -1) {
+ url.hash = url.path.substring(secondHashIndex);
+ url.path = url.path.substring(0, secondHashIndex);
+ }
+
+ // hash paths get the search from the hash if it exists
+ var searchIndex = url.path.indexOf('?');
+ if (searchIndex !== -1) {
+ url.search = url.path.substring(searchIndex);
+ url.path = url.path.substring(0, searchIndex);
+ }
+ }
+ }
+
+ return url;
+ };
+
+ // testRoute(routePath, urlPath, trailingSlashOption, isRegExp) - Test if the route's path matches the URL's path
+ //
+ // Example routePath: '/user/:userId/**'
+ // Example urlPath = '/user/123/bio'
+ utilities.testRoute = function(routePath, urlPath, trailingSlashOption, isRegExp) {
+ // try to fail or succeed as quickly as possible for the most common cases
+
+ // handle trailing slashes (options: strict (default), ignore)
+ if (trailingSlashOption === 'ignore') {
+ // remove trailing / from the route path and URL path
+ if(urlPath.slice(-1) === '/') {
+ urlPath = urlPath.slice(0, -1);
+ }
+ if(routePath.slice(-1) === '/' && !isRegExp) {
+ routePath = routePath.slice(0, -1);
+ }
+ }
+
+ // test regular expressions
+ if (isRegExp) {
+ return utilities.testRegExString(routePath, urlPath);
+ }
+
+ // if the urlPath is an exact match or '*' then the route is a match
+ if (routePath === urlPath || routePath === '*') {
+ return true;
+ }
+
+ // relative routes a/b/c are the same as routes that start with a globstar /**/a/b/c
+ if (routePath.charAt(0) !== '/') {
+ routePath = '/**/' + routePath;
+ }
+
+ // recursively test if the segments match (start at 1 because 0 is always an empty string)
+ return segmentsMatch(routePath.split('/'), 1, urlPath.split('/'), 1)
+ };
+
+ // segmentsMatch(routeSegments, routeIndex, urlSegments, urlIndex, pathVariables)
+ // recursively test the route segments against the url segments in place (without creating copies of the arrays
+ // for each recursive call)
+ //
+ // example routeSegments ['', 'user', ':userId', '**']
+ // example urlSegments ['', 'user', '123', 'bio']
+ function segmentsMatch(routeSegments, routeIndex, urlSegments, urlIndex, pathVariables) {
+ var routeSegment = routeSegments[routeIndex];
+ var urlSegment = urlSegments[urlIndex];
+
+ // if we're at the last route segment and it is a globstar, it will match the rest of the url
+ if (routeSegment === '**' && routeIndex === routeSegments.length - 1) {
+ return true;
+ }
+
+ // we hit the end of the route segments or the url segments
+ if (typeof routeSegment === 'undefined' || typeof urlSegment === 'undefined') {
+ // return true if we hit the end of both at the same time meaning everything else matched, else return false
+ return routeSegment === urlSegment;
+ }
+
+ // if the current segments match, recursively test the remaining segments
+ if (routeSegment === urlSegment || routeSegment === '*' || routeSegment.charAt(0) === ':') {
+ // store the path variable if we have a pathVariables object
+ if (routeSegment.charAt(0) === ':' && typeof pathVariables !== 'undefined') {
+ pathVariables[routeSegment.substring(1)] = urlSegments[urlIndex];
+ }
+ return segmentsMatch(routeSegments, routeIndex + 1, urlSegments, urlIndex + 1, pathVariables);
+ }
+
+ // globstars can match zero to many URL segments
+ if (routeSegment === '**') {
+ // test if the remaining route segments match any combination of the remaining url segments
+ for (var i = urlIndex; i < urlSegments.length; i++) {
+ if (segmentsMatch(routeSegments, routeIndex + 1, urlSegments, i, pathVariables)) {
+ return true;
+ }
+ }
+ }
+
+ // all tests failed, the route segments do not match the url segments
+ return false;
+ }
+
+ // routeArguments(routePath, urlPath, search, isRegExp) - Gets the path variables and query parameter values from the URL
+ utilities.routeArguments = function(routePath, urlPath, search, isRegExp, typecast) {
+ var args = {};
+
+ // regular expressions can't have path variables
+ if (!isRegExp) {
+ // relative routes a/b/c are the same as routes that start with a globstar /**/a/b/c
+ if (routePath.charAt(0) !== '/') {
+ routePath = '/**/' + routePath;
+ }
+
+ // get path variables
+ // urlPath '/customer/123'
+ // routePath '/customer/:id'
+ // parses id = '123'
+ segmentsMatch(routePath.split('/'), 1, urlPath.split('/'), 1, args);
+ }
+
+ var queryParameters = search.substring(1).split('&');
+ // split() on an empty string has a strange behavior of returning [''] instead of []
+ if (queryParameters.length === 1 && queryParameters[0] === '') {
+ queryParameters = [];
+ }
+ for (var i = 0; i < queryParameters.length; i++) {
+ var queryParameter = queryParameters[i];
+ var queryParameterParts = queryParameter.split('=');
+ args[queryParameterParts[0]] = queryParameterParts.splice(1, queryParameterParts.length - 1).join('=');
+ }
+
+ if (typecast) {
+ // parse the arguments into unescaped strings, numbers, or booleans
+ for (var arg in args) {
+ args[arg] = utilities.typecast(args[arg]);
+ }
+ }
+
+ return args;
+ };
+
+ // typecast(value) - Typecast the string value to an unescaped string, number, or boolean
+ utilities.typecast = function(value) {
+ // bool
+ if (value === 'true') {
+ return true;
+ }
+ if (value === 'false') {
+ return false;
+ }
+
+ // number
+ if (!isNaN(value) && value !== '' && value.charAt(0) !== '0') {
+ return +value;
+ }
+
+ // string
+ return decodeURIComponent(value);
+ };
+
+ // testRegExString(pattern, value) - Parse HTML attribute path="/^\/\w+\/\d+$/i" to a regular
+ // expression `new RegExp('^\/\w+\/\d+$', 'i')` and test against it.
+ //
+ // note that 'i' is the only valid option. global 'g', multiline 'm', and sticky 'y' won't be valid matchers for a path.
+ utilities.testRegExString = function(pattern, value) {
+ if (pattern.charAt(0) !== '/') {
+ // must start with a slash
+ return false;
+ }
+ pattern = pattern.slice(1);
+ var options = '';
+ if (pattern.slice(-1) === '/') {
+ pattern = pattern.slice(0, -1);
+ }
+ else if (pattern.slice(-2) === '/i') {
+ pattern = pattern.slice(0, -2);
+ options = 'i';
+ }
+ else {
+ // must end with a slash followed by zero or more options
+ return false;
+ }
+ return new RegExp(pattern, options).test(value);
+ };
+
+ document.registerElement('app-router', {
+ prototype: AppRouter
+ });
+
+})(window, document);
diff --git a/polymer_1.0.4/bower_components/cors-upload-sample/.bower.json b/polymer_1.0.4/bower_components/cors-upload-sample/.bower.json
new file mode 100644
index 0000000..5a80cde
--- /dev/null
+++ b/polymer_1.0.4/bower_components/cors-upload-sample/.bower.json
@@ -0,0 +1,13 @@
+{
+ "name": "cors-upload-sample",
+ "homepage": "https://github.com/googledrive/cors-upload-sample",
+ "_release": "a8c9d0b144",
+ "_resolution": {
+ "type": "branch",
+ "branch": "master",
+ "commit": "a8c9d0b144fde34d414ee80c2e70dd312c8aa8b3"
+ },
+ "_source": "git://github.com/googledrive/cors-upload-sample.git",
+ "_target": "master",
+ "_originalSource": "googledrive/cors-upload-sample"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/cors-upload-sample/LICENSE b/polymer_1.0.4/bower_components/cors-upload-sample/LICENSE
new file mode 100644
index 0000000..37ec93a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/cors-upload-sample/LICENSE
@@ -0,0 +1,191 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities
+that control, are controlled by, or are under common control with that entity.
+For the purposes of this definition, "control" means (i) the power, direct or
+indirect, to cause the direction or management of such entity, whether by
+contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
+outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+"Object" form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included
+in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative Works
+shall not include works that remain separable from, or merely link (or bind by
+name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version
+of the Work and any modifications or additions to that Work or Derivative Works
+thereof, that is intentionally submitted to Licensor for inclusion in the Work
+by the copyright owner or by an individual or Legal Entity authorized to submit
+on behalf of the copyright owner. For the purposes of this definition,
+"submitted" means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for
+the purpose of discussing and improving the Work, but excluding communication
+that is conspicuously marked or otherwise designated in writing by the copyright
+owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+2. Grant of Copyright License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.
+
+3. Grant of Patent License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable (except as stated in this section) patent license to make, have
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where
+such license applies only to those patent claims licensable by such Contributor
+that are necessarily infringed by their Contribution(s) alone or by combination
+of their Contribution(s) with the Work to which such Contribution(s) was
+submitted. If You institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work or a
+Contribution incorporated within the Work constitutes direct or contributory
+patent infringement, then any patent licenses granted to You under this License
+for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution.
+
+You may reproduce and distribute copies of the Work or Derivative Works thereof
+in any medium, with or without modifications, and in Source or Object form,
+provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of
+this License; and
+You must cause any modified files to carry prominent notices stating that You
+changed the files; and
+You must retain, in the Source form of any Derivative Works that You distribute,
+all copyright, patent, trademark, and attribution notices from the Source form
+of the Work, excluding those notices that do not pertain to any part of the
+Derivative Works; and
+If the Work includes a "NOTICE" text file as part of its distribution, then any
+Derivative Works that You distribute must include a readable copy of the
+attribution notices contained within such NOTICE file, excluding those notices
+that do not pertain to any part of the Derivative Works, in at least one of the
+following places: within a NOTICE text file distributed as part of the
+Derivative Works; within the Source form or documentation, if provided along
+with the Derivative Works; or, within a display generated by the Derivative
+Works, if and wherever such third-party notices normally appear. The contents of
+the NOTICE file are for informational purposes only and do not modify the
+License. You may add Your own attribution notices within Derivative Works that
+You distribute, alongside or as an addendum to the NOTICE text from the Work,
+provided that such additional attribution notices cannot be construed as
+modifying the License.
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies
+with the conditions stated in this License.
+
+5. Submission of Contributions.
+
+Unless You explicitly state otherwise, any Contribution intentionally submitted
+for inclusion in the Work by You to the Licensor shall be under the terms and
+conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the terms of
+any separate license agreement you may have executed with Licensor regarding
+such Contributions.
+
+6. Trademarks.
+
+This License does not grant permission to use the trade names, trademarks,
+service marks, or product names of the Licensor, except as required for
+reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty.
+
+Unless required by applicable law or agreed to in writing, Licensor provides the
+Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+including, without limitation, any warranties or conditions of TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
+solely responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your exercise of
+permissions under this License.
+
+8. Limitation of Liability.
+
+In no event and under no legal theory, whether in tort (including negligence),
+contract, or otherwise, unless required by applicable law (such as deliberate
+and grossly negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License or
+out of the use or inability to use the Work (including but not limited to
+damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+any and all other commercial damages or losses), even if such Contributor has
+been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability.
+
+While redistributing the Work or Derivative Works thereof, You may choose to
+offer, and charge a fee for, acceptance of support, warranty, indemnity, or
+other liability obligations and/or rights consistent with this License. However,
+in accepting such obligations, You may act only on Your own behalf and on Your
+sole responsibility, not on behalf of any other Contributor, and only if You
+agree to indemnify, defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason of your
+accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work
+
+To apply the Apache License to your work, attach the following boilerplate
+notice, with the fields enclosed by brackets "[]" replaced with your own
+identifying information. (Don't include the brackets!) The text should be
+enclosed in the appropriate comment syntax for the file format. We also
+recommend that a file or class name and description of purpose be included on
+the same "printed page" as the copyright notice for easier identification within
+third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/polymer_1.0.4/bower_components/cors-upload-sample/README.md b/polymer_1.0.4/bower_components/cors-upload-sample/README.md
new file mode 100644
index 0000000..db14e64
--- /dev/null
+++ b/polymer_1.0.4/bower_components/cors-upload-sample/README.md
@@ -0,0 +1,24 @@
+# cors-upload-sample
+
+Sample code for uploading files directly with vanilla Javascript (XHR/CORS). Try the [live version](http://googledrive.github.io/cors-upload-sample)
+and drag & drop files to upload them to Google Drive.
+
+This sample has only been tested with Chrome. Other browsers may or may not work.
+
+## Usage
+
+If you'd like to use the code in your own project, copy `upload.js` and include it.
+
+ <script src="/path/to/upload.js"></script>
+
+When uploading a file, create a new MediaUploader initialized with a Blob or File and access token. Then call `upload()` to start the upload process.
+
+ var uploader = new MediaUploader({
+ file: content,
+ token: accessToken,
+ });
+ uploader.upload();
+
+Your access token need to be authorized for any of the Drive scopes that permit writes (drive, drive.file, or drive.appdata.) You can go through [one of the OAuth 2.0 flows](https://developers.google.com/accounts/docs/OAuth2) to retrieve one or use [Google+ Sign-In](https://developers.google.com/+/web/signin/) button.
+
+See `upload.js` for additional parameters you can include when initializing the uploader, including callbacks for success & failure events.
diff --git a/polymer_1.0.4/bower_components/cors-upload-sample/index.html b/polymer_1.0.4/bower_components/cors-upload-sample/index.html
new file mode 100644
index 0000000..dcfcd57
--- /dev/null
+++ b/polymer_1.0.4/bower_components/cors-upload-sample/index.html
@@ -0,0 +1,93 @@
+<html>
+ <head>
+ <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
+ <style>
+ #drop_zone {
+ border: 2px dashed #bbb;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ padding: 25px;
+ text-align: center;
+ font: 20pt bold 'Helvetica';
+ color: #bbb;
+ }
+ </style>
+ </head>
+ <body>
+ <span id="signin">
+ <span
+ class="g-signin"
+ data-callback="signinCallback"
+ data-clientid="692008307570.apps.googleusercontent.com"
+ data-cookiepolicy="single_host_origin"
+ data-scope="https://www.googleapis.com/auth/drive.file">
+ </span>
+ </span>
+
+ <div id="drop_zone" style="display:none;">Drop files here</div>
+
+ <div id="results"/>
+ <script src="upload.js"></script>
+ <script type="text/javascript">
+
+ var accessToken = null;
+
+ /**
+ * Callback for G+ Sign-in. Swaps views if login successful.
+ */
+ function signinCallback(result) {
+ if(result.access_token) {
+ accessToken = result.access_token;
+ document.getElementById('signin').style.display = 'none';
+ document.getElementById('drop_zone').style.display = null;
+ }
+ }
+
+ /**
+ * Called when files are dropped on to the drop target. For each file,
+ * uploads the content to Drive & displays the results when complete.
+ */
+ function handleFileSelect(evt) {
+ evt.stopPropagation();
+ evt.preventDefault();
+
+ var files = evt.dataTransfer.files; // FileList object.
+
+ var output = [];
+ for (var i = 0, f; f = files[i]; i++) {
+ var uploader = new MediaUploader({
+ file: f,
+ token: accessToken,
+ onComplete: function(data) {
+ var element = document.createElement("pre");
+ element.appendChild(document.createTextNode(data));
+ document.getElementById('results').appendChild(element);
+ }
+ });
+ uploader.upload();
+ }
+ }
+
+ /**
+ * Dragover handler to set the drop effect.
+ */
+ function handleDragOver(evt) {
+ evt.stopPropagation();
+ evt.preventDefault();
+ evt.dataTransfer.dropEffect = 'copy';
+ }
+
+ /**
+ * Wire up drag & drop listeners once page loads
+ */
+ document.addEventListener('DOMContentLoaded', function () {
+ var dropZone = document.getElementById('drop_zone');
+ dropZone.addEventListener('dragover', handleDragOver, false);
+ dropZone.addEventListener('drop', handleFileSelect, false);
+ });
+
+ </script>
+ <script src="https://apis.google.com/js/client:plusone.js"></script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/cors-upload-sample/upload.js b/polymer_1.0.4/bower_components/cors-upload-sample/upload.js
new file mode 100644
index 0000000..cc867a1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/cors-upload-sample/upload.js
@@ -0,0 +1,267 @@
+/**
+ * Helper for implementing retries with backoff. Initial retry
+ * delay is 1 second, increasing by 2x (+jitter) for subsequent retries
+ *
+ * @constructor
+ */
+var RetryHandler = function() {
+ this.interval = 1000; // Start at one second
+ this.maxInterval = 60 * 1000; // Don't wait longer than a minute
+};
+
+/**
+ * Invoke the function after waiting
+ *
+ * @param {function} fn Function to invoke
+ */
+RetryHandler.prototype.retry = function(fn) {
+ setTimeout(fn, this.interval);
+ this.interval = this.nextInterval_();
+};
+
+/**
+ * Reset the counter (e.g. after successful request.)
+ */
+RetryHandler.prototype.reset = function() {
+ this.interval = 1000;
+};
+
+/**
+ * Calculate the next wait time.
+ * @return {number} Next wait interval, in milliseconds
+ *
+ * @private
+ */
+RetryHandler.prototype.nextInterval_ = function() {
+ var interval = this.interval * 2 + this.getRandomInt_(0, 1000);
+ return Math.min(interval, this.maxInterval);
+};
+
+/**
+ * Get a random int in the range of min to max. Used to add jitter to wait times.
+ *
+ * @param {number} min Lower bounds
+ * @param {number} max Upper bounds
+ * @private
+ */
+RetryHandler.prototype.getRandomInt_ = function(min, max) {
+ return Math.floor(Math.random() * (max - min + 1) + min);
+};
+
+
+/**
+ * Helper class for resumable uploads using XHR/CORS. Can upload any Blob-like item, whether
+ * files or in-memory constructs.
+ *
+ * @example
+ * var content = new Blob(["Hello world"], {"type": "text/plain"});
+ * var uploader = new MediaUploader({
+ * file: content,
+ * token: accessToken,
+ * onComplete: function(data) { ... }
+ * onError: function(data) { ... }
+ * });
+ * uploader.upload();
+ *
+ * @constructor
+ * @param {object} options Hash of options
+ * @param {string} options.token Access token
+ * @param {blob} options.file Blob-like item to upload
+ * @param {string} [options.fileId] ID of file if replacing
+ * @param {object} [options.params] Additional query parameters
+ * @param {string} [options.contentType] Content-type, if overriding the type of the blob.
+ * @param {object} [options.metadata] File metadata
+ * @param {function} [options.onComplete] Callback for when upload is complete
+ * @param {function} [options.onProgress] Callback for status for the in-progress upload
+ * @param {function} [options.onError] Callback if upload fails
+ */
+var MediaUploader = function(options) {
+ var noop = function() {};
+ this.file = options.file;
+ this.contentType = options.contentType || this.file.type || 'application/octet-stream';
+ this.metadata = options.metadata || {
+ 'title': this.file.name,
+ 'mimeType': this.contentType
+ };
+ this.token = options.token;
+ this.onComplete = options.onComplete || noop;
+ this.onProgress = options.onProgress || noop;
+ this.onError = options.onError || noop;
+ this.offset = options.offset || 0;
+ this.chunkSize = options.chunkSize || 0;
+ this.retryHandler = new RetryHandler();
+
+ this.url = options.url;
+ if (!this.url) {
+ var params = options.params || {};
+ params.uploadType = 'resumable';
+ this.url = this.buildUrl_(options.fileId, params, options.baseUrl);
+ }
+ this.httpMethod = options.fileId ? 'PUT' : 'POST';
+};
+
+/**
+ * Initiate the upload.
+ */
+MediaUploader.prototype.upload = function() {
+ var self = this;
+ var xhr = new XMLHttpRequest();
+
+ xhr.open(this.httpMethod, this.url, true);
+ xhr.setRequestHeader('Authorization', 'Bearer ' + this.token);
+ xhr.setRequestHeader('Content-Type', 'application/json');
+ xhr.setRequestHeader('X-Upload-Content-Length', this.file.size);
+ xhr.setRequestHeader('X-Upload-Content-Type', this.contentType);
+
+ xhr.onload = function(e) {
+ if (e.target.status < 400) {
+ var location = e.target.getResponseHeader('Location');
+ this.url = location;
+ this.sendFile_();
+ } else {
+ this.onUploadError_(e);
+ }
+ }.bind(this);
+ xhr.onerror = this.onUploadError_.bind(this);
+ xhr.send(JSON.stringify(this.metadata));
+};
+
+/**
+ * Send the actual file content.
+ *
+ * @private
+ */
+MediaUploader.prototype.sendFile_ = function() {
+ var content = this.file;
+ var end = this.file.size;
+
+ if (this.offset || this.chunkSize) {
+ // Only bother to slice the file if we're either resuming or uploading in chunks
+ if (this.chunkSize) {
+ end = Math.min(this.offset + this.chunkSize, this.file.size);
+ }
+ content = content.slice(this.offset, end);
+ }
+
+ var xhr = new XMLHttpRequest();
+ xhr.open('PUT', this.url, true);
+ xhr.setRequestHeader('Content-Type', this.contentType);
+ xhr.setRequestHeader('Content-Range', "bytes " + this.offset + "-" + (end - 1) + "/" + this.file.size);
+ xhr.setRequestHeader('X-Upload-Content-Type', this.file.type);
+ if (xhr.upload) {
+ xhr.upload.addEventListener('progress', this.onProgress);
+ }
+ xhr.onload = this.onContentUploadSuccess_.bind(this);
+ xhr.onerror = this.onContentUploadError_.bind(this);
+ xhr.send(content);
+};
+
+/**
+ * Query for the state of the file for resumption.
+ *
+ * @private
+ */
+MediaUploader.prototype.resume_ = function() {
+ var xhr = new XMLHttpRequest();
+ xhr.open('PUT', this.url, true);
+ xhr.setRequestHeader('Content-Range', "bytes */" + this.file.size);
+ xhr.setRequestHeader('X-Upload-Content-Type', this.file.type);
+ if (xhr.upload) {
+ xhr.upload.addEventListener('progress', this.onProgress);
+ }
+ xhr.onload = this.onContentUploadSuccess_.bind(this);
+ xhr.onerror = this.onContentUploadError_.bind(this);
+ xhr.send();
+};
+
+/**
+ * Extract the last saved range if available in the request.
+ *
+ * @param {XMLHttpRequest} xhr Request object
+ */
+MediaUploader.prototype.extractRange_ = function(xhr) {
+ var range = xhr.getResponseHeader('Range');
+ if (range) {
+ this.offset = parseInt(range.match(/\d+/g).pop(), 10) + 1;
+ }
+};
+
+/**
+ * Handle successful responses for uploads. Depending on the context,
+ * may continue with uploading the next chunk of the file or, if complete,
+ * invokes the caller's callback.
+ *
+ * @private
+ * @param {object} e XHR event
+ */
+MediaUploader.prototype.onContentUploadSuccess_ = function(e) {
+ if (e.target.status == 200 || e.target.status == 201) {
+ this.onComplete(e.target.response);
+ } else if (e.target.status == 308) {
+ this.extractRange_(e.target);
+ this.retryHandler.reset();
+ this.sendFile_();
+ }
+};
+
+/**
+ * Handles errors for uploads. Either retries or aborts depending
+ * on the error.
+ *
+ * @private
+ * @param {object} e XHR event
+ */
+MediaUploader.prototype.onContentUploadError_ = function(e) {
+ if (e.target.status && e.target.status < 500) {
+ this.onError(e.target.response);
+ } else {
+ this.retryHandler.retry(this.resume_.bind(this));
+ }
+};
+
+/**
+ * Handles errors for the initial request.
+ *
+ * @private
+ * @param {object} e XHR event
+ */
+MediaUploader.prototype.onUploadError_ = function(e) {
+ this.onError(e.target.response); // TODO - Retries for initial upload
+};
+
+/**
+ * Construct a query string from a hash/object
+ *
+ * @private
+ * @param {object} [params] Key/value pairs for query string
+ * @return {string} query string
+ */
+MediaUploader.prototype.buildQuery_ = function(params) {
+ params = params || {};
+ return Object.keys(params).map(function(key) {
+ return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
+ }).join('&');
+};
+
+/**
+ * Build the drive upload URL
+ *
+ * @private
+ * @param {string} [id] File ID if replacing
+ * @param {object} [params] Query parameters
+ * @return {string} URL
+ */
+MediaUploader.prototype.buildUrl_ = function(id, params, baseUrl) {
+ var url = baseUrl || 'https://www.googleapis.com/upload/drive/v2/files/';
+ if (id) {
+ url += id;
+ }
+ var query = this.buildQuery_(params);
+ if (query) {
+ url += '?' + query;
+ }
+ return url;
+};
+
+
+
diff --git a/polymer_1.0.4/bower_components/firebase-element/.bower.json b/polymer_1.0.4/bower_components/firebase-element/.bower.json
new file mode 100644
index 0000000..22e741b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/.bower.json
@@ -0,0 +1,33 @@
+{
+ "name": "firebase-element",
+ "version": "1.0.1",
+ "private": true,
+ "main": [
+ "firebase-collection.html",
+ "firebase-document.html",
+ "firebase-auth.html",
+ "firebase-query-behavior.html"
+ ],
+ "dependencies": {
+ "polymer": "polymer/polymer#^1.0.0",
+ "firebase": "^2.2.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#1.0.2",
+ "promise-polyfill": "polymerlabs/promise-polyfill#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "web-component-tester": "*"
+ },
+ "homepage": "https://github.com/GoogleWebComponents/firebase-element",
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "46ec824cff5f62fbd8768c62f936f66c2c7f047e"
+ },
+ "_source": "git://github.com/GoogleWebComponents/firebase-element.git",
+ "_target": "^1.0.0",
+ "_originalSource": "GoogleWebComponents/firebase-element"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/firebase-element/.gitignore b/polymer_1.0.4/bower_components/firebase-element/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/firebase-element/README.md b/polymer_1.0.4/bower_components/firebase-element/README.md
new file mode 100644
index 0000000..53a2f65
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/README.md
@@ -0,0 +1,14 @@
+firebase-element
+================
+
+See the [component page](http://polymerelements.github.io/firebase-element) for more information.
+
+firebase.html
+=============
+
+Import files are a new invention, so libraries like [`firebase`](http://firebase.com) do not yet provide them.
+
+`firebase.html` is an intermediary that provides an import file for the `firebase` component. `firebase.html` depends on `firebase`.
+
+Components that want to use `firebase` should depend on `firebase-element` and import `firebase.html` to be safe from library duplication.
+Such components need not use Polymer or `firebase-element`, but we put the import and the element in one package for convenience.
diff --git a/polymer_1.0.4/bower_components/firebase-element/bower.json b/polymer_1.0.4/bower_components/firebase-element/bower.json
new file mode 100644
index 0000000..da21b1a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/bower.json
@@ -0,0 +1,18 @@
+{
+ "name": "firebase-element",
+ "version": "1.0.1",
+ "private": true,
+ "main": ["firebase-collection.html","firebase-document.html","firebase-auth.html","firebase-query-behavior.html"],
+ "dependencies": {
+ "polymer": "polymer/polymer#^1.0.0",
+ "firebase": "^2.2.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#1.0.2",
+ "promise-polyfill": "polymerlabs/promise-polyfill#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "web-component-tester": "*"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/firebase-element/demo/index.html b/polymer_1.0.4/bower_components/firebase-element/demo/index.html
new file mode 100644
index 0000000..28c6c75
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/demo/index.html
@@ -0,0 +1,60 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>Firebase Element Demos</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../firebase-collection.html">
+ <link rel="import" href="../firebase-document.html">
+ <link rel="import" href="x-pretty-json.html">
+ <link rel="import" href="x-login.html">
+</head>
+<body>
+ <div class="horizontal center-justified layout">
+ <div class="vertical-section">
+ <h3>Dinosaurs by Height</h3>
+ <template is="dom-bind">
+ <firebase-collection
+ order-by-child="height"
+ location="https://dinosaur-facts.firebaseio.com/dinosaurs"
+ data="{{dinosaurs}}"></firebase-collection>
+ <template is="dom-repeat" items="[[dinosaurs]]" as="dinosaur">
+ <h4>[[dinosaur.__firebaseKey__]]</h4>
+ <span>Height: </span><span>[[dinosaur.height]]</span><span>m</span>
+ </template>
+ </template>
+ </div>
+ <div class="vertical-section">
+ <h3>Dinosaur Scores Document</h3>
+ <template is="dom-bind">
+ <firebase-document
+ location="https://dinosaur-facts.firebaseio.com/scores"
+ data="{{dinosaurs}}"></firebase-document>
+ <x-pretty-json object=[[dinosaurs]]></x-pretty-json>
+ </template>
+ </div>
+
+ <div class="vertical-section">
+ <h3>Authentication Example</h3>
+ <x-login></x-login>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/firebase-element/demo/x-login.html b/polymer_1.0.4/bower_components/firebase-element/demo/x-login.html
new file mode 100644
index 0000000..6b5455b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/demo/x-login.html
@@ -0,0 +1,180 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../firebase-auth.html">
+<dom-module id="x-login">
+ <template>
+ <firebase-auth id="firebaseLogin" user="{{user}}" status-known="{{statusKnown}}" location="https://polymer-tests.firebaseio.com" provider="{{provider}}" on-error="errorHandler" on-user-created="userSuccessHandler" on-password-changed="userSuccessHandler" on-password-reset="userSuccessHandler" on-user-removed="userSuccessHandler"></firebase-auth>
+
+ Firebase location:
+ <input value="https://polymer-tests.firebaseio.com" size="40" disabled>
+ <br>
+
+ Provider type:
+ <select value="{{provider::change}}">
+ <option>anonymous</option>
+ <option>facebook</option>
+ <option>github</option>
+ <option>google</option>
+ <option>twitter</option>
+ <option>password</option>
+ </select>
+ <em>Only 'anonymous', 'google', and 'password' are activated for demo Firebase account</em>
+ <br>
+
+ Login params (JSON):
+ <input value="{{params::input}}" id="params">
+ <em>Required by some provider types</em>
+ <br>
+
+ <div hidden$="{{computePasswordHidden(provider)}}">
+ <br><em>Password-specific options:</em><br>
+ <input placeholder="email" value="{{email::input}}">
+ <input placeholder="password" value="{{password::input}}">
+ <button on-tap="createUserHandler" disabled$="{{computeCreateUserDisabled(email, password)}}">Create user</button>
+ <br>
+ <input placeholder="new password" value="{{newPassword::input}}">
+ <button on-tap="changePasswordHandler" disabled$="{{computeChangePasswordDisabled(email, password, newPassword)}}">Change password</button>
+ <br>
+ <button on-tap="resetPasswordHandler" disabled$="{{computeResetPasswordDisabled(email, password)}}">Reset password</button>
+ <button on-tap="removeUserHandler" disabled$="{{computeRemoveUserDisabled(email, password)}}">Remove user</button>
+ </div>
+ <br>
+ <div id="message">[[message]]</div>
+ <br>
+
+ <button on-tap="login" hidden$="{{computeLoginHidden(statusKnown, user)}}">Login</button>
+ <button on-tap="logout" hidden$="{{computeLogoutHidden(statusKnown, user)}}">Logout</button>
+
+ <h3>Login status:</h3>
+ <p>{{computeLoginStatus(statusKnown, user)}}</p>
+
+ <h3>User ID:</h3>
+ <pre>{{user.uid}}</pre>
+ </template>
+</dom-module>
+<script>
+ Polymer({
+ is: 'x-login',
+
+ properties: {
+ provider: {
+ type: String,
+ value: 'anonymous'
+ },
+
+ message: {
+ type: String,
+ value: ''
+ },
+
+ email: {
+ type: String,
+ value: ''
+ },
+
+ password: {
+ type: String,
+ value: ''
+ },
+
+ user: {
+ type: Object,
+ value: null
+ },
+
+ statusKnown: {
+ type: Boolean
+ }
+ },
+
+ login: function() {
+ var params;
+
+ try {
+ params = JSON.parse(this.params);
+ } catch (e) {
+ params = null;
+ }
+
+ if (this.provider == 'password') {
+ params = params || {};
+ params.email = this.email;
+ params.password = this.password;
+ }
+
+ this.$.firebaseLogin.login(params);
+ },
+
+ logout: function() {
+ this.$.firebaseLogin.logout();
+ },
+
+ errorHandler: function(e) {
+ this.message = 'Error: ' + e.detail.message;
+ },
+
+ userSuccessHandler: function(e) {
+ this.message = e.type + ' success!';
+ },
+
+ createUserHandler: function(e) {
+ this.$.firebaseLogin.createUser(this.email, this.password);
+ },
+
+ changePasswordHandler: function(e) {
+ this.$.firebaseLogin.changePassword(this.email, this.password, this.newPassword);
+ },
+
+ resetPasswordHandler: function(e) {
+ this.$.firebaseLogin.sendPasswordResetEmail(this.email);
+ },
+
+ computePasswordHidden: function(provider) {
+ return provider !== 'password';
+ },
+
+ computeCreateUserDisabled: function(email, password) {
+ return !email || !password;
+ },
+
+ computeChangePasswordDisabled: function(email, password, newPassword) {
+ return !email || !password || !newPassword;
+ },
+
+ computeResetPasswordDisabled: function(email, password) {
+ return !email || !password;
+ },
+
+ computeRemoveUserDisabled: function(email, password) {
+ return !email || !password;
+ },
+
+ computeLoginHidden: function(statusKnown, user) {
+ return !statusKnown || !!user;
+ },
+
+ computeLogoutHidden: function(statusKnown, user) {
+ return !statusKnown || !user;
+ },
+
+ computeLoginStatus: function(statusKnown, user) {
+ if (statusKnown && user) {
+ return 'Logged in';
+ }
+
+ if (statusKnown) {
+ return 'Logged out';
+ }
+
+ return 'Unknown (checking status...)';
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/firebase-element/demo/x-pretty-json.html b/polymer_1.0.4/bower_components/firebase-element/demo/x-pretty-json.html
new file mode 100644
index 0000000..9039f48
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/demo/x-pretty-json.html
@@ -0,0 +1,26 @@
+<link rel="import" href="../../polymer/polymer.html">
+
+<dom-module id="x-pretty-json">
+ <template>
+ <pre>[[prettify(object)]]</pre>
+ </template>
+ <script>
+ Polymer({
+ is: 'x-pretty-json',
+
+ properties: {
+ object: {
+ type: Object
+ }
+ },
+
+ prettify: function(object) {
+ if (!object) {
+ return '';
+ }
+
+ return JSON.stringify(object, null, ' ');
+ }
+ })
+ </script>
+</dom-module>
diff --git a/polymer_1.0.4/bower_components/firebase-element/firebase-auth.html b/polymer_1.0.4/bower_components/firebase-element/firebase-auth.html
new file mode 100644
index 0000000..f9a26c1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/firebase-auth.html
@@ -0,0 +1,383 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="firebase.html">
+<link rel="import" href="../polymer/polymer.html">
+
+<!--
+Element wrapper for the Firebase authentication API (https://www.firebase.com/docs/web/guide/user-auth.html).
+-->
+
+<script>
+ Polymer({
+ is: 'firebase-auth',
+
+ properties: {
+ /**
+ * Firebase location URL (must have simple login enabled via Forge interface).
+ */
+ location: {
+ type: String,
+ reflectToAttribute: true,
+ observer: '_locationChanged'
+ },
+
+ /**
+ * Default login provider type. May be one of: `anonymous`, `custom`, `password`
+ * `facebook`, `github`, `twitter`, `google`.
+ */
+ provider: {
+ type: String,
+ reflectToAttribute: true,
+ value: 'anonymous'
+ },
+
+ /**
+ * When logged in, this property reflects the firebase user auth object.
+ */
+ user: {
+ type: Object,
+ readOnly: true,
+ notify: true
+ },
+
+ /**
+ * When true, login will be attempted if login status check determines no user is
+ * logged in. Should generally only be used with provider types that do not present
+ * a login UI, such as 'anonymous'.
+ */
+ autoLogin: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true
+ },
+
+ /**
+ * When true, login status can be determined by checking `user` property.
+ */
+ statusKnown: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ readOnly: true,
+ reflectToAttribute: true
+ },
+
+ /**
+ * When true, authentication will try to redirect instead of using a
+ * popup if possible.
+ */
+ redirect: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true
+ },
+
+ /**
+ * Provider-specific parameters to pass to login. May be overridden at `login()`-time.
+ */
+ params: {
+ type: Object
+ },
+
+ /**
+ * Provider-specific options to pass to login, for provider types that take a second
+ * object to pass firebase-specific options. May be overridden at `login()`-time.
+ */
+ options: {
+ type: Object
+ },
+
+ /**
+ * A pointer to the Firebase instance being used by the firebase-auth element.
+ */
+ ref: {
+ type: Object,
+ readOnly: true,
+ notify: true
+ },
+
+ _boundAuthHandler: {
+ value: function() {
+ return this._authHandler.bind(this);
+ }
+ },
+
+ _boundOnlineHandler: {
+ value: function() {
+ return this._onlineHandler.bind(this);
+ }
+ },
+
+ _queuedLogin: {
+ type: Object
+ }
+ },
+
+ attached: function() {
+ window.addEventListener('online', this._boundOnlineHandler);
+ },
+
+ detached: function() {
+ window.removeEventListener('online', this._boundOnlineHandler);
+ this.ref.offAuth(this._boundAuthHandler);
+ },
+
+ _locationChanged: function(location) {
+ if (this.ref) {
+ this.ref.offAuth(this._boundAuthHandler);
+ }
+
+ if (location) {
+ this._setRef(new Firebase(location));
+ this.ref.onAuth(this._boundAuthHandler);
+ } else {
+ this._setRef(null)
+ }
+ },
+
+ _loginHandler: function(error, user) {
+ if (error) {
+ // an error occurred while attempting login
+ this.fire('error', error);
+ } else {
+ this._authHandler(user);
+ }
+ },
+
+ _authHandler: function(user) {
+ if (user) {
+ // user authenticated with Firebase
+ this._setUser(user);
+ this._setStatusKnown(true);
+ this.fire('login', {user: user});
+ } else {
+ this._setUser(null);
+
+ if (this.statusKnown) {
+ this._setStatusKnown(false);
+ this.fire('logout');
+ }
+
+ if (this._queuedLogin) {
+ this.login(this._queuedLogin.params, this._queuedLogin.options);
+ this._queuedLogin = null;
+ } else if (!this.statusKnown && this.autoLogin) {
+ this.login();
+ }
+
+ this._setStatusKnown(true);
+ }
+ },
+
+ /**
+ * Performs a login attempt, using the `provider` specified via attribute/property,
+ * or optionally via `provider` argument to the `login` function. Optionally,
+ * provider-specific login parameters can be specified via attribute (JSON)/property,
+ * or via the `params` argument to the `login` function.
+ *
+ * If the login is successful, the `login` event is fired, with `e.detail.user`
+ * containing the authenticated user object from Firebase.
+ *
+ * If login fails, the `error` event is fired, with `e.detail` containing error
+ * information supplied from Firebase.
+ *
+ * If the browswer supports `navigator.onLine` network status reporting and the
+ * network is currently offline, the login attempt will be queued until the network
+ * is restored.
+ *
+ * @method login
+ * @param {string} params (optional)
+ * @param {string} options (optional)
+ */
+ login: function(params, options) {
+ if (navigator.onLine === false) {
+ this._queuedLogin = {params: params, options: options};
+ } else {
+ params = params || (this.params && JSON.parse(this.params)) || undefined;
+ options = options || (this.options && JSON.parse(this.options)) || undefined;
+ switch(this.provider) {
+ case 'password':
+ this.ref.authWithPassword(params, this._loginHandler.bind(this), options);
+ break;
+ case 'anonymous':
+ this.ref.authAnonymously(this._loginHandler.bind(this), params);
+ break;
+ case 'custom':
+ this.ref.authWithCustomToken(params.token, this._loginHandler.bind(this));
+ break;
+ case 'facebook':
+ case 'google':
+ case 'github':
+ case 'twitter':
+ if (this.redirect) {
+ this.ref.authWithOAuthRedirect(this.provider, this._loginHandler.bind(this), params);
+ } else {
+ this.ref.authWithOAuthPopup(this.provider, this._loginHandler.bind(this), params);
+ }
+ break;
+ default:
+ throw 'Unknown provider: ' + this.provider;
+ }
+ }
+ },
+
+ /**
+ * Performs a logout attempt.
+ *
+ * If the login is successful, the `logout` event is fired.
+ *
+ * If login fails, the `error` event is fired, with `e.detail` containing error
+ * information supplied from Firebase.
+ *
+ * If the browswer supports `navigator.onLine` network status reporting and the
+ * network is currently offline, the logout attempt will be queued until the network
+ * is restored.
+ *
+ * @method logout
+ */
+ logout: function() {
+ if (navigator.onLine === false) {
+ this.queuedLogout = true;
+ } else {
+ this.ref.unauth();
+ }
+ },
+
+ _onlineHandler: function() {
+ if (this.queuedLogout) {
+ this.queuedLogout = false;
+ this.logout();
+ } else if (this.queuedLogin) {
+ this.login(this.queuedLogin.params, this.queuedLogin.options);
+ this.queuedLogin = null;
+ }
+ },
+
+ /**
+ * Creates a "password provider"-based user account.
+ *
+ * If the operation is successful, the `user-created` event is fired.
+ *
+ * If the operation fails, the `error` event is fired, with `e.detail`
+ * containing error information supplied from Firebase.
+ *
+ * @method createUser
+ * @param {string} email
+ * @param {string} password
+ */
+ createUser: function(email, password) {
+ this.ref.createUser({email: email, password: password}, function(error) {
+ if (!error) {
+ this.fire('user-created');
+ } else {
+ this.fire('error', error);
+ }
+ }.bind(this));
+ },
+
+ /**
+ * Changes the password of a "password provider"-based user account.
+ *
+ * If the operation is successful, the `password-changed` event is fired.
+ *
+ * If the operation fails, the `error` event is fired, with `e.detail`
+ * containing error information supplied from Firebase.
+ *
+ * @method changePassword
+ * @param {string} email
+ * @param {string} oldPassword
+ * @param {string} newPassword
+ */
+ changePassword: function(email, oldPassword, newPassword) {
+ this.ref.changePassword({
+ email: email,
+ oldPassword: oldPassword,
+ newPassword: newPassword
+ }, function(error) {
+ if (!error) {
+ this.fire('password-changed');
+ } else {
+ this.fire('error', error);
+ }
+ }.bind(this));
+ },
+
+ /**
+ * Sends a password reset email for a "password provider"-based user account.
+ *
+ * If the operation is successful, the `password-reset` event is fired.
+ *
+ * If the operation fails, the `error` event is fired, with `e.detail`
+ * containing error information supplied from Firebase.
+ *
+ * @method sendPasswordResetEmail
+ * @param {string} email
+ */
+ sendPasswordResetEmail: function(email) {
+ this.ref.resetPassword({email: email}, function(error) {
+ if (!error) {
+ this.fire('password-reset');
+ } else {
+ this.fire('error', error);
+ }
+ }.bind(this));
+ },
+
+ /**
+ * Changes the email of a "password provider"-based user account.
+ *
+ * If the operation is successful, the `email-changed` event is fired.
+ *
+ * If the operation fails, the `error` event is fired, with `e.detail`
+ * containing error information supplied from Firebase.
+ *
+ * @method changeEmail
+ * @param {string} oldEmail
+ * @param {string} newEmail
+ * @param {string} Password
+ */
+ changeEmail: function(oldEmail, newEmail, password) {
+ this.ref.changeEmail({
+ oldEmail: oldEmail,
+ newEmail: newEmail,
+ password: password
+ }, function(error) {
+ if (!error) {
+ this.fire('email-changed');
+ } else {
+ this.fire('error', error);
+ }
+ }.bind(this));
+ },
+
+ /**
+ * Removes a "password provider"-based user account.
+ *
+ * If the operation is successful, the `user-removed` event is fired.
+ *
+ * If the operation fails, the `error` event is fired, with `e.detail`
+ * containing error information supplied from Firebase.
+ *
+ * @method removeUser
+ * @param {string} email
+ * @param {string} password
+ */
+ removeUser: function(email, password) {
+ this.ref.removeUser({email: email, password: password}, function(error, success) {
+ if (!error) {
+ this.fire('user-removed');
+ } else {
+ this.fire('error', error);
+ }
+ }.bind(this));
+ }
+ });
+</script>
+
diff --git a/polymer_1.0.4/bower_components/firebase-element/firebase-collection.html b/polymer_1.0.4/bower_components/firebase-element/firebase-collection.html
new file mode 100644
index 0000000..2b4f1f4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/firebase-collection.html
@@ -0,0 +1,474 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="firebase-query-behavior.html">
+
+<!--
+An element wrapper for the Firebase API that provides a view into the provided
+Firebase location as an ordered collection.
+
+By default, Firebase yields values as unsorted document objects, where each of
+the children are accessible via object keys. The `<firebase-collection>`
+element allows Firebase API orderBy*, limitTo* and other query-oriented methods
+to be specified declaratively. The element then produces and maintains an Array
+of ordered child items of the document that is convenient for iterating over
+in other elements such as `<template is="dom-repeat">`.
+
+Example:
+
+ <template is="dom-bind">
+ <firebase-collection
+ order-by-child="height"
+ limit-to-first="3"
+ location="https://dinosaur-facts.firebaseio.com/dinosaurs"
+ data="{{dinosaurs}}"></firebase-collection>
+ <template is="dom-repeat" items="[[dinosaurs]]" as="dinosaur">
+ <h4>[[dinosaur.__firebaseKey__]]</h4>
+ <span>Height: </span><span>[[dinosaur.height]]</span><span>m</span>
+ </template>
+ </template>
+
+As you may have noticed above, the original key of each item is available as
+the `__firebaseKey__` property on the item.
+
+The element makes special accomodations for documents whose children are
+primitive values. A primitive value is wrapped in an object with the form:
+
+```javascript
+{
+ value: /* original primitive value */
+ __firebaseKey__: /* key of primitive value in parent document */
+}
+```
+
+Accessor methods such as `add` and `remove` are provided to enable convenient
+manipulation of the collection without direct knowledge of Firebase key values.
+-->
+
+<script>
+ Polymer({
+ is: 'firebase-collection',
+
+ behaviors: [
+ Polymer.FirebaseQueryBehavior
+ ],
+
+ properties: {
+ /**
+ * A pointer to the current Firebase Query instance being used to
+ * populate `data`.
+ */
+ query: {
+ type: Object,
+ notify: true,
+ computed: '_computeQuery(location, limitToFirst, limitToLast, _orderByMethodName, _startAt, _endAt, _equalTo)',
+ observer: '_queryChanged'
+ },
+
+ /**
+ * An ordered array of data items produced by the current Firebase Query
+ * instance.
+ */
+ data: {
+ type: Array,
+ readOnly: true,
+ notify: true,
+ value: function() {
+ return [];
+ }
+ },
+
+ /**
+ * Specify a child key to order the set of records reflected on the
+ * client.
+ */
+ orderByChild: {
+ type: String,
+ value: null,
+ reflectToAttribute: true
+ },
+
+ /**
+ * Specify to order by key the set of records reflected on the client.
+ */
+ orderByKey: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true
+ },
+
+ /**
+ * Specify to order by value the set of records reflected on the client.
+ */
+ orderByValue: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true
+ },
+
+ /**
+ * Specify to order by priority the set of records reflected on the
+ * client.
+ */
+ orderByPriority: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true
+ },
+
+ /**
+ * Specify a maximum number of records reflected on the client limited to
+ * the first certain number of children.
+ */
+ limitToFirst: {
+ type: Number,
+ value: null,
+ reflectToAttribute: true,
+ },
+
+ /**
+ * Specify a maximum number of records reflected on the client limited to
+ * the last certain number of children.
+ */
+ limitToLast: {
+ type: Number,
+ value: null,
+ reflectToAttribute: true
+ },
+
+ /**
+ * Specify a start record for the set of records reflected in the
+ * collection.
+ */
+ startAt: {
+ type: String,
+ value: null,
+ reflectToAttribute: true
+ },
+
+ /**
+ * Specify an end record for the set of records reflected in the
+ * collection.
+ */
+ endAt: {
+ type: String,
+ value: null,
+ reflectToAttribute: true
+ },
+
+ /**
+ * Specify to create a query which includes children which match the
+ * specified value. The argument type depends on which orderBy*() function
+ * was used in this query. Specify a value that matches the orderBy*()
+ * type.
+ */
+ equalTo: {
+ type: String,
+ value: null,
+ reflectToAttribute: true
+ },
+
+ _valueMap: {
+ type: Object,
+ value: function() {
+ return {};
+ }
+ },
+
+ _orderByMethodName: {
+ computed: '_computeOrderByMethodName(orderByChild, orderByKey, orderByValue, orderByPriority)'
+ },
+
+ _orderByTypeCast: {
+ computed: '_computeOrderByTypeCast(orderByChild, orderByKey, orderByValue, orderByPriority)'
+ },
+
+ _startAt: {
+ computed: '_computeStartAt(startAt, _orderByTypeCast)'
+ },
+
+ _endAt: {
+ computed: '_computeEndAt(endAt, _orderByTypeCast)'
+ },
+
+ _equalTo: {
+ computed: '_computeEqualTo(equalTo, _orderByTypeCast)'
+ }
+ },
+
+ listeners: {
+ 'firebase-child-added': '_onFirebaseChildAdded',
+ 'firebase-child-removed': '_onFirebaseChildRemoved',
+ 'firebase-child-changed': '_onFirebaseChildChanged',
+ 'firebase-child-moved': '_onFirebaseChildChanged',
+ },
+
+ /**
+ * Add an item to the document referenced at `location`. A key associated
+ * with the item will be created by Firebase, and can be accessed via the
+ * Firebase Query instance returned by this method.
+ *
+ * @param {Object} data A value to add to the document.
+ * @return {Object} A Firebase Query instance referring to the added item.
+ */
+ add: function(data) {
+ var query;
+
+ this._log('Adding new item to collection with value:', data);
+
+ query = this.query.ref().push();
+ query.set(data);
+
+ return query;
+ },
+
+ /**
+ * Remove an item from the document referenced at `location`. The item
+ * is assumed to be an identical reference to an item already in the
+ * `data` Array.
+ *
+ * @param {Object} data An identical reference to an item in `this.data`.
+ */
+ remove: function(data) {
+ if (data == null || data.__firebaseKey__ == null) {
+ this._error('Failed to remove unknown value:', data);
+ return;
+ }
+
+ this._log('Removing collection item "' + data.__firebaseKey__ + '"', data.value);
+
+ this.removeByKey(data.__firebaseKey__);
+ },
+
+ /**
+ * Look up an item in the local `data` Array by key.
+ *
+ * @param {String} key The key associated with the item in the parent
+ * document.
+ */
+ getByKey: function(key) {
+ return this._valueMap[key];
+ },
+
+ /**
+ * Remove an item from the document associated with `location` by key.
+ *
+ * @param {String} key The key associated with the item in the document
+ * located at `location`.
+ */
+ removeByKey: function(key) {
+ this.query.ref().child(key).remove();
+ },
+
+ _applyLocalDataChanges: function(change) {
+ var pathParts = change.path.split('.');
+ var index;
+ var value;
+
+ if (pathParts.length < 2 || pathParts[1] === 'splices') {
+ return;
+ }
+
+ index = parseInt(pathParts[1], 10);
+ value = this.data[index];
+ this.query.ref().child(value.__firebaseKey__).set(value);
+ },
+
+ _computeQuery: function(location, limitToFirst, limitToLast, orderByMethodName, startAt, endAt, equalTo) {
+ var query;
+
+ if (!location) {
+ return;
+ }
+
+ query = new Firebase(location);
+
+ if (orderByMethodName) {
+ if (orderByMethodName === 'orderByChild') {
+ query = query[orderByMethodName](this.orderByChild);
+ } else {
+ query = query[orderByMethodName]();
+ }
+ }
+
+ if (startAt != null) {
+ query = query.startAt(startAt);
+ }
+
+ if (endAt != null) {
+ query = query.endAt(endAt);
+ }
+
+ if (equalTo != null) {
+ query = query.equalTo(equalTo);
+ }
+
+ if (limitToLast != null) {
+ query = query.limitToLast(limitToLast);
+ }
+
+ if (limitToFirst != null) {
+ query = query.limitToFirst(limitToFirst);
+ }
+
+ return query;
+ },
+
+ _queryChanged: function() {
+ Polymer.FirebaseQueryBehavior._queryChanged.apply(this, arguments);
+ this._valueMap = {};
+ this._setData([]);
+ },
+
+ _computeOrderByMethodName: function(orderByChild, orderByKey, orderByValue, orderByPriority) {
+ if (orderByChild) {
+ return 'orderByChild';
+ }
+
+ if (orderByKey) {
+ return 'orderByKey';
+ }
+
+ if (orderByValue) {
+ return 'orderByValue';
+ }
+
+ if (orderByPriority) {
+ return 'orderByPriority';
+ }
+
+ return null;
+ },
+
+ _computeOrderByTypeCast: function(orderByChild, orderByKey, orderByValue, orderByPriority) {
+ if (orderByKey) {
+ return String;
+ }
+
+ return function(value) {
+ return value;
+ }
+ },
+
+ _computeStartAt: function(startAt, orderByTypeCast) {
+ return orderByTypeCast(startAt);
+ },
+
+ _computeEndAt: function(endAt, orderByTypeCast) {
+ return orderByTypeCast(endAt);
+ },
+
+ _computeEqualTo: function(equalTo, orderByTypeCast) {
+ return orderByTypeCast(equalTo);
+ },
+
+ _valueFromSnapshot: function(snapshot) {
+ var value = snapshot.val();
+
+ if (!(value instanceof Object)) {
+ value = {
+ value: value,
+ __firebasePrimitive__: true
+ };
+ }
+
+ value.__firebaseKey__ = snapshot.key();
+
+ return value;
+ },
+
+ _valueToPersistable: function(value) {
+ var persistable;
+
+ if (value.__firebasePrimitive__) {
+ return value.value;
+ }
+
+ persistable = {};
+
+ for (var property in value) {
+ if (property === '__firebaseKey__') {
+ continue;
+ }
+
+ persistable[property] = value[property];
+ }
+
+ return persistable;
+ },
+
+ _onFirebaseChildAdded: function(event) {
+ this._applyRemoteDataChange(function() {
+ var value = this._valueFromSnapshot(event.detail.childSnapshot);
+ var previousValueKey = event.detail.previousChildName;
+ var index = previousValueKey != null ?
+ this.data.indexOf(this._valueMap[previousValueKey]) + 1 : 0;
+
+ this._valueMap[value.__firebaseKey__] = value;
+
+ this.splice('data', index, 0, value);
+ });
+ },
+
+ _onFirebaseChildRemoved: function(event) {
+ this._applyRemoteDataChange(function() {
+ var key = event.detail.oldChildSnapshot.key();
+ var value = this._valueMap[key];
+
+ if (!value) {
+ this._error('Received firebase-child-removed event for unknown child "' + key + '"');
+ return;
+ }
+
+ this._valueMap[key] = null;
+ this.splice('data', this.data.indexOf(value), 1);
+ });
+ },
+
+ _onFirebaseChildChanged: function(event) {
+ this._applyRemoteDataChange(function() {
+ var value = this._valueFromSnapshot(event.detail.childSnapshot);
+ var oldValue = this._valueMap[value.__firebaseKey__];
+
+ if (!oldValue) {
+ this._error('Received firebase-child-changed event for unknown child "' + value.__firebaseKey__ + '"');
+ return;
+ }
+
+ this._valueMap[oldValue.__firebaseKey__] = null;
+ this._valueMap[value.__firebaseKey__] = value;
+ this.splice('data', this.data.indexOf(oldValue), 1, value);
+ });
+ },
+
+ _onFirebaseChildMoved: function(event) {
+ this._applyRemoteDataChange(function() {
+ var key = event.detail.childSnapshot.key();
+ var value = this._valueMap[key];
+ var previousChild;
+ var newIndex;
+
+ if (!value) {
+ this._error('Received firebase-child-moved event for unknown child "' + key + '"');
+ return;
+ }
+
+ previousValue = event.detail.previousChildName != null ?
+ this._valueMap[event.detail.previousChildName] : null;
+ newIndex = previousValue != null ?
+ this.data.indexOf(previousValue) + 1 : 0;
+
+ this.splice('data', this.data.indexOf(value), 1);
+ this.splice('data', newIndex, 0, value);
+ });
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/firebase-element/firebase-document.html b/polymer_1.0.4/bower_components/firebase-element/firebase-document.html
new file mode 100644
index 0000000..afc5b74
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/firebase-document.html
@@ -0,0 +1,110 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="firebase.html">
+<link rel="import" href="firebase-query-behavior.html">
+
+<!--
+An element wrapper for the Firebase API.
+
+A `<firebase-document>` is a reference to a remote document somewhere on
+Firebase. The element fetchs a document at a provided `location`, and exposes
+it as an Object that is suitable for deep two-way databinding.
+
+Example:
+
+ <firebase-document
+ location="https://dinosaur-facts.firebaseio.com/dinosaurs"
+ data="{{dinosaurs}}">
+
+In the above example, if the `dinosaurs` object is data-bound elsewhere via
+Polymer's data-binding system, changes to the document will be automatically
+reflected in the remote document and any other clients referencing that
+document.
+-->
+
+<script>
+ Polymer({
+ is: 'firebase-document',
+
+ behaviors: [
+ Polymer.FirebaseQueryBehavior
+ ],
+
+ properties: {
+
+ /**
+ * Firebase Query object corresponding to `location`.
+ */
+ query: {
+ type: Object,
+ notify: true,
+ computed: '_computeQuery(location)',
+ observer: '_queryChanged'
+ },
+
+ /**
+ * The `data` object mapped to `location`.
+ */
+ data: {
+ type: Object,
+ notify: true
+ }
+ },
+
+ listeners: {
+ 'firebase-value': '_onFirebaseValue'
+ },
+
+ _applyLocalDataChanges: function(change) {
+ var pathFragments = change.path.split('.');
+
+ if (pathFragments.length === 1) {
+ this._updateRemoteDocument();
+ return;
+ }
+
+ this._setRemoteDocumentChild(
+ pathFragments[1],
+ change.base[pathFragments[1]]
+ );
+ },
+
+ _onFirebaseValue: function(event) {
+ this._applyRemoteDataChange(function() {
+ this.set('data', event.detail.val());
+ });
+ },
+
+ _computeQuery: function(location) {
+ if (!location) {
+ return;
+ }
+
+ return new Firebase(location);
+ },
+
+ _updateRemoteDocument: function() {
+ this._log('Updating remote document');
+ this.query.update(this.dataAsObject);
+ },
+
+ _setRemoteDocumentChild: function(key, value) {
+ this._log('Setting child "' + key + '" to', value);
+ this.query.child(key).set(value);
+ },
+
+ _removeRemoteDocumentChild: function(key) {
+ this._log('Removing child "' + key + '"');
+ this.query.child(key).remove();
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/firebase-element/firebase-query-behavior.html b/polymer_1.0.4/bower_components/firebase-element/firebase-query-behavior.html
new file mode 100644
index 0000000..57ab5a0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/firebase-query-behavior.html
@@ -0,0 +1,185 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="firebase.html">
+
+<script>
+ /** @polymerBehavior */
+ Polymer.FirebaseQueryBehavior = {
+ properties: {
+ /**
+ * A Firebase API location that references an accessible document.
+ */
+ location: {
+ type: String,
+ notify: true,
+ reflectToAttribute: true
+ },
+
+ /**
+ * Firebase Query object corresponding to `location`.
+ */
+ query: {
+ type: Object,
+ notify: true,
+ readOnly: true
+ },
+
+ /**
+ * If true, verbose debugging information will be printed to the console.
+ */
+ log: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true
+ },
+
+ _receivingRemoteChanges: {
+ type: Boolean,
+ value: false
+ }
+ },
+
+ observers: [
+ '_dataChanged(data.*)'
+ ],
+
+ get dataAsObject() {
+ if (Array.isArray(this.data)) {
+ return this.data.reduce(function(object, value, index) {
+ object[index] = value;
+ }, {});
+ }
+
+ return this.data;
+ },
+
+ /**
+ * Disconnects the current Firebase Query instance.
+ */
+ disconnect: function() {
+ this.location = '';
+ },
+
+ _applyLocalDataChanges: function(changes) {
+ // Virtual..
+ },
+
+ _applyRemoteDataChange: function(applyChange) {
+ this._receivingRemoteChanges = true;
+ applyChange.call(this);
+ this._receivingRemoteChanges = false;
+ },
+
+ _dataChanged: function(changes) {
+ if (this._receivingRemoteChanges) {
+ return;
+ }
+
+ this._applyLocalDataChanges(changes);
+ },
+
+ _queryChanged: function(query, oldQuery) {
+ if (oldQuery) {
+ this._stopListeningToQuery(oldQuery);
+ }
+
+ if (query) {
+ this._listenToQuery(query);
+ }
+ },
+
+ _listenToQuery: function(query) {
+ this._log('Adding Firebase event handlers.');
+ query.on('value', this._onQueryValue, this._onQueryCancel, this);
+ query.on('child_added', this._onQueryChildAdded, this._onQueryCancel, this);
+ query.on('child_removed', this._onQueryChildRemoved, this._onQueryCancel, this);
+ query.on('child_changed', this._onQueryChildChanged, this._onQueryCancel, this);
+ query.on('child_moved', this._onQueryChildMoved, this._onQueryCancel, this);
+ },
+
+ _stopListeningToQuery: function(query) {
+ this._log('Removing Firebase event handlers');
+ query.off('value', this._onQueryValue, this);
+ query.off('child_added', this._onQueryChildAdded, this);
+ query.off('child_removed', this._onQueryChildRemoved, this);
+ query.off('child_changed', this._onQueryChildChanged, this);
+ query.off('child_moved', this._onQueryChildMoved, this);
+ },
+
+ _onQueryValue: function(snapshot) {
+ this._log('Firebase Event: "value"', snapshot);
+ this.fire('firebase-value', snapshot, { bubbles: false });
+ },
+
+ _onQueryChildAdded: function(childSnapshot, previousChildName) {
+ this._log('Firebase Event: "child_added"', childSnapshot, previousChildName);
+ this.fire('firebase-child-added', {
+ childSnapshot: childSnapshot,
+ previousChildName: previousChildName
+ }, { bubbles: false });
+ },
+
+ _onQueryChildRemoved: function(oldChildSnapshot) {
+ this._log('Firebase Event: "child_removed"', oldChildSnapshot);
+ this.fire('firebase-child-removed', {
+ oldChildSnapshot: oldChildSnapshot
+ }, { bubbles: false });
+ },
+
+ _onQueryChildChanged: function(childSnapshot, previousChildName) {
+ this._log('Firebase Event: "child_changed"', childSnapshot, previousChildName);
+ this.fire('firebase-child-changed', {
+ childSnapshot: childSnapshot,
+ previousChildName: previousChildName
+ }, { bubbles: false });
+ },
+
+ _onQueryChildMoved: function(childSnapshot, previousChildName) {
+ this._log('Firebase Event: "child_changed"', childSnapshot, previousChildName);
+ this.fire('firebase-child-moved', {
+ childSnapshot: childSnapshot,
+ previousChildName: previousChildName
+ }, { bubbles: false });
+ },
+
+ _onQueryCancel: function(error) {
+ if (error) {
+ this._error('Firebase Error', error);
+ }
+
+ this._log('Firebase query subscription cancelled.');
+ this.disconnect();
+ },
+
+ _log: function() {
+ var args;
+
+ if (this.log) {
+ args = Array.prototype.slice.call(arguments).map(function(arg) {
+ if (arg && typeof arg.val === 'function') {
+ return arg.val();
+ }
+
+ return arg;
+ });
+
+ console.log.apply(console, args);
+ }
+ },
+
+ _error: function() {
+ if (this.log) {
+ console.error.apply(console, arguments);
+ }
+ }
+ };
+</script>
diff --git a/polymer_1.0.4/bower_components/firebase-element/firebase.html b/polymer_1.0.4/bower_components/firebase-element/firebase.html
new file mode 100644
index 0000000..a31f955
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/firebase.html
@@ -0,0 +1,10 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<script src='../firebase/firebase.js'></script>
diff --git a/polymer_1.0.4/bower_components/firebase-element/index.html b/polymer_1.0.4/bower_components/firebase-element/index.html
new file mode 100644
index 0000000..bbfb9b9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+ <title>Firebase Elements</title>
+</head>
+<body>
+
+ <iron-component-page src="firebase-collection.html"></iron-component-page>
+
+</body>
+</html>
+
+
diff --git a/polymer_1.0.4/bower_components/firebase-element/test/firebase-collection.html b/polymer_1.0.4/bower_components/firebase-element/test/firebase-collection.html
new file mode 100644
index 0000000..9cc9c5f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/test/firebase-collection.html
@@ -0,0 +1,259 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>firebase-collection</title>
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../promise-polyfill/promise-polyfill.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="test-helpers.html">
+ <link rel="import" href="../firebase-collection.html">
+</head>
+<body>
+ <test-fixture id="TrivialCollection">
+ <template>
+ <firebase-collection
+ location="https://fb-element-demo.firebaseio.com/test/trivial"
+ log>
+ </firebase-collection>
+ </template>
+ </test-fixture>
+ <test-fixture id="PrimitiveCollection">
+ <template>
+ <firebase-collection
+ location="https://fb-element-demo.firebaseio.com/test/primitives"
+ order-by-value
+ log>
+ </firebase-collection>
+ </template>
+ </test-fixture>
+ <test-fixture id="ChangingChildren">
+ <template>
+ <firebase-collection
+ location="https://fb-element-demo.firebaseio.com/test/changing_children"
+ order-by-child="foo"
+ log>
+ </firebase-collection>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="SyncingCollections">
+ <template>
+ <firebase-collection
+ location="https://fb-element-demo.firebaseio.com/test/syncing"
+ log>
+ </firebase-collection>
+ <firebase-collection
+ location="https://fb-element-demo.firebaseio.com/test/syncing"
+ order-by-child="foo"
+ log>
+ </firebase-collection>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('<firebase-document>', function() {
+ var firebase;
+
+ suite('basic usage', function() {
+ setup(function() {
+ firebase = fixture('TrivialCollection');
+ });
+
+ teardown(function() {
+ firebase.disconnect();
+ });
+
+ test('exposes data as an array', function(done) {
+ waitForEvent(firebase, 'firebase-child-added').then(function() {
+ expect(firebase.data).to.be.an('array');
+ done();
+ }).catch(function(e) {
+ done(e);
+ });
+ });
+
+ test('receives data from Firebase location', function(done) {
+ waitForEvent(firebase, 'data-changed').then(function() {
+ expect(firebase.data[0].value).to.be.equal(true);
+ done();
+ }).catch(function(e) {
+ done(e);
+ });
+ });
+ });
+
+ suite('ordered primitives', function() {
+ setup(function() {
+ firebase = fixture('PrimitiveCollection');
+ });
+
+ teardown(function() {
+ firebase.disconnect();
+ });
+
+ test('converts primitives into objects with a value key', function(done) {
+ waitForEvent(firebase, 'firebase-child-added').then(function() {
+ expect(firebase.data[0]).to.be.an('object');
+ done();
+ }).catch(function(e) {
+ done(e);
+ });
+ });
+
+ test('orders primitives by value', function(done) {
+ waitForEvent(firebase, 'firebase-value').then(function() {
+ var lastValue = -Infinity;
+ expect(firebase.data.length).to.be.greaterThan(0);
+ firebase.data.forEach(function(item) {
+ expect(item.value).to.not.be.lessThan(lastValue);
+ lastValue = item.value;
+ });
+ done();
+ }).catch(function(e) {
+ done(e);
+ });
+ });
+
+ suite('adding a value locally', function() {
+ setup(function(done) {
+ waitForEvent(firebase, 'firebase-value').then(function() {
+ done();
+ }).catch(function(e) {
+ done(e);
+ });
+ });
+
+ test('can be done with `add`', function(done) {
+ var length = firebase.data.length;
+ var newValue = firebase.data[firebase.data.length - 1].value + 1;
+ var key;
+
+ waitForEvent(firebase, 'firebase-child-added').then(function() {
+ expect(firebase.data.length).to.be.equal(length + 1);
+ expect(firebase.data[firebase.data.length - 1].value).to.be.equal(newValue);
+ done();
+ }).catch(function(e) {
+ done(e);
+ }).then(function() {
+ firebase.removeByKey(key);
+ });
+
+ key = firebase.add(newValue).key();
+ });
+ });
+ });
+
+ suite('a child changes', function() {
+ setup(function(done) {
+ firebase = fixture('ChangingChildren');
+ waitForEvent(firebase, 'firebase-value').then(function() {
+ done();
+ }).catch(function(e) {
+ done(e)
+ });
+ });
+
+ test('updates the child key in place with the new value', function(done) {
+ var childrenKeys = [];
+
+ waitForEvent(firebase, 'firebase-value').then(function() {
+ var middleValue = firebase.getByKey(childrenKeys[1]);
+ var changes;
+
+ expect(middleValue.foo).to.be.equal(1);
+ expect(middleValue.bar).to.be.equal(1);
+
+ changes = waitForEvent(firebase, 'firebase-child-changed');
+
+ firebase.set('data.' + firebase.data.indexOf(middleValue) + '.bar', 2);
+
+ return changes;
+ }).then(function() {
+ var middleValue = firebase.getByKey(childrenKeys[1]);
+
+ expect(middleValue.foo).to.be.equal(1);
+ expect(middleValue.bar).to.be.equal(2);
+
+ done();
+ }).catch(function(e) {
+ done(e);
+ }).then(function() {
+ childrenKeys.forEach(function(key) {
+ firebase.removeByKey(key);
+ });
+ });
+
+ childrenKeys = [0, 1, 2].map(function(value, index) {
+ return firebase.add({
+ foo: value,
+ bar: index
+ }).key();
+ });
+ });
+ });
+
+ suite('syncing collections', function() {
+ var localFirebase;
+ var remoteFirebase;
+
+ setup(function(done) {
+ firebase = fixture('SyncingCollections');
+ localFirebase = firebase[0];
+ remoteFirebase = firebase[1];
+ Promise.all([
+ waitForEvent(localFirebase, 'firebase-value'),
+ waitForEvent(remoteFirebase, 'firebase-value')
+ ]).then(function() {
+ done();
+ }).catch(function(e) {
+ done(e);
+ });
+ });
+
+ test('syncs a new item at the correct index', function(done) {
+ var data = {
+ foo: 100
+ };
+ var key;
+
+ waitForEvent(remoteFirebase, 'firebase-value').then(function() {
+ var value = remoteFirebase.getByKey(key);
+ var lowValue = remoteFirebase.getByKey('lowValue');
+ var highValue = remoteFirebase.getByKey('highValue');
+
+ var index = remoteFirebase.data.indexOf(value);
+ var lowIndex = remoteFirebase.data.indexOf(lowValue);
+ var highIndex = remoteFirebase.data.indexOf(highValue);
+
+ expect(value).to.be.okay;
+ expect(index).to.be.lessThan(highIndex);
+ expect(index).to.be.greaterThan(lowIndex);
+ done();
+ }).catch(function(e) {
+ done(e);
+ }).then(function() {
+ localFirebase.removeByKey(key);
+ });
+
+ key = localFirebase.add(data).key();
+ });
+ });
+ });
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/firebase-element/test/firebase-document.html b/polymer_1.0.4/bower_components/firebase-element/test/firebase-document.html
new file mode 100644
index 0000000..bae48b1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/test/firebase-document.html
@@ -0,0 +1,221 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>firebase-document</title>
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../promise-polyfill/promise-polyfill.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="test-helpers.html">
+ <link rel="import" href="../firebase-document.html">
+</head>
+<body>
+ <test-fixture id="TrivialDocument">
+ <template>
+ <firebase-document
+ location="https://fb-element-demo.firebaseio.com/test/trivial"
+ log>
+ </firebase-document>
+ </template>
+ </test-fixture>
+ <test-fixture id="UpdateableDocument">
+ <template>
+ <firebase-document
+ location="https://fb-element-demo.firebaseio.com/test/updateable_document"
+ log>
+ </firebase-document>
+ </template>
+ </test-fixture>
+ <test-fixture id="MalleableDocument">
+ <template>
+ <firebase-document
+ id="local"
+ location="https://fb-element-demo.firebaseio.com/test/document"
+ log>
+ </firebase-document>
+ <firebase-document
+ id="remote"
+ location="https://fb-element-demo.firebaseio.com/test/document"
+ log>
+ </firebase-document>
+ </template>
+ </test-fixture>
+ <script>
+
+ suite('<firebase-document>', function() {
+ var firebase;
+
+ suite('basic usage', function() {
+ setup(function() {
+ firebase = fixture('TrivialDocument');
+ });
+
+ teardown(function() {
+ firebase.disconnect();
+ });
+
+ test('receives data from Firebase location', function(done) {
+ waitForEvent(firebase, 'data-changed').then(function() {
+ expect(firebase.data.passed).to.be.equal(true);
+ done();
+ }).catch(function() {
+ done(e);
+ });
+ });
+ });
+
+ suite('document updating', function() {
+ setup(function(done) {
+ firebase = fixture('UpdateableDocument');
+ waitForEvent(firebase, 'firebase-value').then(function() {
+ done();
+ });
+ });
+
+ test('setting data property updates the document', function(done) {
+ var data = {};
+ var newValue = Math.random().toString().split('.').pop();
+
+ data[newValue] = newValue;
+
+ waitForEvent(firebase, 'firebase-value').then(function() {
+ expect(firebase.data[newValue]).to.be.eql(newValue);
+ done();
+ }).catch(function(e) {
+ done(e);
+ }).then(function() {
+ firebase.set('data.' + newValue, null);
+ });
+
+ firebase.set('data', data);
+ });
+ });
+
+ suite('document manipulation', function() {
+ var localFirebase;
+ var remoteFirebase;
+ var key;
+
+ setup(function(done) {
+ firebase = fixture('MalleableDocument');
+ key = randomKey();
+
+ localFirebase = firebase[0];
+ remoteFirebase = firebase[1];
+
+ Promise.all([
+ localFirebase.data ? null : waitForEvent(localFirebase, 'data-changed'),
+ remoteFirebase.data ? null : waitForEvent(remoteFirebase, 'data-changed')
+ ]).then(function() {
+ done();
+ });
+ });
+
+ teardown(function(done) {
+ new Promise(function(resolve, reject) {
+ if (localFirebase.data[key] == null) {
+ resolve();
+ } else {
+ resolve(waitForEvent(localFirebase, 'firebase-value'));
+ localFirebase.set('data.' + key, null);
+ }
+ }).then(function() {
+ localFirebase.disconnect();
+ remoteFirebase.disconnect();
+ done();
+ }).catch(function(e) {
+ done(e);
+ });
+ });
+
+ test('all clients reflect same document', function() {
+ expect(localFirebase.data.permanentValue).to.be.okay;
+ expect(localFirebase.data).to.be.eql(remoteFirebase.data);
+ });
+
+ test('local data-bound child-add reflects remotely', function(done) {
+
+ waitForEvent(remoteFirebase, 'firebase-child-added').then(function() {
+ expect(remoteFirebase.data[key]).to.be.equal(
+ localFirebase.data[key]
+ );
+ }).then(function() {
+ done();
+ }).catch(function(e) {
+ done(e);
+ });
+
+ localFirebase.set('data.' + key, 'foo');
+ });
+
+ test('local data-bound child-remove reflects remotely', function(done) {
+
+ waitForEvent(remoteFirebase, 'firebase-child-added').then(function() {
+ var dataIsRemoved = waitForEvent(remoteFirebase, 'firebase-child-removed');
+ localFirebase.set('data.' + key, null);
+ return dataIsRemoved;
+ }).then(function() {
+ expect(localFirebase.data[key]).to.not.be.okay;
+ expect(remoteFirebase.data[key]).to.not.be.okay;
+ done();
+ }).catch(function(e) {
+ done(e);
+ });
+
+ localFirebase.set('data.' + key, 'foo');
+ });
+
+ test('child sub-tree modifications reflect remotely', function(done) {
+
+ waitForEvent(remoteFirebase, 'firebase-child-added').then(function() {
+ expect(localFirebase.data[key].foo).to.be.equal(1);
+ expect(remoteFirebase.data[key]).to.be.eql(localFirebase.data[key]);
+
+ var subtreeKeyIsAdded = waitForEvent(remoteFirebase, 'firebase-child-changed');
+ localFirebase.set('data.' + key + '.bar', 2);
+ return subtreeKeyIsAdded;
+ }).then(function() {
+ expect(localFirebase.data[key].bar).to.be.equal(2);
+ expect(remoteFirebase.data[key]).to.be.eql(localFirebase.data[key]);
+
+ expect(localFirebase.data[key].foo).to.be.okay;
+ expect(remoteFirebase.data[key].foo).to.be.okay;
+
+ var subtreeKeyIsRemoved = waitForEvent(remoteFirebase, 'firebase-child-changed');
+ localFirebase.set('data.' + key + '.foo', null);
+ return subtreeKeyIsRemoved;
+ }).then(function() {
+ expect(localFirebase.data[key].foo).to.not.be.okay;
+ expect(remoteFirebase.data[key].foo).to.not.be.okay;
+
+ expect(localFirebase.data[key].bar).to.be.okay;
+ expect(remoteFirebase.data[key].bar).to.be.okay;
+
+ done();
+ }).catch(function(e) {
+ done(e);
+ });
+
+ localFirebase.set('data.' + key, {
+ foo: 1
+ });
+ });
+ });
+ });
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/firebase-element/test/index.html b/polymer_1.0.4/bower_components/firebase-element/test/index.html
new file mode 100644
index 0000000..7845598
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'firebase-document.html',
+ 'firebase-collection.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/firebase-element/test/test-helpers.html b/polymer_1.0.4/bower_components/firebase-element/test/test-helpers.html
new file mode 100644
index 0000000..bfd28b0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase-element/test/test-helpers.html
@@ -0,0 +1,14 @@
+<script>
+ function randomKey() {
+ return (0|(Math.random() * 999999999)).toString();
+ }
+
+ function waitForEvent(element, event) {
+ return new Promise(function(resolve, reject) {
+ element.addEventListener(event, function onEvent() {
+ element.removeEventListener(event, onEvent);
+ resolve();
+ });
+ });
+ }
+</script>
diff --git a/polymer_1.0.4/bower_components/firebase/.bower.json b/polymer_1.0.4/bower_components/firebase/.bower.json
new file mode 100644
index 0000000..a577a57
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase/.bower.json
@@ -0,0 +1,34 @@
+{
+ "name": "firebase",
+ "version": "2.2.7",
+ "homepage": "https://firebase.com",
+ "authors": [
+ "Firebase <operations@firebase.com>"
+ ],
+ "description": "Firebase Web Client",
+ "main": "firebase.js",
+ "keywords": [
+ "Firebase",
+ "synchronization",
+ "real-time",
+ "websocket"
+ ],
+ "license": "MIT",
+ "private": false,
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "_release": "2.2.7",
+ "_resolution": {
+ "type": "version",
+ "tag": "v2.2.7",
+ "commit": "904997bac4594a0946dab838da071fdeac9ef2d2"
+ },
+ "_source": "git://github.com/firebase/firebase-bower.git",
+ "_target": "^2.2.0",
+ "_originalSource": "firebase"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/firebase/README.md b/polymer_1.0.4/bower_components/firebase/README.md
new file mode 100644
index 0000000..3c88c2a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase/README.md
@@ -0,0 +1,10 @@
+firebase-bower
+==============
+
+To use firebase via bower, do:
+
+ bower install firebase
+
+NOTE: This repo is automatically generated and is not monitored for issues / pull requests. Please contact support@firebase.com for any bugs/suggestions on Firebase or the bower module.
+
+LICENSE - Refer to: https://www.firebase.com/terms/terms-of-service.html
diff --git a/polymer_1.0.4/bower_components/firebase/bower.json b/polymer_1.0.4/bower_components/firebase/bower.json
new file mode 100644
index 0000000..854e5a1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase/bower.json
@@ -0,0 +1,25 @@
+{
+ "name": "firebase",
+ "version": "2.2.7",
+ "homepage": "https://firebase.com",
+ "authors": [
+ "Firebase <operations@firebase.com>"
+ ],
+ "description": "Firebase Web Client",
+ "main": "firebase.js",
+ "keywords": [
+ "Firebase",
+ "synchronization",
+ "real-time",
+ "websocket"
+ ],
+ "license": "MIT",
+ "private": false,
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ]
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/firebase/firebase-debug.js b/polymer_1.0.4/bower_components/firebase/firebase-debug.js
new file mode 100644
index 0000000..891ca66
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase/firebase-debug.js
@@ -0,0 +1,13080 @@
+/*! @license Firebase v2.2.7
+ License: https://www.firebase.com/terms/terms-of-service.html */
+(function(ns) {
+ ns.wrapper = function(goog, fb) {
+ var CLOSURE_NO_DEPS = true;
+ var COMPILED = false;
+var goog = goog || {};
+goog.global = this;
+goog.global.CLOSURE_UNCOMPILED_DEFINES;
+goog.global.CLOSURE_DEFINES;
+goog.isDef = function(val) {
+ return val !== void 0;
+};
+goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {
+ var parts = name.split(".");
+ var cur = opt_objectToExportTo || goog.global;
+ if (!(parts[0] in cur) && cur.execScript) {
+ cur.execScript("var " + parts[0]);
+ }
+ for (var part;parts.length && (part = parts.shift());) {
+ if (!parts.length && goog.isDef(opt_object)) {
+ cur[part] = opt_object;
+ } else {
+ if (cur[part]) {
+ cur = cur[part];
+ } else {
+ cur = cur[part] = {};
+ }
+ }
+ }
+};
+goog.define = function(name, defaultValue) {
+ var value = defaultValue;
+ if (!COMPILED) {
+ if (goog.global.CLOSURE_UNCOMPILED_DEFINES && Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_UNCOMPILED_DEFINES, name)) {
+ value = goog.global.CLOSURE_UNCOMPILED_DEFINES[name];
+ } else {
+ if (goog.global.CLOSURE_DEFINES && Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_DEFINES, name)) {
+ value = goog.global.CLOSURE_DEFINES[name];
+ }
+ }
+ }
+ goog.exportPath_(name, value);
+};
+goog.define("goog.DEBUG", true);
+goog.define("goog.LOCALE", "en");
+goog.define("goog.TRUSTED_SITE", true);
+goog.define("goog.STRICT_MODE_COMPATIBLE", false);
+goog.define("goog.DISALLOW_TEST_ONLY_CODE", COMPILED && !goog.DEBUG);
+goog.provide = function(name) {
+ if (!COMPILED) {
+ if (goog.isProvided_(name)) {
+ throw Error('Namespace "' + name + '" already declared.');
+ }
+ }
+ goog.constructNamespace_(name);
+};
+goog.constructNamespace_ = function(name, opt_obj) {
+ if (!COMPILED) {
+ delete goog.implicitNamespaces_[name];
+ var namespace = name;
+ while (namespace = namespace.substring(0, namespace.lastIndexOf("."))) {
+ if (goog.getObjectByName(namespace)) {
+ break;
+ }
+ goog.implicitNamespaces_[namespace] = true;
+ }
+ }
+ goog.exportPath_(name, opt_obj);
+};
+goog.VALID_MODULE_RE_ = /^[a-zA-Z_$][a-zA-Z0-9._$]*$/;
+goog.module = function(name) {
+ if (!goog.isString(name) || !name || name.search(goog.VALID_MODULE_RE_) == -1) {
+ throw Error("Invalid module identifier");
+ }
+ if (!goog.isInModuleLoader_()) {
+ throw Error("Module " + name + " has been loaded incorrectly.");
+ }
+ if (goog.moduleLoaderState_.moduleName) {
+ throw Error("goog.module may only be called once per module.");
+ }
+ goog.moduleLoaderState_.moduleName = name;
+ if (!COMPILED) {
+ if (goog.isProvided_(name)) {
+ throw Error('Namespace "' + name + '" already declared.');
+ }
+ delete goog.implicitNamespaces_[name];
+ }
+};
+goog.module.get = function(name) {
+ return goog.module.getInternal_(name);
+};
+goog.module.getInternal_ = function(name) {
+ if (!COMPILED) {
+ if (goog.isProvided_(name)) {
+ return name in goog.loadedModules_ ? goog.loadedModules_[name] : goog.getObjectByName(name);
+ } else {
+ return null;
+ }
+ }
+};
+goog.moduleLoaderState_ = null;
+goog.isInModuleLoader_ = function() {
+ return goog.moduleLoaderState_ != null;
+};
+goog.module.declareTestMethods = function() {
+ if (!goog.isInModuleLoader_()) {
+ throw new Error("goog.module.declareTestMethods must be called from " + "within a goog.module");
+ }
+ goog.moduleLoaderState_.declareTestMethods = true;
+};
+goog.module.declareLegacyNamespace = function() {
+ if (!COMPILED && !goog.isInModuleLoader_()) {
+ throw new Error("goog.module.declareLegacyNamespace must be called from " + "within a goog.module");
+ }
+ if (!COMPILED && !goog.moduleLoaderState_.moduleName) {
+ throw Error("goog.module must be called prior to " + "goog.module.declareLegacyNamespace.");
+ }
+ goog.moduleLoaderState_.declareLegacyNamespace = true;
+};
+goog.setTestOnly = function(opt_message) {
+ if (goog.DISALLOW_TEST_ONLY_CODE) {
+ opt_message = opt_message || "";
+ throw Error("Importing test-only code into non-debug environment" + (opt_message ? ": " + opt_message : "."));
+ }
+};
+goog.forwardDeclare = function(name) {
+};
+if (!COMPILED) {
+ goog.isProvided_ = function(name) {
+ return name in goog.loadedModules_ || !goog.implicitNamespaces_[name] && goog.isDefAndNotNull(goog.getObjectByName(name));
+ };
+ goog.implicitNamespaces_ = {"goog.module":true};
+}
+goog.getObjectByName = function(name, opt_obj) {
+ var parts = name.split(".");
+ var cur = opt_obj || goog.global;
+ for (var part;part = parts.shift();) {
+ if (goog.isDefAndNotNull(cur[part])) {
+ cur = cur[part];
+ } else {
+ return null;
+ }
+ }
+ return cur;
+};
+goog.globalize = function(obj, opt_global) {
+ var global = opt_global || goog.global;
+ for (var x in obj) {
+ global[x] = obj[x];
+ }
+};
+goog.addDependency = function(relPath, provides, requires, opt_isModule) {
+ if (goog.DEPENDENCIES_ENABLED) {
+ var provide, require;
+ var path = relPath.replace(/\\/g, "/");
+ var deps = goog.dependencies_;
+ for (var i = 0;provide = provides[i];i++) {
+ deps.nameToPath[provide] = path;
+ deps.pathIsModule[path] = !!opt_isModule;
+ }
+ for (var j = 0;require = requires[j];j++) {
+ if (!(path in deps.requires)) {
+ deps.requires[path] = {};
+ }
+ deps.requires[path][require] = true;
+ }
+ }
+};
+goog.define("goog.ENABLE_DEBUG_LOADER", true);
+goog.logToConsole_ = function(msg) {
+ if (goog.global.console) {
+ goog.global.console["error"](msg);
+ }
+};
+goog.require = function(name) {
+ if (!COMPILED) {
+ if (goog.ENABLE_DEBUG_LOADER && goog.IS_OLD_IE_) {
+ goog.maybeProcessDeferredDep_(name);
+ }
+ if (goog.isProvided_(name)) {
+ if (goog.isInModuleLoader_()) {
+ return goog.module.getInternal_(name);
+ } else {
+ return null;
+ }
+ }
+ if (goog.ENABLE_DEBUG_LOADER) {
+ var path = goog.getPathFromDeps_(name);
+ if (path) {
+ goog.included_[path] = true;
+ goog.writeScripts_();
+ return null;
+ }
+ }
+ var errorMessage = "goog.require could not find: " + name;
+ goog.logToConsole_(errorMessage);
+ throw Error(errorMessage);
+ }
+};
+goog.basePath = "";
+goog.global.CLOSURE_BASE_PATH;
+goog.global.CLOSURE_NO_DEPS;
+goog.global.CLOSURE_IMPORT_SCRIPT;
+goog.nullFunction = function() {
+};
+goog.identityFunction = function(opt_returnValue, var_args) {
+ return opt_returnValue;
+};
+goog.abstractMethod = function() {
+ throw Error("unimplemented abstract method");
+};
+goog.addSingletonGetter = function(ctor) {
+ ctor.getInstance = function() {
+ if (ctor.instance_) {
+ return ctor.instance_;
+ }
+ if (goog.DEBUG) {
+ goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor;
+ }
+ return ctor.instance_ = new ctor;
+ };
+};
+goog.instantiatedSingletons_ = [];
+goog.define("goog.LOAD_MODULE_USING_EVAL", true);
+goog.define("goog.SEAL_MODULE_EXPORTS", goog.DEBUG);
+goog.loadedModules_ = {};
+goog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER;
+if (goog.DEPENDENCIES_ENABLED) {
+ goog.included_ = {};
+ goog.dependencies_ = {pathIsModule:{}, nameToPath:{}, requires:{}, visited:{}, written:{}, deferred:{}};
+ goog.inHtmlDocument_ = function() {
+ var doc = goog.global.document;
+ return typeof doc != "undefined" && "write" in doc;
+ };
+ goog.findBasePath_ = function() {
+ if (goog.global.CLOSURE_BASE_PATH) {
+ goog.basePath = goog.global.CLOSURE_BASE_PATH;
+ return;
+ } else {
+ if (!goog.inHtmlDocument_()) {
+ return;
+ }
+ }
+ var doc = goog.global.document;
+ var scripts = doc.getElementsByTagName("script");
+ for (var i = scripts.length - 1;i >= 0;--i) {
+ var script = (scripts[i]);
+ var src = script.src;
+ var qmark = src.lastIndexOf("?");
+ var l = qmark == -1 ? src.length : qmark;
+ if (src.substr(l - 7, 7) == "base.js") {
+ goog.basePath = src.substr(0, l - 7);
+ return;
+ }
+ }
+ };
+ goog.importScript_ = function(src, opt_sourceText) {
+ var importScript = goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_;
+ if (importScript(src, opt_sourceText)) {
+ goog.dependencies_.written[src] = true;
+ }
+ };
+ goog.IS_OLD_IE_ = !goog.global.atob && goog.global.document && goog.global.document.all;
+ goog.importModule_ = function(src) {
+ var bootstrap = 'goog.retrieveAndExecModule_("' + src + '");';
+ if (goog.importScript_("", bootstrap)) {
+ goog.dependencies_.written[src] = true;
+ }
+ };
+ goog.queuedModules_ = [];
+ goog.wrapModule_ = function(srcUrl, scriptText) {
+ if (!goog.LOAD_MODULE_USING_EVAL || !goog.isDef(goog.global.JSON)) {
+ return "" + "goog.loadModule(function(exports) {" + '"use strict";' + scriptText + "\n" + ";return exports" + "});" + "\n//# sourceURL=" + srcUrl + "\n";
+ } else {
+ return "" + "goog.loadModule(" + goog.global.JSON.stringify(scriptText + "\n//# sourceURL=" + srcUrl + "\n") + ");";
+ }
+ };
+ goog.loadQueuedModules_ = function() {
+ var count = goog.queuedModules_.length;
+ if (count > 0) {
+ var queue = goog.queuedModules_;
+ goog.queuedModules_ = [];
+ for (var i = 0;i < count;i++) {
+ var path = queue[i];
+ goog.maybeProcessDeferredPath_(path);
+ }
+ }
+ };
+ goog.maybeProcessDeferredDep_ = function(name) {
+ if (goog.isDeferredModule_(name) && goog.allDepsAreAvailable_(name)) {
+ var path = goog.getPathFromDeps_(name);
+ goog.maybeProcessDeferredPath_(goog.basePath + path);
+ }
+ };
+ goog.isDeferredModule_ = function(name) {
+ var path = goog.getPathFromDeps_(name);
+ if (path && goog.dependencies_.pathIsModule[path]) {
+ var abspath = goog.basePath + path;
+ return abspath in goog.dependencies_.deferred;
+ }
+ return false;
+ };
+ goog.allDepsAreAvailable_ = function(name) {
+ var path = goog.getPathFromDeps_(name);
+ if (path && path in goog.dependencies_.requires) {
+ for (var requireName in goog.dependencies_.requires[path]) {
+ if (!goog.isProvided_(requireName) && !goog.isDeferredModule_(requireName)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ };
+ goog.maybeProcessDeferredPath_ = function(abspath) {
+ if (abspath in goog.dependencies_.deferred) {
+ var src = goog.dependencies_.deferred[abspath];
+ delete goog.dependencies_.deferred[abspath];
+ goog.globalEval(src);
+ }
+ };
+ goog.loadModule = function(moduleDef) {
+ var previousState = goog.moduleLoaderState_;
+ try {
+ goog.moduleLoaderState_ = {moduleName:undefined, declareTestMethods:false};
+ var exports;
+ if (goog.isFunction(moduleDef)) {
+ exports = moduleDef.call(goog.global, {});
+ } else {
+ if (goog.isString(moduleDef)) {
+ exports = goog.loadModuleFromSource_.call(goog.global, moduleDef);
+ } else {
+ throw Error("Invalid module definition");
+ }
+ }
+ var moduleName = goog.moduleLoaderState_.moduleName;
+ if (!goog.isString(moduleName) || !moduleName) {
+ throw Error('Invalid module name "' + moduleName + '"');
+ }
+ if (goog.moduleLoaderState_.declareLegacyNamespace) {
+ goog.constructNamespace_(moduleName, exports);
+ } else {
+ if (goog.SEAL_MODULE_EXPORTS && Object.seal) {
+ Object.seal(exports);
+ }
+ }
+ goog.loadedModules_[moduleName] = exports;
+ if (goog.moduleLoaderState_.declareTestMethods) {
+ for (var entry in exports) {
+ if (entry.indexOf("test", 0) === 0 || entry == "tearDown" || entry == "setUp" || entry == "setUpPage" || entry == "tearDownPage") {
+ goog.global[entry] = exports[entry];
+ }
+ }
+ }
+ } finally {
+ goog.moduleLoaderState_ = previousState;
+ }
+ };
+ goog.loadModuleFromSource_ = function(source) {
+ var exports = {};
+ eval(arguments[0]);
+ return exports;
+ };
+ goog.writeScriptTag_ = function(src, opt_sourceText) {
+ if (goog.inHtmlDocument_()) {
+ var doc = goog.global.document;
+ if (doc.readyState == "complete") {
+ var isDeps = /\bdeps.js$/.test(src);
+ if (isDeps) {
+ return false;
+ } else {
+ throw Error('Cannot write "' + src + '" after document load');
+ }
+ }
+ var isOldIE = goog.IS_OLD_IE_;
+ if (opt_sourceText === undefined) {
+ if (!isOldIE) {
+ doc.write('<script type="text/javascript" src="' + src + '"></' + "script>");
+ } else {
+ var state = " onreadystatechange='goog.onScriptLoad_(this, " + ++goog.lastNonModuleScriptIndex_ + ")' ";
+ doc.write('<script type="text/javascript" src="' + src + '"' + state + "></" + "script>");
+ }
+ } else {
+ doc.write('<script type="text/javascript">' + opt_sourceText + "</" + "script>");
+ }
+ return true;
+ } else {
+ return false;
+ }
+ };
+ goog.lastNonModuleScriptIndex_ = 0;
+ goog.onScriptLoad_ = function(script, scriptIndex) {
+ if (script.readyState == "complete" && goog.lastNonModuleScriptIndex_ == scriptIndex) {
+ goog.loadQueuedModules_();
+ }
+ return true;
+ };
+ goog.writeScripts_ = function() {
+ var scripts = [];
+ var seenScript = {};
+ var deps = goog.dependencies_;
+ function visitNode(path) {
+ if (path in deps.written) {
+ return;
+ }
+ if (path in deps.visited) {
+ if (!(path in seenScript)) {
+ seenScript[path] = true;
+ scripts.push(path);
+ }
+ return;
+ }
+ deps.visited[path] = true;
+ if (path in deps.requires) {
+ for (var requireName in deps.requires[path]) {
+ if (!goog.isProvided_(requireName)) {
+ if (requireName in deps.nameToPath) {
+ visitNode(deps.nameToPath[requireName]);
+ } else {
+ throw Error("Undefined nameToPath for " + requireName);
+ }
+ }
+ }
+ }
+ if (!(path in seenScript)) {
+ seenScript[path] = true;
+ scripts.push(path);
+ }
+ }
+ for (var path in goog.included_) {
+ if (!deps.written[path]) {
+ visitNode(path);
+ }
+ }
+ for (var i = 0;i < scripts.length;i++) {
+ var path = scripts[i];
+ goog.dependencies_.written[path] = true;
+ }
+ var moduleState = goog.moduleLoaderState_;
+ goog.moduleLoaderState_ = null;
+ var loadingModule = false;
+ for (var i = 0;i < scripts.length;i++) {
+ var path = scripts[i];
+ if (path) {
+ if (!deps.pathIsModule[path]) {
+ goog.importScript_(goog.basePath + path);
+ } else {
+ loadingModule = true;
+ goog.importModule_(goog.basePath + path);
+ }
+ } else {
+ goog.moduleLoaderState_ = moduleState;
+ throw Error("Undefined script input");
+ }
+ }
+ goog.moduleLoaderState_ = moduleState;
+ };
+ goog.getPathFromDeps_ = function(rule) {
+ if (rule in goog.dependencies_.nameToPath) {
+ return goog.dependencies_.nameToPath[rule];
+ } else {
+ return null;
+ }
+ };
+ goog.findBasePath_();
+ if (!goog.global.CLOSURE_NO_DEPS) {
+ goog.importScript_(goog.basePath + "deps.js");
+ }
+}
+goog.normalizePath_ = function(path) {
+ var components = path.split("/");
+ var i = 0;
+ while (i < components.length) {
+ if (components[i] == ".") {
+ components.splice(i, 1);
+ } else {
+ if (i && components[i] == ".." && components[i - 1] && components[i - 1] != "..") {
+ components.splice(--i, 2);
+ } else {
+ i++;
+ }
+ }
+ }
+ return components.join("/");
+};
+goog.retrieveAndExecModule_ = function(src) {
+ if (!COMPILED) {
+ var originalPath = src;
+ src = goog.normalizePath_(src);
+ var importScript = goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_;
+ var scriptText = null;
+ var xhr = new goog.global["XMLHttpRequest"];
+ xhr.onload = function() {
+ scriptText = this.responseText;
+ };
+ xhr.open("get", src, false);
+ xhr.send();
+ scriptText = xhr.responseText;
+ if (scriptText != null) {
+ var execModuleScript = goog.wrapModule_(src, scriptText);
+ var isOldIE = goog.IS_OLD_IE_;
+ if (isOldIE) {
+ goog.dependencies_.deferred[originalPath] = execModuleScript;
+ goog.queuedModules_.push(originalPath);
+ } else {
+ importScript(src, execModuleScript);
+ }
+ } else {
+ throw new Error("load of " + src + "failed");
+ }
+ }
+};
+goog.typeOf = function(value) {
+ var s = typeof value;
+ if (s == "object") {
+ if (value) {
+ if (value instanceof Array) {
+ return "array";
+ } else {
+ if (value instanceof Object) {
+ return s;
+ }
+ }
+ var className = Object.prototype.toString.call((value));
+ if (className == "[object Window]") {
+ return "object";
+ }
+ if (className == "[object Array]" || typeof value.length == "number" && typeof value.splice != "undefined" && typeof value.propertyIsEnumerable != "undefined" && !value.propertyIsEnumerable("splice")) {
+ return "array";
+ }
+ if (className == "[object Function]" || typeof value.call != "undefined" && typeof value.propertyIsEnumerable != "undefined" && !value.propertyIsEnumerable("call")) {
+ return "function";
+ }
+ } else {
+ return "null";
+ }
+ } else {
+ if (s == "function" && typeof value.call == "undefined") {
+ return "object";
+ }
+ }
+ return s;
+};
+goog.isNull = function(val) {
+ return val === null;
+};
+goog.isDefAndNotNull = function(val) {
+ return val != null;
+};
+goog.isArray = function(val) {
+ return goog.typeOf(val) == "array";
+};
+goog.isArrayLike = function(val) {
+ var type = goog.typeOf(val);
+ return type == "array" || type == "object" && typeof val.length == "number";
+};
+goog.isDateLike = function(val) {
+ return goog.isObject(val) && typeof val.getFullYear == "function";
+};
+goog.isString = function(val) {
+ return typeof val == "string";
+};
+goog.isBoolean = function(val) {
+ return typeof val == "boolean";
+};
+goog.isNumber = function(val) {
+ return typeof val == "number";
+};
+goog.isFunction = function(val) {
+ return goog.typeOf(val) == "function";
+};
+goog.isObject = function(val) {
+ var type = typeof val;
+ return type == "object" && val != null || type == "function";
+};
+goog.getUid = function(obj) {
+ return obj[goog.UID_PROPERTY_] || (obj[goog.UID_PROPERTY_] = ++goog.uidCounter_);
+};
+goog.hasUid = function(obj) {
+ return!!obj[goog.UID_PROPERTY_];
+};
+goog.removeUid = function(obj) {
+ if ("removeAttribute" in obj) {
+ obj.removeAttribute(goog.UID_PROPERTY_);
+ }
+ try {
+ delete obj[goog.UID_PROPERTY_];
+ } catch (ex) {
+ }
+};
+goog.UID_PROPERTY_ = "closure_uid_" + (Math.random() * 1E9 >>> 0);
+goog.uidCounter_ = 0;
+goog.getHashCode = goog.getUid;
+goog.removeHashCode = goog.removeUid;
+goog.cloneObject = function(obj) {
+ var type = goog.typeOf(obj);
+ if (type == "object" || type == "array") {
+ if (obj.clone) {
+ return obj.clone();
+ }
+ var clone = type == "array" ? [] : {};
+ for (var key in obj) {
+ clone[key] = goog.cloneObject(obj[key]);
+ }
+ return clone;
+ }
+ return obj;
+};
+goog.bindNative_ = function(fn, selfObj, var_args) {
+ return(fn.call.apply(fn.bind, arguments));
+};
+goog.bindJs_ = function(fn, selfObj, var_args) {
+ if (!fn) {
+ throw new Error;
+ }
+ if (arguments.length > 2) {
+ var boundArgs = Array.prototype.slice.call(arguments, 2);
+ return function() {
+ var newArgs = Array.prototype.slice.call(arguments);
+ Array.prototype.unshift.apply(newArgs, boundArgs);
+ return fn.apply(selfObj, newArgs);
+ };
+ } else {
+ return function() {
+ return fn.apply(selfObj, arguments);
+ };
+ }
+};
+goog.bind = function(fn, selfObj, var_args) {
+ if (Function.prototype.bind && Function.prototype.bind.toString().indexOf("native code") != -1) {
+ goog.bind = goog.bindNative_;
+ } else {
+ goog.bind = goog.bindJs_;
+ }
+ return goog.bind.apply(null, arguments);
+};
+goog.partial = function(fn, var_args) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ return function() {
+ var newArgs = args.slice();
+ newArgs.push.apply(newArgs, arguments);
+ return fn.apply(this, newArgs);
+ };
+};
+goog.mixin = function(target, source) {
+ for (var x in source) {
+ target[x] = source[x];
+ }
+};
+goog.now = goog.TRUSTED_SITE && Date.now || function() {
+ return+new Date;
+};
+goog.globalEval = function(script) {
+ if (goog.global.execScript) {
+ goog.global.execScript(script, "JavaScript");
+ } else {
+ if (goog.global.eval) {
+ if (goog.evalWorksForGlobals_ == null) {
+ goog.global.eval("var _et_ = 1;");
+ if (typeof goog.global["_et_"] != "undefined") {
+ delete goog.global["_et_"];
+ goog.evalWorksForGlobals_ = true;
+ } else {
+ goog.evalWorksForGlobals_ = false;
+ }
+ }
+ if (goog.evalWorksForGlobals_) {
+ goog.global.eval(script);
+ } else {
+ var doc = goog.global.document;
+ var scriptElt = doc.createElement("script");
+ scriptElt.type = "text/javascript";
+ scriptElt.defer = false;
+ scriptElt.appendChild(doc.createTextNode(script));
+ doc.body.appendChild(scriptElt);
+ doc.body.removeChild(scriptElt);
+ }
+ } else {
+ throw Error("goog.globalEval not available");
+ }
+ }
+};
+goog.evalWorksForGlobals_ = null;
+goog.cssNameMapping_;
+goog.cssNameMappingStyle_;
+goog.getCssName = function(className, opt_modifier) {
+ var getMapping = function(cssName) {
+ return goog.cssNameMapping_[cssName] || cssName;
+ };
+ var renameByParts = function(cssName) {
+ var parts = cssName.split("-");
+ var mapped = [];
+ for (var i = 0;i < parts.length;i++) {
+ mapped.push(getMapping(parts[i]));
+ }
+ return mapped.join("-");
+ };
+ var rename;
+ if (goog.cssNameMapping_) {
+ rename = goog.cssNameMappingStyle_ == "BY_WHOLE" ? getMapping : renameByParts;
+ } else {
+ rename = function(a) {
+ return a;
+ };
+ }
+ if (opt_modifier) {
+ return className + "-" + rename(opt_modifier);
+ } else {
+ return rename(className);
+ }
+};
+goog.setCssNameMapping = function(mapping, opt_style) {
+ goog.cssNameMapping_ = mapping;
+ goog.cssNameMappingStyle_ = opt_style;
+};
+goog.global.CLOSURE_CSS_NAME_MAPPING;
+if (!COMPILED && goog.global.CLOSURE_CSS_NAME_MAPPING) {
+ goog.cssNameMapping_ = goog.global.CLOSURE_CSS_NAME_MAPPING;
+}
+goog.getMsg = function(str, opt_values) {
+ if (opt_values) {
+ str = str.replace(/\{\$([^}]+)}/g, function(match, key) {
+ return key in opt_values ? opt_values[key] : match;
+ });
+ }
+ return str;
+};
+goog.getMsgWithFallback = function(a, b) {
+ return a;
+};
+goog.exportSymbol = function(publicPath, object, opt_objectToExportTo) {
+ goog.exportPath_(publicPath, object, opt_objectToExportTo);
+};
+goog.exportProperty = function(object, publicName, symbol) {
+ object[publicName] = symbol;
+};
+goog.inherits = function(childCtor, parentCtor) {
+ function tempCtor() {
+ }
+ tempCtor.prototype = parentCtor.prototype;
+ childCtor.superClass_ = parentCtor.prototype;
+ childCtor.prototype = new tempCtor;
+ childCtor.prototype.constructor = childCtor;
+ childCtor.base = function(me, methodName, var_args) {
+ var args = new Array(arguments.length - 2);
+ for (var i = 2;i < arguments.length;i++) {
+ args[i - 2] = arguments[i];
+ }
+ return parentCtor.prototype[methodName].apply(me, args);
+ };
+};
+goog.base = function(me, opt_methodName, var_args) {
+ var caller = arguments.callee.caller;
+ if (goog.STRICT_MODE_COMPATIBLE || goog.DEBUG && !caller) {
+ throw Error("arguments.caller not defined. goog.base() cannot be used " + "with strict mode code. See " + "http://www.ecma-international.org/ecma-262/5.1/#sec-C");
+ }
+ if (caller.superClass_) {
+ var ctorArgs = new Array(arguments.length - 1);
+ for (var i = 1;i < arguments.length;i++) {
+ ctorArgs[i - 1] = arguments[i];
+ }
+ return caller.superClass_.constructor.apply(me, ctorArgs);
+ }
+ var args = new Array(arguments.length - 2);
+ for (var i = 2;i < arguments.length;i++) {
+ args[i - 2] = arguments[i];
+ }
+ var foundCaller = false;
+ for (var ctor = me.constructor;ctor;ctor = ctor.superClass_ && ctor.superClass_.constructor) {
+ if (ctor.prototype[opt_methodName] === caller) {
+ foundCaller = true;
+ } else {
+ if (foundCaller) {
+ return ctor.prototype[opt_methodName].apply(me, args);
+ }
+ }
+ }
+ if (me[opt_methodName] === caller) {
+ return me.constructor.prototype[opt_methodName].apply(me, args);
+ } else {
+ throw Error("goog.base called from a method of one name " + "to a method of a different name");
+ }
+};
+goog.scope = function(fn) {
+ fn.call(goog.global);
+};
+if (!COMPILED) {
+ goog.global["COMPILED"] = COMPILED;
+}
+goog.defineClass = function(superClass, def) {
+ var constructor = def.constructor;
+ var statics = def.statics;
+ if (!constructor || constructor == Object.prototype.constructor) {
+ constructor = function() {
+ throw Error("cannot instantiate an interface (no constructor defined).");
+ };
+ }
+ var cls = goog.defineClass.createSealingConstructor_(constructor, superClass);
+ if (superClass) {
+ goog.inherits(cls, superClass);
+ }
+ delete def.constructor;
+ delete def.statics;
+ goog.defineClass.applyProperties_(cls.prototype, def);
+ if (statics != null) {
+ if (statics instanceof Function) {
+ statics(cls);
+ } else {
+ goog.defineClass.applyProperties_(cls, statics);
+ }
+ }
+ return cls;
+};
+goog.defineClass.ClassDescriptor;
+goog.define("goog.defineClass.SEAL_CLASS_INSTANCES", goog.DEBUG);
+goog.defineClass.createSealingConstructor_ = function(ctr, superClass) {
+ if (goog.defineClass.SEAL_CLASS_INSTANCES && Object.seal instanceof Function) {
+ if (superClass && superClass.prototype && superClass.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_]) {
+ return ctr;
+ }
+ var wrappedCtr = function() {
+ var instance = ctr.apply(this, arguments) || this;
+ instance[goog.UID_PROPERTY_] = instance[goog.UID_PROPERTY_];
+ if (this.constructor === wrappedCtr) {
+ Object.seal(instance);
+ }
+ return instance;
+ };
+ return wrappedCtr;
+ }
+ return ctr;
+};
+goog.defineClass.OBJECT_PROTOTYPE_FIELDS_ = ["constructor", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "valueOf"];
+goog.defineClass.applyProperties_ = function(target, source) {
+ var key;
+ for (key in source) {
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
+ target[key] = source[key];
+ }
+ }
+ for (var i = 0;i < goog.defineClass.OBJECT_PROTOTYPE_FIELDS_.length;i++) {
+ key = goog.defineClass.OBJECT_PROTOTYPE_FIELDS_[i];
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
+ target[key] = source[key];
+ }
+ }
+};
+goog.tagUnsealableClass = function(ctr) {
+ if (!COMPILED && goog.defineClass.SEAL_CLASS_INSTANCES) {
+ ctr.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_] = true;
+ }
+};
+goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_ = "goog_defineClass_legacy_unsealable";
+goog.provide("goog.debug.Error");
+goog.debug.Error = function(opt_msg) {
+ if (Error.captureStackTrace) {
+ Error.captureStackTrace(this, goog.debug.Error);
+ } else {
+ var stack = (new Error).stack;
+ if (stack) {
+ this.stack = stack;
+ }
+ }
+ if (opt_msg) {
+ this.message = String(opt_msg);
+ }
+};
+goog.inherits(goog.debug.Error, Error);
+goog.debug.Error.prototype.name = "CustomError";
+goog.provide("goog.object");
+goog.object.forEach = function(obj, f, opt_obj) {
+ for (var key in obj) {
+ f.call(opt_obj, obj[key], key, obj);
+ }
+};
+goog.object.filter = function(obj, f, opt_obj) {
+ var res = {};
+ for (var key in obj) {
+ if (f.call(opt_obj, obj[key], key, obj)) {
+ res[key] = obj[key];
+ }
+ }
+ return res;
+};
+goog.object.map = function(obj, f, opt_obj) {
+ var res = {};
+ for (var key in obj) {
+ res[key] = f.call(opt_obj, obj[key], key, obj);
+ }
+ return res;
+};
+goog.object.some = function(obj, f, opt_obj) {
+ for (var key in obj) {
+ if (f.call(opt_obj, obj[key], key, obj)) {
+ return true;
+ }
+ }
+ return false;
+};
+goog.object.every = function(obj, f, opt_obj) {
+ for (var key in obj) {
+ if (!f.call(opt_obj, obj[key], key, obj)) {
+ return false;
+ }
+ }
+ return true;
+};
+goog.object.getCount = function(obj) {
+ var rv = 0;
+ for (var key in obj) {
+ rv++;
+ }
+ return rv;
+};
+goog.object.getAnyKey = function(obj) {
+ for (var key in obj) {
+ return key;
+ }
+};
+goog.object.getAnyValue = function(obj) {
+ for (var key in obj) {
+ return obj[key];
+ }
+};
+goog.object.contains = function(obj, val) {
+ return goog.object.containsValue(obj, val);
+};
+goog.object.getValues = function(obj) {
+ var res = [];
+ var i = 0;
+ for (var key in obj) {
+ res[i++] = obj[key];
+ }
+ return res;
+};
+goog.object.getKeys = function(obj) {
+ var res = [];
+ var i = 0;
+ for (var key in obj) {
+ res[i++] = key;
+ }
+ return res;
+};
+goog.object.getValueByKeys = function(obj, var_args) {
+ var isArrayLike = goog.isArrayLike(var_args);
+ var keys = isArrayLike ? var_args : arguments;
+ for (var i = isArrayLike ? 0 : 1;i < keys.length;i++) {
+ obj = obj[keys[i]];
+ if (!goog.isDef(obj)) {
+ break;
+ }
+ }
+ return obj;
+};
+goog.object.containsKey = function(obj, key) {
+ return key in obj;
+};
+goog.object.containsValue = function(obj, val) {
+ for (var key in obj) {
+ if (obj[key] == val) {
+ return true;
+ }
+ }
+ return false;
+};
+goog.object.findKey = function(obj, f, opt_this) {
+ for (var key in obj) {
+ if (f.call(opt_this, obj[key], key, obj)) {
+ return key;
+ }
+ }
+ return undefined;
+};
+goog.object.findValue = function(obj, f, opt_this) {
+ var key = goog.object.findKey(obj, f, opt_this);
+ return key && obj[key];
+};
+goog.object.isEmpty = function(obj) {
+ for (var key in obj) {
+ return false;
+ }
+ return true;
+};
+goog.object.clear = function(obj) {
+ for (var i in obj) {
+ delete obj[i];
+ }
+};
+goog.object.remove = function(obj, key) {
+ var rv;
+ if (rv = key in obj) {
+ delete obj[key];
+ }
+ return rv;
+};
+goog.object.add = function(obj, key, val) {
+ if (key in obj) {
+ throw Error('The object already contains the key "' + key + '"');
+ }
+ goog.object.set(obj, key, val);
+};
+goog.object.get = function(obj, key, opt_val) {
+ if (key in obj) {
+ return obj[key];
+ }
+ return opt_val;
+};
+goog.object.set = function(obj, key, value) {
+ obj[key] = value;
+};
+goog.object.setIfUndefined = function(obj, key, value) {
+ return key in obj ? obj[key] : obj[key] = value;
+};
+goog.object.setWithReturnValueIfNotSet = function(obj, key, f) {
+ if (key in obj) {
+ return obj[key];
+ }
+ var val = f();
+ obj[key] = val;
+ return val;
+};
+goog.object.equals = function(a, b) {
+ for (var k in a) {
+ if (!(k in b) || a[k] !== b[k]) {
+ return false;
+ }
+ }
+ for (var k in b) {
+ if (!(k in a)) {
+ return false;
+ }
+ }
+ return true;
+};
+goog.object.clone = function(obj) {
+ var res = {};
+ for (var key in obj) {
+ res[key] = obj[key];
+ }
+ return res;
+};
+goog.object.unsafeClone = function(obj) {
+ var type = goog.typeOf(obj);
+ if (type == "object" || type == "array") {
+ if (obj.clone) {
+ return obj.clone();
+ }
+ var clone = type == "array" ? [] : {};
+ for (var key in obj) {
+ clone[key] = goog.object.unsafeClone(obj[key]);
+ }
+ return clone;
+ }
+ return obj;
+};
+goog.object.transpose = function(obj) {
+ var transposed = {};
+ for (var key in obj) {
+ transposed[obj[key]] = key;
+ }
+ return transposed;
+};
+goog.object.PROTOTYPE_FIELDS_ = ["constructor", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "valueOf"];
+goog.object.extend = function(target, var_args) {
+ var key, source;
+ for (var i = 1;i < arguments.length;i++) {
+ source = arguments[i];
+ for (key in source) {
+ target[key] = source[key];
+ }
+ for (var j = 0;j < goog.object.PROTOTYPE_FIELDS_.length;j++) {
+ key = goog.object.PROTOTYPE_FIELDS_[j];
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
+ target[key] = source[key];
+ }
+ }
+ }
+};
+goog.object.create = function(var_args) {
+ var argLength = arguments.length;
+ if (argLength == 1 && goog.isArray(arguments[0])) {
+ return goog.object.create.apply(null, arguments[0]);
+ }
+ if (argLength % 2) {
+ throw Error("Uneven number of arguments");
+ }
+ var rv = {};
+ for (var i = 0;i < argLength;i += 2) {
+ rv[arguments[i]] = arguments[i + 1];
+ }
+ return rv;
+};
+goog.object.createSet = function(var_args) {
+ var argLength = arguments.length;
+ if (argLength == 1 && goog.isArray(arguments[0])) {
+ return goog.object.createSet.apply(null, arguments[0]);
+ }
+ var rv = {};
+ for (var i = 0;i < argLength;i++) {
+ rv[arguments[i]] = true;
+ }
+ return rv;
+};
+goog.object.createImmutableView = function(obj) {
+ var result = obj;
+ if (Object.isFrozen && !Object.isFrozen(obj)) {
+ result = Object.create(obj);
+ Object.freeze(result);
+ }
+ return result;
+};
+goog.object.isImmutableView = function(obj) {
+ return!!Object.isFrozen && Object.isFrozen(obj);
+};
+goog.provide("goog.dom.NodeType");
+goog.dom.NodeType = {ELEMENT:1, ATTRIBUTE:2, TEXT:3, CDATA_SECTION:4, ENTITY_REFERENCE:5, ENTITY:6, PROCESSING_INSTRUCTION:7, COMMENT:8, DOCUMENT:9, DOCUMENT_TYPE:10, DOCUMENT_FRAGMENT:11, NOTATION:12};
+goog.provide("goog.json");
+goog.provide("goog.json.Replacer");
+goog.provide("goog.json.Reviver");
+goog.provide("goog.json.Serializer");
+goog.define("goog.json.USE_NATIVE_JSON", false);
+goog.json.isValid = function(s) {
+ if (/^\s*$/.test(s)) {
+ return false;
+ }
+ var backslashesRe = /\\["\\\/bfnrtu]/g;
+ var simpleValuesRe = /"[^"\\\n\r\u2028\u2029\x00-\x08\x0a-\x1f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
+ var openBracketsRe = /(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g;
+ var remainderRe = /^[\],:{}\s\u2028\u2029]*$/;
+ return remainderRe.test(s.replace(backslashesRe, "@").replace(simpleValuesRe, "]").replace(openBracketsRe, ""));
+};
+goog.json.parse = goog.json.USE_NATIVE_JSON ? (goog.global["JSON"]["parse"]) : function(s) {
+ var o = String(s);
+ if (goog.json.isValid(o)) {
+ try {
+ return(eval("(" + o + ")"));
+ } catch (ex) {
+ }
+ }
+ throw Error("Invalid JSON string: " + o);
+};
+goog.json.unsafeParse = goog.json.USE_NATIVE_JSON ? (goog.global["JSON"]["parse"]) : function(s) {
+ return(eval("(" + s + ")"));
+};
+goog.json.Replacer;
+goog.json.Reviver;
+goog.json.serialize = goog.json.USE_NATIVE_JSON ? (goog.global["JSON"]["stringify"]) : function(object, opt_replacer) {
+ return(new goog.json.Serializer(opt_replacer)).serialize(object);
+};
+goog.json.Serializer = function(opt_replacer) {
+ this.replacer_ = opt_replacer;
+};
+goog.json.Serializer.prototype.serialize = function(object) {
+ var sb = [];
+ this.serializeInternal(object, sb);
+ return sb.join("");
+};
+goog.json.Serializer.prototype.serializeInternal = function(object, sb) {
+ switch(typeof object) {
+ case "string":
+ this.serializeString_((object), sb);
+ break;
+ case "number":
+ this.serializeNumber_((object), sb);
+ break;
+ case "boolean":
+ sb.push(object);
+ break;
+ case "undefined":
+ sb.push("null");
+ break;
+ case "object":
+ if (object == null) {
+ sb.push("null");
+ break;
+ }
+ if (goog.isArray(object)) {
+ this.serializeArray((object), sb);
+ break;
+ }
+ this.serializeObject_((object), sb);
+ break;
+ case "function":
+ break;
+ default:
+ throw Error("Unknown type: " + typeof object);;
+ }
+};
+goog.json.Serializer.charToJsonCharCache_ = {'"':'\\"', "\\":"\\\\", "/":"\\/", "\b":"\\b", "\f":"\\f", "\n":"\\n", "\r":"\\r", "\t":"\\t", "\x0B":"\\u000b"};
+goog.json.Serializer.charsToReplace_ = /\uffff/.test("\uffff") ? /[\\\"\x00-\x1f\x7f-\uffff]/g : /[\\\"\x00-\x1f\x7f-\xff]/g;
+goog.json.Serializer.prototype.serializeString_ = function(s, sb) {
+ sb.push('"', s.replace(goog.json.Serializer.charsToReplace_, function(c) {
+ if (c in goog.json.Serializer.charToJsonCharCache_) {
+ return goog.json.Serializer.charToJsonCharCache_[c];
+ }
+ var cc = c.charCodeAt(0);
+ var rv = "\\u";
+ if (cc < 16) {
+ rv += "000";
+ } else {
+ if (cc < 256) {
+ rv += "00";
+ } else {
+ if (cc < 4096) {
+ rv += "0";
+ }
+ }
+ }
+ return goog.json.Serializer.charToJsonCharCache_[c] = rv + cc.toString(16);
+ }), '"');
+};
+goog.json.Serializer.prototype.serializeNumber_ = function(n, sb) {
+ sb.push(isFinite(n) && !isNaN(n) ? n : "null");
+};
+goog.json.Serializer.prototype.serializeArray = function(arr, sb) {
+ var l = arr.length;
+ sb.push("[");
+ var sep = "";
+ for (var i = 0;i < l;i++) {
+ sb.push(sep);
+ var value = arr[i];
+ this.serializeInternal(this.replacer_ ? this.replacer_.call(arr, String(i), value) : value, sb);
+ sep = ",";
+ }
+ sb.push("]");
+};
+goog.json.Serializer.prototype.serializeObject_ = function(obj, sb) {
+ sb.push("{");
+ var sep = "";
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
+ var value = obj[key];
+ if (typeof value != "function") {
+ sb.push(sep);
+ this.serializeString_(key, sb);
+ sb.push(":");
+ this.serializeInternal(this.replacer_ ? this.replacer_.call(obj, key, value) : value, sb);
+ sep = ",";
+ }
+ }
+ }
+ sb.push("}");
+};
+goog.provide("goog.string");
+goog.provide("goog.string.Unicode");
+goog.define("goog.string.DETECT_DOUBLE_ESCAPING", false);
+goog.define("goog.string.FORCE_NON_DOM_HTML_UNESCAPING", false);
+goog.string.Unicode = {NBSP:"\u00a0"};
+goog.string.startsWith = function(str, prefix) {
+ return str.lastIndexOf(prefix, 0) == 0;
+};
+goog.string.endsWith = function(str, suffix) {
+ var l = str.length - suffix.length;
+ return l >= 0 && str.indexOf(suffix, l) == l;
+};
+goog.string.caseInsensitiveStartsWith = function(str, prefix) {
+ return goog.string.caseInsensitiveCompare(prefix, str.substr(0, prefix.length)) == 0;
+};
+goog.string.caseInsensitiveEndsWith = function(str, suffix) {
+ return goog.string.caseInsensitiveCompare(suffix, str.substr(str.length - suffix.length, suffix.length)) == 0;
+};
+goog.string.caseInsensitiveEquals = function(str1, str2) {
+ return str1.toLowerCase() == str2.toLowerCase();
+};
+goog.string.subs = function(str, var_args) {
+ var splitParts = str.split("%s");
+ var returnString = "";
+ var subsArguments = Array.prototype.slice.call(arguments, 1);
+ while (subsArguments.length && splitParts.length > 1) {
+ returnString += splitParts.shift() + subsArguments.shift();
+ }
+ return returnString + splitParts.join("%s");
+};
+goog.string.collapseWhitespace = function(str) {
+ return str.replace(/[\s\xa0]+/g, " ").replace(/^\s+|\s+$/g, "");
+};
+goog.string.isEmptyOrWhitespace = function(str) {
+ return/^[\s\xa0]*$/.test(str);
+};
+goog.string.isEmptyString = function(str) {
+ return str.length == 0;
+};
+goog.string.isEmpty = goog.string.isEmptyOrWhitespace;
+goog.string.isEmptyOrWhitespaceSafe = function(str) {
+ return goog.string.isEmptyOrWhitespace(goog.string.makeSafe(str));
+};
+goog.string.isEmptySafe = goog.string.isEmptyOrWhitespaceSafe;
+goog.string.isBreakingWhitespace = function(str) {
+ return!/[^\t\n\r ]/.test(str);
+};
+goog.string.isAlpha = function(str) {
+ return!/[^a-zA-Z]/.test(str);
+};
+goog.string.isNumeric = function(str) {
+ return!/[^0-9]/.test(str);
+};
+goog.string.isAlphaNumeric = function(str) {
+ return!/[^a-zA-Z0-9]/.test(str);
+};
+goog.string.isSpace = function(ch) {
+ return ch == " ";
+};
+goog.string.isUnicodeChar = function(ch) {
+ return ch.length == 1 && ch >= " " && ch <= "~" || ch >= "\u0080" && ch <= "\ufffd";
+};
+goog.string.stripNewlines = function(str) {
+ return str.replace(/(\r\n|\r|\n)+/g, " ");
+};
+goog.string.canonicalizeNewlines = function(str) {
+ return str.replace(/(\r\n|\r|\n)/g, "\n");
+};
+goog.string.normalizeWhitespace = function(str) {
+ return str.replace(/\xa0|\s/g, " ");
+};
+goog.string.normalizeSpaces = function(str) {
+ return str.replace(/\xa0|[ \t]+/g, " ");
+};
+goog.string.collapseBreakingSpaces = function(str) {
+ return str.replace(/[\t\r\n ]+/g, " ").replace(/^[\t\r\n ]+|[\t\r\n ]+$/g, "");
+};
+goog.string.trim = goog.TRUSTED_SITE && String.prototype.trim ? function(str) {
+ return str.trim();
+} : function(str) {
+ return str.replace(/^[\s\xa0]+|[\s\xa0]+$/g, "");
+};
+goog.string.trimLeft = function(str) {
+ return str.replace(/^[\s\xa0]+/, "");
+};
+goog.string.trimRight = function(str) {
+ return str.replace(/[\s\xa0]+$/, "");
+};
+goog.string.caseInsensitiveCompare = function(str1, str2) {
+ var test1 = String(str1).toLowerCase();
+ var test2 = String(str2).toLowerCase();
+ if (test1 < test2) {
+ return-1;
+ } else {
+ if (test1 == test2) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+};
+goog.string.numerateCompareRegExp_ = /(\.\d+)|(\d+)|(\D+)/g;
+goog.string.numerateCompare = function(str1, str2) {
+ if (str1 == str2) {
+ return 0;
+ }
+ if (!str1) {
+ return-1;
+ }
+ if (!str2) {
+ return 1;
+ }
+ var tokens1 = str1.toLowerCase().match(goog.string.numerateCompareRegExp_);
+ var tokens2 = str2.toLowerCase().match(goog.string.numerateCompareRegExp_);
+ var count = Math.min(tokens1.length, tokens2.length);
+ for (var i = 0;i < count;i++) {
+ var a = tokens1[i];
+ var b = tokens2[i];
+ if (a != b) {
+ var num1 = parseInt(a, 10);
+ if (!isNaN(num1)) {
+ var num2 = parseInt(b, 10);
+ if (!isNaN(num2) && num1 - num2) {
+ return num1 - num2;
+ }
+ }
+ return a < b ? -1 : 1;
+ }
+ }
+ if (tokens1.length != tokens2.length) {
+ return tokens1.length - tokens2.length;
+ }
+ return str1 < str2 ? -1 : 1;
+};
+goog.string.urlEncode = function(str) {
+ return encodeURIComponent(String(str));
+};
+goog.string.urlDecode = function(str) {
+ return decodeURIComponent(str.replace(/\+/g, " "));
+};
+goog.string.newLineToBr = function(str, opt_xml) {
+ return str.replace(/(\r\n|\r|\n)/g, opt_xml ? "<br />" : "<br>");
+};
+goog.string.htmlEscape = function(str, opt_isLikelyToContainHtmlChars) {
+ if (opt_isLikelyToContainHtmlChars) {
+ str = str.replace(goog.string.AMP_RE_, "&").replace(goog.string.LT_RE_, "<").replace(goog.string.GT_RE_, ">").replace(goog.string.QUOT_RE_, """).replace(goog.string.SINGLE_QUOTE_RE_, "'").replace(goog.string.NULL_RE_, "�");
+ if (goog.string.DETECT_DOUBLE_ESCAPING) {
+ str = str.replace(goog.string.E_RE_, "e");
+ }
+ return str;
+ } else {
+ if (!goog.string.ALL_RE_.test(str)) {
+ return str;
+ }
+ if (str.indexOf("&") != -1) {
+ str = str.replace(goog.string.AMP_RE_, "&");
+ }
+ if (str.indexOf("<") != -1) {
+ str = str.replace(goog.string.LT_RE_, "<");
+ }
+ if (str.indexOf(">") != -1) {
+ str = str.replace(goog.string.GT_RE_, ">");
+ }
+ if (str.indexOf('"') != -1) {
+ str = str.replace(goog.string.QUOT_RE_, """);
+ }
+ if (str.indexOf("'") != -1) {
+ str = str.replace(goog.string.SINGLE_QUOTE_RE_, "'");
+ }
+ if (str.indexOf("\x00") != -1) {
+ str = str.replace(goog.string.NULL_RE_, "�");
+ }
+ if (goog.string.DETECT_DOUBLE_ESCAPING && str.indexOf("e") != -1) {
+ str = str.replace(goog.string.E_RE_, "e");
+ }
+ return str;
+ }
+};
+goog.string.AMP_RE_ = /&/g;
+goog.string.LT_RE_ = /</g;
+goog.string.GT_RE_ = />/g;
+goog.string.QUOT_RE_ = /"/g;
+goog.string.SINGLE_QUOTE_RE_ = /'/g;
+goog.string.NULL_RE_ = /\x00/g;
+goog.string.E_RE_ = /e/g;
+goog.string.ALL_RE_ = goog.string.DETECT_DOUBLE_ESCAPING ? /[\x00&<>"'e]/ : /[\x00&<>"']/;
+goog.string.unescapeEntities = function(str) {
+ if (goog.string.contains(str, "&")) {
+ if (!goog.string.FORCE_NON_DOM_HTML_UNESCAPING && "document" in goog.global) {
+ return goog.string.unescapeEntitiesUsingDom_(str);
+ } else {
+ return goog.string.unescapePureXmlEntities_(str);
+ }
+ }
+ return str;
+};
+goog.string.unescapeEntitiesWithDocument = function(str, document) {
+ if (goog.string.contains(str, "&")) {
+ return goog.string.unescapeEntitiesUsingDom_(str, document);
+ }
+ return str;
+};
+goog.string.unescapeEntitiesUsingDom_ = function(str, opt_document) {
+ var seen = {"&":"&", "<":"<", ">":">", """:'"'};
+ var div;
+ if (opt_document) {
+ div = opt_document.createElement("div");
+ } else {
+ div = goog.global.document.createElement("div");
+ }
+ return str.replace(goog.string.HTML_ENTITY_PATTERN_, function(s, entity) {
+ var value = seen[s];
+ if (value) {
+ return value;
+ }
+ if (entity.charAt(0) == "#") {
+ var n = Number("0" + entity.substr(1));
+ if (!isNaN(n)) {
+ value = String.fromCharCode(n);
+ }
+ }
+ if (!value) {
+ div.innerHTML = s + " ";
+ value = div.firstChild.nodeValue.slice(0, -1);
+ }
+ return seen[s] = value;
+ });
+};
+goog.string.unescapePureXmlEntities_ = function(str) {
+ return str.replace(/&([^;]+);/g, function(s, entity) {
+ switch(entity) {
+ case "amp":
+ return "&";
+ case "lt":
+ return "<";
+ case "gt":
+ return ">";
+ case "quot":
+ return'"';
+ default:
+ if (entity.charAt(0) == "#") {
+ var n = Number("0" + entity.substr(1));
+ if (!isNaN(n)) {
+ return String.fromCharCode(n);
+ }
+ }
+ return s;
+ }
+ });
+};
+goog.string.HTML_ENTITY_PATTERN_ = /&([^;\s<&]+);?/g;
+goog.string.whitespaceEscape = function(str, opt_xml) {
+ return goog.string.newLineToBr(str.replace(/ /g, "  "), opt_xml);
+};
+goog.string.preserveSpaces = function(str) {
+ return str.replace(/(^|[\n ]) /g, "$1" + goog.string.Unicode.NBSP);
+};
+goog.string.stripQuotes = function(str, quoteChars) {
+ var length = quoteChars.length;
+ for (var i = 0;i < length;i++) {
+ var quoteChar = length == 1 ? quoteChars : quoteChars.charAt(i);
+ if (str.charAt(0) == quoteChar && str.charAt(str.length - 1) == quoteChar) {
+ return str.substring(1, str.length - 1);
+ }
+ }
+ return str;
+};
+goog.string.truncate = function(str, chars, opt_protectEscapedCharacters) {
+ if (opt_protectEscapedCharacters) {
+ str = goog.string.unescapeEntities(str);
+ }
+ if (str.length > chars) {
+ str = str.substring(0, chars - 3) + "...";
+ }
+ if (opt_protectEscapedCharacters) {
+ str = goog.string.htmlEscape(str);
+ }
+ return str;
+};
+goog.string.truncateMiddle = function(str, chars, opt_protectEscapedCharacters, opt_trailingChars) {
+ if (opt_protectEscapedCharacters) {
+ str = goog.string.unescapeEntities(str);
+ }
+ if (opt_trailingChars && str.length > chars) {
+ if (opt_trailingChars > chars) {
+ opt_trailingChars = chars;
+ }
+ var endPoint = str.length - opt_trailingChars;
+ var startPoint = chars - opt_trailingChars;
+ str = str.substring(0, startPoint) + "..." + str.substring(endPoint);
+ } else {
+ if (str.length > chars) {
+ var half = Math.floor(chars / 2);
+ var endPos = str.length - half;
+ half += chars % 2;
+ str = str.substring(0, half) + "..." + str.substring(endPos);
+ }
+ }
+ if (opt_protectEscapedCharacters) {
+ str = goog.string.htmlEscape(str);
+ }
+ return str;
+};
+goog.string.specialEscapeChars_ = {"\x00":"\\0", "\b":"\\b", "\f":"\\f", "\n":"\\n", "\r":"\\r", "\t":"\\t", "\x0B":"\\x0B", '"':'\\"', "\\":"\\\\"};
+goog.string.jsEscapeCache_ = {"'":"\\'"};
+goog.string.quote = function(s) {
+ s = String(s);
+ if (s.quote) {
+ return s.quote();
+ } else {
+ var sb = ['"'];
+ for (var i = 0;i < s.length;i++) {
+ var ch = s.charAt(i);
+ var cc = ch.charCodeAt(0);
+ sb[i + 1] = goog.string.specialEscapeChars_[ch] || (cc > 31 && cc < 127 ? ch : goog.string.escapeChar(ch));
+ }
+ sb.push('"');
+ return sb.join("");
+ }
+};
+goog.string.escapeString = function(str) {
+ var sb = [];
+ for (var i = 0;i < str.length;i++) {
+ sb[i] = goog.string.escapeChar(str.charAt(i));
+ }
+ return sb.join("");
+};
+goog.string.escapeChar = function(c) {
+ if (c in goog.string.jsEscapeCache_) {
+ return goog.string.jsEscapeCache_[c];
+ }
+ if (c in goog.string.specialEscapeChars_) {
+ return goog.string.jsEscapeCache_[c] = goog.string.specialEscapeChars_[c];
+ }
+ var rv = c;
+ var cc = c.charCodeAt(0);
+ if (cc > 31 && cc < 127) {
+ rv = c;
+ } else {
+ if (cc < 256) {
+ rv = "\\x";
+ if (cc < 16 || cc > 256) {
+ rv += "0";
+ }
+ } else {
+ rv = "\\u";
+ if (cc < 4096) {
+ rv += "0";
+ }
+ }
+ rv += cc.toString(16).toUpperCase();
+ }
+ return goog.string.jsEscapeCache_[c] = rv;
+};
+goog.string.contains = function(str, subString) {
+ return str.indexOf(subString) != -1;
+};
+goog.string.caseInsensitiveContains = function(str, subString) {
+ return goog.string.contains(str.toLowerCase(), subString.toLowerCase());
+};
+goog.string.countOf = function(s, ss) {
+ return s && ss ? s.split(ss).length - 1 : 0;
+};
+goog.string.removeAt = function(s, index, stringLength) {
+ var resultStr = s;
+ if (index >= 0 && index < s.length && stringLength > 0) {
+ resultStr = s.substr(0, index) + s.substr(index + stringLength, s.length - index - stringLength);
+ }
+ return resultStr;
+};
+goog.string.remove = function(s, ss) {
+ var re = new RegExp(goog.string.regExpEscape(ss), "");
+ return s.replace(re, "");
+};
+goog.string.removeAll = function(s, ss) {
+ var re = new RegExp(goog.string.regExpEscape(ss), "g");
+ return s.replace(re, "");
+};
+goog.string.regExpEscape = function(s) {
+ return String(s).replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, "\\$1").replace(/\x08/g, "\\x08");
+};
+goog.string.repeat = function(string, length) {
+ return(new Array(length + 1)).join(string);
+};
+goog.string.padNumber = function(num, length, opt_precision) {
+ var s = goog.isDef(opt_precision) ? num.toFixed(opt_precision) : String(num);
+ var index = s.indexOf(".");
+ if (index == -1) {
+ index = s.length;
+ }
+ return goog.string.repeat("0", Math.max(0, length - index)) + s;
+};
+goog.string.makeSafe = function(obj) {
+ return obj == null ? "" : String(obj);
+};
+goog.string.buildString = function(var_args) {
+ return Array.prototype.join.call(arguments, "");
+};
+goog.string.getRandomString = function() {
+ var x = 2147483648;
+ return Math.floor(Math.random() * x).toString(36) + Math.abs(Math.floor(Math.random() * x) ^ goog.now()).toString(36);
+};
+goog.string.compareVersions = function(version1, version2) {
+ var order = 0;
+ var v1Subs = goog.string.trim(String(version1)).split(".");
+ var v2Subs = goog.string.trim(String(version2)).split(".");
+ var subCount = Math.max(v1Subs.length, v2Subs.length);
+ for (var subIdx = 0;order == 0 && subIdx < subCount;subIdx++) {
+ var v1Sub = v1Subs[subIdx] || "";
+ var v2Sub = v2Subs[subIdx] || "";
+ var v1CompParser = new RegExp("(\\d*)(\\D*)", "g");
+ var v2CompParser = new RegExp("(\\d*)(\\D*)", "g");
+ do {
+ var v1Comp = v1CompParser.exec(v1Sub) || ["", "", ""];
+ var v2Comp = v2CompParser.exec(v2Sub) || ["", "", ""];
+ if (v1Comp[0].length == 0 && v2Comp[0].length == 0) {
+ break;
+ }
+ var v1CompNum = v1Comp[1].length == 0 ? 0 : parseInt(v1Comp[1], 10);
+ var v2CompNum = v2Comp[1].length == 0 ? 0 : parseInt(v2Comp[1], 10);
+ order = goog.string.compareElements_(v1CompNum, v2CompNum) || goog.string.compareElements_(v1Comp[2].length == 0, v2Comp[2].length == 0) || goog.string.compareElements_(v1Comp[2], v2Comp[2]);
+ } while (order == 0);
+ }
+ return order;
+};
+goog.string.compareElements_ = function(left, right) {
+ if (left < right) {
+ return-1;
+ } else {
+ if (left > right) {
+ return 1;
+ }
+ }
+ return 0;
+};
+goog.string.HASHCODE_MAX_ = 4294967296;
+goog.string.hashCode = function(str) {
+ var result = 0;
+ for (var i = 0;i < str.length;++i) {
+ result = 31 * result + str.charCodeAt(i);
+ result %= goog.string.HASHCODE_MAX_;
+ }
+ return result;
+};
+goog.string.uniqueStringCounter_ = Math.random() * 2147483648 | 0;
+goog.string.createUniqueString = function() {
+ return "goog_" + goog.string.uniqueStringCounter_++;
+};
+goog.string.toNumber = function(str) {
+ var num = Number(str);
+ if (num == 0 && goog.string.isEmptyOrWhitespace(str)) {
+ return NaN;
+ }
+ return num;
+};
+goog.string.isLowerCamelCase = function(str) {
+ return/^[a-z]+([A-Z][a-z]*)*$/.test(str);
+};
+goog.string.isUpperCamelCase = function(str) {
+ return/^([A-Z][a-z]*)+$/.test(str);
+};
+goog.string.toCamelCase = function(str) {
+ return String(str).replace(/\-([a-z])/g, function(all, match) {
+ return match.toUpperCase();
+ });
+};
+goog.string.toSelectorCase = function(str) {
+ return String(str).replace(/([A-Z])/g, "-$1").toLowerCase();
+};
+goog.string.toTitleCase = function(str, opt_delimiters) {
+ var delimiters = goog.isString(opt_delimiters) ? goog.string.regExpEscape(opt_delimiters) : "\\s";
+ delimiters = delimiters ? "|[" + delimiters + "]+" : "";
+ var regexp = new RegExp("(^" + delimiters + ")([a-z])", "g");
+ return str.replace(regexp, function(all, p1, p2) {
+ return p1 + p2.toUpperCase();
+ });
+};
+goog.string.capitalize = function(str) {
+ return String(str.charAt(0)).toUpperCase() + String(str.substr(1)).toLowerCase();
+};
+goog.string.parseInt = function(value) {
+ if (isFinite(value)) {
+ value = String(value);
+ }
+ if (goog.isString(value)) {
+ return/^\s*-?0x/i.test(value) ? parseInt(value, 16) : parseInt(value, 10);
+ }
+ return NaN;
+};
+goog.string.splitLimit = function(str, separator, limit) {
+ var parts = str.split(separator);
+ var returnVal = [];
+ while (limit > 0 && parts.length) {
+ returnVal.push(parts.shift());
+ limit--;
+ }
+ if (parts.length) {
+ returnVal.push(parts.join(separator));
+ }
+ return returnVal;
+};
+goog.string.editDistance = function(a, b) {
+ var v0 = [];
+ var v1 = [];
+ if (a == b) {
+ return 0;
+ }
+ if (!a.length || !b.length) {
+ return Math.max(a.length, b.length);
+ }
+ for (var i = 0;i < b.length + 1;i++) {
+ v0[i] = i;
+ }
+ for (var i = 0;i < a.length;i++) {
+ v1[0] = i + 1;
+ for (var j = 0;j < b.length;j++) {
+ var cost = a[i] != b[j];
+ v1[j + 1] = Math.min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost);
+ }
+ for (var j = 0;j < v0.length;j++) {
+ v0[j] = v1[j];
+ }
+ }
+ return v1[b.length];
+};
+goog.provide("goog.labs.userAgent.util");
+goog.require("goog.string");
+goog.labs.userAgent.util.getNativeUserAgentString_ = function() {
+ var navigator = goog.labs.userAgent.util.getNavigator_();
+ if (navigator) {
+ var userAgent = navigator.userAgent;
+ if (userAgent) {
+ return userAgent;
+ }
+ }
+ return "";
+};
+goog.labs.userAgent.util.getNavigator_ = function() {
+ return goog.global.navigator;
+};
+goog.labs.userAgent.util.userAgent_ = goog.labs.userAgent.util.getNativeUserAgentString_();
+goog.labs.userAgent.util.setUserAgent = function(opt_userAgent) {
+ goog.labs.userAgent.util.userAgent_ = opt_userAgent || goog.labs.userAgent.util.getNativeUserAgentString_();
+};
+goog.labs.userAgent.util.getUserAgent = function() {
+ return goog.labs.userAgent.util.userAgent_;
+};
+goog.labs.userAgent.util.matchUserAgent = function(str) {
+ var userAgent = goog.labs.userAgent.util.getUserAgent();
+ return goog.string.contains(userAgent, str);
+};
+goog.labs.userAgent.util.matchUserAgentIgnoreCase = function(str) {
+ var userAgent = goog.labs.userAgent.util.getUserAgent();
+ return goog.string.caseInsensitiveContains(userAgent, str);
+};
+goog.labs.userAgent.util.extractVersionTuples = function(userAgent) {
+ var versionRegExp = new RegExp("(\\w[\\w ]+)" + "/" + "([^\\s]+)" + "\\s*" + "(?:\\((.*?)\\))?", "g");
+ var data = [];
+ var match;
+ while (match = versionRegExp.exec(userAgent)) {
+ data.push([match[1], match[2], match[3] || undefined]);
+ }
+ return data;
+};
+goog.provide("goog.labs.userAgent.platform");
+goog.require("goog.labs.userAgent.util");
+goog.require("goog.string");
+goog.labs.userAgent.platform.isAndroid = function() {
+ return goog.labs.userAgent.util.matchUserAgent("Android");
+};
+goog.labs.userAgent.platform.isIpod = function() {
+ return goog.labs.userAgent.util.matchUserAgent("iPod");
+};
+goog.labs.userAgent.platform.isIphone = function() {
+ return goog.labs.userAgent.util.matchUserAgent("iPhone") && !goog.labs.userAgent.util.matchUserAgent("iPod") && !goog.labs.userAgent.util.matchUserAgent("iPad");
+};
+goog.labs.userAgent.platform.isIpad = function() {
+ return goog.labs.userAgent.util.matchUserAgent("iPad");
+};
+goog.labs.userAgent.platform.isIos = function() {
+ return goog.labs.userAgent.platform.isIphone() || goog.labs.userAgent.platform.isIpad() || goog.labs.userAgent.platform.isIpod();
+};
+goog.labs.userAgent.platform.isMacintosh = function() {
+ return goog.labs.userAgent.util.matchUserAgent("Macintosh");
+};
+goog.labs.userAgent.platform.isLinux = function() {
+ return goog.labs.userAgent.util.matchUserAgent("Linux");
+};
+goog.labs.userAgent.platform.isWindows = function() {
+ return goog.labs.userAgent.util.matchUserAgent("Windows");
+};
+goog.labs.userAgent.platform.isChromeOS = function() {
+ return goog.labs.userAgent.util.matchUserAgent("CrOS");
+};
+goog.labs.userAgent.platform.getVersion = function() {
+ var userAgentString = goog.labs.userAgent.util.getUserAgent();
+ var version = "", re;
+ if (goog.labs.userAgent.platform.isWindows()) {
+ re = /Windows (?:NT|Phone) ([0-9.]+)/;
+ var match = re.exec(userAgentString);
+ if (match) {
+ version = match[1];
+ } else {
+ version = "0.0";
+ }
+ } else {
+ if (goog.labs.userAgent.platform.isIos()) {
+ re = /(?:iPhone|iPod|iPad|CPU)\s+OS\s+(\S+)/;
+ var match = re.exec(userAgentString);
+ version = match && match[1].replace(/_/g, ".");
+ } else {
+ if (goog.labs.userAgent.platform.isMacintosh()) {
+ re = /Mac OS X ([0-9_.]+)/;
+ var match = re.exec(userAgentString);
+ version = match ? match[1].replace(/_/g, ".") : "10";
+ } else {
+ if (goog.labs.userAgent.platform.isAndroid()) {
+ re = /Android\s+([^\);]+)(\)|;)/;
+ var match = re.exec(userAgentString);
+ version = match && match[1];
+ } else {
+ if (goog.labs.userAgent.platform.isChromeOS()) {
+ re = /(?:CrOS\s+(?:i686|x86_64)\s+([0-9.]+))/;
+ var match = re.exec(userAgentString);
+ version = match && match[1];
+ }
+ }
+ }
+ }
+ }
+ return version || "";
+};
+goog.labs.userAgent.platform.isVersionOrHigher = function(version) {
+ return goog.string.compareVersions(goog.labs.userAgent.platform.getVersion(), version) >= 0;
+};
+goog.provide("goog.crypt.Hash");
+goog.crypt.Hash = function() {
+ this.blockSize = -1;
+};
+goog.crypt.Hash.prototype.reset = goog.abstractMethod;
+goog.crypt.Hash.prototype.update = goog.abstractMethod;
+goog.crypt.Hash.prototype.digest = goog.abstractMethod;
+goog.provide("goog.crypt.Sha1");
+goog.require("goog.crypt.Hash");
+goog.crypt.Sha1 = function() {
+ goog.crypt.Sha1.base(this, "constructor");
+ this.blockSize = 512 / 8;
+ this.chain_ = [];
+ this.buf_ = [];
+ this.W_ = [];
+ this.pad_ = [];
+ this.pad_[0] = 128;
+ for (var i = 1;i < this.blockSize;++i) {
+ this.pad_[i] = 0;
+ }
+ this.inbuf_ = 0;
+ this.total_ = 0;
+ this.reset();
+};
+goog.inherits(goog.crypt.Sha1, goog.crypt.Hash);
+goog.crypt.Sha1.prototype.reset = function() {
+ this.chain_[0] = 1732584193;
+ this.chain_[1] = 4023233417;
+ this.chain_[2] = 2562383102;
+ this.chain_[3] = 271733878;
+ this.chain_[4] = 3285377520;
+ this.inbuf_ = 0;
+ this.total_ = 0;
+};
+goog.crypt.Sha1.prototype.compress_ = function(buf, opt_offset) {
+ if (!opt_offset) {
+ opt_offset = 0;
+ }
+ var W = this.W_;
+ if (goog.isString(buf)) {
+ for (var i = 0;i < 16;i++) {
+ W[i] = buf.charCodeAt(opt_offset) << 24 | buf.charCodeAt(opt_offset + 1) << 16 | buf.charCodeAt(opt_offset + 2) << 8 | buf.charCodeAt(opt_offset + 3);
+ opt_offset += 4;
+ }
+ } else {
+ for (var i = 0;i < 16;i++) {
+ W[i] = buf[opt_offset] << 24 | buf[opt_offset + 1] << 16 | buf[opt_offset + 2] << 8 | buf[opt_offset + 3];
+ opt_offset += 4;
+ }
+ }
+ for (var i = 16;i < 80;i++) {
+ var t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
+ W[i] = (t << 1 | t >>> 31) & 4294967295;
+ }
+ var a = this.chain_[0];
+ var b = this.chain_[1];
+ var c = this.chain_[2];
+ var d = this.chain_[3];
+ var e = this.chain_[4];
+ var f, k;
+ for (var i = 0;i < 80;i++) {
+ if (i < 40) {
+ if (i < 20) {
+ f = d ^ b & (c ^ d);
+ k = 1518500249;
+ } else {
+ f = b ^ c ^ d;
+ k = 1859775393;
+ }
+ } else {
+ if (i < 60) {
+ f = b & c | d & (b | c);
+ k = 2400959708;
+ } else {
+ f = b ^ c ^ d;
+ k = 3395469782;
+ }
+ }
+ var t = (a << 5 | a >>> 27) + f + e + k + W[i] & 4294967295;
+ e = d;
+ d = c;
+ c = (b << 30 | b >>> 2) & 4294967295;
+ b = a;
+ a = t;
+ }
+ this.chain_[0] = this.chain_[0] + a & 4294967295;
+ this.chain_[1] = this.chain_[1] + b & 4294967295;
+ this.chain_[2] = this.chain_[2] + c & 4294967295;
+ this.chain_[3] = this.chain_[3] + d & 4294967295;
+ this.chain_[4] = this.chain_[4] + e & 4294967295;
+};
+goog.crypt.Sha1.prototype.update = function(bytes, opt_length) {
+ if (bytes == null) {
+ return;
+ }
+ if (!goog.isDef(opt_length)) {
+ opt_length = bytes.length;
+ }
+ var lengthMinusBlock = opt_length - this.blockSize;
+ var n = 0;
+ var buf = this.buf_;
+ var inbuf = this.inbuf_;
+ while (n < opt_length) {
+ if (inbuf == 0) {
+ while (n <= lengthMinusBlock) {
+ this.compress_(bytes, n);
+ n += this.blockSize;
+ }
+ }
+ if (goog.isString(bytes)) {
+ while (n < opt_length) {
+ buf[inbuf] = bytes.charCodeAt(n);
+ ++inbuf;
+ ++n;
+ if (inbuf == this.blockSize) {
+ this.compress_(buf);
+ inbuf = 0;
+ break;
+ }
+ }
+ } else {
+ while (n < opt_length) {
+ buf[inbuf] = bytes[n];
+ ++inbuf;
+ ++n;
+ if (inbuf == this.blockSize) {
+ this.compress_(buf);
+ inbuf = 0;
+ break;
+ }
+ }
+ }
+ }
+ this.inbuf_ = inbuf;
+ this.total_ += opt_length;
+};
+goog.crypt.Sha1.prototype.digest = function() {
+ var digest = [];
+ var totalBits = this.total_ * 8;
+ if (this.inbuf_ < 56) {
+ this.update(this.pad_, 56 - this.inbuf_);
+ } else {
+ this.update(this.pad_, this.blockSize - (this.inbuf_ - 56));
+ }
+ for (var i = this.blockSize - 1;i >= 56;i--) {
+ this.buf_[i] = totalBits & 255;
+ totalBits /= 256;
+ }
+ this.compress_(this.buf_);
+ var n = 0;
+ for (var i = 0;i < 5;i++) {
+ for (var j = 24;j >= 0;j -= 8) {
+ digest[n] = this.chain_[i] >> j & 255;
+ ++n;
+ }
+ }
+ return digest;
+};
+goog.provide("goog.asserts");
+goog.provide("goog.asserts.AssertionError");
+goog.require("goog.debug.Error");
+goog.require("goog.dom.NodeType");
+goog.require("goog.string");
+goog.define("goog.asserts.ENABLE_ASSERTS", goog.DEBUG);
+goog.asserts.AssertionError = function(messagePattern, messageArgs) {
+ messageArgs.unshift(messagePattern);
+ goog.debug.Error.call(this, goog.string.subs.apply(null, messageArgs));
+ messageArgs.shift();
+ this.messagePattern = messagePattern;
+};
+goog.inherits(goog.asserts.AssertionError, goog.debug.Error);
+goog.asserts.AssertionError.prototype.name = "AssertionError";
+goog.asserts.DEFAULT_ERROR_HANDLER = function(e) {
+ throw e;
+};
+goog.asserts.errorHandler_ = goog.asserts.DEFAULT_ERROR_HANDLER;
+goog.asserts.doAssertFailure_ = function(defaultMessage, defaultArgs, givenMessage, givenArgs) {
+ var message = "Assertion failed";
+ if (givenMessage) {
+ message += ": " + givenMessage;
+ var args = givenArgs;
+ } else {
+ if (defaultMessage) {
+ message += ": " + defaultMessage;
+ args = defaultArgs;
+ }
+ }
+ var e = new goog.asserts.AssertionError("" + message, args || []);
+ goog.asserts.errorHandler_(e);
+};
+goog.asserts.setErrorHandler = function(errorHandler) {
+ if (goog.asserts.ENABLE_ASSERTS) {
+ goog.asserts.errorHandler_ = errorHandler;
+ }
+};
+goog.asserts.assert = function(condition, opt_message, var_args) {
+ if (goog.asserts.ENABLE_ASSERTS && !condition) {
+ goog.asserts.doAssertFailure_("", null, opt_message, Array.prototype.slice.call(arguments, 2));
+ }
+ return condition;
+};
+goog.asserts.fail = function(opt_message, var_args) {
+ if (goog.asserts.ENABLE_ASSERTS) {
+ goog.asserts.errorHandler_(new goog.asserts.AssertionError("Failure" + (opt_message ? ": " + opt_message : ""), Array.prototype.slice.call(arguments, 1)));
+ }
+};
+goog.asserts.assertNumber = function(value, opt_message, var_args) {
+ if (goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value)) {
+ goog.asserts.doAssertFailure_("Expected number but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2));
+ }
+ return(value);
+};
+goog.asserts.assertString = function(value, opt_message, var_args) {
+ if (goog.asserts.ENABLE_ASSERTS && !goog.isString(value)) {
+ goog.asserts.doAssertFailure_("Expected string but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2));
+ }
+ return(value);
+};
+goog.asserts.assertFunction = function(value, opt_message, var_args) {
+ if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) {
+ goog.asserts.doAssertFailure_("Expected function but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2));
+ }
+ return(value);
+};
+goog.asserts.assertObject = function(value, opt_message, var_args) {
+ if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) {
+ goog.asserts.doAssertFailure_("Expected object but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2));
+ }
+ return(value);
+};
+goog.asserts.assertArray = function(value, opt_message, var_args) {
+ if (goog.asserts.ENABLE_ASSERTS && !goog.isArray(value)) {
+ goog.asserts.doAssertFailure_("Expected array but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2));
+ }
+ return(value);
+};
+goog.asserts.assertBoolean = function(value, opt_message, var_args) {
+ if (goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value)) {
+ goog.asserts.doAssertFailure_("Expected boolean but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2));
+ }
+ return(value);
+};
+goog.asserts.assertElement = function(value, opt_message, var_args) {
+ if (goog.asserts.ENABLE_ASSERTS && (!goog.isObject(value) || value.nodeType != goog.dom.NodeType.ELEMENT)) {
+ goog.asserts.doAssertFailure_("Expected Element but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2));
+ }
+ return(value);
+};
+goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) {
+ if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) {
+ goog.asserts.doAssertFailure_("Expected instanceof %s but got %s.", [goog.asserts.getType_(type), goog.asserts.getType_(value)], opt_message, Array.prototype.slice.call(arguments, 3));
+ }
+ return value;
+};
+goog.asserts.assertObjectPrototypeIsIntact = function() {
+ for (var key in Object.prototype) {
+ goog.asserts.fail(key + " should not be enumerable in Object.prototype.");
+ }
+};
+goog.asserts.getType_ = function(value) {
+ if (value instanceof Function) {
+ return value.displayName || value.name || "unknown type name";
+ } else {
+ if (value instanceof Object) {
+ return value.constructor.displayName || value.constructor.name || Object.prototype.toString.call(value);
+ } else {
+ return value === null ? "null" : typeof value;
+ }
+ }
+};
+goog.provide("goog.array");
+goog.provide("goog.array.ArrayLike");
+goog.require("goog.asserts");
+goog.define("goog.NATIVE_ARRAY_PROTOTYPES", goog.TRUSTED_SITE);
+goog.define("goog.array.ASSUME_NATIVE_FUNCTIONS", false);
+goog.array.ArrayLike;
+goog.array.peek = function(array) {
+ return array[array.length - 1];
+};
+goog.array.last = goog.array.peek;
+goog.array.ARRAY_PROTOTYPE_ = Array.prototype;
+goog.array.indexOf = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.indexOf) ? function(arr, obj, opt_fromIndex) {
+ goog.asserts.assert(arr.length != null);
+ return goog.array.ARRAY_PROTOTYPE_.indexOf.call(arr, obj, opt_fromIndex);
+} : function(arr, obj, opt_fromIndex) {
+ var fromIndex = opt_fromIndex == null ? 0 : opt_fromIndex < 0 ? Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex;
+ if (goog.isString(arr)) {
+ if (!goog.isString(obj) || obj.length != 1) {
+ return-1;
+ }
+ return arr.indexOf(obj, fromIndex);
+ }
+ for (var i = fromIndex;i < arr.length;i++) {
+ if (i in arr && arr[i] === obj) {
+ return i;
+ }
+ }
+ return-1;
+};
+goog.array.lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.lastIndexOf) ? function(arr, obj, opt_fromIndex) {
+ goog.asserts.assert(arr.length != null);
+ var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;
+ return goog.array.ARRAY_PROTOTYPE_.lastIndexOf.call(arr, obj, fromIndex);
+} : function(arr, obj, opt_fromIndex) {
+ var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;
+ if (fromIndex < 0) {
+ fromIndex = Math.max(0, arr.length + fromIndex);
+ }
+ if (goog.isString(arr)) {
+ if (!goog.isString(obj) || obj.length != 1) {
+ return-1;
+ }
+ return arr.lastIndexOf(obj, fromIndex);
+ }
+ for (var i = fromIndex;i >= 0;i--) {
+ if (i in arr && arr[i] === obj) {
+ return i;
+ }
+ }
+ return-1;
+};
+goog.array.forEach = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.forEach) ? function(arr, f, opt_obj) {
+ goog.asserts.assert(arr.length != null);
+ goog.array.ARRAY_PROTOTYPE_.forEach.call(arr, f, opt_obj);
+} : function(arr, f, opt_obj) {
+ var l = arr.length;
+ var arr2 = goog.isString(arr) ? arr.split("") : arr;
+ for (var i = 0;i < l;i++) {
+ if (i in arr2) {
+ f.call(opt_obj, arr2[i], i, arr);
+ }
+ }
+};
+goog.array.forEachRight = function(arr, f, opt_obj) {
+ var l = arr.length;
+ var arr2 = goog.isString(arr) ? arr.split("") : arr;
+ for (var i = l - 1;i >= 0;--i) {
+ if (i in arr2) {
+ f.call(opt_obj, arr2[i], i, arr);
+ }
+ }
+};
+goog.array.filter = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.filter) ? function(arr, f, opt_obj) {
+ goog.asserts.assert(arr.length != null);
+ return goog.array.ARRAY_PROTOTYPE_.filter.call(arr, f, opt_obj);
+} : function(arr, f, opt_obj) {
+ var l = arr.length;
+ var res = [];
+ var resLength = 0;
+ var arr2 = goog.isString(arr) ? arr.split("") : arr;
+ for (var i = 0;i < l;i++) {
+ if (i in arr2) {
+ var val = arr2[i];
+ if (f.call(opt_obj, val, i, arr)) {
+ res[resLength++] = val;
+ }
+ }
+ }
+ return res;
+};
+goog.array.map = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.map) ? function(arr, f, opt_obj) {
+ goog.asserts.assert(arr.length != null);
+ return goog.array.ARRAY_PROTOTYPE_.map.call(arr, f, opt_obj);
+} : function(arr, f, opt_obj) {
+ var l = arr.length;
+ var res = new Array(l);
+ var arr2 = goog.isString(arr) ? arr.split("") : arr;
+ for (var i = 0;i < l;i++) {
+ if (i in arr2) {
+ res[i] = f.call(opt_obj, arr2[i], i, arr);
+ }
+ }
+ return res;
+};
+goog.array.reduce = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.reduce) ? function(arr, f, val, opt_obj) {
+ goog.asserts.assert(arr.length != null);
+ var params = [];
+ for (var i = 1, l = arguments.length;i < l;i++) {
+ params.push(arguments[i]);
+ }
+ if (opt_obj) {
+ params[0] = goog.bind(f, opt_obj);
+ }
+ return goog.array.ARRAY_PROTOTYPE_.reduce.apply(arr, params);
+} : function(arr, f, val, opt_obj) {
+ var rval = val;
+ goog.array.forEach(arr, function(val, index) {
+ rval = f.call(opt_obj, rval, val, index, arr);
+ });
+ return rval;
+};
+goog.array.reduceRight = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.reduceRight) ? function(arr, f, val, opt_obj) {
+ goog.asserts.assert(arr.length != null);
+ if (opt_obj) {
+ f = goog.bind(f, opt_obj);
+ }
+ return goog.array.ARRAY_PROTOTYPE_.reduceRight.call(arr, f, val);
+} : function(arr, f, val, opt_obj) {
+ var rval = val;
+ goog.array.forEachRight(arr, function(val, index) {
+ rval = f.call(opt_obj, rval, val, index, arr);
+ });
+ return rval;
+};
+goog.array.some = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.some) ? function(arr, f, opt_obj) {
+ goog.asserts.assert(arr.length != null);
+ return goog.array.ARRAY_PROTOTYPE_.some.call(arr, f, opt_obj);
+} : function(arr, f, opt_obj) {
+ var l = arr.length;
+ var arr2 = goog.isString(arr) ? arr.split("") : arr;
+ for (var i = 0;i < l;i++) {
+ if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
+ return true;
+ }
+ }
+ return false;
+};
+goog.array.every = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.every) ? function(arr, f, opt_obj) {
+ goog.asserts.assert(arr.length != null);
+ return goog.array.ARRAY_PROTOTYPE_.every.call(arr, f, opt_obj);
+} : function(arr, f, opt_obj) {
+ var l = arr.length;
+ var arr2 = goog.isString(arr) ? arr.split("") : arr;
+ for (var i = 0;i < l;i++) {
+ if (i in arr2 && !f.call(opt_obj, arr2[i], i, arr)) {
+ return false;
+ }
+ }
+ return true;
+};
+goog.array.count = function(arr, f, opt_obj) {
+ var count = 0;
+ goog.array.forEach(arr, function(element, index, arr) {
+ if (f.call(opt_obj, element, index, arr)) {
+ ++count;
+ }
+ }, opt_obj);
+ return count;
+};
+goog.array.find = function(arr, f, opt_obj) {
+ var i = goog.array.findIndex(arr, f, opt_obj);
+ return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i];
+};
+goog.array.findIndex = function(arr, f, opt_obj) {
+ var l = arr.length;
+ var arr2 = goog.isString(arr) ? arr.split("") : arr;
+ for (var i = 0;i < l;i++) {
+ if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
+ return i;
+ }
+ }
+ return-1;
+};
+goog.array.findRight = function(arr, f, opt_obj) {
+ var i = goog.array.findIndexRight(arr, f, opt_obj);
+ return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i];
+};
+goog.array.findIndexRight = function(arr, f, opt_obj) {
+ var l = arr.length;
+ var arr2 = goog.isString(arr) ? arr.split("") : arr;
+ for (var i = l - 1;i >= 0;i--) {
+ if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
+ return i;
+ }
+ }
+ return-1;
+};
+goog.array.contains = function(arr, obj) {
+ return goog.array.indexOf(arr, obj) >= 0;
+};
+goog.array.isEmpty = function(arr) {
+ return arr.length == 0;
+};
+goog.array.clear = function(arr) {
+ if (!goog.isArray(arr)) {
+ for (var i = arr.length - 1;i >= 0;i--) {
+ delete arr[i];
+ }
+ }
+ arr.length = 0;
+};
+goog.array.insert = function(arr, obj) {
+ if (!goog.array.contains(arr, obj)) {
+ arr.push(obj);
+ }
+};
+goog.array.insertAt = function(arr, obj, opt_i) {
+ goog.array.splice(arr, opt_i, 0, obj);
+};
+goog.array.insertArrayAt = function(arr, elementsToAdd, opt_i) {
+ goog.partial(goog.array.splice, arr, opt_i, 0).apply(null, elementsToAdd);
+};
+goog.array.insertBefore = function(arr, obj, opt_obj2) {
+ var i;
+ if (arguments.length == 2 || (i = goog.array.indexOf(arr, opt_obj2)) < 0) {
+ arr.push(obj);
+ } else {
+ goog.array.insertAt(arr, obj, i);
+ }
+};
+goog.array.remove = function(arr, obj) {
+ var i = goog.array.indexOf(arr, obj);
+ var rv;
+ if (rv = i >= 0) {
+ goog.array.removeAt(arr, i);
+ }
+ return rv;
+};
+goog.array.removeAt = function(arr, i) {
+ goog.asserts.assert(arr.length != null);
+ return goog.array.ARRAY_PROTOTYPE_.splice.call(arr, i, 1).length == 1;
+};
+goog.array.removeIf = function(arr, f, opt_obj) {
+ var i = goog.array.findIndex(arr, f, opt_obj);
+ if (i >= 0) {
+ goog.array.removeAt(arr, i);
+ return true;
+ }
+ return false;
+};
+goog.array.removeAllIf = function(arr, f, opt_obj) {
+ var removedCount = 0;
+ goog.array.forEachRight(arr, function(val, index) {
+ if (f.call(opt_obj, val, index, arr)) {
+ if (goog.array.removeAt(arr, index)) {
+ removedCount++;
+ }
+ }
+ });
+ return removedCount;
+};
+goog.array.concat = function(var_args) {
+ return goog.array.ARRAY_PROTOTYPE_.concat.apply(goog.array.ARRAY_PROTOTYPE_, arguments);
+};
+goog.array.join = function(var_args) {
+ return goog.array.ARRAY_PROTOTYPE_.concat.apply(goog.array.ARRAY_PROTOTYPE_, arguments);
+};
+goog.array.toArray = function(object) {
+ var length = object.length;
+ if (length > 0) {
+ var rv = new Array(length);
+ for (var i = 0;i < length;i++) {
+ rv[i] = object[i];
+ }
+ return rv;
+ }
+ return[];
+};
+goog.array.clone = goog.array.toArray;
+goog.array.extend = function(arr1, var_args) {
+ for (var i = 1;i < arguments.length;i++) {
+ var arr2 = arguments[i];
+ if (goog.isArrayLike(arr2)) {
+ var len1 = arr1.length || 0;
+ var len2 = arr2.length || 0;
+ arr1.length = len1 + len2;
+ for (var j = 0;j < len2;j++) {
+ arr1[len1 + j] = arr2[j];
+ }
+ } else {
+ arr1.push(arr2);
+ }
+ }
+};
+goog.array.splice = function(arr, index, howMany, var_args) {
+ goog.asserts.assert(arr.length != null);
+ return goog.array.ARRAY_PROTOTYPE_.splice.apply(arr, goog.array.slice(arguments, 1));
+};
+goog.array.slice = function(arr, start, opt_end) {
+ goog.asserts.assert(arr.length != null);
+ if (arguments.length <= 2) {
+ return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start);
+ } else {
+ return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start, opt_end);
+ }
+};
+goog.array.removeDuplicates = function(arr, opt_rv, opt_hashFn) {
+ var returnArray = opt_rv || arr;
+ var defaultHashFn = function(item) {
+ return goog.isObject(current) ? "o" + goog.getUid(current) : (typeof current).charAt(0) + current;
+ };
+ var hashFn = opt_hashFn || defaultHashFn;
+ var seen = {}, cursorInsert = 0, cursorRead = 0;
+ while (cursorRead < arr.length) {
+ var current = arr[cursorRead++];
+ var key = hashFn(current);
+ if (!Object.prototype.hasOwnProperty.call(seen, key)) {
+ seen[key] = true;
+ returnArray[cursorInsert++] = current;
+ }
+ }
+ returnArray.length = cursorInsert;
+};
+goog.array.binarySearch = function(arr, target, opt_compareFn) {
+ return goog.array.binarySearch_(arr, opt_compareFn || goog.array.defaultCompare, false, target);
+};
+goog.array.binarySelect = function(arr, evaluator, opt_obj) {
+ return goog.array.binarySearch_(arr, evaluator, true, undefined, opt_obj);
+};
+goog.array.binarySearch_ = function(arr, compareFn, isEvaluator, opt_target, opt_selfObj) {
+ var left = 0;
+ var right = arr.length;
+ var found;
+ while (left < right) {
+ var middle = left + right >> 1;
+ var compareResult;
+ if (isEvaluator) {
+ compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);
+ } else {
+ compareResult = compareFn(opt_target, arr[middle]);
+ }
+ if (compareResult > 0) {
+ left = middle + 1;
+ } else {
+ right = middle;
+ found = !compareResult;
+ }
+ }
+ return found ? left : ~left;
+};
+goog.array.sort = function(arr, opt_compareFn) {
+ arr.sort(opt_compareFn || goog.array.defaultCompare);
+};
+goog.array.stableSort = function(arr, opt_compareFn) {
+ for (var i = 0;i < arr.length;i++) {
+ arr[i] = {index:i, value:arr[i]};
+ }
+ var valueCompareFn = opt_compareFn || goog.array.defaultCompare;
+ function stableCompareFn(obj1, obj2) {
+ return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;
+ }
+ goog.array.sort(arr, stableCompareFn);
+ for (var i = 0;i < arr.length;i++) {
+ arr[i] = arr[i].value;
+ }
+};
+goog.array.sortByKey = function(arr, keyFn, opt_compareFn) {
+ var keyCompareFn = opt_compareFn || goog.array.defaultCompare;
+ goog.array.sort(arr, function(a, b) {
+ return keyCompareFn(keyFn(a), keyFn(b));
+ });
+};
+goog.array.sortObjectsByKey = function(arr, key, opt_compareFn) {
+ goog.array.sortByKey(arr, function(obj) {
+ return obj[key];
+ }, opt_compareFn);
+};
+goog.array.isSorted = function(arr, opt_compareFn, opt_strict) {
+ var compare = opt_compareFn || goog.array.defaultCompare;
+ for (var i = 1;i < arr.length;i++) {
+ var compareResult = compare(arr[i - 1], arr[i]);
+ if (compareResult > 0 || compareResult == 0 && opt_strict) {
+ return false;
+ }
+ }
+ return true;
+};
+goog.array.equals = function(arr1, arr2, opt_equalsFn) {
+ if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) || arr1.length != arr2.length) {
+ return false;
+ }
+ var l = arr1.length;
+ var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality;
+ for (var i = 0;i < l;i++) {
+ if (!equalsFn(arr1[i], arr2[i])) {
+ return false;
+ }
+ }
+ return true;
+};
+goog.array.compare3 = function(arr1, arr2, opt_compareFn) {
+ var compare = opt_compareFn || goog.array.defaultCompare;
+ var l = Math.min(arr1.length, arr2.length);
+ for (var i = 0;i < l;i++) {
+ var result = compare(arr1[i], arr2[i]);
+ if (result != 0) {
+ return result;
+ }
+ }
+ return goog.array.defaultCompare(arr1.length, arr2.length);
+};
+goog.array.defaultCompare = function(a, b) {
+ return a > b ? 1 : a < b ? -1 : 0;
+};
+goog.array.inverseDefaultCompare = function(a, b) {
+ return-goog.array.defaultCompare(a, b);
+};
+goog.array.defaultCompareEquality = function(a, b) {
+ return a === b;
+};
+goog.array.binaryInsert = function(array, value, opt_compareFn) {
+ var index = goog.array.binarySearch(array, value, opt_compareFn);
+ if (index < 0) {
+ goog.array.insertAt(array, value, -(index + 1));
+ return true;
+ }
+ return false;
+};
+goog.array.binaryRemove = function(array, value, opt_compareFn) {
+ var index = goog.array.binarySearch(array, value, opt_compareFn);
+ return index >= 0 ? goog.array.removeAt(array, index) : false;
+};
+goog.array.bucket = function(array, sorter, opt_obj) {
+ var buckets = {};
+ for (var i = 0;i < array.length;i++) {
+ var value = array[i];
+ var key = sorter.call(opt_obj, value, i, array);
+ if (goog.isDef(key)) {
+ var bucket = buckets[key] || (buckets[key] = []);
+ bucket.push(value);
+ }
+ }
+ return buckets;
+};
+goog.array.toObject = function(arr, keyFunc, opt_obj) {
+ var ret = {};
+ goog.array.forEach(arr, function(element, index) {
+ ret[keyFunc.call(opt_obj, element, index, arr)] = element;
+ });
+ return ret;
+};
+goog.array.range = function(startOrEnd, opt_end, opt_step) {
+ var array = [];
+ var start = 0;
+ var end = startOrEnd;
+ var step = opt_step || 1;
+ if (opt_end !== undefined) {
+ start = startOrEnd;
+ end = opt_end;
+ }
+ if (step * (end - start) < 0) {
+ return[];
+ }
+ if (step > 0) {
+ for (var i = start;i < end;i += step) {
+ array.push(i);
+ }
+ } else {
+ for (var i = start;i > end;i += step) {
+ array.push(i);
+ }
+ }
+ return array;
+};
+goog.array.repeat = function(value, n) {
+ var array = [];
+ for (var i = 0;i < n;i++) {
+ array[i] = value;
+ }
+ return array;
+};
+goog.array.flatten = function(var_args) {
+ var CHUNK_SIZE = 8192;
+ var result = [];
+ for (var i = 0;i < arguments.length;i++) {
+ var element = arguments[i];
+ if (goog.isArray(element)) {
+ for (var c = 0;c < element.length;c += CHUNK_SIZE) {
+ var chunk = goog.array.slice(element, c, c + CHUNK_SIZE);
+ var recurseResult = goog.array.flatten.apply(null, chunk);
+ for (var r = 0;r < recurseResult.length;r++) {
+ result.push(recurseResult[r]);
+ }
+ }
+ } else {
+ result.push(element);
+ }
+ }
+ return result;
+};
+goog.array.rotate = function(array, n) {
+ goog.asserts.assert(array.length != null);
+ if (array.length) {
+ n %= array.length;
+ if (n > 0) {
+ goog.array.ARRAY_PROTOTYPE_.unshift.apply(array, array.splice(-n, n));
+ } else {
+ if (n < 0) {
+ goog.array.ARRAY_PROTOTYPE_.push.apply(array, array.splice(0, -n));
+ }
+ }
+ }
+ return array;
+};
+goog.array.moveItem = function(arr, fromIndex, toIndex) {
+ goog.asserts.assert(fromIndex >= 0 && fromIndex < arr.length);
+ goog.asserts.assert(toIndex >= 0 && toIndex < arr.length);
+ var removedItems = goog.array.ARRAY_PROTOTYPE_.splice.call(arr, fromIndex, 1);
+ goog.array.ARRAY_PROTOTYPE_.splice.call(arr, toIndex, 0, removedItems[0]);
+};
+goog.array.zip = function(var_args) {
+ if (!arguments.length) {
+ return[];
+ }
+ var result = [];
+ for (var i = 0;true;i++) {
+ var value = [];
+ for (var j = 0;j < arguments.length;j++) {
+ var arr = arguments[j];
+ if (i >= arr.length) {
+ return result;
+ }
+ value.push(arr[i]);
+ }
+ result.push(value);
+ }
+};
+goog.array.shuffle = function(arr, opt_randFn) {
+ var randFn = opt_randFn || Math.random;
+ for (var i = arr.length - 1;i > 0;i--) {
+ var j = Math.floor(randFn() * (i + 1));
+ var tmp = arr[i];
+ arr[i] = arr[j];
+ arr[j] = tmp;
+ }
+};
+goog.array.copyByIndex = function(arr, index_arr) {
+ var result = [];
+ goog.array.forEach(index_arr, function(index) {
+ result.push(arr[index]);
+ });
+ return result;
+};
+goog.provide("goog.labs.userAgent.browser");
+goog.require("goog.array");
+goog.require("goog.labs.userAgent.util");
+goog.require("goog.object");
+goog.require("goog.string");
+goog.labs.userAgent.browser.matchOpera_ = function() {
+ return goog.labs.userAgent.util.matchUserAgent("Opera") || goog.labs.userAgent.util.matchUserAgent("OPR");
+};
+goog.labs.userAgent.browser.matchIE_ = function() {
+ return goog.labs.userAgent.util.matchUserAgent("Trident") || goog.labs.userAgent.util.matchUserAgent("MSIE");
+};
+goog.labs.userAgent.browser.matchFirefox_ = function() {
+ return goog.labs.userAgent.util.matchUserAgent("Firefox");
+};
+goog.labs.userAgent.browser.matchSafari_ = function() {
+ return goog.labs.userAgent.util.matchUserAgent("Safari") && !(goog.labs.userAgent.browser.matchChrome_() || goog.labs.userAgent.browser.matchCoast_() || goog.labs.userAgent.browser.matchOpera_() || goog.labs.userAgent.browser.isSilk() || goog.labs.userAgent.util.matchUserAgent("Android"));
+};
+goog.labs.userAgent.browser.matchCoast_ = function() {
+ return goog.labs.userAgent.util.matchUserAgent("Coast");
+};
+goog.labs.userAgent.browser.matchIosWebview_ = function() {
+ return(goog.labs.userAgent.util.matchUserAgent("iPad") || goog.labs.userAgent.util.matchUserAgent("iPhone")) && !goog.labs.userAgent.browser.matchSafari_() && !goog.labs.userAgent.browser.matchChrome_() && !goog.labs.userAgent.browser.matchCoast_() && goog.labs.userAgent.util.matchUserAgent("AppleWebKit");
+};
+goog.labs.userAgent.browser.matchChrome_ = function() {
+ return(goog.labs.userAgent.util.matchUserAgent("Chrome") || goog.labs.userAgent.util.matchUserAgent("CriOS")) && !goog.labs.userAgent.browser.matchOpera_();
+};
+goog.labs.userAgent.browser.matchAndroidBrowser_ = function() {
+ return goog.labs.userAgent.util.matchUserAgent("Android") && !(goog.labs.userAgent.browser.isChrome() || goog.labs.userAgent.browser.isFirefox() || goog.labs.userAgent.browser.isOpera() || goog.labs.userAgent.browser.isSilk());
+};
+goog.labs.userAgent.browser.isOpera = goog.labs.userAgent.browser.matchOpera_;
+goog.labs.userAgent.browser.isIE = goog.labs.userAgent.browser.matchIE_;
+goog.labs.userAgent.browser.isFirefox = goog.labs.userAgent.browser.matchFirefox_;
+goog.labs.userAgent.browser.isSafari = goog.labs.userAgent.browser.matchSafari_;
+goog.labs.userAgent.browser.isCoast = goog.labs.userAgent.browser.matchCoast_;
+goog.labs.userAgent.browser.isIosWebview = goog.labs.userAgent.browser.matchIosWebview_;
+goog.labs.userAgent.browser.isChrome = goog.labs.userAgent.browser.matchChrome_;
+goog.labs.userAgent.browser.isAndroidBrowser = goog.labs.userAgent.browser.matchAndroidBrowser_;
+goog.labs.userAgent.browser.isSilk = function() {
+ return goog.labs.userAgent.util.matchUserAgent("Silk");
+};
+goog.labs.userAgent.browser.getVersion = function() {
+ var userAgentString = goog.labs.userAgent.util.getUserAgent();
+ if (goog.labs.userAgent.browser.isIE()) {
+ return goog.labs.userAgent.browser.getIEVersion_(userAgentString);
+ }
+ var versionTuples = goog.labs.userAgent.util.extractVersionTuples(userAgentString);
+ var versionMap = {};
+ goog.array.forEach(versionTuples, function(tuple) {
+ var key = tuple[0];
+ var value = tuple[1];
+ versionMap[key] = value;
+ });
+ var versionMapHasKey = goog.partial(goog.object.containsKey, versionMap);
+ function lookUpValueWithKeys(keys) {
+ var key = goog.array.find(keys, versionMapHasKey);
+ return versionMap[key] || "";
+ }
+ if (goog.labs.userAgent.browser.isOpera()) {
+ return lookUpValueWithKeys(["Version", "Opera", "OPR"]);
+ }
+ if (goog.labs.userAgent.browser.isChrome()) {
+ return lookUpValueWithKeys(["Chrome", "CriOS"]);
+ }
+ var tuple = versionTuples[2];
+ return tuple && tuple[1] || "";
+};
+goog.labs.userAgent.browser.isVersionOrHigher = function(version) {
+ return goog.string.compareVersions(goog.labs.userAgent.browser.getVersion(), version) >= 0;
+};
+goog.labs.userAgent.browser.getIEVersion_ = function(userAgent) {
+ var rv = /rv: *([\d\.]*)/.exec(userAgent);
+ if (rv && rv[1]) {
+ return rv[1];
+ }
+ var version = "";
+ var msie = /MSIE +([\d\.]+)/.exec(userAgent);
+ if (msie && msie[1]) {
+ var tridentVersion = /Trident\/(\d.\d)/.exec(userAgent);
+ if (msie[1] == "7.0") {
+ if (tridentVersion && tridentVersion[1]) {
+ switch(tridentVersion[1]) {
+ case "4.0":
+ version = "8.0";
+ break;
+ case "5.0":
+ version = "9.0";
+ break;
+ case "6.0":
+ version = "10.0";
+ break;
+ case "7.0":
+ version = "11.0";
+ break;
+ }
+ } else {
+ version = "7.0";
+ }
+ } else {
+ version = msie[1];
+ }
+ }
+ return version;
+};
+goog.provide("goog.labs.userAgent.engine");
+goog.require("goog.array");
+goog.require("goog.labs.userAgent.util");
+goog.require("goog.string");
+goog.labs.userAgent.engine.isPresto = function() {
+ return goog.labs.userAgent.util.matchUserAgent("Presto");
+};
+goog.labs.userAgent.engine.isTrident = function() {
+ return goog.labs.userAgent.util.matchUserAgent("Trident") || goog.labs.userAgent.util.matchUserAgent("MSIE");
+};
+goog.labs.userAgent.engine.isWebKit = function() {
+ return goog.labs.userAgent.util.matchUserAgentIgnoreCase("WebKit");
+};
+goog.labs.userAgent.engine.isGecko = function() {
+ return goog.labs.userAgent.util.matchUserAgent("Gecko") && !goog.labs.userAgent.engine.isWebKit() && !goog.labs.userAgent.engine.isTrident();
+};
+goog.labs.userAgent.engine.getVersion = function() {
+ var userAgentString = goog.labs.userAgent.util.getUserAgent();
+ if (userAgentString) {
+ var tuples = goog.labs.userAgent.util.extractVersionTuples(userAgentString);
+ var engineTuple = tuples[1];
+ if (engineTuple) {
+ if (engineTuple[0] == "Gecko") {
+ return goog.labs.userAgent.engine.getVersionForKey_(tuples, "Firefox");
+ }
+ return engineTuple[1];
+ }
+ var browserTuple = tuples[0];
+ var info;
+ if (browserTuple && (info = browserTuple[2])) {
+ var match = /Trident\/([^\s;]+)/.exec(info);
+ if (match) {
+ return match[1];
+ }
+ }
+ }
+ return "";
+};
+goog.labs.userAgent.engine.isVersionOrHigher = function(version) {
+ return goog.string.compareVersions(goog.labs.userAgent.engine.getVersion(), version) >= 0;
+};
+goog.labs.userAgent.engine.getVersionForKey_ = function(tuples, key) {
+ var pair = goog.array.find(tuples, function(pair) {
+ return key == pair[0];
+ });
+ return pair && pair[1] || "";
+};
+goog.provide("goog.crypt");
+goog.require("goog.array");
+goog.require("goog.asserts");
+goog.crypt.stringToByteArray = function(str) {
+ var output = [], p = 0;
+ for (var i = 0;i < str.length;i++) {
+ var c = str.charCodeAt(i);
+ while (c > 255) {
+ output[p++] = c & 255;
+ c >>= 8;
+ }
+ output[p++] = c;
+ }
+ return output;
+};
+goog.crypt.byteArrayToString = function(bytes) {
+ var CHUNK_SIZE = 8192;
+ if (bytes.length < CHUNK_SIZE) {
+ return String.fromCharCode.apply(null, bytes);
+ }
+ var str = "";
+ for (var i = 0;i < bytes.length;i += CHUNK_SIZE) {
+ var chunk = goog.array.slice(bytes, i, i + CHUNK_SIZE);
+ str += String.fromCharCode.apply(null, chunk);
+ }
+ return str;
+};
+goog.crypt.byteArrayToHex = function(array) {
+ return goog.array.map(array, function(numByte) {
+ var hexByte = numByte.toString(16);
+ return hexByte.length > 1 ? hexByte : "0" + hexByte;
+ }).join("");
+};
+goog.crypt.hexToByteArray = function(hexString) {
+ goog.asserts.assert(hexString.length % 2 == 0, "Key string length must be multiple of 2");
+ var arr = [];
+ for (var i = 0;i < hexString.length;i += 2) {
+ arr.push(parseInt(hexString.substring(i, i + 2), 16));
+ }
+ return arr;
+};
+goog.crypt.stringToUtf8ByteArray = function(str) {
+ str = str.replace(/\r\n/g, "\n");
+ var out = [], p = 0;
+ for (var i = 0;i < str.length;i++) {
+ var c = str.charCodeAt(i);
+ if (c < 128) {
+ out[p++] = c;
+ } else {
+ if (c < 2048) {
+ out[p++] = c >> 6 | 192;
+ out[p++] = c & 63 | 128;
+ } else {
+ out[p++] = c >> 12 | 224;
+ out[p++] = c >> 6 & 63 | 128;
+ out[p++] = c & 63 | 128;
+ }
+ }
+ }
+ return out;
+};
+goog.crypt.utf8ByteArrayToString = function(bytes) {
+ var out = [], pos = 0, c = 0;
+ while (pos < bytes.length) {
+ var c1 = bytes[pos++];
+ if (c1 < 128) {
+ out[c++] = String.fromCharCode(c1);
+ } else {
+ if (c1 > 191 && c1 < 224) {
+ var c2 = bytes[pos++];
+ out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63);
+ } else {
+ var c2 = bytes[pos++];
+ var c3 = bytes[pos++];
+ out[c++] = String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
+ }
+ }
+ }
+ return out.join("");
+};
+goog.crypt.xorByteArray = function(bytes1, bytes2) {
+ goog.asserts.assert(bytes1.length == bytes2.length, "XOR array lengths must match");
+ var result = [];
+ for (var i = 0;i < bytes1.length;i++) {
+ result.push(bytes1[i] ^ bytes2[i]);
+ }
+ return result;
+};
+goog.provide("goog.userAgent");
+goog.require("goog.labs.userAgent.browser");
+goog.require("goog.labs.userAgent.engine");
+goog.require("goog.labs.userAgent.platform");
+goog.require("goog.labs.userAgent.util");
+goog.require("goog.string");
+goog.define("goog.userAgent.ASSUME_IE", false);
+goog.define("goog.userAgent.ASSUME_GECKO", false);
+goog.define("goog.userAgent.ASSUME_WEBKIT", false);
+goog.define("goog.userAgent.ASSUME_MOBILE_WEBKIT", false);
+goog.define("goog.userAgent.ASSUME_OPERA", false);
+goog.define("goog.userAgent.ASSUME_ANY_VERSION", false);
+goog.userAgent.BROWSER_KNOWN_ = goog.userAgent.ASSUME_IE || goog.userAgent.ASSUME_GECKO || goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_OPERA;
+goog.userAgent.getUserAgentString = function() {
+ return goog.labs.userAgent.util.getUserAgent();
+};
+goog.userAgent.getNavigator = function() {
+ return goog.global["navigator"] || null;
+};
+goog.userAgent.OPERA = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_OPERA : goog.labs.userAgent.browser.isOpera();
+goog.userAgent.IE = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_IE : goog.labs.userAgent.browser.isIE();
+goog.userAgent.GECKO = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_GECKO : goog.labs.userAgent.engine.isGecko();
+goog.userAgent.WEBKIT = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_MOBILE_WEBKIT : goog.labs.userAgent.engine.isWebKit();
+goog.userAgent.isMobile_ = function() {
+ return goog.userAgent.WEBKIT && goog.labs.userAgent.util.matchUserAgent("Mobile");
+};
+goog.userAgent.MOBILE = goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.isMobile_();
+goog.userAgent.SAFARI = goog.userAgent.WEBKIT;
+goog.userAgent.determinePlatform_ = function() {
+ var navigator = goog.userAgent.getNavigator();
+ return navigator && navigator.platform || "";
+};
+goog.userAgent.PLATFORM = goog.userAgent.determinePlatform_();
+goog.define("goog.userAgent.ASSUME_MAC", false);
+goog.define("goog.userAgent.ASSUME_WINDOWS", false);
+goog.define("goog.userAgent.ASSUME_LINUX", false);
+goog.define("goog.userAgent.ASSUME_X11", false);
+goog.define("goog.userAgent.ASSUME_ANDROID", false);
+goog.define("goog.userAgent.ASSUME_IPHONE", false);
+goog.define("goog.userAgent.ASSUME_IPAD", false);
+goog.userAgent.PLATFORM_KNOWN_ = goog.userAgent.ASSUME_MAC || goog.userAgent.ASSUME_WINDOWS || goog.userAgent.ASSUME_LINUX || goog.userAgent.ASSUME_X11 || goog.userAgent.ASSUME_ANDROID || goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD;
+goog.userAgent.MAC = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_MAC : goog.labs.userAgent.platform.isMacintosh();
+goog.userAgent.WINDOWS = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_WINDOWS : goog.labs.userAgent.platform.isWindows();
+goog.userAgent.isLegacyLinux_ = function() {
+ return goog.labs.userAgent.platform.isLinux() || goog.labs.userAgent.platform.isChromeOS();
+};
+goog.userAgent.LINUX = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_LINUX : goog.userAgent.isLegacyLinux_();
+goog.userAgent.isX11_ = function() {
+ var navigator = goog.userAgent.getNavigator();
+ return!!navigator && goog.string.contains(navigator["appVersion"] || "", "X11");
+};
+goog.userAgent.X11 = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_X11 : goog.userAgent.isX11_();
+goog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_ANDROID : goog.labs.userAgent.platform.isAndroid();
+goog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_IPHONE : goog.labs.userAgent.platform.isIphone();
+goog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_IPAD : goog.labs.userAgent.platform.isIpad();
+goog.userAgent.determineVersion_ = function() {
+ var version = "", re;
+ if (goog.userAgent.OPERA && goog.global["opera"]) {
+ var operaVersion = goog.global["opera"].version;
+ return goog.isFunction(operaVersion) ? operaVersion() : operaVersion;
+ }
+ if (goog.userAgent.GECKO) {
+ re = /rv\:([^\);]+)(\)|;)/;
+ } else {
+ if (goog.userAgent.IE) {
+ re = /\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/;
+ } else {
+ if (goog.userAgent.WEBKIT) {
+ re = /WebKit\/(\S+)/;
+ }
+ }
+ }
+ if (re) {
+ var arr = re.exec(goog.userAgent.getUserAgentString());
+ version = arr ? arr[1] : "";
+ }
+ if (goog.userAgent.IE) {
+ var docMode = goog.userAgent.getDocumentMode_();
+ if (docMode > parseFloat(version)) {
+ return String(docMode);
+ }
+ }
+ return version;
+};
+goog.userAgent.getDocumentMode_ = function() {
+ var doc = goog.global["document"];
+ return doc ? doc["documentMode"] : undefined;
+};
+goog.userAgent.VERSION = goog.userAgent.determineVersion_();
+goog.userAgent.compare = function(v1, v2) {
+ return goog.string.compareVersions(v1, v2);
+};
+goog.userAgent.isVersionOrHigherCache_ = {};
+goog.userAgent.isVersionOrHigher = function(version) {
+ return goog.userAgent.ASSUME_ANY_VERSION || goog.userAgent.isVersionOrHigherCache_[version] || (goog.userAgent.isVersionOrHigherCache_[version] = goog.string.compareVersions(goog.userAgent.VERSION, version) >= 0);
+};
+goog.userAgent.isVersion = goog.userAgent.isVersionOrHigher;
+goog.userAgent.isDocumentModeOrHigher = function(documentMode) {
+ return goog.userAgent.IE && goog.userAgent.DOCUMENT_MODE >= documentMode;
+};
+goog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher;
+goog.userAgent.DOCUMENT_MODE = function() {
+ var doc = goog.global["document"];
+ if (!doc || !goog.userAgent.IE) {
+ return undefined;
+ }
+ var mode = goog.userAgent.getDocumentMode_();
+ return mode || (doc["compatMode"] == "CSS1Compat" ? parseInt(goog.userAgent.VERSION, 10) : 5);
+}();
+goog.provide("goog.crypt.base64");
+goog.require("goog.crypt");
+goog.require("goog.userAgent");
+goog.crypt.base64.byteToCharMap_ = null;
+goog.crypt.base64.charToByteMap_ = null;
+goog.crypt.base64.byteToCharMapWebSafe_ = null;
+goog.crypt.base64.charToByteMapWebSafe_ = null;
+goog.crypt.base64.ENCODED_VALS_BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789";
+goog.crypt.base64.ENCODED_VALS = goog.crypt.base64.ENCODED_VALS_BASE + "+/=";
+goog.crypt.base64.ENCODED_VALS_WEBSAFE = goog.crypt.base64.ENCODED_VALS_BASE + "-_.";
+goog.crypt.base64.HAS_NATIVE_SUPPORT = goog.userAgent.GECKO || goog.userAgent.WEBKIT || goog.userAgent.OPERA || typeof goog.global.atob == "function";
+goog.crypt.base64.encodeByteArray = function(input, opt_webSafe) {
+ if (!goog.isArrayLike(input)) {
+ throw Error("encodeByteArray takes an array as a parameter");
+ }
+ goog.crypt.base64.init_();
+ var byteToCharMap = opt_webSafe ? goog.crypt.base64.byteToCharMapWebSafe_ : goog.crypt.base64.byteToCharMap_;
+ var output = [];
+ for (var i = 0;i < input.length;i += 3) {
+ var byte1 = input[i];
+ var haveByte2 = i + 1 < input.length;
+ var byte2 = haveByte2 ? input[i + 1] : 0;
+ var haveByte3 = i + 2 < input.length;
+ var byte3 = haveByte3 ? input[i + 2] : 0;
+ var outByte1 = byte1 >> 2;
+ var outByte2 = (byte1 & 3) << 4 | byte2 >> 4;
+ var outByte3 = (byte2 & 15) << 2 | byte3 >> 6;
+ var outByte4 = byte3 & 63;
+ if (!haveByte3) {
+ outByte4 = 64;
+ if (!haveByte2) {
+ outByte3 = 64;
+ }
+ }
+ output.push(byteToCharMap[outByte1], byteToCharMap[outByte2], byteToCharMap[outByte3], byteToCharMap[outByte4]);
+ }
+ return output.join("");
+};
+goog.crypt.base64.encodeString = function(input, opt_webSafe) {
+ if (goog.crypt.base64.HAS_NATIVE_SUPPORT && !opt_webSafe) {
+ return goog.global.btoa(input);
+ }
+ return goog.crypt.base64.encodeByteArray(goog.crypt.stringToByteArray(input), opt_webSafe);
+};
+goog.crypt.base64.decodeString = function(input, opt_webSafe) {
+ if (goog.crypt.base64.HAS_NATIVE_SUPPORT && !opt_webSafe) {
+ return goog.global.atob(input);
+ }
+ return goog.crypt.byteArrayToString(goog.crypt.base64.decodeStringToByteArray(input, opt_webSafe));
+};
+goog.crypt.base64.decodeStringToByteArray = function(input, opt_webSafe) {
+ goog.crypt.base64.init_();
+ var charToByteMap = opt_webSafe ? goog.crypt.base64.charToByteMapWebSafe_ : goog.crypt.base64.charToByteMap_;
+ var output = [];
+ for (var i = 0;i < input.length;) {
+ var byte1 = charToByteMap[input.charAt(i++)];
+ var haveByte2 = i < input.length;
+ var byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;
+ ++i;
+ var haveByte3 = i < input.length;
+ var byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;
+ ++i;
+ var haveByte4 = i < input.length;
+ var byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;
+ ++i;
+ if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) {
+ throw Error();
+ }
+ var outByte1 = byte1 << 2 | byte2 >> 4;
+ output.push(outByte1);
+ if (byte3 != 64) {
+ var outByte2 = byte2 << 4 & 240 | byte3 >> 2;
+ output.push(outByte2);
+ if (byte4 != 64) {
+ var outByte3 = byte3 << 6 & 192 | byte4;
+ output.push(outByte3);
+ }
+ }
+ }
+ return output;
+};
+goog.crypt.base64.init_ = function() {
+ if (!goog.crypt.base64.byteToCharMap_) {
+ goog.crypt.base64.byteToCharMap_ = {};
+ goog.crypt.base64.charToByteMap_ = {};
+ goog.crypt.base64.byteToCharMapWebSafe_ = {};
+ goog.crypt.base64.charToByteMapWebSafe_ = {};
+ for (var i = 0;i < goog.crypt.base64.ENCODED_VALS.length;i++) {
+ goog.crypt.base64.byteToCharMap_[i] = goog.crypt.base64.ENCODED_VALS.charAt(i);
+ goog.crypt.base64.charToByteMap_[goog.crypt.base64.byteToCharMap_[i]] = i;
+ goog.crypt.base64.byteToCharMapWebSafe_[i] = goog.crypt.base64.ENCODED_VALS_WEBSAFE.charAt(i);
+ goog.crypt.base64.charToByteMapWebSafe_[goog.crypt.base64.byteToCharMapWebSafe_[i]] = i;
+ if (i >= goog.crypt.base64.ENCODED_VALS_BASE.length) {
+ goog.crypt.base64.charToByteMap_[goog.crypt.base64.ENCODED_VALS_WEBSAFE.charAt(i)] = i;
+ goog.crypt.base64.charToByteMapWebSafe_[goog.crypt.base64.ENCODED_VALS.charAt(i)] = i;
+ }
+ }
+ }
+};
+goog.provide("fb.constants");
+var NODE_CLIENT = false;
+var CLIENT_VERSION = "0.0.0";
+goog.provide("fb.util.obj");
+fb.util.obj.contains = function(obj, key) {
+ return Object.prototype.hasOwnProperty.call(obj, key);
+};
+fb.util.obj.get = function(obj, key) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
+ return obj[key];
+ }
+};
+fb.util.obj.foreach = function(obj, fn) {
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
+ fn(key, obj[key]);
+ }
+ }
+};
+fb.util.obj.clone = function(obj) {
+ var clone = {};
+ fb.util.obj.foreach(obj, function(key, value) {
+ clone[key] = value;
+ });
+ return clone;
+};
+goog.provide("fb.util");
+goog.require("fb.util.obj");
+fb.util.querystring = function(querystringParams) {
+ var params = [];
+ fb.util.obj.foreach(querystringParams, function(key, value) {
+ if (goog.isArray(value)) {
+ goog.array.forEach(value, function(arrayVal) {
+ params.push(encodeURIComponent(key) + "=" + encodeURIComponent(arrayVal));
+ });
+ } else {
+ params.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
+ }
+ });
+ return params.length ? "&" + params.join("&") : "";
+};
+fb.util.querystringDecode = function(querystring) {
+ var obj = {};
+ var tokens = querystring.replace(/^\?/, "").split("&");
+ goog.array.forEach(tokens, function(token) {
+ if (token) {
+ var key = token.split("=");
+ obj[key[0]] = key[1];
+ }
+ });
+ return obj;
+};
+goog.provide("fb.util.validation");
+fb.util.validation.validateArgCount = function(fnName, minCount, maxCount, argCount) {
+ var argError;
+ if (argCount < minCount) {
+ argError = "at least " + minCount;
+ } else {
+ if (argCount > maxCount) {
+ argError = maxCount === 0 ? "none" : "no more than " + maxCount;
+ }
+ }
+ if (argError) {
+ var error = fnName + " failed: Was called with " + argCount + (argCount === 1 ? " argument." : " arguments.") + " Expects " + argError + ".";
+ throw new Error(error);
+ }
+};
+fb.util.validation.errorPrefix = function(fnName, argumentNumber, optional) {
+ var argName = "";
+ switch(argumentNumber) {
+ case 1:
+ argName = optional ? "first" : "First";
+ break;
+ case 2:
+ argName = optional ? "second" : "Second";
+ break;
+ case 3:
+ argName = optional ? "third" : "Third";
+ break;
+ case 4:
+ argName = optional ? "fourth" : "Fourth";
+ break;
+ default:
+ throw new Error("errorPrefix called with argumentNumber > 4. Need to update it?");;
+ }
+ var error = fnName + " failed: ";
+ error += argName + " argument ";
+ return error;
+};
+fb.util.validation.validateNamespace = function(fnName, argumentNumber, namespace, optional) {
+ if (optional && !goog.isDef(namespace)) {
+ return;
+ }
+ if (!goog.isString(namespace)) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + "must be a valid firebase namespace.");
+ }
+};
+fb.util.validation.validateCallback = function(fnName, argumentNumber, callback, optional) {
+ if (optional && !goog.isDef(callback)) {
+ return;
+ }
+ if (!goog.isFunction(callback)) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + "must be a valid function.");
+ }
+};
+fb.util.validation.validateContextObject = function(fnName, argumentNumber, context, optional) {
+ if (optional && !goog.isDef(context)) {
+ return;
+ }
+ if (!goog.isObject(context) || context === null) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + "must be a valid context object.");
+ }
+};
+goog.provide("fb.util.json");
+goog.require("goog.json");
+fb.util.json.eval = function(str) {
+ if (typeof JSON !== "undefined" && goog.isDef(JSON.parse)) {
+ return JSON.parse(str);
+ } else {
+ return goog.json.parse(str);
+ }
+};
+fb.util.json.stringify = function(data) {
+ if (typeof JSON !== "undefined" && goog.isDef(JSON.stringify)) {
+ return JSON.stringify(data);
+ } else {
+ return goog.json.serialize(data);
+ }
+};
+goog.provide("fb.core.SnapshotHolder");
+fb.core.SnapshotHolder = function() {
+ this.rootNode_ = fb.core.snap.EMPTY_NODE;
+};
+fb.core.SnapshotHolder.prototype.getNode = function(path) {
+ return this.rootNode_.getChild(path);
+};
+fb.core.SnapshotHolder.prototype.updateSnapshot = function(path, newSnapshotNode) {
+ this.rootNode_ = this.rootNode_.updateChild(path, newSnapshotNode);
+};
+if (goog.DEBUG) {
+ fb.core.SnapshotHolder.prototype.toString = function() {
+ return this.rootNode_.toString();
+ };
+}
+;goog.provide("fb.core.view.CompleteChildSource");
+fb.core.view.CompleteChildSource = function() {
+};
+fb.core.view.CompleteChildSource.prototype.getCompleteChild = function(childKey) {
+};
+fb.core.view.CompleteChildSource.prototype.getChildAfterChild = function(index, child, reverse) {
+};
+fb.core.view.NoCompleteChildSource_ = function() {
+};
+fb.core.view.NoCompleteChildSource_.prototype.getCompleteChild = function() {
+ return null;
+};
+fb.core.view.NoCompleteChildSource_.prototype.getChildAfterChild = function() {
+ return null;
+};
+fb.core.view.NO_COMPLETE_CHILD_SOURCE = new fb.core.view.NoCompleteChildSource_;
+fb.core.view.WriteTreeCompleteChildSource = function(writes, viewCache, optCompleteServerCache) {
+ this.writes_ = writes;
+ this.viewCache_ = viewCache;
+ this.optCompleteServerCache_ = optCompleteServerCache;
+};
+fb.core.view.WriteTreeCompleteChildSource.prototype.getCompleteChild = function(childKey) {
+ var node = this.viewCache_.getEventCache();
+ if (node.isCompleteForChild(childKey)) {
+ return node.getNode().getImmediateChild(childKey);
+ } else {
+ var serverNode = this.optCompleteServerCache_ != null ? new fb.core.view.CacheNode(this.optCompleteServerCache_, true, false) : this.viewCache_.getServerCache();
+ return this.writes_.calcCompleteChild(childKey, serverNode);
+ }
+};
+fb.core.view.WriteTreeCompleteChildSource.prototype.getChildAfterChild = function(index, child, reverse) {
+ var completeServerData = this.optCompleteServerCache_ != null ? this.optCompleteServerCache_ : this.viewCache_.getCompleteServerSnap();
+ var nodes = this.writes_.calcIndexedSlice(completeServerData, child, 1, reverse, index);
+ if (nodes.length === 0) {
+ return null;
+ } else {
+ return nodes[0];
+ }
+};
+goog.provide("fb.core.view.EventQueue");
+fb.core.view.EventQueue = function() {
+ this.eventLists_ = [];
+ this.recursionDepth_ = 0;
+};
+fb.core.view.EventQueue.prototype.queueEvents = function(eventDataList) {
+ var currList = null;
+ for (var i = 0;i < eventDataList.length;i++) {
+ var eventData = eventDataList[i];
+ var eventPath = eventData.getPath();
+ if (currList !== null && !eventPath.equals(currList.getPath())) {
+ this.eventLists_.push(currList);
+ currList = null;
+ }
+ if (currList === null) {
+ currList = new fb.core.view.EventList(eventPath);
+ }
+ currList.add(eventData);
+ }
+ if (currList) {
+ this.eventLists_.push(currList);
+ }
+};
+fb.core.view.EventQueue.prototype.raiseEventsAtPath = function(path, eventDataList) {
+ this.queueEvents(eventDataList);
+ this.raiseQueuedEventsMatchingPredicate_(function(eventPath) {
+ return eventPath.equals(path);
+ });
+};
+fb.core.view.EventQueue.prototype.raiseEventsForChangedPath = function(changedPath, eventDataList) {
+ this.queueEvents(eventDataList);
+ this.raiseQueuedEventsMatchingPredicate_(function(eventPath) {
+ return eventPath.contains(changedPath) || changedPath.contains(eventPath);
+ });
+};
+fb.core.view.EventQueue.prototype.raiseQueuedEventsMatchingPredicate_ = function(predicate) {
+ this.recursionDepth_++;
+ var sentAll = true;
+ for (var i = 0;i < this.eventLists_.length;i++) {
+ var eventList = this.eventLists_[i];
+ if (eventList) {
+ var eventPath = eventList.getPath();
+ if (predicate(eventPath)) {
+ this.eventLists_[i].raise();
+ this.eventLists_[i] = null;
+ } else {
+ sentAll = false;
+ }
+ }
+ }
+ if (sentAll) {
+ this.eventLists_ = [];
+ }
+ this.recursionDepth_--;
+};
+fb.core.view.EventList = function(path) {
+ this.path_ = path;
+ this.events_ = [];
+};
+fb.core.view.EventList.prototype.add = function(eventData) {
+ this.events_.push(eventData);
+};
+fb.core.view.EventList.prototype.raise = function() {
+ for (var i = 0;i < this.events_.length;i++) {
+ var eventData = this.events_[i];
+ if (eventData !== null) {
+ this.events_[i] = null;
+ var eventFn = eventData.getEventRunner();
+ if (fb.core.util.logger) {
+ fb.core.util.log("event: " + eventData.toString());
+ }
+ fb.core.util.exceptionGuard(eventFn);
+ }
+ }
+};
+fb.core.view.EventList.prototype.getPath = function() {
+ return this.path_;
+};
+goog.provide("fb.core.view.Change");
+fb.core.view.Change = function(type, snapshotNode, childName, oldSnap, prevName) {
+ this.type = type;
+ this.snapshotNode = snapshotNode;
+ this.childName = childName;
+ this.oldSnap = oldSnap;
+ this.prevName = prevName;
+};
+fb.core.view.Change.valueChange = function(snapshot) {
+ return new fb.core.view.Change(fb.core.view.Change.VALUE, snapshot);
+};
+fb.core.view.Change.childAddedChange = function(childKey, snapshot) {
+ return new fb.core.view.Change(fb.core.view.Change.CHILD_ADDED, snapshot, childKey);
+};
+fb.core.view.Change.childRemovedChange = function(childKey, snapshot) {
+ return new fb.core.view.Change(fb.core.view.Change.CHILD_REMOVED, snapshot, childKey);
+};
+fb.core.view.Change.childChangedChange = function(childKey, newSnapshot, oldSnapshot) {
+ return new fb.core.view.Change(fb.core.view.Change.CHILD_CHANGED, newSnapshot, childKey, oldSnapshot);
+};
+fb.core.view.Change.childMovedChange = function(childKey, snapshot) {
+ return new fb.core.view.Change(fb.core.view.Change.CHILD_MOVED, snapshot, childKey);
+};
+fb.core.view.Change.prototype.changeWithPrevName = function(prevName) {
+ return new fb.core.view.Change(this.type, this.snapshotNode, this.childName, this.oldSnap, prevName);
+};
+fb.core.view.Change.CHILD_ADDED = "child_added";
+fb.core.view.Change.CHILD_REMOVED = "child_removed";
+fb.core.view.Change.CHILD_CHANGED = "child_changed";
+fb.core.view.Change.CHILD_MOVED = "child_moved";
+fb.core.view.Change.VALUE = "value";
+goog.provide("fb.core.view.Event");
+fb.core.view.Event = function() {
+};
+fb.core.view.Event.prototype.getPath;
+fb.core.view.Event.prototype.getEventType;
+fb.core.view.Event.prototype.getEventRunner;
+fb.core.view.Event.prototype.toString;
+fb.core.view.DataEvent = function(eventType, eventRegistration, snapshot, prevName) {
+ this.eventRegistration = eventRegistration;
+ this.snapshot = snapshot;
+ this.prevName = prevName;
+ this.eventType = eventType;
+};
+fb.core.view.DataEvent.prototype.getPath = function() {
+ var ref = this.snapshot.ref();
+ if (this.eventType === "value") {
+ return ref.path;
+ } else {
+ return ref.parent().path;
+ }
+};
+fb.core.view.DataEvent.prototype.getEventType = function() {
+ return this.eventType;
+};
+fb.core.view.DataEvent.prototype.getEventRunner = function() {
+ return this.eventRegistration.getEventRunner(this);
+};
+fb.core.view.DataEvent.prototype.toString = function() {
+ return this.getPath().toString() + ":" + this.eventType + ":" + fb.util.json.stringify(this.snapshot.exportVal());
+};
+fb.core.view.CancelEvent = function(eventRegistration, error, path) {
+ this.eventRegistration = eventRegistration;
+ this.error = error;
+ this.path = path;
+};
+fb.core.view.CancelEvent.prototype.getPath = function() {
+ return this.path;
+};
+fb.core.view.CancelEvent.prototype.getEventType = function() {
+ return "cancel";
+};
+fb.core.view.CancelEvent.prototype.getEventRunner = function() {
+ return this.eventRegistration.getEventRunner(this);
+};
+fb.core.view.CancelEvent.prototype.toString = function() {
+ return this.path.toString() + ":cancel";
+};
+goog.provide("fb.core.view.CacheNode");
+fb.core.view.CacheNode = function(node, fullyInitialized, filtered) {
+ this.node_ = node;
+ this.fullyInitialized_ = fullyInitialized;
+ this.filtered_ = filtered;
+};
+fb.core.view.CacheNode.prototype.isFullyInitialized = function() {
+ return this.fullyInitialized_;
+};
+fb.core.view.CacheNode.prototype.isFiltered = function() {
+ return this.filtered_;
+};
+fb.core.view.CacheNode.prototype.isCompleteForPath = function(path) {
+ if (path.isEmpty()) {
+ return this.isFullyInitialized() && !this.filtered_;
+ } else {
+ var childKey = path.getFront();
+ return this.isCompleteForChild(childKey);
+ }
+};
+fb.core.view.CacheNode.prototype.isCompleteForChild = function(key) {
+ return this.isFullyInitialized() && !this.filtered_ || this.node_.hasChild(key);
+};
+fb.core.view.CacheNode.prototype.getNode = function() {
+ return this.node_;
+};
+goog.provide("fb.core.stats.StatsListener");
+fb.core.stats.StatsListener = function(collection) {
+ this.collection_ = collection;
+ this.last_ = null;
+};
+fb.core.stats.StatsListener.prototype.get = function() {
+ var newStats = this.collection_.get();
+ var delta = goog.object.clone(newStats);
+ if (this.last_) {
+ for (var stat in this.last_) {
+ delta[stat] = delta[stat] - this.last_[stat];
+ }
+ }
+ this.last_ = newStats;
+ return delta;
+};
+goog.provide("fb.core.stats.StatsReporter");
+var FIRST_STATS_MIN_TIME = 10 * 1E3;
+var FIRST_STATS_MAX_TIME = 30 * 1E3;
+var REPORT_STATS_INTERVAL = 5 * 60 * 1E3;
+fb.core.stats.StatsReporter = function(collection, connection) {
+ this.statsToReport_ = {};
+ this.statsListener_ = new fb.core.stats.StatsListener(collection);
+ this.server_ = connection;
+ var timeout = FIRST_STATS_MIN_TIME + (FIRST_STATS_MAX_TIME - FIRST_STATS_MIN_TIME) * Math.random();
+ setTimeout(goog.bind(this.reportStats_, this), Math.floor(timeout));
+};
+fb.core.stats.StatsReporter.prototype.includeStat = function(stat) {
+ this.statsToReport_[stat] = true;
+};
+fb.core.stats.StatsReporter.prototype.reportStats_ = function() {
+ var stats = this.statsListener_.get();
+ var reportedStats = {};
+ var haveStatsToReport = false;
+ for (var stat in stats) {
+ if (stats[stat] > 0 && fb.util.obj.contains(this.statsToReport_, stat)) {
+ reportedStats[stat] = stats[stat];
+ haveStatsToReport = true;
+ }
+ }
+ if (haveStatsToReport) {
+ this.server_.reportStats(reportedStats);
+ }
+ setTimeout(goog.bind(this.reportStats_, this), Math.floor(Math.random() * 2 * REPORT_STATS_INTERVAL));
+};
+goog.provide("fb.core.stats.StatsCollection");
+goog.require("fb.util.obj");
+goog.require("goog.array");
+goog.require("goog.object");
+fb.core.stats.StatsCollection = function() {
+ this.counters_ = {};
+};
+fb.core.stats.StatsCollection.prototype.incrementCounter = function(name, amount) {
+ if (!goog.isDef(amount)) {
+ amount = 1;
+ }
+ if (!fb.util.obj.contains(this.counters_, name)) {
+ this.counters_[name] = 0;
+ }
+ this.counters_[name] += amount;
+};
+fb.core.stats.StatsCollection.prototype.get = function() {
+ return goog.object.clone(this.counters_);
+};
+goog.provide("fb.core.stats.StatsManager");
+goog.require("fb.core.stats.StatsCollection");
+goog.require("fb.core.stats.StatsListener");
+goog.require("fb.core.stats.StatsReporter");
+fb.core.stats.StatsManager = {};
+fb.core.stats.StatsManager.collections_ = {};
+fb.core.stats.StatsManager.reporters_ = {};
+fb.core.stats.StatsManager.getCollection = function(repoInfo) {
+ var hashString = repoInfo.toString();
+ if (!fb.core.stats.StatsManager.collections_[hashString]) {
+ fb.core.stats.StatsManager.collections_[hashString] = new fb.core.stats.StatsCollection;
+ }
+ return fb.core.stats.StatsManager.collections_[hashString];
+};
+fb.core.stats.StatsManager.getOrCreateReporter = function(repoInfo, creatorFunction) {
+ var hashString = repoInfo.toString();
+ if (!fb.core.stats.StatsManager.reporters_[hashString]) {
+ fb.core.stats.StatsManager.reporters_[hashString] = creatorFunction();
+ }
+ return fb.core.stats.StatsManager.reporters_[hashString];
+};
+goog.provide("fb.core.ServerActions");
+fb.core.ServerActions = goog.defineClass(null, {listen:goog.abstractMethod, unlisten:goog.abstractMethod, put:goog.abstractMethod, merge:goog.abstractMethod, auth:goog.abstractMethod, unauth:goog.abstractMethod, onDisconnectPut:goog.abstractMethod, onDisconnectMerge:goog.abstractMethod, onDisconnectCancel:goog.abstractMethod, reportStats:goog.abstractMethod});
+goog.provide("fb.core.snap.Node");
+goog.provide("fb.core.snap.NamedNode");
+fb.core.snap.Node = function() {
+};
+fb.core.snap.Node.prototype.isLeafNode;
+fb.core.snap.Node.prototype.getPriority;
+fb.core.snap.Node.prototype.updatePriority;
+fb.core.snap.Node.prototype.getImmediateChild;
+fb.core.snap.Node.prototype.getChild;
+fb.core.snap.Node.prototype.getPredecessorChildName;
+fb.core.snap.Node.prototype.updateImmediateChild;
+fb.core.snap.Node.prototype.updateChild;
+fb.core.snap.Node.prototype.hasChild;
+fb.core.snap.Node.prototype.isEmpty;
+fb.core.snap.Node.prototype.numChildren;
+fb.core.snap.Node.prototype.val;
+fb.core.snap.Node.prototype.hash;
+fb.core.snap.Node.prototype.compareTo;
+fb.core.snap.Node.prototype.equals;
+fb.core.snap.Node.prototype.withIndex;
+fb.core.snap.Node.prototype.isIndexed;
+fb.core.snap.NamedNode = function(name, node) {
+ this.name = name;
+ this.node = node;
+};
+fb.core.snap.NamedNode.Wrap = function(name, node) {
+ return new fb.core.snap.NamedNode(name, node);
+};
+goog.provide("fb.core.snap.comparators");
+fb.core.snap.NAME_ONLY_COMPARATOR = function(left, right) {
+ return fb.core.util.nameCompare(left.name, right.name);
+};
+fb.core.snap.NAME_COMPARATOR = function(left, right) {
+ return fb.core.util.nameCompare(left, right);
+};
+goog.provide("fb.core.operation.Overwrite");
+fb.core.operation.Overwrite = function(source, path, snap) {
+ this.type = fb.core.OperationType.OVERWRITE;
+ this.source = source;
+ this.path = path;
+ this.snap = snap;
+};
+fb.core.operation.Overwrite.prototype.operationForChild = function(childName) {
+ if (this.path.isEmpty()) {
+ return new fb.core.operation.Overwrite(this.source, fb.core.util.Path.Empty, this.snap.getImmediateChild(childName));
+ } else {
+ return new fb.core.operation.Overwrite(this.source, this.path.popFront(), this.snap);
+ }
+};
+if (goog.DEBUG) {
+ fb.core.operation.Overwrite.prototype.toString = function() {
+ return "Operation(" + this.path + ": " + this.source.toString() + " overwrite: " + this.snap.toString() + ")";
+ };
+}
+;goog.provide("fb.core.operation.AckUserWrite");
+fb.core.operation.AckUserWrite = function(path, revert) {
+ this.type = fb.core.OperationType.ACK_USER_WRITE;
+ this.source = fb.core.OperationSource.User;
+ this.path = path;
+ this.revert = revert;
+};
+fb.core.operation.AckUserWrite.prototype.operationForChild = function(childName) {
+ if (!this.path.isEmpty()) {
+ return new fb.core.operation.AckUserWrite(this.path.popFront(), this.revert);
+ } else {
+ return this;
+ }
+};
+if (goog.DEBUG) {
+ fb.core.operation.AckUserWrite.prototype.toString = function() {
+ return "Operation(" + this.path + ": " + this.source.toString() + " ack write revert=" + this.revert + ")";
+ };
+}
+;goog.provide("fb.core.operation.ListenComplete");
+fb.core.operation.ListenComplete = function(source, path) {
+ this.type = fb.core.OperationType.LISTEN_COMPLETE;
+ this.source = source;
+ this.path = path;
+};
+fb.core.operation.ListenComplete.prototype.operationForChild = function(childName) {
+ if (this.path.isEmpty()) {
+ return new fb.core.operation.ListenComplete(this.source, fb.core.util.Path.Empty);
+ } else {
+ return new fb.core.operation.ListenComplete(this.source, this.path.popFront());
+ }
+};
+if (goog.DEBUG) {
+ fb.core.operation.ListenComplete.prototype.toString = function() {
+ return "Operation(" + this.path + ": " + this.source.toString() + " listen_complete)";
+ };
+}
+;goog.provide("fb.core.util.SortedMap");
+goog.require("goog.array");
+fb.Comparator;
+fb.core.util.SortedMap = goog.defineClass(null, {constructor:function(comparator, opt_root) {
+ this.comparator_ = comparator;
+ this.root_ = opt_root ? opt_root : fb.core.util.SortedMap.EMPTY_NODE_;
+}, insert:function(key, value) {
+ return new fb.core.util.SortedMap(this.comparator_, this.root_.insert(key, value, this.comparator_).copy(null, null, fb.LLRBNode.BLACK, null, null));
+}, remove:function(key) {
+ return new fb.core.util.SortedMap(this.comparator_, this.root_.remove(key, this.comparator_).copy(null, null, fb.LLRBNode.BLACK, null, null));
+}, get:function(key) {
+ var cmp;
+ var node = this.root_;
+ while (!node.isEmpty()) {
+ cmp = this.comparator_(key, node.key);
+ if (cmp === 0) {
+ return node.value;
+ } else {
+ if (cmp < 0) {
+ node = node.left;
+ } else {
+ if (cmp > 0) {
+ node = node.right;
+ }
+ }
+ }
+ }
+ return null;
+}, getPredecessorKey:function(key) {
+ var cmp, node = this.root_, rightParent = null;
+ while (!node.isEmpty()) {
+ cmp = this.comparator_(key, node.key);
+ if (cmp === 0) {
+ if (!node.left.isEmpty()) {
+ node = node.left;
+ while (!node.right.isEmpty()) {
+ node = node.right;
+ }
+ return node.key;
+ } else {
+ if (rightParent) {
+ return rightParent.key;
+ } else {
+ return null;
+ }
+ }
+ } else {
+ if (cmp < 0) {
+ node = node.left;
+ } else {
+ if (cmp > 0) {
+ rightParent = node;
+ node = node.right;
+ }
+ }
+ }
+ }
+ throw new Error("Attempted to find predecessor key for a nonexistent key. What gives?");
+}, isEmpty:function() {
+ return this.root_.isEmpty();
+}, count:function() {
+ return this.root_.count();
+}, minKey:function() {
+ return this.root_.minKey();
+}, maxKey:function() {
+ return this.root_.maxKey();
+}, inorderTraversal:function(action) {
+ return this.root_.inorderTraversal(action);
+}, reverseTraversal:function(action) {
+ return this.root_.reverseTraversal(action);
+}, getIterator:function(opt_resultGenerator) {
+ return new fb.core.util.SortedMapIterator(this.root_, null, this.comparator_, false, opt_resultGenerator);
+}, getIteratorFrom:function(key, opt_resultGenerator) {
+ return new fb.core.util.SortedMapIterator(this.root_, key, this.comparator_, false, opt_resultGenerator);
+}, getReverseIteratorFrom:function(key, opt_resultGenerator) {
+ return new fb.core.util.SortedMapIterator(this.root_, key, this.comparator_, true, opt_resultGenerator);
+}, getReverseIterator:function(opt_resultGenerator) {
+ return new fb.core.util.SortedMapIterator(this.root_, null, this.comparator_, true, opt_resultGenerator);
+}});
+fb.core.util.SortedMapIterator = goog.defineClass(null, {constructor:function(node, startKey, comparator, isReverse, opt_resultGenerator) {
+ this.resultGenerator_ = opt_resultGenerator || null;
+ this.isReverse_ = isReverse;
+ this.nodeStack_ = [];
+ var cmp = 1;
+ while (!node.isEmpty()) {
+ cmp = startKey ? comparator(node.key, startKey) : 1;
+ if (isReverse) {
+ cmp *= -1;
+ }
+ if (cmp < 0) {
+ if (this.isReverse_) {
+ node = node.left;
+ } else {
+ node = node.right;
+ }
+ } else {
+ if (cmp === 0) {
+ this.nodeStack_.push(node);
+ break;
+ } else {
+ this.nodeStack_.push(node);
+ if (this.isReverse_) {
+ node = node.right;
+ } else {
+ node = node.left;
+ }
+ }
+ }
+ }
+}, getNext:function() {
+ if (this.nodeStack_.length === 0) {
+ return null;
+ }
+ var node = this.nodeStack_.pop(), result;
+ if (this.resultGenerator_) {
+ result = this.resultGenerator_(node.key, node.value);
+ } else {
+ result = {key:node.key, value:node.value};
+ }
+ if (this.isReverse_) {
+ node = node.left;
+ while (!node.isEmpty()) {
+ this.nodeStack_.push(node);
+ node = node.right;
+ }
+ } else {
+ node = node.right;
+ while (!node.isEmpty()) {
+ this.nodeStack_.push(node);
+ node = node.left;
+ }
+ }
+ return result;
+}, hasNext:function() {
+ return this.nodeStack_.length > 0;
+}, peek:function() {
+ if (this.nodeStack_.length === 0) {
+ return null;
+ }
+ var node = goog.array.peek(this.nodeStack_);
+ if (this.resultGenerator_) {
+ return this.resultGenerator_(node.key, node.value);
+ } else {
+ return{key:node.key, value:node.value};
+ }
+}});
+fb.LLRBNode = goog.defineClass(null, {constructor:function(key, value, color, opt_left, opt_right) {
+ this.key = key;
+ this.value = value;
+ this.color = color != null ? color : fb.LLRBNode.RED;
+ this.left = opt_left != null ? opt_left : fb.core.util.SortedMap.EMPTY_NODE_;
+ this.right = opt_right != null ? opt_right : fb.core.util.SortedMap.EMPTY_NODE_;
+}, statics:{RED:true, BLACK:false}, copy:function(key, value, color, left, right) {
+ return new fb.LLRBNode(key != null ? key : this.key, value != null ? value : this.value, color != null ? color : this.color, left != null ? left : this.left, right != null ? right : this.right);
+}, count:function() {
+ return this.left.count() + 1 + this.right.count();
+}, isEmpty:function() {
+ return false;
+}, inorderTraversal:function(action) {
+ return this.left.inorderTraversal(action) || action(this.key, this.value) || this.right.inorderTraversal(action);
+}, reverseTraversal:function(action) {
+ return this.right.reverseTraversal(action) || action(this.key, this.value) || this.left.reverseTraversal(action);
+}, min_:function() {
+ if (this.left.isEmpty()) {
+ return this;
+ } else {
+ return this.left.min_();
+ }
+}, minKey:function() {
+ return this.min_().key;
+}, maxKey:function() {
+ if (this.right.isEmpty()) {
+ return this.key;
+ } else {
+ return this.right.maxKey();
+ }
+}, insert:function(key, value, comparator) {
+ var cmp, n;
+ n = this;
+ cmp = comparator(key, n.key);
+ if (cmp < 0) {
+ n = n.copy(null, null, null, n.left.insert(key, value, comparator), null);
+ } else {
+ if (cmp === 0) {
+ n = n.copy(null, value, null, null, null);
+ } else {
+ n = n.copy(null, null, null, null, n.right.insert(key, value, comparator));
+ }
+ }
+ return n.fixUp_();
+}, removeMin_:function() {
+ var n;
+ if (this.left.isEmpty()) {
+ return fb.core.util.SortedMap.EMPTY_NODE_;
+ }
+ n = this;
+ if (!n.left.isRed_() && !n.left.left.isRed_()) {
+ n = n.moveRedLeft_();
+ }
+ n = n.copy(null, null, null, n.left.removeMin_(), null);
+ return n.fixUp_();
+}, remove:function(key, comparator) {
+ var n, smallest;
+ n = this;
+ if (comparator(key, n.key) < 0) {
+ if (!n.left.isEmpty() && !n.left.isRed_() && !n.left.left.isRed_()) {
+ n = n.moveRedLeft_();
+ }
+ n = n.copy(null, null, null, n.left.remove(key, comparator), null);
+ } else {
+ if (n.left.isRed_()) {
+ n = n.rotateRight_();
+ }
+ if (!n.right.isEmpty() && !n.right.isRed_() && !n.right.left.isRed_()) {
+ n = n.moveRedRight_();
+ }
+ if (comparator(key, n.key) === 0) {
+ if (n.right.isEmpty()) {
+ return fb.core.util.SortedMap.EMPTY_NODE_;
+ } else {
+ smallest = n.right.min_();
+ n = n.copy(smallest.key, smallest.value, null, null, n.right.removeMin_());
+ }
+ }
+ n = n.copy(null, null, null, null, n.right.remove(key, comparator));
+ }
+ return n.fixUp_();
+}, isRed_:function() {
+ return this.color;
+}, fixUp_:function() {
+ var n = this;
+ if (n.right.isRed_() && !n.left.isRed_()) {
+ n = n.rotateLeft_();
+ }
+ if (n.left.isRed_() && n.left.left.isRed_()) {
+ n = n.rotateRight_();
+ }
+ if (n.left.isRed_() && n.right.isRed_()) {
+ n = n.colorFlip_();
+ }
+ return n;
+}, moveRedLeft_:function() {
+ var n = this.colorFlip_();
+ if (n.right.left.isRed_()) {
+ n = n.copy(null, null, null, null, n.right.rotateRight_());
+ n = n.rotateLeft_();
+ n = n.colorFlip_();
+ }
+ return n;
+}, moveRedRight_:function() {
+ var n = this.colorFlip_();
+ if (n.left.left.isRed_()) {
+ n = n.rotateRight_();
+ n = n.colorFlip_();
+ }
+ return n;
+}, rotateLeft_:function() {
+ var nl;
+ nl = this.copy(null, null, fb.LLRBNode.RED, null, this.right.left);
+ return this.right.copy(null, null, this.color, nl, null);
+}, rotateRight_:function() {
+ var nr;
+ nr = this.copy(null, null, fb.LLRBNode.RED, this.left.right, null);
+ return this.left.copy(null, null, this.color, null, nr);
+}, colorFlip_:function() {
+ var left, right;
+ left = this.left.copy(null, null, !this.left.color, null, null);
+ right = this.right.copy(null, null, !this.right.color, null, null);
+ return this.copy(null, null, !this.color, left, right);
+}, checkMaxDepth_:function() {
+ var blackDepth;
+ blackDepth = this.check_();
+ if (Math.pow(2, blackDepth) <= this.count() + 1) {
+ return true;
+ } else {
+ return false;
+ }
+}, check_:function() {
+ var blackDepth;
+ if (this.isRed_() && this.left.isRed_()) {
+ throw new Error("Red node has red child(" + this.key + "," + this.value + ")");
+ }
+ if (this.right.isRed_()) {
+ throw new Error("Right child of (" + this.key + "," + this.value + ") is red");
+ }
+ blackDepth = this.left.check_();
+ if (blackDepth !== this.right.check_()) {
+ throw new Error("Black depths differ");
+ } else {
+ return blackDepth + (this.isRed_() ? 0 : 1);
+ }
+}});
+fb.LLRBEmptyNode = goog.defineClass(null, {constructor:function() {
+}, copy:function() {
+ return this;
+}, insert:function(key, value, comparator) {
+ return new fb.LLRBNode(key, value, null);
+}, remove:function(key, comparator) {
+ return this;
+}, count:function() {
+ return 0;
+}, isEmpty:function() {
+ return true;
+}, inorderTraversal:function(action) {
+ return false;
+}, reverseTraversal:function(action) {
+ return false;
+}, minKey:function() {
+ return null;
+}, maxKey:function() {
+ return null;
+}, check_:function() {
+ return 0;
+}, isRed_:function() {
+ return false;
+}});
+fb.core.util.SortedMap.EMPTY_NODE_ = new fb.LLRBEmptyNode;
+goog.provide("fb.core.util.NodePatches");
+(function() {
+ if (NODE_CLIENT) {
+ var version = process["version"];
+ if (version === "v0.10.22" || version === "v0.10.23" || version === "v0.10.24") {
+ var Writable = require("_stream_writable");
+ Writable["prototype"]["write"] = function(chunk, encoding, cb) {
+ var state = this["_writableState"];
+ var ret = false;
+ if (typeof encoding === "function") {
+ cb = encoding;
+ encoding = null;
+ }
+ if (Buffer["isBuffer"](chunk)) {
+ encoding = "buffer";
+ } else {
+ if (!encoding) {
+ encoding = state["defaultEncoding"];
+ }
+ }
+ if (typeof cb !== "function") {
+ cb = function() {
+ };
+ }
+ if (state["ended"]) {
+ writeAfterEnd(this, state, cb);
+ } else {
+ if (validChunk(this, state, chunk, cb)) {
+ ret = writeOrBuffer(this, state, chunk, encoding, cb);
+ }
+ }
+ return ret;
+ };
+ function writeAfterEnd(stream, state, cb) {
+ var er = new Error("write after end");
+ stream["emit"]("error", er);
+ process["nextTick"](function() {
+ cb(er);
+ });
+ }
+ function validChunk(stream, state, chunk, cb) {
+ var valid = true;
+ if (!Buffer["isBuffer"](chunk) && "string" !== typeof chunk && chunk !== null && chunk !== undefined && !state["objectMode"]) {
+ var er = new TypeError("Invalid non-string/buffer chunk");
+ stream["emit"]("error", er);
+ process["nextTick"](function() {
+ cb(er);
+ });
+ valid = false;
+ }
+ return valid;
+ }
+ function writeOrBuffer(stream, state, chunk, encoding, cb) {
+ chunk = decodeChunk(state, chunk, encoding);
+ if (Buffer["isBuffer"](chunk)) {
+ encoding = "buffer";
+ }
+ var len = state["objectMode"] ? 1 : chunk["length"];
+ state["length"] += len;
+ var ret = state["length"] < state["highWaterMark"];
+ if (!ret) {
+ state["needDrain"] = true;
+ }
+ if (state["writing"]) {
+ state["buffer"]["push"](new WriteReq(chunk, encoding, cb));
+ } else {
+ doWrite(stream, state, len, chunk, encoding, cb);
+ }
+ return ret;
+ }
+ function decodeChunk(state, chunk, encoding) {
+ if (!state["objectMode"] && state["decodeStrings"] !== false && typeof chunk === "string") {
+ chunk = new Buffer(chunk, encoding);
+ }
+ return chunk;
+ }
+ function WriteReq(chunk, encoding, cb) {
+ this["chunk"] = chunk;
+ this["encoding"] = encoding;
+ this["callback"] = cb;
+ }
+ function doWrite(stream, state, len, chunk, encoding, cb) {
+ state["writelen"] = len;
+ state["writecb"] = cb;
+ state["writing"] = true;
+ state["sync"] = true;
+ stream["_write"](chunk, encoding, state["onwrite"]);
+ state["sync"] = false;
+ }
+ var Duplex = require("_stream_duplex");
+ Duplex["prototype"]["write"] = Writable["prototype"]["write"];
+ }
+ }
+})();
+goog.provide("fb.core.util.ServerValues");
+fb.core.util.ServerValues.generateWithValues = function(values) {
+ values = values || {};
+ values["timestamp"] = values["timestamp"] || (new Date).getTime();
+ return values;
+};
+fb.core.util.ServerValues.resolveDeferredValue = function(value, serverValues) {
+ if (!value || typeof value !== "object") {
+ return(value);
+ } else {
+ fb.core.util.assert(".sv" in value, "Unexpected leaf node or priority contents");
+ return serverValues[value[".sv"]];
+ }
+};
+fb.core.util.ServerValues.resolveDeferredValueTree = function(tree, serverValues) {
+ var resolvedTree = new fb.core.SparseSnapshotTree;
+ tree.forEachTree(new fb.core.util.Path(""), function(path, node) {
+ resolvedTree.remember(path, fb.core.util.ServerValues.resolveDeferredValueSnapshot(node, serverValues));
+ });
+ return resolvedTree;
+};
+fb.core.util.ServerValues.resolveDeferredValueSnapshot = function(node, serverValues) {
+ var rawPri = (node.getPriority().val()), priority = fb.core.util.ServerValues.resolveDeferredValue(rawPri, serverValues), newNode;
+ if (node.isLeafNode()) {
+ var leafNode = (node);
+ var value = fb.core.util.ServerValues.resolveDeferredValue(leafNode.getValue(), serverValues);
+ if (value !== leafNode.getValue() || priority !== leafNode.getPriority().val()) {
+ return new fb.core.snap.LeafNode(value, fb.core.snap.NodeFromJSON(priority));
+ } else {
+ return node;
+ }
+ } else {
+ var childrenNode = (node);
+ newNode = childrenNode;
+ if (priority !== childrenNode.getPriority().val()) {
+ newNode = newNode.updatePriority(new fb.core.snap.LeafNode(priority));
+ }
+ childrenNode.forEachChild(fb.core.snap.PriorityIndex, function(childName, childNode) {
+ var newChildNode = fb.core.util.ServerValues.resolveDeferredValueSnapshot(childNode, serverValues);
+ if (newChildNode !== childNode) {
+ newNode = newNode.updateImmediateChild(childName, newChildNode);
+ }
+ });
+ return newNode;
+ }
+};
+goog.provide("fb.core.util.Path");
+goog.provide("fb.core.util.ValidationPath");
+fb.core.util.Path = goog.defineClass(null, {constructor:function(pathOrString, opt_pieceNum) {
+ if (arguments.length == 1) {
+ this.pieces_ = pathOrString.split("/");
+ var copyTo = 0;
+ for (var i = 0;i < this.pieces_.length;i++) {
+ if (this.pieces_[i].length > 0) {
+ this.pieces_[copyTo] = this.pieces_[i];
+ copyTo++;
+ }
+ }
+ this.pieces_.length = copyTo;
+ this.pieceNum_ = 0;
+ } else {
+ this.pieces_ = pathOrString;
+ this.pieceNum_ = opt_pieceNum;
+ }
+}, getFront:function() {
+ if (this.pieceNum_ >= this.pieces_.length) {
+ return null;
+ }
+ return this.pieces_[this.pieceNum_];
+}, getLength:function() {
+ return this.pieces_.length - this.pieceNum_;
+}, popFront:function() {
+ var pieceNum = this.pieceNum_;
+ if (pieceNum < this.pieces_.length) {
+ pieceNum++;
+ }
+ return new fb.core.util.Path(this.pieces_, pieceNum);
+}, getBack:function() {
+ if (this.pieceNum_ < this.pieces_.length) {
+ return this.pieces_[this.pieces_.length - 1];
+ }
+ return null;
+}, toString:function() {
+ var pathString = "";
+ for (var i = this.pieceNum_;i < this.pieces_.length;i++) {
+ if (this.pieces_[i] !== "") {
+ pathString += "/" + this.pieces_[i];
+ }
+ }
+ return pathString || "/";
+}, toUrlEncodedString:function() {
+ var pathString = "";
+ for (var i = this.pieceNum_;i < this.pieces_.length;i++) {
+ if (this.pieces_[i] !== "") {
+ pathString += "/" + goog.string.urlEncode(this.pieces_[i]);
+ }
+ }
+ return pathString || "/";
+}, slice:function(opt_begin) {
+ var begin = opt_begin || 0;
+ return this.pieces_.slice(this.pieceNum_ + begin);
+}, parent:function() {
+ if (this.pieceNum_ >= this.pieces_.length) {
+ return null;
+ }
+ var pieces = [];
+ for (var i = this.pieceNum_;i < this.pieces_.length - 1;i++) {
+ pieces.push(this.pieces_[i]);
+ }
+ return new fb.core.util.Path(pieces, 0);
+}, child:function(childPathObj) {
+ var pieces = [];
+ for (var i = this.pieceNum_;i < this.pieces_.length;i++) {
+ pieces.push(this.pieces_[i]);
+ }
+ if (childPathObj instanceof fb.core.util.Path) {
+ for (i = childPathObj.pieceNum_;i < childPathObj.pieces_.length;i++) {
+ pieces.push(childPathObj.pieces_[i]);
+ }
+ } else {
+ var childPieces = childPathObj.split("/");
+ for (i = 0;i < childPieces.length;i++) {
+ if (childPieces[i].length > 0) {
+ pieces.push(childPieces[i]);
+ }
+ }
+ }
+ return new fb.core.util.Path(pieces, 0);
+}, isEmpty:function() {
+ return this.pieceNum_ >= this.pieces_.length;
+}, statics:{relativePath:function(outerPath, innerPath) {
+ var outer = outerPath.getFront(), inner = innerPath.getFront();
+ if (outer === null) {
+ return innerPath;
+ } else {
+ if (outer === inner) {
+ return fb.core.util.Path.relativePath(outerPath.popFront(), innerPath.popFront());
+ } else {
+ throw new Error("INTERNAL ERROR: innerPath (" + innerPath + ") is not within " + "outerPath (" + outerPath + ")");
+ }
+ }
+}}, equals:function(other) {
+ if (this.getLength() !== other.getLength()) {
+ return false;
+ }
+ for (var i = this.pieceNum_, j = other.pieceNum_;i <= this.pieces_.length;i++, j++) {
+ if (this.pieces_[i] !== other.pieces_[j]) {
+ return false;
+ }
+ }
+ return true;
+}, contains:function(other) {
+ var i = this.pieceNum_;
+ var j = other.pieceNum_;
+ if (this.getLength() > other.getLength()) {
+ return false;
+ }
+ while (i < this.pieces_.length) {
+ if (this.pieces_[i] !== other.pieces_[j]) {
+ return false;
+ }
+ ++i;
+ ++j;
+ }
+ return true;
+}});
+fb.core.util.Path.Empty = new fb.core.util.Path("");
+fb.core.util.ValidationPath = goog.defineClass(null, {constructor:function(path, errorPrefix) {
+ this.parts_ = path.slice();
+ this.byteLength_ = Math.max(1, this.parts_.length);
+ this.errorPrefix_ = errorPrefix;
+ for (var i = 0;i < this.parts_.length;i++) {
+ this.byteLength_ += fb.util.utf8.stringLength(this.parts_[i]);
+ }
+ this.checkValid_();
+}, statics:{MAX_PATH_DEPTH:32, MAX_PATH_LENGTH_BYTES:768}, push:function(child) {
+ if (this.parts_.length > 0) {
+ this.byteLength_ += 1;
+ }
+ this.parts_.push(child);
+ this.byteLength_ += fb.util.utf8.stringLength(child);
+ this.checkValid_();
+}, pop:function() {
+ var last = this.parts_.pop();
+ this.byteLength_ -= fb.util.utf8.stringLength(last);
+ if (this.parts_.length > 0) {
+ this.byteLength_ -= 1;
+ }
+}, checkValid_:function() {
+ if (this.byteLength_ > fb.core.util.ValidationPath.MAX_PATH_LENGTH_BYTES) {
+ throw new Error(this.errorPrefix_ + "has a key path longer than " + fb.core.util.ValidationPath.MAX_PATH_LENGTH_BYTES + " bytes (" + this.byteLength_ + ").");
+ }
+ if (this.parts_.length > fb.core.util.ValidationPath.MAX_PATH_DEPTH) {
+ throw new Error(this.errorPrefix_ + "path specified exceeds the maximum depth that can be written (" + fb.core.util.ValidationPath.MAX_PATH_DEPTH + ") or object contains a cycle " + this.toErrorString());
+ }
+}, toErrorString:function() {
+ if (this.parts_.length == 0) {
+ return "";
+ }
+ return "in property '" + this.parts_.join(".") + "'";
+}});
+goog.provide("fb.core.storage.MemoryStorage");
+goog.require("fb.util.obj");
+goog.scope(function() {
+ var obj = fb.util.obj;
+ fb.core.storage.MemoryStorage = function() {
+ this.cache_ = {};
+ };
+ var MemoryStorage = fb.core.storage.MemoryStorage;
+ MemoryStorage.prototype.set = function(key, value) {
+ if (value == null) {
+ delete this.cache_[key];
+ } else {
+ this.cache_[key] = value;
+ }
+ };
+ MemoryStorage.prototype.get = function(key) {
+ if (obj.contains(this.cache_, key)) {
+ return this.cache_[key];
+ }
+ return null;
+ };
+ MemoryStorage.prototype.remove = function(key) {
+ delete this.cache_[key];
+ };
+ MemoryStorage.prototype.isInMemoryStorage = true;
+});
+goog.provide("fb.core.storage.DOMStorageWrapper");
+goog.require("fb.util.obj");
+goog.scope(function() {
+ fb.core.storage.DOMStorageWrapper = function(domStorage) {
+ this.domStorage_ = domStorage;
+ this.prefix_ = "firebase:";
+ };
+ var DOMStorageWrapper = fb.core.storage.DOMStorageWrapper;
+ DOMStorageWrapper.prototype.set = function(key, value) {
+ if (value == null) {
+ this.domStorage_.removeItem(this.prefixedName_(key));
+ } else {
+ this.domStorage_.setItem(this.prefixedName_(key), fb.util.json.stringify(value));
+ }
+ };
+ DOMStorageWrapper.prototype.get = function(key) {
+ var storedVal = this.domStorage_.getItem(this.prefixedName_(key));
+ if (storedVal == null) {
+ return null;
+ } else {
+ return fb.util.json.eval(storedVal);
+ }
+ };
+ DOMStorageWrapper.prototype.remove = function(key) {
+ this.domStorage_.removeItem(this.prefixedName_(key));
+ };
+ DOMStorageWrapper.prototype.isInMemoryStorage = false;
+ DOMStorageWrapper.prototype.prefixedName_ = function(name) {
+ return this.prefix_ + name;
+ };
+ DOMStorageWrapper.prototype.toString = function() {
+ return this.domStorage_.toString();
+ };
+});
+goog.provide("fb.core.storage");
+goog.require("fb.core.storage.DOMStorageWrapper");
+goog.require("fb.core.storage.MemoryStorage");
+fb.core.storage.createStoragefor = function(domStorageName) {
+ try {
+ if (typeof window !== "undefined" && typeof window[domStorageName] !== "undefined") {
+ var domStorage = window[domStorageName];
+ domStorage.setItem("firebase:sentinel", "cache");
+ domStorage.removeItem("firebase:sentinel");
+ return new fb.core.storage.DOMStorageWrapper(domStorage);
+ }
+ } catch (e) {
+ }
+ return new fb.core.storage.MemoryStorage;
+};
+fb.core.storage.PersistentStorage = fb.core.storage.createStoragefor("localStorage");
+fb.core.storage.SessionStorage = fb.core.storage.createStoragefor("sessionStorage");
+goog.provide("fb.core.RepoInfo");
+goog.require("fb.core.storage");
+fb.core.RepoInfo = function(host, secure, namespace, webSocketOnly, persistenceKey) {
+ this.host = host.toLowerCase();
+ this.domain = this.host.substr(this.host.indexOf(".") + 1);
+ this.secure = secure;
+ this.namespace = namespace;
+ this.webSocketOnly = webSocketOnly;
+ this.persistenceKey = persistenceKey || "";
+ this.internalHost = fb.core.storage.PersistentStorage.get("host:" + host) || this.host;
+};
+fb.core.RepoInfo.prototype.needsQueryParam = function() {
+ return this.host !== this.internalHost;
+};
+fb.core.RepoInfo.prototype.isCacheableHost = function() {
+ return this.internalHost.substr(0, 2) === "s-";
+};
+fb.core.RepoInfo.prototype.isDemoHost = function() {
+ return this.domain === "firebaseio-demo.com";
+};
+fb.core.RepoInfo.prototype.isCustomHost = function() {
+ return this.domain !== "firebaseio.com" && this.domain !== "firebaseio-demo.com";
+};
+fb.core.RepoInfo.prototype.updateHost = function(newHost) {
+ if (newHost !== this.internalHost) {
+ this.internalHost = newHost;
+ if (this.isCacheableHost()) {
+ fb.core.storage.PersistentStorage.set("host:" + this.host, this.internalHost);
+ }
+ }
+};
+fb.core.RepoInfo.prototype.toString = function() {
+ var str = (this.secure ? "https://" : "http://") + this.host;
+ if (this.persistenceKey) {
+ str += "<" + this.persistenceKey + ">";
+ }
+ return str;
+};
+goog.provide("fb.core.util");
+goog.require("fb.constants");
+goog.require("fb.core.RepoInfo");
+goog.require("fb.core.storage");
+goog.require("fb.util.json");
+goog.require("goog.crypt.Sha1");
+goog.require("goog.crypt.base64");
+goog.require("goog.object");
+goog.require("goog.string");
+fb.core.util.LUIDGenerator = function() {
+ var id = 1;
+ return function() {
+ return id++;
+ };
+}();
+fb.core.util.assert = function(assertion, message) {
+ if (!assertion) {
+ throw fb.core.util.assertionError(message);
+ }
+};
+fb.core.util.assertionError = function(message) {
+ return new Error("Firebase (" + Firebase.SDK_VERSION + ") INTERNAL ASSERT FAILED: " + message);
+};
+fb.core.util.assertWeak = function(assertion, message) {
+ if (!assertion) {
+ fb.core.util.error(message);
+ }
+};
+fb.core.util.base64Encode = function(str) {
+ var utf8Bytes = fb.util.utf8.stringToByteArray(str);
+ return goog.crypt.base64.encodeByteArray(utf8Bytes, true);
+};
+fb.core.util.base64Decode = function(str) {
+ try {
+ if (NODE_CLIENT) {
+ return(new Buffer(str, "base64")).toString("utf8");
+ } else {
+ if (typeof atob !== "undefined") {
+ return atob(str);
+ } else {
+ return goog.crypt.base64.decodeString(str, true);
+ }
+ }
+ } catch (e) {
+ fb.core.util.log("base64Decode failed: ", e);
+ }
+ return null;
+};
+fb.core.util.sha1 = function(str) {
+ var utf8Bytes = fb.util.utf8.stringToByteArray(str);
+ var sha1 = new goog.crypt.Sha1;
+ sha1.update(utf8Bytes);
+ var sha1Bytes = sha1.digest();
+ return goog.crypt.base64.encodeByteArray(sha1Bytes);
+};
+fb.core.util.buildLogMessage_ = function(var_args) {
+ var message = "";
+ for (var i = 0;i < arguments.length;i++) {
+ if (goog.isArrayLike(arguments[i])) {
+ message += fb.core.util.buildLogMessage_.apply(null, arguments[i]);
+ } else {
+ if (typeof arguments[i] === "object") {
+ message += fb.util.json.stringify(arguments[i]);
+ } else {
+ message += arguments[i];
+ }
+ }
+ message += " ";
+ }
+ return message;
+};
+fb.core.util.logger = null;
+fb.core.util.firstLog_ = true;
+fb.core.util.log = function(var_args) {
+ if (fb.core.util.firstLog_ === true) {
+ fb.core.util.firstLog_ = false;
+ if (fb.core.util.logger === null && fb.core.storage.SessionStorage.get("logging_enabled") === true) {
+ Firebase.enableLogging(true);
+ }
+ }
+ if (fb.core.util.logger) {
+ var message = fb.core.util.buildLogMessage_.apply(null, arguments);
+ fb.core.util.logger(message);
+ }
+};
+fb.core.util.logWrapper = function(prefix) {
+ return function() {
+ fb.core.util.log(prefix, arguments);
+ };
+};
+fb.core.util.error = function(var_args) {
+ if (typeof console !== "undefined") {
+ var message = "FIREBASE INTERNAL ERROR: " + fb.core.util.buildLogMessage_.apply(null, arguments);
+ if (typeof console.error !== "undefined") {
+ console.error(message);
+ } else {
+ console.log(message);
+ }
+ }
+};
+fb.core.util.fatal = function(var_args) {
+ var message = fb.core.util.buildLogMessage_.apply(null, arguments);
+ throw new Error("FIREBASE FATAL ERROR: " + message);
+};
+fb.core.util.warn = function(var_args) {
+ if (typeof console !== "undefined") {
+ var message = "FIREBASE WARNING: " + fb.core.util.buildLogMessage_.apply(null, arguments);
+ if (typeof console.warn !== "undefined") {
+ console.warn(message);
+ } else {
+ console.log(message);
+ }
+ }
+};
+fb.core.util.warnIfPageIsSecure = function() {
+ if (typeof window !== "undefined" && window.location && window.location.protocol && window.location.protocol.indexOf("https:") !== -1) {
+ fb.core.util.warn("Insecure Firebase access from a secure page. " + "Please use https in calls to new Firebase().");
+ }
+};
+fb.core.util.warnAboutUnsupportedMethod = function(methodName) {
+ fb.core.util.warn(methodName + " is unsupported and will likely change soon. " + "Please do not use.");
+};
+fb.core.util.parseRepoInfo = function(dataURL) {
+ var parsedUrl = fb.core.util.parseURL(dataURL), namespace = parsedUrl.subdomain;
+ if (parsedUrl.domain === "firebase") {
+ fb.core.util.fatal(parsedUrl.host + " is no longer supported. " + "Please use <YOUR FIREBASE>.firebaseio.com instead");
+ }
+ if (!namespace || namespace == "undefined") {
+ fb.core.util.fatal("Cannot parse Firebase url. " + "Please use https://<YOUR FIREBASE>.firebaseio.com");
+ }
+ if (!parsedUrl.secure) {
+ fb.core.util.warnIfPageIsSecure();
+ }
+ var webSocketOnly = parsedUrl.scheme === "ws" || parsedUrl.scheme === "wss";
+ return{repoInfo:new fb.core.RepoInfo(parsedUrl.host, parsedUrl.secure, namespace, webSocketOnly), path:new fb.core.util.Path(parsedUrl.pathString)};
+};
+fb.core.util.parseURL = function(dataURL) {
+ var host = "", domain = "", subdomain = "", pathString = "";
+ var secure = true, scheme = "https", port = 443;
+ if (goog.isString(dataURL)) {
+ var colonInd = dataURL.indexOf("//");
+ if (colonInd >= 0) {
+ scheme = dataURL.substring(0, colonInd - 1);
+ dataURL = dataURL.substring(colonInd + 2);
+ }
+ var slashInd = dataURL.indexOf("/");
+ if (slashInd === -1) {
+ slashInd = dataURL.length;
+ }
+ host = dataURL.substring(0, slashInd);
+ pathString = fb.core.util.decodePath(dataURL.substring(slashInd));
+ var parts = host.split(".");
+ if (parts.length === 3) {
+ domain = parts[1];
+ subdomain = parts[0].toLowerCase();
+ } else {
+ if (parts.length === 2) {
+ domain = parts[0];
+ }
+ }
+ colonInd = host.indexOf(":");
+ if (colonInd >= 0) {
+ secure = scheme === "https" || scheme === "wss";
+ port = goog.string.parseInt(host.substring(colonInd + 1));
+ }
+ }
+ return{host:host, port:port, domain:domain, subdomain:subdomain, secure:secure, scheme:scheme, pathString:pathString};
+};
+fb.core.util.decodePath = function(pathString) {
+ var pathStringDecoded = "";
+ var pieces = pathString.split("/");
+ for (var i = 0;i < pieces.length;i++) {
+ if (pieces[i].length > 0) {
+ var piece = pieces[i];
+ try {
+ piece = goog.string.urlDecode(piece);
+ } catch (e) {
+ }
+ pathStringDecoded += "/" + piece;
+ }
+ }
+ return pathStringDecoded;
+};
+fb.core.util.isInvalidJSONNumber = function(data) {
+ return goog.isNumber(data) && (data != data || data == Number.POSITIVE_INFINITY || data == Number.NEGATIVE_INFINITY);
+};
+fb.core.util.executeWhenDOMReady = function(fn) {
+ if (NODE_CLIENT || document.readyState === "complete") {
+ fn();
+ } else {
+ var called = false;
+ var wrappedFn = function() {
+ if (!document.body) {
+ setTimeout(wrappedFn, Math.floor(10));
+ return;
+ }
+ if (!called) {
+ called = true;
+ fn();
+ }
+ };
+ if (document.addEventListener) {
+ document.addEventListener("DOMContentLoaded", wrappedFn, false);
+ window.addEventListener("load", wrappedFn, false);
+ } else {
+ if (document.attachEvent) {
+ document.attachEvent("onreadystatechange", function() {
+ if (document.readyState === "complete") {
+ wrappedFn();
+ }
+ });
+ window.attachEvent("onload", wrappedFn);
+ }
+ }
+ }
+};
+fb.core.util.MIN_NAME = "[MIN_NAME]";
+fb.core.util.MAX_NAME = "[MAX_NAME]";
+fb.core.util.nameCompare = function(a, b) {
+ if (a === b) {
+ return 0;
+ } else {
+ if (a === fb.core.util.MIN_NAME || b === fb.core.util.MAX_NAME) {
+ return-1;
+ } else {
+ if (b === fb.core.util.MIN_NAME || a === fb.core.util.MAX_NAME) {
+ return 1;
+ } else {
+ var aAsInt = fb.core.util.tryParseInt(a), bAsInt = fb.core.util.tryParseInt(b);
+ if (aAsInt !== null) {
+ if (bAsInt !== null) {
+ return aAsInt - bAsInt == 0 ? a.length - b.length : aAsInt - bAsInt;
+ } else {
+ return-1;
+ }
+ } else {
+ if (bAsInt !== null) {
+ return 1;
+ } else {
+ return a < b ? -1 : 1;
+ }
+ }
+ }
+ }
+ }
+};
+fb.core.util.stringCompare = function(a, b) {
+ if (a === b) {
+ return 0;
+ } else {
+ if (a < b) {
+ return-1;
+ } else {
+ return 1;
+ }
+ }
+};
+fb.core.util.requireKey = function(key, obj) {
+ if (obj && key in obj) {
+ return obj[key];
+ } else {
+ throw new Error("Missing required key (" + key + ") in object: " + fb.util.json.stringify(obj));
+ }
+};
+fb.core.util.ObjectToUniqueKey = function(obj) {
+ if (typeof obj !== "object" || obj === null) {
+ return fb.util.json.stringify(obj);
+ }
+ var keys = [];
+ for (var k in obj) {
+ keys.push(k);
+ }
+ keys.sort();
+ var key = "{";
+ for (var i = 0;i < keys.length;i++) {
+ if (i !== 0) {
+ key += ",";
+ }
+ key += fb.util.json.stringify(keys[i]);
+ key += ":";
+ key += fb.core.util.ObjectToUniqueKey(obj[keys[i]]);
+ }
+ key += "}";
+ return key;
+};
+fb.core.util.splitStringBySize = function(str, segsize) {
+ if (str.length <= segsize) {
+ return[str];
+ }
+ var dataSegs = [];
+ for (var c = 0;c < str.length;c += segsize) {
+ if (c + segsize > str) {
+ dataSegs.push(str.substring(c, str.length));
+ } else {
+ dataSegs.push(str.substring(c, c + segsize));
+ }
+ }
+ return dataSegs;
+};
+fb.core.util.each = function(obj, fn) {
+ if (goog.isArray(obj)) {
+ for (var i = 0;i < obj.length;++i) {
+ fn(i, obj[i]);
+ }
+ } else {
+ goog.object.forEach(obj, fn);
+ }
+};
+fb.core.util.bindCallback = function(callback, opt_context) {
+ return opt_context ? goog.bind(callback, opt_context) : callback;
+};
+fb.core.util.doubleToIEEE754String = function(v) {
+ fb.core.util.assert(!fb.core.util.isInvalidJSONNumber(v), "Invalid JSON number");
+ var ebits = 11, fbits = 52;
+ var bias = (1 << ebits - 1) - 1, s, e, f, ln, i, bits, str, bytes;
+ if (v === 0) {
+ e = 0;
+ f = 0;
+ s = 1 / v === -Infinity ? 1 : 0;
+ } else {
+ s = v < 0;
+ v = Math.abs(v);
+ if (v >= Math.pow(2, 1 - bias)) {
+ ln = Math.min(Math.floor(Math.log(v) / Math.LN2), bias);
+ e = ln + bias;
+ f = Math.round(v * Math.pow(2, fbits - ln) - Math.pow(2, fbits));
+ } else {
+ e = 0;
+ f = Math.round(v / Math.pow(2, 1 - bias - fbits));
+ }
+ }
+ bits = [];
+ for (i = fbits;i;i -= 1) {
+ bits.push(f % 2 ? 1 : 0);
+ f = Math.floor(f / 2);
+ }
+ for (i = ebits;i;i -= 1) {
+ bits.push(e % 2 ? 1 : 0);
+ e = Math.floor(e / 2);
+ }
+ bits.push(s ? 1 : 0);
+ bits.reverse();
+ str = bits.join("");
+ var hexByteString = "";
+ for (i = 0;i < 64;i += 8) {
+ var hexByte = parseInt(str.substr(i, 8), 2).toString(16);
+ if (hexByte.length === 1) {
+ hexByte = "0" + hexByte;
+ }
+ hexByteString = hexByteString + hexByte;
+ }
+ return hexByteString.toLowerCase();
+};
+fb.core.util.isChromeExtensionContentScript = function() {
+ return!!(typeof window === "object" && window["chrome"] && window["chrome"]["extension"] && !/^chrome/.test(window.location.href));
+};
+fb.core.util.isWindowsStoreApp = function() {
+ return typeof Windows === "object" && typeof Windows.UI === "object";
+};
+fb.core.util.errorForServerCode = function(code) {
+ var reason = "Unknown Error";
+ if (code === "too_big") {
+ reason = "The data requested exceeds the maximum size " + "that can be accessed with a single request.";
+ } else {
+ if (code == "permission_denied") {
+ reason = "Client doesn't have permission to access the desired data.";
+ } else {
+ if (code == "unavailable") {
+ reason = "The service is unavailable";
+ }
+ }
+ }
+ var error = new Error(code + ": " + reason);
+ error.code = code.toUpperCase();
+ return error;
+};
+fb.core.util.INTEGER_REGEXP_ = new RegExp("^-?\\d{1,10}$");
+fb.core.util.tryParseInt = function(str) {
+ if (fb.core.util.INTEGER_REGEXP_.test(str)) {
+ var intVal = Number(str);
+ if (intVal >= -2147483648 && intVal <= 2147483647) {
+ return intVal;
+ }
+ }
+ return null;
+};
+fb.core.util.exceptionGuard = function(fn) {
+ try {
+ fn();
+ } catch (e) {
+ setTimeout(function() {
+ var stack = e.stack || "";
+ fb.core.util.warn("Exception was thrown by user callback.", stack);
+ throw e;
+ }, Math.floor(0));
+ }
+};
+fb.core.util.callUserCallback = function(opt_callback, var_args) {
+ if (goog.isFunction(opt_callback)) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ var newArgs = args.slice();
+ fb.core.util.exceptionGuard(function() {
+ opt_callback.apply(null, newArgs);
+ });
+ }
+};
+fb.core.util.beingCrawled = function() {
+ var userAgent = typeof window === "object" && window["navigator"] && window["navigator"]["userAgent"] || "";
+ return userAgent.search(/googlebot|google webmaster tools|bingbot|yahoo! slurp|baiduspider|yandexbot|duckduckbot/i) >= 0;
+};
+goog.provide("fb.util.utf8");
+goog.require("fb.core.util");
+fb.util.utf8.stringToByteArray = function(str) {
+ var out = [], p = 0;
+ for (var i = 0;i < str.length;i++) {
+ var c = str.charCodeAt(i);
+ if (c >= 55296 && c <= 56319) {
+ var high = c - 55296;
+ i++;
+ fb.core.util.assert(i < str.length, "Surrogate pair missing trail surrogate.");
+ var low = str.charCodeAt(i) - 56320;
+ c = 65536 + (high << 10) + low;
+ }
+ if (c < 128) {
+ out[p++] = c;
+ } else {
+ if (c < 2048) {
+ out[p++] = c >> 6 | 192;
+ out[p++] = c & 63 | 128;
+ } else {
+ if (c < 65536) {
+ out[p++] = c >> 12 | 224;
+ out[p++] = c >> 6 & 63 | 128;
+ out[p++] = c & 63 | 128;
+ } else {
+ out[p++] = c >> 18 | 240;
+ out[p++] = c >> 12 & 63 | 128;
+ out[p++] = c >> 6 & 63 | 128;
+ out[p++] = c & 63 | 128;
+ }
+ }
+ }
+ }
+ return out;
+};
+fb.util.utf8.stringLength = function(str) {
+ var p = 0;
+ for (var i = 0;i < str.length;i++) {
+ var c = str.charCodeAt(i);
+ if (c < 128) {
+ p++;
+ } else {
+ if (c < 2048) {
+ p += 2;
+ } else {
+ if (c >= 55296 && c <= 56319) {
+ p += 4;
+ i++;
+ } else {
+ p += 3;
+ }
+ }
+ }
+ }
+ return p;
+};
+goog.provide("fb.util.jwt");
+goog.require("fb.core.util");
+goog.require("fb.util.json");
+goog.require("fb.util.obj");
+goog.require("goog.crypt.base64");
+goog.require("goog.json");
+fb.util.jwt.decode = function(token) {
+ var header = {}, claims = {}, data = {}, signature = "";
+ try {
+ var parts = token.split(".");
+ header = fb.util.json.eval(fb.core.util.base64Decode(parts[0]) || "");
+ claims = fb.util.json.eval(fb.core.util.base64Decode(parts[1]) || "");
+ signature = parts[2];
+ data = claims["d"] || {};
+ delete claims["d"];
+ } catch (e) {
+ }
+ return{header:header, claims:claims, data:data, signature:signature};
+};
+fb.util.jwt.isValidTimestamp = function(token) {
+ var claims = fb.util.jwt.decode(token).claims, now = Math.floor((new Date).getTime() / 1E3), validSince, validUntil;
+ if (typeof claims === "object") {
+ if (claims.hasOwnProperty("nbf")) {
+ validSince = fb.util.obj.get(claims, "nbf");
+ } else {
+ if (claims.hasOwnProperty("iat")) {
+ validSince = fb.util.obj.get(claims, "iat");
+ }
+ }
+ if (claims.hasOwnProperty("exp")) {
+ validUntil = fb.util.obj.get(claims, "exp");
+ } else {
+ validUntil = validSince + 86400;
+ }
+ }
+ return now && validSince && validUntil && now >= validSince && now <= validUntil;
+};
+fb.util.jwt.issuedAtTime = function(token) {
+ var claims = fb.util.jwt.decode(token).claims;
+ if (typeof claims === "object" && claims.hasOwnProperty("iat")) {
+ return fb.util.obj.get(claims, "iat");
+ }
+ return null;
+};
+fb.util.jwt.isValidFormat = function(token) {
+ var decoded = fb.util.jwt.decode(token), claims = decoded.claims;
+ return!!decoded.signature && !!claims && typeof claims === "object" && claims.hasOwnProperty("iat");
+};
+fb.util.jwt.isAdmin = function(token) {
+ var claims = fb.util.jwt.decode(token).claims;
+ return typeof claims === "object" && fb.util.obj.get(claims, "admin") === true;
+};
+goog.provide("fb.core.view.EventGenerator");
+goog.require("fb.core.snap.NamedNode");
+goog.require("fb.core.util");
+fb.core.view.EventGenerator = function(query) {
+ this.query_ = query;
+ this.index_ = query.getQueryParams().getIndex();
+};
+fb.core.view.EventGenerator.prototype.generateEventsForChanges = function(changes, eventCache, eventRegistrations) {
+ var events = [], self = this;
+ var moves = [];
+ goog.array.forEach(changes, function(change) {
+ if (change.type === fb.core.view.Change.CHILD_CHANGED && self.index_.indexedValueChanged((change.oldSnap), change.snapshotNode)) {
+ moves.push(fb.core.view.Change.childMovedChange((change.childName), change.snapshotNode));
+ }
+ });
+ this.generateEventsForType_(events, fb.core.view.Change.CHILD_REMOVED, changes, eventRegistrations, eventCache);
+ this.generateEventsForType_(events, fb.core.view.Change.CHILD_ADDED, changes, eventRegistrations, eventCache);
+ this.generateEventsForType_(events, fb.core.view.Change.CHILD_MOVED, moves, eventRegistrations, eventCache);
+ this.generateEventsForType_(events, fb.core.view.Change.CHILD_CHANGED, changes, eventRegistrations, eventCache);
+ this.generateEventsForType_(events, fb.core.view.Change.VALUE, changes, eventRegistrations, eventCache);
+ return events;
+};
+fb.core.view.EventGenerator.prototype.generateEventsForType_ = function(events, eventType, changes, registrations, eventCache) {
+ var filteredChanges = goog.array.filter(changes, function(change) {
+ return change.type === eventType;
+ });
+ var self = this;
+ goog.array.sort(filteredChanges, goog.bind(this.compareChanges_, this));
+ goog.array.forEach(filteredChanges, function(change) {
+ var materializedChange = self.materializeSingleChange_(change, eventCache);
+ goog.array.forEach(registrations, function(registration) {
+ if (registration.respondsTo(change.type)) {
+ events.push(registration.createEvent(materializedChange, self.query_));
+ }
+ });
+ });
+};
+fb.core.view.EventGenerator.prototype.materializeSingleChange_ = function(change, eventCache) {
+ if (change.type === "value" || change.type === "child_removed") {
+ return change;
+ } else {
+ change.prevName = eventCache.getPredecessorChildName((change.childName), change.snapshotNode, this.index_);
+ return change;
+ }
+};
+fb.core.view.EventGenerator.prototype.compareChanges_ = function(a, b) {
+ if (a.childName == null || b.childName == null) {
+ throw fb.core.util.assertionError("Should only compare child_ events.");
+ }
+ var aWrapped = new fb.core.snap.NamedNode(a.childName, a.snapshotNode);
+ var bWrapped = new fb.core.snap.NamedNode(b.childName, b.snapshotNode);
+ return this.index_.compare(aWrapped, bWrapped);
+};
+goog.provide("fb.core.view.ChildChangeAccumulator");
+goog.require("fb.core.util");
+fb.core.view.ChildChangeAccumulator = function() {
+ this.changeMap_ = {};
+};
+fb.core.view.ChildChangeAccumulator.prototype.trackChildChange = function(change) {
+ var Change = fb.core.view.Change;
+ var type = change.type;
+ var childKey = (change.childName);
+ fb.core.util.assert(type == fb.core.view.Change.CHILD_ADDED || type == fb.core.view.Change.CHILD_CHANGED || type == fb.core.view.Change.CHILD_REMOVED, "Only child changes supported for tracking");
+ fb.core.util.assert(childKey !== ".priority", "Only non-priority child changes can be tracked.");
+ var oldChange = fb.util.obj.get(this.changeMap_, childKey);
+ if (oldChange) {
+ var oldType = oldChange.type;
+ if (type == Change.CHILD_ADDED && oldType == Change.CHILD_REMOVED) {
+ this.changeMap_[childKey] = Change.childChangedChange(childKey, change.snapshotNode, oldChange.snapshotNode);
+ } else {
+ if (type == Change.CHILD_REMOVED && oldType == Change.CHILD_ADDED) {
+ delete this.changeMap_[childKey];
+ } else {
+ if (type == Change.CHILD_REMOVED && oldType == Change.CHILD_CHANGED) {
+ this.changeMap_[childKey] = Change.childRemovedChange(childKey, (oldChange.oldSnap));
+ } else {
+ if (type == Change.CHILD_CHANGED && oldType == Change.CHILD_ADDED) {
+ this.changeMap_[childKey] = Change.childAddedChange(childKey, change.snapshotNode);
+ } else {
+ if (type == Change.CHILD_CHANGED && oldType == Change.CHILD_CHANGED) {
+ this.changeMap_[childKey] = Change.childChangedChange(childKey, change.snapshotNode, (oldChange.oldSnap));
+ } else {
+ throw fb.core.util.assertionError("Illegal combination of changes: " + change + " occurred after " + oldChange);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ this.changeMap_[childKey] = change;
+ }
+};
+fb.core.view.ChildChangeAccumulator.prototype.getChanges = function() {
+ return goog.object.getValues(this.changeMap_);
+};
+goog.provide("fb.core.view.EventRegistration");
+goog.require("fb.core.view.Change");
+goog.require("fb.core.view.Event");
+goog.require("fb.core.util");
+fb.core.view.EventRegistration = function() {
+};
+fb.core.view.EventRegistration.prototype.respondsTo;
+fb.core.view.EventRegistration.prototype.createEvent;
+fb.core.view.EventRegistration.prototype.getEventRunner;
+fb.core.view.EventRegistration.prototype.createCancelEvent;
+fb.core.view.EventRegistration.prototype.matches;
+fb.core.view.EventRegistration.prototype.hasAnyCallback;
+fb.core.view.ValueEventRegistration = function(callback, cancelCallback, context) {
+ this.callback_ = callback;
+ this.cancelCallback_ = cancelCallback;
+ this.context_ = context || null;
+};
+fb.core.view.ValueEventRegistration.prototype.respondsTo = function(eventType) {
+ return eventType === "value";
+};
+fb.core.view.ValueEventRegistration.prototype.createEvent = function(change, query) {
+ var index = query.getQueryParams().getIndex();
+ return new fb.core.view.DataEvent("value", this, new fb.api.DataSnapshot(change.snapshotNode, query.ref(), index));
+};
+fb.core.view.ValueEventRegistration.prototype.getEventRunner = function(eventData) {
+ var ctx = this.context_;
+ if (eventData.getEventType() === "cancel") {
+ fb.core.util.assert(this.cancelCallback_, "Raising a cancel event on a listener with no cancel callback");
+ var cancelCB = this.cancelCallback_;
+ return function() {
+ cancelCB.call(ctx, eventData.error);
+ };
+ } else {
+ var cb = this.callback_;
+ return function() {
+ cb.call(ctx, eventData.snapshot);
+ };
+ }
+};
+fb.core.view.ValueEventRegistration.prototype.createCancelEvent = function(error, path) {
+ if (this.cancelCallback_) {
+ return new fb.core.view.CancelEvent(this, error, path);
+ } else {
+ return null;
+ }
+};
+fb.core.view.ValueEventRegistration.prototype.matches = function(other) {
+ if (!(other instanceof fb.core.view.ValueEventRegistration)) {
+ return false;
+ } else {
+ if (!other.callback_ || !this.callback_) {
+ return true;
+ } else {
+ return other.callback_ === this.callback_ && other.context_ === this.context_;
+ }
+ }
+};
+fb.core.view.ValueEventRegistration.prototype.hasAnyCallback = function() {
+ return this.callback_ !== null;
+};
+fb.core.view.ChildEventRegistration = function(callbacks, cancelCallback, context) {
+ this.callbacks_ = callbacks;
+ this.cancelCallback_ = cancelCallback;
+ this.context_ = context;
+};
+fb.core.view.ChildEventRegistration.prototype.respondsTo = function(eventType) {
+ var eventToCheck = eventType === "children_added" ? "child_added" : eventType;
+ eventToCheck = eventToCheck === "children_removed" ? "child_removed" : eventToCheck;
+ return goog.object.containsKey(this.callbacks_, eventToCheck);
+};
+fb.core.view.ChildEventRegistration.prototype.createCancelEvent = function(error, path) {
+ if (this.cancelCallback_) {
+ return new fb.core.view.CancelEvent(this, error, path);
+ } else {
+ return null;
+ }
+};
+fb.core.view.ChildEventRegistration.prototype.createEvent = function(change, query) {
+ fb.core.util.assert(change.childName != null, "Child events should have a childName.");
+ var ref = query.ref().child((change.childName));
+ var index = query.getQueryParams().getIndex();
+ return new fb.core.view.DataEvent(change.type, this, new fb.api.DataSnapshot(change.snapshotNode, ref, index), change.prevName);
+};
+fb.core.view.ChildEventRegistration.prototype.getEventRunner = function(eventData) {
+ var ctx = this.context_;
+ if (eventData.getEventType() === "cancel") {
+ fb.core.util.assert(this.cancelCallback_, "Raising a cancel event on a listener with no cancel callback");
+ var cancelCB = this.cancelCallback_;
+ return function() {
+ cancelCB.call(ctx, eventData.error);
+ };
+ } else {
+ var cb = this.callbacks_[eventData.eventType];
+ return function() {
+ cb.call(ctx, eventData.snapshot, eventData.prevName);
+ };
+ }
+};
+fb.core.view.ChildEventRegistration.prototype.matches = function(other) {
+ if (other instanceof fb.core.view.ChildEventRegistration) {
+ if (!this.callbacks_ || !other.callbacks_) {
+ return true;
+ } else {
+ if (this.context_ === other.context_) {
+ var otherCount = goog.object.getCount(other.callbacks_);
+ var thisCount = goog.object.getCount(this.callbacks_);
+ if (otherCount === thisCount) {
+ if (otherCount === 1) {
+ var otherKey = (goog.object.getAnyKey(other.callbacks_));
+ var thisKey = (goog.object.getAnyKey(this.callbacks_));
+ return thisKey === otherKey && (!other.callbacks_[otherKey] || !this.callbacks_[thisKey] || other.callbacks_[otherKey] === this.callbacks_[thisKey]);
+ } else {
+ return goog.object.every(this.callbacks_, function(cb, eventType) {
+ return other.callbacks_[eventType] === cb;
+ });
+ }
+ }
+ }
+ }
+ }
+ return false;
+};
+fb.core.view.ChildEventRegistration.prototype.hasAnyCallback = function() {
+ return this.callbacks_ !== null;
+};
+goog.provide("fb.core.view.filter.IndexedFilter");
+goog.require("fb.core.util");
+fb.core.view.filter.IndexedFilter = function(index) {
+ this.index_ = index;
+};
+fb.core.view.filter.IndexedFilter.prototype.updateChild = function(snap, key, newChild, source, optChangeAccumulator) {
+ var Change = fb.core.view.Change;
+ fb.core.util.assert(snap.isIndexed(this.index_), "A node must be indexed if only a child is updated");
+ var oldChild = snap.getImmediateChild(key);
+ if (oldChild.equals(newChild)) {
+ return snap;
+ }
+ if (optChangeAccumulator != null) {
+ if (newChild.isEmpty()) {
+ if (snap.hasChild(key)) {
+ optChangeAccumulator.trackChildChange(Change.childRemovedChange(key, oldChild));
+ } else {
+ fb.core.util.assert(snap.isLeafNode(), "A child remove without an old child only makes sense on a leaf node");
+ }
+ } else {
+ if (oldChild.isEmpty()) {
+ optChangeAccumulator.trackChildChange(Change.childAddedChange(key, newChild));
+ } else {
+ optChangeAccumulator.trackChildChange(Change.childChangedChange(key, newChild, oldChild));
+ }
+ }
+ }
+ if (snap.isLeafNode() && newChild.isEmpty()) {
+ return snap;
+ } else {
+ return snap.updateImmediateChild(key, newChild).withIndex(this.index_);
+ }
+};
+fb.core.view.filter.IndexedFilter.prototype.updateFullNode = function(oldSnap, newSnap, optChangeAccumulator) {
+ var Change = fb.core.view.Change;
+ if (optChangeAccumulator != null) {
+ if (!oldSnap.isLeafNode()) {
+ oldSnap.forEachChild(fb.core.snap.PriorityIndex, function(key, childNode) {
+ if (!newSnap.hasChild(key)) {
+ optChangeAccumulator.trackChildChange(Change.childRemovedChange(key, childNode));
+ }
+ });
+ }
+ if (!newSnap.isLeafNode()) {
+ newSnap.forEachChild(fb.core.snap.PriorityIndex, function(key, childNode) {
+ if (oldSnap.hasChild(key)) {
+ var oldChild = oldSnap.getImmediateChild(key);
+ if (!oldChild.equals(childNode)) {
+ optChangeAccumulator.trackChildChange(Change.childChangedChange(key, childNode, oldChild));
+ }
+ } else {
+ optChangeAccumulator.trackChildChange(Change.childAddedChange(key, childNode));
+ }
+ });
+ }
+ }
+ return newSnap.withIndex(this.index_);
+};
+fb.core.view.filter.IndexedFilter.prototype.updatePriority = function(oldSnap, newPriority) {
+ if (oldSnap.isEmpty()) {
+ return fb.core.snap.EMPTY_NODE;
+ } else {
+ return oldSnap.updatePriority(newPriority);
+ }
+};
+fb.core.view.filter.IndexedFilter.prototype.filtersNodes = function() {
+ return false;
+};
+fb.core.view.filter.IndexedFilter.prototype.getIndexedFilter = function() {
+ return this;
+};
+fb.core.view.filter.IndexedFilter.prototype.getIndex = function() {
+ return this.index_;
+};
+goog.provide("fb.core.view.filter.RangedFilter");
+goog.require("fb.core.view.filter.IndexedFilter");
+fb.core.view.filter.RangedFilter = function(params) {
+ this.indexedFilter_ = new fb.core.view.filter.IndexedFilter(params.getIndex());
+ this.index_ = params.getIndex();
+ this.startPost_ = this.getStartPost_(params);
+ this.endPost_ = this.getEndPost_(params);
+};
+fb.core.view.filter.RangedFilter.prototype.getStartPost = function() {
+ return this.startPost_;
+};
+fb.core.view.filter.RangedFilter.prototype.getEndPost = function() {
+ return this.endPost_;
+};
+fb.core.view.filter.RangedFilter.prototype.matches = function(node) {
+ return this.index_.compare(this.getStartPost(), node) <= 0 && this.index_.compare(node, this.getEndPost()) <= 0;
+};
+fb.core.view.filter.RangedFilter.prototype.updateChild = function(snap, key, newChild, source, optChangeAccumulator) {
+ if (!this.matches(new fb.core.snap.NamedNode(key, newChild))) {
+ newChild = fb.core.snap.EMPTY_NODE;
+ }
+ return this.indexedFilter_.updateChild(snap, key, newChild, source, optChangeAccumulator);
+};
+fb.core.view.filter.RangedFilter.prototype.updateFullNode = function(oldSnap, newSnap, optChangeAccumulator) {
+ if (newSnap.isLeafNode()) {
+ newSnap = fb.core.snap.EMPTY_NODE;
+ }
+ var filtered = newSnap.withIndex(this.index_);
+ filtered = filtered.updatePriority(fb.core.snap.EMPTY_NODE);
+ var self = this;
+ newSnap.forEachChild(fb.core.snap.PriorityIndex, function(key, childNode) {
+ if (!self.matches(new fb.core.snap.NamedNode(key, childNode))) {
+ filtered = filtered.updateImmediateChild(key, fb.core.snap.EMPTY_NODE);
+ }
+ });
+ return this.indexedFilter_.updateFullNode(oldSnap, filtered, optChangeAccumulator);
+};
+fb.core.view.filter.RangedFilter.prototype.updatePriority = function(oldSnap, newPriority) {
+ return oldSnap;
+};
+fb.core.view.filter.RangedFilter.prototype.filtersNodes = function() {
+ return true;
+};
+fb.core.view.filter.RangedFilter.prototype.getIndexedFilter = function() {
+ return this.indexedFilter_;
+};
+fb.core.view.filter.RangedFilter.prototype.getIndex = function() {
+ return this.index_;
+};
+fb.core.view.filter.RangedFilter.prototype.getStartPost_ = function(params) {
+ if (params.hasStart()) {
+ var startName = params.getIndexStartName();
+ return params.getIndex().makePost(params.getIndexStartValue(), startName);
+ } else {
+ return params.getIndex().minPost();
+ }
+};
+fb.core.view.filter.RangedFilter.prototype.getEndPost_ = function(params) {
+ if (params.hasEnd()) {
+ var endName = params.getIndexEndName();
+ return params.getIndex().makePost(params.getIndexEndValue(), endName);
+ } else {
+ return params.getIndex().maxPost();
+ }
+};
+goog.provide("fb.core.view.filter.NodeFilter");
+goog.require("fb.core.view.ChildChangeAccumulator");
+goog.require("fb.core.view.CompleteChildSource");
+fb.core.view.filter.NodeFilter = function() {
+};
+fb.core.view.filter.NodeFilter.prototype.updateChild = function(snap, key, newChild, source, optChangeAccumulator) {
+};
+fb.core.view.filter.NodeFilter.prototype.updateFullNode = function(oldSnap, newSnap, optChangeAccumulator) {
+};
+fb.core.view.filter.NodeFilter.prototype.updatePriority = function(oldSnap, newPriority) {
+};
+fb.core.view.filter.NodeFilter.prototype.filtersNodes = function() {
+};
+fb.core.view.filter.NodeFilter.prototype.getIndexedFilter = function() {
+};
+fb.core.view.filter.NodeFilter.prototype.getIndex = function() {
+};
+goog.provide("fb.core.view.filter.LimitedFilter");
+goog.require("fb.core.snap.NamedNode");
+goog.require("fb.core.view.filter.RangedFilter");
+goog.require("fb.core.util");
+fb.core.view.filter.LimitedFilter = function(params) {
+ this.rangedFilter_ = new fb.core.view.filter.RangedFilter(params);
+ this.index_ = params.getIndex();
+ this.limit_ = params.getLimit();
+ this.reverse_ = !params.isViewFromLeft();
+};
+fb.core.view.filter.LimitedFilter.prototype.updateChild = function(snap, key, newChild, source, optChangeAccumulator) {
+ if (!this.rangedFilter_.matches(new fb.core.snap.NamedNode(key, newChild))) {
+ newChild = fb.core.snap.EMPTY_NODE;
+ }
+ if (snap.getImmediateChild(key).equals(newChild)) {
+ return snap;
+ } else {
+ if (snap.numChildren() < this.limit_) {
+ return this.rangedFilter_.getIndexedFilter().updateChild(snap, key, newChild, source, optChangeAccumulator);
+ } else {
+ return this.fullLimitUpdateChild_(snap, key, newChild, source, optChangeAccumulator);
+ }
+ }
+};
+fb.core.view.filter.LimitedFilter.prototype.updateFullNode = function(oldSnap, newSnap, optChangeAccumulator) {
+ var filtered;
+ if (newSnap.isLeafNode() || newSnap.isEmpty()) {
+ filtered = fb.core.snap.EMPTY_NODE.withIndex(this.index_);
+ } else {
+ if (this.limit_ * 2 < newSnap.numChildren() && newSnap.isIndexed(this.index_)) {
+ filtered = fb.core.snap.EMPTY_NODE.withIndex(this.index_);
+ var iterator;
+ newSnap = (newSnap);
+ if (this.reverse_) {
+ iterator = newSnap.getReverseIteratorFrom(this.rangedFilter_.getEndPost(), this.index_);
+ } else {
+ iterator = newSnap.getIteratorFrom(this.rangedFilter_.getStartPost(), this.index_);
+ }
+ var count = 0;
+ while (iterator.hasNext() && count < this.limit_) {
+ var next = iterator.getNext();
+ var inRange;
+ if (this.reverse_) {
+ inRange = this.index_.compare(this.rangedFilter_.getStartPost(), next) <= 0;
+ } else {
+ inRange = this.index_.compare(next, this.rangedFilter_.getEndPost()) <= 0;
+ }
+ if (inRange) {
+ filtered = filtered.updateImmediateChild(next.name, next.node);
+ count++;
+ } else {
+ break;
+ }
+ }
+ } else {
+ filtered = newSnap.withIndex(this.index_);
+ filtered = (filtered.updatePriority(fb.core.snap.EMPTY_NODE));
+ var startPost;
+ var endPost;
+ var cmp;
+ if (this.reverse_) {
+ iterator = filtered.getReverseIterator(this.index_);
+ startPost = this.rangedFilter_.getEndPost();
+ endPost = this.rangedFilter_.getStartPost();
+ var indexCompare = this.index_.getCompare();
+ cmp = function(a, b) {
+ return indexCompare(b, a);
+ };
+ } else {
+ iterator = filtered.getIterator(this.index_);
+ startPost = this.rangedFilter_.getStartPost();
+ endPost = this.rangedFilter_.getEndPost();
+ cmp = this.index_.getCompare();
+ }
+ count = 0;
+ var foundStartPost = false;
+ while (iterator.hasNext()) {
+ next = iterator.getNext();
+ if (!foundStartPost && cmp(startPost, next) <= 0) {
+ foundStartPost = true;
+ }
+ inRange = foundStartPost && count < this.limit_ && cmp(next, endPost) <= 0;
+ if (inRange) {
+ count++;
+ } else {
+ filtered = filtered.updateImmediateChild(next.name, fb.core.snap.EMPTY_NODE);
+ }
+ }
+ }
+ }
+ return this.rangedFilter_.getIndexedFilter().updateFullNode(oldSnap, filtered, optChangeAccumulator);
+};
+fb.core.view.filter.LimitedFilter.prototype.updatePriority = function(oldSnap, newPriority) {
+ return oldSnap;
+};
+fb.core.view.filter.LimitedFilter.prototype.filtersNodes = function() {
+ return true;
+};
+fb.core.view.filter.LimitedFilter.prototype.getIndexedFilter = function() {
+ return this.rangedFilter_.getIndexedFilter();
+};
+fb.core.view.filter.LimitedFilter.prototype.getIndex = function() {
+ return this.index_;
+};
+fb.core.view.filter.LimitedFilter.prototype.fullLimitUpdateChild_ = function(snap, childKey, childSnap, source, optChangeAccumulator) {
+ var Change = fb.core.view.Change;
+ var cmp;
+ if (this.reverse_) {
+ var indexCmp = this.index_.getCompare();
+ cmp = function(a, b) {
+ return indexCmp(b, a);
+ };
+ } else {
+ cmp = this.index_.getCompare();
+ }
+ var oldEventCache = (snap);
+ fb.core.util.assert(oldEventCache.numChildren() == this.limit_, "");
+ var newChildNamedNode = new fb.core.snap.NamedNode(childKey, childSnap);
+ var windowBoundary = (this.reverse_ ? oldEventCache.getFirstChild(this.index_) : oldEventCache.getLastChild(this.index_));
+ var inRange = this.rangedFilter_.matches(newChildNamedNode);
+ if (oldEventCache.hasChild(childKey)) {
+ var oldChildSnap = oldEventCache.getImmediateChild(childKey);
+ var nextChild = source.getChildAfterChild(this.index_, windowBoundary, this.reverse_);
+ if (nextChild != null && nextChild.name == childKey) {
+ nextChild = source.getChildAfterChild(this.index_, nextChild, this.reverse_);
+ }
+ var compareNext = nextChild == null ? 1 : cmp(nextChild, newChildNamedNode);
+ var remainsInWindow = inRange && !childSnap.isEmpty() && compareNext >= 0;
+ if (remainsInWindow) {
+ if (optChangeAccumulator != null) {
+ optChangeAccumulator.trackChildChange(Change.childChangedChange(childKey, childSnap, oldChildSnap));
+ }
+ return oldEventCache.updateImmediateChild(childKey, childSnap);
+ } else {
+ if (optChangeAccumulator != null) {
+ optChangeAccumulator.trackChildChange(Change.childRemovedChange(childKey, oldChildSnap));
+ }
+ var newEventCache = oldEventCache.updateImmediateChild(childKey, fb.core.snap.EMPTY_NODE);
+ var nextChildInRange = nextChild != null && this.rangedFilter_.matches(nextChild);
+ if (nextChildInRange) {
+ if (optChangeAccumulator != null) {
+ optChangeAccumulator.trackChildChange(Change.childAddedChange(nextChild.name, nextChild.node));
+ }
+ return newEventCache.updateImmediateChild(nextChild.name, nextChild.node);
+ } else {
+ return newEventCache;
+ }
+ }
+ } else {
+ if (childSnap.isEmpty()) {
+ return snap;
+ } else {
+ if (inRange) {
+ if (cmp(windowBoundary, newChildNamedNode) >= 0) {
+ if (optChangeAccumulator != null) {
+ optChangeAccumulator.trackChildChange(Change.childRemovedChange(windowBoundary.name, windowBoundary.node));
+ optChangeAccumulator.trackChildChange(Change.childAddedChange(childKey, childSnap));
+ }
+ return oldEventCache.updateImmediateChild(childKey, childSnap).updateImmediateChild(windowBoundary.name, fb.core.snap.EMPTY_NODE);
+ } else {
+ return snap;
+ }
+ } else {
+ return snap;
+ }
+ }
+ }
+};
+goog.provide("fb.core.view.ViewProcessor");
+goog.require("fb.core.view.CompleteChildSource");
+goog.require("fb.core.util");
+fb.core.view.ProcessorResult = function(viewCache, changes) {
+ this.viewCache = viewCache;
+ this.changes = changes;
+};
+fb.core.view.ViewProcessor = function(filter) {
+ this.filter_ = filter;
+};
+fb.core.view.ViewProcessor.prototype.assertIndexed = function(viewCache) {
+ fb.core.util.assert(viewCache.getEventCache().getNode().isIndexed(this.filter_.getIndex()), "Event snap not indexed");
+ fb.core.util.assert(viewCache.getServerCache().getNode().isIndexed(this.filter_.getIndex()), "Server snap not indexed");
+};
+fb.core.view.ViewProcessor.prototype.applyOperation = function(oldViewCache, operation, writesCache, optCompleteCache) {
+ var accumulator = new fb.core.view.ChildChangeAccumulator;
+ var newViewCache, constrainNode;
+ if (operation.type === fb.core.OperationType.OVERWRITE) {
+ var overwrite = (operation);
+ if (overwrite.source.fromUser) {
+ newViewCache = this.applyUserOverwrite_(oldViewCache, overwrite.path, overwrite.snap, writesCache, optCompleteCache, accumulator);
+ } else {
+ fb.core.util.assert(overwrite.source.fromServer, "Unknown source.");
+ constrainNode = overwrite.source.tagged;
+ newViewCache = this.applyServerOverwrite_(oldViewCache, overwrite.path, overwrite.snap, writesCache, optCompleteCache, constrainNode, accumulator);
+ }
+ } else {
+ if (operation.type === fb.core.OperationType.MERGE) {
+ var merge = (operation);
+ if (merge.source.fromUser) {
+ newViewCache = this.applyUserMerge_(oldViewCache, merge.path, merge.children, writesCache, optCompleteCache, accumulator);
+ } else {
+ fb.core.util.assert(merge.source.fromServer, "Unknown source.");
+ constrainNode = merge.source.tagged;
+ newViewCache = this.applyServerMerge_(oldViewCache, merge.path, merge.children, writesCache, optCompleteCache, constrainNode, accumulator);
+ }
+ } else {
+ if (operation.type === fb.core.OperationType.ACK_USER_WRITE) {
+ var ackUserWrite = (operation);
+ if (!ackUserWrite.revert) {
+ newViewCache = this.ackUserWrite_(oldViewCache, ackUserWrite.path, writesCache, optCompleteCache, accumulator);
+ } else {
+ newViewCache = this.revertUserWrite_(oldViewCache, ackUserWrite.path, writesCache, optCompleteCache, accumulator);
+ }
+ } else {
+ if (operation.type === fb.core.OperationType.LISTEN_COMPLETE) {
+ newViewCache = this.listenComplete_(oldViewCache, operation.path, writesCache, optCompleteCache, accumulator);
+ } else {
+ throw fb.core.util.assertionError("Unknown operation type: " + operation.type);
+ }
+ }
+ }
+ }
+ var changes = accumulator.getChanges();
+ this.maybeAddValueEvent_(oldViewCache, newViewCache, changes);
+ return new fb.core.view.ProcessorResult(newViewCache, changes);
+};
+fb.core.view.ViewProcessor.prototype.maybeAddValueEvent_ = function(oldViewCache, newViewCache, accumulator) {
+ var eventSnap = newViewCache.getEventCache();
+ if (eventSnap.isFullyInitialized()) {
+ var isLeafOrEmpty = eventSnap.getNode().isLeafNode() || eventSnap.getNode().isEmpty();
+ var oldCompleteSnap = oldViewCache.getCompleteEventSnap();
+ if (accumulator.length > 0 || !oldViewCache.getEventCache().isFullyInitialized() || isLeafOrEmpty && !eventSnap.getNode().equals((oldCompleteSnap)) || !eventSnap.getNode().getPriority().equals(oldCompleteSnap.getPriority())) {
+ accumulator.push(fb.core.view.Change.valueChange((newViewCache.getCompleteEventSnap())));
+ }
+ }
+};
+fb.core.view.ViewProcessor.prototype.generateEventCacheAfterServerEvent_ = function(viewCache, changePath, writesCache, source, accumulator) {
+ var oldEventSnap = viewCache.getEventCache();
+ if (writesCache.shadowingWrite(changePath) != null) {
+ return viewCache;
+ } else {
+ var newEventCache, serverNode;
+ if (changePath.isEmpty()) {
+ fb.core.util.assert(viewCache.getServerCache().isFullyInitialized(), "If change path is empty, we must have complete server data");
+ if (viewCache.getServerCache().isFiltered()) {
+ var serverCache = viewCache.getCompleteServerSnap();
+ var completeChildren = serverCache instanceof fb.core.snap.ChildrenNode ? serverCache : fb.core.snap.EMPTY_NODE;
+ var completeEventChildren = writesCache.calcCompleteEventChildren(completeChildren);
+ newEventCache = this.filter_.updateFullNode(viewCache.getEventCache().getNode(), completeEventChildren, accumulator);
+ } else {
+ var completeNode = (writesCache.calcCompleteEventCache(viewCache.getCompleteServerSnap()));
+ newEventCache = this.filter_.updateFullNode(viewCache.getEventCache().getNode(), completeNode, accumulator);
+ }
+ } else {
+ var childKey = changePath.getFront();
+ if (childKey == ".priority") {
+ fb.core.util.assert(changePath.getLength() == 1, "Can't have a priority with additional path components");
+ var oldEventNode = oldEventSnap.getNode();
+ serverNode = viewCache.getServerCache().getNode();
+ var updatedPriority = writesCache.calcEventCacheAfterServerOverwrite(changePath, oldEventNode, serverNode);
+ if (updatedPriority != null) {
+ newEventCache = this.filter_.updatePriority(oldEventNode, updatedPriority);
+ } else {
+ newEventCache = oldEventSnap.getNode();
+ }
+ } else {
+ var childChangePath = changePath.popFront();
+ var newEventChild;
+ if (oldEventSnap.isCompleteForChild(childKey)) {
+ serverNode = viewCache.getServerCache().getNode();
+ var eventChildUpdate = writesCache.calcEventCacheAfterServerOverwrite(changePath, oldEventSnap.getNode(), serverNode);
+ if (eventChildUpdate != null) {
+ newEventChild = oldEventSnap.getNode().getImmediateChild(childKey).updateChild(childChangePath, eventChildUpdate);
+ } else {
+ newEventChild = oldEventSnap.getNode().getImmediateChild(childKey);
+ }
+ } else {
+ newEventChild = writesCache.calcCompleteChild(childKey, viewCache.getServerCache());
+ }
+ if (newEventChild != null) {
+ newEventCache = this.filter_.updateChild(oldEventSnap.getNode(), childKey, newEventChild, source, accumulator);
+ } else {
+ newEventCache = oldEventSnap.getNode();
+ }
+ }
+ }
+ return viewCache.updateEventSnap(newEventCache, oldEventSnap.isFullyInitialized() || changePath.isEmpty(), this.filter_.filtersNodes());
+ }
+};
+fb.core.view.ViewProcessor.prototype.applyServerOverwrite_ = function(oldViewCache, changePath, changedSnap, writesCache, optCompleteCache, constrainServerNode, accumulator) {
+ var oldServerSnap = oldViewCache.getServerCache();
+ var newServerCache;
+ var serverFilter = constrainServerNode ? this.filter_ : this.filter_.getIndexedFilter();
+ if (changePath.isEmpty()) {
+ newServerCache = serverFilter.updateFullNode(oldServerSnap.getNode(), changedSnap, null);
+ } else {
+ if (serverFilter.filtersNodes() && !oldServerSnap.isFiltered()) {
+ var newServerNode = oldServerSnap.getNode().updateChild(changePath, changedSnap);
+ newServerCache = serverFilter.updateFullNode(oldServerSnap.getNode(), newServerNode, null);
+ } else {
+ var childKey = changePath.getFront();
+ if (!oldServerSnap.isCompleteForPath(changePath) && changePath.getLength() > 1) {
+ return oldViewCache;
+ }
+ var childNode = oldServerSnap.getNode().getImmediateChild(childKey);
+ var newChildNode = childNode.updateChild(changePath.popFront(), changedSnap);
+ if (childKey == ".priority") {
+ newServerCache = serverFilter.updatePriority(oldServerSnap.getNode(), newChildNode);
+ } else {
+ newServerCache = serverFilter.updateChild(oldServerSnap.getNode(), childKey, newChildNode, fb.core.view.NO_COMPLETE_CHILD_SOURCE, null);
+ }
+ }
+ }
+ var newViewCache = oldViewCache.updateServerSnap(newServerCache, oldServerSnap.isFullyInitialized() || changePath.isEmpty(), serverFilter.filtersNodes());
+ var source = new fb.core.view.WriteTreeCompleteChildSource(writesCache, newViewCache, optCompleteCache);
+ return this.generateEventCacheAfterServerEvent_(newViewCache, changePath, writesCache, source, accumulator);
+};
+fb.core.view.ViewProcessor.prototype.applyUserOverwrite_ = function(oldViewCache, changePath, changedSnap, writesCache, optCompleteCache, accumulator) {
+ var oldEventSnap = oldViewCache.getEventCache();
+ var newViewCache, newEventCache;
+ var source = new fb.core.view.WriteTreeCompleteChildSource(writesCache, oldViewCache, optCompleteCache);
+ if (changePath.isEmpty()) {
+ newEventCache = this.filter_.updateFullNode(oldViewCache.getEventCache().getNode(), changedSnap, accumulator);
+ newViewCache = oldViewCache.updateEventSnap(newEventCache, true, this.filter_.filtersNodes());
+ } else {
+ var childKey = changePath.getFront();
+ if (childKey === ".priority") {
+ newEventCache = this.filter_.updatePriority(oldViewCache.getEventCache().getNode(), changedSnap);
+ newViewCache = oldViewCache.updateEventSnap(newEventCache, oldEventSnap.isFullyInitialized(), oldEventSnap.isFiltered());
+ } else {
+ var childChangePath = changePath.popFront();
+ var oldChild = oldEventSnap.getNode().getImmediateChild(childKey);
+ var newChild;
+ if (childChangePath.isEmpty()) {
+ newChild = changedSnap;
+ } else {
+ var childNode = source.getCompleteChild(childKey);
+ if (childNode != null) {
+ if (childChangePath.getBack() === ".priority" && childNode.getChild((childChangePath.parent())).isEmpty()) {
+ newChild = childNode;
+ } else {
+ newChild = childNode.updateChild(childChangePath, changedSnap);
+ }
+ } else {
+ newChild = fb.core.snap.EMPTY_NODE;
+ }
+ }
+ if (!oldChild.equals(newChild)) {
+ var newEventSnap = this.filter_.updateChild(oldEventSnap.getNode(), childKey, newChild, source, accumulator);
+ newViewCache = oldViewCache.updateEventSnap(newEventSnap, oldEventSnap.isFullyInitialized(), this.filter_.filtersNodes());
+ } else {
+ newViewCache = oldViewCache;
+ }
+ }
+ }
+ return newViewCache;
+};
+fb.core.view.ViewProcessor.cacheHasChild_ = function(viewCache, childKey) {
+ return viewCache.getEventCache().isCompleteForChild(childKey);
+};
+fb.core.view.ViewProcessor.prototype.applyUserMerge_ = function(viewCache, path, changedChildren, writesCache, serverCache, accumulator) {
+ var self = this;
+ var curViewCache = viewCache;
+ changedChildren.foreach(function(relativePath, childNode) {
+ var writePath = path.child(relativePath);
+ if (fb.core.view.ViewProcessor.cacheHasChild_(viewCache, writePath.getFront())) {
+ curViewCache = self.applyUserOverwrite_(curViewCache, writePath, childNode, writesCache, serverCache, accumulator);
+ }
+ });
+ changedChildren.foreach(function(relativePath, childNode) {
+ var writePath = path.child(relativePath);
+ if (!fb.core.view.ViewProcessor.cacheHasChild_(viewCache, writePath.getFront())) {
+ curViewCache = self.applyUserOverwrite_(curViewCache, writePath, childNode, writesCache, serverCache, accumulator);
+ }
+ });
+ return curViewCache;
+};
+fb.core.view.ViewProcessor.prototype.applyMerge_ = function(node, merge) {
+ merge.foreach(function(relativePath, childNode) {
+ node = node.updateChild(relativePath, childNode);
+ });
+ return node;
+};
+fb.core.view.ViewProcessor.prototype.applyServerMerge_ = function(viewCache, path, changedChildren, writesCache, serverCache, constrainServerNode, accumulator) {
+ if (viewCache.getServerCache().getNode().isEmpty() && !viewCache.getServerCache().isFullyInitialized()) {
+ return viewCache;
+ }
+ var curViewCache = viewCache;
+ var viewMergeTree;
+ if (path.isEmpty()) {
+ viewMergeTree = changedChildren;
+ } else {
+ viewMergeTree = fb.core.util.ImmutableTree.Empty.setTree(path, changedChildren);
+ }
+ var serverNode = viewCache.getServerCache().getNode();
+ var self = this;
+ viewMergeTree.children.inorderTraversal(function(childKey, childTree) {
+ if (serverNode.hasChild(childKey)) {
+ var serverChild = viewCache.getServerCache().getNode().getImmediateChild(childKey);
+ var newChild = self.applyMerge_(serverChild, childTree);
+ curViewCache = self.applyServerOverwrite_(curViewCache, new fb.core.util.Path(childKey), newChild, writesCache, serverCache, constrainServerNode, accumulator);
+ }
+ });
+ viewMergeTree.children.inorderTraversal(function(childKey, childMergeTree) {
+ var isUnknownDeepMerge = !viewCache.getServerCache().isFullyInitialized() && childMergeTree.value == null;
+ if (!serverNode.hasChild(childKey) && !isUnknownDeepMerge) {
+ var serverChild = viewCache.getServerCache().getNode().getImmediateChild(childKey);
+ var newChild = self.applyMerge_(serverChild, childMergeTree);
+ curViewCache = self.applyServerOverwrite_(curViewCache, new fb.core.util.Path(childKey), newChild, writesCache, serverCache, constrainServerNode, accumulator);
+ }
+ });
+ return curViewCache;
+};
+fb.core.view.ViewProcessor.prototype.ackUserWrite_ = function(viewCache, ackPath, writesCache, optCompleteCache, accumulator) {
+ if (writesCache.shadowingWrite(ackPath) != null) {
+ return viewCache;
+ } else {
+ var source = new fb.core.view.WriteTreeCompleteChildSource(writesCache, viewCache, optCompleteCache);
+ var oldEventCache = viewCache.getEventCache().getNode();
+ var newEventCache = oldEventCache;
+ var eventCacheComplete;
+ if (viewCache.getServerCache().isFullyInitialized()) {
+ if (ackPath.isEmpty()) {
+ var update = (writesCache.calcCompleteEventCache(viewCache.getCompleteServerSnap()));
+ newEventCache = this.filter_.updateFullNode(viewCache.getEventCache().getNode(), update, accumulator);
+ } else {
+ if (ackPath.getFront() === ".priority") {
+ var updatedPriority = writesCache.calcCompleteChild(ackPath.getFront(), viewCache.getServerCache());
+ if (updatedPriority != null && !oldEventCache.isEmpty() && !oldEventCache.getPriority().equals(updatedPriority)) {
+ newEventCache = this.filter_.updatePriority(oldEventCache, updatedPriority);
+ }
+ } else {
+ var childKey = ackPath.getFront();
+ var updatedChild = writesCache.calcCompleteChild(childKey, viewCache.getServerCache());
+ if (updatedChild != null) {
+ newEventCache = this.filter_.updateChild(viewCache.getEventCache().getNode(), childKey, updatedChild, source, accumulator);
+ }
+ }
+ }
+ eventCacheComplete = true;
+ } else {
+ if (viewCache.getEventCache().isFullyInitialized() || ackPath.isEmpty()) {
+ newEventCache = oldEventCache;
+ var completeEventSnap = viewCache.getEventCache().getNode();
+ if (!completeEventSnap.isLeafNode()) {
+ var self = this;
+ completeEventSnap = (completeEventSnap);
+ completeEventSnap.forEachChild(fb.core.snap.PriorityIndex, function(key, childNode) {
+ var completeChild = writesCache.calcCompleteChild(key, viewCache.getServerCache());
+ if (completeChild != null) {
+ newEventCache = self.filter_.updateChild(newEventCache, key, completeChild, source, accumulator);
+ }
+ });
+ }
+ eventCacheComplete = viewCache.getEventCache().isFullyInitialized();
+ } else {
+ var childKey = ackPath.getFront();
+ if (ackPath.getLength() == 1 || viewCache.getEventCache().isCompleteForChild(childKey)) {
+ var completeChild = writesCache.calcCompleteChild(childKey, viewCache.getServerCache());
+ if (completeChild != null) {
+ newEventCache = this.filter_.updateChild(oldEventCache, childKey, completeChild, source, accumulator);
+ }
+ }
+ eventCacheComplete = false;
+ }
+ }
+ return viewCache.updateEventSnap(newEventCache, eventCacheComplete, this.filter_.filtersNodes());
+ }
+};
+fb.core.view.ViewProcessor.prototype.revertUserWrite_ = function(viewCache, path, writesCache, optCompleteServerCache, accumulator) {
+ var complete;
+ if (writesCache.shadowingWrite(path) != null) {
+ return viewCache;
+ } else {
+ var source = new fb.core.view.WriteTreeCompleteChildSource(writesCache, viewCache, optCompleteServerCache);
+ var oldEventCache = viewCache.getEventCache().getNode();
+ var newEventCache;
+ if (path.isEmpty() || path.getFront() === ".priority") {
+ var newNode;
+ if (viewCache.getServerCache().isFullyInitialized()) {
+ newNode = writesCache.calcCompleteEventCache(viewCache.getCompleteServerSnap());
+ } else {
+ var serverChildren = viewCache.getServerCache().getNode();
+ fb.core.util.assert(serverChildren instanceof fb.core.snap.ChildrenNode, "serverChildren would be complete if leaf node");
+ newNode = writesCache.calcCompleteEventChildren((serverChildren));
+ }
+ newNode = (newNode);
+ newEventCache = this.filter_.updateFullNode(oldEventCache, newNode, accumulator);
+ } else {
+ var childKey = path.getFront();
+ var newChild = writesCache.calcCompleteChild(childKey, viewCache.getServerCache());
+ if (newChild == null && viewCache.getServerCache().isCompleteForChild(childKey)) {
+ newChild = oldEventCache.getImmediateChild(childKey);
+ }
+ if (newChild != null) {
+ newEventCache = this.filter_.updateChild(oldEventCache, childKey, newChild, source, accumulator);
+ } else {
+ if (viewCache.getEventCache().getNode().hasChild(childKey)) {
+ newEventCache = this.filter_.updateChild(oldEventCache, childKey, fb.core.snap.EMPTY_NODE, source, accumulator);
+ } else {
+ newEventCache = oldEventCache;
+ }
+ }
+ if (newEventCache.isEmpty() && viewCache.getServerCache().isFullyInitialized()) {
+ complete = writesCache.calcCompleteEventCache(viewCache.getCompleteServerSnap());
+ if (complete.isLeafNode()) {
+ newEventCache = this.filter_.updateFullNode(newEventCache, complete, accumulator);
+ }
+ }
+ }
+ complete = viewCache.getServerCache().isFullyInitialized() || writesCache.shadowingWrite(fb.core.util.Path.Empty) != null;
+ return viewCache.updateEventSnap(newEventCache, complete, this.filter_.filtersNodes());
+ }
+};
+fb.core.view.ViewProcessor.prototype.listenComplete_ = function(viewCache, path, writesCache, serverCache, accumulator) {
+ var oldServerNode = viewCache.getServerCache();
+ var newViewCache = viewCache.updateServerSnap(oldServerNode.getNode(), oldServerNode.isFullyInitialized() || path.isEmpty(), oldServerNode.isFiltered());
+ return this.generateEventCacheAfterServerEvent_(newViewCache, path, writesCache, fb.core.view.NO_COMPLETE_CHILD_SOURCE, accumulator);
+};
+goog.provide("fb.core.snap.Index");
+goog.provide("fb.core.snap.PriorityIndex");
+goog.provide("fb.core.snap.SubKeyIndex");
+goog.require("fb.core.snap.comparators");
+goog.require("fb.core.util");
+fb.core.snap.Index = function() {
+};
+fb.core.snap.Index.FallbackType;
+fb.core.snap.Index.Fallback = {};
+fb.core.snap.Index.prototype.compare = goog.abstractMethod;
+fb.core.snap.Index.prototype.isDefinedOn = goog.abstractMethod;
+fb.core.snap.Index.prototype.getCompare = function() {
+ return goog.bind(this.compare, this);
+};
+fb.core.snap.Index.prototype.indexedValueChanged = function(oldNode, newNode) {
+ var oldWrapped = new fb.core.snap.NamedNode(fb.core.util.MIN_NAME, oldNode);
+ var newWrapped = new fb.core.snap.NamedNode(fb.core.util.MIN_NAME, newNode);
+ return this.compare(oldWrapped, newWrapped) !== 0;
+};
+fb.core.snap.Index.prototype.minPost = function() {
+ return fb.core.snap.NamedNode.MIN;
+};
+fb.core.snap.Index.prototype.maxPost = goog.abstractMethod;
+fb.core.snap.Index.prototype.makePost = goog.abstractMethod;
+fb.core.snap.Index.prototype.toString = goog.abstractMethod;
+fb.core.snap.SubKeyIndex = function(indexKey) {
+ fb.core.snap.Index.call(this);
+ this.indexKey_ = indexKey;
+};
+goog.inherits(fb.core.snap.SubKeyIndex, fb.core.snap.Index);
+fb.core.snap.SubKeyIndex.prototype.extractChild = function(snap) {
+ return snap.getImmediateChild(this.indexKey_);
+};
+fb.core.snap.SubKeyIndex.prototype.isDefinedOn = function(node) {
+ return!node.getImmediateChild(this.indexKey_).isEmpty();
+};
+fb.core.snap.SubKeyIndex.prototype.compare = function(a, b) {
+ var aChild = this.extractChild(a.node);
+ var bChild = this.extractChild(b.node);
+ var indexCmp = aChild.compareTo(bChild);
+ if (indexCmp === 0) {
+ return fb.core.util.nameCompare(a.name, b.name);
+ } else {
+ return indexCmp;
+ }
+};
+fb.core.snap.SubKeyIndex.prototype.makePost = function(indexValue, name) {
+ var valueNode = fb.core.snap.NodeFromJSON(indexValue);
+ var node = fb.core.snap.EMPTY_NODE.updateImmediateChild(this.indexKey_, valueNode);
+ return new fb.core.snap.NamedNode(name, node);
+};
+fb.core.snap.SubKeyIndex.prototype.maxPost = function() {
+ var node = fb.core.snap.EMPTY_NODE.updateImmediateChild(this.indexKey_, fb.core.snap.MAX_NODE);
+ return new fb.core.snap.NamedNode(fb.core.util.MAX_NAME, node);
+};
+fb.core.snap.SubKeyIndex.prototype.toString = function() {
+ return this.indexKey_;
+};
+fb.core.snap.PriorityIndex_ = function() {
+ fb.core.snap.Index.call(this);
+};
+goog.inherits(fb.core.snap.PriorityIndex_, fb.core.snap.Index);
+fb.core.snap.PriorityIndex_.prototype.compare = function(a, b) {
+ var aPriority = a.node.getPriority();
+ var bPriority = b.node.getPriority();
+ var indexCmp = aPriority.compareTo(bPriority);
+ if (indexCmp === 0) {
+ return fb.core.util.nameCompare(a.name, b.name);
+ } else {
+ return indexCmp;
+ }
+};
+fb.core.snap.PriorityIndex_.prototype.isDefinedOn = function(node) {
+ return!node.getPriority().isEmpty();
+};
+fb.core.snap.PriorityIndex_.prototype.indexedValueChanged = function(oldNode, newNode) {
+ return!oldNode.getPriority().equals(newNode.getPriority());
+};
+fb.core.snap.PriorityIndex_.prototype.minPost = function() {
+ return fb.core.snap.NamedNode.MIN;
+};
+fb.core.snap.PriorityIndex_.prototype.maxPost = function() {
+ return new fb.core.snap.NamedNode(fb.core.util.MAX_NAME, new fb.core.snap.LeafNode("[PRIORITY-POST]", fb.core.snap.MAX_NODE));
+};
+fb.core.snap.PriorityIndex_.prototype.makePost = function(indexValue, name) {
+ var priorityNode = fb.core.snap.NodeFromJSON(indexValue);
+ return new fb.core.snap.NamedNode(name, new fb.core.snap.LeafNode("[PRIORITY-POST]", priorityNode));
+};
+fb.core.snap.PriorityIndex_.prototype.toString = function() {
+ return ".priority";
+};
+fb.core.snap.PriorityIndex = new fb.core.snap.PriorityIndex_;
+fb.core.snap.KeyIndex_ = function() {
+ fb.core.snap.Index.call(this);
+};
+goog.inherits(fb.core.snap.KeyIndex_, fb.core.snap.Index);
+fb.core.snap.KeyIndex_.prototype.compare = function(a, b) {
+ return fb.core.util.nameCompare(a.name, b.name);
+};
+fb.core.snap.KeyIndex_.prototype.isDefinedOn = function(node) {
+ throw fb.core.util.assertionError("KeyIndex.isDefinedOn not expected to be called.");
+};
+fb.core.snap.KeyIndex_.prototype.indexedValueChanged = function(oldNode, newNode) {
+ return false;
+};
+fb.core.snap.KeyIndex_.prototype.minPost = function() {
+ return fb.core.snap.NamedNode.MIN;
+};
+fb.core.snap.KeyIndex_.prototype.maxPost = function() {
+ return new fb.core.snap.NamedNode(fb.core.util.MAX_NAME, fb.core.snap.EMPTY_NODE);
+};
+fb.core.snap.KeyIndex_.prototype.makePost = function(indexValue, name) {
+ fb.core.util.assert(goog.isString(indexValue), "KeyIndex indexValue must always be a string.");
+ return new fb.core.snap.NamedNode((indexValue), fb.core.snap.EMPTY_NODE);
+};
+fb.core.snap.KeyIndex_.prototype.toString = function() {
+ return ".key";
+};
+fb.core.snap.KeyIndex = new fb.core.snap.KeyIndex_;
+fb.core.snap.ValueIndex_ = function() {
+ fb.core.snap.Index.call(this);
+};
+goog.inherits(fb.core.snap.ValueIndex_, fb.core.snap.Index);
+fb.core.snap.ValueIndex_.prototype.compare = function(a, b) {
+ var indexCmp = a.node.compareTo(b.node);
+ if (indexCmp === 0) {
+ return fb.core.util.nameCompare(a.name, b.name);
+ } else {
+ return indexCmp;
+ }
+};
+fb.core.snap.ValueIndex_.prototype.isDefinedOn = function(node) {
+ return true;
+};
+fb.core.snap.ValueIndex_.prototype.indexedValueChanged = function(oldNode, newNode) {
+ return!oldNode.equals(newNode);
+};
+fb.core.snap.ValueIndex_.prototype.minPost = function() {
+ return fb.core.snap.NamedNode.MIN;
+};
+fb.core.snap.ValueIndex_.prototype.maxPost = function() {
+ return fb.core.snap.NamedNode.MAX;
+};
+fb.core.snap.ValueIndex_.prototype.makePost = function(indexValue, name) {
+ var valueNode = fb.core.snap.NodeFromJSON(indexValue);
+ return new fb.core.snap.NamedNode(name, valueNode);
+};
+fb.core.snap.ValueIndex_.prototype.toString = function() {
+ return ".value";
+};
+fb.core.snap.ValueIndex = new fb.core.snap.ValueIndex_;
+goog.provide("fb.core.view.QueryParams");
+goog.require("fb.core.snap.Index");
+goog.require("fb.core.snap.PriorityIndex");
+goog.require("fb.core.util");
+goog.require("fb.core.view.filter.IndexedFilter");
+goog.require("fb.core.view.filter.LimitedFilter");
+goog.require("fb.core.view.filter.NodeFilter");
+goog.require("fb.core.view.filter.RangedFilter");
+fb.core.view.QueryParams = function() {
+ this.limitSet_ = false;
+ this.startSet_ = false;
+ this.startNameSet_ = false;
+ this.endSet_ = false;
+ this.endNameSet_ = false;
+ this.limit_ = 0;
+ this.viewFrom_ = "";
+ this.indexStartValue_ = null;
+ this.indexStartName_ = "";
+ this.indexEndValue_ = null;
+ this.indexEndName_ = "";
+ this.index_ = fb.core.snap.PriorityIndex;
+};
+fb.core.view.QueryParams.WIRE_PROTOCOL_CONSTANTS_ = {INDEX_START_VALUE:"sp", INDEX_START_NAME:"sn", INDEX_END_VALUE:"ep", INDEX_END_NAME:"en", LIMIT:"l", VIEW_FROM:"vf", VIEW_FROM_LEFT:"l", VIEW_FROM_RIGHT:"r", INDEX:"i"};
+fb.core.view.QueryParams.REST_QUERY_CONSTANTS_ = {ORDER_BY:"orderBy", PRIORITY_INDEX:"$priority", VALUE_INDEX:"$value", KEY_INDEX:"$key", START_AT:"startAt", END_AT:"endAt", LIMIT_TO_FIRST:"limitToFirst", LIMIT_TO_LAST:"limitToLast"};
+fb.core.view.QueryParams.DEFAULT = new fb.core.view.QueryParams;
+fb.core.view.QueryParams.prototype.hasStart = function() {
+ return this.startSet_;
+};
+fb.core.view.QueryParams.prototype.isViewFromLeft = function() {
+ if (this.viewFrom_ === "") {
+ return this.startSet_;
+ } else {
+ return this.viewFrom_ === fb.core.view.QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_LEFT;
+ }
+};
+fb.core.view.QueryParams.prototype.getIndexStartValue = function() {
+ fb.core.util.assert(this.startSet_, "Only valid if start has been set");
+ return this.indexStartValue_;
+};
+fb.core.view.QueryParams.prototype.getIndexStartName = function() {
+ fb.core.util.assert(this.startSet_, "Only valid if start has been set");
+ if (this.startNameSet_) {
+ return this.indexStartName_;
+ } else {
+ return fb.core.util.MIN_NAME;
+ }
+};
+fb.core.view.QueryParams.prototype.hasEnd = function() {
+ return this.endSet_;
+};
+fb.core.view.QueryParams.prototype.getIndexEndValue = function() {
+ fb.core.util.assert(this.endSet_, "Only valid if end has been set");
+ return this.indexEndValue_;
+};
+fb.core.view.QueryParams.prototype.getIndexEndName = function() {
+ fb.core.util.assert(this.endSet_, "Only valid if end has been set");
+ if (this.endNameSet_) {
+ return this.indexEndName_;
+ } else {
+ return fb.core.util.MAX_NAME;
+ }
+};
+fb.core.view.QueryParams.prototype.hasLimit = function() {
+ return this.limitSet_;
+};
+fb.core.view.QueryParams.prototype.hasAnchoredLimit = function() {
+ return this.limitSet_ && this.viewFrom_ !== "";
+};
+fb.core.view.QueryParams.prototype.getLimit = function() {
+ fb.core.util.assert(this.limitSet_, "Only valid if limit has been set");
+ return this.limit_;
+};
+fb.core.view.QueryParams.prototype.getIndex = function() {
+ return this.index_;
+};
+fb.core.view.QueryParams.prototype.copy_ = function() {
+ var copy = new fb.core.view.QueryParams;
+ copy.limitSet_ = this.limitSet_;
+ copy.limit_ = this.limit_;
+ copy.startSet_ = this.startSet_;
+ copy.indexStartValue_ = this.indexStartValue_;
+ copy.startNameSet_ = this.startNameSet_;
+ copy.indexStartName_ = this.indexStartName_;
+ copy.endSet_ = this.endSet_;
+ copy.indexEndValue_ = this.indexEndValue_;
+ copy.endNameSet_ = this.endNameSet_;
+ copy.indexEndName_ = this.indexEndName_;
+ copy.index_ = this.index_;
+ return copy;
+};
+fb.core.view.QueryParams.prototype.limit = function(newLimit) {
+ var newParams = this.copy_();
+ newParams.limitSet_ = true;
+ newParams.limit_ = newLimit;
+ newParams.viewFrom_ = "";
+ return newParams;
+};
+fb.core.view.QueryParams.prototype.limitToFirst = function(newLimit) {
+ var newParams = this.copy_();
+ newParams.limitSet_ = true;
+ newParams.limit_ = newLimit;
+ newParams.viewFrom_ = fb.core.view.QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_LEFT;
+ return newParams;
+};
+fb.core.view.QueryParams.prototype.limitToLast = function(newLimit) {
+ var newParams = this.copy_();
+ newParams.limitSet_ = true;
+ newParams.limit_ = newLimit;
+ newParams.viewFrom_ = fb.core.view.QueryParams.WIRE_PROTOCOL_CONSTANTS_.VIEW_FROM_RIGHT;
+ return newParams;
+};
+fb.core.view.QueryParams.prototype.startAt = function(indexValue, key) {
+ var newParams = this.copy_();
+ newParams.startSet_ = true;
+ if (!goog.isDef(indexValue)) {
+ indexValue = null;
+ }
+ newParams.indexStartValue_ = indexValue;
+ if (key != null) {
+ newParams.startNameSet_ = true;
+ newParams.indexStartName_ = key;
+ } else {
+ newParams.startNameSet_ = false;
+ newParams.indexStartName_ = "";
+ }
+ return newParams;
+};
+fb.core.view.QueryParams.prototype.endAt = function(indexValue, key) {
+ var newParams = this.copy_();
+ newParams.endSet_ = true;
+ if (!goog.isDef(indexValue)) {
+ indexValue = null;
+ }
+ newParams.indexEndValue_ = indexValue;
+ if (goog.isDef(key)) {
+ newParams.endNameSet_ = true;
+ newParams.indexEndName_ = key;
+ } else {
+ newParams.startEndSet_ = false;
+ newParams.indexEndName_ = "";
+ }
+ return newParams;
+};
+fb.core.view.QueryParams.prototype.orderBy = function(index) {
+ var newParams = this.copy_();
+ newParams.index_ = index;
+ return newParams;
+};
+fb.core.view.QueryParams.prototype.getQueryObject = function() {
+ var WIRE_PROTOCOL_CONSTANTS = fb.core.view.QueryParams.WIRE_PROTOCOL_CONSTANTS_;
+ var obj = {};
+ if (this.startSet_) {
+ obj[WIRE_PROTOCOL_CONSTANTS.INDEX_START_VALUE] = this.indexStartValue_;
+ if (this.startNameSet_) {
+ obj[WIRE_PROTOCOL_CONSTANTS.INDEX_START_NAME] = this.indexStartName_;
+ }
+ }
+ if (this.endSet_) {
+ obj[WIRE_PROTOCOL_CONSTANTS.INDEX_END_VALUE] = this.indexEndValue_;
+ if (this.endNameSet_) {
+ obj[WIRE_PROTOCOL_CONSTANTS.INDEX_END_NAME] = this.indexEndName_;
+ }
+ }
+ if (this.limitSet_) {
+ obj[WIRE_PROTOCOL_CONSTANTS.LIMIT] = this.limit_;
+ var viewFrom = this.viewFrom_;
+ if (viewFrom === "") {
+ if (this.isViewFromLeft()) {
+ viewFrom = WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_LEFT;
+ } else {
+ viewFrom = WIRE_PROTOCOL_CONSTANTS.VIEW_FROM_RIGHT;
+ }
+ }
+ obj[WIRE_PROTOCOL_CONSTANTS.VIEW_FROM] = viewFrom;
+ }
+ if (this.index_ !== fb.core.snap.PriorityIndex) {
+ obj[WIRE_PROTOCOL_CONSTANTS.INDEX] = this.index_.toString();
+ }
+ return obj;
+};
+fb.core.view.QueryParams.prototype.loadsAllData = function() {
+ return!(this.startSet_ || this.endSet_ || this.limitSet_);
+};
+fb.core.view.QueryParams.prototype.isDefault = function() {
+ return this.loadsAllData() && this.index_ == fb.core.snap.PriorityIndex;
+};
+fb.core.view.QueryParams.prototype.getNodeFilter = function() {
+ if (this.loadsAllData()) {
+ return new fb.core.view.filter.IndexedFilter(this.getIndex());
+ } else {
+ if (this.hasLimit()) {
+ return new fb.core.view.filter.LimitedFilter(this);
+ } else {
+ return new fb.core.view.filter.RangedFilter(this);
+ }
+ }
+};
+fb.core.view.QueryParams.prototype.toRestQueryStringParameters = function() {
+ var REST_CONSTANTS = fb.core.view.QueryParams.REST_QUERY_CONSTANTS_;
+ var qs = {};
+ if (this.isDefault()) {
+ return qs;
+ }
+ var orderBy;
+ if (this.index_ === fb.core.snap.PriorityIndex) {
+ orderBy = REST_CONSTANTS.PRIORITY_INDEX;
+ } else {
+ if (this.index_ === fb.core.snap.ValueIndex) {
+ orderBy = REST_CONSTANTS.VALUE_INDEX;
+ } else {
+ if (this.index_ === fb.core.snap.KeyIndex) {
+ orderBy = REST_CONSTANTS.KEY_INDEX;
+ } else {
+ fb.core.util.assert(this.index_ instanceof fb.core.snap.SubKeyIndex, "Unrecognized index type!");
+ orderBy = this.index_.toString();
+ }
+ }
+ }
+ qs[REST_CONSTANTS.ORDER_BY] = fb.util.json.stringify(orderBy);
+ if (this.startSet_) {
+ qs[REST_CONSTANTS.START_AT] = fb.util.json.stringify(this.indexStartValue_);
+ if (this.startNameSet_) {
+ qs[REST_CONSTANTS.START_AT] += "," + fb.util.json.stringify(this.indexStartName_);
+ }
+ }
+ if (this.endSet_) {
+ qs[REST_CONSTANTS.END_AT] = fb.util.json.stringify(this.indexEndValue_);
+ if (this.endNameSet_) {
+ qs[REST_CONSTANTS.END_AT] += "," + fb.util.json.stringify(this.indexEndName_);
+ }
+ }
+ if (this.limitSet_) {
+ if (this.isViewFromLeft()) {
+ qs[REST_CONSTANTS.LIMIT_TO_FIRST] = this.limit_;
+ } else {
+ qs[REST_CONSTANTS.LIMIT_TO_LAST] = this.limit_;
+ }
+ }
+ return qs;
+};
+if (goog.DEBUG) {
+ fb.core.view.QueryParams.prototype.toString = function() {
+ return fb.util.json.stringify(this.getQueryObject());
+ };
+}
+;goog.provide("fb.core.snap.IndexMap");
+goog.require("fb.core.snap.Index");
+goog.require("fb.core.util");
+fb.core.snap.IndexMap = function(indexes, indexSet) {
+ this.indexes_ = indexes;
+ this.indexSet_ = indexSet;
+};
+fb.core.snap.IndexMap.prototype.get = function(indexKey) {
+ var sortedMap = fb.util.obj.get(this.indexes_, indexKey);
+ if (!sortedMap) {
+ throw new Error("No index defined for " + indexKey);
+ }
+ if (sortedMap === fb.core.snap.Index.Fallback) {
+ return null;
+ } else {
+ return sortedMap;
+ }
+};
+fb.core.snap.IndexMap.prototype.hasIndex = function(indexDefinition) {
+ return goog.object.contains(this.indexSet_, indexDefinition.toString());
+};
+fb.core.snap.IndexMap.prototype.addIndex = function(indexDefinition, existingChildren) {
+ fb.core.util.assert(indexDefinition !== fb.core.snap.KeyIndex, "KeyIndex always exists and isn't meant to be added to the IndexMap.");
+ var childList = [];
+ var sawIndexedValue = false;
+ var iter = existingChildren.getIterator(fb.core.snap.NamedNode.Wrap);
+ var next = iter.getNext();
+ while (next) {
+ sawIndexedValue = sawIndexedValue || indexDefinition.isDefinedOn(next.node);
+ childList.push(next);
+ next = iter.getNext();
+ }
+ var newIndex;
+ if (sawIndexedValue) {
+ newIndex = fb.core.snap.buildChildSet(childList, indexDefinition.getCompare());
+ } else {
+ newIndex = fb.core.snap.Index.Fallback;
+ }
+ var indexName = indexDefinition.toString();
+ var newIndexSet = goog.object.clone(this.indexSet_);
+ newIndexSet[indexName] = indexDefinition;
+ var newIndexes = goog.object.clone(this.indexes_);
+ newIndexes[indexName] = newIndex;
+ return new fb.core.snap.IndexMap(newIndexes, newIndexSet);
+};
+fb.core.snap.IndexMap.prototype.addToIndexes = function(namedNode, existingChildren) {
+ var self = this;
+ var newIndexes = goog.object.map(this.indexes_, function(indexedChildren, indexName) {
+ var index = fb.util.obj.get(self.indexSet_, indexName);
+ fb.core.util.assert(index, "Missing index implementation for " + indexName);
+ if (indexedChildren === fb.core.snap.Index.Fallback) {
+ if (index.isDefinedOn(namedNode.node)) {
+ var childList = [];
+ var iter = existingChildren.getIterator(fb.core.snap.NamedNode.Wrap);
+ var next = iter.getNext();
+ while (next) {
+ if (next.name != namedNode.name) {
+ childList.push(next);
+ }
+ next = iter.getNext();
+ }
+ childList.push(namedNode);
+ return fb.core.snap.buildChildSet(childList, index.getCompare());
+ } else {
+ return fb.core.snap.Index.Fallback;
+ }
+ } else {
+ var existingSnap = existingChildren.get(namedNode.name);
+ var newChildren = indexedChildren;
+ if (existingSnap) {
+ newChildren = newChildren.remove(new fb.core.snap.NamedNode(namedNode.name, existingSnap));
+ }
+ return newChildren.insert(namedNode, namedNode.node);
+ }
+ });
+ return new fb.core.snap.IndexMap(newIndexes, this.indexSet_);
+};
+fb.core.snap.IndexMap.prototype.removeFromIndexes = function(namedNode, existingChildren) {
+ var newIndexes = goog.object.map(this.indexes_, function(indexedChildren) {
+ if (indexedChildren === fb.core.snap.Index.Fallback) {
+ return indexedChildren;
+ } else {
+ var existingSnap = existingChildren.get(namedNode.name);
+ if (existingSnap) {
+ return indexedChildren.remove(new fb.core.snap.NamedNode(namedNode.name, existingSnap));
+ } else {
+ return indexedChildren;
+ }
+ }
+ });
+ return new fb.core.snap.IndexMap(newIndexes, this.indexSet_);
+};
+fb.core.snap.IndexMap.Default = new fb.core.snap.IndexMap({".priority":fb.core.snap.Index.Fallback}, {".priority":fb.core.snap.PriorityIndex});
+goog.provide("fb.core.snap.LeafNode");
+goog.require("fb.core.snap.Node");
+goog.require("fb.core.util");
+fb.core.snap.LeafNode = function(value, opt_priorityNode) {
+ this.value_ = value;
+ fb.core.util.assert(goog.isDef(this.value_) && this.value_ !== null, "LeafNode shouldn't be created with null/undefined value.");
+ this.priorityNode_ = opt_priorityNode || fb.core.snap.EMPTY_NODE;
+ fb.core.snap.validatePriorityNode(this.priorityNode_);
+ this.lazyHash_ = null;
+};
+fb.core.snap.LeafNode.prototype.isLeafNode = function() {
+ return true;
+};
+fb.core.snap.LeafNode.prototype.getPriority = function() {
+ return this.priorityNode_;
+};
+fb.core.snap.LeafNode.prototype.updatePriority = function(newPriorityNode) {
+ return new fb.core.snap.LeafNode(this.value_, newPriorityNode);
+};
+fb.core.snap.LeafNode.prototype.getImmediateChild = function(childName) {
+ if (childName === ".priority") {
+ return this.priorityNode_;
+ } else {
+ return fb.core.snap.EMPTY_NODE;
+ }
+};
+fb.core.snap.LeafNode.prototype.getChild = function(path) {
+ if (path.isEmpty()) {
+ return this;
+ } else {
+ if (path.getFront() === ".priority") {
+ return this.priorityNode_;
+ } else {
+ return fb.core.snap.EMPTY_NODE;
+ }
+ }
+};
+fb.core.snap.LeafNode.prototype.hasChild = function() {
+ return false;
+};
+fb.core.snap.LeafNode.prototype.getPredecessorChildName = function(childName, childNode) {
+ return null;
+};
+fb.core.snap.LeafNode.prototype.updateImmediateChild = function(childName, newChildNode) {
+ if (childName === ".priority") {
+ return this.updatePriority(newChildNode);
+ } else {
+ if (newChildNode.isEmpty() && childName !== ".priority") {
+ return this;
+ } else {
+ return fb.core.snap.EMPTY_NODE.updateImmediateChild(childName, newChildNode).updatePriority(this.priorityNode_);
+ }
+ }
+};
+fb.core.snap.LeafNode.prototype.updateChild = function(path, newChildNode) {
+ var front = path.getFront();
+ if (front === null) {
+ return newChildNode;
+ } else {
+ if (newChildNode.isEmpty() && front !== ".priority") {
+ return this;
+ } else {
+ fb.core.util.assert(front !== ".priority" || path.getLength() === 1, ".priority must be the last token in a path");
+ return this.updateImmediateChild(front, fb.core.snap.EMPTY_NODE.updateChild(path.popFront(), newChildNode));
+ }
+ }
+};
+fb.core.snap.LeafNode.prototype.isEmpty = function() {
+ return false;
+};
+fb.core.snap.LeafNode.prototype.numChildren = function() {
+ return 0;
+};
+fb.core.snap.LeafNode.prototype.val = function(opt_exportFormat) {
+ if (opt_exportFormat && !this.getPriority().isEmpty()) {
+ return{".value":this.getValue(), ".priority":this.getPriority().val()};
+ } else {
+ return this.getValue();
+ }
+};
+fb.core.snap.LeafNode.prototype.hash = function() {
+ if (this.lazyHash_ === null) {
+ var toHash = "";
+ if (!this.priorityNode_.isEmpty()) {
+ toHash += "priority:" + fb.core.snap.priorityHashText((this.priorityNode_.val())) + ":";
+ }
+ var type = typeof this.value_;
+ toHash += type + ":";
+ if (type === "number") {
+ toHash += fb.core.util.doubleToIEEE754String((this.value_));
+ } else {
+ toHash += this.value_;
+ }
+ this.lazyHash_ = fb.core.util.sha1(toHash);
+ }
+ return(this.lazyHash_);
+};
+fb.core.snap.LeafNode.prototype.getValue = function() {
+ return this.value_;
+};
+fb.core.snap.LeafNode.prototype.compareTo = function(other) {
+ if (other === fb.core.snap.EMPTY_NODE) {
+ return 1;
+ } else {
+ if (other instanceof fb.core.snap.ChildrenNode) {
+ return-1;
+ } else {
+ fb.core.util.assert(other.isLeafNode(), "Unknown node type");
+ return this.compareToLeafNode_((other));
+ }
+ }
+};
+fb.core.snap.LeafNode.VALUE_TYPE_ORDER = ["object", "boolean", "number", "string"];
+fb.core.snap.LeafNode.prototype.compareToLeafNode_ = function(otherLeaf) {
+ var otherLeafType = typeof otherLeaf.value_;
+ var thisLeafType = typeof this.value_;
+ var otherIndex = goog.array.indexOf(fb.core.snap.LeafNode.VALUE_TYPE_ORDER, otherLeafType);
+ var thisIndex = goog.array.indexOf(fb.core.snap.LeafNode.VALUE_TYPE_ORDER, thisLeafType);
+ fb.core.util.assert(otherIndex >= 0, "Unknown leaf type: " + otherLeafType);
+ fb.core.util.assert(thisIndex >= 0, "Unknown leaf type: " + thisLeafType);
+ if (otherIndex === thisIndex) {
+ if (thisLeafType === "object") {
+ return 0;
+ } else {
+ if (this.value_ < otherLeaf.value_) {
+ return-1;
+ } else {
+ if (this.value_ === otherLeaf.value_) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+ }
+ } else {
+ return thisIndex - otherIndex;
+ }
+};
+fb.core.snap.LeafNode.prototype.withIndex = function() {
+ return this;
+};
+fb.core.snap.LeafNode.prototype.isIndexed = function() {
+ return true;
+};
+fb.core.snap.LeafNode.prototype.equals = function(other) {
+ if (other === this) {
+ return true;
+ } else {
+ if (other.isLeafNode()) {
+ var otherLeaf = (other);
+ return this.value_ === otherLeaf.value_ && this.priorityNode_.equals(otherLeaf.priorityNode_);
+ } else {
+ return false;
+ }
+ }
+};
+if (goog.DEBUG) {
+ fb.core.snap.LeafNode.prototype.toString = function() {
+ return fb.util.json.stringify(this.val(true));
+ };
+}
+;goog.provide("fb.core.snap.ChildrenNode");
+goog.require("fb.core.snap.IndexMap");
+goog.require("fb.core.snap.LeafNode");
+goog.require("fb.core.snap.NamedNode");
+goog.require("fb.core.snap.Node");
+goog.require("fb.core.snap.PriorityIndex");
+goog.require("fb.core.snap.comparators");
+goog.require("fb.core.util");
+goog.require("fb.core.util.SortedMap");
+fb.core.snap.ChildrenNode = function(children, priorityNode, indexMap) {
+ this.children_ = children;
+ this.priorityNode_ = priorityNode;
+ if (this.priorityNode_) {
+ fb.core.snap.validatePriorityNode(this.priorityNode_);
+ }
+ if (children.isEmpty()) {
+ fb.core.util.assert(!this.priorityNode_ || this.priorityNode_.isEmpty(), "An empty node cannot have a priority");
+ }
+ this.indexMap_ = indexMap;
+ this.lazyHash_ = null;
+};
+fb.core.snap.ChildrenNode.prototype.isLeafNode = function() {
+ return false;
+};
+fb.core.snap.ChildrenNode.prototype.getPriority = function() {
+ return this.priorityNode_ || fb.core.snap.EMPTY_NODE;
+};
+fb.core.snap.ChildrenNode.prototype.updatePriority = function(newPriorityNode) {
+ if (this.children_.isEmpty()) {
+ return this;
+ } else {
+ return new fb.core.snap.ChildrenNode(this.children_, newPriorityNode, this.indexMap_);
+ }
+};
+fb.core.snap.ChildrenNode.prototype.getImmediateChild = function(childName) {
+ if (childName === ".priority") {
+ return this.getPriority();
+ } else {
+ var child = this.children_.get(childName);
+ return child === null ? fb.core.snap.EMPTY_NODE : child;
+ }
+};
+fb.core.snap.ChildrenNode.prototype.getChild = function(path) {
+ var front = path.getFront();
+ if (front === null) {
+ return this;
+ }
+ return this.getImmediateChild(front).getChild(path.popFront());
+};
+fb.core.snap.ChildrenNode.prototype.hasChild = function(childName) {
+ return this.children_.get(childName) !== null;
+};
+fb.core.snap.ChildrenNode.prototype.updateImmediateChild = function(childName, newChildNode) {
+ fb.core.util.assert(newChildNode, "We should always be passing snapshot nodes");
+ if (childName === ".priority") {
+ return this.updatePriority(newChildNode);
+ } else {
+ var namedNode = new fb.core.snap.NamedNode(childName, newChildNode);
+ var newChildren, newIndexMap, newPriority;
+ if (newChildNode.isEmpty()) {
+ newChildren = this.children_.remove(childName);
+ newIndexMap = this.indexMap_.removeFromIndexes(namedNode, this.children_);
+ } else {
+ newChildren = this.children_.insert(childName, newChildNode);
+ newIndexMap = this.indexMap_.addToIndexes(namedNode, this.children_);
+ }
+ newPriority = newChildren.isEmpty() ? fb.core.snap.EMPTY_NODE : this.priorityNode_;
+ return new fb.core.snap.ChildrenNode(newChildren, newPriority, newIndexMap);
+ }
+};
+fb.core.snap.ChildrenNode.prototype.updateChild = function(path, newChildNode) {
+ var front = path.getFront();
+ if (front === null) {
+ return newChildNode;
+ } else {
+ fb.core.util.assert(path.getFront() !== ".priority" || path.getLength() === 1, ".priority must be the last token in a path");
+ var newImmediateChild = this.getImmediateChild(front).updateChild(path.popFront(), newChildNode);
+ return this.updateImmediateChild(front, newImmediateChild);
+ }
+};
+fb.core.snap.ChildrenNode.prototype.isEmpty = function() {
+ return this.children_.isEmpty();
+};
+fb.core.snap.ChildrenNode.prototype.numChildren = function() {
+ return this.children_.count();
+};
+fb.core.snap.ChildrenNode.INTEGER_REGEXP_ = /^(0|[1-9]\d*)$/;
+fb.core.snap.ChildrenNode.prototype.val = function(opt_exportFormat) {
+ if (this.isEmpty()) {
+ return null;
+ }
+ var obj = {};
+ var numKeys = 0, maxKey = 0, allIntegerKeys = true;
+ this.forEachChild(fb.core.snap.PriorityIndex, function(key, childNode) {
+ obj[key] = childNode.val(opt_exportFormat);
+ numKeys++;
+ if (allIntegerKeys && fb.core.snap.ChildrenNode.INTEGER_REGEXP_.test(key)) {
+ maxKey = Math.max(maxKey, Number(key));
+ } else {
+ allIntegerKeys = false;
+ }
+ });
+ if (!opt_exportFormat && allIntegerKeys && maxKey < 2 * numKeys) {
+ var array = [];
+ for (var key in obj) {
+ array[key] = obj[key];
+ }
+ return array;
+ } else {
+ if (opt_exportFormat && !this.getPriority().isEmpty()) {
+ obj[".priority"] = this.getPriority().val();
+ }
+ return obj;
+ }
+};
+fb.core.snap.ChildrenNode.prototype.hash = function() {
+ if (this.lazyHash_ === null) {
+ var toHash = "";
+ if (!this.getPriority().isEmpty()) {
+ toHash += "priority:" + fb.core.snap.priorityHashText((this.getPriority().val())) + ":";
+ }
+ this.forEachChild(fb.core.snap.PriorityIndex, function(key, childNode) {
+ var childHash = childNode.hash();
+ if (childHash !== "") {
+ toHash += ":" + key + ":" + childHash;
+ }
+ });
+ this.lazyHash_ = toHash === "" ? "" : fb.core.util.sha1(toHash);
+ }
+ return this.lazyHash_;
+};
+fb.core.snap.ChildrenNode.prototype.getPredecessorChildName = function(childName, childNode, index) {
+ var idx = this.resolveIndex_(index);
+ if (idx) {
+ var predecessor = idx.getPredecessorKey(new fb.core.snap.NamedNode(childName, childNode));
+ return predecessor ? predecessor.name : null;
+ } else {
+ return this.children_.getPredecessorKey(childName);
+ }
+};
+fb.core.snap.ChildrenNode.prototype.getFirstChildName = function(indexDefinition) {
+ var idx = this.resolveIndex_(indexDefinition);
+ if (idx) {
+ var minKey = idx.minKey();
+ return minKey && minKey.name;
+ } else {
+ return this.children_.minKey();
+ }
+};
+fb.core.snap.ChildrenNode.prototype.getFirstChild = function(indexDefinition) {
+ var minKey = this.getFirstChildName(indexDefinition);
+ if (minKey) {
+ return new fb.core.snap.NamedNode(minKey, this.children_.get(minKey));
+ } else {
+ return null;
+ }
+};
+fb.core.snap.ChildrenNode.prototype.getLastChildName = function(indexDefinition) {
+ var idx = this.resolveIndex_(indexDefinition);
+ if (idx) {
+ var maxKey = idx.maxKey();
+ return maxKey && maxKey.name;
+ } else {
+ return this.children_.maxKey();
+ }
+};
+fb.core.snap.ChildrenNode.prototype.getLastChild = function(indexDefinition) {
+ var maxKey = this.getLastChildName(indexDefinition);
+ if (maxKey) {
+ return new fb.core.snap.NamedNode(maxKey, this.children_.get(maxKey));
+ } else {
+ return null;
+ }
+};
+fb.core.snap.ChildrenNode.prototype.forEachChild = function(index, action) {
+ var idx = this.resolveIndex_(index);
+ if (idx) {
+ return idx.inorderTraversal(function(wrappedNode) {
+ return action(wrappedNode.name, wrappedNode.node);
+ });
+ } else {
+ return this.children_.inorderTraversal(action);
+ }
+};
+fb.core.snap.ChildrenNode.prototype.getIterator = function(indexDefinition) {
+ return this.getIteratorFrom(indexDefinition.minPost(), indexDefinition);
+};
+fb.core.snap.ChildrenNode.prototype.getIteratorFrom = function(startPost, indexDefinition) {
+ var idx = this.resolveIndex_(indexDefinition);
+ if (idx) {
+ return idx.getIteratorFrom(startPost, function(key) {
+ return key;
+ });
+ } else {
+ var iterator = this.children_.getIteratorFrom(startPost.name, fb.core.snap.NamedNode.Wrap);
+ var next = iterator.peek();
+ while (next != null && indexDefinition.compare(next, startPost) < 0) {
+ iterator.getNext();
+ next = iterator.peek();
+ }
+ return iterator;
+ }
+};
+fb.core.snap.ChildrenNode.prototype.getReverseIterator = function(indexDefinition) {
+ return this.getReverseIteratorFrom(indexDefinition.maxPost(), indexDefinition);
+};
+fb.core.snap.ChildrenNode.prototype.getReverseIteratorFrom = function(endPost, indexDefinition) {
+ var idx = this.resolveIndex_(indexDefinition);
+ if (idx) {
+ return idx.getReverseIteratorFrom(endPost, function(key) {
+ return key;
+ });
+ } else {
+ var iterator = this.children_.getReverseIteratorFrom(endPost.name, fb.core.snap.NamedNode.Wrap);
+ var next = iterator.peek();
+ while (next != null && indexDefinition.compare(next, endPost) > 0) {
+ iterator.getNext();
+ next = iterator.peek();
+ }
+ return iterator;
+ }
+};
+fb.core.snap.ChildrenNode.prototype.compareTo = function(other) {
+ if (this.isEmpty()) {
+ if (other.isEmpty()) {
+ return 0;
+ } else {
+ return-1;
+ }
+ } else {
+ if (other.isLeafNode() || other.isEmpty()) {
+ return 1;
+ } else {
+ if (other === fb.core.snap.MAX_NODE) {
+ return-1;
+ } else {
+ return 0;
+ }
+ }
+ }
+};
+fb.core.snap.ChildrenNode.prototype.withIndex = function(indexDefinition) {
+ if (indexDefinition === fb.core.snap.KeyIndex || this.indexMap_.hasIndex(indexDefinition)) {
+ return this;
+ } else {
+ var newIndexMap = this.indexMap_.addIndex(indexDefinition, this.children_);
+ return new fb.core.snap.ChildrenNode(this.children_, this.priorityNode_, newIndexMap);
+ }
+};
+fb.core.snap.ChildrenNode.prototype.isIndexed = function(index) {
+ return index === fb.core.snap.KeyIndex || this.indexMap_.hasIndex(index);
+};
+fb.core.snap.ChildrenNode.prototype.equals = function(other) {
+ if (other === this) {
+ return true;
+ } else {
+ if (other.isLeafNode()) {
+ return false;
+ } else {
+ var otherChildrenNode = (other);
+ if (!this.getPriority().equals(otherChildrenNode.getPriority())) {
+ return false;
+ } else {
+ if (this.children_.count() === otherChildrenNode.children_.count()) {
+ var thisIter = this.getIterator(fb.core.snap.PriorityIndex);
+ var otherIter = otherChildrenNode.getIterator(fb.core.snap.PriorityIndex);
+ var thisCurrent = thisIter.getNext();
+ var otherCurrent = otherIter.getNext();
+ while (thisCurrent && otherCurrent) {
+ if (thisCurrent.name !== otherCurrent.name || !thisCurrent.node.equals(otherCurrent.node)) {
+ return false;
+ }
+ thisCurrent = thisIter.getNext();
+ otherCurrent = otherIter.getNext();
+ }
+ return thisCurrent === null && otherCurrent === null;
+ } else {
+ return false;
+ }
+ }
+ }
+ }
+};
+fb.core.snap.ChildrenNode.prototype.resolveIndex_ = function(indexDefinition) {
+ if (indexDefinition === fb.core.snap.KeyIndex) {
+ return null;
+ } else {
+ return this.indexMap_.get(indexDefinition.toString());
+ }
+};
+if (goog.DEBUG) {
+ fb.core.snap.ChildrenNode.prototype.toString = function() {
+ return fb.util.json.stringify(this.val(true));
+ };
+}
+;goog.provide("fb.core.snap");
+goog.require("fb.core.snap.ChildrenNode");
+goog.require("fb.core.snap.IndexMap");
+goog.require("fb.core.snap.LeafNode");
+goog.require("fb.core.util");
+var USE_HINZE = true;
+fb.core.snap.NodeFromJSON = function(json, opt_priority) {
+ if (json === null) {
+ return fb.core.snap.EMPTY_NODE;
+ }
+ var priority = null;
+ if (typeof json === "object" && ".priority" in json) {
+ priority = json[".priority"];
+ } else {
+ if (typeof opt_priority !== "undefined") {
+ priority = opt_priority;
+ }
+ }
+ fb.core.util.assert(priority === null || typeof priority === "string" || typeof priority === "number" || typeof priority === "object" && ".sv" in priority, "Invalid priority type found: " + typeof priority);
+ if (typeof json === "object" && ".value" in json && json[".value"] !== null) {
+ json = json[".value"];
+ }
+ if (typeof json !== "object" || ".sv" in json) {
+ var jsonLeaf = (json);
+ return new fb.core.snap.LeafNode(jsonLeaf, fb.core.snap.NodeFromJSON(priority));
+ }
+ if (!(json instanceof Array) && USE_HINZE) {
+ var children = [];
+ var childrenHavePriority = false;
+ var hinzeJsonObj = (json);
+ fb.util.obj.foreach(hinzeJsonObj, function(key, child) {
+ if (typeof key !== "string" || key.substring(0, 1) !== ".") {
+ var childNode = fb.core.snap.NodeFromJSON(hinzeJsonObj[key]);
+ if (!childNode.isEmpty()) {
+ childrenHavePriority = childrenHavePriority || !childNode.getPriority().isEmpty();
+ children.push(new fb.core.snap.NamedNode(key, childNode));
+ }
+ }
+ });
+ if (children.length == 0) {
+ return fb.core.snap.EMPTY_NODE;
+ }
+ var childSet = (fb.core.snap.buildChildSet(children, fb.core.snap.NAME_ONLY_COMPARATOR, function(namedNode) {
+ return namedNode.name;
+ }, fb.core.snap.NAME_COMPARATOR));
+ if (childrenHavePriority) {
+ var sortedChildSet = fb.core.snap.buildChildSet(children, fb.core.snap.PriorityIndex.getCompare());
+ return new fb.core.snap.ChildrenNode(childSet, fb.core.snap.NodeFromJSON(priority), new fb.core.snap.IndexMap({".priority":sortedChildSet}, {".priority":fb.core.snap.PriorityIndex}));
+ } else {
+ return new fb.core.snap.ChildrenNode(childSet, fb.core.snap.NodeFromJSON(priority), fb.core.snap.IndexMap.Default);
+ }
+ } else {
+ var node = fb.core.snap.EMPTY_NODE;
+ var jsonObj = (json);
+ goog.object.forEach(jsonObj, function(childData, key) {
+ if (fb.util.obj.contains(jsonObj, key)) {
+ if (key.substring(0, 1) !== ".") {
+ var childNode = fb.core.snap.NodeFromJSON(childData);
+ if (childNode.isLeafNode() || !childNode.isEmpty()) {
+ node = node.updateImmediateChild(key, childNode);
+ }
+ }
+ }
+ });
+ return node.updatePriority(fb.core.snap.NodeFromJSON(priority));
+ }
+};
+var LOG_2 = Math.log(2);
+fb.core.snap.Base12Num = function(length) {
+ var logBase2 = function(num) {
+ return parseInt(Math.log(num) / LOG_2, 10);
+ };
+ var bitMask = function(bits) {
+ return parseInt(Array(bits + 1).join("1"), 2);
+ };
+ this.count = logBase2(length + 1);
+ this.current_ = this.count - 1;
+ var mask = bitMask(this.count);
+ this.bits_ = length + 1 & mask;
+};
+fb.core.snap.Base12Num.prototype.nextBitIsOne = function() {
+ var result = !(this.bits_ & 1 << this.current_);
+ this.current_--;
+ return result;
+};
+fb.core.snap.buildChildSet = function(childList, cmp, keyFn, mapSortFn) {
+ childList.sort(cmp);
+ var buildBalancedTree = function(low, high) {
+ var length = high - low;
+ if (length == 0) {
+ return null;
+ } else {
+ if (length == 1) {
+ var namedNode = childList[low];
+ var key = keyFn ? keyFn(namedNode) : namedNode;
+ return new fb.LLRBNode(key, namedNode.node, fb.LLRBNode.BLACK, null, null);
+ } else {
+ var middle = parseInt(length / 2, 10) + low;
+ var left = buildBalancedTree(low, middle);
+ var right = buildBalancedTree(middle + 1, high);
+ namedNode = childList[middle];
+ key = keyFn ? keyFn(namedNode) : namedNode;
+ return new fb.LLRBNode(key, namedNode.node, fb.LLRBNode.BLACK, left, right);
+ }
+ }
+ };
+ var buildFrom12Array = function(base12) {
+ var node = null;
+ var root = null;
+ var index = childList.length;
+ var buildPennant = function(chunkSize, color) {
+ var low = index - chunkSize;
+ var high = index;
+ index -= chunkSize;
+ var childTree = buildBalancedTree(low + 1, high);
+ var namedNode = childList[low];
+ var key = keyFn ? keyFn(namedNode) : namedNode;
+ attachPennant(new fb.LLRBNode(key, namedNode.node, color, null, childTree));
+ };
+ var attachPennant = function(pennant) {
+ if (node) {
+ node.left = pennant;
+ node = pennant;
+ } else {
+ root = pennant;
+ node = pennant;
+ }
+ };
+ for (var i = 0;i < base12.count;++i) {
+ var isOne = base12.nextBitIsOne();
+ var chunkSize = Math.pow(2, base12.count - (i + 1));
+ if (isOne) {
+ buildPennant(chunkSize, fb.LLRBNode.BLACK);
+ } else {
+ buildPennant(chunkSize, fb.LLRBNode.BLACK);
+ buildPennant(chunkSize, fb.LLRBNode.RED);
+ }
+ }
+ return root;
+ };
+ var base12 = new fb.core.snap.Base12Num(childList.length);
+ var root = buildFrom12Array(base12);
+ if (root !== null) {
+ return new fb.core.util.SortedMap(mapSortFn || cmp, root);
+ } else {
+ return new fb.core.util.SortedMap(mapSortFn || cmp);
+ }
+};
+fb.core.snap.priorityHashText = function(priority) {
+ if (typeof priority === "number") {
+ return "number:" + fb.core.util.doubleToIEEE754String(priority);
+ } else {
+ return "string:" + priority;
+ }
+};
+fb.core.snap.validatePriorityNode = function(priorityNode) {
+ if (priorityNode.isLeafNode()) {
+ var val = priorityNode.val();
+ fb.core.util.assert(typeof val === "string" || typeof val === "number" || typeof val === "object" && fb.util.obj.contains(val, ".sv"), "Priority must be a string or number.");
+ } else {
+ fb.core.util.assert(priorityNode === fb.core.snap.MAX_NODE || priorityNode.isEmpty(), "priority of unexpected type.");
+ }
+ fb.core.util.assert(priorityNode === fb.core.snap.MAX_NODE || priorityNode.getPriority().isEmpty(), "Priority nodes can't have a priority of their own.");
+};
+fb.core.snap.EMPTY_NODE = new fb.core.snap.ChildrenNode(new fb.core.util.SortedMap(fb.core.snap.NAME_COMPARATOR), null, fb.core.snap.IndexMap.Default);
+fb.core.snap.MAX_NODE_ = function() {
+ fb.core.snap.ChildrenNode.call(this, new fb.core.util.SortedMap(fb.core.snap.NAME_COMPARATOR), fb.core.snap.EMPTY_NODE, fb.core.snap.IndexMap.Default);
+};
+goog.inherits(fb.core.snap.MAX_NODE_, fb.core.snap.ChildrenNode);
+fb.core.snap.MAX_NODE_.prototype.compareTo = function(other) {
+ if (other === this) {
+ return 0;
+ } else {
+ return 1;
+ }
+};
+fb.core.snap.MAX_NODE_.prototype.equals = function(other) {
+ return other === this;
+};
+fb.core.snap.MAX_NODE_.prototype.getPriority = function() {
+ return this;
+};
+fb.core.snap.MAX_NODE_.prototype.getImmediateChild = function(childName) {
+ return fb.core.snap.EMPTY_NODE;
+};
+fb.core.snap.MAX_NODE_.prototype.isEmpty = function() {
+ return false;
+};
+fb.core.snap.MAX_NODE = new fb.core.snap.MAX_NODE_;
+fb.core.snap.NamedNode.MIN = new fb.core.snap.NamedNode(fb.core.util.MIN_NAME, fb.core.snap.EMPTY_NODE);
+fb.core.snap.NamedNode.MAX = new fb.core.snap.NamedNode(fb.core.util.MAX_NAME, fb.core.snap.MAX_NODE);
+goog.provide("fb.core.view.ViewCache");
+goog.require("fb.core.view.CacheNode");
+goog.require("fb.core.snap");
+fb.core.view.ViewCache = function(eventCache, serverCache) {
+ this.eventCache_ = eventCache;
+ this.serverCache_ = serverCache;
+};
+fb.core.view.ViewCache.Empty = new fb.core.view.ViewCache(new fb.core.view.CacheNode(fb.core.snap.EMPTY_NODE, false, false), new fb.core.view.CacheNode(fb.core.snap.EMPTY_NODE, false, false));
+fb.core.view.ViewCache.prototype.updateEventSnap = function(eventSnap, complete, filtered) {
+ return new fb.core.view.ViewCache(new fb.core.view.CacheNode(eventSnap, complete, filtered), this.serverCache_);
+};
+fb.core.view.ViewCache.prototype.updateServerSnap = function(serverSnap, complete, filtered) {
+ return new fb.core.view.ViewCache(this.eventCache_, new fb.core.view.CacheNode(serverSnap, complete, filtered));
+};
+fb.core.view.ViewCache.prototype.getEventCache = function() {
+ return this.eventCache_;
+};
+fb.core.view.ViewCache.prototype.getCompleteEventSnap = function() {
+ return this.eventCache_.isFullyInitialized() ? this.eventCache_.getNode() : null;
+};
+fb.core.view.ViewCache.prototype.getServerCache = function() {
+ return this.serverCache_;
+};
+fb.core.view.ViewCache.prototype.getCompleteServerSnap = function() {
+ return this.serverCache_.isFullyInitialized() ? this.serverCache_.getNode() : null;
+};
+goog.provide("fb.core.view.View");
+goog.require("fb.core.view.EventGenerator");
+goog.require("fb.core.view.ViewCache");
+goog.require("fb.core.view.ViewProcessor");
+goog.require("fb.core.util");
+fb.core.view.View = function(query, initialViewCache) {
+ this.query_ = query;
+ var params = query.getQueryParams();
+ var indexFilter = new fb.core.view.filter.IndexedFilter(params.getIndex());
+ var filter = params.getNodeFilter();
+ this.processor_ = new fb.core.view.ViewProcessor(filter);
+ var initialServerCache = initialViewCache.getServerCache();
+ var initialEventCache = initialViewCache.getEventCache();
+ var serverSnap = indexFilter.updateFullNode(fb.core.snap.EMPTY_NODE, initialServerCache.getNode(), null);
+ var eventSnap = filter.updateFullNode(fb.core.snap.EMPTY_NODE, initialEventCache.getNode(), null);
+ var newServerCache = new fb.core.view.CacheNode(serverSnap, initialServerCache.isFullyInitialized(), indexFilter.filtersNodes());
+ var newEventCache = new fb.core.view.CacheNode(eventSnap, initialEventCache.isFullyInitialized(), filter.filtersNodes());
+ this.viewCache_ = new fb.core.view.ViewCache(newEventCache, newServerCache);
+ this.eventRegistrations_ = [];
+ this.eventGenerator_ = new fb.core.view.EventGenerator(query);
+};
+fb.core.view.View.prototype.getQuery = function() {
+ return this.query_;
+};
+fb.core.view.View.prototype.getServerCache = function() {
+ return this.viewCache_.getServerCache().getNode();
+};
+fb.core.view.View.prototype.getCompleteServerCache = function(path) {
+ var cache = this.viewCache_.getCompleteServerSnap();
+ if (cache) {
+ if (this.query_.getQueryParams().loadsAllData() || !path.isEmpty() && !cache.getImmediateChild(path.getFront()).isEmpty()) {
+ return cache.getChild(path);
+ }
+ }
+ return null;
+};
+fb.core.view.View.prototype.isEmpty = function() {
+ return this.eventRegistrations_.length === 0;
+};
+fb.core.view.View.prototype.addEventRegistration = function(eventRegistration) {
+ this.eventRegistrations_.push(eventRegistration);
+};
+fb.core.view.View.prototype.removeEventRegistration = function(eventRegistration, cancelError) {
+ var cancelEvents = [];
+ if (cancelError) {
+ fb.core.util.assert(eventRegistration == null, "A cancel should cancel all event registrations.");
+ var path = this.query_.path;
+ goog.array.forEach(this.eventRegistrations_, function(registration) {
+ cancelError = (cancelError);
+ var maybeEvent = registration.createCancelEvent(cancelError, path);
+ if (maybeEvent) {
+ cancelEvents.push(maybeEvent);
+ }
+ });
+ }
+ if (eventRegistration) {
+ var remaining = [];
+ for (var i = 0;i < this.eventRegistrations_.length;++i) {
+ var existing = this.eventRegistrations_[i];
+ if (!existing.matches(eventRegistration)) {
+ remaining.push(existing);
+ } else {
+ if (eventRegistration.hasAnyCallback()) {
+ remaining = remaining.concat(this.eventRegistrations_.slice(i + 1));
+ break;
+ }
+ }
+ }
+ this.eventRegistrations_ = remaining;
+ } else {
+ this.eventRegistrations_ = [];
+ }
+ return cancelEvents;
+};
+fb.core.view.View.prototype.applyOperation = function(operation, writesCache, optCompleteServerCache) {
+ if (operation.type === fb.core.OperationType.MERGE && operation.source.queryId !== null) {
+ fb.core.util.assert(this.viewCache_.getCompleteServerSnap(), "We should always have a full cache before handling merges");
+ fb.core.util.assert(this.viewCache_.getCompleteEventSnap(), "Missing event cache, even though we have a server cache");
+ }
+ var oldViewCache = this.viewCache_;
+ var result = this.processor_.applyOperation(oldViewCache, operation, writesCache, optCompleteServerCache);
+ this.processor_.assertIndexed(result.viewCache);
+ fb.core.util.assert(result.viewCache.getServerCache().isFullyInitialized() || !oldViewCache.getServerCache().isFullyInitialized(), "Once a server snap is complete, it should never go back");
+ this.viewCache_ = result.viewCache;
+ return this.generateEventsForChanges_(result.changes, result.viewCache.getEventCache().getNode(), null);
+};
+fb.core.view.View.prototype.getInitialEvents = function(registration) {
+ var eventSnap = this.viewCache_.getEventCache();
+ var initialChanges = [];
+ if (!eventSnap.getNode().isLeafNode()) {
+ var eventNode = (eventSnap.getNode());
+ eventNode.forEachChild(fb.core.snap.PriorityIndex, function(key, childNode) {
+ initialChanges.push(fb.core.view.Change.childAddedChange(key, childNode));
+ });
+ }
+ if (eventSnap.isFullyInitialized()) {
+ initialChanges.push(fb.core.view.Change.valueChange(eventSnap.getNode()));
+ }
+ return this.generateEventsForChanges_(initialChanges, eventSnap.getNode(), registration);
+};
+fb.core.view.View.prototype.generateEventsForChanges_ = function(changes, eventCache, opt_eventRegistration) {
+ var registrations = opt_eventRegistration ? [opt_eventRegistration] : this.eventRegistrations_;
+ return this.eventGenerator_.generateEventsForChanges(changes, eventCache, registrations);
+};
+goog.provide("fb.core.operation.Merge");
+goog.require("fb.core.util");
+fb.core.operation.Merge = function(source, path, children) {
+ this.type = fb.core.OperationType.MERGE;
+ this.source = source;
+ this.path = path;
+ this.children = children;
+};
+fb.core.operation.Merge.prototype.operationForChild = function(childName) {
+ if (this.path.isEmpty()) {
+ var childTree = this.children.subtree(new fb.core.util.Path(childName));
+ if (childTree.isEmpty()) {
+ return null;
+ } else {
+ if (childTree.value) {
+ return new fb.core.operation.Overwrite(this.source, fb.core.util.Path.Empty, childTree.value);
+ } else {
+ return new fb.core.operation.Merge(this.source, fb.core.util.Path.Empty, childTree);
+ }
+ }
+ } else {
+ fb.core.util.assert(this.path.getFront() === childName, "Can't get a merge for a child not on the path of the operation");
+ return new fb.core.operation.Merge(this.source, this.path.popFront(), this.children);
+ }
+};
+if (goog.DEBUG) {
+ fb.core.operation.Merge.prototype.toString = function() {
+ return "Operation(" + this.path + ": " + this.source.toString() + " merge: " + this.children.toString() + ")";
+ };
+}
+;goog.provide("fb.core.Operation");
+goog.require("fb.core.operation.AckUserWrite");
+goog.require("fb.core.operation.Merge");
+goog.require("fb.core.operation.Overwrite");
+goog.require("fb.core.operation.ListenComplete");
+goog.require("fb.core.util");
+fb.core.OperationType = {OVERWRITE:0, MERGE:1, ACK_USER_WRITE:2, LISTEN_COMPLETE:3};
+fb.core.Operation = function() {
+};
+fb.core.Operation.prototype.source;
+fb.core.Operation.prototype.type;
+fb.core.Operation.prototype.path;
+fb.core.Operation.prototype.operationForChild = goog.abstractMethod;
+fb.core.OperationSource = function(fromUser, fromServer, queryId, tagged) {
+ this.fromUser = fromUser;
+ this.fromServer = fromServer;
+ this.queryId = queryId;
+ this.tagged = tagged;
+ fb.core.util.assert(!tagged || fromServer, "Tagged queries must be from server.");
+};
+fb.core.OperationSource.User = new fb.core.OperationSource(true, false, null, false);
+fb.core.OperationSource.Server = new fb.core.OperationSource(false, true, null, false);
+fb.core.OperationSource.forServerTaggedQuery = function(queryId) {
+ return new fb.core.OperationSource(false, true, queryId, true);
+};
+if (goog.DEBUG) {
+ fb.core.OperationSource.prototype.toString = function() {
+ return this.fromUser ? "user" : this.tagged ? "server(queryID=" + this.queryId + ")" : "server";
+ };
+}
+;goog.provide("fb.core.ReadonlyRestClient");
+goog.require("fb.core.util");
+goog.require("fb.util");
+goog.require("fb.util.json");
+goog.require("fb.util.jwt");
+goog.require("fb.util.obj");
+fb.core.ReadonlyRestClient = goog.defineClass(null, {constructor:function(repoInfo, onDataUpdate) {
+ this.log_ = fb.core.util.logWrapper("p:rest:");
+ this.repoInfo_ = repoInfo;
+ this.onDataUpdate_ = onDataUpdate;
+ this.credential_ = null;
+ this.listens_ = {};
+}, listen:function(query, currentHashFn, tag, onComplete) {
+ var pathString = query.path.toString();
+ this.log_("Listen called for " + pathString + " " + query.queryIdentifier());
+ var listenId = fb.core.ReadonlyRestClient.getListenId_(query, tag);
+ var thisListen = new Object;
+ this.listens_[listenId] = thisListen;
+ var queryStringParamaters = query.getQueryParams().toRestQueryStringParameters();
+ var self = this;
+ this.restRequest_(pathString + ".json", queryStringParamaters, function(error, result) {
+ var data = result;
+ if (error === 404) {
+ data = null;
+ error = null;
+ }
+ if (error === null) {
+ self.onDataUpdate_(pathString, data, false, tag);
+ }
+ if (fb.util.obj.get(self.listens_, listenId) === thisListen) {
+ var status;
+ if (!error) {
+ status = "ok";
+ } else {
+ if (error == 401) {
+ status = "permission_denied";
+ } else {
+ status = "rest_error:" + error;
+ }
+ }
+ onComplete(status, null);
+ }
+ });
+}, unlisten:function(query, tag) {
+ var listenId = fb.core.ReadonlyRestClient.getListenId_(query, tag);
+ delete this.listens_[listenId];
+}, auth:function(cred, opt_callback, opt_cancelCallback) {
+ this.credential_ = cred;
+ var res = fb.util.jwt.decode(cred);
+ var auth = res.data;
+ var expires = res.claims && res.claims["exp"];
+ if (opt_callback) {
+ opt_callback("ok", {"auth":auth, "expires":expires});
+ }
+}, unauth:function(onComplete) {
+ this.credential_ = null;
+ onComplete("ok", null);
+}, onDisconnectPut:function(pathString, data, opt_onComplete) {
+}, onDisconnectMerge:function(pathString, data, opt_onComplete) {
+}, onDisconnectCancel:function(pathString, opt_onComplete) {
+}, put:function(pathString, data, opt_onComplete, opt_hash) {
+}, merge:function(pathString, data, onComplete, opt_hash) {
+}, reportStats:function(stats) {
+}, restRequest_:function(pathString, queryStringParameters, callback) {
+ queryStringParameters = queryStringParameters || {};
+ queryStringParameters["format"] = "export";
+ if (this.credential_) {
+ queryStringParameters["auth"] = this.credential_;
+ }
+ var url = (this.repoInfo_.secure ? "https://" : "http://") + this.repoInfo_.host + pathString + "?" + fb.util.querystring(queryStringParameters);
+ this.log_("Sending REST request for " + url);
+ var xhr = new XMLHttpRequest;
+ var self = this;
+ xhr.onreadystatechange = function() {
+ if (callback && xhr.readyState === 4) {
+ self.log_("REST Response for " + url + " received. status:", xhr.status, "response:", xhr.responseText);
+ var res = null;
+ if (xhr.status >= 200 && xhr.status < 300) {
+ try {
+ res = fb.util.json.eval(xhr.responseText);
+ } catch (e) {
+ fb.core.util.warn("Failed to parse JSON response for " + url + ": " + xhr.responseText);
+ }
+ callback(null, res);
+ } else {
+ if (xhr.status !== 401 && xhr.status !== 404) {
+ fb.core.util.warn("Got unsuccessful REST response for " + url + " Status: " + xhr.status);
+ }
+ callback(xhr.status);
+ }
+ callback = null;
+ }
+ };
+ xhr.open("GET", url, true);
+ xhr.send();
+}, statics:{getListenId_:function(query, opt_tag) {
+ if (goog.isDef(opt_tag)) {
+ return "tag$" + opt_tag;
+ } else {
+ fb.core.util.assert(query.getQueryParams().isDefault(), "should have a tag if it's not a default query.");
+ return query.path.toString();
+ }
+}}});
+goog.provide("fb.core.util.ImmutableTree");
+goog.require("fb.core.util");
+goog.require("fb.core.util.Path");
+goog.require("fb.core.util.SortedMap");
+goog.require("fb.util.json");
+goog.require("fb.util.obj");
+goog.require("goog.object");
+fb.core.util.ImmutableTree = goog.defineClass(null, {constructor:function(value, opt_children) {
+ this.value = value;
+ this.children = opt_children || fb.core.util.ImmutableTree.EmptyChildren_;
+}, statics:{EmptyChildren_:new fb.core.util.SortedMap(fb.core.util.stringCompare), fromObject:function(obj) {
+ var tree = fb.core.util.ImmutableTree.Empty;
+ goog.object.forEach(obj, function(childSnap, childPath) {
+ tree = tree.set(new fb.core.util.Path(childPath), childSnap);
+ });
+ return tree;
+}}, isEmpty:function() {
+ return this.value === null && this.children.isEmpty();
+}, findRootMostMatchingPathAndValue:function(relativePath, predicate) {
+ if (this.value != null && predicate(this.value)) {
+ return{path:fb.core.util.Path.Empty, value:this.value};
+ } else {
+ if (relativePath.isEmpty()) {
+ return null;
+ } else {
+ var front = relativePath.getFront();
+ var child = this.children.get(front);
+ if (child !== null) {
+ var childExistingPathAndValue = child.findRootMostMatchingPathAndValue(relativePath.popFront(), predicate);
+ if (childExistingPathAndValue != null) {
+ var fullPath = (new fb.core.util.Path(front)).child(childExistingPathAndValue.path);
+ return{path:fullPath, value:childExistingPathAndValue.value};
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+ }
+}, findRootMostValueAndPath:function(relativePath) {
+ return this.findRootMostMatchingPathAndValue(relativePath, function() {
+ return true;
+ });
+}, subtree:function(relativePath) {
+ if (relativePath.isEmpty()) {
+ return this;
+ } else {
+ var front = relativePath.getFront();
+ var childTree = this.children.get(front);
+ if (childTree !== null) {
+ return childTree.subtree(relativePath.popFront());
+ } else {
+ return fb.core.util.ImmutableTree.Empty;
+ }
+ }
+}, set:function(relativePath, toSet) {
+ if (relativePath.isEmpty()) {
+ return new fb.core.util.ImmutableTree(toSet, this.children);
+ } else {
+ var front = relativePath.getFront();
+ var child = this.children.get(front) || fb.core.util.ImmutableTree.Empty;
+ var newChild = child.set(relativePath.popFront(), toSet);
+ var newChildren = this.children.insert(front, newChild);
+ return new fb.core.util.ImmutableTree(this.value, newChildren);
+ }
+}, remove:function(relativePath) {
+ if (relativePath.isEmpty()) {
+ if (this.children.isEmpty()) {
+ return fb.core.util.ImmutableTree.Empty;
+ } else {
+ return new fb.core.util.ImmutableTree(null, this.children);
+ }
+ } else {
+ var front = relativePath.getFront();
+ var child = this.children.get(front);
+ if (child) {
+ var newChild = child.remove(relativePath.popFront());
+ var newChildren;
+ if (newChild.isEmpty()) {
+ newChildren = this.children.remove(front);
+ } else {
+ newChildren = this.children.insert(front, newChild);
+ }
+ if (this.value === null && newChildren.isEmpty()) {
+ return fb.core.util.ImmutableTree.Empty;
+ } else {
+ return new fb.core.util.ImmutableTree(this.value, newChildren);
+ }
+ } else {
+ return this;
+ }
+ }
+}, get:function(relativePath) {
+ if (relativePath.isEmpty()) {
+ return this.value;
+ } else {
+ var front = relativePath.getFront();
+ var child = this.children.get(front);
+ if (child) {
+ return child.get(relativePath.popFront());
+ } else {
+ return null;
+ }
+ }
+}, setTree:function(relativePath, newTree) {
+ if (relativePath.isEmpty()) {
+ return newTree;
+ } else {
+ var front = relativePath.getFront();
+ var child = this.children.get(front) || fb.core.util.ImmutableTree.Empty;
+ var newChild = child.setTree(relativePath.popFront(), newTree);
+ var newChildren;
+ if (newChild.isEmpty()) {
+ newChildren = this.children.remove(front);
+ } else {
+ newChildren = this.children.insert(front, newChild);
+ }
+ return new fb.core.util.ImmutableTree(this.value, newChildren);
+ }
+}, fold:function(fn) {
+ return this.fold_(fb.core.util.Path.Empty, fn);
+}, fold_:function(pathSoFar, fn) {
+ var accum = {};
+ this.children.inorderTraversal(function(childKey, childTree) {
+ accum[childKey] = childTree.fold_(pathSoFar.child(childKey), fn);
+ });
+ return fn(pathSoFar, this.value, accum);
+}, findOnPath:function(path, f) {
+ return this.findOnPath_(path, fb.core.util.Path.Empty, f);
+}, findOnPath_:function(pathToFollow, pathSoFar, f) {
+ var result = this.value ? f(pathSoFar, this.value) : false;
+ if (result) {
+ return result;
+ } else {
+ if (pathToFollow.isEmpty()) {
+ return null;
+ } else {
+ var front = pathToFollow.getFront();
+ var nextChild = this.children.get(front);
+ if (nextChild) {
+ return nextChild.findOnPath_(pathToFollow.popFront(), pathSoFar.child(front), f);
+ } else {
+ return null;
+ }
+ }
+ }
+}, foreachOnPathWhile:function(path, f) {
+ return this.foreachOnPathWhile_(path, fb.core.util.Path.Empty, f);
+}, foreachOnPathWhile_:function(pathToFollow, currentRelativePath, f) {
+ if (pathToFollow.isEmpty()) {
+ return currentRelativePath;
+ } else {
+ var shouldContinue = true;
+ if (this.value) {
+ shouldContinue = f(currentRelativePath, this.value);
+ }
+ if (shouldContinue === true) {
+ var front = pathToFollow.getFront();
+ var nextChild = this.children.get(front);
+ if (nextChild) {
+ return nextChild.foreachOnPath_(pathToFollow.popFront(), currentRelativePath.child(front), f);
+ } else {
+ return currentRelativePath;
+ }
+ } else {
+ return currentRelativePath;
+ }
+ }
+}, foreachOnPath:function(path, f) {
+ return this.foreachOnPath_(path, fb.core.util.Path.Empty, f);
+}, foreachOnPath_:function(pathToFollow, currentRelativePath, f) {
+ if (pathToFollow.isEmpty()) {
+ return this;
+ } else {
+ if (this.value) {
+ f(currentRelativePath, this.value);
+ }
+ var front = pathToFollow.getFront();
+ var nextChild = this.children.get(front);
+ if (nextChild) {
+ return nextChild.foreachOnPath_(pathToFollow.popFront(), currentRelativePath.child(front), f);
+ } else {
+ return fb.core.util.ImmutableTree.Empty;
+ }
+ }
+}, foreach:function(f) {
+ this.foreach_(fb.core.util.Path.Empty, f);
+}, foreach_:function(currentRelativePath, f) {
+ this.children.inorderTraversal(function(childName, childTree) {
+ childTree.foreach_(currentRelativePath.child(childName), f);
+ });
+ if (this.value) {
+ f(currentRelativePath, this.value);
+ }
+}, foreachChild:function(f) {
+ this.children.inorderTraversal(function(childName, childTree) {
+ if (childTree.value) {
+ f(childName, childTree.value);
+ }
+ });
+}});
+fb.core.util.ImmutableTree.Empty = new fb.core.util.ImmutableTree(null);
+if (goog.DEBUG) {
+ fb.core.util.ImmutableTree.prototype.toString = function() {
+ var json = {};
+ this.foreach(function(relativePath, value) {
+ var pathString = relativePath.toString();
+ json[pathString] = value.toString();
+ });
+ return fb.util.json.stringify(json);
+ };
+}
+;goog.provide("fb.core.CompoundWrite");
+goog.require("fb.core.snap.Node");
+goog.require("fb.core.util");
+goog.require("fb.core.util.ImmutableTree");
+fb.core.CompoundWrite = function(writeTree) {
+ this.writeTree_ = writeTree;
+};
+fb.core.CompoundWrite.Empty = new fb.core.CompoundWrite((new fb.core.util.ImmutableTree(null)));
+fb.core.CompoundWrite.prototype.addWrite = function(path, node) {
+ if (path.isEmpty()) {
+ return new fb.core.CompoundWrite(new fb.core.util.ImmutableTree(node));
+ } else {
+ var rootmost = this.writeTree_.findRootMostValueAndPath(path);
+ if (rootmost != null) {
+ var rootMostPath = rootmost.path, value = rootmost.value;
+ var relativePath = fb.core.util.Path.relativePath(rootMostPath, path);
+ value = value.updateChild(relativePath, node);
+ return new fb.core.CompoundWrite(this.writeTree_.set(rootMostPath, value));
+ } else {
+ var subtree = new fb.core.util.ImmutableTree(node);
+ var newWriteTree = this.writeTree_.setTree(path, subtree);
+ return new fb.core.CompoundWrite(newWriteTree);
+ }
+ }
+};
+fb.core.CompoundWrite.prototype.addWrites = function(path, updates) {
+ var newWrite = this;
+ fb.util.obj.foreach(updates, function(childKey, node) {
+ newWrite = newWrite.addWrite(path.child(childKey), node);
+ });
+ return newWrite;
+};
+fb.core.CompoundWrite.prototype.removeWrite = function(path) {
+ if (path.isEmpty()) {
+ return fb.core.CompoundWrite.Empty;
+ } else {
+ var newWriteTree = this.writeTree_.setTree(path, fb.core.util.ImmutableTree.Empty);
+ return new fb.core.CompoundWrite(newWriteTree);
+ }
+};
+fb.core.CompoundWrite.prototype.hasCompleteWrite = function(path) {
+ return this.getCompleteNode(path) != null;
+};
+fb.core.CompoundWrite.prototype.getCompleteNode = function(path) {
+ var rootmost = this.writeTree_.findRootMostValueAndPath(path);
+ if (rootmost != null) {
+ return this.writeTree_.get(rootmost.path).getChild(fb.core.util.Path.relativePath(rootmost.path, path));
+ } else {
+ return null;
+ }
+};
+fb.core.CompoundWrite.prototype.getCompleteChildren = function() {
+ var children = [];
+ var node = this.writeTree_.value;
+ if (node != null) {
+ if (!node.isLeafNode()) {
+ node = (node);
+ node.forEachChild(fb.core.snap.PriorityIndex, function(childName, childNode) {
+ children.push(new fb.core.snap.NamedNode(childName, childNode));
+ });
+ }
+ } else {
+ this.writeTree_.children.inorderTraversal(function(childName, childTree) {
+ if (childTree.value != null) {
+ children.push(new fb.core.snap.NamedNode(childName, childTree.value));
+ }
+ });
+ }
+ return children;
+};
+fb.core.CompoundWrite.prototype.childCompoundWrite = function(path) {
+ if (path.isEmpty()) {
+ return this;
+ } else {
+ var shadowingNode = this.getCompleteNode(path);
+ if (shadowingNode != null) {
+ return new fb.core.CompoundWrite(new fb.core.util.ImmutableTree(shadowingNode));
+ } else {
+ return new fb.core.CompoundWrite(this.writeTree_.subtree(path));
+ }
+ }
+};
+fb.core.CompoundWrite.prototype.isEmpty = function() {
+ return this.writeTree_.isEmpty();
+};
+fb.core.CompoundWrite.prototype.apply = function(node) {
+ return fb.core.CompoundWrite.applySubtreeWrite_(fb.core.util.Path.Empty, this.writeTree_, node);
+};
+fb.core.CompoundWrite.applySubtreeWrite_ = function(relativePath, writeTree, node) {
+ if (writeTree.value != null) {
+ return node.updateChild(relativePath, writeTree.value);
+ } else {
+ var priorityWrite = null;
+ writeTree.children.inorderTraversal(function(childKey, childTree) {
+ if (childKey === ".priority") {
+ fb.core.util.assert(childTree.value !== null, "Priority writes must always be leaf nodes");
+ priorityWrite = childTree.value;
+ } else {
+ node = fb.core.CompoundWrite.applySubtreeWrite_(relativePath.child(childKey), childTree, node);
+ }
+ });
+ if (!node.getChild(relativePath).isEmpty() && priorityWrite !== null) {
+ node = node.updateChild(relativePath.child(".priority"), (priorityWrite));
+ }
+ return node;
+ }
+};
+goog.provide("fb.core.WriteTree");
+goog.require("fb.core.CompoundWrite");
+goog.require("fb.core.util");
+goog.require("fb.core.view.CacheNode");
+fb.core.WriteRecord;
+fb.core.WriteTree = function() {
+ this.visibleWrites_ = (fb.core.CompoundWrite.Empty);
+ this.allWrites_ = [];
+ this.lastWriteId_ = -1;
+};
+fb.core.WriteTree.prototype.childWrites = function(path) {
+ return new fb.core.WriteTreeRef(path, this);
+};
+fb.core.WriteTree.prototype.addOverwrite = function(path, snap, writeId, visible) {
+ fb.core.util.assert(writeId > this.lastWriteId_, "Stacking an older write on top of newer ones");
+ if (!goog.isDef(visible)) {
+ visible = true;
+ }
+ this.allWrites_.push({path:path, snap:snap, writeId:writeId, visible:visible});
+ if (visible) {
+ this.visibleWrites_ = this.visibleWrites_.addWrite(path, snap);
+ }
+ this.lastWriteId_ = writeId;
+};
+fb.core.WriteTree.prototype.addMerge = function(path, changedChildren, writeId) {
+ fb.core.util.assert(writeId > this.lastWriteId_, "Stacking an older merge on top of newer ones");
+ this.allWrites_.push({path:path, children:changedChildren, writeId:writeId, visible:true});
+ this.visibleWrites_ = this.visibleWrites_.addWrites(path, changedChildren);
+ this.lastWriteId_ = writeId;
+};
+fb.core.WriteTree.prototype.removeWrite = function(writeId) {
+ var idx = goog.array.findIndex(this.allWrites_, function(s) {
+ return s.writeId === writeId;
+ });
+ fb.core.util.assert(idx >= 0, "removeWrite called with nonexistent writeId.");
+ var writeToRemove = this.allWrites_[idx];
+ this.allWrites_.splice(idx, 1);
+ var removedWriteWasVisible = writeToRemove.visible;
+ var removedWriteOverlapsWithOtherWrites = false;
+ var i = this.allWrites_.length - 1;
+ while (removedWriteWasVisible && i >= 0) {
+ var currentWrite = this.allWrites_[i];
+ if (currentWrite.visible) {
+ if (i >= idx && this.recordContainsPath_(currentWrite, writeToRemove.path)) {
+ removedWriteWasVisible = false;
+ } else {
+ if (writeToRemove.path.contains(currentWrite.path)) {
+ removedWriteOverlapsWithOtherWrites = true;
+ }
+ }
+ }
+ i--;
+ }
+ if (!removedWriteWasVisible) {
+ return null;
+ } else {
+ if (removedWriteOverlapsWithOtherWrites) {
+ this.resetTree_();
+ return writeToRemove.path;
+ } else {
+ if (writeToRemove.snap) {
+ this.visibleWrites_ = this.visibleWrites_.removeWrite(writeToRemove.path);
+ } else {
+ var children = writeToRemove.children;
+ var self = this;
+ goog.object.forEach(children, function(childSnap, childName) {
+ self.visibleWrites_ = self.visibleWrites_.removeWrite(writeToRemove.path.child(childName));
+ });
+ }
+ return writeToRemove.path;
+ }
+ }
+};
+fb.core.WriteTree.prototype.getCompleteWriteData = function(path) {
+ return this.visibleWrites_.getCompleteNode(path);
+};
+fb.core.WriteTree.prototype.calcCompleteEventCache = function(treePath, completeServerCache, writeIdsToExclude, includeHiddenWrites) {
+ if (!writeIdsToExclude && !includeHiddenWrites) {
+ var shadowingNode = this.visibleWrites_.getCompleteNode(treePath);
+ if (shadowingNode != null) {
+ return shadowingNode;
+ } else {
+ var subMerge = this.visibleWrites_.childCompoundWrite(treePath);
+ if (subMerge.isEmpty()) {
+ return completeServerCache;
+ } else {
+ if (completeServerCache == null && !subMerge.hasCompleteWrite(fb.core.util.Path.Empty)) {
+ return null;
+ } else {
+ var layeredCache = completeServerCache || fb.core.snap.EMPTY_NODE;
+ return subMerge.apply(layeredCache);
+ }
+ }
+ }
+ } else {
+ var merge = this.visibleWrites_.childCompoundWrite(treePath);
+ if (!includeHiddenWrites && merge.isEmpty()) {
+ return completeServerCache;
+ } else {
+ if (!includeHiddenWrites && completeServerCache == null && !merge.hasCompleteWrite(fb.core.util.Path.Empty)) {
+ return null;
+ } else {
+ var filter = function(write) {
+ return(write.visible || includeHiddenWrites) && (!writeIdsToExclude || !goog.array.contains(writeIdsToExclude, write.writeId)) && (write.path.contains(treePath) || treePath.contains(write.path));
+ };
+ var mergeAtPath = fb.core.WriteTree.layerTree_(this.allWrites_, filter, treePath);
+ layeredCache = completeServerCache || fb.core.snap.EMPTY_NODE;
+ return mergeAtPath.apply(layeredCache);
+ }
+ }
+ }
+};
+fb.core.WriteTree.prototype.calcCompleteEventChildren = function(treePath, completeServerChildren) {
+ var completeChildren = fb.core.snap.EMPTY_NODE;
+ var topLevelSet = this.visibleWrites_.getCompleteNode(treePath);
+ if (topLevelSet) {
+ if (!topLevelSet.isLeafNode()) {
+ topLevelSet.forEachChild(fb.core.snap.PriorityIndex, function(childName, childSnap) {
+ completeChildren = completeChildren.updateImmediateChild(childName, childSnap);
+ });
+ }
+ return completeChildren;
+ } else {
+ if (completeServerChildren) {
+ var merge = this.visibleWrites_.childCompoundWrite(treePath);
+ completeServerChildren.forEachChild(fb.core.snap.PriorityIndex, function(childName, childNode) {
+ var node = merge.childCompoundWrite(new fb.core.util.Path(childName)).apply(childNode);
+ completeChildren = completeChildren.updateImmediateChild(childName, node);
+ });
+ goog.array.forEach(merge.getCompleteChildren(), function(namedNode) {
+ completeChildren = completeChildren.updateImmediateChild(namedNode.name, namedNode.node);
+ });
+ return completeChildren;
+ } else {
+ merge = this.visibleWrites_.childCompoundWrite(treePath);
+ goog.array.forEach(merge.getCompleteChildren(), function(namedNode) {
+ completeChildren = completeChildren.updateImmediateChild(namedNode.name, namedNode.node);
+ });
+ return completeChildren;
+ }
+ }
+};
+fb.core.WriteTree.prototype.calcEventCacheAfterServerOverwrite = function(treePath, childPath, existingEventSnap, existingServerSnap) {
+ fb.core.util.assert(existingEventSnap || existingServerSnap, "Either existingEventSnap or existingServerSnap must exist");
+ var path = treePath.child(childPath);
+ if (this.visibleWrites_.hasCompleteWrite(path)) {
+ return null;
+ } else {
+ var childMerge = this.visibleWrites_.childCompoundWrite(path);
+ if (childMerge.isEmpty()) {
+ return existingServerSnap.getChild(childPath);
+ } else {
+ return childMerge.apply(existingServerSnap.getChild(childPath));
+ }
+ }
+};
+fb.core.WriteTree.prototype.calcCompleteChild = function(treePath, childKey, existingServerSnap) {
+ var path = treePath.child(childKey);
+ var shadowingNode = this.visibleWrites_.getCompleteNode(path);
+ if (shadowingNode != null) {
+ return shadowingNode;
+ } else {
+ if (existingServerSnap.isCompleteForChild(childKey)) {
+ var childMerge = this.visibleWrites_.childCompoundWrite(path);
+ return childMerge.apply(existingServerSnap.getNode().getImmediateChild(childKey));
+ } else {
+ return null;
+ }
+ }
+};
+fb.core.WriteTree.prototype.shadowingWrite = function(path) {
+ return this.visibleWrites_.getCompleteNode(path);
+};
+fb.core.WriteTree.prototype.calcIndexedSlice = function(treePath, completeServerData, startPost, count, reverse, index) {
+ var toIterate;
+ var merge = this.visibleWrites_.childCompoundWrite(treePath);
+ var shadowingNode = merge.getCompleteNode(fb.core.util.Path.Empty);
+ if (shadowingNode != null) {
+ toIterate = shadowingNode;
+ } else {
+ if (completeServerData != null) {
+ toIterate = merge.apply(completeServerData);
+ } else {
+ return[];
+ }
+ }
+ toIterate = toIterate.withIndex(index);
+ if (!toIterate.isEmpty() && !toIterate.isLeafNode()) {
+ var nodes = [];
+ var cmp = index.getCompare();
+ var iter = reverse ? toIterate.getReverseIteratorFrom(startPost, index) : toIterate.getIteratorFrom(startPost, index);
+ var next = iter.getNext();
+ while (next && nodes.length < count) {
+ if (cmp(next, startPost) !== 0) {
+ nodes.push(next);
+ }
+ next = iter.getNext();
+ }
+ return nodes;
+ } else {
+ return[];
+ }
+};
+fb.core.WriteTree.prototype.recordContainsPath_ = function(writeRecord, path) {
+ if (writeRecord.snap) {
+ return writeRecord.path.contains(path);
+ } else {
+ return!!goog.object.findKey(writeRecord.children, function(childSnap, childName) {
+ return writeRecord.path.child(childName).contains(path);
+ });
+ }
+};
+fb.core.WriteTree.prototype.resetTree_ = function() {
+ this.visibleWrites_ = fb.core.WriteTree.layerTree_(this.allWrites_, fb.core.WriteTree.DefaultFilter_, fb.core.util.Path.Empty);
+ if (this.allWrites_.length > 0) {
+ this.lastWriteId_ = this.allWrites_[this.allWrites_.length - 1].writeId;
+ } else {
+ this.lastWriteId_ = -1;
+ }
+};
+fb.core.WriteTree.DefaultFilter_ = function(write) {
+ return write.visible;
+};
+fb.core.WriteTree.layerTree_ = function(writes, filter, treeRoot) {
+ var compoundWrite = fb.core.CompoundWrite.Empty;
+ for (var i = 0;i < writes.length;++i) {
+ var write = writes[i];
+ if (filter(write)) {
+ var writePath = write.path;
+ var relativePath;
+ if (write.snap) {
+ if (treeRoot.contains(writePath)) {
+ relativePath = fb.core.util.Path.relativePath(treeRoot, writePath);
+ compoundWrite = compoundWrite.addWrite(relativePath, write.snap);
+ } else {
+ if (writePath.contains(treeRoot)) {
+ relativePath = fb.core.util.Path.relativePath(writePath, treeRoot);
+ compoundWrite = compoundWrite.addWrite(fb.core.util.Path.Empty, write.snap.getChild(relativePath));
+ } else {
+ }
+ }
+ } else {
+ if (write.children) {
+ if (treeRoot.contains(writePath)) {
+ relativePath = fb.core.util.Path.relativePath(treeRoot, writePath);
+ compoundWrite = compoundWrite.addWrites(relativePath, write.children);
+ } else {
+ if (writePath.contains(treeRoot)) {
+ relativePath = fb.core.util.Path.relativePath(writePath, treeRoot);
+ if (relativePath.isEmpty()) {
+ compoundWrite = compoundWrite.addWrites(fb.core.util.Path.Empty, write.children);
+ } else {
+ var child = fb.util.obj.get(write.children, relativePath.getFront());
+ if (child) {
+ var deepNode = child.getChild(relativePath.popFront());
+ compoundWrite = compoundWrite.addWrite(fb.core.util.Path.Empty, deepNode);
+ }
+ }
+ } else {
+ }
+ }
+ } else {
+ throw fb.core.util.assertionError("WriteRecord should have .snap or .children");
+ }
+ }
+ }
+ }
+ return compoundWrite;
+};
+fb.core.WriteTreeRef = function(path, writeTree) {
+ this.treePath_ = path;
+ this.writeTree_ = writeTree;
+};
+fb.core.WriteTreeRef.prototype.calcCompleteEventCache = function(completeServerCache, writeIdsToExclude, includeHiddenWrites) {
+ return this.writeTree_.calcCompleteEventCache(this.treePath_, completeServerCache, writeIdsToExclude, includeHiddenWrites);
+};
+fb.core.WriteTreeRef.prototype.calcCompleteEventChildren = function(completeServerChildren) {
+ return this.writeTree_.calcCompleteEventChildren(this.treePath_, completeServerChildren);
+};
+fb.core.WriteTreeRef.prototype.calcEventCacheAfterServerOverwrite = function(path, existingEventSnap, existingServerSnap) {
+ return this.writeTree_.calcEventCacheAfterServerOverwrite(this.treePath_, path, existingEventSnap, existingServerSnap);
+};
+fb.core.WriteTreeRef.prototype.shadowingWrite = function(path) {
+ return this.writeTree_.shadowingWrite(this.treePath_.child(path));
+};
+fb.core.WriteTreeRef.prototype.calcIndexedSlice = function(completeServerData, startPost, count, reverse, index) {
+ return this.writeTree_.calcIndexedSlice(this.treePath_, completeServerData, startPost, count, reverse, index);
+};
+fb.core.WriteTreeRef.prototype.calcCompleteChild = function(childKey, existingServerCache) {
+ return this.writeTree_.calcCompleteChild(this.treePath_, childKey, existingServerCache);
+};
+fb.core.WriteTreeRef.prototype.child = function(childName) {
+ return new fb.core.WriteTreeRef(this.treePath_.child(childName), this.writeTree_);
+};
+goog.provide("fb.core.SyncPoint");
+goog.require("fb.core.util");
+goog.require("fb.core.util.ImmutableTree");
+goog.require("fb.core.view.ViewCache");
+goog.require("fb.core.view.EventRegistration");
+goog.require("fb.core.view.View");
+goog.require("goog.array");
+fb.core.SyncPoint = function() {
+ this.views_ = {};
+};
+fb.core.SyncPoint.prototype.isEmpty = function() {
+ return goog.object.isEmpty(this.views_);
+};
+fb.core.SyncPoint.prototype.applyOperation = function(operation, writesCache, optCompleteServerCache) {
+ var queryId = operation.source.queryId;
+ if (queryId !== null) {
+ var view = fb.util.obj.get(this.views_, queryId);
+ fb.core.util.assert(view != null, "SyncTree gave us an op for an invalid query.");
+ return view.applyOperation(operation, writesCache, optCompleteServerCache);
+ } else {
+ var events = [];
+ goog.object.forEach(this.views_, function(view) {
+ events = events.concat(view.applyOperation(operation, writesCache, optCompleteServerCache));
+ });
+ return events;
+ }
+};
+fb.core.SyncPoint.prototype.addEventRegistration = function(query, eventRegistration, writesCache, serverCache, serverCacheComplete) {
+ var queryId = query.queryIdentifier();
+ var view = fb.util.obj.get(this.views_, queryId);
+ if (!view) {
+ var eventCache = writesCache.calcCompleteEventCache(serverCacheComplete ? serverCache : null);
+ var eventCacheComplete = false;
+ if (eventCache) {
+ eventCacheComplete = true;
+ } else {
+ if (serverCache instanceof fb.core.snap.ChildrenNode) {
+ eventCache = writesCache.calcCompleteEventChildren(serverCache);
+ eventCacheComplete = false;
+ } else {
+ eventCache = fb.core.snap.EMPTY_NODE;
+ eventCacheComplete = false;
+ }
+ }
+ var viewCache = new fb.core.view.ViewCache(new fb.core.view.CacheNode((eventCache), eventCacheComplete, false), new fb.core.view.CacheNode((serverCache), serverCacheComplete, false));
+ view = new fb.core.view.View(query, viewCache);
+ this.views_[queryId] = view;
+ }
+ view.addEventRegistration(eventRegistration);
+ return view.getInitialEvents(eventRegistration);
+};
+fb.core.SyncPoint.prototype.removeEventRegistration = function(query, eventRegistration, cancelError) {
+ var queryId = query.queryIdentifier();
+ var removed = [];
+ var cancelEvents = [];
+ var hadCompleteView = this.hasCompleteView();
+ if (queryId === "default") {
+ var self = this;
+ goog.object.forEach(this.views_, function(view, viewQueryId) {
+ cancelEvents = cancelEvents.concat(view.removeEventRegistration(eventRegistration, cancelError));
+ if (view.isEmpty()) {
+ delete self.views_[viewQueryId];
+ if (!view.getQuery().getQueryParams().loadsAllData()) {
+ removed.push(view.getQuery());
+ }
+ }
+ });
+ } else {
+ var view = fb.util.obj.get(this.views_, queryId);
+ if (view) {
+ cancelEvents = cancelEvents.concat(view.removeEventRegistration(eventRegistration, cancelError));
+ if (view.isEmpty()) {
+ delete this.views_[queryId];
+ if (!view.getQuery().getQueryParams().loadsAllData()) {
+ removed.push(view.getQuery());
+ }
+ }
+ }
+ }
+ if (hadCompleteView && !this.hasCompleteView()) {
+ removed.push(new Firebase(query.repo, query.path));
+ }
+ return{removed:removed, events:cancelEvents};
+};
+fb.core.SyncPoint.prototype.getQueryViews = function() {
+ return goog.array.filter(goog.object.getValues(this.views_), function(view) {
+ return!view.getQuery().getQueryParams().loadsAllData();
+ });
+};
+fb.core.SyncPoint.prototype.getCompleteServerCache = function(path) {
+ var serverCache = null;
+ goog.object.forEach(this.views_, function(view) {
+ serverCache = serverCache || view.getCompleteServerCache(path);
+ });
+ return serverCache;
+};
+fb.core.SyncPoint.prototype.viewForQuery = function(query) {
+ var params = query.getQueryParams();
+ if (params.loadsAllData()) {
+ return this.getCompleteView();
+ } else {
+ var queryId = query.queryIdentifier();
+ return fb.util.obj.get(this.views_, queryId);
+ }
+};
+fb.core.SyncPoint.prototype.viewExistsForQuery = function(query) {
+ return this.viewForQuery(query) != null;
+};
+fb.core.SyncPoint.prototype.hasCompleteView = function() {
+ return this.getCompleteView() != null;
+};
+fb.core.SyncPoint.prototype.getCompleteView = function() {
+ var completeView = goog.object.findValue(this.views_, function(view) {
+ return view.getQuery().getQueryParams().loadsAllData();
+ });
+ return completeView || null;
+};
+goog.provide("fb.core.SyncTree");
+goog.require("fb.core.Operation");
+goog.require("fb.core.SyncPoint");
+goog.require("fb.core.WriteTree");
+goog.require("fb.core.util");
+fb.core.ListenProvider;
+fb.core.SyncTree = function(listenProvider) {
+ this.syncPointTree_ = fb.core.util.ImmutableTree.Empty;
+ this.pendingWriteTree_ = new fb.core.WriteTree;
+ this.tagToQueryMap_ = {};
+ this.queryToTagMap_ = {};
+ this.listenProvider_ = listenProvider;
+};
+fb.core.SyncTree.prototype.applyUserOverwrite = function(path, newData, writeId, visible) {
+ this.pendingWriteTree_.addOverwrite(path, newData, writeId, visible);
+ if (!visible) {
+ return[];
+ } else {
+ return this.applyOperationToSyncPoints_(new fb.core.operation.Overwrite(fb.core.OperationSource.User, path, newData));
+ }
+};
+fb.core.SyncTree.prototype.applyUserMerge = function(path, changedChildren, writeId) {
+ this.pendingWriteTree_.addMerge(path, changedChildren, writeId);
+ var changeTree = fb.core.util.ImmutableTree.fromObject(changedChildren);
+ return this.applyOperationToSyncPoints_(new fb.core.operation.Merge(fb.core.OperationSource.User, path, changeTree));
+};
+fb.core.SyncTree.prototype.ackUserWrite = function(writeId, revert) {
+ revert = revert || false;
+ var pathToReevaluate = this.pendingWriteTree_.removeWrite(writeId);
+ if (pathToReevaluate == null) {
+ return[];
+ } else {
+ return this.applyOperationToSyncPoints_(new fb.core.operation.AckUserWrite(pathToReevaluate, revert));
+ }
+};
+fb.core.SyncTree.prototype.applyServerOverwrite = function(path, newData) {
+ return this.applyOperationToSyncPoints_(new fb.core.operation.Overwrite(fb.core.OperationSource.Server, path, newData));
+};
+fb.core.SyncTree.prototype.applyServerMerge = function(path, changedChildren) {
+ var changeTree = fb.core.util.ImmutableTree.fromObject(changedChildren);
+ return this.applyOperationToSyncPoints_(new fb.core.operation.Merge(fb.core.OperationSource.Server, path, changeTree));
+};
+fb.core.SyncTree.prototype.applyListenComplete = function(path) {
+ return this.applyOperationToSyncPoints_(new fb.core.operation.ListenComplete(fb.core.OperationSource.Server, path));
+};
+fb.core.SyncTree.prototype.applyTaggedQueryOverwrite = function(path, snap, tag) {
+ var queryKey = this.queryKeyForTag_(tag);
+ if (queryKey != null) {
+ var r = this.parseQueryKey_(queryKey);
+ var queryPath = r.path, queryId = r.queryId;
+ var relativePath = fb.core.util.Path.relativePath(queryPath, path);
+ var op = new fb.core.operation.Overwrite(fb.core.OperationSource.forServerTaggedQuery(queryId), relativePath, snap);
+ return this.applyTaggedOperation_(queryPath, queryId, op);
+ } else {
+ return[];
+ }
+};
+fb.core.SyncTree.prototype.applyTaggedQueryMerge = function(path, changedChildren, tag) {
+ var queryKey = this.queryKeyForTag_(tag);
+ if (queryKey) {
+ var r = this.parseQueryKey_(queryKey);
+ var queryPath = r.path, queryId = r.queryId;
+ var relativePath = fb.core.util.Path.relativePath(queryPath, path);
+ var changeTree = fb.core.util.ImmutableTree.fromObject(changedChildren);
+ var op = new fb.core.operation.Merge(fb.core.OperationSource.forServerTaggedQuery(queryId), relativePath, changeTree);
+ return this.applyTaggedOperation_(queryPath, queryId, op);
+ } else {
+ return[];
+ }
+};
+fb.core.SyncTree.prototype.applyTaggedListenComplete = function(path, tag) {
+ var queryKey = this.queryKeyForTag_(tag);
+ if (queryKey) {
+ var r = this.parseQueryKey_(queryKey);
+ var queryPath = r.path, queryId = r.queryId;
+ var relativePath = fb.core.util.Path.relativePath(queryPath, path);
+ var op = new fb.core.operation.ListenComplete(fb.core.OperationSource.forServerTaggedQuery(queryId), relativePath);
+ return this.applyTaggedOperation_(queryPath, queryId, op);
+ } else {
+ return[];
+ }
+};
+fb.core.SyncTree.prototype.addEventRegistration = function(query, eventRegistration) {
+ var path = query.path;
+ var serverCache = null;
+ var foundAncestorDefaultView = false;
+ this.syncPointTree_.foreachOnPathWhile(path, function(pathToSyncPoint, sp) {
+ var relativePath = fb.core.util.Path.relativePath(pathToSyncPoint, path);
+ serverCache = sp.getCompleteServerCache(relativePath);
+ foundAncestorDefaultView = foundAncestorDefaultView || sp.hasCompleteView();
+ return!serverCache;
+ });
+ var syncPoint = this.syncPointTree_.get(path);
+ if (!syncPoint) {
+ syncPoint = new fb.core.SyncPoint;
+ this.syncPointTree_ = this.syncPointTree_.set(path, syncPoint);
+ } else {
+ foundAncestorDefaultView = foundAncestorDefaultView || syncPoint.hasCompleteView();
+ serverCache = serverCache || syncPoint.getCompleteServerCache(fb.core.util.Path.Empty);
+ }
+ var serverCacheComplete;
+ if (serverCache != null) {
+ serverCacheComplete = true;
+ } else {
+ serverCacheComplete = false;
+ serverCache = fb.core.snap.EMPTY_NODE;
+ var subtree = this.syncPointTree_.subtree(path);
+ subtree.foreachChild(function(childName, childSyncPoint) {
+ var completeCache = childSyncPoint.getCompleteServerCache(fb.core.util.Path.Empty);
+ if (completeCache) {
+ serverCache = serverCache.updateImmediateChild(childName, completeCache);
+ }
+ });
+ }
+ var viewAlreadyExists = syncPoint.viewExistsForQuery(query);
+ if (!viewAlreadyExists && !query.getQueryParams().loadsAllData()) {
+ var queryKey = this.makeQueryKey_(query);
+ fb.core.util.assert(!goog.object.containsKey(this.queryToTagMap_, queryKey), "View does not exist, but we have a tag");
+ var tag = fb.core.SyncTree.getNextQueryTag_();
+ this.queryToTagMap_[queryKey] = tag;
+ this.tagToQueryMap_["_" + tag] = queryKey;
+ }
+ var writesCache = this.pendingWriteTree_.childWrites(path);
+ var events = syncPoint.addEventRegistration(query, eventRegistration, writesCache, serverCache, serverCacheComplete);
+ if (!viewAlreadyExists && !foundAncestorDefaultView) {
+ var view = (syncPoint.viewForQuery(query));
+ events = events.concat(this.setupListener_(query, view));
+ }
+ return events;
+};
+fb.core.SyncTree.prototype.removeEventRegistration = function(query, eventRegistration, cancelError) {
+ var path = query.path;
+ var maybeSyncPoint = this.syncPointTree_.get(path);
+ var cancelEvents = [];
+ if (maybeSyncPoint && (query.queryIdentifier() === "default" || maybeSyncPoint.viewExistsForQuery(query))) {
+ var removedAndEvents = maybeSyncPoint.removeEventRegistration(query, eventRegistration, cancelError);
+ if (maybeSyncPoint.isEmpty()) {
+ this.syncPointTree_ = this.syncPointTree_.remove(path);
+ }
+ var removed = removedAndEvents.removed;
+ cancelEvents = removedAndEvents.events;
+ var removingDefault = -1 !== goog.array.findIndex(removed, function(query) {
+ return query.getQueryParams().loadsAllData();
+ });
+ var covered = this.syncPointTree_.findOnPath(path, function(relativePath, parentSyncPoint) {
+ return parentSyncPoint.hasCompleteView();
+ });
+ if (removingDefault && !covered) {
+ var subtree = this.syncPointTree_.subtree(path);
+ if (!subtree.isEmpty()) {
+ var newViews = this.collectDistinctViewsForSubTree_(subtree);
+ for (var i = 0;i < newViews.length;++i) {
+ var view = newViews[i], newQuery = view.getQuery();
+ var listener = this.createListenerForView_(view);
+ this.listenProvider_.startListening(newQuery, this.tagForQuery_(newQuery), listener.hashFn, listener.onComplete);
+ }
+ } else {
+ }
+ }
+ if (!covered && removed.length > 0 && !cancelError) {
+ if (removingDefault) {
+ var defaultTag = null;
+ this.listenProvider_.stopListening(query, defaultTag);
+ } else {
+ var self = this;
+ goog.array.forEach(removed, function(queryToRemove) {
+ var queryIdToRemove = queryToRemove.queryIdentifier();
+ var tagToRemove = self.queryToTagMap_[self.makeQueryKey_(queryToRemove)];
+ self.listenProvider_.stopListening(queryToRemove, tagToRemove);
+ });
+ }
+ }
+ this.removeTags_(removed);
+ } else {
+ }
+ return cancelEvents;
+};
+fb.core.SyncTree.prototype.calcCompleteEventCache = function(path, writeIdsToExclude) {
+ var includeHiddenSets = true;
+ var writeTree = this.pendingWriteTree_;
+ var serverCache = this.syncPointTree_.findOnPath(path, function(pathSoFar, syncPoint) {
+ var relativePath = fb.core.util.Path.relativePath(pathSoFar, path);
+ var serverCache = syncPoint.getCompleteServerCache(relativePath);
+ if (serverCache) {
+ return serverCache;
+ }
+ });
+ return writeTree.calcCompleteEventCache(path, serverCache, writeIdsToExclude, includeHiddenSets);
+};
+fb.core.SyncTree.prototype.collectDistinctViewsForSubTree_ = function(subtree) {
+ return subtree.fold(function(relativePath, maybeChildSyncPoint, childMap) {
+ if (maybeChildSyncPoint && maybeChildSyncPoint.hasCompleteView()) {
+ var completeView = maybeChildSyncPoint.getCompleteView();
+ return[completeView];
+ } else {
+ var views = [];
+ if (maybeChildSyncPoint) {
+ views = maybeChildSyncPoint.getQueryViews();
+ }
+ goog.object.forEach(childMap, function(childViews) {
+ views = views.concat(childViews);
+ });
+ return views;
+ }
+ });
+};
+fb.core.SyncTree.prototype.removeTags_ = function(queries) {
+ for (var j = 0;j < queries.length;++j) {
+ var removedQuery = queries[j];
+ if (!removedQuery.getQueryParams().loadsAllData()) {
+ var removedQueryKey = this.makeQueryKey_(removedQuery);
+ var removedQueryTag = this.queryToTagMap_[removedQueryKey];
+ delete this.queryToTagMap_[removedQueryKey];
+ delete this.tagToQueryMap_["_" + removedQueryTag];
+ }
+ }
+};
+fb.core.SyncTree.prototype.setupListener_ = function(query, view) {
+ var path = query.path;
+ var tag = this.tagForQuery_(query);
+ var listener = this.createListenerForView_(view);
+ var events = this.listenProvider_.startListening(query, tag, listener.hashFn, listener.onComplete);
+ var subtree = this.syncPointTree_.subtree(path);
+ if (tag) {
+ fb.core.util.assert(!subtree.value.hasCompleteView(), "If we're adding a query, it shouldn't be shadowed");
+ } else {
+ var queriesToStop = subtree.fold(function(relativePath, maybeChildSyncPoint, childMap) {
+ if (!relativePath.isEmpty() && maybeChildSyncPoint && maybeChildSyncPoint.hasCompleteView()) {
+ return[maybeChildSyncPoint.getCompleteView().getQuery()];
+ } else {
+ var queries = [];
+ if (maybeChildSyncPoint) {
+ queries = queries.concat(goog.array.map(maybeChildSyncPoint.getQueryViews(), function(view) {
+ return view.getQuery();
+ }));
+ }
+ goog.object.forEach(childMap, function(childQueries) {
+ queries = queries.concat(childQueries);
+ });
+ return queries;
+ }
+ });
+ for (var i = 0;i < queriesToStop.length;++i) {
+ var queryToStop = queriesToStop[i];
+ this.listenProvider_.stopListening(queryToStop, this.tagForQuery_(queryToStop));
+ }
+ }
+ return events;
+};
+fb.core.SyncTree.prototype.createListenerForView_ = function(view) {
+ var self = this;
+ var query = view.getQuery();
+ var tag = this.tagForQuery_(query);
+ return{hashFn:function() {
+ var cache = view.getServerCache() || fb.core.snap.EMPTY_NODE;
+ return cache.hash();
+ }, onComplete:function(status, data) {
+ if (status === "ok") {
+ if (tag) {
+ return self.applyTaggedListenComplete(query.path, tag);
+ } else {
+ return self.applyListenComplete(query.path);
+ }
+ } else {
+ var error = fb.core.util.errorForServerCode(status);
+ return self.removeEventRegistration(query, null, error);
+ }
+ }};
+};
+fb.core.SyncTree.prototype.makeQueryKey_ = function(query) {
+ return query.path.toString() + "$" + query.queryIdentifier();
+};
+fb.core.SyncTree.prototype.parseQueryKey_ = function(queryKey) {
+ var splitIndex = queryKey.indexOf("$");
+ fb.core.util.assert(splitIndex !== -1 && splitIndex < queryKey.length - 1, "Bad queryKey.");
+ return{queryId:queryKey.substr(splitIndex + 1), path:new fb.core.util.Path(queryKey.substr(0, splitIndex))};
+};
+fb.core.SyncTree.prototype.queryKeyForTag_ = function(tag) {
+ return goog.object.get(this.tagToQueryMap_, "_" + tag);
+};
+fb.core.SyncTree.prototype.tagForQuery_ = function(query) {
+ var queryKey = this.makeQueryKey_(query);
+ return fb.util.obj.get(this.queryToTagMap_, queryKey);
+};
+fb.core.SyncTree.nextQueryTag_ = 1;
+fb.core.SyncTree.getNextQueryTag_ = function() {
+ return fb.core.SyncTree.nextQueryTag_++;
+};
+fb.core.SyncTree.prototype.applyTaggedOperation_ = function(queryPath, queryId, operation) {
+ var syncPoint = this.syncPointTree_.get(queryPath);
+ fb.core.util.assert(syncPoint, "Missing sync point for query tag that we're tracking");
+ var writesCache = this.pendingWriteTree_.childWrites(queryPath);
+ return syncPoint.applyOperation(operation, writesCache, null);
+};
+fb.core.SyncTree.prototype.applyOperationToSyncPoints_ = function(operation) {
+ return this.applyOperationHelper_(operation, this.syncPointTree_, null, this.pendingWriteTree_.childWrites(fb.core.util.Path.Empty));
+};
+fb.core.SyncTree.prototype.applyOperationHelper_ = function(operation, syncPointTree, serverCache, writesCache) {
+ if (operation.path.isEmpty()) {
+ return this.applyOperationDescendantsHelper_(operation, syncPointTree, serverCache, writesCache);
+ } else {
+ var syncPoint = syncPointTree.get(fb.core.util.Path.Empty);
+ if (serverCache == null && syncPoint != null) {
+ serverCache = syncPoint.getCompleteServerCache(fb.core.util.Path.Empty);
+ }
+ var events = [];
+ var childName = operation.path.getFront();
+ var childOperation = operation.operationForChild(childName);
+ var childTree = syncPointTree.children.get(childName);
+ if (childTree && childOperation) {
+ var childServerCache = serverCache ? serverCache.getImmediateChild(childName) : null;
+ var childWritesCache = writesCache.child(childName);
+ events = events.concat(this.applyOperationHelper_(childOperation, childTree, childServerCache, childWritesCache));
+ }
+ if (syncPoint) {
+ events = events.concat(syncPoint.applyOperation(operation, writesCache, serverCache));
+ }
+ return events;
+ }
+};
+fb.core.SyncTree.prototype.applyOperationDescendantsHelper_ = function(operation, syncPointTree, serverCache, writesCache) {
+ var syncPoint = syncPointTree.get(fb.core.util.Path.Empty);
+ if (serverCache == null && syncPoint != null) {
+ serverCache = syncPoint.getCompleteServerCache(fb.core.util.Path.Empty);
+ }
+ var events = [];
+ var self = this;
+ syncPointTree.children.inorderTraversal(function(childName, childTree) {
+ var childServerCache = serverCache ? serverCache.getImmediateChild(childName) : null;
+ var childWritesCache = writesCache.child(childName);
+ var childOperation = operation.operationForChild(childName);
+ if (childOperation) {
+ events = events.concat(self.applyOperationDescendantsHelper_(childOperation, childTree, childServerCache, childWritesCache));
+ }
+ });
+ if (syncPoint) {
+ events = events.concat(syncPoint.applyOperation(operation, writesCache, serverCache));
+ }
+ return events;
+};
+goog.provide("fb.core.util.Tree");
+goog.require("fb.core.util");
+goog.require("fb.core.util.Path");
+goog.require("fb.util.obj");
+goog.require("goog.object");
+fb.core.util.TreeNode = goog.defineClass(null, {constructor:function() {
+ this.children = {};
+ this.childCount = 0;
+ this.value = null;
+}});
+fb.core.util.Tree = goog.defineClass(null, {constructor:function(opt_name, opt_parent, opt_node) {
+ this.name_ = opt_name ? opt_name : "";
+ this.parent_ = opt_parent ? opt_parent : null;
+ this.node_ = opt_node ? opt_node : new fb.core.util.TreeNode;
+}, subTree:function(pathObj) {
+ var path = pathObj instanceof fb.core.util.Path ? pathObj : new fb.core.util.Path(pathObj);
+ var child = this, next;
+ while ((next = path.getFront()) !== null) {
+ var childNode = fb.util.obj.get(child.node_.children, next) || new fb.core.util.TreeNode;
+ child = new fb.core.util.Tree(next, child, childNode);
+ path = path.popFront();
+ }
+ return child;
+}, getValue:function() {
+ return this.node_.value;
+}, setValue:function(value) {
+ fb.core.util.assert(typeof value !== "undefined", "Cannot set value to undefined");
+ this.node_.value = value;
+ this.updateParents_();
+}, clear:function() {
+ this.node_.value = null;
+ this.node_.children = {};
+ this.node_.childCount = 0;
+ this.updateParents_();
+}, hasChildren:function() {
+ return this.node_.childCount > 0;
+}, isEmpty:function() {
+ return this.getValue() === null && !this.hasChildren();
+}, forEachChild:function(action) {
+ var self = this;
+ goog.object.forEach(this.node_.children, function(childTree, child) {
+ action(new fb.core.util.Tree(child, self, childTree));
+ });
+}, forEachDescendant:function(action, opt_includeSelf, opt_childrenFirst) {
+ if (opt_includeSelf && !opt_childrenFirst) {
+ action(this);
+ }
+ this.forEachChild(function(child) {
+ child.forEachDescendant(action, true, opt_childrenFirst);
+ });
+ if (opt_includeSelf && opt_childrenFirst) {
+ action(this);
+ }
+}, forEachAncestor:function(action, opt_includeSelf) {
+ var node = opt_includeSelf ? this : this.parent();
+ while (node !== null) {
+ if (action(node)) {
+ return true;
+ }
+ node = node.parent();
+ }
+ return false;
+}, forEachImmediateDescendantWithValue:function(action) {
+ this.forEachChild(function(child) {
+ if (child.getValue() !== null) {
+ action(child);
+ } else {
+ child.forEachImmediateDescendantWithValue(action);
+ }
+ });
+}, path:function() {
+ return new fb.core.util.Path(this.parent_ === null ? this.name_ : this.parent_.path() + "/" + this.name_);
+}, name:function() {
+ return this.name_;
+}, parent:function() {
+ return this.parent_;
+}, updateParents_:function() {
+ if (this.parent_ !== null) {
+ this.parent_.updateChild_(this.name_, this);
+ }
+}, updateChild_:function(childName, child) {
+ var childEmpty = child.isEmpty();
+ var childExists = fb.util.obj.contains(this.node_.children, childName);
+ if (childEmpty && childExists) {
+ delete this.node_.children[childName];
+ this.node_.childCount--;
+ this.updateParents_();
+ } else {
+ if (!childEmpty && !childExists) {
+ this.node_.children[childName] = child.node_;
+ this.node_.childCount++;
+ this.updateParents_();
+ }
+ }
+}});
+goog.provide("fb.core.util.EventEmitter");
+goog.require("fb.core.util");
+goog.require("goog.array");
+fb.core.util.EventEmitter = goog.defineClass(null, {constructor:function(allowedEvents) {
+ fb.core.util.assert(goog.isArray(allowedEvents) && allowedEvents.length > 0, "Requires a non-empty array");
+ this.allowedEvents_ = allowedEvents;
+ this.listeners_ = {};
+}, getInitialEvent:goog.abstractMethod, trigger:function(eventType, var_args) {
+ var listeners = this.listeners_[eventType] || [];
+ for (var i = 0;i < listeners.length;i++) {
+ listeners[i].callback.apply(listeners[i].context, Array.prototype.slice.call(arguments, 1));
+ }
+}, on:function(eventType, callback, context) {
+ this.validateEventType_(eventType);
+ this.listeners_[eventType] = this.listeners_[eventType] || [];
+ this.listeners_[eventType].push({callback:callback, context:context});
+ var eventData = this.getInitialEvent(eventType);
+ if (eventData) {
+ callback.apply(context, eventData);
+ }
+}, off:function(eventType, callback, context) {
+ this.validateEventType_(eventType);
+ var listeners = this.listeners_[eventType] || [];
+ for (var i = 0;i < listeners.length;i++) {
+ if (listeners[i].callback === callback && (!context || context === listeners[i].context)) {
+ listeners.splice(i, 1);
+ return;
+ }
+ }
+}, validateEventType_:function(eventType) {
+ fb.core.util.assert(goog.array.find(this.allowedEvents_, function(et) {
+ return et === eventType;
+ }), "Unknown event: " + eventType);
+}});
+goog.provide("fb.core.util.nextPushId");
+goog.require("fb.core.util");
+fb.core.util.nextPushId = function() {
+ var PUSH_CHARS = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
+ var lastPushTime = 0;
+ var lastRandChars = [];
+ return function(now) {
+ var duplicateTime = now === lastPushTime;
+ lastPushTime = now;
+ var timeStampChars = new Array(8);
+ for (var i = 7;i >= 0;i--) {
+ timeStampChars[i] = PUSH_CHARS.charAt(now % 64);
+ now = Math.floor(now / 64);
+ }
+ fb.core.util.assert(now === 0, "Cannot push at time == 0");
+ var id = timeStampChars.join("");
+ if (!duplicateTime) {
+ for (i = 0;i < 12;i++) {
+ lastRandChars[i] = Math.floor(Math.random() * 64);
+ }
+ } else {
+ for (i = 11;i >= 0 && lastRandChars[i] === 63;i--) {
+ lastRandChars[i] = 0;
+ }
+ lastRandChars[i]++;
+ }
+ for (i = 0;i < 12;i++) {
+ id += PUSH_CHARS.charAt(lastRandChars[i]);
+ }
+ fb.core.util.assert(id.length === 20, "nextPushId: Length should be 20.");
+ return id;
+ };
+}();
+goog.provide("fb.core.util.OnlineMonitor");
+goog.require("fb.core.util");
+goog.require("fb.core.util.EventEmitter");
+fb.core.util.OnlineMonitor = goog.defineClass(fb.core.util.EventEmitter, {constructor:function() {
+ fb.core.util.EventEmitter.call(this, ["online"]);
+ this.online_ = true;
+ if (typeof window !== "undefined" && typeof window.addEventListener !== "undefined") {
+ var self = this;
+ window.addEventListener("online", function() {
+ if (!self.online_) {
+ self.online_ = true;
+ self.trigger("online", true);
+ }
+ }, false);
+ window.addEventListener("offline", function() {
+ if (self.online_) {
+ self.online_ = false;
+ self.trigger("online", false);
+ }
+ }, false);
+ }
+}, getInitialEvent:function(eventType) {
+ fb.core.util.assert(eventType === "online", "Unknown event type: " + eventType);
+ return[this.online_];
+}, currentlyOnline:function() {
+ return this.online_;
+}});
+goog.addSingletonGetter(fb.core.util.OnlineMonitor);
+goog.provide("fb.core.util.VisibilityMonitor");
+goog.require("fb.core.util");
+goog.require("fb.core.util.EventEmitter");
+fb.core.util.VisibilityMonitor = goog.defineClass(fb.core.util.EventEmitter, {constructor:function() {
+ fb.core.util.EventEmitter.call(this, ["visible"]);
+ var hidden, visibilityChange;
+ if (typeof document !== "undefined" && typeof document.addEventListener !== "undefined") {
+ if (typeof document["hidden"] !== "undefined") {
+ visibilityChange = "visibilitychange";
+ hidden = "hidden";
+ } else {
+ if (typeof document["mozHidden"] !== "undefined") {
+ visibilityChange = "mozvisibilitychange";
+ hidden = "mozHidden";
+ } else {
+ if (typeof document["msHidden"] !== "undefined") {
+ visibilityChange = "msvisibilitychange";
+ hidden = "msHidden";
+ } else {
+ if (typeof document["webkitHidden"] !== "undefined") {
+ visibilityChange = "webkitvisibilitychange";
+ hidden = "webkitHidden";
+ }
+ }
+ }
+ }
+ }
+ this.visible_ = true;
+ if (visibilityChange) {
+ var self = this;
+ document.addEventListener(visibilityChange, function() {
+ var visible = !document[hidden];
+ if (visible !== self.visible_) {
+ self.visible_ = visible;
+ self.trigger("visible", visible);
+ }
+ }, false);
+ }
+}, getInitialEvent:function(eventType) {
+ fb.core.util.assert(eventType === "visible", "Unknown event type: " + eventType);
+ return[this.visible_];
+}});
+goog.addSingletonGetter(fb.core.util.VisibilityMonitor);
+goog.provide("fb.core.util.validation");
+goog.require("fb.core.util");
+goog.require("fb.core.util.Path");
+goog.require("fb.core.util.ValidationPath");
+goog.require("fb.util.obj");
+goog.require("fb.util.utf8");
+goog.require("fb.util.validation");
+fb.core.util.validation = {INVALID_KEY_REGEX_:/[\[\].#$\/\u0000-\u001F\u007F]/, INVALID_PATH_REGEX_:/[\[\].#$\u0000-\u001F\u007F]/, VALID_AUTH_PROVIDER:/^[a-zA-Z][a-zA-Z._\-+]+$/, MAX_LEAF_SIZE_:10 * 1024 * 1024, isValidKey:function(key) {
+ return goog.isString(key) && key.length !== 0 && !fb.core.util.validation.INVALID_KEY_REGEX_.test(key);
+}, isValidPathString:function(pathString) {
+ return goog.isString(pathString) && pathString.length !== 0 && !fb.core.util.validation.INVALID_PATH_REGEX_.test(pathString);
+}, isValidRootPathString:function(pathString) {
+ if (pathString) {
+ pathString = pathString.replace(/^\/*\.info(\/|$)/, "/");
+ }
+ return fb.core.util.validation.isValidPathString(pathString);
+}, isValidPriority:function(priority) {
+ return priority === null || goog.isString(priority) || goog.isNumber(priority) && !fb.core.util.isInvalidJSONNumber(priority) || goog.isObject(priority) && fb.util.obj.contains(priority, ".sv");
+}, validateFirebaseDataArg:function(fnName, argumentNumber, data, path, optional) {
+ if (optional && !goog.isDef(data)) {
+ return;
+ }
+ fb.core.util.validation.validateFirebaseData(fb.util.validation.errorPrefix(fnName, argumentNumber, optional), data, path);
+}, validateFirebaseData:function(errorPrefix, data, path) {
+ if (path instanceof fb.core.util.Path) {
+ path = new fb.core.util.ValidationPath(path, errorPrefix);
+ }
+ if (!goog.isDef(data)) {
+ throw new Error(errorPrefix + "contains undefined " + path.toErrorString());
+ }
+ if (goog.isFunction(data)) {
+ throw new Error(errorPrefix + "contains a function " + path.toErrorString() + " with contents: " + data.toString());
+ }
+ if (fb.core.util.isInvalidJSONNumber(data)) {
+ throw new Error(errorPrefix + "contains " + data.toString() + " " + path.toErrorString());
+ }
+ if (goog.isString(data) && data.length > fb.core.util.validation.MAX_LEAF_SIZE_ / 3 && fb.util.utf8.stringLength(data) > fb.core.util.validation.MAX_LEAF_SIZE_) {
+ throw new Error(errorPrefix + "contains a string greater than " + fb.core.util.validation.MAX_LEAF_SIZE_ + " utf8 bytes " + path.toErrorString() + " ('" + data.substring(0, 50) + "...')");
+ }
+ if (goog.isObject(data)) {
+ var hasDotValue = false, hasActualChild = false;
+ fb.util.obj.foreach(data, function(key, value) {
+ if (key === ".value") {
+ hasDotValue = true;
+ } else {
+ if (key !== ".priority" && key !== ".sv") {
+ hasActualChild = true;
+ if (!fb.core.util.validation.isValidKey(key)) {
+ throw new Error(errorPrefix + " contains an invalid key (" + key + ") " + path.toErrorString() + ". Keys must be non-empty strings " + 'and can\'t contain ".", "#", "$", "/", "[", or "]"');
+ }
+ }
+ }
+ path.push(key);
+ fb.core.util.validation.validateFirebaseData(errorPrefix, value, path);
+ path.pop();
+ });
+ if (hasDotValue && hasActualChild) {
+ throw new Error(errorPrefix + ' contains ".value" child ' + path.toErrorString() + " in addition to actual children.");
+ }
+ }
+}, validateFirebaseMergeDataArg:function(fnName, argumentNumber, data, path, optional) {
+ if (optional && !goog.isDef(data)) {
+ return;
+ }
+ if (!goog.isObject(data) || goog.isArray(data)) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + " must be an Object containing " + "the children to replace.");
+ }
+ if (fb.util.obj.contains(data, ".value")) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + ' must not contain ".value". ' + "To overwrite with a leaf value, just use .set() instead.");
+ }
+ fb.core.util.validation.validateFirebaseDataArg(fnName, argumentNumber, data, path, optional);
+}, validatePriority:function(fnName, argumentNumber, priority, optional) {
+ if (optional && !goog.isDef(priority)) {
+ return;
+ }
+ if (fb.core.util.isInvalidJSONNumber(priority)) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + "is " + priority.toString() + ", but must be a valid Firebase priority (a string, finite number, " + "server value, or null).");
+ }
+ if (!fb.core.util.validation.isValidPriority(priority)) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + "must be a valid Firebase priority " + "(a string, finite number, server value, or null).");
+ }
+}, validateEventType:function(fnName, argumentNumber, eventType, optional) {
+ if (optional && !goog.isDef(eventType)) {
+ return;
+ }
+ switch(eventType) {
+ case "value":
+ ;
+ case "child_added":
+ ;
+ case "child_removed":
+ ;
+ case "child_changed":
+ ;
+ case "child_moved":
+ break;
+ default:
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + 'must be a valid event type: "value", "child_added", "child_removed", ' + '"child_changed", or "child_moved".');;
+ }
+}, validateKey:function(fnName, argumentNumber, key, optional) {
+ if (optional && !goog.isDef(key)) {
+ return;
+ }
+ if (!fb.core.util.validation.isValidKey(key)) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + 'was an invalid key: "' + key + '". Firebase keys must be non-empty strings and ' + 'can\'t contain ".", "#", "$", "/", "[", or "]").');
+ }
+}, validatePathString:function(fnName, argumentNumber, pathString, optional) {
+ if (optional && !goog.isDef(pathString)) {
+ return;
+ }
+ if (!fb.core.util.validation.isValidPathString(pathString)) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + 'was an invalid path: "' + pathString + '". Paths must be non-empty strings and ' + 'can\'t contain ".", "#", "$", "[", or "]"');
+ }
+}, validateRootPathString:function(fnName, argumentNumber, pathString, optional) {
+ if (pathString) {
+ pathString = pathString.replace(/^\/*\.info(\/|$)/, "/");
+ }
+ fb.core.util.validation.validatePathString(fnName, argumentNumber, pathString, optional);
+}, validateWritablePath:function(fnName, path) {
+ if (path.getFront() === ".info") {
+ throw new Error(fnName + " failed: Can't modify data under /.info/");
+ }
+}, validateUrl:function(fnName, argumentNumber, parsedUrl) {
+ var pathString = parsedUrl.path.toString();
+ if (!goog.isString(parsedUrl.repoInfo.host) || parsedUrl.repoInfo.host.length === 0 || !fb.core.util.validation.isValidKey(parsedUrl.repoInfo.namespace) || pathString.length !== 0 && !fb.core.util.validation.isValidRootPathString(pathString)) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, false) + "must be a valid firebase URL and " + 'the path can\'t contain ".", "#", "$", "[", or "]".');
+ }
+}, validateCredential:function(fnName, argumentNumber, cred, optional) {
+ if (optional && !goog.isDef(cred)) {
+ return;
+ }
+ if (!goog.isString(cred)) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + "must be a valid credential (a string).");
+ }
+}, validateBoolean:function(fnName, argumentNumber, bool, optional) {
+ if (optional && !goog.isDef(bool)) {
+ return;
+ }
+ if (!goog.isBoolean(bool)) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + "must be a boolean.");
+ }
+}, validateString:function(fnName, argumentNumber, string, optional) {
+ if (optional && !goog.isDef(string)) {
+ return;
+ }
+ if (!goog.isString(string)) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + "must be a valid string.");
+ }
+}, validateAuthProvider:function(fnName, argumentNumber, provider, optional) {
+ if (optional && !goog.isDef(provider)) {
+ return;
+ }
+ fb.core.util.validation.validateString(fnName, argumentNumber, provider, optional);
+ if (!fb.core.util.validation.VALID_AUTH_PROVIDER.test(provider)) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + "'" + provider + "' is not a valid authentication provider.");
+ }
+}, validateObject:function(fnName, argumentNumber, obj, optional) {
+ if (optional && !goog.isDef(obj)) {
+ return;
+ }
+ if (!goog.isObject(obj) || obj === null) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + "must be a valid object.");
+ }
+}, validateObjectContainsKey:function(fnName, argumentNumber, obj, key, optional, opt_type) {
+ var objectContainsKey = goog.isObject(obj) && fb.util.obj.contains(obj, key);
+ if (!objectContainsKey) {
+ if (optional) {
+ return;
+ } else {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + 'must contain the key "' + key + '"');
+ }
+ }
+ if (opt_type) {
+ var val = fb.util.obj.get(obj, key);
+ if (opt_type === "number" && !goog.isNumber(val) || opt_type === "string" && !goog.isString(val) || opt_type === "boolean" && !goog.isBoolean(val) || opt_type === "function" && !goog.isFunction(val) || opt_type === "object" && !goog.isObject(val)) {
+ if (optional) {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + 'contains invalid value for key "' + key + '" (must be of type "' + opt_type + '")');
+ } else {
+ throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + 'must contain the key "' + key + '" with type "' + opt_type + '"');
+ }
+ }
+ }
+}};
+goog.provide("fb.core.util.CountedSet");
+goog.require("fb.core.util");
+goog.require("fb.util.obj");
+goog.require("goog.object");
+fb.core.util.CountedSet = goog.defineClass(null, {constructor:function() {
+ this.set = {};
+}, add:function(item, val) {
+ this.set[item] = val !== null ? val : true;
+}, contains:function(key) {
+ return fb.util.obj.contains(this.set, key);
+}, get:function(item) {
+ return this.contains(item) ? this.set[item] : undefined;
+}, remove:function(item) {
+ delete this.set[item];
+}, clear:function() {
+ this.set = {};
+}, isEmpty:function() {
+ return goog.object.isEmpty(this.set);
+}, count:function() {
+ return goog.object.getCount(this.set);
+}, each:function(fn) {
+ goog.object.forEach(this.set, function(v, k) {
+ fn(k, v);
+ });
+}, keys:function() {
+ var keys = [];
+ goog.object.forEach(this.set, function(v, k) {
+ keys.push(k);
+ });
+ return keys;
+}});
+goog.provide("fb.core.SparseSnapshotTree");
+goog.require("fb.core.snap.Node");
+goog.require("fb.core.snap.PriorityIndex");
+goog.require("fb.core.util.CountedSet");
+goog.require("fb.core.util.Path");
+fb.core.SparseSnapshotTree = function() {
+ this.value_ = null;
+ this.children_ = null;
+};
+fb.core.SparseSnapshotTree.prototype.find = function(path) {
+ if (this.value_ != null) {
+ return this.value_.getChild(path);
+ } else {
+ if (!path.isEmpty() && this.children_ != null) {
+ var childKey = path.getFront();
+ path = path.popFront();
+ if (this.children_.contains(childKey)) {
+ var childTree = this.children_.get(childKey);
+ return childTree.find(path);
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+};
+fb.core.SparseSnapshotTree.prototype.remember = function(path, data) {
+ if (path.isEmpty()) {
+ this.value_ = data;
+ this.children_ = null;
+ } else {
+ if (this.value_ !== null) {
+ this.value_ = this.value_.updateChild(path, data);
+ } else {
+ if (this.children_ == null) {
+ this.children_ = new fb.core.util.CountedSet;
+ }
+ var childKey = path.getFront();
+ if (!this.children_.contains(childKey)) {
+ this.children_.add(childKey, new fb.core.SparseSnapshotTree);
+ }
+ var child = this.children_.get(childKey);
+ path = path.popFront();
+ child.remember(path, data);
+ }
+ }
+};
+fb.core.SparseSnapshotTree.prototype.forget = function(path) {
+ if (path.isEmpty()) {
+ this.value_ = null;
+ this.children_ = null;
+ return true;
+ } else {
+ if (this.value_ !== null) {
+ if (this.value_.isLeafNode()) {
+ return false;
+ } else {
+ var value = this.value_;
+ this.value_ = null;
+ var self = this;
+ value.forEachChild(fb.core.snap.PriorityIndex, function(key, tree) {
+ self.remember(new fb.core.util.Path(key), tree);
+ });
+ return this.forget(path);
+ }
+ } else {
+ if (this.children_ !== null) {
+ var childKey = path.getFront();
+ path = path.popFront();
+ if (this.children_.contains(childKey)) {
+ var safeToRemove = this.children_.get(childKey).forget(path);
+ if (safeToRemove) {
+ this.children_.remove(childKey);
+ }
+ }
+ if (this.children_.isEmpty()) {
+ this.children_ = null;
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ }
+ }
+};
+fb.core.SparseSnapshotTree.prototype.forEachTree = function(prefixPath, func) {
+ if (this.value_ !== null) {
+ func(prefixPath, this.value_);
+ } else {
+ this.forEachChild(function(key, tree) {
+ var path = new fb.core.util.Path(prefixPath.toString() + "/" + key);
+ tree.forEachTree(path, func);
+ });
+ }
+};
+fb.core.SparseSnapshotTree.prototype.forEachChild = function(func) {
+ if (this.children_ !== null) {
+ this.children_.each(function(key, tree) {
+ func(key, tree);
+ });
+ }
+};
+goog.provide("fb.login.Constants");
+fb.login.Constants = {SESSION_PERSISTENCE_KEY_PREFIX:"session", DEFAULT_SERVER_HOST:"auth.firebase.com", SERVER_HOST:"auth.firebase.com", API_VERSION:"v2", POPUP_PATH_TO_CHANNEL:"/auth/channel", POPUP_RELAY_FRAME_NAME:"__winchan_relay_frame", POPUP_CLOSE_CMD:"die", JSONP_CALLBACK_NAMESPACE:"__firebase_auth_jsonp", REDIR_REQUEST_ID_KEY:"redirect_request_id", REDIR_REQUEST_COMPLETION_KEY:"__firebase_request_key", REDIR_CLIENT_OPTIONS_KEY:"redirect_client_options", INTERNAL_REDIRECT_SENTINAL_PATH:"/blank/page.html",
+CLIENT_OPTION_SESSION_PERSISTENCE:"remember", CLIENT_OPTION_REDIRECT_TO:"redirectTo"};
+goog.provide("fb.login.RequestInfo");
+goog.require("fb.login.Constants");
+fb.login.RequestInfo = function(opt_clientOptions, opt_transportOptions, opt_serverParams) {
+ this.clientOptions = opt_clientOptions || {};
+ this.transportOptions = opt_transportOptions || {};
+ this.serverParams = opt_serverParams || {};
+ if (!this.clientOptions[fb.login.Constants.CLIENT_OPTION_SESSION_PERSISTENCE]) {
+ this.clientOptions[fb.login.Constants.CLIENT_OPTION_SESSION_PERSISTENCE] = "default";
+ }
+};
+fb.login.RequestInfo.CLIENT_OPTIONS = [fb.login.Constants.CLIENT_OPTION_SESSION_PERSISTENCE, fb.login.Constants.CLIENT_OPTION_REDIRECT_TO];
+fb.login.RequestInfo.fromParams = function(opt_params) {
+ var clientOptions = {}, serverParams = {};
+ fb.util.obj.foreach(opt_params || {}, function(param, value) {
+ if (goog.array.contains(fb.login.RequestInfo.CLIENT_OPTIONS, param)) {
+ clientOptions[param] = value;
+ } else {
+ serverParams[param] = value;
+ }
+ });
+ return new fb.login.RequestInfo(clientOptions, {}, serverParams);
+};
+goog.provide("fb.login.SessionManager");
+goog.require("fb.core.storage");
+goog.require("fb.login.Constants");
+goog.require("fb.util.json");
+goog.require("fb.util.jwt");
+fb.login.SessionManager = function(repoInfo, stores) {
+ this.persistenceKey_ = [fb.login.Constants.SESSION_PERSISTENCE_KEY_PREFIX, repoInfo.persistenceKey, repoInfo.namespace].join(":");
+ this.stores_ = stores;
+};
+fb.login.SessionManager.prototype.set = function(data, store) {
+ if (!store) {
+ if (this.stores_.length) {
+ store = this.stores_[0];
+ } else {
+ throw new Error("fb.login.SessionManager : No storage options available!");
+ }
+ }
+ store.set(this.persistenceKey_, data);
+};
+fb.login.SessionManager.prototype.get = function() {
+ var sessions = goog.array.map(this.stores_, goog.bind(this.getFromStore_, this));
+ sessions = goog.array.filter(sessions, function(session) {
+ return session !== null;
+ });
+ goog.array.sort(sessions, function(a, b) {
+ return fb.util.jwt.issuedAtTime(b["token"]) - fb.util.jwt.issuedAtTime(a["token"]);
+ });
+ if (sessions.length > 0) {
+ return sessions.shift();
+ }
+ return null;
+};
+fb.login.SessionManager.prototype.getFromStore_ = function(store) {
+ try {
+ var session = store.get(this.persistenceKey_);
+ if (session && session["token"]) {
+ return session;
+ }
+ } catch (e) {
+ }
+ return null;
+};
+fb.login.SessionManager.prototype.clear = function(store) {
+ var stores = store ? [store] : this.stores_, self = this;
+ goog.array.forEach(this.stores_, function(store) {
+ store.remove(self.persistenceKey_);
+ });
+};
+goog.provide("fb.login.util.environment");
+fb.login.util.environment.getUA = function() {
+ if (typeof navigator !== "undefined" && typeof navigator["userAgent"] === "string") {
+ return navigator["userAgent"];
+ } else {
+ return "";
+ }
+};
+fb.login.util.environment.isMobileWrapper = function() {
+ return fb.login.util.environment.isMobileCordova() || fb.login.util.environment.isMobileWindows() || fb.login.util.environment.isIosWebview();
+};
+fb.login.util.environment.isMobileCordova = function() {
+ return typeof window !== "undefined" && !!(window["cordova"] || window["phonegap"] || window["PhoneGap"]) && /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(fb.login.util.environment.getUA());
+};
+fb.login.util.environment.isMobileWindows = function() {
+ return typeof navigator !== "undefined" && (!!fb.login.util.environment.getUA().match(/Windows Phone/) || !!window["Windows"] && /^ms-appx:/.test(location.href));
+};
+fb.login.util.environment.isMobileFirefox = function() {
+ var ua = fb.login.util.environment.getUA();
+ return ua.indexOf("Fennec/") !== -1 || ua.indexOf("Firefox/") !== -1 && ua.indexOf("Android") !== -1;
+};
+fb.login.util.environment.isIosWebview = function() {
+ var ua = fb.login.util.environment.getUA();
+ return typeof navigator !== "undefined" && typeof window !== "undefined" && !!(ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i) || ua.match(/CriOS/) || ua.match(/Twitter for iPhone/) || ua.match(/FBAN\/FBIOS/) || window["navigator"]["standalone"]);
+};
+fb.login.util.environment.isHeadlessBrowser = function() {
+ return!!fb.login.util.environment.getUA().match(/PhantomJS/);
+};
+fb.login.util.environment.isLocalFile = function() {
+ return typeof location !== "undefined" && /^file:\//.test(location.href);
+};
+fb.login.util.environment.isIE = function() {
+ var ua = fb.login.util.environment.getUA();
+ return!!(ua.match(/MSIE/) || ua.match(/Trident/));
+};
+fb.login.util.environment.isIEVersionAtLeast = function(version) {
+ var ua = fb.login.util.environment.getUA(), match;
+ if (ua === "") {
+ return false;
+ }
+ if (navigator["appName"] === "Microsoft Internet Explorer") {
+ match = ua.match(/MSIE ([0-9]{1,}[\.0-9]{0,})/);
+ if (match && match.length > 1) {
+ return parseFloat(match[1]) >= version;
+ }
+ } else {
+ if (ua.indexOf("Trident") > -1) {
+ match = ua.match(/rv:([0-9]{2,2}[\.0-9]{0,})/);
+ if (match && match.length > 1) {
+ return parseFloat(match[1]) >= version;
+ }
+ }
+ }
+ return false;
+};
+goog.provide("fb.login.transports.util");
+goog.require("fb.login.Constants");
+goog.require("fb.util");
+fb.login.transports.util.findRelay = function() {
+ var loc = window["location"], frames = window["opener"]["frames"], i;
+ for (i = frames.length - 1;i >= 0;i--) {
+ try {
+ if (frames[i]["location"]["protocol"] === window["location"]["protocol"] && frames[i]["location"]["host"] === window["location"]["host"] && frames[i]["name"] === fb.login.Constants.POPUP_RELAY_FRAME_NAME) {
+ return frames[i];
+ }
+ } catch (e) {
+ }
+ }
+ return null;
+};
+fb.login.transports.util.addListener = function(target, event, cb) {
+ if (target["attachEvent"]) {
+ target["attachEvent"]("on" + event, cb);
+ } else {
+ if (target["addEventListener"]) {
+ target["addEventListener"](event, cb, false);
+ }
+ }
+};
+fb.login.transports.util.removeListener = function(target, event, cb) {
+ if (target["detachEvent"]) {
+ target["detachEvent"]("on" + event, cb);
+ } else {
+ if (target["removeEventListener"]) {
+ target["removeEventListener"](event, cb, false);
+ }
+ }
+};
+fb.login.transports.util.extractOrigin = function(url) {
+ if (!/^https?:\/\//.test(url)) {
+ url = window["location"]["href"];
+ }
+ var m = /^(https?:\/\/[\-_a-zA-Z\.0-9:]+)/.exec(url);
+ if (m) {
+ return m[1];
+ }
+ return url;
+};
+fb.login.transports.util.extractRedirectCompletionHash = function(hashStr) {
+ var hash = "";
+ try {
+ hashStr = hashStr.replace("#", "");
+ var hashObj = fb.util.querystringDecode(hashStr);
+ if (hashObj && fb.util.obj.contains(hashObj, fb.login.Constants.REDIR_REQUEST_COMPLETION_KEY)) {
+ hash = fb.util.obj.get(hashObj, fb.login.Constants.REDIR_REQUEST_COMPLETION_KEY);
+ }
+ } catch (e) {
+ }
+ return hash;
+};
+fb.login.transports.util.replaceRedirectCompletionHash = function() {
+ try {
+ var exp = new RegExp("&" + fb.login.Constants.REDIR_REQUEST_COMPLETION_KEY + "=([a-zA-z0-9]*)");
+ document.location.hash = document.location.hash.replace(exp, "");
+ } catch (e) {
+ }
+};
+fb.login.transports.util.getBaseUrl = function() {
+ var parsedUrl = fb.core.util.parseURL(fb.login.Constants.SERVER_HOST);
+ return parsedUrl.scheme + "://" + parsedUrl.host + "/" + fb.login.Constants.API_VERSION;
+};
+fb.login.transports.util.getPopupChannelUrl = function(namespace) {
+ return fb.login.transports.util.getBaseUrl() + "/" + namespace + fb.login.Constants.POPUP_PATH_TO_CHANNEL;
+};
+goog.provide("fb.login.Transport");
+fb.login.Transport = function(options) {
+};
+fb.login.Transport.isAvailable = function() {
+};
+fb.login.Transport.prototype.open = function(url, params, onComplete) {
+};
+fb.login.Transport.prototype.classification = function() {
+};
+goog.provide("fb.login.transports.PopupReceiver");
+goog.require("fb.login.Constants");
+goog.require("fb.login.Transport");
+goog.require("fb.login.transports.util");
+goog.require("fb.login.util.environment");
+goog.require("fb.util.json");
+fb.login.transports.PopupReceiver = function(cb) {
+ var self = this;
+ this.cb = cb;
+ this.targetOrigin = "*";
+ if (fb.login.util.environment.isIEVersionAtLeast(8)) {
+ this.messageTarget = this.inboundTarget = fb.login.transports.util.findRelay();
+ } else {
+ this.messageTarget = window["opener"];
+ this.inboundTarget = window;
+ }
+ if (!self.messageTarget) {
+ throw "Unable to find relay frame";
+ }
+ fb.login.transports.util.addListener(this.inboundTarget, "message", goog.bind(this.onMessage_, this));
+ fb.login.transports.util.addListener(this.inboundTarget, "message", goog.bind(this.onDie_, this));
+ try {
+ this.doPost_({"a":"ready"});
+ } catch (e) {
+ fb.login.transports.util.addListener(this.messageTarget, "load", function(e) {
+ self.doPost_({"a":"ready"});
+ });
+ }
+ fb.login.transports.util.addListener(window, "unload", goog.bind(this.onUnload_, this));
+};
+fb.login.transports.PopupReceiver.prototype.doPost_ = function(msg) {
+ msg = fb.util.json.stringify(msg);
+ if (fb.login.util.environment.isIEVersionAtLeast(8)) {
+ this.messageTarget["doPost"](msg, this.targetOrigin);
+ } else {
+ this.messageTarget["postMessage"](msg, this.targetOrigin);
+ }
+};
+fb.login.transports.PopupReceiver.prototype.onMessage_ = function(e) {
+ var self = this, d;
+ try {
+ d = fb.util.json.eval(e["data"]);
+ } catch (err) {
+ }
+ if (!d || d["a"] !== "request") {
+ return;
+ }
+ fb.login.transports.util.removeListener(window, "message", this.onMessage_);
+ this.targetOrigin = e["origin"];
+ if (this.cb) {
+ setTimeout(function() {
+ self.cb(self.targetOrigin, d["d"], function(response, forceKeepWindowOpen) {
+ self.autoClose = !forceKeepWindowOpen;
+ self.cb = undefined;
+ self.doPost_({"a":"response", "d":response, "forceKeepWindowOpen":forceKeepWindowOpen});
+ });
+ }, 0);
+ }
+};
+fb.login.transports.PopupReceiver.prototype.onUnload_ = function() {
+ try {
+ fb.login.transports.util.removeListener(this.inboundTarget, "message", this.onDie_);
+ } catch (err) {
+ }
+ if (this.cb) {
+ this.doPost_({"a":"error", "d":"unknown closed window"});
+ this.cb = undefined;
+ }
+ try {
+ window.close();
+ } catch (err) {
+ }
+};
+fb.login.transports.PopupReceiver.prototype.onDie_ = function(e) {
+ if (this.autoClose && e["data"] === fb.login.Constants.POPUP_CLOSE_CMD) {
+ try {
+ window.close();
+ } catch (err) {
+ }
+ }
+};
+goog.provide("fb.login.transports.Redirect");
+goog.require("fb.constants");
+goog.require("fb.core.storage");
+goog.require("fb.login.Transport");
+goog.require("fb.login.transports.util");
+goog.require("fb.util");
+fb.login.transports.Redirect = function(options) {
+ this.requestId_ = goog.string.getRandomString() + goog.string.getRandomString() + goog.string.getRandomString();
+ this.options_ = options;
+};
+fb.login.transports.Redirect.prototype.open = function(url, params, cb) {
+ fb.core.storage.SessionStorage.set(fb.login.Constants.REDIR_REQUEST_ID_KEY, this.requestId_);
+ fb.core.storage.SessionStorage.set(fb.login.Constants.REDIR_REQUEST_ID_KEY, this.requestId_);
+ params["requestId"] = this.requestId_;
+ params["redirectTo"] = params["redirectTo"] || window["location"]["href"];
+ url += (/\?/.test(url) ? "" : "?") + fb.util.querystring(params);
+ window["location"] = url;
+};
+fb.login.transports.Redirect["isAvailable"] = function() {
+ return!NODE_CLIENT && !fb.login.util.environment.isLocalFile() && !fb.login.util.environment.isMobileCordova();
+};
+fb.login.transports.Redirect.prototype.classification = function() {
+ return "redirect";
+};
+goog.provide("fb.login.Errors");
+var errors = {"NETWORK_ERROR":"Unable to contact the Firebase server.", "SERVER_ERROR":"An unknown server error occurred.", "TRANSPORT_UNAVAILABLE":"There are no login transports available for the requested method.", "REQUEST_INTERRUPTED":"The browser redirected the page before the login request could complete.", "USER_CANCELLED":"The user cancelled authentication."};
+fb.login.Errors.get = function(code) {
+ var msg = fb.util.obj.get(errors, code);
+ var e = new Error(msg, code);
+ e["code"] = code;
+ return e;
+};
+goog.provide("fb.login.transports.Popup");
+goog.require("fb.core.util");
+goog.require("fb.login.Constants");
+goog.require("fb.login.Errors");
+goog.require("fb.login.Transport");
+goog.require("fb.login.transports.util");
+goog.require("fb.login.util.environment");
+goog.require("fb.util");
+goog.require("fb.util.json");
+fb.login.transports.Popup = function(options) {
+ if (!options["window_features"] || fb.login.util.environment.isMobileFirefox()) {
+ options["window_features"] = undefined;
+ }
+ if (!options["window_name"]) {
+ options["window_name"] = "_blank";
+ }
+ this.options = options;
+};
+fb.login.transports.Popup.prototype.open = function(url, params, cb) {
+ var self = this, isIE = fb.login.util.environment.isIEVersionAtLeast(8), iframe, messageTarget;
+ if (!this.options["relay_url"]) {
+ return cb(new Error("invalid arguments: origin of url and relay_url must match"));
+ }
+ var origin = fb.login.transports.util.extractOrigin(url);
+ if (origin !== fb.login.transports.util.extractOrigin(self.options["relay_url"])) {
+ if (cb) {
+ setTimeout(function() {
+ cb(new Error("invalid arguments: origin of url and relay_url must match"));
+ }, 0);
+ }
+ return;
+ }
+ if (isIE) {
+ iframe = document.createElement("iframe");
+ iframe["setAttribute"]("src", self.options["relay_url"]);
+ iframe["style"]["display"] = "none";
+ iframe["setAttribute"]("name", fb.login.Constants.POPUP_RELAY_FRAME_NAME);
+ document["body"]["appendChild"](iframe);
+ messageTarget = iframe["contentWindow"];
+ }
+ url += (/\?/.test(url) ? "" : "?") + fb.util.querystring(params);
+ var popup = window.open(url, self.options["window_name"], self.options["window_features"]);
+ if (!messageTarget) {
+ messageTarget = popup;
+ }
+ var closeInterval = setInterval(function() {
+ if (popup && popup["closed"]) {
+ cleanup(false);
+ if (cb) {
+ cb(fb.login.Errors.get("USER_CANCELLED"));
+ cb = null;
+ }
+ return;
+ }
+ }, 500);
+ var req = fb.util.json.stringify({"a":"request", "d":params});
+ function cleanup(forceKeepWindowOpen) {
+ if (iframe) {
+ document["body"]["removeChild"](iframe);
+ iframe = undefined;
+ }
+ if (closeInterval) {
+ closeInterval = clearInterval(closeInterval);
+ }
+ fb.login.transports.util.removeListener(window, "message", onMessage);
+ fb.login.transports.util.removeListener(window, "unload", cleanup);
+ if (popup && !forceKeepWindowOpen) {
+ try {
+ popup["close"]();
+ } catch (securityViolation) {
+ messageTarget["postMessage"](fb.login.Constants.POPUP_CLOSE_CMD, origin);
+ }
+ }
+ popup = messageTarget = undefined;
+ }
+ fb.login.transports.util.addListener(window, "unload", cleanup);
+ function onMessage(e) {
+ if (e["origin"] !== origin) {
+ return;
+ }
+ try {
+ var d = fb.util.json.eval(e["data"]);
+ if (d["a"] === "ready") {
+ messageTarget["postMessage"](req, origin);
+ } else {
+ if (d["a"] === "error") {
+ cleanup(false);
+ if (cb) {
+ cb(d["d"]);
+ cb = null;
+ }
+ } else {
+ if (d["a"] === "response") {
+ cleanup(d["forceKeepWindowOpen"]);
+ if (cb) {
+ cb(null, d["d"]);
+ cb = null;
+ }
+ }
+ }
+ }
+ } catch (err) {
+ }
+ }
+ fb.login.transports.util.addListener(window, "message", onMessage);
+};
+fb.login.transports.Popup["isAvailable"] = function() {
+ return!NODE_CLIENT && "postMessage" in window && !fb.login.util.environment.isLocalFile() && !fb.login.util.environment.isMobileWrapper() && !fb.login.util.environment.isHeadlessBrowser();
+};
+fb.login.transports.Popup.prototype.classification = function() {
+ return "popup";
+};
+goog.provide("fb.login.transports.NodeHttp");
+goog.require("fb.login.Constants");
+goog.require("fb.login.Errors");
+goog.require("fb.login.Transport");
+goog.require("fb.login.transports.util");
+goog.require("fb.login.util.environment");
+goog.require("fb.util");
+goog.require("fb.util.json");
+fb.login.transports.NodeHttp = function(options) {
+ if (!options["method"]) {
+ options["method"] = "GET";
+ }
+ if (!options["headers"]) {
+ options["headers"] = {};
+ }
+ if (!options["headers"]["content_type"]) {
+ options["headers"]["content_type"] = "application/json";
+ }
+ options["headers"]["content_type"] = options["headers"]["content_type"].toLowerCase();
+ this.options = options;
+};
+fb.login.transports.NodeHttp.prototype.open = function(url, params, cb) {
+ var self = this, parsedUrl = fb.core.util.parseURL(url), http = parsedUrl.scheme === "http" ? require("http") : require("https"), method = this.options["method"], payload;
+ var headers = {"Accept":"application/json;text/plain"};
+ goog.object.extend(headers, this.options["headers"]);
+ var requestOpts = {"host":parsedUrl.host.split(":")[0], "port":parsedUrl.port, "path":parsedUrl.pathString, "method":this.options["method"].toUpperCase()};
+ if (method === "GET") {
+ requestOpts["path"] += (/\?/.test(requestOpts["path"]) ? "" : "?") + fb.util.querystring(params);
+ payload = null;
+ } else {
+ var contentType = this.options["headers"]["content_type"];
+ if (contentType === "application/json") {
+ payload = fb.util.json.stringify(params);
+ }
+ if (contentType === "application/x-www-form-urlencoded") {
+ payload = fb.util.querystring(params);
+ }
+ headers["Content-Length"] = Buffer["byteLength"](payload, "utf8");
+ }
+ requestOpts["headers"] = headers;
+ var req = http["request"](requestOpts, function(response) {
+ var res = "";
+ response["setEncoding"]("utf8");
+ response["on"]("data", function(d) {
+ res += d;
+ });
+ response["on"]("end", function() {
+ try {
+ res = fb.util.json.eval(res + "");
+ } catch (e) {
+ }
+ if (cb) {
+ cb(null, res);
+ cb = null;
+ }
+ });
+ });
+ if (method !== "GET") {
+ req["write"](payload);
+ }
+ req["on"]("error", function(e) {
+ if (e && e["code"] && (e["code"] === "ENOTFOUND" || e["code"] === "ENETDOWN")) {
+ cb(fb.login.Errors.get("NETWORK_ERROR"));
+ } else {
+ cb(fb.login.Errors.get("SERVER_ERROR"));
+ }
+ cb = null;
+ });
+ req["end"]();
+};
+fb.login.transports.NodeHttp["isAvailable"] = function() {
+ return NODE_CLIENT;
+};
+fb.login.transports.NodeHttp.prototype.classification = function() {
+ return "json";
+};
+goog.provide("fb.login.transports.XHR");
+goog.require("fb.login.Constants");
+goog.require("fb.login.Errors");
+goog.require("fb.login.Transport");
+goog.require("fb.login.transports.util");
+goog.require("fb.login.util.environment");
+goog.require("fb.util");
+goog.require("fb.util.json");
+fb.login.transports.XHR = function(options) {
+ if (!options["method"]) {
+ options["method"] = "GET";
+ }
+ if (!options["headers"]) {
+ options["headers"] = {};
+ }
+ if (!options["headers"]["content_type"]) {
+ options["headers"]["content_type"] = "application/json";
+ }
+ options["headers"]["content_type"] = options["headers"]["content_type"].toLowerCase();
+ this.options = options;
+};
+fb.login.transports.XHR.prototype.open = function(url, params, cb) {
+ var self = this;
+ var xhr = new XMLHttpRequest, method = this.options["method"].toUpperCase(), payload;
+ function handleInterrupt_(e) {
+ if (cb) {
+ cb(fb.login.Errors.get("REQUEST_INTERRUPTED"));
+ cb = null;
+ }
+ }
+ fb.login.transports.util.addListener(window, "beforeunload", handleInterrupt_);
+ xhr.onreadystatechange = function() {
+ if (cb && xhr.readyState === 4) {
+ var res;
+ if (xhr.status >= 200 && xhr.status < 300) {
+ try {
+ res = fb.util.json.eval(xhr.responseText);
+ } catch (e) {
+ }
+ cb(null, res);
+ } else {
+ if (xhr.status >= 500 && xhr.status < 600) {
+ cb(fb.login.Errors.get("SERVER_ERROR"));
+ } else {
+ cb(fb.login.Errors.get("NETWORK_ERROR"));
+ }
+ }
+ cb = null;
+ fb.login.transports.util.removeListener(window, "beforeunload", handleInterrupt_);
+ }
+ };
+ if (method === "GET") {
+ url += (/\?/.test(url) ? "" : "?") + fb.util.querystring(params);
+ payload = null;
+ } else {
+ var contentType = this.options["headers"]["content_type"];
+ if (contentType === "application/json") {
+ payload = fb.util.json.stringify(params);
+ }
+ if (contentType === "application/x-www-form-urlencoded") {
+ payload = fb.util.querystring(params);
+ }
+ }
+ xhr.open(method, url, true);
+ var headers = {"X-Requested-With":"XMLHttpRequest", "Accept":"application/json;text/plain"};
+ goog.object.extend(headers, this.options["headers"]);
+ for (var header in headers) {
+ xhr.setRequestHeader(header, headers[header]);
+ }
+ xhr.send(payload);
+};
+fb.login.transports.XHR["isAvailable"] = function() {
+ return!NODE_CLIENT && !!window["XMLHttpRequest"] && (!fb.login.util.environment.isIE() || fb.login.util.environment.isIEVersionAtLeast(10));
+};
+fb.login.transports.XHR.prototype.classification = function() {
+ return "json";
+};
+goog.provide("fb.login.transports.CordovaInAppBrowser");
+goog.require("fb.core.util");
+goog.require("fb.login.Constants");
+goog.require("fb.login.Errors");
+goog.require("fb.login.RequestInfo");
+goog.require("fb.login.Transport");
+goog.require("fb.login.transports.XHR");
+goog.require("fb.login.transports.util");
+goog.require("fb.login.util.environment");
+goog.require("fb.util");
+goog.require("fb.util.json");
+fb.login.transports.CordovaInAppBrowser = function(options) {
+ this.requestId_ = goog.string.getRandomString() + goog.string.getRandomString() + goog.string.getRandomString();
+ this.options_ = options;
+};
+fb.login.transports.CordovaInAppBrowser.prototype.open = function(url, params, cb) {
+ var self = this, parsedUrl = fb.core.util.parseURL(fb.login.Constants.SERVER_HOST), windowRef;
+ function isSentinelPathMatch(url) {
+ try {
+ var a = document.createElement("a");
+ a["href"] = url;
+ return a["host"] === parsedUrl.host && a["pathname"] === fb.login.Constants.INTERNAL_REDIRECT_SENTINAL_PATH;
+ } catch (e) {
+ }
+ return false;
+ }
+ function onClose_(e) {
+ if (cb) {
+ cb(fb.login.Errors.get("USER_CANCELLED"));
+ cb = null;
+ }
+ }
+ params["requestId"] = this.requestId_;
+ params[fb.login.Constants.CLIENT_OPTION_REDIRECT_TO] = parsedUrl.scheme + "://" + parsedUrl.host + fb.login.Constants.INTERNAL_REDIRECT_SENTINAL_PATH;
+ url += /\?/.test(url) ? "" : "?";
+ url += fb.util.querystring(params);
+ windowRef = window.open(url, "_blank", "location=no");
+ if (!windowRef || !goog.isFunction(windowRef.addEventListener)) {
+ cb(fb.login.Errors.get("TRANSPORT_UNAVAILABLE"));
+ return;
+ }
+ windowRef.addEventListener("loadstart", function(e) {
+ if (!e || !e["url"] || !isSentinelPathMatch(e["url"])) {
+ return;
+ }
+ var reqKey = fb.login.transports.util.extractRedirectCompletionHash(e["url"]);
+ windowRef.removeEventListener("exit", onClose_);
+ windowRef.close();
+ var path = "/auth/session";
+ var requestInfo = new fb.login.RequestInfo(null, null, {"requestId":self.requestId_, "requestKey":reqKey});
+ self.options_["requestWithCredential"](path, requestInfo, cb);
+ cb = null;
+ });
+ windowRef.addEventListener("exit", onClose_);
+};
+fb.login.transports.CordovaInAppBrowser["isAvailable"] = function() {
+ return!NODE_CLIENT && fb.login.util.environment.isMobileCordova();
+};
+fb.login.transports.CordovaInAppBrowser.prototype.classification = function() {
+ return "redirect";
+};
+goog.provide("fb.login.transports.JSONP");
+goog.require("fb.login.Constants");
+goog.require("fb.login.Errors");
+goog.require("fb.login.Transport");
+goog.require("fb.login.transports.util");
+goog.require("fb.util");
+goog.require("fb.util.json");
+fb.login.transports.JSONP = function(options) {
+ if (!options["callback_parameter"]) {
+ options["callback_parameter"] = "callback";
+ }
+ this.options = options;
+ window[fb.login.Constants.JSONP_CALLBACK_NAMESPACE] = window[fb.login.Constants.JSONP_CALLBACK_NAMESPACE] || {};
+};
+fb.login.transports.JSONP.prototype.open = function(url, params, cb) {
+ var id = "fn" + (new Date).getTime() + Math.floor(Math.random() * 99999);
+ params[this.options["callback_parameter"]] = fb.login.Constants.JSONP_CALLBACK_NAMESPACE + "." + id;
+ url += (/\?/.test(url) ? "" : "?") + fb.util.querystring(params);
+ function handleInterrupt_(e) {
+ if (cb) {
+ cb(fb.login.Errors.get("REQUEST_INTERRUPTED"));
+ cb = null;
+ }
+ }
+ fb.login.transports.util.addListener(window, "beforeunload", handleInterrupt_);
+ function cleanup_() {
+ setTimeout(function() {
+ window[fb.login.Constants.JSONP_CALLBACK_NAMESPACE][id] = undefined;
+ if (goog.object.isEmpty(window[fb.login.Constants.JSONP_CALLBACK_NAMESPACE])) {
+ window[fb.login.Constants.JSONP_CALLBACK_NAMESPACE] = undefined;
+ }
+ try {
+ var el = document.getElementById(id);
+ if (el) {
+ el.parentNode.removeChild(el);
+ }
+ } catch (e) {
+ }
+ }, 1);
+ fb.login.transports.util.removeListener(window, "beforeunload", handleInterrupt_);
+ }
+ function onload_(res) {
+ if (cb) {
+ cb(null, res);
+ cb = null;
+ }
+ cleanup_();
+ }
+ window[fb.login.Constants.JSONP_CALLBACK_NAMESPACE][id] = onload_;
+ this.writeScriptTag_(id, url, cb);
+};
+fb.login.transports.JSONP.prototype.writeScriptTag_ = function(id, url, cb) {
+ setTimeout(function() {
+ try {
+ var js = document.createElement("script");
+ js.type = "text/javascript";
+ js.id = id;
+ js.async = true;
+ js.src = url;
+ js.onerror = function() {
+ var el = document.getElementById(id);
+ if (el !== null) {
+ el.parentNode.removeChild(el);
+ }
+ if (cb) {
+ cb(fb.login.Errors.get("NETWORK_ERROR"));
+ }
+ };
+ var ref;
+ var headElements = document.getElementsByTagName("head");
+ if (!headElements || goog.array.isEmpty(headElements)) {
+ ref = document.documentElement;
+ } else {
+ ref = headElements[0];
+ }
+ ref.appendChild(js);
+ } catch (e) {
+ if (cb) {
+ cb(fb.login.Errors.get("NETWORK_ERROR"));
+ }
+ }
+ }, 0);
+};
+fb.login.transports.JSONP["isAvailable"] = function() {
+ return typeof document !== "undefined" && goog.isDefAndNotNull(document.createElement);
+};
+fb.login.transports.JSONP.prototype.classification = function() {
+ return "json";
+};
+goog.provide("fb.login.AuthenticationManager");
+goog.require("fb.constants");
+goog.require("fb.core.storage");
+goog.require("fb.core.util");
+goog.require("fb.core.util.EventEmitter");
+goog.require("fb.login.Constants");
+goog.require("fb.login.Errors");
+goog.require("fb.login.RequestInfo");
+goog.require("fb.login.SessionManager");
+goog.require("fb.login.transports.CordovaInAppBrowser");
+goog.require("fb.login.transports.JSONP");
+goog.require("fb.login.transports.NodeHttp");
+goog.require("fb.login.transports.Popup");
+goog.require("fb.login.transports.Redirect");
+goog.require("fb.login.transports.XHR");
+fb.login.AuthenticationManager = function(repoInfo, auth, unauth, onAuthStatus) {
+ fb.core.util.EventEmitter.call(this, ["auth_status"]);
+ this.repoInfo_ = repoInfo;
+ this.authConn_ = auth;
+ this.unauthConn_ = unauth;
+ this.onAuthStatus_ = onAuthStatus;
+ this.sessionManager_ = new fb.login.SessionManager(repoInfo, [fb.core.storage.PersistentStorage, fb.core.storage.SessionStorage]);
+ this.authData_ = null;
+ this.redirectRestart_ = false;
+ this.resumeSession();
+};
+goog.inherits(fb.login.AuthenticationManager, fb.core.util.EventEmitter);
+fb.login.AuthenticationManager.prototype.getAuth = function() {
+ return this.authData_ || null;
+};
+fb.login.AuthenticationManager.prototype.resumeSession = function() {
+ var redirectRequestId = fb.core.storage.SessionStorage.get(fb.login.Constants.REDIR_REQUEST_ID_KEY), self = this;
+ if (redirectRequestId) {
+ this.finishOAuthRedirectLogin_();
+ }
+ var session = this.sessionManager_.get();
+ if (session && session["token"]) {
+ this.updateAuthStatus_(session);
+ this.authConn_(session["token"], function(status, data) {
+ self.authOnComplete_(status, data, false, session["token"], session);
+ }, function(cancelStatus, cancelReason) {
+ self.authOnCancel_("resumeSession()", cancelStatus, cancelReason);
+ });
+ } else {
+ this.updateAuthStatus_(null);
+ }
+};
+fb.login.AuthenticationManager.prototype.authenticate = function(cred, userProfile, clientOptions, opt_onComplete, opt_onCancel) {
+ if (this.repoInfo_.isDemoHost()) {
+ fb.core.util.warn("Firebase authentication is not supported on demo Firebases (*.firebaseio-demo.com). " + "To secure your Firebase, create a production Firebase at https://www.firebase.com.");
+ }
+ var self = this;
+ this.authConn_(cred, function(status, data) {
+ self.authOnComplete_(status, data, true, cred, userProfile, clientOptions || {}, opt_onComplete);
+ }, function(cancelStatus, cancelReason) {
+ self.authOnCancel_("auth()", cancelStatus, cancelReason, opt_onCancel);
+ });
+};
+fb.login.AuthenticationManager.prototype.unauthenticate = function(opt_onComplete) {
+ var self = this;
+ this.sessionManager_.clear();
+ self.updateAuthStatus_(null);
+ this.unauthConn_(function(status, errorReason) {
+ if (status === "ok") {
+ fb.core.util.callUserCallback(opt_onComplete, null);
+ } else {
+ var code = (status || "error").toUpperCase();
+ var message = code;
+ if (errorReason) {
+ message += ": " + errorReason;
+ }
+ var error = new Error(message);
+ error["code"] = code;
+ fb.core.util.callUserCallback(opt_onComplete, error);
+ }
+ });
+};
+fb.login.AuthenticationManager.prototype.authOnComplete_ = function(status, authConnResult, newSession, cred, authData, opt_clientOptions, opt_onComplete) {
+ if (status === "ok") {
+ if (newSession) {
+ var tokenPayload = authConnResult["auth"];
+ authData["auth"] = tokenPayload;
+ authData["expires"] = authConnResult["expires"];
+ authData["token"] = fb.util.jwt.isValidFormat(cred) ? cred : "";
+ var uid = null;
+ if (tokenPayload && fb.util.obj.contains(tokenPayload, "uid")) {
+ uid = fb.util.obj.get(tokenPayload, "uid");
+ } else {
+ if (fb.util.obj.contains(authData, "uid")) {
+ uid = fb.util.obj.get(authData, "uid");
+ }
+ }
+ authData["uid"] = uid;
+ var provider = "custom";
+ if (tokenPayload && fb.util.obj.contains(tokenPayload, "provider")) {
+ provider = fb.util.obj.get(tokenPayload, "provider");
+ } else {
+ if (fb.util.obj.contains(authData, "provider")) {
+ provider = fb.util.obj.get(authData, "provider");
+ }
+ }
+ authData["provider"] = provider;
+ this.sessionManager_.clear();
+ if (fb.util.jwt.isValidFormat(cred)) {
+ opt_clientOptions = opt_clientOptions || {};
+ var store = fb.core.storage.PersistentStorage;
+ if (opt_clientOptions[fb.login.Constants.CLIENT_OPTION_SESSION_PERSISTENCE] === "sessionOnly") {
+ store = fb.core.storage.SessionStorage;
+ }
+ if (opt_clientOptions[fb.login.Constants.CLIENT_OPTION_SESSION_PERSISTENCE] !== "none") {
+ this.sessionManager_.set(authData, store);
+ }
+ }
+ this.updateAuthStatus_(authData);
+ }
+ fb.core.util.callUserCallback(opt_onComplete, null, authData);
+ return;
+ }
+ this.handleBadAuthStatus_();
+ var code = (status || "error").toUpperCase();
+ var message = code;
+ if (authConnResult) {
+ message += ": " + authConnResult;
+ }
+ var error = new Error(message);
+ error["code"] = code;
+ fb.core.util.callUserCallback(opt_onComplete, error);
+};
+fb.login.AuthenticationManager.prototype.authOnCancel_ = function(fromFunction, cancelStatus, cancelReason, opt_onCancel) {
+ fb.core.util.warn(fromFunction + " was canceled: " + cancelReason);
+ this.handleBadAuthStatus_();
+ var err = new Error(cancelReason);
+ err["code"] = cancelStatus.toUpperCase();
+ fb.core.util.callUserCallback(opt_onCancel, err);
+};
+fb.login.AuthenticationManager.prototype.handleBadAuthStatus_ = function() {
+ this.sessionManager_.clear();
+ this.updateAuthStatus_(null);
+};
+fb.login.AuthenticationManager.prototype.authWithCredential = function(provider, opt_params, opt_options, opt_onComplete) {
+ this.checkServerSettingsOrThrow();
+ var requestInfo = new fb.login.RequestInfo(opt_options || {}, {}, opt_params || {});
+ var transports;
+ if (NODE_CLIENT) {
+ transports = [fb.login.transports.NodeHttp];
+ } else {
+ transports = [fb.login.transports.XHR, fb.login.transports.JSONP];
+ }
+ this.authWithTransports_(transports, "/auth/" + provider, requestInfo, opt_onComplete);
+};
+fb.login.AuthenticationManager.prototype.authWithPopup = function(provider, opt_params, opt_onComplete) {
+ this.checkServerSettingsOrThrow();
+ var transports = [fb.login.transports.Popup, fb.login.transports.CordovaInAppBrowser], requestInfo = fb.login.RequestInfo.fromParams(opt_params), width = 625, height = 625;
+ if (provider === "anonymous" || provider === "password") {
+ setTimeout(function() {
+ fb.core.util.callUserCallback(opt_onComplete, fb.login.Errors.get("TRANSPORT_UNAVAILABLE"));
+ }, 0);
+ return;
+ }
+ requestInfo.transportOptions["window_features"] = "" + "menubar=yes," + "modal=yes," + "alwaysRaised=yes" + "location=yes," + "resizable=yes," + "scrollbars=yes," + "status=yes," + "height=" + height + "," + "width=" + width + "," + "top=" + (typeof screen === "object" ? (screen["height"] - height) * .5 : 0) + "," + "left=" + (typeof screen === "object" ? (screen["width"] - width) * .5 : 0);
+ requestInfo.transportOptions["relay_url"] = fb.login.transports.util.getPopupChannelUrl(this.repoInfo_.namespace);
+ requestInfo.transportOptions["requestWithCredential"] = goog.bind(this.requestWithCredential, this);
+ this.authWithTransports_(transports, "/auth/" + provider, requestInfo, opt_onComplete);
+};
+fb.login.AuthenticationManager.prototype.authWithRedirect = function(provider, opt_params, opt_onErr) {
+ this.checkServerSettingsOrThrow();
+ var transports = [fb.login.transports.Redirect], requestInfo = fb.login.RequestInfo.fromParams(opt_params);
+ if (provider === "anonymous" || provider === "firebase") {
+ fb.core.util.callUserCallback(opt_onErr, fb.login.Errors.get("TRANSPORT_UNAVAILABLE"));
+ return;
+ }
+ fb.core.storage.SessionStorage.set(fb.login.Constants.REDIR_CLIENT_OPTIONS_KEY, requestInfo.clientOptions);
+ this.authWithTransports_(transports, "/auth/" + provider, requestInfo, opt_onErr);
+};
+fb.login.AuthenticationManager.prototype.finishOAuthRedirectLogin_ = function() {
+ var redirectRequestId = fb.core.storage.SessionStorage.get(fb.login.Constants.REDIR_REQUEST_ID_KEY);
+ if (redirectRequestId) {
+ var clientOptions = fb.core.storage.SessionStorage.get(fb.login.Constants.REDIR_CLIENT_OPTIONS_KEY);
+ fb.core.storage.SessionStorage.remove(fb.login.Constants.REDIR_REQUEST_ID_KEY);
+ fb.core.storage.SessionStorage.remove(fb.login.Constants.REDIR_CLIENT_OPTIONS_KEY);
+ var transports = [fb.login.transports.XHR, fb.login.transports.JSONP], serverParams = {"requestId":redirectRequestId, "requestKey":fb.login.transports.util.extractRedirectCompletionHash(document.location.hash)}, transportOptions = {}, requestInfo = new fb.login.RequestInfo(clientOptions, transportOptions, serverParams);
+ this.redirectRestart_ = true;
+ fb.login.transports.util.replaceRedirectCompletionHash();
+ this.authWithTransports_(transports, "/auth/session", requestInfo, function(error) {
+ this.redirectRestart_ = false;
+ }.bind(this));
+ }
+};
+fb.login.AuthenticationManager.prototype.createUser = function(params, opt_onComplete) {
+ this.checkServerSettingsOrThrow();
+ var path = "/users";
+ var requestInfo = fb.login.RequestInfo.fromParams(params);
+ requestInfo.serverParams["_method"] = "POST";
+ this.requestWithCredential(path, requestInfo, function(err, res) {
+ if (err) {
+ fb.core.util.callUserCallback(opt_onComplete, err);
+ } else {
+ fb.core.util.callUserCallback(opt_onComplete, err, res);
+ }
+ });
+};
+fb.login.AuthenticationManager.prototype.removeUser = function(params, opt_onComplete) {
+ var self = this;
+ this.checkServerSettingsOrThrow();
+ var path = "/users/" + encodeURIComponent(params["email"]);
+ var requestInfo = fb.login.RequestInfo.fromParams(params);
+ requestInfo.serverParams["_method"] = "DELETE";
+ this.requestWithCredential(path, requestInfo, function(err, res) {
+ if (!err && res && res["uid"]) {
+ if (self.authData_ && self.authData_["uid"] && self.authData_["uid"] === res["uid"]) {
+ self.unauthenticate();
+ }
+ }
+ fb.core.util.callUserCallback(opt_onComplete, err);
+ });
+};
+fb.login.AuthenticationManager.prototype.changePassword = function(params, opt_onComplete) {
+ this.checkServerSettingsOrThrow();
+ var path = "/users/" + encodeURIComponent(params["email"]) + "/password";
+ var requestInfo = fb.login.RequestInfo.fromParams(params);
+ requestInfo.serverParams["_method"] = "PUT";
+ requestInfo.serverParams["password"] = params["newPassword"];
+ this.requestWithCredential(path, requestInfo, function(err, res) {
+ fb.core.util.callUserCallback(opt_onComplete, err);
+ });
+};
+fb.login.AuthenticationManager.prototype.changeEmail = function(params, opt_onComplete) {
+ this.checkServerSettingsOrThrow();
+ var path = "/users/" + encodeURIComponent(params["oldEmail"]) + "/email";
+ var requestInfo = fb.login.RequestInfo.fromParams(params);
+ requestInfo.serverParams["_method"] = "PUT";
+ requestInfo.serverParams["email"] = params["newEmail"];
+ requestInfo.serverParams["password"] = params["password"];
+ this.requestWithCredential(path, requestInfo, function(err, res) {
+ fb.core.util.callUserCallback(opt_onComplete, err);
+ });
+};
+fb.login.AuthenticationManager.prototype.resetPassword = function(params, opt_onComplete) {
+ this.checkServerSettingsOrThrow();
+ var path = "/users/" + encodeURIComponent(params["email"]) + "/password";
+ var requestInfo = fb.login.RequestInfo.fromParams(params);
+ requestInfo.serverParams["_method"] = "POST";
+ this.requestWithCredential(path, requestInfo, function(err, res) {
+ fb.core.util.callUserCallback(opt_onComplete, err);
+ });
+};
+fb.login.AuthenticationManager.prototype.requestWithCredential = function(path, requestInfo, opt_onComplete) {
+ var transports;
+ if (NODE_CLIENT) {
+ transports = [fb.login.transports.NodeHttp];
+ } else {
+ transports = [fb.login.transports.XHR, fb.login.transports.JSONP];
+ }
+ this.requestWithTransports_(transports, path, requestInfo, opt_onComplete);
+};
+fb.login.AuthenticationManager.prototype.authWithTransports_ = function(transports, path, requestInfo, opt_onComplete) {
+ var self = this;
+ this.requestWithTransports_(transports, path, requestInfo, function onLoginReturned(err, res) {
+ if (err || !(res && res["token"] && res["uid"])) {
+ fb.core.util.callUserCallback(opt_onComplete, err || fb.login.Errors.get("UNKNOWN_ERROR"));
+ } else {
+ res = (res);
+ self.authenticate(res["token"], res, requestInfo.clientOptions, function(err, authData) {
+ if (err) {
+ fb.core.util.callUserCallback(opt_onComplete, err);
+ } else {
+ fb.core.util.callUserCallback(opt_onComplete, null, authData);
+ }
+ });
+ }
+ });
+};
+fb.login.AuthenticationManager.prototype.requestWithTransports_ = function(transports, path, requestInfo, opt_onComplete) {
+ var availableTransports = goog.array.filter(transports, function(transport) {
+ return typeof transport["isAvailable"] === "function" && transport["isAvailable"]();
+ });
+ if (availableTransports.length === 0) {
+ setTimeout(function() {
+ fb.core.util.callUserCallback(opt_onComplete, fb.login.Errors.get("TRANSPORT_UNAVAILABLE"));
+ }, 0);
+ return;
+ }
+ var transport = availableTransports.shift();
+ var transportObj = new transport(requestInfo.transportOptions);
+ var request = fb.util.obj.clone(requestInfo.serverParams);
+ request["v"] = this.versionString();
+ request["transport"] = transportObj.classification();
+ request["suppress_status_codes"] = true;
+ var url = fb.login.transports.util.getBaseUrl() + "/" + this.repoInfo_.namespace + path;
+ transportObj.open(url, request, function onTransportReturned(err, res) {
+ if (err) {
+ fb.core.util.callUserCallback(opt_onComplete, err);
+ } else {
+ if (res && res["error"]) {
+ var e = new Error(res["error"]["message"]);
+ e["code"] = res["error"]["code"];
+ e["details"] = res["error"]["details"];
+ fb.core.util.callUserCallback(opt_onComplete, e);
+ } else {
+ fb.core.util.callUserCallback(opt_onComplete, null, res);
+ }
+ }
+ });
+};
+fb.login.AuthenticationManager.prototype.updateAuthStatus_ = function(authData) {
+ var stateChanged = this.authData_ !== null || authData !== null;
+ this.authData_ = authData;
+ if (stateChanged) {
+ this.trigger("auth_status", authData);
+ }
+ this.onAuthStatus_(authData !== null);
+};
+fb.login.AuthenticationManager.prototype.getInitialEvent = function(event) {
+ fb.core.util.assert(event === "auth_status", 'initial event must be of type "auth_status"');
+ if (this.redirectRestart_) {
+ return null;
+ }
+ return[this.authData_];
+};
+fb.login.AuthenticationManager.prototype.versionString = function() {
+ return(NODE_CLIENT ? "node-" : "js-") + CLIENT_VERSION;
+};
+fb.login.AuthenticationManager.prototype.checkServerSettingsOrThrow = function() {
+ if (this.repoInfo_.isCustomHost() && fb.login.Constants.SERVER_HOST === fb.login.Constants.DEFAULT_SERVER_HOST) {
+ throw new Error("This custom Firebase server ('" + this.repoInfo_.domain + "') does not support delegated login.");
+ }
+};
+goog.provide("fb.realtime.Transport");
+goog.require("fb.core.RepoInfo");
+fb.realtime.Transport = function(connId, repoInfo, sessionId) {
+};
+fb.realtime.Transport.prototype.open = function(onMessage, onDisconnect) {
+};
+fb.realtime.Transport.prototype.start = function() {
+};
+fb.realtime.Transport.prototype.close = function() {
+};
+fb.realtime.Transport.prototype.send = function(data) {
+};
+fb.realtime.Transport.prototype.bytesReceived;
+fb.realtime.Transport.prototype.bytesSent;
+goog.provide("fb.realtime.Constants");
+fb.realtime.Constants = {PROTOCOL_VERSION:"5", VERSION_PARAM:"v", SESSION_PARAM:"s", REFERER_PARAM:"r", FORGE_REF:"f", FORGE_DOMAIN:"firebaseio.com"};
+goog.provide("fb.realtime.polling.PacketReceiver");
+fb.realtime.polling.PacketReceiver = function(onMessage) {
+ this.onMessage_ = onMessage;
+ this.pendingResponses = [];
+ this.currentResponseNum = 0;
+ this.closeAfterResponse = -1;
+ this.onClose = null;
+};
+fb.realtime.polling.PacketReceiver.prototype.closeAfter = function(responseNum, callback) {
+ this.closeAfterResponse = responseNum;
+ this.onClose = callback;
+ if (this.closeAfterResponse < this.currentResponseNum) {
+ this.onClose();
+ this.onClose = null;
+ }
+};
+fb.realtime.polling.PacketReceiver.prototype.handleResponse = function(requestNum, data) {
+ this.pendingResponses[requestNum] = data;
+ while (this.pendingResponses[this.currentResponseNum]) {
+ var toProcess = this.pendingResponses[this.currentResponseNum];
+ delete this.pendingResponses[this.currentResponseNum];
+ for (var i = 0;i < toProcess.length;++i) {
+ if (toProcess[i]) {
+ var self = this;
+ fb.core.util.exceptionGuard(function() {
+ self.onMessage_(toProcess[i]);
+ });
+ }
+ }
+ if (this.currentResponseNum === this.closeAfterResponse) {
+ if (this.onClose) {
+ clearTimeout(this.onClose);
+ this.onClose();
+ this.onClose = null;
+ }
+ break;
+ }
+ this.currentResponseNum++;
+ }
+};
+goog.provide("fb.realtime.BrowserPollConnection");
+goog.require("fb.constants");
+goog.require("fb.core.stats.StatsManager");
+goog.require("fb.core.util");
+goog.require("fb.core.util.CountedSet");
+goog.require("fb.realtime.Constants");
+goog.require("fb.realtime.Transport");
+goog.require("fb.realtime.polling.PacketReceiver");
+goog.require("fb.util.json");
+var FIREBASE_LONGPOLL_START_PARAM = "start";
+var FIREBASE_LONGPOLL_CLOSE_COMMAND = "close";
+var FIREBASE_LONGPOLL_COMMAND_CB_NAME = "pLPCommand";
+var FIREBASE_LONGPOLL_DATA_CB_NAME = "pRTLPCB";
+var FIREBASE_LONGPOLL_ID_PARAM = "id";
+var FIREBASE_LONGPOLL_PW_PARAM = "pw";
+var FIREBASE_LONGPOLL_SERIAL_PARAM = "ser";
+var FIREBASE_LONGPOLL_CALLBACK_ID_PARAM = "cb";
+var FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM = "seg";
+var FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET = "ts";
+var FIREBASE_LONGPOLL_DATA_PARAM = "d";
+var FIREBASE_LONGPOLL_DISCONN_FRAME_PARAM = "disconn";
+var FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM = "dframe";
+var MAX_URL_DATA_SIZE = 1870;
+var SEG_HEADER_SIZE = 30;
+var MAX_PAYLOAD_SIZE = MAX_URL_DATA_SIZE - SEG_HEADER_SIZE;
+var KEEPALIVE_REQUEST_INTERVAL = 25E3;
+var LP_CONNECT_TIMEOUT = 3E4;
+fb.realtime.BrowserPollConnection = function(connId, repoInfo, sessionId) {
+ this.connId = connId;
+ this.log_ = fb.core.util.logWrapper(connId);
+ this.repoInfo = repoInfo;
+ this.bytesSent = 0;
+ this.bytesReceived = 0;
+ this.stats_ = fb.core.stats.StatsManager.getCollection(repoInfo);
+ this.sessionId = sessionId;
+ this.everConnected_ = false;
+ this.urlFn = function(params) {
+ if (repoInfo.needsQueryParam()) {
+ params["ns"] = repoInfo.namespace;
+ }
+ var pairs = [];
+ for (var k in params) {
+ if (params.hasOwnProperty(k)) {
+ pairs.push(k + "=" + params[k]);
+ }
+ }
+ return(repoInfo.secure ? "https://" : "http://") + repoInfo.internalHost + "/.lp?" + pairs.join("&");
+ };
+};
+fb.realtime.BrowserPollConnection.prototype.open = function(onMessage, onDisconnect) {
+ this.curSegmentNum = 0;
+ this.onDisconnect_ = onDisconnect;
+ this.myPacketOrderer = new fb.realtime.polling.PacketReceiver(onMessage);
+ this.isClosed_ = false;
+ var self = this;
+ this.connectTimeoutTimer_ = setTimeout(function() {
+ self.log_("Timed out trying to connect.");
+ self.onClosed_();
+ self.connectTimeoutTimer_ = null;
+ }, Math.floor(LP_CONNECT_TIMEOUT));
+ fb.core.util.executeWhenDOMReady(function() {
+ if (self.isClosed_) {
+ return;
+ }
+ self.scriptTagHolder = new FirebaseIFrameScriptHolder(function(command, arg1, arg2, arg3, arg4) {
+ self.incrementIncomingBytes_(arguments);
+ if (!self.scriptTagHolder) {
+ return;
+ }
+ if (self.connectTimeoutTimer_) {
+ clearTimeout(self.connectTimeoutTimer_);
+ self.connectTimeoutTimer_ = null;
+ }
+ self.everConnected_ = true;
+ if (command == FIREBASE_LONGPOLL_START_PARAM) {
+ self.id = arg1;
+ self.password = arg2;
+ } else {
+ if (command === FIREBASE_LONGPOLL_CLOSE_COMMAND) {
+ if (arg1) {
+ self.scriptTagHolder.sendNewPolls = false;
+ self.myPacketOrderer.closeAfter(arg1, function() {
+ self.onClosed_();
+ });
+ } else {
+ self.onClosed_();
+ }
+ } else {
+ throw new Error("Unrecognized command received: " + command);
+ }
+ }
+ }, function(pN, data) {
+ self.incrementIncomingBytes_(arguments);
+ self.myPacketOrderer.handleResponse(pN, data);
+ }, function() {
+ self.onClosed_();
+ }, self.urlFn);
+ var urlParams = {};
+ urlParams[FIREBASE_LONGPOLL_START_PARAM] = "t";
+ urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = Math.floor(Math.random() * 1E8);
+ if (self.scriptTagHolder.uniqueCallbackIdentifier) {
+ urlParams[FIREBASE_LONGPOLL_CALLBACK_ID_PARAM] = self.scriptTagHolder.uniqueCallbackIdentifier;
+ }
+ urlParams[fb.realtime.Constants.VERSION_PARAM] = fb.realtime.Constants.PROTOCOL_VERSION;
+ if (self.sessionId) {
+ urlParams[fb.realtime.Constants.SESSION_PARAM] = self.sessionId;
+ }
+ if (!NODE_CLIENT && typeof location !== "undefined" && location.href && location.href.indexOf(fb.realtime.Constants.FORGE_DOMAIN) !== -1) {
+ urlParams[fb.realtime.Constants.REFERER_PARAM] = fb.realtime.Constants.FORGE_REF;
+ }
+ var connectURL = self.urlFn(urlParams);
+ self.log_("Connecting via long-poll to " + connectURL);
+ self.scriptTagHolder.addTag(connectURL, function() {
+ });
+ });
+};
+fb.realtime.BrowserPollConnection.prototype.start = function() {
+ this.scriptTagHolder.startLongPoll(this.id, this.password);
+ this.addDisconnectPingFrame(this.id, this.password);
+};
+fb.realtime.BrowserPollConnection.forceAllow = function() {
+ fb.realtime.BrowserPollConnection.forceAllow_ = true;
+};
+fb.realtime.BrowserPollConnection.forceDisallow = function() {
+ fb.realtime.BrowserPollConnection.forceDisallow_ = true;
+};
+fb.realtime.BrowserPollConnection["isAvailable"] = function() {
+ return fb.realtime.BrowserPollConnection.forceAllow_ || !fb.realtime.BrowserPollConnection.forceDisallow_ && typeof document !== "undefined" && goog.isDefAndNotNull(document.createElement) && !fb.core.util.isChromeExtensionContentScript() && !fb.core.util.isWindowsStoreApp();
+};
+fb.realtime.BrowserPollConnection.prototype.markConnectionHealthy = function() {
+};
+fb.realtime.BrowserPollConnection.prototype.shutdown_ = function() {
+ this.isClosed_ = true;
+ if (this.scriptTagHolder) {
+ this.scriptTagHolder.close();
+ this.scriptTagHolder = null;
+ }
+ if (this.myDisconnFrame) {
+ document.body.removeChild(this.myDisconnFrame);
+ this.myDisconnFrame = null;
+ }
+ if (this.connectTimeoutTimer_) {
+ clearTimeout(this.connectTimeoutTimer_);
+ this.connectTimeoutTimer_ = null;
+ }
+};
+fb.realtime.BrowserPollConnection.prototype.onClosed_ = function() {
+ if (!this.isClosed_) {
+ this.log_("Longpoll is closing itself");
+ this.shutdown_();
+ if (this.onDisconnect_) {
+ this.onDisconnect_(this.everConnected_);
+ this.onDisconnect_ = null;
+ }
+ }
+};
+fb.realtime.BrowserPollConnection.prototype.close = function() {
+ if (!this.isClosed_) {
+ this.log_("Longpoll is being closed.");
+ this.shutdown_();
+ }
+};
+fb.realtime.BrowserPollConnection.prototype.send = function(data) {
+ var dataStr = fb.util.json.stringify(data);
+ this.bytesSent += dataStr.length;
+ this.stats_.incrementCounter("bytes_sent", dataStr.length);
+ var base64data = fb.core.util.base64Encode(dataStr);
+ var dataSegs = fb.core.util.splitStringBySize(base64data, MAX_PAYLOAD_SIZE);
+ for (var i = 0;i < dataSegs.length;i++) {
+ this.scriptTagHolder.enqueueSegment(this.curSegmentNum, dataSegs.length, dataSegs[i]);
+ this.curSegmentNum++;
+ }
+};
+fb.realtime.BrowserPollConnection.prototype.addDisconnectPingFrame = function(id, pw) {
+ if (NODE_CLIENT) {
+ return;
+ }
+ this.myDisconnFrame = document.createElement("iframe");
+ var urlParams = {};
+ urlParams[FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM] = "t";
+ urlParams[FIREBASE_LONGPOLL_ID_PARAM] = id;
+ urlParams[FIREBASE_LONGPOLL_PW_PARAM] = pw;
+ this.myDisconnFrame.src = this.urlFn(urlParams);
+ this.myDisconnFrame.style.display = "none";
+ document.body.appendChild(this.myDisconnFrame);
+};
+fb.realtime.BrowserPollConnection.prototype.incrementIncomingBytes_ = function(args) {
+ var bytesReceived = fb.util.json.stringify(args).length;
+ this.bytesReceived += bytesReceived;
+ this.stats_.incrementCounter("bytes_received", bytesReceived);
+};
+function FirebaseIFrameScriptHolder(commandCB, onMessageCB, onDisconnectCB, urlFn) {
+ this.urlFn = urlFn;
+ this.onDisconnect = onDisconnectCB;
+ this.outstandingRequests = new fb.core.util.CountedSet;
+ this.pendingSegs = [];
+ this.currentSerial = Math.floor(Math.random() * 1E8);
+ this.sendNewPolls = true;
+ if (!NODE_CLIENT) {
+ this.uniqueCallbackIdentifier = fb.core.util.LUIDGenerator();
+ window[FIREBASE_LONGPOLL_COMMAND_CB_NAME + this.uniqueCallbackIdentifier] = commandCB;
+ window[FIREBASE_LONGPOLL_DATA_CB_NAME + this.uniqueCallbackIdentifier] = onMessageCB;
+ this.myIFrame = this.createIFrame_();
+ var script = "";
+ if (this.myIFrame.src && this.myIFrame.src.substr(0, "javascript:".length) === "javascript:") {
+ var currentDomain = document.domain;
+ script = '<script>document.domain="' + currentDomain + '";\x3c/script>';
+ }
+ var iframeContents = "<html><body>" + script + "</body></html>";
+ try {
+ this.myIFrame.doc.open();
+ this.myIFrame.doc.write(iframeContents);
+ this.myIFrame.doc.close();
+ } catch (e) {
+ fb.core.util.log("frame writing exception");
+ if (e.stack) {
+ fb.core.util.log(e.stack);
+ }
+ fb.core.util.log(e);
+ }
+ } else {
+ this.commandCB = commandCB;
+ this.onMessageCB = onMessageCB;
+ }
+}
+FirebaseIFrameScriptHolder.prototype.createIFrame_ = function() {
+ var iframe = document.createElement("iframe");
+ iframe.style.display = "none";
+ if (document.body) {
+ document.body.appendChild(iframe);
+ try {
+ var a = iframe.contentWindow.document;
+ if (!a) {
+ fb.core.util.log("No IE domain setting required");
+ }
+ } catch (e) {
+ var domain = document.domain;
+ iframe.src = "javascript:void((function(){document.open();document.domain='" + domain + "';document.close();})())";
+ }
+ } else {
+ throw "Document body has not initialized. Wait to initialize Firebase until after the document is ready.";
+ }
+ if (iframe.contentDocument) {
+ iframe.doc = iframe.contentDocument;
+ } else {
+ if (iframe.contentWindow) {
+ iframe.doc = iframe.contentWindow.document;
+ } else {
+ if (iframe.document) {
+ iframe.doc = iframe.document;
+ }
+ }
+ }
+ return iframe;
+};
+FirebaseIFrameScriptHolder.prototype.close = function() {
+ this.alive = false;
+ if (this.myIFrame) {
+ this.myIFrame.doc.body.innerHTML = "";
+ var self = this;
+ setTimeout(function() {
+ if (self.myIFrame !== null) {
+ document.body.removeChild(self.myIFrame);
+ self.myIFrame = null;
+ }
+ }, Math.floor(0));
+ }
+ if (NODE_CLIENT && this.myID) {
+ var urlParams = {};
+ urlParams[FIREBASE_LONGPOLL_DISCONN_FRAME_PARAM] = "t";
+ urlParams[FIREBASE_LONGPOLL_ID_PARAM] = this.myID;
+ urlParams[FIREBASE_LONGPOLL_PW_PARAM] = this.myPW;
+ var theURL = this.urlFn(urlParams);
+ FirebaseIFrameScriptHolder.nodeRestRequest(theURL);
+ }
+ var onDisconnect = this.onDisconnect;
+ if (onDisconnect) {
+ this.onDisconnect = null;
+ onDisconnect();
+ }
+};
+FirebaseIFrameScriptHolder.prototype.startLongPoll = function(id, pw) {
+ this.myID = id;
+ this.myPW = pw;
+ this.alive = true;
+ while (this.newRequest_()) {
+ }
+};
+FirebaseIFrameScriptHolder.prototype.newRequest_ = function() {
+ if (this.alive && this.sendNewPolls && this.outstandingRequests.count() < (this.pendingSegs.length > 0 ? 2 : 1)) {
+ this.currentSerial++;
+ var urlParams = {};
+ urlParams[FIREBASE_LONGPOLL_ID_PARAM] = this.myID;
+ urlParams[FIREBASE_LONGPOLL_PW_PARAM] = this.myPW;
+ urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = this.currentSerial;
+ var theURL = this.urlFn(urlParams);
+ var curDataString = "";
+ var i = 0;
+ while (this.pendingSegs.length > 0) {
+ var nextSeg = this.pendingSegs[0];
+ if (nextSeg.d.length + SEG_HEADER_SIZE + curDataString.length <= MAX_URL_DATA_SIZE) {
+ var theSeg = this.pendingSegs.shift();
+ curDataString = curDataString + "&" + FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM + i + "=" + theSeg.seg + "&" + FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET + i + "=" + theSeg.ts + "&" + FIREBASE_LONGPOLL_DATA_PARAM + i + "=" + theSeg.d;
+ i++;
+ } else {
+ break;
+ }
+ }
+ theURL = theURL + curDataString;
+ this.addLongPollTag_(theURL, this.currentSerial);
+ return true;
+ } else {
+ return false;
+ }
+};
+FirebaseIFrameScriptHolder.prototype.enqueueSegment = function(segnum, totalsegs, data) {
+ this.pendingSegs.push({seg:segnum, ts:totalsegs, d:data});
+ if (this.alive) {
+ this.newRequest_();
+ }
+};
+FirebaseIFrameScriptHolder.prototype.addLongPollTag_ = function(url, serial) {
+ var self = this;
+ self.outstandingRequests.add(serial, 1);
+ var doNewRequest = function() {
+ self.outstandingRequests.remove(serial);
+ self.newRequest_();
+ };
+ var keepaliveTimeout = setTimeout(doNewRequest, Math.floor(KEEPALIVE_REQUEST_INTERVAL));
+ var readyStateCB = function() {
+ clearTimeout(keepaliveTimeout);
+ doNewRequest();
+ };
+ this.addTag(url, readyStateCB);
+};
+FirebaseIFrameScriptHolder.prototype.addTag = function(url, loadCB) {
+ if (NODE_CLIENT) {
+ this.doNodeLongPoll(url, loadCB);
+ } else {
+ var self = this;
+ setTimeout(function() {
+ try {
+ if (!self.sendNewPolls) {
+ return;
+ }
+ var newScript = self.myIFrame.doc.createElement("script");
+ newScript.type = "text/javascript";
+ newScript.async = true;
+ newScript.src = url;
+ newScript.onload = newScript.onreadystatechange = function() {
+ var rstate = newScript.readyState;
+ if (!rstate || rstate === "loaded" || rstate === "complete") {
+ newScript.onload = newScript.onreadystatechange = null;
+ if (newScript.parentNode) {
+ newScript.parentNode.removeChild(newScript);
+ }
+ loadCB();
+ }
+ };
+ newScript.onerror = function() {
+ fb.core.util.log("Long-poll script failed to load: " + url);
+ self.sendNewPolls = false;
+ self.close();
+ };
+ self.myIFrame.doc.body.appendChild(newScript);
+ } catch (e) {
+ }
+ }, Math.floor(1));
+ }
+};
+if (typeof NODE_CLIENT !== "undefined" && NODE_CLIENT) {
+ FirebaseIFrameScriptHolder.request = null;
+ FirebaseIFrameScriptHolder.nodeRestRequest = function(req, onComplete) {
+ if (!FirebaseIFrameScriptHolder.request) {
+ FirebaseIFrameScriptHolder.request = (require("request"));
+ }
+ FirebaseIFrameScriptHolder.request(req, function(error, response, body) {
+ if (error) {
+ throw "Rest request for " + req.url + " failed.";
+ }
+ if (onComplete) {
+ onComplete(body);
+ }
+ });
+ };
+ FirebaseIFrameScriptHolder.prototype.doNodeLongPoll = function(url, loadCB) {
+ var self = this;
+ FirebaseIFrameScriptHolder.nodeRestRequest({url:url, forever:true}, function(body) {
+ self.evalBody(body);
+ loadCB();
+ });
+ };
+ FirebaseIFrameScriptHolder.prototype.evalBody = function(body) {
+ eval("var jsonpCB = function(" + FIREBASE_LONGPOLL_COMMAND_CB_NAME + ", " + FIREBASE_LONGPOLL_DATA_CB_NAME + ") {" + body + "}");
+ jsonpCB(this.commandCB, this.onMessageCB);
+ };
+}
+;goog.provide("fb.realtime.WebSocketConnection");
+goog.require("fb.constants");
+goog.require("fb.core.stats.StatsManager");
+goog.require("fb.core.storage");
+goog.require("fb.core.util");
+goog.require("fb.realtime.Constants");
+goog.require("fb.realtime.Transport");
+goog.require("fb.util.json");
+var WEBSOCKET_MAX_FRAME_SIZE = 16384;
+var WEBSOCKET_KEEPALIVE_INTERVAL = 45E3;
+fb.WebSocket = null;
+if (NODE_CLIENT) {
+ goog.require("fb.core.util.NodePatches");
+ fb.WebSocket = require("faye-websocket")["Client"];
+} else {
+ if (typeof MozWebSocket !== "undefined") {
+ fb.WebSocket = MozWebSocket;
+ } else {
+ if (typeof WebSocket !== "undefined") {
+ fb.WebSocket = WebSocket;
+ }
+ }
+}
+fb.realtime.WebSocketConnection = function(connId, repoInfo, sessionId) {
+ this.connId = connId;
+ this.log_ = fb.core.util.logWrapper(this.connId);
+ this.keepaliveTimer = null;
+ this.frames = null;
+ this.totalFrames = 0;
+ this.bytesSent = 0;
+ this.bytesReceived = 0;
+ this.stats_ = fb.core.stats.StatsManager.getCollection(repoInfo);
+ this.connURL = (repoInfo.secure ? "wss://" : "ws://") + repoInfo.internalHost + "/.ws?" + fb.realtime.Constants.VERSION_PARAM + "=" + fb.realtime.Constants.PROTOCOL_VERSION;
+ if (!NODE_CLIENT && typeof location !== "undefined" && location.href && location.href.indexOf(fb.realtime.Constants.FORGE_DOMAIN) !== -1) {
+ this.connURL = this.connURL + "&" + fb.realtime.Constants.REFERER_PARAM + "=" + fb.realtime.Constants.FORGE_REF;
+ }
+ if (repoInfo.needsQueryParam()) {
+ this.connURL = this.connURL + "&ns=" + repoInfo.namespace;
+ }
+ if (sessionId) {
+ this.connURL = this.connURL + "&" + fb.realtime.Constants.SESSION_PARAM + "=" + sessionId;
+ }
+};
+fb.realtime.WebSocketConnection.prototype.open = function(onMess, onDisconn) {
+ this.onDisconnect = onDisconn;
+ this.onMessage = onMess;
+ this.log_("Websocket connecting to " + this.connURL);
+ this.everConnected_ = false;
+ fb.core.storage.PersistentStorage.set("previous_websocket_failure", true);
+ try {
+ if (NODE_CLIENT) {
+ var options = {"headers":{"User-Agent":"Firebase/" + fb.realtime.Constants.PROTOCOL_VERSION + "/" + CLIENT_VERSION + "/" + process.platform + "/Node"}};
+ this.mySock = new fb.WebSocket(this.connURL, [], options);
+ } else {
+ this.mySock = new fb.WebSocket(this.connURL);
+ }
+ } catch (e) {
+ this.log_("Error instantiating WebSocket.");
+ var error = e.message || e.data;
+ if (error) {
+ this.log_(error);
+ }
+ this.onClosed_();
+ return;
+ }
+ var self = this;
+ this.mySock.onopen = function() {
+ self.log_("Websocket connected.");
+ self.everConnected_ = true;
+ };
+ this.mySock.onclose = function() {
+ self.log_("Websocket connection was disconnected.");
+ self.mySock = null;
+ self.onClosed_();
+ };
+ this.mySock.onmessage = function(m) {
+ self.handleIncomingFrame(m);
+ };
+ this.mySock.onerror = function(e) {
+ self.log_("WebSocket error. Closing connection.");
+ var error = e.message || e.data;
+ if (error) {
+ self.log_(error);
+ }
+ self.onClosed_();
+ };
+};
+fb.realtime.WebSocketConnection.prototype.start = function() {
+};
+fb.realtime.WebSocketConnection.forceDisallow = function() {
+ fb.realtime.WebSocketConnection.forceDisallow_ = true;
+};
+fb.realtime.WebSocketConnection["isAvailable"] = function() {
+ var isOldAndroid = false;
+ if (typeof navigator !== "undefined" && navigator.userAgent) {
+ var oldAndroidRegex = /Android ([0-9]{0,}\.[0-9]{0,})/;
+ var oldAndroidMatch = navigator.userAgent.match(oldAndroidRegex);
+ if (oldAndroidMatch && oldAndroidMatch.length > 1) {
+ if (parseFloat(oldAndroidMatch[1]) < 4.4) {
+ isOldAndroid = true;
+ }
+ }
+ }
+ return!isOldAndroid && fb.WebSocket !== null && !fb.realtime.WebSocketConnection.forceDisallow_;
+};
+fb.realtime.WebSocketConnection["responsesRequiredToBeHealthy"] = 2;
+fb.realtime.WebSocketConnection["healthyTimeout"] = 3E4;
+fb.realtime.WebSocketConnection.previouslyFailed = function() {
+ return fb.core.storage.PersistentStorage.isInMemoryStorage || fb.core.storage.PersistentStorage.get("previous_websocket_failure") === true;
+};
+fb.realtime.WebSocketConnection.prototype.markConnectionHealthy = function() {
+ fb.core.storage.PersistentStorage.remove("previous_websocket_failure");
+};
+fb.realtime.WebSocketConnection.prototype.appendFrame_ = function(data) {
+ this.frames.push(data);
+ if (this.frames.length == this.totalFrames) {
+ var fullMess = this.frames.join("");
+ this.frames = null;
+ var jsonMess = fb.util.json.eval(fullMess);
+ this.onMessage(jsonMess);
+ }
+};
+fb.realtime.WebSocketConnection.prototype.handleNewFrameCount_ = function(frameCount) {
+ this.totalFrames = frameCount;
+ this.frames = [];
+};
+fb.realtime.WebSocketConnection.prototype.extractFrameCount_ = function(data) {
+ fb.core.util.assert(this.frames === null, "We already have a frame buffer");
+ if (data.length <= 6) {
+ var frameCount = Number(data);
+ if (!isNaN(frameCount)) {
+ this.handleNewFrameCount_(frameCount);
+ return null;
+ }
+ }
+ this.handleNewFrameCount_(1);
+ return data;
+};
+fb.realtime.WebSocketConnection.prototype.handleIncomingFrame = function(mess) {
+ if (this.mySock === null) {
+ return;
+ }
+ var data = mess["data"];
+ this.bytesReceived += data.length;
+ this.stats_.incrementCounter("bytes_received", data.length);
+ this.resetKeepAlive();
+ if (this.frames !== null) {
+ this.appendFrame_(data);
+ } else {
+ var remainingData = this.extractFrameCount_(data);
+ if (remainingData !== null) {
+ this.appendFrame_(remainingData);
+ }
+ }
+};
+fb.realtime.WebSocketConnection.prototype.send = function(data) {
+ this.resetKeepAlive();
+ var dataStr = fb.util.json.stringify(data);
+ this.bytesSent += dataStr.length;
+ this.stats_.incrementCounter("bytes_sent", dataStr.length);
+ var dataSegs = fb.core.util.splitStringBySize(dataStr, WEBSOCKET_MAX_FRAME_SIZE);
+ if (dataSegs.length > 1) {
+ this.mySock.send(String(dataSegs.length));
+ }
+ for (var i = 0;i < dataSegs.length;i++) {
+ this.mySock.send(dataSegs[i]);
+ }
+};
+fb.realtime.WebSocketConnection.prototype.shutdown_ = function() {
+ this.isClosed_ = true;
+ if (this.keepaliveTimer) {
+ clearInterval(this.keepaliveTimer);
+ this.keepaliveTimer = null;
+ }
+ if (this.mySock) {
+ this.mySock.close();
+ this.mySock = null;
+ }
+};
+fb.realtime.WebSocketConnection.prototype.onClosed_ = function() {
+ if (!this.isClosed_) {
+ this.log_("WebSocket is closing itself");
+ this.shutdown_();
+ if (this.onDisconnect) {
+ this.onDisconnect(this.everConnected_);
+ this.onDisconnect = null;
+ }
+ }
+};
+fb.realtime.WebSocketConnection.prototype.close = function() {
+ if (!this.isClosed_) {
+ this.log_("WebSocket is being closed");
+ this.shutdown_();
+ }
+};
+fb.realtime.WebSocketConnection.prototype.resetKeepAlive = function() {
+ var self = this;
+ clearInterval(this.keepaliveTimer);
+ this.keepaliveTimer = setInterval(function() {
+ if (self.mySock) {
+ self.mySock.send("0");
+ }
+ self.resetKeepAlive();
+ }, Math.floor(WEBSOCKET_KEEPALIVE_INTERVAL));
+};
+goog.require("fb.constants");
+goog.require("fb.realtime.BrowserPollConnection");
+goog.require("fb.realtime.Transport");
+goog.provide("fb.realtime.TransportManager");
+goog.require("fb.realtime.WebSocketConnection");
+fb.realtime.TransportManager = function(repoInfo) {
+ this.initTransports_(repoInfo);
+};
+fb.realtime.TransportManager.ALL_TRANSPORTS = [fb.realtime.BrowserPollConnection, fb.realtime.WebSocketConnection];
+fb.realtime.TransportManager.prototype.initTransports_ = function(repoInfo) {
+ var isWebSocketsAvailable = fb.realtime.WebSocketConnection && fb.realtime.WebSocketConnection["isAvailable"]();
+ var isSkipPollConnection = isWebSocketsAvailable && !fb.realtime.WebSocketConnection.previouslyFailed();
+ if (repoInfo.webSocketOnly) {
+ if (!isWebSocketsAvailable) {
+ fb.core.util.warn("wss:// URL used, but browser isn't known to support websockets. Trying anyway.");
+ }
+ isSkipPollConnection = true;
+ }
+ if (isSkipPollConnection) {
+ this.transports_ = [fb.realtime.WebSocketConnection];
+ } else {
+ var transports = this.transports_ = [];
+ fb.core.util.each(fb.realtime.TransportManager.ALL_TRANSPORTS, function(i, transport) {
+ if (transport && transport["isAvailable"]()) {
+ transports.push(transport);
+ }
+ });
+ }
+};
+fb.realtime.TransportManager.prototype.initialTransport = function() {
+ if (this.transports_.length > 0) {
+ return this.transports_[0];
+ } else {
+ throw new Error("No transports available");
+ }
+};
+fb.realtime.TransportManager.prototype.upgradeTransport = function() {
+ if (this.transports_.length > 1) {
+ return this.transports_[1];
+ } else {
+ return null;
+ }
+};
+goog.provide("fb.realtime.Connection");
+goog.require("fb.core.storage");
+goog.require("fb.core.util");
+goog.require("fb.realtime.Constants");
+goog.require("fb.realtime.TransportManager");
+var UPGRADE_TIMEOUT = 6E4;
+var DELAY_BEFORE_SENDING_EXTRA_REQUESTS = 5E3;
+var BYTES_SENT_HEALTHY_OVERRIDE = 10 * 1024;
+var BYTES_RECEIVED_HEALTHY_OVERRIDE = 100 * 1024;
+var REALTIME_STATE_CONNECTING = 0;
+var REALTIME_STATE_CONNECTED = 1;
+var REALTIME_STATE_DISCONNECTED = 2;
+var MESSAGE_TYPE = "t";
+var MESSAGE_DATA = "d";
+var CONTROL_SHUTDOWN = "s";
+var CONTROL_RESET = "r";
+var CONTROL_ERROR = "e";
+var CONTROL_PONG = "o";
+var SWITCH_ACK = "a";
+var END_TRANSMISSION = "n";
+var PING = "p";
+var SERVER_HELLO = "h";
+fb.realtime.Connection = function(connId, repoInfo, onMessage, onReady, onDisconnect, onKill) {
+ this.id = connId;
+ this.log_ = fb.core.util.logWrapper("c:" + this.id + ":");
+ this.onMessage_ = onMessage;
+ this.onReady_ = onReady;
+ this.onDisconnect_ = onDisconnect;
+ this.onKill_ = onKill;
+ this.repoInfo_ = repoInfo;
+ this.pendingDataMessages = [];
+ this.connectionCount = 0;
+ this.transportManager_ = new fb.realtime.TransportManager(repoInfo);
+ this.state_ = REALTIME_STATE_CONNECTING;
+ this.log_("Connection created");
+ this.start_();
+};
+fb.realtime.Connection.prototype.start_ = function() {
+ var conn = this.transportManager_.initialTransport();
+ this.conn_ = new conn(this.nextTransportId_(), this.repoInfo_);
+ this.primaryResponsesRequired_ = conn["responsesRequiredToBeHealthy"] || 0;
+ var onMessageReceived = this.connReceiver_(this.conn_);
+ var onConnectionLost = this.disconnReceiver_(this.conn_);
+ this.tx_ = this.conn_;
+ this.rx_ = this.conn_;
+ this.secondaryConn_ = null;
+ this.isHealthy_ = false;
+ var self = this;
+ setTimeout(function() {
+ self.conn_ && self.conn_.open(onMessageReceived, onConnectionLost);
+ }, Math.floor(0));
+ var healthyTimeout_ms = conn["healthyTimeout"] || 0;
+ if (healthyTimeout_ms > 0) {
+ this.healthyTimeout_ = setTimeout(function() {
+ self.healthyTimeout_ = null;
+ if (!self.isHealthy_) {
+ if (self.conn_ && self.conn_.bytesReceived > BYTES_RECEIVED_HEALTHY_OVERRIDE) {
+ self.log_("Connection exceeded healthy timeout but has received " + self.conn_.bytesReceived + " bytes. Marking connection healthy.");
+ self.isHealthy_ = true;
+ self.conn_.markConnectionHealthy();
+ } else {
+ if (self.conn_ && self.conn_.bytesSent > BYTES_SENT_HEALTHY_OVERRIDE) {
+ self.log_("Connection exceeded healthy timeout but has sent " + self.conn_.bytesSent + " bytes. Leaving connection alive.");
+ } else {
+ self.log_("Closing unhealthy connection after timeout.");
+ self.close();
+ }
+ }
+ }
+ }, Math.floor(healthyTimeout_ms));
+ }
+};
+fb.realtime.Connection.prototype.nextTransportId_ = function() {
+ return "c:" + this.id + ":" + this.connectionCount++;
+};
+fb.realtime.Connection.prototype.disconnReceiver_ = function(conn) {
+ var self = this;
+ return function(everConnected) {
+ if (conn === self.conn_) {
+ self.onConnectionLost_(everConnected);
+ } else {
+ if (conn === self.secondaryConn_) {
+ self.log_("Secondary connection lost.");
+ self.onSecondaryConnectionLost_();
+ } else {
+ self.log_("closing an old connection");
+ }
+ }
+ };
+};
+fb.realtime.Connection.prototype.connReceiver_ = function(conn) {
+ var self = this;
+ return function(message) {
+ if (self.state_ != REALTIME_STATE_DISCONNECTED) {
+ if (conn === self.rx_) {
+ self.onPrimaryMessageReceived_(message);
+ } else {
+ if (conn === self.secondaryConn_) {
+ self.onSecondaryMessageReceived_(message);
+ } else {
+ self.log_("message on old connection");
+ }
+ }
+ }
+ };
+};
+fb.realtime.Connection.prototype.sendRequest = function(dataMsg) {
+ var msg = {"t":"d", "d":dataMsg};
+ this.sendData_(msg);
+};
+fb.realtime.Connection.prototype.tryCleanupConnection = function() {
+ if (this.tx_ === this.secondaryConn_ && this.rx_ === this.secondaryConn_) {
+ this.log_("cleaning up and promoting a connection: " + this.secondaryConn_.connId);
+ this.conn_ = this.secondaryConn_;
+ this.secondaryConn_ = null;
+ }
+};
+fb.realtime.Connection.prototype.onSecondaryControl_ = function(controlData) {
+ if (MESSAGE_TYPE in controlData) {
+ var cmd = controlData[MESSAGE_TYPE];
+ if (cmd === SWITCH_ACK) {
+ this.upgradeIfSecondaryHealthy_();
+ } else {
+ if (cmd === CONTROL_RESET) {
+ this.log_("Got a reset on secondary, closing it");
+ this.secondaryConn_.close();
+ if (this.tx_ === this.secondaryConn_ || this.rx_ === this.secondaryConn_) {
+ this.close();
+ }
+ } else {
+ if (cmd === CONTROL_PONG) {
+ this.log_("got pong on secondary.");
+ this.secondaryResponsesRequired_--;
+ this.upgradeIfSecondaryHealthy_();
+ }
+ }
+ }
+ }
+};
+fb.realtime.Connection.prototype.onSecondaryMessageReceived_ = function(parsedData) {
+ var layer = fb.core.util.requireKey("t", parsedData);
+ var data = fb.core.util.requireKey("d", parsedData);
+ if (layer == "c") {
+ this.onSecondaryControl_(data);
+ } else {
+ if (layer == "d") {
+ this.pendingDataMessages.push(data);
+ } else {
+ throw new Error("Unknown protocol layer: " + layer);
+ }
+ }
+};
+fb.realtime.Connection.prototype.upgradeIfSecondaryHealthy_ = function() {
+ if (this.secondaryResponsesRequired_ <= 0) {
+ this.log_("Secondary connection is healthy.");
+ this.isHealthy_ = true;
+ this.secondaryConn_.markConnectionHealthy();
+ this.proceedWithUpgrade_();
+ } else {
+ this.log_("sending ping on secondary.");
+ this.secondaryConn_.send({"t":"c", "d":{"t":PING, "d":{}}});
+ }
+};
+fb.realtime.Connection.prototype.proceedWithUpgrade_ = function() {
+ this.secondaryConn_.start();
+ this.log_("sending client ack on secondary");
+ this.secondaryConn_.send({"t":"c", "d":{"t":SWITCH_ACK, "d":{}}});
+ this.log_("Ending transmission on primary");
+ this.conn_.send({"t":"c", "d":{"t":END_TRANSMISSION, "d":{}}});
+ this.tx_ = this.secondaryConn_;
+ this.tryCleanupConnection();
+};
+fb.realtime.Connection.prototype.onPrimaryMessageReceived_ = function(parsedData) {
+ var layer = fb.core.util.requireKey("t", parsedData);
+ var data = fb.core.util.requireKey("d", parsedData);
+ if (layer == "c") {
+ this.onControl_(data);
+ } else {
+ if (layer == "d") {
+ this.onDataMessage_(data);
+ }
+ }
+};
+fb.realtime.Connection.prototype.onDataMessage_ = function(message) {
+ this.onPrimaryResponse_();
+ this.onMessage_(message);
+};
+fb.realtime.Connection.prototype.onPrimaryResponse_ = function() {
+ if (!this.isHealthy_) {
+ this.primaryResponsesRequired_--;
+ if (this.primaryResponsesRequired_ <= 0) {
+ this.log_("Primary connection is healthy.");
+ this.isHealthy_ = true;
+ this.conn_.markConnectionHealthy();
+ }
+ }
+};
+fb.realtime.Connection.prototype.onControl_ = function(controlData) {
+ var cmd = fb.core.util.requireKey(MESSAGE_TYPE, controlData);
+ if (MESSAGE_DATA in controlData) {
+ var payload = controlData[MESSAGE_DATA];
+ if (cmd === SERVER_HELLO) {
+ this.onHandshake_(payload);
+ } else {
+ if (cmd === END_TRANSMISSION) {
+ this.log_("recvd end transmission on primary");
+ this.rx_ = this.secondaryConn_;
+ for (var i = 0;i < this.pendingDataMessages.length;++i) {
+ this.onDataMessage_(this.pendingDataMessages[i]);
+ }
+ this.pendingDataMessages = [];
+ this.tryCleanupConnection();
+ } else {
+ if (cmd === CONTROL_SHUTDOWN) {
+ this.onConnectionShutdown_(payload);
+ } else {
+ if (cmd === CONTROL_RESET) {
+ this.onReset_(payload);
+ } else {
+ if (cmd === CONTROL_ERROR) {
+ fb.core.util.error("Server Error: " + payload);
+ } else {
+ if (cmd === CONTROL_PONG) {
+ this.log_("got pong on primary.");
+ this.onPrimaryResponse_();
+ this.sendPingOnPrimaryIfNecessary_();
+ } else {
+ fb.core.util.error("Unknown control packet command: " + cmd);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+};
+fb.realtime.Connection.prototype.onHandshake_ = function(handshake) {
+ var timestamp = handshake["ts"];
+ var version = handshake["v"];
+ var host = handshake["h"];
+ this.sessionId = handshake["s"];
+ this.repoInfo_.updateHost(host);
+ if (this.state_ == REALTIME_STATE_CONNECTING) {
+ this.conn_.start();
+ this.onConnectionEstablished_(this.conn_, timestamp);
+ if (fb.realtime.Constants.PROTOCOL_VERSION !== version) {
+ fb.core.util.warn("Protocol version mismatch detected");
+ }
+ this.tryStartUpgrade_();
+ }
+};
+fb.realtime.Connection.prototype.tryStartUpgrade_ = function() {
+ var conn = this.transportManager_.upgradeTransport();
+ if (conn) {
+ this.startUpgrade_(conn);
+ }
+};
+fb.realtime.Connection.prototype.startUpgrade_ = function(conn) {
+ this.secondaryConn_ = new conn(this.nextTransportId_(), this.repoInfo_, this.sessionId);
+ this.secondaryResponsesRequired_ = conn["responsesRequiredToBeHealthy"] || 0;
+ var onMessage = this.connReceiver_(this.secondaryConn_);
+ var onDisconnect = this.disconnReceiver_(this.secondaryConn_);
+ this.secondaryConn_.open(onMessage, onDisconnect);
+ var self = this;
+ setTimeout(function() {
+ if (self.secondaryConn_) {
+ self.log_("Timed out trying to upgrade.");
+ self.secondaryConn_.close();
+ }
+ }, Math.floor(UPGRADE_TIMEOUT));
+};
+fb.realtime.Connection.prototype.onReset_ = function(host) {
+ this.log_("Reset packet received. New host: " + host);
+ this.repoInfo_.updateHost(host);
+ if (this.state_ === REALTIME_STATE_CONNECTED) {
+ this.close();
+ } else {
+ this.closeConnections_();
+ this.start_();
+ }
+};
+fb.realtime.Connection.prototype.onConnectionEstablished_ = function(conn, timestamp) {
+ this.log_("Realtime connection established.");
+ this.conn_ = conn;
+ this.state_ = REALTIME_STATE_CONNECTED;
+ if (this.onReady_) {
+ this.onReady_(timestamp);
+ this.onReady_ = null;
+ }
+ var self = this;
+ if (this.primaryResponsesRequired_ === 0) {
+ this.log_("Primary connection is healthy.");
+ this.isHealthy_ = true;
+ } else {
+ setTimeout(function() {
+ self.sendPingOnPrimaryIfNecessary_();
+ }, Math.floor(DELAY_BEFORE_SENDING_EXTRA_REQUESTS));
+ }
+};
+fb.realtime.Connection.prototype.sendPingOnPrimaryIfNecessary_ = function() {
+ if (!this.isHealthy_ && this.state_ === REALTIME_STATE_CONNECTED) {
+ this.log_("sending ping on primary.");
+ this.sendData_({"t":"c", "d":{"t":PING, "d":{}}});
+ }
+};
+fb.realtime.Connection.prototype.onSecondaryConnectionLost_ = function() {
+ var conn = this.secondaryConn_;
+ this.secondaryConn_ = null;
+ if (this.tx_ === conn || this.rx_ === conn) {
+ this.close();
+ }
+};
+fb.realtime.Connection.prototype.onConnectionLost_ = function(everConnected) {
+ this.conn_ = null;
+ if (!everConnected && this.state_ === REALTIME_STATE_CONNECTING) {
+ this.log_("Realtime connection failed.");
+ if (this.repoInfo_.isCacheableHost()) {
+ fb.core.storage.PersistentStorage.remove("host:" + this.repoInfo_.host);
+ this.repoInfo_.internalHost = this.repoInfo_.host;
+ }
+ } else {
+ if (this.state_ === REALTIME_STATE_CONNECTED) {
+ this.log_("Realtime connection lost.");
+ }
+ }
+ this.close();
+};
+fb.realtime.Connection.prototype.onConnectionShutdown_ = function(reason) {
+ this.log_("Connection shutdown command received. Shutting down...");
+ if (this.onKill_) {
+ this.onKill_(reason);
+ this.onKill_ = null;
+ }
+ this.onDisconnect_ = null;
+ this.close();
+};
+fb.realtime.Connection.prototype.sendData_ = function(data) {
+ if (this.state_ !== REALTIME_STATE_CONNECTED) {
+ throw "Connection is not connected";
+ } else {
+ this.tx_.send(data);
+ }
+};
+fb.realtime.Connection.prototype.close = function() {
+ if (this.state_ !== REALTIME_STATE_DISCONNECTED) {
+ this.log_("Closing realtime connection.");
+ this.state_ = REALTIME_STATE_DISCONNECTED;
+ this.closeConnections_();
+ if (this.onDisconnect_) {
+ this.onDisconnect_();
+ this.onDisconnect_ = null;
+ }
+ }
+};
+fb.realtime.Connection.prototype.closeConnections_ = function() {
+ this.log_("Shutting down all connections");
+ if (this.conn_) {
+ this.conn_.close();
+ this.conn_ = null;
+ }
+ if (this.secondaryConn_) {
+ this.secondaryConn_.close();
+ this.secondaryConn_ = null;
+ }
+ if (this.healthyTimeout_) {
+ clearTimeout(this.healthyTimeout_);
+ this.healthyTimeout_ = null;
+ }
+};
+goog.provide("fb.core.PersistentConnection");
+goog.require("fb.core.ServerActions");
+goog.require("fb.core.util");
+goog.require("fb.core.util.OnlineMonitor");
+goog.require("fb.core.util.VisibilityMonitor");
+goog.require("fb.login.util.environment");
+goog.require("fb.realtime.Connection");
+goog.require("fb.util.json");
+goog.require("fb.util.jwt");
+var RECONNECT_MIN_DELAY = 1E3;
+var RECONNECT_MAX_DELAY_DEFAULT = 60 * 5 * 1E3;
+var RECONNECT_MAX_DELAY_FOR_ADMINS = 30 * 1E3;
+var RECONNECT_DELAY_MULTIPLIER = 1.3;
+var RECONNECT_DELAY_RESET_TIMEOUT = 3E4;
+fb.core.PersistentConnection = function(repoInfo, onDataUpdate, onConnectStatus, onServerInfoUpdate) {
+ this.id = fb.core.PersistentConnection.nextPersistentConnectionId_++;
+ this.log_ = fb.core.util.logWrapper("p:" + this.id + ":");
+ this.interrupted_ = false;
+ this.killed_ = false;
+ this.listens_ = {};
+ this.outstandingPuts_ = [];
+ this.outstandingPutCount_ = 0;
+ this.onDisconnectRequestQueue_ = [];
+ this.connected_ = false;
+ this.reconnectDelay_ = RECONNECT_MIN_DELAY;
+ this.maxReconnectDelay_ = RECONNECT_MAX_DELAY_DEFAULT;
+ this.onDataUpdate_ = onDataUpdate;
+ this.onConnectStatus_ = onConnectStatus;
+ this.onServerInfoUpdate_ = onServerInfoUpdate;
+ this.repoInfo_ = repoInfo;
+ this.securityDebugCallback_ = null;
+ this.requestCBHash_ = {};
+ this.requestNumber_ = 0;
+ this.firstConnection_ = true;
+ this.lastConnectionAttemptTime_ = null;
+ this.lastConnectionEstablishedTime_ = null;
+ this.scheduleConnect_(0);
+ fb.core.util.VisibilityMonitor.getInstance().on("visible", this.onVisible_, this);
+ if (repoInfo.host.indexOf("fblocal") === -1) {
+ fb.core.util.OnlineMonitor.getInstance().on("online", this.onOnline_, this);
+ }
+};
+fb.core.PersistentConnection.nextPersistentConnectionId_ = 0;
+fb.core.PersistentConnection.nextConnectionId_ = 0;
+fb.core.PersistentConnection.prototype.sendRequest = function(action, body, onResponse) {
+ var curReqNum = ++this.requestNumber_;
+ var msg = {"r":curReqNum, "a":action, "b":body};
+ this.log_(fb.util.json.stringify(msg));
+ fb.core.util.assert(this.connected_, "sendRequest call when we're not connected not allowed.");
+ this.realtime_.sendRequest(msg);
+ if (onResponse) {
+ this.requestCBHash_[curReqNum] = onResponse;
+ }
+};
+fb.core.PersistentConnection.prototype.listen = function(query, currentHashFn, tag, onComplete) {
+ var queryId = query.queryIdentifier();
+ var pathString = query.path.toString();
+ this.log_("Listen called for " + pathString + " " + queryId);
+ this.listens_[pathString] = this.listens_[pathString] || {};
+ fb.core.util.assert(!this.listens_[pathString][queryId], "listen() called twice for same path/queryId.");
+ var listenSpec = {onComplete:onComplete, hashFn:currentHashFn, query:query, tag:tag};
+ this.listens_[pathString][queryId] = listenSpec;
+ if (this.connected_) {
+ this.sendListen_(listenSpec);
+ }
+};
+fb.core.PersistentConnection.prototype.sendListen_ = function(listenSpec) {
+ var query = listenSpec.query;
+ var pathString = query.path.toString();
+ var queryId = query.queryIdentifier();
+ var self = this;
+ this.log_("Listen on " + pathString + " for " + queryId);
+ var req = {"p":pathString};
+ var action = "q";
+ if (listenSpec.tag) {
+ req["q"] = query.queryObject();
+ req["t"] = listenSpec.tag;
+ }
+ req["h"] = listenSpec.hashFn();
+ this.sendRequest(action, req, function(message) {
+ var payload = message["d"];
+ var status = message["s"];
+ self.warnOnListenWarnings_(payload, query);
+ var currentListenSpec = self.listens_[pathString] && self.listens_[pathString][queryId];
+ if (currentListenSpec === listenSpec) {
+ self.log_("listen response", message);
+ if (status !== "ok") {
+ self.removeListen_(pathString, queryId);
+ }
+ if (listenSpec.onComplete) {
+ listenSpec.onComplete(status, payload);
+ }
+ }
+ });
+};
+fb.core.PersistentConnection.prototype.warnOnListenWarnings_ = function(payload, query) {
+ if (payload && typeof payload === "object" && fb.util.obj.contains(payload, "w")) {
+ var warnings = fb.util.obj.get(payload, "w");
+ if (goog.isArray(warnings) && goog.array.contains(warnings, "no_index")) {
+ var indexSpec = '".indexOn": "' + query.getQueryParams().getIndex().toString() + '"';
+ var indexPath = query.path.toString();
+ fb.core.util.warn("Using an unspecified index. Consider adding " + indexSpec + " at " + indexPath + " to your security rules for better performance");
+ }
+ }
+};
+fb.core.PersistentConnection.prototype.auth = function(cred, opt_callback, opt_cancelCallback) {
+ this.credential_ = {cred:cred, firstRequestSent:false, callback:opt_callback, cancelCallback:opt_cancelCallback};
+ this.log_("Authenticating using credential: " + cred);
+ this.tryAuth();
+ this.reduceReconnectDelayIfAdminCredential_(cred);
+};
+fb.core.PersistentConnection.prototype.reduceReconnectDelayIfAdminCredential_ = function(credential) {
+ var isFirebaseSecret = credential.length == 40;
+ if (isFirebaseSecret || fb.util.jwt.isAdmin(credential)) {
+ this.log_("Admin auth credential detected. Reducing max reconnect time.");
+ this.maxReconnectDelay_ = RECONNECT_MAX_DELAY_FOR_ADMINS;
+ }
+};
+fb.core.PersistentConnection.prototype.unauth = function(onComplete) {
+ delete this.credential_;
+ if (this.connected_) {
+ this.sendRequest("unauth", {}, function(result) {
+ var status = result["s"];
+ var errorReason = result["d"];
+ onComplete(status, errorReason);
+ });
+ }
+};
+fb.core.PersistentConnection.prototype.tryAuth = function() {
+ var authdata = this.credential_;
+ var self = this;
+ if (this.connected_ && authdata) {
+ var requestData = {"cred":authdata.cred};
+ this.sendRequest("auth", requestData, function(res) {
+ var status = res["s"];
+ var data = res["d"] || "error";
+ if (status !== "ok" && self.credential_ === authdata) {
+ delete self.credential_;
+ }
+ if (!authdata.firstRequestSent) {
+ authdata.firstRequestSent = true;
+ if (authdata.callback) {
+ authdata.callback(status, data);
+ }
+ } else {
+ if (status !== "ok" && authdata.cancelCallback) {
+ authdata.cancelCallback(status, data);
+ }
+ }
+ });
+ }
+};
+fb.core.PersistentConnection.prototype.unlisten = function(query, tag) {
+ var pathString = query.path.toString();
+ var queryId = query.queryIdentifier();
+ this.log_("Unlisten called for " + pathString + " " + queryId);
+ var listen = this.removeListen_(pathString, queryId);
+ if (listen && this.connected_) {
+ this.sendUnlisten_(pathString, queryId, query.queryObject(), tag);
+ }
+};
+fb.core.PersistentConnection.prototype.sendUnlisten_ = function(pathString, queryId, queryObj, tag) {
+ this.log_("Unlisten on " + pathString + " for " + queryId);
+ var self = this;
+ var req = {"p":pathString};
+ var action = "n";
+ if (tag) {
+ req["q"] = queryObj;
+ req["t"] = tag;
+ }
+ this.sendRequest(action, req);
+};
+fb.core.PersistentConnection.prototype.onDisconnectPut = function(pathString, data, opt_onComplete) {
+ if (this.connected_) {
+ this.sendOnDisconnect_("o", pathString, data, opt_onComplete);
+ } else {
+ this.onDisconnectRequestQueue_.push({pathString:pathString, action:"o", data:data, onComplete:opt_onComplete});
+ }
+};
+fb.core.PersistentConnection.prototype.onDisconnectMerge = function(pathString, data, opt_onComplete) {
+ if (this.connected_) {
+ this.sendOnDisconnect_("om", pathString, data, opt_onComplete);
+ } else {
+ this.onDisconnectRequestQueue_.push({pathString:pathString, action:"om", data:data, onComplete:opt_onComplete});
+ }
+};
+fb.core.PersistentConnection.prototype.onDisconnectCancel = function(pathString, opt_onComplete) {
+ if (this.connected_) {
+ this.sendOnDisconnect_("oc", pathString, null, opt_onComplete);
+ } else {
+ this.onDisconnectRequestQueue_.push({pathString:pathString, action:"oc", data:null, onComplete:opt_onComplete});
+ }
+};
+fb.core.PersistentConnection.prototype.sendOnDisconnect_ = function(action, pathString, data, opt_onComplete) {
+ var self = this;
+ var request = {"p":pathString, "d":data};
+ self.log_("onDisconnect " + action, request);
+ this.sendRequest(action, request, function(response) {
+ if (opt_onComplete) {
+ setTimeout(function() {
+ opt_onComplete(response["s"], response["d"]);
+ }, Math.floor(0));
+ }
+ });
+};
+fb.core.PersistentConnection.prototype.put = function(pathString, data, opt_onComplete, opt_hash) {
+ this.putInternal("p", pathString, data, opt_onComplete, opt_hash);
+};
+fb.core.PersistentConnection.prototype.merge = function(pathString, data, onComplete, opt_hash) {
+ this.putInternal("m", pathString, data, onComplete, opt_hash);
+};
+fb.core.PersistentConnection.prototype.putInternal = function(action, pathString, data, opt_onComplete, opt_hash) {
+ var request = {"p":pathString, "d":data};
+ if (goog.isDef(opt_hash)) {
+ request["h"] = opt_hash;
+ }
+ this.outstandingPuts_.push({action:action, request:request, onComplete:opt_onComplete});
+ this.outstandingPutCount_++;
+ var index = this.outstandingPuts_.length - 1;
+ if (this.connected_) {
+ this.sendPut_(index);
+ } else {
+ this.log_("Buffering put: " + pathString);
+ }
+};
+fb.core.PersistentConnection.prototype.sendPut_ = function(index) {
+ var self = this;
+ var action = this.outstandingPuts_[index].action;
+ var request = this.outstandingPuts_[index].request;
+ var onComplete = this.outstandingPuts_[index].onComplete;
+ this.outstandingPuts_[index].queued = this.connected_;
+ this.sendRequest(action, request, function(message) {
+ self.log_(action + " response", message);
+ delete self.outstandingPuts_[index];
+ self.outstandingPutCount_--;
+ if (self.outstandingPutCount_ === 0) {
+ self.outstandingPuts_ = [];
+ }
+ if (onComplete) {
+ onComplete(message["s"], message["d"]);
+ }
+ });
+};
+fb.core.PersistentConnection.prototype.reportStats = function(stats) {
+ if (this.connected_) {
+ var request = {"c":stats};
+ this.log_("reportStats", request);
+ this.sendRequest("s", request, function(result) {
+ var status = result["s"];
+ if (status !== "ok") {
+ var errorReason = result["d"];
+ this.log_("reportStats", "Error sending stats: " + errorReason);
+ }
+ });
+ }
+};
+fb.core.PersistentConnection.prototype.onDataMessage_ = function(message) {
+ if ("r" in message) {
+ this.log_("from server: " + fb.util.json.stringify(message));
+ var reqNum = message["r"];
+ var onResponse = this.requestCBHash_[reqNum];
+ if (onResponse) {
+ delete this.requestCBHash_[reqNum];
+ onResponse(message["b"]);
+ }
+ } else {
+ if ("error" in message) {
+ throw "A server-side error has occurred: " + message["error"];
+ } else {
+ if ("a" in message) {
+ this.onDataPush_(message["a"], message["b"]);
+ }
+ }
+ }
+};
+fb.core.PersistentConnection.prototype.onDataPush_ = function(action, body) {
+ this.log_("handleServerMessage", action, body);
+ if (action === "d") {
+ this.onDataUpdate_(body["p"], body["d"], false, body["t"]);
+ } else {
+ if (action === "m") {
+ this.onDataUpdate_(body["p"], body["d"], true, body["t"]);
+ } else {
+ if (action === "c") {
+ this.onListenRevoked_(body["p"], body["q"]);
+ } else {
+ if (action === "ac") {
+ this.onAuthRevoked_(body["s"], body["d"]);
+ } else {
+ if (action === "sd") {
+ this.onSecurityDebugPacket_(body);
+ } else {
+ fb.core.util.error("Unrecognized action received from server: " + fb.util.json.stringify(action) + "\nAre you using the latest client?");
+ }
+ }
+ }
+ }
+ }
+};
+fb.core.PersistentConnection.prototype.onReady_ = function(timestamp) {
+ this.log_("connection ready");
+ this.connected_ = true;
+ this.lastConnectionEstablishedTime_ = (new Date).getTime();
+ this.handleTimestamp_(timestamp);
+ if (this.firstConnection_) {
+ this.sendConnectStats_();
+ }
+ this.restoreState_();
+ this.firstConnection_ = false;
+ this.onConnectStatus_(true);
+};
+fb.core.PersistentConnection.prototype.scheduleConnect_ = function(timeout) {
+ fb.core.util.assert(!this.realtime_, "Scheduling a connect when we're already connected/ing?");
+ if (this.establishConnectionTimer_) {
+ clearTimeout(this.establishConnectionTimer_);
+ }
+ var self = this;
+ this.establishConnectionTimer_ = setTimeout(function() {
+ self.establishConnectionTimer_ = null;
+ self.establishConnection_();
+ }, Math.floor(timeout));
+};
+fb.core.PersistentConnection.prototype.onVisible_ = function(visible) {
+ if (visible && !this.visible_ && this.reconnectDelay_ === this.maxReconnectDelay_) {
+ this.log_("Window became visible. Reducing delay.");
+ this.reconnectDelay_ = RECONNECT_MIN_DELAY;
+ if (!this.realtime_) {
+ this.scheduleConnect_(0);
+ }
+ }
+ this.visible_ = visible;
+};
+fb.core.PersistentConnection.prototype.onOnline_ = function(online) {
+ if (online) {
+ this.log_("Browser went online.");
+ this.reconnectDelay_ = RECONNECT_MIN_DELAY;
+ if (!this.realtime_) {
+ this.scheduleConnect_(0);
+ }
+ } else {
+ this.log_("Browser went offline. Killing connection.");
+ if (this.realtime_) {
+ this.realtime_.close();
+ }
+ }
+};
+fb.core.PersistentConnection.prototype.onRealtimeDisconnect_ = function() {
+ this.log_("data client disconnected");
+ this.connected_ = false;
+ this.realtime_ = null;
+ this.cancelSentTransactions_();
+ this.requestCBHash_ = {};
+ if (this.shouldReconnect_()) {
+ if (!this.visible_) {
+ this.log_("Window isn't visible. Delaying reconnect.");
+ this.reconnectDelay_ = this.maxReconnectDelay_;
+ this.lastConnectionAttemptTime_ = (new Date).getTime();
+ } else {
+ if (this.lastConnectionEstablishedTime_) {
+ var timeSinceLastConnectSucceeded = (new Date).getTime() - this.lastConnectionEstablishedTime_;
+ if (timeSinceLastConnectSucceeded > RECONNECT_DELAY_RESET_TIMEOUT) {
+ this.reconnectDelay_ = RECONNECT_MIN_DELAY;
+ }
+ this.lastConnectionEstablishedTime_ = null;
+ }
+ }
+ var timeSinceLastConnectAttempt = (new Date).getTime() - this.lastConnectionAttemptTime_;
+ var reconnectDelay = Math.max(0, this.reconnectDelay_ - timeSinceLastConnectAttempt);
+ reconnectDelay = Math.random() * reconnectDelay;
+ this.log_("Trying to reconnect in " + reconnectDelay + "ms");
+ this.scheduleConnect_(reconnectDelay);
+ this.reconnectDelay_ = Math.min(this.maxReconnectDelay_, this.reconnectDelay_ * RECONNECT_DELAY_MULTIPLIER);
+ }
+ this.onConnectStatus_(false);
+};
+fb.core.PersistentConnection.prototype.establishConnection_ = function() {
+ if (this.shouldReconnect_()) {
+ this.log_("Making a connection attempt");
+ this.lastConnectionAttemptTime_ = (new Date).getTime();
+ this.lastConnectionEstablishedTime_ = null;
+ var onDataMessage = goog.bind(this.onDataMessage_, this);
+ var onReady = goog.bind(this.onReady_, this);
+ var onDisconnect = goog.bind(this.onRealtimeDisconnect_, this);
+ var connId = this.id + ":" + fb.core.PersistentConnection.nextConnectionId_++;
+ var self = this;
+ this.realtime_ = new fb.realtime.Connection(connId, this.repoInfo_, onDataMessage, onReady, onDisconnect, function(reason) {
+ fb.core.util.warn(reason + " (" + self.repoInfo_.toString() + ")");
+ self.killed_ = true;
+ });
+ }
+};
+fb.core.PersistentConnection.prototype.interrupt = function() {
+ this.interrupted_ = true;
+ if (this.realtime_) {
+ this.realtime_.close();
+ } else {
+ if (this.establishConnectionTimer_) {
+ clearTimeout(this.establishConnectionTimer_);
+ this.establishConnectionTimer_ = null;
+ }
+ if (this.connected_) {
+ this.onRealtimeDisconnect_();
+ }
+ }
+};
+fb.core.PersistentConnection.prototype.resume = function() {
+ this.interrupted_ = false;
+ this.reconnectDelay_ = RECONNECT_MIN_DELAY;
+ if (!this.realtime_) {
+ this.scheduleConnect_(0);
+ }
+};
+fb.core.PersistentConnection.prototype.handleTimestamp_ = function(timestamp) {
+ var delta = timestamp - (new Date).getTime();
+ this.onServerInfoUpdate_({"serverTimeOffset":delta});
+};
+fb.core.PersistentConnection.prototype.cancelSentTransactions_ = function() {
+ for (var i = 0;i < this.outstandingPuts_.length;i++) {
+ var put = this.outstandingPuts_[i];
+ if (put && "h" in put.request && put.queued) {
+ if (put.onComplete) {
+ put.onComplete("disconnect");
+ }
+ delete this.outstandingPuts_[i];
+ this.outstandingPutCount_--;
+ }
+ }
+ if (this.outstandingPutCount_ === 0) {
+ this.outstandingPuts_ = [];
+ }
+};
+fb.core.PersistentConnection.prototype.onListenRevoked_ = function(pathString, opt_query) {
+ var queryId;
+ if (!opt_query) {
+ queryId = "default";
+ } else {
+ queryId = goog.array.map(opt_query, function(q) {
+ return fb.core.util.ObjectToUniqueKey(q);
+ }).join("$");
+ }
+ var listen = this.removeListen_(pathString, queryId);
+ if (listen && listen.onComplete) {
+ listen.onComplete("permission_denied");
+ }
+};
+fb.core.PersistentConnection.prototype.removeListen_ = function(pathString, queryId) {
+ var normalizedPathString = (new fb.core.util.Path(pathString)).toString();
+ var listen;
+ if (goog.isDef(this.listens_[normalizedPathString])) {
+ listen = this.listens_[normalizedPathString][queryId];
+ delete this.listens_[normalizedPathString][queryId];
+ if (goog.object.getCount(this.listens_[normalizedPathString]) === 0) {
+ delete this.listens_[normalizedPathString];
+ }
+ } else {
+ listen = undefined;
+ }
+ return listen;
+};
+fb.core.PersistentConnection.prototype.onAuthRevoked_ = function(statusCode, explanation) {
+ var cred = this.credential_;
+ delete this.credential_;
+ if (cred && cred.cancelCallback) {
+ cred.cancelCallback(statusCode, explanation);
+ }
+};
+fb.core.PersistentConnection.prototype.onSecurityDebugPacket_ = function(body) {
+ if (this.securityDebugCallback_) {
+ this.securityDebugCallback_(body);
+ } else {
+ if ("msg" in body && typeof console !== "undefined") {
+ console.log("FIREBASE: " + body["msg"].replace("\n", "\nFIREBASE: "));
+ }
+ }
+};
+fb.core.PersistentConnection.prototype.restoreState_ = function() {
+ this.tryAuth();
+ var self = this;
+ goog.object.forEach(this.listens_, function(queries, pathString) {
+ goog.object.forEach(queries, function(listenSpec) {
+ self.sendListen_(listenSpec);
+ });
+ });
+ for (var i = 0;i < this.outstandingPuts_.length;i++) {
+ if (this.outstandingPuts_[i]) {
+ this.sendPut_(i);
+ }
+ }
+ while (this.onDisconnectRequestQueue_.length) {
+ var request = this.onDisconnectRequestQueue_.shift();
+ this.sendOnDisconnect_(request.action, request.pathString, request.data, request.onComplete);
+ }
+};
+fb.core.PersistentConnection.prototype.sendConnectStats_ = function() {
+ var stats = {};
+ stats["sdk.js." + CLIENT_VERSION.replace(/\./g, "-")] = 1;
+ if (fb.login.util.environment.isMobileCordova()) {
+ stats["framework.cordova"] = 1;
+ }
+ this.reportStats(stats);
+};
+fb.core.PersistentConnection.prototype.shouldReconnect_ = function() {
+ var online = fb.core.util.OnlineMonitor.getInstance().currentlyOnline();
+ return!this.killed_ && !this.interrupted_ && online;
+};
+goog.provide("fb.api.INTERNAL");
+goog.require("fb.core.PersistentConnection");
+goog.require("fb.realtime.Connection");
+goog.require("fb.login.transports.PopupReceiver");
+goog.require("fb.login.Constants");
+fb.api.INTERNAL = {};
+fb.api.INTERNAL.forceLongPolling = function() {
+ fb.realtime.WebSocketConnection.forceDisallow();
+ fb.realtime.BrowserPollConnection.forceAllow();
+};
+goog.exportProperty(fb.api.INTERNAL, "forceLongPolling", fb.api.INTERNAL.forceLongPolling);
+fb.api.INTERNAL.forceWebSockets = function() {
+ fb.realtime.BrowserPollConnection.forceDisallow();
+};
+goog.exportProperty(fb.api.INTERNAL, "forceWebSockets", fb.api.INTERNAL.forceWebSockets);
+fb.api.INTERNAL.setSecurityDebugCallback = function(ref, callback) {
+ ref.repo.persistentConnection_.securityDebugCallback_ = callback;
+};
+goog.exportProperty(fb.api.INTERNAL, "setSecurityDebugCallback", fb.api.INTERNAL.setSecurityDebugCallback);
+fb.api.INTERNAL.stats = function(ref, showDelta) {
+ ref.repo.stats(showDelta);
+};
+goog.exportProperty(fb.api.INTERNAL, "stats", fb.api.INTERNAL.stats);
+fb.api.INTERNAL.statsIncrementCounter = function(ref, metric) {
+ ref.repo.statsIncrementCounter(metric);
+};
+goog.exportProperty(fb.api.INTERNAL, "statsIncrementCounter", fb.api.INTERNAL.statsIncrementCounter);
+fb.api.INTERNAL.dataUpdateCount = function(ref) {
+ return ref.repo.dataUpdateCount;
+};
+goog.exportProperty(fb.api.INTERNAL, "dataUpdateCount", fb.api.INTERNAL.dataUpdateCount);
+fb.api.INTERNAL.interceptServerData = function(ref, callback) {
+ return ref.repo.interceptServerData_(callback);
+};
+goog.exportProperty(fb.api.INTERNAL, "interceptServerData", fb.api.INTERNAL.interceptServerData);
+fb.api.INTERNAL.onLoginPopupOpen = function(callback) {
+ new fb.login.transports.PopupReceiver(callback);
+};
+goog.exportProperty(fb.api.INTERNAL, "onPopupOpen", fb.api.INTERNAL.onLoginPopupOpen);
+fb.api.INTERNAL.setAuthenticationServer = function(host) {
+ fb.login.Constants.SERVER_HOST = host;
+};
+goog.exportProperty(fb.api.INTERNAL, "setAuthenticationServer", fb.api.INTERNAL.setAuthenticationServer);
+goog.provide("fb.api.DataSnapshot");
+goog.require("fb.core.snap");
+goog.require("fb.core.util.SortedMap");
+goog.require("fb.core.util.validation");
+fb.api.DataSnapshot = function(node, ref, index) {
+ this.node_ = node;
+ this.query_ = ref;
+ this.index_ = index;
+};
+fb.api.DataSnapshot.prototype.val = function() {
+ fb.util.validation.validateArgCount("Firebase.DataSnapshot.val", 0, 0, arguments.length);
+ return this.node_.val();
+};
+goog.exportProperty(fb.api.DataSnapshot.prototype, "val", fb.api.DataSnapshot.prototype.val);
+fb.api.DataSnapshot.prototype.exportVal = function() {
+ fb.util.validation.validateArgCount("Firebase.DataSnapshot.exportVal", 0, 0, arguments.length);
+ return this.node_.val(true);
+};
+goog.exportProperty(fb.api.DataSnapshot.prototype, "exportVal", fb.api.DataSnapshot.prototype.exportVal);
+fb.api.DataSnapshot.prototype.exists = function() {
+ fb.util.validation.validateArgCount("Firebase.DataSnapshot.exists", 0, 0, arguments.length);
+ return!this.node_.isEmpty();
+};
+goog.exportProperty(fb.api.DataSnapshot.prototype, "exists", fb.api.DataSnapshot.prototype.exists);
+fb.api.DataSnapshot.prototype.child = function(childPathString) {
+ fb.util.validation.validateArgCount("Firebase.DataSnapshot.child", 0, 1, arguments.length);
+ if (goog.isNumber(childPathString)) {
+ childPathString = String(childPathString);
+ }
+ fb.core.util.validation.validatePathString("Firebase.DataSnapshot.child", 1, childPathString, false);
+ var childPath = new fb.core.util.Path(childPathString);
+ var childRef = this.query_.child(childPath);
+ return new fb.api.DataSnapshot(this.node_.getChild(childPath), childRef, fb.core.snap.PriorityIndex);
+};
+goog.exportProperty(fb.api.DataSnapshot.prototype, "child", fb.api.DataSnapshot.prototype.child);
+fb.api.DataSnapshot.prototype.hasChild = function(childPathString) {
+ fb.util.validation.validateArgCount("Firebase.DataSnapshot.hasChild", 1, 1, arguments.length);
+ fb.core.util.validation.validatePathString("Firebase.DataSnapshot.hasChild", 1, childPathString, false);
+ var childPath = new fb.core.util.Path(childPathString);
+ return!this.node_.getChild(childPath).isEmpty();
+};
+goog.exportProperty(fb.api.DataSnapshot.prototype, "hasChild", fb.api.DataSnapshot.prototype.hasChild);
+fb.api.DataSnapshot.prototype.getPriority = function() {
+ fb.util.validation.validateArgCount("Firebase.DataSnapshot.getPriority", 0, 0, arguments.length);
+ return(this.node_.getPriority().val());
+};
+goog.exportProperty(fb.api.DataSnapshot.prototype, "getPriority", fb.api.DataSnapshot.prototype.getPriority);
+fb.api.DataSnapshot.prototype.forEach = function(action) {
+ fb.util.validation.validateArgCount("Firebase.DataSnapshot.forEach", 1, 1, arguments.length);
+ fb.util.validation.validateCallback("Firebase.DataSnapshot.forEach", 1, action, false);
+ if (this.node_.isLeafNode()) {
+ return false;
+ }
+ var childrenNode = (this.node_);
+ var self = this;
+ return!!childrenNode.forEachChild(this.index_, function(key, node) {
+ return action(new fb.api.DataSnapshot(node, self.query_.child(key), fb.core.snap.PriorityIndex));
+ });
+};
+goog.exportProperty(fb.api.DataSnapshot.prototype, "forEach", fb.api.DataSnapshot.prototype.forEach);
+fb.api.DataSnapshot.prototype.hasChildren = function() {
+ fb.util.validation.validateArgCount("Firebase.DataSnapshot.hasChildren", 0, 0, arguments.length);
+ if (this.node_.isLeafNode()) {
+ return false;
+ } else {
+ return!this.node_.isEmpty();
+ }
+};
+goog.exportProperty(fb.api.DataSnapshot.prototype, "hasChildren", fb.api.DataSnapshot.prototype.hasChildren);
+fb.api.DataSnapshot.prototype.name = function() {
+ fb.core.util.warn("Firebase.DataSnapshot.name() being deprecated. " + "Please use Firebase.DataSnapshot.key() instead.");
+ fb.util.validation.validateArgCount("Firebase.DataSnapshot.name", 0, 0, arguments.length);
+ return this.key();
+};
+goog.exportProperty(fb.api.DataSnapshot.prototype, "name", fb.api.DataSnapshot.prototype.name);
+fb.api.DataSnapshot.prototype.key = function() {
+ fb.util.validation.validateArgCount("Firebase.DataSnapshot.key", 0, 0, arguments.length);
+ return this.query_.key();
+};
+goog.exportProperty(fb.api.DataSnapshot.prototype, "key", fb.api.DataSnapshot.prototype.key);
+fb.api.DataSnapshot.prototype.numChildren = function() {
+ fb.util.validation.validateArgCount("Firebase.DataSnapshot.numChildren", 0, 0, arguments.length);
+ return this.node_.numChildren();
+};
+goog.exportProperty(fb.api.DataSnapshot.prototype, "numChildren", fb.api.DataSnapshot.prototype.numChildren);
+fb.api.DataSnapshot.prototype.ref = function() {
+ fb.util.validation.validateArgCount("Firebase.DataSnapshot.ref", 0, 0, arguments.length);
+ return this.query_;
+};
+goog.exportProperty(fb.api.DataSnapshot.prototype, "ref", fb.api.DataSnapshot.prototype.ref);
+goog.provide("fb.core.Repo");
+goog.require("fb.api.DataSnapshot");
+goog.require("fb.core.PersistentConnection");
+goog.require("fb.core.ReadonlyRestClient");
+goog.require("fb.core.SnapshotHolder");
+goog.require("fb.core.SparseSnapshotTree");
+goog.require("fb.core.SyncTree");
+goog.require("fb.core.stats.StatsCollection");
+goog.require("fb.core.stats.StatsListener");
+goog.require("fb.core.stats.StatsManager");
+goog.require("fb.core.stats.StatsReporter");
+goog.require("fb.core.util");
+goog.require("fb.core.util.ServerValues");
+goog.require("fb.core.util.Tree");
+goog.require("fb.core.view.EventQueue");
+goog.require("fb.login.AuthenticationManager");
+goog.require("fb.util.json");
+goog.require("fb.util.jwt");
+goog.require("goog.string");
+fb.core.Repo = function(repoInfo, forceRestClient) {
+ this.repoInfo_ = repoInfo;
+ this.stats_ = fb.core.stats.StatsManager.getCollection(repoInfo);
+ this.eventQueue_ = new fb.core.view.EventQueue;
+ this.nextWriteId_ = 1;
+ this.persistentConnection_ = null;
+ this.server_;
+ if (forceRestClient || fb.core.util.beingCrawled()) {
+ this.server_ = new fb.core.ReadonlyRestClient(this.repoInfo_, goog.bind(this.onDataUpdate_, this));
+ setTimeout(goog.bind(this.onConnectStatus_, this, true), 0);
+ } else {
+ this.persistentConnection_ = new fb.core.PersistentConnection(this.repoInfo_, goog.bind(this.onDataUpdate_, this), goog.bind(this.onConnectStatus_, this), goog.bind(this.onServerInfoUpdate_, this));
+ this.server_ = this.persistentConnection_;
+ }
+ this.statsReporter_ = fb.core.stats.StatsManager.getOrCreateReporter(repoInfo, goog.bind(function() {
+ return new fb.core.stats.StatsReporter(this.stats_, this.server_);
+ }, this));
+ this.transactions_init_();
+ this.infoData_ = new fb.core.SnapshotHolder;
+ var self = this;
+ this.infoSyncTree_ = new fb.core.SyncTree({startListening:function(query, tag, currentHashFn, onComplete) {
+ var infoEvents = [];
+ var node = self.infoData_.getNode(query.path);
+ if (!node.isEmpty()) {
+ infoEvents = self.infoSyncTree_.applyServerOverwrite(query.path, node);
+ setTimeout(function() {
+ onComplete("ok");
+ }, 0);
+ }
+ return infoEvents;
+ }, stopListening:goog.nullFunction});
+ this.updateInfo_("connected", false);
+ this.onDisconnect_ = new fb.core.SparseSnapshotTree;
+ this.auth = new fb.login.AuthenticationManager(repoInfo, goog.bind(this.server_.auth, this.server_), goog.bind(this.server_.unauth, this.server_), goog.bind(this.onAuthStatus_, this));
+ this.dataUpdateCount = 0;
+ this.interceptServerDataCallback_ = null;
+ this.serverSyncTree_ = new fb.core.SyncTree({startListening:function(query, tag, currentHashFn, onComplete) {
+ self.server_.listen(query, currentHashFn, tag, function(status, data) {
+ var events = onComplete(status, data);
+ self.eventQueue_.raiseEventsForChangedPath(query.path, events);
+ });
+ return[];
+ }, stopListening:function(query, tag) {
+ self.server_.unlisten(query, tag);
+ }});
+};
+fb.core.Repo.prototype.toString = function() {
+ return(this.repoInfo_.secure ? "https://" : "http://") + this.repoInfo_.host;
+};
+fb.core.Repo.prototype.name = function() {
+ return this.repoInfo_.namespace;
+};
+fb.core.Repo.prototype.serverTime = function() {
+ var offsetNode = this.infoData_.getNode(new fb.core.util.Path(".info/serverTimeOffset"));
+ var offset = (offsetNode.val()) || 0;
+ return(new Date).getTime() + offset;
+};
+fb.core.Repo.prototype.generateServerValues = function() {
+ return fb.core.util.ServerValues.generateWithValues({"timestamp":this.serverTime()});
+};
+fb.core.Repo.prototype.onDataUpdate_ = function(pathString, data, isMerge, tag) {
+ this.dataUpdateCount++;
+ var path = new fb.core.util.Path(pathString);
+ data = this.interceptServerDataCallback_ ? this.interceptServerDataCallback_(pathString, data) : data;
+ var events = [];
+ if (tag) {
+ if (isMerge) {
+ var taggedChildren = goog.object.map((data), function(raw) {
+ return fb.core.snap.NodeFromJSON(raw);
+ });
+ events = this.serverSyncTree_.applyTaggedQueryMerge(path, taggedChildren, tag);
+ } else {
+ var taggedSnap = fb.core.snap.NodeFromJSON(data);
+ events = this.serverSyncTree_.applyTaggedQueryOverwrite(path, taggedSnap, tag);
+ }
+ } else {
+ if (isMerge) {
+ var changedChildren = goog.object.map((data), function(raw) {
+ return fb.core.snap.NodeFromJSON(raw);
+ });
+ events = this.serverSyncTree_.applyServerMerge(path, changedChildren);
+ } else {
+ var snap = fb.core.snap.NodeFromJSON(data);
+ events = this.serverSyncTree_.applyServerOverwrite(path, snap);
+ }
+ }
+ var affectedPath = path;
+ if (events.length > 0) {
+ affectedPath = this.rerunTransactions_(path);
+ }
+ this.eventQueue_.raiseEventsForChangedPath(affectedPath, events);
+};
+fb.core.Repo.prototype.interceptServerData_ = function(callback) {
+ this.interceptServerDataCallback_ = callback;
+};
+fb.core.Repo.prototype.onConnectStatus_ = function(connectStatus) {
+ this.updateInfo_("connected", connectStatus);
+ if (connectStatus === false) {
+ this.runOnDisconnectEvents_();
+ }
+};
+fb.core.Repo.prototype.onServerInfoUpdate_ = function(updates) {
+ var self = this;
+ fb.core.util.each(updates, function(value, key) {
+ self.updateInfo_(key, value);
+ });
+};
+fb.core.Repo.prototype.onAuthStatus_ = function(authStatus) {
+ this.updateInfo_("authenticated", authStatus);
+};
+fb.core.Repo.prototype.updateInfo_ = function(pathString, value) {
+ var path = new fb.core.util.Path("/.info/" + pathString);
+ var newNode = fb.core.snap.NodeFromJSON(value);
+ this.infoData_.updateSnapshot(path, newNode);
+ var events = this.infoSyncTree_.applyServerOverwrite(path, newNode);
+ this.eventQueue_.raiseEventsForChangedPath(path, events);
+};
+fb.core.Repo.prototype.getNextWriteId_ = function() {
+ return this.nextWriteId_++;
+};
+fb.core.Repo.prototype.setWithPriority = function(path, newVal, newPriority, onComplete) {
+ this.log_("set", {path:path.toString(), value:newVal, priority:newPriority});
+ var serverValues = this.generateServerValues();
+ var newNodeUnresolved = fb.core.snap.NodeFromJSON(newVal, newPriority);
+ var newNode = fb.core.util.ServerValues.resolveDeferredValueSnapshot(newNodeUnresolved, serverValues);
+ var writeId = this.getNextWriteId_();
+ var events = this.serverSyncTree_.applyUserOverwrite(path, newNode, writeId, true);
+ this.eventQueue_.queueEvents(events);
+ var self = this;
+ this.server_.put(path.toString(), newNodeUnresolved.val(true), function(status, errorReason) {
+ var success = status === "ok";
+ if (!success) {
+ fb.core.util.warn("set at " + path + " failed: " + status);
+ }
+ var clearEvents = self.serverSyncTree_.ackUserWrite(writeId, !success);
+ self.eventQueue_.raiseEventsForChangedPath(path, clearEvents);
+ self.callOnCompleteCallback(onComplete, status, errorReason);
+ });
+ var affectedPath = this.abortTransactions_(path);
+ this.rerunTransactions_(affectedPath);
+ this.eventQueue_.raiseEventsForChangedPath(affectedPath, []);
+};
+fb.core.Repo.prototype.update = function(path, childrenToMerge, onComplete) {
+ this.log_("update", {path:path.toString(), value:childrenToMerge});
+ var empty = true;
+ var serverValues = this.generateServerValues();
+ var changedChildren = {};
+ goog.object.forEach(childrenToMerge, function(changedValue, changedKey) {
+ empty = false;
+ var newNodeUnresolved = fb.core.snap.NodeFromJSON(changedValue);
+ changedChildren[changedKey] = fb.core.util.ServerValues.resolveDeferredValueSnapshot(newNodeUnresolved, serverValues);
+ });
+ if (!empty) {
+ var writeId = this.getNextWriteId_();
+ var events = this.serverSyncTree_.applyUserMerge(path, changedChildren, writeId);
+ this.eventQueue_.queueEvents(events);
+ var self = this;
+ this.server_.merge(path.toString(), childrenToMerge, function(status, errorReason) {
+ var success = status === "ok";
+ if (!success) {
+ fb.core.util.warn("update at " + path + " failed: " + status);
+ }
+ var clearEvents = self.serverSyncTree_.ackUserWrite(writeId, !success);
+ var affectedPath = path;
+ if (clearEvents.length > 0) {
+ affectedPath = self.rerunTransactions_(path);
+ }
+ self.eventQueue_.raiseEventsForChangedPath(affectedPath, clearEvents);
+ self.callOnCompleteCallback(onComplete, status, errorReason);
+ });
+ var affectedPath = this.abortTransactions_(path);
+ this.rerunTransactions_(affectedPath);
+ this.eventQueue_.raiseEventsForChangedPath(path, []);
+ } else {
+ fb.core.util.log("update() called with empty data. Don't do anything.");
+ this.callOnCompleteCallback(onComplete, "ok");
+ }
+};
+fb.core.Repo.prototype.runOnDisconnectEvents_ = function() {
+ this.log_("onDisconnectEvents");
+ var self = this;
+ var serverValues = this.generateServerValues();
+ var resolvedOnDisconnectTree = fb.core.util.ServerValues.resolveDeferredValueTree(this.onDisconnect_, serverValues);
+ var events = [];
+ resolvedOnDisconnectTree.forEachTree(fb.core.util.Path.Empty, function(path, snap) {
+ events = events.concat(self.serverSyncTree_.applyServerOverwrite(path, snap));
+ var affectedPath = self.abortTransactions_(path);
+ self.rerunTransactions_(affectedPath);
+ });
+ this.onDisconnect_ = new fb.core.SparseSnapshotTree;
+ this.eventQueue_.raiseEventsForChangedPath(fb.core.util.Path.Empty, events);
+};
+fb.core.Repo.prototype.onDisconnectCancel = function(path, onComplete) {
+ var self = this;
+ this.server_.onDisconnectCancel(path.toString(), function(status, errorReason) {
+ if (status === "ok") {
+ self.onDisconnect_.forget(path);
+ }
+ self.callOnCompleteCallback(onComplete, status, errorReason);
+ });
+};
+fb.core.Repo.prototype.onDisconnectSet = function(path, value, onComplete) {
+ var self = this;
+ var newNode = fb.core.snap.NodeFromJSON(value);
+ this.server_.onDisconnectPut(path.toString(), newNode.val(true), function(status, errorReason) {
+ if (status === "ok") {
+ self.onDisconnect_.remember(path, newNode);
+ }
+ self.callOnCompleteCallback(onComplete, status, errorReason);
+ });
+};
+fb.core.Repo.prototype.onDisconnectSetWithPriority = function(path, value, priority, onComplete) {
+ var self = this;
+ var newNode = fb.core.snap.NodeFromJSON(value, priority);
+ this.server_.onDisconnectPut(path.toString(), newNode.val(true), function(status, errorReason) {
+ if (status === "ok") {
+ self.onDisconnect_.remember(path, newNode);
+ }
+ self.callOnCompleteCallback(onComplete, status, errorReason);
+ });
+};
+fb.core.Repo.prototype.onDisconnectUpdate = function(path, childrenToMerge, onComplete) {
+ var empty = true;
+ for (var childName in childrenToMerge) {
+ empty = false;
+ }
+ if (empty) {
+ fb.core.util.log("onDisconnect().update() called with empty data. Don't do anything.");
+ this.callOnCompleteCallback(onComplete, "ok");
+ return;
+ }
+ var self = this;
+ this.server_.onDisconnectMerge(path.toString(), childrenToMerge, function(status, errorReason) {
+ if (status === "ok") {
+ for (var childName in childrenToMerge) {
+ var newChildNode = fb.core.snap.NodeFromJSON(childrenToMerge[childName]);
+ self.onDisconnect_.remember(path.child(childName), newChildNode);
+ }
+ }
+ self.callOnCompleteCallback(onComplete, status, errorReason);
+ });
+};
+fb.core.Repo.prototype.addEventCallbackForQuery = function(query, eventRegistration) {
+ var events;
+ if (query.path.getFront() === ".info") {
+ events = this.infoSyncTree_.addEventRegistration(query, eventRegistration);
+ } else {
+ events = this.serverSyncTree_.addEventRegistration(query, eventRegistration);
+ }
+ this.eventQueue_.raiseEventsAtPath(query.path, events);
+};
+fb.core.Repo.prototype.removeEventCallbackForQuery = function(query, eventRegistration) {
+ var events;
+ if (query.path.getFront() === ".info") {
+ events = this.infoSyncTree_.removeEventRegistration(query, eventRegistration);
+ } else {
+ events = this.serverSyncTree_.removeEventRegistration(query, eventRegistration);
+ }
+ this.eventQueue_.raiseEventsAtPath(query.path, events);
+};
+fb.core.Repo.prototype.interrupt = function() {
+ if (this.persistentConnection_) {
+ this.persistentConnection_.interrupt();
+ }
+};
+fb.core.Repo.prototype.resume = function() {
+ if (this.persistentConnection_) {
+ this.persistentConnection_.resume();
+ }
+};
+fb.core.Repo.prototype.stats = function(showDelta) {
+ if (typeof console === "undefined") {
+ return;
+ }
+ var stats;
+ if (showDelta) {
+ if (!this.statsListener_) {
+ this.statsListener_ = new fb.core.stats.StatsListener(this.stats_);
+ }
+ stats = this.statsListener_.get();
+ } else {
+ stats = this.stats_.get();
+ }
+ var longestName = goog.array.reduce(goog.object.getKeys(stats), function(previousValue, currentValue, index, array) {
+ return Math.max(currentValue.length, previousValue);
+ }, 0);
+ for (var stat in stats) {
+ var value = stats[stat];
+ for (var i = stat.length;i < longestName + 2;i++) {
+ stat += " ";
+ }
+ console.log(stat + value);
+ }
+};
+fb.core.Repo.prototype.statsIncrementCounter = function(metric) {
+ this.stats_.incrementCounter(metric);
+ this.statsReporter_.includeStat(metric);
+};
+fb.core.Repo.prototype.log_ = function(var_args) {
+ var prefix = "";
+ if (this.persistentConnection_) {
+ prefix = this.persistentConnection_.id + ":";
+ }
+ fb.core.util.log(prefix, arguments);
+};
+fb.core.Repo.prototype.callOnCompleteCallback = function(callback, status, errorReason) {
+ if (callback) {
+ fb.core.util.exceptionGuard(function() {
+ if (status == "ok") {
+ callback(null);
+ } else {
+ var code = (status || "error").toUpperCase();
+ var message = code;
+ if (errorReason) {
+ message += ": " + errorReason;
+ }
+ var error = new Error(message);
+ error.code = code;
+ callback(error);
+ }
+ });
+ }
+};
+goog.provide("fb.core.Repo_transaction");
+goog.require("fb.core.Repo");
+goog.require("fb.core.snap.PriorityIndex");
+goog.require("fb.core.util");
+fb.core.TransactionStatus = {RUN:1, SENT:2, COMPLETED:3, SENT_NEEDS_ABORT:4, NEEDS_ABORT:5};
+fb.core.Repo.MAX_TRANSACTION_RETRIES_ = 25;
+fb.core.Transaction;
+fb.core.Repo.prototype.transactions_init_ = function() {
+ this.transactionQueueTree_ = new fb.core.util.Tree;
+};
+fb.core.Repo.prototype.startTransaction = function(path, transactionUpdate, onComplete, applyLocally) {
+ this.log_("transaction on " + path);
+ var valueCallback = function() {
+ };
+ var watchRef = new Firebase(this, path);
+ watchRef.on("value", valueCallback);
+ var unwatcher = function() {
+ watchRef.off("value", valueCallback);
+ };
+ var transaction = ({path:path, update:transactionUpdate, onComplete:onComplete, status:null, order:fb.core.util.LUIDGenerator(), applyLocally:applyLocally, retryCount:0, unwatcher:unwatcher, abortReason:null, currentWriteId:null, currentInputSnapshot:null, currentOutputSnapshotRaw:null, currentOutputSnapshotResolved:null});
+ var currentState = this.getLatestState_(path);
+ transaction.currentInputSnapshot = currentState;
+ var newVal = transaction.update(currentState.val());
+ if (!goog.isDef(newVal)) {
+ transaction.unwatcher();
+ transaction.currentOutputSnapshotRaw = null;
+ transaction.currentOutputSnapshotResolved = null;
+ if (transaction.onComplete) {
+ var snapshot = new fb.api.DataSnapshot((transaction.currentInputSnapshot), new Firebase(this, transaction.path), fb.core.snap.PriorityIndex);
+ transaction.onComplete(null, false, snapshot);
+ }
+ } else {
+ fb.core.util.validation.validateFirebaseData("transaction failed: Data returned ", newVal, transaction.path);
+ transaction.status = fb.core.TransactionStatus.RUN;
+ var queueNode = this.transactionQueueTree_.subTree(path);
+ var nodeQueue = queueNode.getValue() || [];
+ nodeQueue.push(transaction);
+ queueNode.setValue(nodeQueue);
+ var priorityForNode;
+ if (typeof newVal === "object" && newVal !== null && fb.util.obj.contains(newVal, ".priority")) {
+ priorityForNode = fb.util.obj.get(newVal, ".priority");
+ fb.core.util.assert(fb.core.util.validation.isValidPriority(priorityForNode), "Invalid priority returned by transaction. " + "Priority must be a valid string, finite number, server value, or null.");
+ } else {
+ var currentNode = this.serverSyncTree_.calcCompleteEventCache(path) || fb.core.snap.EMPTY_NODE;
+ priorityForNode = currentNode.getPriority().val();
+ }
+ priorityForNode = (priorityForNode);
+ var serverValues = this.generateServerValues();
+ var newNodeUnresolved = fb.core.snap.NodeFromJSON(newVal, priorityForNode);
+ var newNode = fb.core.util.ServerValues.resolveDeferredValueSnapshot(newNodeUnresolved, serverValues);
+ transaction.currentOutputSnapshotRaw = newNodeUnresolved;
+ transaction.currentOutputSnapshotResolved = newNode;
+ transaction.currentWriteId = this.getNextWriteId_();
+ var events = this.serverSyncTree_.applyUserOverwrite(path, newNode, transaction.currentWriteId, transaction.applyLocally);
+ this.eventQueue_.raiseEventsForChangedPath(path, events);
+ this.sendReadyTransactions_();
+ }
+};
+fb.core.Repo.prototype.getLatestState_ = function(path, excludeSets) {
+ return this.serverSyncTree_.calcCompleteEventCache(path, excludeSets) || fb.core.snap.EMPTY_NODE;
+};
+fb.core.Repo.prototype.sendReadyTransactions_ = function(opt_node) {
+ var node = (opt_node || this.transactionQueueTree_);
+ if (!opt_node) {
+ this.pruneCompletedTransactionsBelowNode_(node);
+ }
+ if (node.getValue() !== null) {
+ var queue = this.buildTransactionQueue_(node);
+ fb.core.util.assert(queue.length > 0, "Sending zero length transaction queue");
+ var allRun = goog.array.every(queue, function(transaction) {
+ return transaction.status === fb.core.TransactionStatus.RUN;
+ });
+ if (allRun) {
+ this.sendTransactionQueue_(node.path(), queue);
+ }
+ } else {
+ if (node.hasChildren()) {
+ var self = this;
+ node.forEachChild(function(childNode) {
+ self.sendReadyTransactions_(childNode);
+ });
+ }
+ }
+};
+fb.core.Repo.prototype.sendTransactionQueue_ = function(path, queue) {
+ var setsToIgnore = goog.array.map(queue, function(txn) {
+ return txn.currentWriteId;
+ });
+ var latestState = this.getLatestState_(path, setsToIgnore);
+ var snapToSend = latestState;
+ var latestHash = latestState.hash();
+ for (var i = 0;i < queue.length;i++) {
+ var txn = queue[i];
+ fb.core.util.assert(txn.status === fb.core.TransactionStatus.RUN, "tryToSendTransactionQueue_: items in queue should all be run.");
+ txn.status = fb.core.TransactionStatus.SENT;
+ txn.retryCount++;
+ var relativePath = fb.core.util.Path.relativePath(path, txn.path);
+ snapToSend = snapToSend.updateChild(relativePath, (txn.currentOutputSnapshotRaw));
+ }
+ var dataToSend = snapToSend.val(true);
+ var pathToSend = path;
+ var self = this;
+ this.server_.put(pathToSend.toString(), dataToSend, function(status) {
+ self.log_("transaction put response", {path:pathToSend.toString(), status:status});
+ var events = [];
+ if (status === "ok") {
+ var callbacks = [];
+ for (i = 0;i < queue.length;i++) {
+ queue[i].status = fb.core.TransactionStatus.COMPLETED;
+ events = events.concat(self.serverSyncTree_.ackUserWrite(queue[i].currentWriteId));
+ if (queue[i].onComplete) {
+ var node = (queue[i].currentOutputSnapshotResolved);
+ var ref = new Firebase(self, queue[i].path);
+ var snapshot = new fb.api.DataSnapshot(node, ref, fb.core.snap.PriorityIndex);
+ callbacks.push(goog.bind(queue[i].onComplete, null, null, true, snapshot));
+ }
+ queue[i].unwatcher();
+ }
+ self.pruneCompletedTransactionsBelowNode_(self.transactionQueueTree_.subTree(path));
+ self.sendReadyTransactions_();
+ self.eventQueue_.raiseEventsForChangedPath(path, events);
+ for (i = 0;i < callbacks.length;i++) {
+ fb.core.util.exceptionGuard(callbacks[i]);
+ }
+ } else {
+ if (status === "datastale") {
+ for (i = 0;i < queue.length;i++) {
+ if (queue[i].status === fb.core.TransactionStatus.SENT_NEEDS_ABORT) {
+ queue[i].status = fb.core.TransactionStatus.NEEDS_ABORT;
+ } else {
+ queue[i].status = fb.core.TransactionStatus.RUN;
+ }
+ }
+ } else {
+ fb.core.util.warn("transaction at " + pathToSend.toString() + " failed: " + status);
+ for (i = 0;i < queue.length;i++) {
+ queue[i].status = fb.core.TransactionStatus.NEEDS_ABORT;
+ queue[i].abortReason = status;
+ }
+ }
+ self.rerunTransactions_(path);
+ }
+ }, latestHash);
+};
+fb.core.Repo.prototype.rerunTransactions_ = function(changedPath) {
+ var rootMostTransactionNode = this.getAncestorTransactionNode_(changedPath);
+ var path = rootMostTransactionNode.path();
+ var queue = this.buildTransactionQueue_(rootMostTransactionNode);
+ this.rerunTransactionQueue_(queue, path);
+ return path;
+};
+fb.core.Repo.prototype.rerunTransactionQueue_ = function(queue, path) {
+ if (queue.length === 0) {
+ return;
+ }
+ var callbacks = [];
+ var events = [];
+ var setsToIgnore = goog.array.map(queue, function(q) {
+ return q.currentWriteId;
+ });
+ for (var i = 0;i < queue.length;i++) {
+ var transaction = queue[i];
+ var relativePath = fb.core.util.Path.relativePath(path, transaction.path);
+ var abortTransaction = false, abortReason;
+ fb.core.util.assert(relativePath !== null, "rerunTransactionsUnderNode_: relativePath should not be null.");
+ if (transaction.status === fb.core.TransactionStatus.NEEDS_ABORT) {
+ abortTransaction = true;
+ abortReason = transaction.abortReason;
+ events = events.concat(this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true));
+ } else {
+ if (transaction.status === fb.core.TransactionStatus.RUN) {
+ if (transaction.retryCount >= fb.core.Repo.MAX_TRANSACTION_RETRIES_) {
+ abortTransaction = true;
+ abortReason = "maxretry";
+ events = events.concat(this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true));
+ } else {
+ var currentNode = this.getLatestState_(transaction.path, setsToIgnore);
+ transaction.currentInputSnapshot = currentNode;
+ var newData = queue[i].update(currentNode.val());
+ if (goog.isDef(newData)) {
+ fb.core.util.validation.validateFirebaseData("transaction failed: Data returned ", newData, transaction.path);
+ var newDataNode = fb.core.snap.NodeFromJSON(newData);
+ var hasExplicitPriority = typeof newData === "object" && newData != null && fb.util.obj.contains(newData, ".priority");
+ if (!hasExplicitPriority) {
+ newDataNode = newDataNode.updatePriority(currentNode.getPriority());
+ }
+ var oldWriteId = transaction.currentWriteId;
+ var serverValues = this.generateServerValues();
+ var newNodeResolved = fb.core.util.ServerValues.resolveDeferredValueSnapshot(newDataNode, serverValues);
+ transaction.currentOutputSnapshotRaw = newDataNode;
+ transaction.currentOutputSnapshotResolved = newNodeResolved;
+ transaction.currentWriteId = this.getNextWriteId_();
+ goog.array.remove(setsToIgnore, oldWriteId);
+ events = events.concat(this.serverSyncTree_.applyUserOverwrite(transaction.path, newNodeResolved, transaction.currentWriteId, transaction.applyLocally));
+ events = events.concat(this.serverSyncTree_.ackUserWrite(oldWriteId, true));
+ } else {
+ abortTransaction = true;
+ abortReason = "nodata";
+ events = events.concat(this.serverSyncTree_.ackUserWrite(transaction.currentWriteId, true));
+ }
+ }
+ }
+ }
+ this.eventQueue_.raiseEventsForChangedPath(path, events);
+ events = [];
+ if (abortTransaction) {
+ queue[i].status = fb.core.TransactionStatus.COMPLETED;
+ (function(unwatcher) {
+ setTimeout(unwatcher, Math.floor(0));
+ })(queue[i].unwatcher);
+ if (queue[i].onComplete) {
+ if (abortReason === "nodata") {
+ var ref = new Firebase(this, queue[i].path);
+ var lastInput = (queue[i].currentInputSnapshot);
+ var snapshot = new fb.api.DataSnapshot(lastInput, ref, fb.core.snap.PriorityIndex);
+ callbacks.push(goog.bind(queue[i].onComplete, null, null, false, snapshot));
+ } else {
+ callbacks.push(goog.bind(queue[i].onComplete, null, new Error(abortReason), false, null));
+ }
+ }
+ }
+ }
+ this.pruneCompletedTransactionsBelowNode_(this.transactionQueueTree_);
+ for (i = 0;i < callbacks.length;i++) {
+ fb.core.util.exceptionGuard(callbacks[i]);
+ }
+ this.sendReadyTransactions_();
+};
+fb.core.Repo.prototype.getAncestorTransactionNode_ = function(path) {
+ var front;
+ var transactionNode = this.transactionQueueTree_;
+ while ((front = path.getFront()) !== null && transactionNode.getValue() === null) {
+ transactionNode = transactionNode.subTree(front);
+ path = path.popFront();
+ }
+ return transactionNode;
+};
+fb.core.Repo.prototype.buildTransactionQueue_ = function(transactionNode) {
+ var transactionQueue = [];
+ this.aggregateTransactionQueuesForNode_(transactionNode, transactionQueue);
+ transactionQueue.sort(function(a, b) {
+ return a.order - b.order;
+ });
+ return transactionQueue;
+};
+fb.core.Repo.prototype.aggregateTransactionQueuesForNode_ = function(node, queue) {
+ var nodeQueue = node.getValue();
+ if (nodeQueue !== null) {
+ for (var i = 0;i < nodeQueue.length;i++) {
+ queue.push(nodeQueue[i]);
+ }
+ }
+ var self = this;
+ node.forEachChild(function(child) {
+ self.aggregateTransactionQueuesForNode_(child, queue);
+ });
+};
+fb.core.Repo.prototype.pruneCompletedTransactionsBelowNode_ = function(node) {
+ var queue = node.getValue();
+ if (queue) {
+ var to = 0;
+ for (var from = 0;from < queue.length;from++) {
+ if (queue[from].status !== fb.core.TransactionStatus.COMPLETED) {
+ queue[to] = queue[from];
+ to++;
+ }
+ }
+ queue.length = to;
+ node.setValue(queue.length > 0 ? queue : null);
+ }
+ var self = this;
+ node.forEachChild(function(childNode) {
+ self.pruneCompletedTransactionsBelowNode_(childNode);
+ });
+};
+fb.core.Repo.prototype.abortTransactions_ = function(path) {
+ var affectedPath = this.getAncestorTransactionNode_(path).path();
+ var transactionNode = this.transactionQueueTree_.subTree(path);
+ var self = this;
+ transactionNode.forEachAncestor(function(node) {
+ self.abortTransactionsOnNode_(node);
+ });
+ this.abortTransactionsOnNode_(transactionNode);
+ transactionNode.forEachDescendant(function(node) {
+ self.abortTransactionsOnNode_(node);
+ });
+ return affectedPath;
+};
+fb.core.Repo.prototype.abortTransactionsOnNode_ = function(node) {
+ var queue = node.getValue();
+ if (queue !== null) {
+ var callbacks = [];
+ var events = [];
+ var lastSent = -1;
+ for (var i = 0;i < queue.length;i++) {
+ if (queue[i].status === fb.core.TransactionStatus.SENT_NEEDS_ABORT) {
+ } else {
+ if (queue[i].status === fb.core.TransactionStatus.SENT) {
+ fb.core.util.assert(lastSent === i - 1, "All SENT items should be at beginning of queue.");
+ lastSent = i;
+ queue[i].status = fb.core.TransactionStatus.SENT_NEEDS_ABORT;
+ queue[i].abortReason = "set";
+ } else {
+ fb.core.util.assert(queue[i].status === fb.core.TransactionStatus.RUN, "Unexpected transaction status in abort");
+ queue[i].unwatcher();
+ events = events.concat(this.serverSyncTree_.ackUserWrite(queue[i].currentWriteId, true));
+ if (queue[i].onComplete) {
+ var snapshot = null;
+ callbacks.push(goog.bind(queue[i].onComplete, null, new Error("set"), false, snapshot));
+ }
+ }
+ }
+ }
+ if (lastSent === -1) {
+ node.setValue(null);
+ } else {
+ queue.length = lastSent + 1;
+ }
+ this.eventQueue_.raiseEventsForChangedPath(node.path(), events);
+ for (i = 0;i < callbacks.length;i++) {
+ fb.core.util.exceptionGuard(callbacks[i]);
+ }
+ }
+};
+goog.provide("fb.core.RepoManager");
+goog.require("fb.core.Repo");
+goog.require("fb.core.Repo_transaction");
+goog.require("fb.util.obj");
+fb.core.RepoManager = function() {
+ this.repos_ = {};
+ this.useRestClient_ = false;
+};
+goog.addSingletonGetter(fb.core.RepoManager);
+fb.core.RepoManager.prototype.interrupt = function() {
+ for (var repo in this.repos_) {
+ this.repos_[repo].interrupt();
+ }
+};
+goog.exportProperty(fb.core.RepoManager.prototype, "interrupt", fb.core.RepoManager.prototype.interrupt);
+fb.core.RepoManager.prototype.resume = function() {
+ for (var repo in this.repos_) {
+ this.repos_[repo].resume();
+ }
+};
+goog.exportProperty(fb.core.RepoManager.prototype, "resume", fb.core.RepoManager.prototype.resume);
+fb.core.RepoManager.prototype.getRepo = function(repoInfo) {
+ var repoHashString = repoInfo.toString();
+ var repo = fb.util.obj.get(this.repos_, repoHashString);
+ if (!repo) {
+ repo = new fb.core.Repo(repoInfo, this.useRestClient_);
+ this.repos_[repoHashString] = repo;
+ }
+ return repo;
+};
+fb.core.RepoManager.prototype.forceRestClient = function() {
+ this.useRestClient_ = true;
+};
+goog.provide("fb.api.OnDisconnect");
+goog.require("fb.constants");
+goog.require("fb.core.Repo");
+goog.require("fb.core.util.validation");
+goog.require("fb.util.validation");
+fb.api.OnDisconnect = function(repo, path) {
+ this.repo_ = repo;
+ this.path_ = path;
+};
+fb.api.OnDisconnect.prototype.cancel = function(opt_onComplete) {
+ fb.util.validation.validateArgCount("Firebase.onDisconnect().cancel", 0, 1, arguments.length);
+ fb.util.validation.validateCallback("Firebase.onDisconnect().cancel", 1, opt_onComplete, true);
+ this.repo_.onDisconnectCancel(this.path_, opt_onComplete || null);
+};
+goog.exportProperty(fb.api.OnDisconnect.prototype, "cancel", fb.api.OnDisconnect.prototype.cancel);
+fb.api.OnDisconnect.prototype.remove = function(opt_onComplete) {
+ fb.util.validation.validateArgCount("Firebase.onDisconnect().remove", 0, 1, arguments.length);
+ fb.core.util.validation.validateWritablePath("Firebase.onDisconnect().remove", this.path_);
+ fb.util.validation.validateCallback("Firebase.onDisconnect().remove", 1, opt_onComplete, true);
+ this.repo_.onDisconnectSet(this.path_, null, opt_onComplete);
+};
+goog.exportProperty(fb.api.OnDisconnect.prototype, "remove", fb.api.OnDisconnect.prototype.remove);
+fb.api.OnDisconnect.prototype.set = function(value, opt_onComplete) {
+ fb.util.validation.validateArgCount("Firebase.onDisconnect().set", 1, 2, arguments.length);
+ fb.core.util.validation.validateWritablePath("Firebase.onDisconnect().set", this.path_);
+ fb.core.util.validation.validateFirebaseDataArg("Firebase.onDisconnect().set", 1, value, this.path_, false);
+ fb.util.validation.validateCallback("Firebase.onDisconnect().set", 2, opt_onComplete, true);
+ this.repo_.onDisconnectSet(this.path_, value, opt_onComplete);
+};
+goog.exportProperty(fb.api.OnDisconnect.prototype, "set", fb.api.OnDisconnect.prototype.set);
+fb.api.OnDisconnect.prototype.setWithPriority = function(value, priority, opt_onComplete) {
+ fb.util.validation.validateArgCount("Firebase.onDisconnect().setWithPriority", 2, 3, arguments.length);
+ fb.core.util.validation.validateWritablePath("Firebase.onDisconnect().setWithPriority", this.path_);
+ fb.core.util.validation.validateFirebaseDataArg("Firebase.onDisconnect().setWithPriority", 1, value, this.path_, false);
+ fb.core.util.validation.validatePriority("Firebase.onDisconnect().setWithPriority", 2, priority, false);
+ fb.util.validation.validateCallback("Firebase.onDisconnect().setWithPriority", 3, opt_onComplete, true);
+ this.repo_.onDisconnectSetWithPriority(this.path_, value, priority, opt_onComplete);
+};
+goog.exportProperty(fb.api.OnDisconnect.prototype, "setWithPriority", fb.api.OnDisconnect.prototype.setWithPriority);
+fb.api.OnDisconnect.prototype.update = function(objectToMerge, opt_onComplete) {
+ fb.util.validation.validateArgCount("Firebase.onDisconnect().update", 1, 2, arguments.length);
+ fb.core.util.validation.validateWritablePath("Firebase.onDisconnect().update", this.path_);
+ if (goog.isArray(objectToMerge)) {
+ var newObjectToMerge = {};
+ for (var i = 0;i < objectToMerge.length;++i) {
+ newObjectToMerge["" + i] = objectToMerge[i];
+ }
+ objectToMerge = newObjectToMerge;
+ fb.core.util.warn("Passing an Array to Firebase.onDisconnect().update() is deprecated. Use set() if you want to overwrite the " + "existing data, or an Object with integer keys if you really do want to only update some of the children.");
+ }
+ fb.core.util.validation.validateFirebaseMergeDataArg("Firebase.onDisconnect().update", 1, objectToMerge, this.path_, false);
+ fb.util.validation.validateCallback("Firebase.onDisconnect().update", 2, opt_onComplete, true);
+ this.repo_.onDisconnectUpdate(this.path_, objectToMerge, opt_onComplete);
+};
+goog.exportProperty(fb.api.OnDisconnect.prototype, "update", fb.api.OnDisconnect.prototype.update);
+goog.provide("fb.api.Query");
+goog.require("fb.api.DataSnapshot");
+goog.require("fb.core.snap");
+goog.require("fb.core.util");
+goog.require("fb.core.util.validation");
+goog.require("fb.core.view.EventRegistration");
+goog.require("fb.core.view.QueryParams");
+goog.require("fb.util.json");
+goog.require("fb.util.validation");
+fb.api.Query = function(repo, path, queryParams, orderByCalled) {
+ this.repo = repo;
+ this.path = path;
+ this.queryParams_ = queryParams;
+ this.orderByCalled_ = orderByCalled;
+};
+fb.api.Query.prototype.validateQueryEndpoints_ = function(params) {
+ var startNode = null;
+ var endNode = null;
+ if (params.hasStart()) {
+ startNode = params.getIndexStartValue();
+ }
+ if (params.hasEnd()) {
+ endNode = params.getIndexEndValue();
+ }
+ if (params.getIndex() === fb.core.snap.KeyIndex) {
+ var tooManyArgsError = "Query: When ordering by key, you may only pass one argument to " + "startAt(), endAt(), or equalTo().";
+ var wrongArgTypeError = "Query: When ordering by key, the argument passed to startAt(), endAt()," + "or equalTo() must be a string.";
+ if (params.hasStart()) {
+ var startName = params.getIndexStartName();
+ if (startName != fb.core.util.MIN_NAME) {
+ throw new Error(tooManyArgsError);
+ } else {
+ if (typeof startNode !== "string") {
+ throw new Error(wrongArgTypeError);
+ }
+ }
+ }
+ if (params.hasEnd()) {
+ var endName = params.getIndexEndName();
+ if (endName != fb.core.util.MAX_NAME) {
+ throw new Error(tooManyArgsError);
+ } else {
+ if (typeof endNode !== "string") {
+ throw new Error(wrongArgTypeError);
+ }
+ }
+ }
+ } else {
+ if (params.getIndex() === fb.core.snap.PriorityIndex) {
+ if (startNode != null && !fb.core.util.validation.isValidPriority(startNode) || endNode != null && !fb.core.util.validation.isValidPriority(endNode)) {
+ throw new Error("Query: When ordering by priority, the first argument passed to startAt(), " + "endAt(), or equalTo() must be a valid priority value (null, a number, or a string).");
+ }
+ } else {
+ fb.core.util.assert(params.getIndex() instanceof fb.core.snap.SubKeyIndex || params.getIndex() === fb.core.snap.ValueIndex, "unknown index type.");
+ if (startNode != null && typeof startNode === "object" || endNode != null && typeof endNode === "object") {
+ throw new Error("Query: First argument passed to startAt(), endAt(), or equalTo() cannot be " + "an object.");
+ }
+ }
+ }
+};
+fb.api.Query.prototype.validateLimit_ = function(params) {
+ if (params.hasStart() && params.hasEnd() && params.hasLimit() && !params.hasAnchoredLimit()) {
+ throw new Error("Query: Can't combine startAt(), endAt(), and limit(). Use limitToFirst() or limitToLast() instead.");
+ }
+};
+fb.api.Query.prototype.validateNoPreviousOrderByCall_ = function(fnName) {
+ if (this.orderByCalled_ === true) {
+ throw new Error(fnName + ": You can't combine multiple orderBy calls.");
+ }
+};
+fb.api.Query.prototype.getQueryParams = function() {
+ return this.queryParams_;
+};
+fb.api.Query.prototype.ref = function() {
+ fb.util.validation.validateArgCount("Query.ref", 0, 0, arguments.length);
+ return new Firebase(this.repo, this.path);
+};
+goog.exportProperty(fb.api.Query.prototype, "ref", fb.api.Query.prototype.ref);
+fb.api.Query.prototype.on = function(eventType, callback, cancelCallbackOrContext, context) {
+ fb.util.validation.validateArgCount("Query.on", 2, 4, arguments.length);
+ fb.core.util.validation.validateEventType("Query.on", 1, eventType, false);
+ fb.util.validation.validateCallback("Query.on", 2, callback, false);
+ var ret = this.getCancelAndContextArgs_("Query.on", cancelCallbackOrContext, context);
+ if (eventType === "value") {
+ this.onValueEvent(callback, ret.cancel, ret.context);
+ } else {
+ var callbacks = {};
+ callbacks[eventType] = callback;
+ this.onChildEvent(callbacks, ret.cancel, ret.context);
+ }
+ return callback;
+};
+goog.exportProperty(fb.api.Query.prototype, "on", fb.api.Query.prototype.on);
+fb.api.Query.prototype.onValueEvent = function(callback, cancelCallback, context) {
+ var container = new fb.core.view.ValueEventRegistration(callback, cancelCallback || null, context || null);
+ this.repo.addEventCallbackForQuery(this, container);
+};
+fb.api.Query.prototype.onChildEvent = function(callbacks, cancelCallback, context) {
+ var container = new fb.core.view.ChildEventRegistration(callbacks, cancelCallback, context);
+ this.repo.addEventCallbackForQuery(this, container);
+};
+fb.api.Query.prototype.off = function(eventType, callback, opt_context) {
+ fb.util.validation.validateArgCount("Query.off", 0, 3, arguments.length);
+ fb.core.util.validation.validateEventType("Query.off", 1, eventType, true);
+ fb.util.validation.validateCallback("Query.off", 2, callback, true);
+ fb.util.validation.validateContextObject("Query.off", 3, opt_context, true);
+ var container = null;
+ var callbacks = null;
+ if (eventType === "value") {
+ var valueCallback = (callback) || null;
+ container = new fb.core.view.ValueEventRegistration(valueCallback, null, opt_context || null);
+ } else {
+ if (eventType) {
+ if (callback) {
+ callbacks = {};
+ callbacks[eventType] = callback;
+ }
+ container = new fb.core.view.ChildEventRegistration(callbacks, null, opt_context || null);
+ }
+ }
+ this.repo.removeEventCallbackForQuery(this, container);
+};
+goog.exportProperty(fb.api.Query.prototype, "off", fb.api.Query.prototype.off);
+fb.api.Query.prototype.once = function(eventType, userCallback) {
+ fb.util.validation.validateArgCount("Query.once", 2, 4, arguments.length);
+ fb.core.util.validation.validateEventType("Query.once", 1, eventType, false);
+ fb.util.validation.validateCallback("Query.once", 2, userCallback, false);
+ var ret = this.getCancelAndContextArgs_("Query.once", arguments[2], arguments[3]);
+ var self = this, firstCall = true;
+ var onceCallback = function(snapshot) {
+ if (firstCall) {
+ firstCall = false;
+ self.off(eventType, onceCallback);
+ goog.bind(userCallback, ret.context)(snapshot);
+ }
+ };
+ this.on(eventType, onceCallback, function(err) {
+ self.off(eventType, onceCallback);
+ if (ret.cancel) {
+ goog.bind(ret.cancel, ret.context)(err);
+ }
+ });
+};
+goog.exportProperty(fb.api.Query.prototype, "once", fb.api.Query.prototype.once);
+fb.api.Query.prototype.limit = function(limit) {
+ fb.core.util.warn("Query.limit() being deprecated. " + "Please use Query.limitToFirst() or Query.limitToLast() instead.");
+ fb.util.validation.validateArgCount("Query.limit", 1, 1, arguments.length);
+ if (!goog.isNumber(limit) || Math.floor(limit) !== limit || limit <= 0) {
+ throw new Error("Query.limit: First argument must be a positive integer.");
+ }
+ if (this.queryParams_.hasLimit()) {
+ throw new Error("Query.limit: Limit was already set (by another call to limit, limitToFirst, or" + "limitToLast.");
+ }
+ var newParams = this.queryParams_.limit(limit);
+ this.validateLimit_(newParams);
+ return new fb.api.Query(this.repo, this.path, newParams, this.orderByCalled_);
+};
+goog.exportProperty(fb.api.Query.prototype, "limit", fb.api.Query.prototype.limit);
+fb.api.Query.prototype.limitToFirst = function(limit) {
+ fb.util.validation.validateArgCount("Query.limitToFirst", 1, 1, arguments.length);
+ if (!goog.isNumber(limit) || Math.floor(limit) !== limit || limit <= 0) {
+ throw new Error("Query.limitToFirst: First argument must be a positive integer.");
+ }
+ if (this.queryParams_.hasLimit()) {
+ throw new Error("Query.limitToFirst: Limit was already set (by another call to limit, " + "limitToFirst, or limitToLast).");
+ }
+ return new fb.api.Query(this.repo, this.path, this.queryParams_.limitToFirst(limit), this.orderByCalled_);
+};
+goog.exportProperty(fb.api.Query.prototype, "limitToFirst", fb.api.Query.prototype.limitToFirst);
+fb.api.Query.prototype.limitToLast = function(limit) {
+ fb.util.validation.validateArgCount("Query.limitToLast", 1, 1, arguments.length);
+ if (!goog.isNumber(limit) || Math.floor(limit) !== limit || limit <= 0) {
+ throw new Error("Query.limitToLast: First argument must be a positive integer.");
+ }
+ if (this.queryParams_.hasLimit()) {
+ throw new Error("Query.limitToLast: Limit was already set (by another call to limit, " + "limitToFirst, or limitToLast).");
+ }
+ return new fb.api.Query(this.repo, this.path, this.queryParams_.limitToLast(limit), this.orderByCalled_);
+};
+goog.exportProperty(fb.api.Query.prototype, "limitToLast", fb.api.Query.prototype.limitToLast);
+fb.api.Query.prototype.orderByChild = function(key) {
+ fb.util.validation.validateArgCount("Query.orderByChild", 1, 1, arguments.length);
+ if (key === "$key") {
+ throw new Error('Query.orderByChild: "$key" is invalid. Use Query.orderByKey() instead.');
+ } else {
+ if (key === "$priority") {
+ throw new Error('Query.orderByChild: "$priority" is invalid. Use Query.orderByPriority() instead.');
+ } else {
+ if (key === "$value") {
+ throw new Error('Query.orderByChild: "$value" is invalid. Use Query.orderByValue() instead.');
+ }
+ }
+ }
+ fb.core.util.validation.validateKey("Query.orderByChild", 1, key, false);
+ this.validateNoPreviousOrderByCall_("Query.orderByChild");
+ var index = new fb.core.snap.SubKeyIndex(key);
+ var newParams = this.queryParams_.orderBy(index);
+ this.validateQueryEndpoints_(newParams);
+ return new fb.api.Query(this.repo, this.path, newParams, true);
+};
+goog.exportProperty(fb.api.Query.prototype, "orderByChild", fb.api.Query.prototype.orderByChild);
+fb.api.Query.prototype.orderByKey = function() {
+ fb.util.validation.validateArgCount("Query.orderByKey", 0, 0, arguments.length);
+ this.validateNoPreviousOrderByCall_("Query.orderByKey");
+ var newParams = this.queryParams_.orderBy(fb.core.snap.KeyIndex);
+ this.validateQueryEndpoints_(newParams);
+ return new fb.api.Query(this.repo, this.path, newParams, true);
+};
+goog.exportProperty(fb.api.Query.prototype, "orderByKey", fb.api.Query.prototype.orderByKey);
+fb.api.Query.prototype.orderByPriority = function() {
+ fb.util.validation.validateArgCount("Query.orderByPriority", 0, 0, arguments.length);
+ this.validateNoPreviousOrderByCall_("Query.orderByPriority");
+ var newParams = this.queryParams_.orderBy(fb.core.snap.PriorityIndex);
+ this.validateQueryEndpoints_(newParams);
+ return new fb.api.Query(this.repo, this.path, newParams, true);
+};
+goog.exportProperty(fb.api.Query.prototype, "orderByPriority", fb.api.Query.prototype.orderByPriority);
+fb.api.Query.prototype.orderByValue = function() {
+ fb.util.validation.validateArgCount("Query.orderByValue", 0, 0, arguments.length);
+ this.validateNoPreviousOrderByCall_("Query.orderByValue");
+ var newParams = this.queryParams_.orderBy(fb.core.snap.ValueIndex);
+ this.validateQueryEndpoints_(newParams);
+ return new fb.api.Query(this.repo, this.path, newParams, true);
+};
+goog.exportProperty(fb.api.Query.prototype, "orderByValue", fb.api.Query.prototype.orderByValue);
+fb.api.Query.prototype.startAt = function(value, name) {
+ fb.util.validation.validateArgCount("Query.startAt", 0, 2, arguments.length);
+ fb.core.util.validation.validateFirebaseDataArg("Query.startAt", 1, value, this.path, true);
+ fb.core.util.validation.validateKey("Query.startAt", 2, name, true);
+ var newParams = this.queryParams_.startAt(value, name);
+ this.validateLimit_(newParams);
+ this.validateQueryEndpoints_(newParams);
+ if (this.queryParams_.hasStart()) {
+ throw new Error("Query.startAt: Starting point was already set (by another call to startAt " + "or equalTo).");
+ }
+ if (!goog.isDef(value)) {
+ value = null;
+ name = null;
+ }
+ return new fb.api.Query(this.repo, this.path, newParams, this.orderByCalled_);
+};
+goog.exportProperty(fb.api.Query.prototype, "startAt", fb.api.Query.prototype.startAt);
+fb.api.Query.prototype.endAt = function(value, name) {
+ fb.util.validation.validateArgCount("Query.endAt", 0, 2, arguments.length);
+ fb.core.util.validation.validateFirebaseDataArg("Query.endAt", 1, value, this.path, true);
+ fb.core.util.validation.validateKey("Query.endAt", 2, name, true);
+ var newParams = this.queryParams_.endAt(value, name);
+ this.validateLimit_(newParams);
+ this.validateQueryEndpoints_(newParams);
+ if (this.queryParams_.hasEnd()) {
+ throw new Error("Query.endAt: Ending point was already set (by another call to endAt or " + "equalTo).");
+ }
+ return new fb.api.Query(this.repo, this.path, newParams, this.orderByCalled_);
+};
+goog.exportProperty(fb.api.Query.prototype, "endAt", fb.api.Query.prototype.endAt);
+fb.api.Query.prototype.equalTo = function(value, name) {
+ fb.util.validation.validateArgCount("Query.equalTo", 1, 2, arguments.length);
+ fb.core.util.validation.validateFirebaseDataArg("Query.equalTo", 1, value, this.path, false);
+ fb.core.util.validation.validateKey("Query.equalTo", 2, name, true);
+ if (this.queryParams_.hasStart()) {
+ throw new Error("Query.equalTo: Starting point was already set (by another call to endAt or " + "equalTo).");
+ }
+ if (this.queryParams_.hasEnd()) {
+ throw new Error("Query.equalTo: Ending point was already set (by another call to endAt or " + "equalTo).");
+ }
+ return this.startAt(value, name).endAt(value, name);
+};
+goog.exportProperty(fb.api.Query.prototype, "equalTo", fb.api.Query.prototype.equalTo);
+fb.api.Query.prototype.toString = function() {
+ fb.util.validation.validateArgCount("Query.toString", 0, 0, arguments.length);
+ return this.repo.toString() + this.path.toUrlEncodedString();
+};
+goog.exportProperty(fb.api.Query.prototype, "toString", fb.api.Query.prototype.toString);
+fb.api.Query.prototype.queryObject = function() {
+ return this.queryParams_.getQueryObject();
+};
+fb.api.Query.prototype.queryIdentifier = function() {
+ var obj = this.queryObject();
+ var id = fb.core.util.ObjectToUniqueKey(obj);
+ return id === "{}" ? "default" : id;
+};
+fb.api.Query.prototype.getCancelAndContextArgs_ = function(fnName, cancelOrContext, context) {
+ var ret = {cancel:null, context:null};
+ if (cancelOrContext && context) {
+ ret.cancel = (cancelOrContext);
+ fb.util.validation.validateCallback(fnName, 3, ret.cancel, true);
+ ret.context = context;
+ fb.util.validation.validateContextObject(fnName, 4, ret.context, true);
+ } else {
+ if (cancelOrContext) {
+ if (typeof cancelOrContext === "object" && cancelOrContext !== null) {
+ ret.context = cancelOrContext;
+ } else {
+ if (typeof cancelOrContext === "function") {
+ ret.cancel = cancelOrContext;
+ } else {
+ throw new Error(fb.util.validation.errorPrefix(fnName, 3, true) + " must either be a cancel callback or a context object.");
+ }
+ }
+ }
+ }
+ return ret;
+};
+goog.provide("fb.api.TEST_ACCESS");
+goog.require("fb.core.PersistentConnection");
+fb.api.TEST_ACCESS.DataConnection = fb.core.PersistentConnection;
+goog.exportProperty(fb.api.TEST_ACCESS, "DataConnection", fb.api.TEST_ACCESS.DataConnection);
+fb.core.PersistentConnection.prototype.simpleListen = function(pathString, onComplete) {
+ this.sendRequest("q", {"p":pathString}, onComplete);
+};
+goog.exportProperty(fb.api.TEST_ACCESS.DataConnection.prototype, "simpleListen", fb.api.TEST_ACCESS.DataConnection.prototype.simpleListen);
+fb.core.PersistentConnection.prototype.echo = function(data, onEcho) {
+ this.sendRequest("echo", {"d":data}, onEcho);
+};
+goog.exportProperty(fb.api.TEST_ACCESS.DataConnection.prototype, "echo", fb.api.TEST_ACCESS.DataConnection.prototype.echo);
+goog.exportProperty(fb.core.PersistentConnection.prototype, "interrupt", fb.core.PersistentConnection.prototype.interrupt);
+fb.api.TEST_ACCESS.RealTimeConnection = fb.realtime.Connection;
+goog.exportProperty(fb.api.TEST_ACCESS, "RealTimeConnection", fb.api.TEST_ACCESS.RealTimeConnection);
+goog.exportProperty(fb.realtime.Connection.prototype, "sendRequest", fb.realtime.Connection.prototype.sendRequest);
+goog.exportProperty(fb.realtime.Connection.prototype, "close", fb.realtime.Connection.prototype.close);
+fb.api.TEST_ACCESS.hijackHash = function(newHash) {
+ var oldPut = fb.core.PersistentConnection.prototype.put;
+ fb.core.PersistentConnection.prototype.put = function(pathString, data, opt_onComplete, opt_hash) {
+ if (goog.isDef(opt_hash)) {
+ opt_hash = newHash();
+ }
+ oldPut.call(this, pathString, data, opt_onComplete, opt_hash);
+ };
+ return function() {
+ fb.core.PersistentConnection.prototype.put = oldPut;
+ };
+};
+goog.exportProperty(fb.api.TEST_ACCESS, "hijackHash", fb.api.TEST_ACCESS.hijackHash);
+fb.api.TEST_ACCESS.ConnectionTarget = fb.core.RepoInfo;
+goog.exportProperty(fb.api.TEST_ACCESS, "ConnectionTarget", fb.api.TEST_ACCESS.ConnectionTarget);
+fb.api.TEST_ACCESS.queryIdentifier = function(query) {
+ return query.queryIdentifier();
+};
+goog.exportProperty(fb.api.TEST_ACCESS, "queryIdentifier", fb.api.TEST_ACCESS.queryIdentifier);
+fb.api.TEST_ACCESS.listens = function(firebaseRef) {
+ return firebaseRef.repo.persistentConnection_.listens_;
+};
+goog.exportProperty(fb.api.TEST_ACCESS, "listens", fb.api.TEST_ACCESS.listens);
+fb.api.TEST_ACCESS.forceRestClient = function(repoManager) {
+ repoManager.forceRestClient();
+};
+goog.exportProperty(fb.api.TEST_ACCESS, "forceRestClient", fb.api.TEST_ACCESS.forceRestClient);
+goog.provide("Firebase");
+goog.require("fb.api.INTERNAL");
+goog.require("fb.api.OnDisconnect");
+goog.require("fb.api.Query");
+goog.require("fb.api.TEST_ACCESS");
+goog.require("fb.constants");
+goog.require("fb.core.Repo");
+goog.require("fb.core.RepoManager");
+goog.require("fb.core.storage");
+goog.require("fb.core.util");
+goog.require("fb.core.util.nextPushId");
+goog.require("fb.core.util.validation");
+goog.require("goog.string");
+Firebase = function(urlOrRepo, pathOrContext) {
+ var repo, path, repoManager;
+ if (urlOrRepo instanceof fb.core.Repo) {
+ repo = urlOrRepo;
+ path = (pathOrContext);
+ } else {
+ fb.util.validation.validateArgCount("new Firebase", 1, 2, arguments.length);
+ var parsedUrl = fb.core.util.parseRepoInfo(arguments[0]), repoInfo = parsedUrl.repoInfo;
+ fb.core.util.validation.validateUrl("new Firebase", 1, parsedUrl);
+ if (pathOrContext) {
+ if (pathOrContext instanceof fb.core.RepoManager) {
+ repoManager = (pathOrContext);
+ } else {
+ if (goog.isString(pathOrContext)) {
+ repoManager = fb.core.RepoManager.getInstance();
+ repoInfo.persistenceKey = pathOrContext;
+ } else {
+ throw new Error("Expected a valid Firebase.Context for second argument to new Firebase()");
+ }
+ }
+ } else {
+ repoManager = fb.core.RepoManager.getInstance();
+ }
+ repo = repoManager.getRepo(repoInfo);
+ path = parsedUrl.path;
+ }
+ fb.api.Query.call(this, repo, path, fb.core.view.QueryParams.DEFAULT, false);
+};
+goog.inherits(Firebase, fb.api.Query);
+if (NODE_CLIENT) {
+ module["exports"] = Firebase;
+}
+Firebase.prototype.name = function() {
+ fb.core.util.warn("Firebase.name() being deprecated. Please use Firebase.key() instead.");
+ fb.util.validation.validateArgCount("Firebase.name", 0, 0, arguments.length);
+ return this.key();
+};
+Firebase.prototype.key = function() {
+ fb.util.validation.validateArgCount("Firebase.key", 0, 0, arguments.length);
+ if (this.path.isEmpty()) {
+ return null;
+ } else {
+ return this.path.getBack();
+ }
+};
+Firebase.prototype.child = function(pathString) {
+ fb.util.validation.validateArgCount("Firebase.child", 1, 1, arguments.length);
+ if (goog.isNumber(pathString)) {
+ pathString = String(pathString);
+ } else {
+ if (!(pathString instanceof fb.core.util.Path)) {
+ if (this.path.getFront() === null) {
+ fb.core.util.validation.validateRootPathString("Firebase.child", 1, pathString, false);
+ } else {
+ fb.core.util.validation.validatePathString("Firebase.child", 1, pathString, false);
+ }
+ }
+ }
+ return new Firebase(this.repo, this.path.child(pathString));
+};
+Firebase.prototype.parent = function() {
+ fb.util.validation.validateArgCount("Firebase.parent", 0, 0, arguments.length);
+ var parentPath = this.path.parent();
+ return parentPath === null ? null : new Firebase(this.repo, parentPath);
+};
+Firebase.prototype.root = function() {
+ fb.util.validation.validateArgCount("Firebase.ref", 0, 0, arguments.length);
+ var ref = this;
+ while (ref.parent() !== null) {
+ ref = ref.parent();
+ }
+ return ref;
+};
+Firebase.prototype.set = function(newVal, onComplete) {
+ fb.util.validation.validateArgCount("Firebase.set", 1, 2, arguments.length);
+ fb.core.util.validation.validateWritablePath("Firebase.set", this.path);
+ fb.core.util.validation.validateFirebaseDataArg("Firebase.set", 1, newVal, this.path, false);
+ fb.util.validation.validateCallback("Firebase.set", 2, onComplete, true);
+ this.repo.setWithPriority(this.path, newVal, null, onComplete || null);
+};
+Firebase.prototype.update = function(objectToMerge, onComplete) {
+ fb.util.validation.validateArgCount("Firebase.update", 1, 2, arguments.length);
+ fb.core.util.validation.validateWritablePath("Firebase.update", this.path);
+ if (goog.isArray(objectToMerge)) {
+ var newObjectToMerge = {};
+ for (var i = 0;i < objectToMerge.length;++i) {
+ newObjectToMerge["" + i] = objectToMerge[i];
+ }
+ objectToMerge = newObjectToMerge;
+ fb.core.util.warn("Passing an Array to Firebase.update() is deprecated. Use set() if you want to overwrite the existing data, or " + "an Object with integer keys if you really do want to only update some of the children.");
+ }
+ fb.core.util.validation.validateFirebaseMergeDataArg("Firebase.update", 1, objectToMerge, this.path, false);
+ fb.util.validation.validateCallback("Firebase.update", 2, onComplete, true);
+ this.repo.update(this.path, objectToMerge, onComplete || null);
+};
+Firebase.prototype.setWithPriority = function(newVal, newPriority, onComplete) {
+ fb.util.validation.validateArgCount("Firebase.setWithPriority", 2, 3, arguments.length);
+ fb.core.util.validation.validateWritablePath("Firebase.setWithPriority", this.path);
+ fb.core.util.validation.validateFirebaseDataArg("Firebase.setWithPriority", 1, newVal, this.path, false);
+ fb.core.util.validation.validatePriority("Firebase.setWithPriority", 2, newPriority, false);
+ fb.util.validation.validateCallback("Firebase.setWithPriority", 3, onComplete, true);
+ if (this.key() === ".length" || this.key() === ".keys") {
+ throw "Firebase.setWithPriority failed: " + this.key() + " is a read-only object.";
+ }
+ this.repo.setWithPriority(this.path, newVal, newPriority, onComplete || null);
+};
+Firebase.prototype.remove = function(onComplete) {
+ fb.util.validation.validateArgCount("Firebase.remove", 0, 1, arguments.length);
+ fb.core.util.validation.validateWritablePath("Firebase.remove", this.path);
+ fb.util.validation.validateCallback("Firebase.remove", 1, onComplete, true);
+ this.set(null, onComplete);
+};
+Firebase.prototype.transaction = function(transactionUpdate, onComplete, applyLocally) {
+ fb.util.validation.validateArgCount("Firebase.transaction", 1, 3, arguments.length);
+ fb.core.util.validation.validateWritablePath("Firebase.transaction", this.path);
+ fb.util.validation.validateCallback("Firebase.transaction", 1, transactionUpdate, false);
+ fb.util.validation.validateCallback("Firebase.transaction", 2, onComplete, true);
+ fb.core.util.validation.validateBoolean("Firebase.transaction", 3, applyLocally, true);
+ if (this.key() === ".length" || this.key() === ".keys") {
+ throw "Firebase.transaction failed: " + this.key() + " is a read-only object.";
+ }
+ if (typeof applyLocally === "undefined") {
+ applyLocally = true;
+ }
+ this.repo.startTransaction(this.path, transactionUpdate, onComplete || null, applyLocally);
+};
+Firebase.prototype.setPriority = function(priority, opt_onComplete) {
+ fb.util.validation.validateArgCount("Firebase.setPriority", 1, 2, arguments.length);
+ fb.core.util.validation.validateWritablePath("Firebase.setPriority", this.path);
+ fb.core.util.validation.validatePriority("Firebase.setPriority", 1, priority, false);
+ fb.util.validation.validateCallback("Firebase.setPriority", 2, opt_onComplete, true);
+ this.repo.setWithPriority(this.path.child(".priority"), priority, null, opt_onComplete);
+};
+Firebase.prototype.push = function(value, onComplete) {
+ fb.util.validation.validateArgCount("Firebase.push", 0, 2, arguments.length);
+ fb.core.util.validation.validateWritablePath("Firebase.push", this.path);
+ fb.core.util.validation.validateFirebaseDataArg("Firebase.push", 1, value, this.path, true);
+ fb.util.validation.validateCallback("Firebase.push", 2, onComplete, true);
+ var now = this.repo.serverTime();
+ var name = fb.core.util.nextPushId(now);
+ var pushedRef = this.child(name);
+ if (typeof value !== "undefined" && value !== null) {
+ pushedRef.set(value, onComplete);
+ }
+ return pushedRef;
+};
+Firebase.prototype.onDisconnect = function() {
+ fb.core.util.validation.validateWritablePath("Firebase.onDisconnect", this.path);
+ return new fb.api.OnDisconnect(this.repo, this.path);
+};
+Firebase.prototype.auth = function(cred, opt_onComplete, opt_onCancel) {
+ fb.core.util.warn("FirebaseRef.auth() being deprecated. " + "Please use FirebaseRef.authWithCustomToken() instead.");
+ fb.util.validation.validateArgCount("Firebase.auth", 1, 3, arguments.length);
+ fb.core.util.validation.validateCredential("Firebase.auth", 1, cred, false);
+ fb.util.validation.validateCallback("Firebase.auth", 2, opt_onComplete, true);
+ fb.util.validation.validateCallback("Firebase.auth", 3, opt_onComplete, true);
+ var clientOptions = {};
+ clientOptions[fb.login.Constants.CLIENT_OPTION_SESSION_PERSISTENCE] = "none";
+ this.repo.auth.authenticate(cred, {}, clientOptions, opt_onComplete, opt_onCancel);
+};
+Firebase.prototype.unauth = function(opt_onComplete) {
+ fb.util.validation.validateArgCount("Firebase.unauth", 0, 1, arguments.length);
+ fb.util.validation.validateCallback("Firebase.unauth", 1, opt_onComplete, true);
+ this.repo.auth.unauthenticate(opt_onComplete);
+};
+Firebase.prototype.getAuth = function() {
+ fb.util.validation.validateArgCount("Firebase.getAuth", 0, 0, arguments.length);
+ return this.repo.auth.getAuth();
+};
+Firebase.prototype.onAuth = function(callback, opt_context) {
+ fb.util.validation.validateArgCount("Firebase.onAuth", 1, 2, arguments.length);
+ fb.util.validation.validateCallback("Firebase.onAuth", 1, callback, false);
+ fb.util.validation.validateContextObject("Firebase.onAuth", 2, opt_context, true);
+ this.repo.auth.on("auth_status", callback, opt_context);
+};
+Firebase.prototype.offAuth = function(callback, opt_context) {
+ fb.util.validation.validateArgCount("Firebase.offAuth", 1, 2, arguments.length);
+ fb.util.validation.validateCallback("Firebase.offAuth", 1, callback, false);
+ fb.util.validation.validateContextObject("Firebase.offAuth", 2, opt_context, true);
+ this.repo.auth.off("auth_status", callback, opt_context);
+};
+Firebase.prototype.authWithCustomToken = function(token, onComplete, opt_options) {
+ fb.util.validation.validateArgCount("Firebase.authWithCustomToken", 2, 3, arguments.length);
+ fb.core.util.validation.validateCredential("Firebase.authWithCustomToken", 1, token, false);
+ fb.util.validation.validateCallback("Firebase.authWithCustomToken", 2, onComplete, false);
+ fb.core.util.validation.validateObject("Firebase.authWithCustomToken", 3, opt_options, true);
+ this.repo.auth.authenticate(token, {}, opt_options || {}, onComplete);
+};
+Firebase.prototype.authWithOAuthPopup = function(provider, onComplete, opt_options) {
+ fb.util.validation.validateArgCount("Firebase.authWithOAuthPopup", 2, 3, arguments.length);
+ fb.core.util.validation.validateAuthProvider("Firebase.authWithOAuthPopup", 1, provider, false);
+ fb.util.validation.validateCallback("Firebase.authWithOAuthPopup", 2, onComplete, false);
+ fb.core.util.validation.validateObject("Firebase.authWithOAuthPopup", 3, opt_options, true);
+ this.repo.auth.authWithPopup(provider, opt_options, onComplete);
+};
+Firebase.prototype.authWithOAuthRedirect = function(provider, onErr, opt_options) {
+ fb.util.validation.validateArgCount("Firebase.authWithOAuthRedirect", 2, 3, arguments.length);
+ fb.core.util.validation.validateAuthProvider("Firebase.authWithOAuthRedirect", 1, provider, false);
+ fb.util.validation.validateCallback("Firebase.authWithOAuthRedirect", 2, onErr, false);
+ fb.core.util.validation.validateObject("Firebase.authWithOAuthRedirect", 3, opt_options, true);
+ this.repo.auth.authWithRedirect(provider, opt_options, onErr);
+};
+Firebase.prototype.authWithOAuthToken = function(provider, params, onComplete, opt_options) {
+ fb.util.validation.validateArgCount("Firebase.authWithOAuthToken", 3, 4, arguments.length);
+ fb.core.util.validation.validateAuthProvider("Firebase.authWithOAuthToken", 1, provider, false);
+ fb.util.validation.validateCallback("Firebase.authWithOAuthToken", 3, onComplete, false);
+ fb.core.util.validation.validateObject("Firebase.authWithOAuthToken", 4, opt_options, true);
+ if (goog.isString(params)) {
+ fb.core.util.validation.validateString("Firebase.authWithOAuthToken", 2, params, false);
+ this.repo.auth.authWithCredential(provider + "/token", {"access_token":params}, opt_options, onComplete);
+ } else {
+ fb.core.util.validation.validateObject("Firebase.authWithOAuthToken", 2, params, false);
+ this.repo.auth.authWithCredential(provider + "/token", params, opt_options, onComplete);
+ }
+};
+Firebase.prototype.authAnonymously = function(onComplete, opt_options) {
+ fb.util.validation.validateArgCount("Firebase.authAnonymously", 1, 2, arguments.length);
+ fb.util.validation.validateCallback("Firebase.authAnonymously", 1, onComplete, false);
+ fb.core.util.validation.validateObject("Firebase.authAnonymously", 2, opt_options, true);
+ this.repo.auth.authWithCredential("anonymous", {}, opt_options, onComplete);
+};
+Firebase.prototype.authWithPassword = function(params, onComplete, opt_options) {
+ fb.util.validation.validateArgCount("Firebase.authWithPassword", 2, 3, arguments.length);
+ fb.core.util.validation.validateObject("Firebase.authWithPassword", 1, params, false);
+ fb.core.util.validation.validateObjectContainsKey("Firebase.authWithPassword", 1, params, "email", false, "string");
+ fb.core.util.validation.validateObjectContainsKey("Firebase.authWithPassword", 1, params, "password", false, "string");
+ fb.util.validation.validateCallback("Firebase.authWithPassword", 2, onComplete, false);
+ fb.core.util.validation.validateObject("Firebase.authWithPassword", 3, opt_options, true);
+ this.repo.auth.authWithCredential("password", params, opt_options, onComplete);
+};
+Firebase.prototype.createUser = function(params, onComplete) {
+ fb.util.validation.validateArgCount("Firebase.createUser", 2, 2, arguments.length);
+ fb.core.util.validation.validateObject("Firebase.createUser", 1, params, false);
+ fb.core.util.validation.validateObjectContainsKey("Firebase.createUser", 1, params, "email", false, "string");
+ fb.core.util.validation.validateObjectContainsKey("Firebase.createUser", 1, params, "password", false, "string");
+ fb.util.validation.validateCallback("Firebase.createUser", 2, onComplete, false);
+ this.repo.auth.createUser(params, onComplete);
+};
+Firebase.prototype.removeUser = function(params, onComplete) {
+ fb.util.validation.validateArgCount("Firebase.removeUser", 2, 2, arguments.length);
+ fb.core.util.validation.validateObject("Firebase.removeUser", 1, params, false);
+ fb.core.util.validation.validateObjectContainsKey("Firebase.removeUser", 1, params, "email", false, "string");
+ fb.core.util.validation.validateObjectContainsKey("Firebase.removeUser", 1, params, "password", false, "string");
+ fb.util.validation.validateCallback("Firebase.removeUser", 2, onComplete, false);
+ this.repo.auth.removeUser(params, onComplete);
+};
+Firebase.prototype.changePassword = function(params, onComplete) {
+ fb.util.validation.validateArgCount("Firebase.changePassword", 2, 2, arguments.length);
+ fb.core.util.validation.validateObject("Firebase.changePassword", 1, params, false);
+ fb.core.util.validation.validateObjectContainsKey("Firebase.changePassword", 1, params, "email", false, "string");
+ fb.core.util.validation.validateObjectContainsKey("Firebase.changePassword", 1, params, "oldPassword", false, "string");
+ fb.core.util.validation.validateObjectContainsKey("Firebase.changePassword", 1, params, "newPassword", false, "string");
+ fb.util.validation.validateCallback("Firebase.changePassword", 2, onComplete, false);
+ this.repo.auth.changePassword(params, onComplete);
+};
+Firebase.prototype.changeEmail = function(params, onComplete) {
+ fb.util.validation.validateArgCount("Firebase.changeEmail", 2, 2, arguments.length);
+ fb.core.util.validation.validateObject("Firebase.changeEmail", 1, params, false);
+ fb.core.util.validation.validateObjectContainsKey("Firebase.changeEmail", 1, params, "oldEmail", false, "string");
+ fb.core.util.validation.validateObjectContainsKey("Firebase.changeEmail", 1, params, "newEmail", false, "string");
+ fb.core.util.validation.validateObjectContainsKey("Firebase.changeEmail", 1, params, "password", false, "string");
+ fb.util.validation.validateCallback("Firebase.changeEmail", 2, onComplete, false);
+ this.repo.auth.changeEmail(params, onComplete);
+};
+Firebase.prototype.resetPassword = function(params, onComplete) {
+ fb.util.validation.validateArgCount("Firebase.resetPassword", 2, 2, arguments.length);
+ fb.core.util.validation.validateObject("Firebase.resetPassword", 1, params, false);
+ fb.core.util.validation.validateObjectContainsKey("Firebase.resetPassword", 1, params, "email", false, "string");
+ fb.util.validation.validateCallback("Firebase.resetPassword", 2, onComplete, false);
+ this.repo.auth.resetPassword(params, onComplete);
+};
+Firebase.goOffline = function() {
+ fb.util.validation.validateArgCount("Firebase.goOffline", 0, 0, arguments.length);
+ fb.core.RepoManager.getInstance().interrupt();
+};
+Firebase.goOnline = function() {
+ fb.util.validation.validateArgCount("Firebase.goOnline", 0, 0, arguments.length);
+ fb.core.RepoManager.getInstance().resume();
+};
+Firebase.enableLogging = function(logger, persistent) {
+ fb.core.util.assert(!persistent || (logger === true || logger === false), "Can't turn on custom loggers persistently.");
+ if (logger === true) {
+ if (typeof console !== "undefined") {
+ if (typeof console.log === "function") {
+ fb.core.util.logger = goog.bind(console.log, console);
+ } else {
+ if (typeof console.log === "object") {
+ fb.core.util.logger = function(message) {
+ console.log(message);
+ };
+ }
+ }
+ }
+ if (persistent) {
+ fb.core.storage.SessionStorage.set("logging_enabled", true);
+ }
+ } else {
+ if (logger) {
+ fb.core.util.logger = logger;
+ } else {
+ fb.core.util.logger = null;
+ fb.core.storage.SessionStorage.remove("logging_enabled");
+ }
+ }
+};
+Firebase.ServerValue = {"TIMESTAMP":{".sv":"timestamp"}};
+Firebase.SDK_VERSION = CLIENT_VERSION;
+Firebase.INTERNAL = fb.api.INTERNAL;
+Firebase.Context = fb.core.RepoManager;
+Firebase.TEST_ACCESS = fb.api.TEST_ACCESS;
+
+ }
+ ns.wrapper(ns.goog, ns.fb);
+}({goog:{}, fb:{}}));
+Firebase.SDK_VERSION = '2.2.7';
+
diff --git a/polymer_1.0.4/bower_components/firebase/firebase.js b/polymer_1.0.4/bower_components/firebase/firebase.js
new file mode 100644
index 0000000..bfbf35b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/firebase/firebase.js
@@ -0,0 +1,263 @@
+/*! @license Firebase v2.2.7
+ License: https://www.firebase.com/terms/terms-of-service.html */
+(function() {var h,aa=this;function n(a){return void 0!==a}function ba(){}function ca(a){a.ub=function(){return a.tf?a.tf:a.tf=new a}}
+function da(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
+else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function ea(a){return"array"==da(a)}function fa(a){var b=da(a);return"array"==b||"object"==b&&"number"==typeof a.length}function p(a){return"string"==typeof a}function ga(a){return"number"==typeof a}function ha(a){return"function"==da(a)}function ia(a){var b=typeof a;return"object"==b&&null!=a||"function"==b}function ja(a,b,c){return a.call.apply(a.bind,arguments)}
+function ka(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}}function q(a,b,c){q=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?ja:ka;return q.apply(null,arguments)}var la=Date.now||function(){return+new Date};
+function ma(a,b){function c(){}c.prototype=b.prototype;a.Zg=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.Vg=function(a,c,f){for(var g=Array(arguments.length-2),k=2;k<arguments.length;k++)g[k-2]=arguments[k];return b.prototype[c].apply(a,g)}};function r(a,b){for(var c in a)b.call(void 0,a[c],c,a)}function na(a,b){var c={},d;for(d in a)c[d]=b.call(void 0,a[d],d,a);return c}function oa(a,b){for(var c in a)if(!b.call(void 0,a[c],c,a))return!1;return!0}function pa(a){var b=0,c;for(c in a)b++;return b}function qa(a){for(var b in a)return b}function ra(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b}function sa(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b}function ta(a,b){for(var c in a)if(a[c]==b)return!0;return!1}
+function ua(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d}function va(a,b){var c=ua(a,b,void 0);return c&&a[c]}function wa(a){for(var b in a)return!1;return!0}function xa(a){var b={},c;for(c in a)b[c]=a[c];return b}var ya="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" ");
+function za(a,b){for(var c,d,e=1;e<arguments.length;e++){d=arguments[e];for(c in d)a[c]=d[c];for(var f=0;f<ya.length;f++)c=ya[f],Object.prototype.hasOwnProperty.call(d,c)&&(a[c]=d[c])}};function Aa(a){a=String(a);if(/^\s*$/.test(a)?0:/^[\],:{}\s\u2028\u2029]*$/.test(a.replace(/\\["\\\/bfnrtu]/g,"@").replace(/"[^"\\\n\r\u2028\u2029\x00-\x08\x0a-\x1f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g,"")))try{return eval("("+a+")")}catch(b){}throw Error("Invalid JSON string: "+a);}function Ba(){this.Pd=void 0}
+function Ca(a,b,c){switch(typeof b){case "string":Da(b,c);break;case "number":c.push(isFinite(b)&&!isNaN(b)?b:"null");break;case "boolean":c.push(b);break;case "undefined":c.push("null");break;case "object":if(null==b){c.push("null");break}if(ea(b)){var d=b.length;c.push("[");for(var e="",f=0;f<d;f++)c.push(e),e=b[f],Ca(a,a.Pd?a.Pd.call(b,String(f),e):e,c),e=",";c.push("]");break}c.push("{");d="";for(f in b)Object.prototype.hasOwnProperty.call(b,f)&&(e=b[f],"function"!=typeof e&&(c.push(d),Da(f,c),
+c.push(":"),Ca(a,a.Pd?a.Pd.call(b,f,e):e,c),d=","));c.push("}");break;case "function":break;default:throw Error("Unknown type: "+typeof b);}}var Ea={'"':'\\"',"\\":"\\\\","/":"\\/","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\x0B":"\\u000b"},Fa=/\uffff/.test("\uffff")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g;
+function Da(a,b){b.push('"',a.replace(Fa,function(a){if(a in Ea)return Ea[a];var b=a.charCodeAt(0),e="\\u";16>b?e+="000":256>b?e+="00":4096>b&&(e+="0");return Ea[a]=e+b.toString(16)}),'"')};function Ga(){return Math.floor(2147483648*Math.random()).toString(36)+Math.abs(Math.floor(2147483648*Math.random())^la()).toString(36)};var Ha;a:{var Ia=aa.navigator;if(Ia){var Ja=Ia.userAgent;if(Ja){Ha=Ja;break a}}Ha=""};function Ka(){this.Wa=-1};function La(){this.Wa=-1;this.Wa=64;this.R=[];this.le=[];this.Tf=[];this.Id=[];this.Id[0]=128;for(var a=1;a<this.Wa;++a)this.Id[a]=0;this.be=this.$b=0;this.reset()}ma(La,Ka);La.prototype.reset=function(){this.R[0]=1732584193;this.R[1]=4023233417;this.R[2]=2562383102;this.R[3]=271733878;this.R[4]=3285377520;this.be=this.$b=0};
+function Ma(a,b,c){c||(c=0);var d=a.Tf;if(p(b))for(var e=0;16>e;e++)d[e]=b.charCodeAt(c)<<24|b.charCodeAt(c+1)<<16|b.charCodeAt(c+2)<<8|b.charCodeAt(c+3),c+=4;else for(e=0;16>e;e++)d[e]=b[c]<<24|b[c+1]<<16|b[c+2]<<8|b[c+3],c+=4;for(e=16;80>e;e++){var f=d[e-3]^d[e-8]^d[e-14]^d[e-16];d[e]=(f<<1|f>>>31)&4294967295}b=a.R[0];c=a.R[1];for(var g=a.R[2],k=a.R[3],l=a.R[4],m,e=0;80>e;e++)40>e?20>e?(f=k^c&(g^k),m=1518500249):(f=c^g^k,m=1859775393):60>e?(f=c&g|k&(c|g),m=2400959708):(f=c^g^k,m=3395469782),f=(b<<
+5|b>>>27)+f+l+m+d[e]&4294967295,l=k,k=g,g=(c<<30|c>>>2)&4294967295,c=b,b=f;a.R[0]=a.R[0]+b&4294967295;a.R[1]=a.R[1]+c&4294967295;a.R[2]=a.R[2]+g&4294967295;a.R[3]=a.R[3]+k&4294967295;a.R[4]=a.R[4]+l&4294967295}
+La.prototype.update=function(a,b){if(null!=a){n(b)||(b=a.length);for(var c=b-this.Wa,d=0,e=this.le,f=this.$b;d<b;){if(0==f)for(;d<=c;)Ma(this,a,d),d+=this.Wa;if(p(a))for(;d<b;){if(e[f]=a.charCodeAt(d),++f,++d,f==this.Wa){Ma(this,e);f=0;break}}else for(;d<b;)if(e[f]=a[d],++f,++d,f==this.Wa){Ma(this,e);f=0;break}}this.$b=f;this.be+=b}};var t=Array.prototype,Na=t.indexOf?function(a,b,c){return t.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(p(a))return p(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},Oa=t.forEach?function(a,b,c){t.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=p(a)?a.split(""):a,f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)},Pa=t.filter?function(a,b,c){return t.filter.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=[],f=0,g=p(a)?
+a.split(""):a,k=0;k<d;k++)if(k in g){var l=g[k];b.call(c,l,k,a)&&(e[f++]=l)}return e},Qa=t.map?function(a,b,c){return t.map.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=Array(d),f=p(a)?a.split(""):a,g=0;g<d;g++)g in f&&(e[g]=b.call(c,f[g],g,a));return e},Ra=t.reduce?function(a,b,c,d){for(var e=[],f=1,g=arguments.length;f<g;f++)e.push(arguments[f]);d&&(e[0]=q(b,d));return t.reduce.apply(a,e)}:function(a,b,c,d){var e=c;Oa(a,function(c,g){e=b.call(d,e,c,g,a)});return e},Sa=t.every?function(a,b,
+c){return t.every.call(a,b,c)}:function(a,b,c){for(var d=a.length,e=p(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&!b.call(c,e[f],f,a))return!1;return!0};function Ta(a,b){var c=Ua(a,b,void 0);return 0>c?null:p(a)?a.charAt(c):a[c]}function Ua(a,b,c){for(var d=a.length,e=p(a)?a.split(""):a,f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return f;return-1}function Va(a,b){var c=Na(a,b);0<=c&&t.splice.call(a,c,1)}function Wa(a,b,c){return 2>=arguments.length?t.slice.call(a,b):t.slice.call(a,b,c)}
+function Xa(a,b){a.sort(b||Ya)}function Ya(a,b){return a>b?1:a<b?-1:0};var Za=-1!=Ha.indexOf("Opera")||-1!=Ha.indexOf("OPR"),$a=-1!=Ha.indexOf("Trident")||-1!=Ha.indexOf("MSIE"),ab=-1!=Ha.indexOf("Gecko")&&-1==Ha.toLowerCase().indexOf("webkit")&&!(-1!=Ha.indexOf("Trident")||-1!=Ha.indexOf("MSIE")),bb=-1!=Ha.toLowerCase().indexOf("webkit");
+(function(){var a="",b;if(Za&&aa.opera)return a=aa.opera.version,ha(a)?a():a;ab?b=/rv\:([^\);]+)(\)|;)/:$a?b=/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/:bb&&(b=/WebKit\/(\S+)/);b&&(a=(a=b.exec(Ha))?a[1]:"");return $a&&(b=(b=aa.document)?b.documentMode:void 0,b>parseFloat(a))?String(b):a})();var cb=null,db=null,eb=null;function fb(a,b){if(!fa(a))throw Error("encodeByteArray takes an array as a parameter");gb();for(var c=b?db:cb,d=[],e=0;e<a.length;e+=3){var f=a[e],g=e+1<a.length,k=g?a[e+1]:0,l=e+2<a.length,m=l?a[e+2]:0,v=f>>2,f=(f&3)<<4|k>>4,k=(k&15)<<2|m>>6,m=m&63;l||(m=64,g||(k=64));d.push(c[v],c[f],c[k],c[m])}return d.join("")}
+function gb(){if(!cb){cb={};db={};eb={};for(var a=0;65>a;a++)cb[a]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a),db[a]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.".charAt(a),eb[db[a]]=a,62<=a&&(eb["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a)]=a)}};function u(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function w(a,b){if(Object.prototype.hasOwnProperty.call(a,b))return a[b]}function hb(a,b){for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&b(c,a[c])}function ib(a){var b={};hb(a,function(a,d){b[a]=d});return b};function jb(a){var b=[];hb(a,function(a,d){ea(d)?Oa(d,function(d){b.push(encodeURIComponent(a)+"="+encodeURIComponent(d))}):b.push(encodeURIComponent(a)+"="+encodeURIComponent(d))});return b.length?"&"+b.join("&"):""}function kb(a){var b={};a=a.replace(/^\?/,"").split("&");Oa(a,function(a){a&&(a=a.split("="),b[a[0]]=a[1])});return b};function x(a,b,c,d){var e;d<b?e="at least "+b:d>c&&(e=0===c?"none":"no more than "+c);if(e)throw Error(a+" failed: Was called with "+d+(1===d?" argument.":" arguments.")+" Expects "+e+".");}function z(a,b,c){var d="";switch(b){case 1:d=c?"first":"First";break;case 2:d=c?"second":"Second";break;case 3:d=c?"third":"Third";break;case 4:d=c?"fourth":"Fourth";break;default:throw Error("errorPrefix called with argumentNumber > 4. Need to update it?");}return a=a+" failed: "+(d+" argument ")}
+function A(a,b,c,d){if((!d||n(c))&&!ha(c))throw Error(z(a,b,d)+"must be a valid function.");}function lb(a,b,c){if(n(c)&&(!ia(c)||null===c))throw Error(z(a,b,!0)+"must be a valid context object.");};function mb(a){return"undefined"!==typeof JSON&&n(JSON.parse)?JSON.parse(a):Aa(a)}function B(a){if("undefined"!==typeof JSON&&n(JSON.stringify))a=JSON.stringify(a);else{var b=[];Ca(new Ba,a,b);a=b.join("")}return a};function nb(){this.Sd=C}nb.prototype.j=function(a){return this.Sd.oa(a)};nb.prototype.toString=function(){return this.Sd.toString()};function ob(){}ob.prototype.pf=function(){return null};ob.prototype.xe=function(){return null};var pb=new ob;function qb(a,b,c){this.Qf=a;this.Ka=b;this.Hd=c}qb.prototype.pf=function(a){var b=this.Ka.D;if(rb(b,a))return b.j().M(a);b=null!=this.Hd?new sb(this.Hd,!0,!1):this.Ka.u();return this.Qf.Xa(a,b)};qb.prototype.xe=function(a,b,c){var d=null!=this.Hd?this.Hd:tb(this.Ka);a=this.Qf.me(d,b,1,c,a);return 0===a.length?null:a[0]};function ub(){this.tb=[]}function vb(a,b){for(var c=null,d=0;d<b.length;d++){var e=b[d],f=e.Yb();null===c||f.Z(c.Yb())||(a.tb.push(c),c=null);null===c&&(c=new wb(f));c.add(e)}c&&a.tb.push(c)}function xb(a,b,c){vb(a,c);yb(a,function(a){return a.Z(b)})}function zb(a,b,c){vb(a,c);yb(a,function(a){return a.contains(b)||b.contains(a)})}
+function yb(a,b){for(var c=!0,d=0;d<a.tb.length;d++){var e=a.tb[d];if(e)if(e=e.Yb(),b(e)){for(var e=a.tb[d],f=0;f<e.sd.length;f++){var g=e.sd[f];if(null!==g){e.sd[f]=null;var k=g.Ub();Ab&&Bb("event: "+g.toString());Cb(k)}}a.tb[d]=null}else c=!1}c&&(a.tb=[])}function wb(a){this.qa=a;this.sd=[]}wb.prototype.add=function(a){this.sd.push(a)};wb.prototype.Yb=function(){return this.qa};function D(a,b,c,d){this.type=a;this.Ja=b;this.Ya=c;this.Je=d;this.Nd=void 0}function Db(a){return new D(Eb,a)}var Eb="value";function Fb(a,b,c,d){this.te=b;this.Wd=c;this.Nd=d;this.rd=a}Fb.prototype.Yb=function(){var a=this.Wd.lc();return"value"===this.rd?a.path:a.parent().path};Fb.prototype.ye=function(){return this.rd};Fb.prototype.Ub=function(){return this.te.Ub(this)};Fb.prototype.toString=function(){return this.Yb().toString()+":"+this.rd+":"+B(this.Wd.lf())};function Gb(a,b,c){this.te=a;this.error=b;this.path=c}Gb.prototype.Yb=function(){return this.path};Gb.prototype.ye=function(){return"cancel"};
+Gb.prototype.Ub=function(){return this.te.Ub(this)};Gb.prototype.toString=function(){return this.path.toString()+":cancel"};function sb(a,b,c){this.B=a;this.$=b;this.Tb=c}function Hb(a){return a.$}function rb(a,b){return a.$&&!a.Tb||a.B.Ha(b)}sb.prototype.j=function(){return this.B};function Ib(a){this.dg=a;this.Ad=null}Ib.prototype.get=function(){var a=this.dg.get(),b=xa(a);if(this.Ad)for(var c in this.Ad)b[c]-=this.Ad[c];this.Ad=a;return b};function Jb(a,b){this.Mf={};this.Yd=new Ib(a);this.ca=b;var c=1E4+2E4*Math.random();setTimeout(q(this.Hf,this),Math.floor(c))}Jb.prototype.Hf=function(){var a=this.Yd.get(),b={},c=!1,d;for(d in a)0<a[d]&&u(this.Mf,d)&&(b[d]=a[d],c=!0);c&&this.ca.Te(b);setTimeout(q(this.Hf,this),Math.floor(6E5*Math.random()))};function Kb(){this.Dc={}}function Lb(a,b,c){n(c)||(c=1);u(a.Dc,b)||(a.Dc[b]=0);a.Dc[b]+=c}Kb.prototype.get=function(){return xa(this.Dc)};var Mb={},Nb={};function Ob(a){a=a.toString();Mb[a]||(Mb[a]=new Kb);return Mb[a]}function Pb(a,b){var c=a.toString();Nb[c]||(Nb[c]=b());return Nb[c]};function E(a,b){this.name=a;this.S=b}function Qb(a,b){return new E(a,b)};function Rb(a,b){return Sb(a.name,b.name)}function Tb(a,b){return Sb(a,b)};function Ub(a,b,c){this.type=Vb;this.source=a;this.path=b;this.Ia=c}Ub.prototype.Wc=function(a){return this.path.e()?new Ub(this.source,F,this.Ia.M(a)):new Ub(this.source,G(this.path),this.Ia)};Ub.prototype.toString=function(){return"Operation("+this.path+": "+this.source.toString()+" overwrite: "+this.Ia.toString()+")"};function Wb(a,b){this.type=Xb;this.source=Yb;this.path=a;this.Ve=b}Wb.prototype.Wc=function(){return this.path.e()?this:new Wb(G(this.path),this.Ve)};Wb.prototype.toString=function(){return"Operation("+this.path+": "+this.source.toString()+" ack write revert="+this.Ve+")"};function Zb(a,b){this.type=$b;this.source=a;this.path=b}Zb.prototype.Wc=function(){return this.path.e()?new Zb(this.source,F):new Zb(this.source,G(this.path))};Zb.prototype.toString=function(){return"Operation("+this.path+": "+this.source.toString()+" listen_complete)"};function ac(a,b){this.La=a;this.xa=b?b:bc}h=ac.prototype;h.Na=function(a,b){return new ac(this.La,this.xa.Na(a,b,this.La).X(null,null,!1,null,null))};h.remove=function(a){return new ac(this.La,this.xa.remove(a,this.La).X(null,null,!1,null,null))};h.get=function(a){for(var b,c=this.xa;!c.e();){b=this.La(a,c.key);if(0===b)return c.value;0>b?c=c.left:0<b&&(c=c.right)}return null};
+function cc(a,b){for(var c,d=a.xa,e=null;!d.e();){c=a.La(b,d.key);if(0===c){if(d.left.e())return e?e.key:null;for(d=d.left;!d.right.e();)d=d.right;return d.key}0>c?d=d.left:0<c&&(e=d,d=d.right)}throw Error("Attempted to find predecessor key for a nonexistent key. What gives?");}h.e=function(){return this.xa.e()};h.count=function(){return this.xa.count()};h.Rc=function(){return this.xa.Rc()};h.ec=function(){return this.xa.ec()};h.ha=function(a){return this.xa.ha(a)};
+h.Wb=function(a){return new dc(this.xa,null,this.La,!1,a)};h.Xb=function(a,b){return new dc(this.xa,a,this.La,!1,b)};h.Zb=function(a,b){return new dc(this.xa,a,this.La,!0,b)};h.rf=function(a){return new dc(this.xa,null,this.La,!0,a)};function dc(a,b,c,d,e){this.Rd=e||null;this.Ee=d;this.Pa=[];for(e=1;!a.e();)if(e=b?c(a.key,b):1,d&&(e*=-1),0>e)a=this.Ee?a.left:a.right;else if(0===e){this.Pa.push(a);break}else this.Pa.push(a),a=this.Ee?a.right:a.left}
+function H(a){if(0===a.Pa.length)return null;var b=a.Pa.pop(),c;c=a.Rd?a.Rd(b.key,b.value):{key:b.key,value:b.value};if(a.Ee)for(b=b.left;!b.e();)a.Pa.push(b),b=b.right;else for(b=b.right;!b.e();)a.Pa.push(b),b=b.left;return c}function ec(a){if(0===a.Pa.length)return null;var b;b=a.Pa;b=b[b.length-1];return a.Rd?a.Rd(b.key,b.value):{key:b.key,value:b.value}}function fc(a,b,c,d,e){this.key=a;this.value=b;this.color=null!=c?c:!0;this.left=null!=d?d:bc;this.right=null!=e?e:bc}h=fc.prototype;
+h.X=function(a,b,c,d,e){return new fc(null!=a?a:this.key,null!=b?b:this.value,null!=c?c:this.color,null!=d?d:this.left,null!=e?e:this.right)};h.count=function(){return this.left.count()+1+this.right.count()};h.e=function(){return!1};h.ha=function(a){return this.left.ha(a)||a(this.key,this.value)||this.right.ha(a)};function gc(a){return a.left.e()?a:gc(a.left)}h.Rc=function(){return gc(this).key};h.ec=function(){return this.right.e()?this.key:this.right.ec()};
+h.Na=function(a,b,c){var d,e;e=this;d=c(a,e.key);e=0>d?e.X(null,null,null,e.left.Na(a,b,c),null):0===d?e.X(null,b,null,null,null):e.X(null,null,null,null,e.right.Na(a,b,c));return hc(e)};function ic(a){if(a.left.e())return bc;a.left.fa()||a.left.left.fa()||(a=jc(a));a=a.X(null,null,null,ic(a.left),null);return hc(a)}
+h.remove=function(a,b){var c,d;c=this;if(0>b(a,c.key))c.left.e()||c.left.fa()||c.left.left.fa()||(c=jc(c)),c=c.X(null,null,null,c.left.remove(a,b),null);else{c.left.fa()&&(c=kc(c));c.right.e()||c.right.fa()||c.right.left.fa()||(c=lc(c),c.left.left.fa()&&(c=kc(c),c=lc(c)));if(0===b(a,c.key)){if(c.right.e())return bc;d=gc(c.right);c=c.X(d.key,d.value,null,null,ic(c.right))}c=c.X(null,null,null,null,c.right.remove(a,b))}return hc(c)};h.fa=function(){return this.color};
+function hc(a){a.right.fa()&&!a.left.fa()&&(a=mc(a));a.left.fa()&&a.left.left.fa()&&(a=kc(a));a.left.fa()&&a.right.fa()&&(a=lc(a));return a}function jc(a){a=lc(a);a.right.left.fa()&&(a=a.X(null,null,null,null,kc(a.right)),a=mc(a),a=lc(a));return a}function mc(a){return a.right.X(null,null,a.color,a.X(null,null,!0,null,a.right.left),null)}function kc(a){return a.left.X(null,null,a.color,null,a.X(null,null,!0,a.left.right,null))}
+function lc(a){return a.X(null,null,!a.color,a.left.X(null,null,!a.left.color,null,null),a.right.X(null,null,!a.right.color,null,null))}function nc(){}h=nc.prototype;h.X=function(){return this};h.Na=function(a,b){return new fc(a,b,null)};h.remove=function(){return this};h.count=function(){return 0};h.e=function(){return!0};h.ha=function(){return!1};h.Rc=function(){return null};h.ec=function(){return null};h.fa=function(){return!1};var bc=new nc;function oc(a,b){return a&&"object"===typeof a?(J(".sv"in a,"Unexpected leaf node or priority contents"),b[a[".sv"]]):a}function pc(a,b){var c=new qc;rc(a,new K(""),function(a,e){c.mc(a,sc(e,b))});return c}function sc(a,b){var c=a.A().K(),c=oc(c,b),d;if(a.N()){var e=oc(a.Ba(),b);return e!==a.Ba()||c!==a.A().K()?new tc(e,L(c)):a}d=a;c!==a.A().K()&&(d=d.da(new tc(c)));a.U(M,function(a,c){var e=sc(c,b);e!==c&&(d=d.Q(a,e))});return d};function K(a,b){if(1==arguments.length){this.n=a.split("/");for(var c=0,d=0;d<this.n.length;d++)0<this.n[d].length&&(this.n[c]=this.n[d],c++);this.n.length=c;this.Y=0}else this.n=a,this.Y=b}function N(a,b){var c=O(a);if(null===c)return b;if(c===O(b))return N(G(a),G(b));throw Error("INTERNAL ERROR: innerPath ("+b+") is not within outerPath ("+a+")");}function O(a){return a.Y>=a.n.length?null:a.n[a.Y]}function uc(a){return a.n.length-a.Y}
+function G(a){var b=a.Y;b<a.n.length&&b++;return new K(a.n,b)}function vc(a){return a.Y<a.n.length?a.n[a.n.length-1]:null}h=K.prototype;h.toString=function(){for(var a="",b=this.Y;b<this.n.length;b++)""!==this.n[b]&&(a+="/"+this.n[b]);return a||"/"};h.slice=function(a){return this.n.slice(this.Y+(a||0))};h.parent=function(){if(this.Y>=this.n.length)return null;for(var a=[],b=this.Y;b<this.n.length-1;b++)a.push(this.n[b]);return new K(a,0)};
+h.w=function(a){for(var b=[],c=this.Y;c<this.n.length;c++)b.push(this.n[c]);if(a instanceof K)for(c=a.Y;c<a.n.length;c++)b.push(a.n[c]);else for(a=a.split("/"),c=0;c<a.length;c++)0<a[c].length&&b.push(a[c]);return new K(b,0)};h.e=function(){return this.Y>=this.n.length};h.Z=function(a){if(uc(this)!==uc(a))return!1;for(var b=this.Y,c=a.Y;b<=this.n.length;b++,c++)if(this.n[b]!==a.n[c])return!1;return!0};
+h.contains=function(a){var b=this.Y,c=a.Y;if(uc(this)>uc(a))return!1;for(;b<this.n.length;){if(this.n[b]!==a.n[c])return!1;++b;++c}return!0};var F=new K("");function wc(a,b){this.Qa=a.slice();this.Ea=Math.max(1,this.Qa.length);this.kf=b;for(var c=0;c<this.Qa.length;c++)this.Ea+=xc(this.Qa[c]);yc(this)}wc.prototype.push=function(a){0<this.Qa.length&&(this.Ea+=1);this.Qa.push(a);this.Ea+=xc(a);yc(this)};wc.prototype.pop=function(){var a=this.Qa.pop();this.Ea-=xc(a);0<this.Qa.length&&--this.Ea};
+function yc(a){if(768<a.Ea)throw Error(a.kf+"has a key path longer than 768 bytes ("+a.Ea+").");if(32<a.Qa.length)throw Error(a.kf+"path specified exceeds the maximum depth that can be written (32) or object contains a cycle "+zc(a));}function zc(a){return 0==a.Qa.length?"":"in property '"+a.Qa.join(".")+"'"};function Ac(){this.wc={}}Ac.prototype.set=function(a,b){null==b?delete this.wc[a]:this.wc[a]=b};Ac.prototype.get=function(a){return u(this.wc,a)?this.wc[a]:null};Ac.prototype.remove=function(a){delete this.wc[a]};Ac.prototype.uf=!0;function Bc(a){this.Ec=a;this.Md="firebase:"}h=Bc.prototype;h.set=function(a,b){null==b?this.Ec.removeItem(this.Md+a):this.Ec.setItem(this.Md+a,B(b))};h.get=function(a){a=this.Ec.getItem(this.Md+a);return null==a?null:mb(a)};h.remove=function(a){this.Ec.removeItem(this.Md+a)};h.uf=!1;h.toString=function(){return this.Ec.toString()};function Cc(a){try{if("undefined"!==typeof window&&"undefined"!==typeof window[a]){var b=window[a];b.setItem("firebase:sentinel","cache");b.removeItem("firebase:sentinel");return new Bc(b)}}catch(c){}return new Ac}var Dc=Cc("localStorage"),P=Cc("sessionStorage");function Ec(a,b,c,d,e){this.host=a.toLowerCase();this.domain=this.host.substr(this.host.indexOf(".")+1);this.lb=b;this.Cb=c;this.Tg=d;this.Ld=e||"";this.Oa=Dc.get("host:"+a)||this.host}function Fc(a,b){b!==a.Oa&&(a.Oa=b,"s-"===a.Oa.substr(0,2)&&Dc.set("host:"+a.host,a.Oa))}Ec.prototype.toString=function(){var a=(this.lb?"https://":"http://")+this.host;this.Ld&&(a+="<"+this.Ld+">");return a};var Gc=function(){var a=1;return function(){return a++}}();function J(a,b){if(!a)throw Hc(b);}function Hc(a){return Error("Firebase (2.2.7) INTERNAL ASSERT FAILED: "+a)}
+function Ic(a){try{var b;if("undefined"!==typeof atob)b=atob(a);else{gb();for(var c=eb,d=[],e=0;e<a.length;){var f=c[a.charAt(e++)],g=e<a.length?c[a.charAt(e)]:0;++e;var k=e<a.length?c[a.charAt(e)]:64;++e;var l=e<a.length?c[a.charAt(e)]:64;++e;if(null==f||null==g||null==k||null==l)throw Error();d.push(f<<2|g>>4);64!=k&&(d.push(g<<4&240|k>>2),64!=l&&d.push(k<<6&192|l))}if(8192>d.length)b=String.fromCharCode.apply(null,d);else{a="";for(c=0;c<d.length;c+=8192)a+=String.fromCharCode.apply(null,Wa(d,c,
+c+8192));b=a}}return b}catch(m){Bb("base64Decode failed: ",m)}return null}function Jc(a){var b=Kc(a);a=new La;a.update(b);var b=[],c=8*a.be;56>a.$b?a.update(a.Id,56-a.$b):a.update(a.Id,a.Wa-(a.$b-56));for(var d=a.Wa-1;56<=d;d--)a.le[d]=c&255,c/=256;Ma(a,a.le);for(d=c=0;5>d;d++)for(var e=24;0<=e;e-=8)b[c]=a.R[d]>>e&255,++c;return fb(b)}
+function Lc(a){for(var b="",c=0;c<arguments.length;c++)b=fa(arguments[c])?b+Lc.apply(null,arguments[c]):"object"===typeof arguments[c]?b+B(arguments[c]):b+arguments[c],b+=" ";return b}var Ab=null,Mc=!0;function Bb(a){!0===Mc&&(Mc=!1,null===Ab&&!0===P.get("logging_enabled")&&Nc(!0));if(Ab){var b=Lc.apply(null,arguments);Ab(b)}}function Oc(a){return function(){Bb(a,arguments)}}
+function Pc(a){if("undefined"!==typeof console){var b="FIREBASE INTERNAL ERROR: "+Lc.apply(null,arguments);"undefined"!==typeof console.error?console.error(b):console.log(b)}}function Qc(a){var b=Lc.apply(null,arguments);throw Error("FIREBASE FATAL ERROR: "+b);}function Q(a){if("undefined"!==typeof console){var b="FIREBASE WARNING: "+Lc.apply(null,arguments);"undefined"!==typeof console.warn?console.warn(b):console.log(b)}}
+function Rc(a){var b="",c="",d="",e="",f=!0,g="https",k=443;if(p(a)){var l=a.indexOf("//");0<=l&&(g=a.substring(0,l-1),a=a.substring(l+2));l=a.indexOf("/");-1===l&&(l=a.length);b=a.substring(0,l);e="";a=a.substring(l).split("/");for(l=0;l<a.length;l++)if(0<a[l].length){var m=a[l];try{m=decodeURIComponent(m.replace(/\+/g," "))}catch(v){}e+="/"+m}a=b.split(".");3===a.length?(c=a[1],d=a[0].toLowerCase()):2===a.length&&(c=a[0]);l=b.indexOf(":");0<=l&&(f="https"===g||"wss"===g,k=b.substring(l+1),isFinite(k)&&
+(k=String(k)),k=p(k)?/^\s*-?0x/i.test(k)?parseInt(k,16):parseInt(k,10):NaN)}return{host:b,port:k,domain:c,Qg:d,lb:f,scheme:g,Zc:e}}function Sc(a){return ga(a)&&(a!=a||a==Number.POSITIVE_INFINITY||a==Number.NEGATIVE_INFINITY)}
+function Tc(a){if("complete"===document.readyState)a();else{var b=!1,c=function(){document.body?b||(b=!0,a()):setTimeout(c,Math.floor(10))};document.addEventListener?(document.addEventListener("DOMContentLoaded",c,!1),window.addEventListener("load",c,!1)):document.attachEvent&&(document.attachEvent("onreadystatechange",function(){"complete"===document.readyState&&c()}),window.attachEvent("onload",c))}}
+function Sb(a,b){if(a===b)return 0;if("[MIN_NAME]"===a||"[MAX_NAME]"===b)return-1;if("[MIN_NAME]"===b||"[MAX_NAME]"===a)return 1;var c=Uc(a),d=Uc(b);return null!==c?null!==d?0==c-d?a.length-b.length:c-d:-1:null!==d?1:a<b?-1:1}function Vc(a,b){if(b&&a in b)return b[a];throw Error("Missing required key ("+a+") in object: "+B(b));}
+function Wc(a){if("object"!==typeof a||null===a)return B(a);var b=[],c;for(c in a)b.push(c);b.sort();c="{";for(var d=0;d<b.length;d++)0!==d&&(c+=","),c+=B(b[d]),c+=":",c+=Wc(a[b[d]]);return c+"}"}function Xc(a,b){if(a.length<=b)return[a];for(var c=[],d=0;d<a.length;d+=b)d+b>a?c.push(a.substring(d,a.length)):c.push(a.substring(d,d+b));return c}function Yc(a,b){if(ea(a))for(var c=0;c<a.length;++c)b(c,a[c]);else r(a,b)}
+function Zc(a){J(!Sc(a),"Invalid JSON number");var b,c,d,e;0===a?(d=c=0,b=-Infinity===1/a?1:0):(b=0>a,a=Math.abs(a),a>=Math.pow(2,-1022)?(d=Math.min(Math.floor(Math.log(a)/Math.LN2),1023),c=d+1023,d=Math.round(a*Math.pow(2,52-d)-Math.pow(2,52))):(c=0,d=Math.round(a/Math.pow(2,-1074))));e=[];for(a=52;a;--a)e.push(d%2?1:0),d=Math.floor(d/2);for(a=11;a;--a)e.push(c%2?1:0),c=Math.floor(c/2);e.push(b?1:0);e.reverse();b=e.join("");c="";for(a=0;64>a;a+=8)d=parseInt(b.substr(a,8),2).toString(16),1===d.length&&
+(d="0"+d),c+=d;return c.toLowerCase()}var $c=/^-?\d{1,10}$/;function Uc(a){return $c.test(a)&&(a=Number(a),-2147483648<=a&&2147483647>=a)?a:null}function Cb(a){try{a()}catch(b){setTimeout(function(){Q("Exception was thrown by user callback.",b.stack||"");throw b;},Math.floor(0))}}function R(a,b){if(ha(a)){var c=Array.prototype.slice.call(arguments,1).slice();Cb(function(){a.apply(null,c)})}};function Kc(a){for(var b=[],c=0,d=0;d<a.length;d++){var e=a.charCodeAt(d);55296<=e&&56319>=e&&(e-=55296,d++,J(d<a.length,"Surrogate pair missing trail surrogate."),e=65536+(e<<10)+(a.charCodeAt(d)-56320));128>e?b[c++]=e:(2048>e?b[c++]=e>>6|192:(65536>e?b[c++]=e>>12|224:(b[c++]=e>>18|240,b[c++]=e>>12&63|128),b[c++]=e>>6&63|128),b[c++]=e&63|128)}return b}function xc(a){for(var b=0,c=0;c<a.length;c++){var d=a.charCodeAt(c);128>d?b++:2048>d?b+=2:55296<=d&&56319>=d?(b+=4,c++):b+=3}return b};function ad(a){var b={},c={},d={},e="";try{var f=a.split("."),b=mb(Ic(f[0])||""),c=mb(Ic(f[1])||""),e=f[2],d=c.d||{};delete c.d}catch(g){}return{Wg:b,Ac:c,data:d,Ng:e}}function bd(a){a=ad(a).Ac;return"object"===typeof a&&a.hasOwnProperty("iat")?w(a,"iat"):null}function cd(a){a=ad(a);var b=a.Ac;return!!a.Ng&&!!b&&"object"===typeof b&&b.hasOwnProperty("iat")};function dd(a){this.V=a;this.g=a.o.g}function ed(a,b,c,d){var e=[],f=[];Oa(b,function(b){"child_changed"===b.type&&a.g.xd(b.Je,b.Ja)&&f.push(new D("child_moved",b.Ja,b.Ya))});fd(a,e,"child_removed",b,d,c);fd(a,e,"child_added",b,d,c);fd(a,e,"child_moved",f,d,c);fd(a,e,"child_changed",b,d,c);fd(a,e,Eb,b,d,c);return e}function fd(a,b,c,d,e,f){d=Pa(d,function(a){return a.type===c});Xa(d,q(a.eg,a));Oa(d,function(c){var d=gd(a,c,f);Oa(e,function(e){e.Jf(c.type)&&b.push(e.createEvent(d,a.V))})})}
+function gd(a,b,c){"value"!==b.type&&"child_removed"!==b.type&&(b.Nd=c.qf(b.Ya,b.Ja,a.g));return b}dd.prototype.eg=function(a,b){if(null==a.Ya||null==b.Ya)throw Hc("Should only compare child_ events.");return this.g.compare(new E(a.Ya,a.Ja),new E(b.Ya,b.Ja))};function hd(){this.eb={}}
+function id(a,b){var c=b.type,d=b.Ya;J("child_added"==c||"child_changed"==c||"child_removed"==c,"Only child changes supported for tracking");J(".priority"!==d,"Only non-priority child changes can be tracked.");var e=w(a.eb,d);if(e){var f=e.type;if("child_added"==c&&"child_removed"==f)a.eb[d]=new D("child_changed",b.Ja,d,e.Ja);else if("child_removed"==c&&"child_added"==f)delete a.eb[d];else if("child_removed"==c&&"child_changed"==f)a.eb[d]=new D("child_removed",e.Je,d);else if("child_changed"==c&&
+"child_added"==f)a.eb[d]=new D("child_added",b.Ja,d);else if("child_changed"==c&&"child_changed"==f)a.eb[d]=new D("child_changed",b.Ja,d,e.Je);else throw Hc("Illegal combination of changes: "+b+" occurred after "+e);}else a.eb[d]=b};function jd(a,b,c){this.Pb=a;this.qb=b;this.sb=c||null}h=jd.prototype;h.Jf=function(a){return"value"===a};h.createEvent=function(a,b){var c=b.o.g;return new Fb("value",this,new S(a.Ja,b.lc(),c))};h.Ub=function(a){var b=this.sb;if("cancel"===a.ye()){J(this.qb,"Raising a cancel event on a listener with no cancel callback");var c=this.qb;return function(){c.call(b,a.error)}}var d=this.Pb;return function(){d.call(b,a.Wd)}};h.ff=function(a,b){return this.qb?new Gb(this,a,b):null};
+h.matches=function(a){return a instanceof jd?a.Pb&&this.Pb?a.Pb===this.Pb&&a.sb===this.sb:!0:!1};h.sf=function(){return null!==this.Pb};function kd(a,b,c){this.ga=a;this.qb=b;this.sb=c}h=kd.prototype;h.Jf=function(a){a="children_added"===a?"child_added":a;return("children_removed"===a?"child_removed":a)in this.ga};h.ff=function(a,b){return this.qb?new Gb(this,a,b):null};
+h.createEvent=function(a,b){J(null!=a.Ya,"Child events should have a childName.");var c=b.lc().w(a.Ya);return new Fb(a.type,this,new S(a.Ja,c,b.o.g),a.Nd)};h.Ub=function(a){var b=this.sb;if("cancel"===a.ye()){J(this.qb,"Raising a cancel event on a listener with no cancel callback");var c=this.qb;return function(){c.call(b,a.error)}}var d=this.ga[a.rd];return function(){d.call(b,a.Wd,a.Nd)}};
+h.matches=function(a){if(a instanceof kd){if(!this.ga||!a.ga)return!0;if(this.sb===a.sb){var b=pa(a.ga);if(b===pa(this.ga)){if(1===b){var b=qa(a.ga),c=qa(this.ga);return c===b&&(!a.ga[b]||!this.ga[c]||a.ga[b]===this.ga[c])}return oa(this.ga,function(b,c){return a.ga[c]===b})}}}return!1};h.sf=function(){return null!==this.ga};function ld(a){this.g=a}h=ld.prototype;h.G=function(a,b,c,d,e){J(a.Ic(this.g),"A node must be indexed if only a child is updated");d=a.M(b);if(d.Z(c))return a;null!=e&&(c.e()?a.Ha(b)?id(e,new D("child_removed",d,b)):J(a.N(),"A child remove without an old child only makes sense on a leaf node"):d.e()?id(e,new D("child_added",c,b)):id(e,new D("child_changed",c,b,d)));return a.N()&&c.e()?a:a.Q(b,c).mb(this.g)};
+h.ta=function(a,b,c){null!=c&&(a.N()||a.U(M,function(a,e){b.Ha(a)||id(c,new D("child_removed",e,a))}),b.N()||b.U(M,function(b,e){if(a.Ha(b)){var f=a.M(b);f.Z(e)||id(c,new D("child_changed",e,b,f))}else id(c,new D("child_added",e,b))}));return b.mb(this.g)};h.da=function(a,b){return a.e()?C:a.da(b)};h.Ga=function(){return!1};h.Vb=function(){return this};function md(a){this.Ae=new ld(a.g);this.g=a.g;var b;a.la?(b=nd(a),b=a.g.Oc(od(a),b)):b=a.g.Sc();this.dd=b;a.na?(b=pd(a),a=a.g.Oc(qd(a),b)):a=a.g.Pc();this.Fc=a}h=md.prototype;h.matches=function(a){return 0>=this.g.compare(this.dd,a)&&0>=this.g.compare(a,this.Fc)};h.G=function(a,b,c,d,e){this.matches(new E(b,c))||(c=C);return this.Ae.G(a,b,c,d,e)};h.ta=function(a,b,c){b.N()&&(b=C);var d=b.mb(this.g),d=d.da(C),e=this;b.U(M,function(a,b){e.matches(new E(a,b))||(d=d.Q(a,C))});return this.Ae.ta(a,d,c)};
+h.da=function(a){return a};h.Ga=function(){return!0};h.Vb=function(){return this.Ae};function rd(a){this.ra=new md(a);this.g=a.g;J(a.ia,"Only valid if limit has been set");this.ja=a.ja;this.Jb=!sd(a)}h=rd.prototype;h.G=function(a,b,c,d,e){this.ra.matches(new E(b,c))||(c=C);return a.M(b).Z(c)?a:a.Db()<this.ja?this.ra.Vb().G(a,b,c,d,e):td(this,a,b,c,d,e)};
+h.ta=function(a,b,c){var d;if(b.N()||b.e())d=C.mb(this.g);else if(2*this.ja<b.Db()&&b.Ic(this.g)){d=C.mb(this.g);b=this.Jb?b.Zb(this.ra.Fc,this.g):b.Xb(this.ra.dd,this.g);for(var e=0;0<b.Pa.length&&e<this.ja;){var f=H(b),g;if(g=this.Jb?0>=this.g.compare(this.ra.dd,f):0>=this.g.compare(f,this.ra.Fc))d=d.Q(f.name,f.S),e++;else break}}else{d=b.mb(this.g);d=d.da(C);var k,l,m;if(this.Jb){b=d.rf(this.g);k=this.ra.Fc;l=this.ra.dd;var v=ud(this.g);m=function(a,b){return v(b,a)}}else b=d.Wb(this.g),k=this.ra.dd,
+l=this.ra.Fc,m=ud(this.g);for(var e=0,y=!1;0<b.Pa.length;)f=H(b),!y&&0>=m(k,f)&&(y=!0),(g=y&&e<this.ja&&0>=m(f,l))?e++:d=d.Q(f.name,C)}return this.ra.Vb().ta(a,d,c)};h.da=function(a){return a};h.Ga=function(){return!0};h.Vb=function(){return this.ra.Vb()};
+function td(a,b,c,d,e,f){var g;if(a.Jb){var k=ud(a.g);g=function(a,b){return k(b,a)}}else g=ud(a.g);J(b.Db()==a.ja,"");var l=new E(c,d),m=a.Jb?wd(b,a.g):xd(b,a.g),v=a.ra.matches(l);if(b.Ha(c)){var y=b.M(c),m=e.xe(a.g,m,a.Jb);null!=m&&m.name==c&&(m=e.xe(a.g,m,a.Jb));e=null==m?1:g(m,l);if(v&&!d.e()&&0<=e)return null!=f&&id(f,new D("child_changed",d,c,y)),b.Q(c,d);null!=f&&id(f,new D("child_removed",y,c));b=b.Q(c,C);return null!=m&&a.ra.matches(m)?(null!=f&&id(f,new D("child_added",m.S,m.name)),b.Q(m.name,
+m.S)):b}return d.e()?b:v&&0<=g(m,l)?(null!=f&&(id(f,new D("child_removed",m.S,m.name)),id(f,new D("child_added",d,c))),b.Q(c,d).Q(m.name,C)):b};function yd(a,b){this.he=a;this.cg=b}function zd(a){this.I=a}
+zd.prototype.bb=function(a,b,c,d){var e=new hd,f;if(b.type===Vb)b.source.ve?c=Ad(this,a,b.path,b.Ia,c,d,e):(J(b.source.of,"Unknown source."),f=b.source.af,c=Bd(this,a,b.path,b.Ia,c,d,f,e));else if(b.type===Cd)b.source.ve?c=Dd(this,a,b.path,b.children,c,d,e):(J(b.source.of,"Unknown source."),f=b.source.af,c=Ed(this,a,b.path,b.children,c,d,f,e));else if(b.type===Xb)if(b.Ve)if(f=b.path,null!=c.sc(f))c=a;else{b=new qb(c,a,d);d=a.D.j();if(f.e()||".priority"===O(f))Hb(a.u())?b=c.ua(tb(a)):(b=a.u().j(),
+J(b instanceof T,"serverChildren would be complete if leaf node"),b=c.xc(b)),b=this.I.ta(d,b,e);else{f=O(f);var g=c.Xa(f,a.u());null==g&&rb(a.u(),f)&&(g=d.M(f));b=null!=g?this.I.G(d,f,g,b,e):a.D.j().Ha(f)?this.I.G(d,f,C,b,e):d;b.e()&&Hb(a.u())&&(d=c.ua(tb(a)),d.N()&&(b=this.I.ta(b,d,e)))}d=Hb(a.u())||null!=c.sc(F);c=Fd(a,b,d,this.I.Ga())}else c=Gd(this,a,b.path,c,d,e);else if(b.type===$b)d=b.path,b=a.u(),f=b.j(),g=b.$||d.e(),c=Hd(this,new Id(a.D,new sb(f,g,b.Tb)),d,c,pb,e);else throw Hc("Unknown operation type: "+
+b.type);e=ra(e.eb);d=c;b=d.D;b.$&&(f=b.j().N()||b.j().e(),g=Jd(a),(0<e.length||!a.D.$||f&&!b.j().Z(g)||!b.j().A().Z(g.A()))&&e.push(Db(Jd(d))));return new yd(c,e)};
+function Hd(a,b,c,d,e,f){var g=b.D;if(null!=d.sc(c))return b;var k;if(c.e())J(Hb(b.u()),"If change path is empty, we must have complete server data"),b.u().Tb?(e=tb(b),d=d.xc(e instanceof T?e:C)):d=d.ua(tb(b)),f=a.I.ta(b.D.j(),d,f);else{var l=O(c);if(".priority"==l)J(1==uc(c),"Can't have a priority with additional path components"),f=g.j(),k=b.u().j(),d=d.hd(c,f,k),f=null!=d?a.I.da(f,d):g.j();else{var m=G(c);rb(g,l)?(k=b.u().j(),d=d.hd(c,g.j(),k),d=null!=d?g.j().M(l).G(m,d):g.j().M(l)):d=d.Xa(l,b.u());
+f=null!=d?a.I.G(g.j(),l,d,e,f):g.j()}}return Fd(b,f,g.$||c.e(),a.I.Ga())}function Bd(a,b,c,d,e,f,g,k){var l=b.u();g=g?a.I:a.I.Vb();if(c.e())d=g.ta(l.j(),d,null);else if(g.Ga()&&!l.Tb)d=l.j().G(c,d),d=g.ta(l.j(),d,null);else{var m=O(c);if((c.e()?!l.$||l.Tb:!rb(l,O(c)))&&1<uc(c))return b;d=l.j().M(m).G(G(c),d);d=".priority"==m?g.da(l.j(),d):g.G(l.j(),m,d,pb,null)}l=l.$||c.e();b=new Id(b.D,new sb(d,l,g.Ga()));return Hd(a,b,c,e,new qb(e,b,f),k)}
+function Ad(a,b,c,d,e,f,g){var k=b.D;e=new qb(e,b,f);if(c.e())g=a.I.ta(b.D.j(),d,g),a=Fd(b,g,!0,a.I.Ga());else if(f=O(c),".priority"===f)g=a.I.da(b.D.j(),d),a=Fd(b,g,k.$,k.Tb);else{var l=G(c);c=k.j().M(f);if(!l.e()){var m=e.pf(f);d=null!=m?".priority"===vc(l)&&m.oa(l.parent()).e()?m:m.G(l,d):C}c.Z(d)?a=b:(g=a.I.G(k.j(),f,d,e,g),a=Fd(b,g,k.$,a.I.Ga()))}return a}
+function Dd(a,b,c,d,e,f,g){var k=b;Kd(d,function(d,m){var v=c.w(d);rb(b.D,O(v))&&(k=Ad(a,k,v,m,e,f,g))});Kd(d,function(d,m){var v=c.w(d);rb(b.D,O(v))||(k=Ad(a,k,v,m,e,f,g))});return k}function Ld(a,b){Kd(b,function(b,d){a=a.G(b,d)});return a}
+function Ed(a,b,c,d,e,f,g,k){if(b.u().j().e()&&!Hb(b.u()))return b;var l=b;c=c.e()?d:Md(Nd,c,d);var m=b.u().j();c.children.ha(function(c,d){if(m.Ha(c)){var I=b.u().j().M(c),I=Ld(I,d);l=Bd(a,l,new K(c),I,e,f,g,k)}});c.children.ha(function(c,d){var I=!Hb(b.u())&&null==d.value;m.Ha(c)||I||(I=b.u().j().M(c),I=Ld(I,d),l=Bd(a,l,new K(c),I,e,f,g,k))});return l}
+function Gd(a,b,c,d,e,f){if(null!=d.sc(c))return b;var g=new qb(d,b,e),k=e=b.D.j();if(Hb(b.u())){if(c.e())e=d.ua(tb(b)),k=a.I.ta(b.D.j(),e,f);else if(".priority"===O(c)){var l=d.Xa(O(c),b.u());null==l||e.e()||e.A().Z(l)||(k=a.I.da(e,l))}else l=O(c),e=d.Xa(l,b.u()),null!=e&&(k=a.I.G(b.D.j(),l,e,g,f));e=!0}else if(b.D.$||c.e())k=e,e=b.D.j(),e.N()||e.U(M,function(c){var e=d.Xa(c,b.u());null!=e&&(k=a.I.G(k,c,e,g,f))}),e=b.D.$;else{l=O(c);if(1==uc(c)||rb(b.D,l))c=d.Xa(l,b.u()),null!=c&&(k=a.I.G(e,l,c,
+g,f));e=!1}return Fd(b,k,e,a.I.Ga())};function Od(){}var Pd={};function ud(a){return q(a.compare,a)}Od.prototype.xd=function(a,b){return 0!==this.compare(new E("[MIN_NAME]",a),new E("[MIN_NAME]",b))};Od.prototype.Sc=function(){return Qd};function Rd(a){this.bc=a}ma(Rd,Od);h=Rd.prototype;h.Hc=function(a){return!a.M(this.bc).e()};h.compare=function(a,b){var c=a.S.M(this.bc),d=b.S.M(this.bc),c=c.Cc(d);return 0===c?Sb(a.name,b.name):c};h.Oc=function(a,b){var c=L(a),c=C.Q(this.bc,c);return new E(b,c)};
+h.Pc=function(){var a=C.Q(this.bc,Sd);return new E("[MAX_NAME]",a)};h.toString=function(){return this.bc};function Td(){}ma(Td,Od);h=Td.prototype;h.compare=function(a,b){var c=a.S.A(),d=b.S.A(),c=c.Cc(d);return 0===c?Sb(a.name,b.name):c};h.Hc=function(a){return!a.A().e()};h.xd=function(a,b){return!a.A().Z(b.A())};h.Sc=function(){return Qd};h.Pc=function(){return new E("[MAX_NAME]",new tc("[PRIORITY-POST]",Sd))};h.Oc=function(a,b){var c=L(a);return new E(b,new tc("[PRIORITY-POST]",c))};
+h.toString=function(){return".priority"};var M=new Td;function Ud(){}ma(Ud,Od);h=Ud.prototype;h.compare=function(a,b){return Sb(a.name,b.name)};h.Hc=function(){throw Hc("KeyIndex.isDefinedOn not expected to be called.");};h.xd=function(){return!1};h.Sc=function(){return Qd};h.Pc=function(){return new E("[MAX_NAME]",C)};h.Oc=function(a){J(p(a),"KeyIndex indexValue must always be a string.");return new E(a,C)};h.toString=function(){return".key"};var Vd=new Ud;function Wd(){}ma(Wd,Od);h=Wd.prototype;
+h.compare=function(a,b){var c=a.S.Cc(b.S);return 0===c?Sb(a.name,b.name):c};h.Hc=function(){return!0};h.xd=function(a,b){return!a.Z(b)};h.Sc=function(){return Qd};h.Pc=function(){return Xd};h.Oc=function(a,b){var c=L(a);return new E(b,c)};h.toString=function(){return".value"};var Yd=new Wd;function Zd(){this.Rb=this.na=this.Lb=this.la=this.ia=!1;this.ja=0;this.Nb="";this.dc=null;this.xb="";this.ac=null;this.vb="";this.g=M}var $d=new Zd;function sd(a){return""===a.Nb?a.la:"l"===a.Nb}function od(a){J(a.la,"Only valid if start has been set");return a.dc}function nd(a){J(a.la,"Only valid if start has been set");return a.Lb?a.xb:"[MIN_NAME]"}function qd(a){J(a.na,"Only valid if end has been set");return a.ac}
+function pd(a){J(a.na,"Only valid if end has been set");return a.Rb?a.vb:"[MAX_NAME]"}function ae(a){var b=new Zd;b.ia=a.ia;b.ja=a.ja;b.la=a.la;b.dc=a.dc;b.Lb=a.Lb;b.xb=a.xb;b.na=a.na;b.ac=a.ac;b.Rb=a.Rb;b.vb=a.vb;b.g=a.g;return b}h=Zd.prototype;h.Ge=function(a){var b=ae(this);b.ia=!0;b.ja=a;b.Nb="";return b};h.He=function(a){var b=ae(this);b.ia=!0;b.ja=a;b.Nb="l";return b};h.Ie=function(a){var b=ae(this);b.ia=!0;b.ja=a;b.Nb="r";return b};
+h.Xd=function(a,b){var c=ae(this);c.la=!0;n(a)||(a=null);c.dc=a;null!=b?(c.Lb=!0,c.xb=b):(c.Lb=!1,c.xb="");return c};h.qd=function(a,b){var c=ae(this);c.na=!0;n(a)||(a=null);c.ac=a;n(b)?(c.Rb=!0,c.vb=b):(c.Yg=!1,c.vb="");return c};function be(a,b){var c=ae(a);c.g=b;return c}function ce(a){var b={};a.la&&(b.sp=a.dc,a.Lb&&(b.sn=a.xb));a.na&&(b.ep=a.ac,a.Rb&&(b.en=a.vb));if(a.ia){b.l=a.ja;var c=a.Nb;""===c&&(c=sd(a)?"l":"r");b.vf=c}a.g!==M&&(b.i=a.g.toString());return b}
+function de(a){return!(a.la||a.na||a.ia)}function ee(a){var b={};if(de(a)&&a.g==M)return b;var c;a.g===M?c="$priority":a.g===Yd?c="$value":a.g===Vd?c="$key":(J(a.g instanceof Rd,"Unrecognized index type!"),c=a.g.toString());b.orderBy=B(c);a.la&&(b.startAt=B(a.dc),a.Lb&&(b.startAt+=","+B(a.xb)));a.na&&(b.endAt=B(a.ac),a.Rb&&(b.endAt+=","+B(a.vb)));a.ia&&(sd(a)?b.limitToFirst=a.ja:b.limitToLast=a.ja);return b}h.toString=function(){return B(ce(this))};function fe(a,b){this.yd=a;this.cc=b}fe.prototype.get=function(a){var b=w(this.yd,a);if(!b)throw Error("No index defined for "+a);return b===Pd?null:b};function ge(a,b,c){var d=na(a.yd,function(d,f){var g=w(a.cc,f);J(g,"Missing index implementation for "+f);if(d===Pd){if(g.Hc(b.S)){for(var k=[],l=c.Wb(Qb),m=H(l);m;)m.name!=b.name&&k.push(m),m=H(l);k.push(b);return he(k,ud(g))}return Pd}g=c.get(b.name);k=d;g&&(k=k.remove(new E(b.name,g)));return k.Na(b,b.S)});return new fe(d,a.cc)}
+function ie(a,b,c){var d=na(a.yd,function(a){if(a===Pd)return a;var d=c.get(b.name);return d?a.remove(new E(b.name,d)):a});return new fe(d,a.cc)}var je=new fe({".priority":Pd},{".priority":M});function tc(a,b){this.C=a;J(n(this.C)&&null!==this.C,"LeafNode shouldn't be created with null/undefined value.");this.ba=b||C;ke(this.ba);this.Bb=null}h=tc.prototype;h.N=function(){return!0};h.A=function(){return this.ba};h.da=function(a){return new tc(this.C,a)};h.M=function(a){return".priority"===a?this.ba:C};h.oa=function(a){return a.e()?this:".priority"===O(a)?this.ba:C};h.Ha=function(){return!1};h.qf=function(){return null};
+h.Q=function(a,b){return".priority"===a?this.da(b):b.e()&&".priority"!==a?this:C.Q(a,b).da(this.ba)};h.G=function(a,b){var c=O(a);if(null===c)return b;if(b.e()&&".priority"!==c)return this;J(".priority"!==c||1===uc(a),".priority must be the last token in a path");return this.Q(c,C.G(G(a),b))};h.e=function(){return!1};h.Db=function(){return 0};h.K=function(a){return a&&!this.A().e()?{".value":this.Ba(),".priority":this.A().K()}:this.Ba()};
+h.hash=function(){if(null===this.Bb){var a="";this.ba.e()||(a+="priority:"+le(this.ba.K())+":");var b=typeof this.C,a=a+(b+":"),a="number"===b?a+Zc(this.C):a+this.C;this.Bb=Jc(a)}return this.Bb};h.Ba=function(){return this.C};h.Cc=function(a){if(a===C)return 1;if(a instanceof T)return-1;J(a.N(),"Unknown node type");var b=typeof a.C,c=typeof this.C,d=Na(me,b),e=Na(me,c);J(0<=d,"Unknown leaf type: "+b);J(0<=e,"Unknown leaf type: "+c);return d===e?"object"===c?0:this.C<a.C?-1:this.C===a.C?0:1:e-d};
+var me=["object","boolean","number","string"];tc.prototype.mb=function(){return this};tc.prototype.Ic=function(){return!0};tc.prototype.Z=function(a){return a===this?!0:a.N()?this.C===a.C&&this.ba.Z(a.ba):!1};tc.prototype.toString=function(){return B(this.K(!0))};function T(a,b,c){this.m=a;(this.ba=b)&&ke(this.ba);a.e()&&J(!this.ba||this.ba.e(),"An empty node cannot have a priority");this.wb=c;this.Bb=null}h=T.prototype;h.N=function(){return!1};h.A=function(){return this.ba||C};h.da=function(a){return this.m.e()?this:new T(this.m,a,this.wb)};h.M=function(a){if(".priority"===a)return this.A();a=this.m.get(a);return null===a?C:a};h.oa=function(a){var b=O(a);return null===b?this:this.M(b).oa(G(a))};h.Ha=function(a){return null!==this.m.get(a)};
+h.Q=function(a,b){J(b,"We should always be passing snapshot nodes");if(".priority"===a)return this.da(b);var c=new E(a,b),d,e;b.e()?(d=this.m.remove(a),c=ie(this.wb,c,this.m)):(d=this.m.Na(a,b),c=ge(this.wb,c,this.m));e=d.e()?C:this.ba;return new T(d,e,c)};h.G=function(a,b){var c=O(a);if(null===c)return b;J(".priority"!==O(a)||1===uc(a),".priority must be the last token in a path");var d=this.M(c).G(G(a),b);return this.Q(c,d)};h.e=function(){return this.m.e()};h.Db=function(){return this.m.count()};
+var ne=/^(0|[1-9]\d*)$/;h=T.prototype;h.K=function(a){if(this.e())return null;var b={},c=0,d=0,e=!0;this.U(M,function(f,g){b[f]=g.K(a);c++;e&&ne.test(f)?d=Math.max(d,Number(f)):e=!1});if(!a&&e&&d<2*c){var f=[],g;for(g in b)f[g]=b[g];return f}a&&!this.A().e()&&(b[".priority"]=this.A().K());return b};h.hash=function(){if(null===this.Bb){var a="";this.A().e()||(a+="priority:"+le(this.A().K())+":");this.U(M,function(b,c){var d=c.hash();""!==d&&(a+=":"+b+":"+d)});this.Bb=""===a?"":Jc(a)}return this.Bb};
+h.qf=function(a,b,c){return(c=oe(this,c))?(a=cc(c,new E(a,b)))?a.name:null:cc(this.m,a)};function wd(a,b){var c;c=(c=oe(a,b))?(c=c.Rc())&&c.name:a.m.Rc();return c?new E(c,a.m.get(c)):null}function xd(a,b){var c;c=(c=oe(a,b))?(c=c.ec())&&c.name:a.m.ec();return c?new E(c,a.m.get(c)):null}h.U=function(a,b){var c=oe(this,a);return c?c.ha(function(a){return b(a.name,a.S)}):this.m.ha(b)};h.Wb=function(a){return this.Xb(a.Sc(),a)};
+h.Xb=function(a,b){var c=oe(this,b);if(c)return c.Xb(a,function(a){return a});for(var c=this.m.Xb(a.name,Qb),d=ec(c);null!=d&&0>b.compare(d,a);)H(c),d=ec(c);return c};h.rf=function(a){return this.Zb(a.Pc(),a)};h.Zb=function(a,b){var c=oe(this,b);if(c)return c.Zb(a,function(a){return a});for(var c=this.m.Zb(a.name,Qb),d=ec(c);null!=d&&0<b.compare(d,a);)H(c),d=ec(c);return c};h.Cc=function(a){return this.e()?a.e()?0:-1:a.N()||a.e()?1:a===Sd?-1:0};
+h.mb=function(a){if(a===Vd||ta(this.wb.cc,a.toString()))return this;var b=this.wb,c=this.m;J(a!==Vd,"KeyIndex always exists and isn't meant to be added to the IndexMap.");for(var d=[],e=!1,c=c.Wb(Qb),f=H(c);f;)e=e||a.Hc(f.S),d.push(f),f=H(c);d=e?he(d,ud(a)):Pd;e=a.toString();c=xa(b.cc);c[e]=a;a=xa(b.yd);a[e]=d;return new T(this.m,this.ba,new fe(a,c))};h.Ic=function(a){return a===Vd||ta(this.wb.cc,a.toString())};
+h.Z=function(a){if(a===this)return!0;if(a.N())return!1;if(this.A().Z(a.A())&&this.m.count()===a.m.count()){var b=this.Wb(M);a=a.Wb(M);for(var c=H(b),d=H(a);c&&d;){if(c.name!==d.name||!c.S.Z(d.S))return!1;c=H(b);d=H(a)}return null===c&&null===d}return!1};function oe(a,b){return b===Vd?null:a.wb.get(b.toString())}h.toString=function(){return B(this.K(!0))};function L(a,b){if(null===a)return C;var c=null;"object"===typeof a&&".priority"in a?c=a[".priority"]:"undefined"!==typeof b&&(c=b);J(null===c||"string"===typeof c||"number"===typeof c||"object"===typeof c&&".sv"in c,"Invalid priority type found: "+typeof c);"object"===typeof a&&".value"in a&&null!==a[".value"]&&(a=a[".value"]);if("object"!==typeof a||".sv"in a)return new tc(a,L(c));if(a instanceof Array){var d=C,e=a;r(e,function(a,b){if(u(e,b)&&"."!==b.substring(0,1)){var c=L(a);if(c.N()||!c.e())d=
+d.Q(b,c)}});return d.da(L(c))}var f=[],g=!1,k=a;hb(k,function(a){if("string"!==typeof a||"."!==a.substring(0,1)){var b=L(k[a]);b.e()||(g=g||!b.A().e(),f.push(new E(a,b)))}});if(0==f.length)return C;var l=he(f,Rb,function(a){return a.name},Tb);if(g){var m=he(f,ud(M));return new T(l,L(c),new fe({".priority":m},{".priority":M}))}return new T(l,L(c),je)}var pe=Math.log(2);
+function qe(a){this.count=parseInt(Math.log(a+1)/pe,10);this.hf=this.count-1;this.bg=a+1&parseInt(Array(this.count+1).join("1"),2)}function re(a){var b=!(a.bg&1<<a.hf);a.hf--;return b}
+function he(a,b,c,d){function e(b,d){var f=d-b;if(0==f)return null;if(1==f){var m=a[b],v=c?c(m):m;return new fc(v,m.S,!1,null,null)}var m=parseInt(f/2,10)+b,f=e(b,m),y=e(m+1,d),m=a[m],v=c?c(m):m;return new fc(v,m.S,!1,f,y)}a.sort(b);var f=function(b){function d(b,g){var k=v-b,y=v;v-=b;var y=e(k+1,y),k=a[k],I=c?c(k):k,y=new fc(I,k.S,g,null,y);f?f.left=y:m=y;f=y}for(var f=null,m=null,v=a.length,y=0;y<b.count;++y){var I=re(b),vd=Math.pow(2,b.count-(y+1));I?d(vd,!1):(d(vd,!1),d(vd,!0))}return m}(new qe(a.length));
+return null!==f?new ac(d||b,f):new ac(d||b)}function le(a){return"number"===typeof a?"number:"+Zc(a):"string:"+a}function ke(a){if(a.N()){var b=a.K();J("string"===typeof b||"number"===typeof b||"object"===typeof b&&u(b,".sv"),"Priority must be a string or number.")}else J(a===Sd||a.e(),"priority of unexpected type.");J(a===Sd||a.A().e(),"Priority nodes can't have a priority of their own.")}var C=new T(new ac(Tb),null,je);function se(){T.call(this,new ac(Tb),C,je)}ma(se,T);h=se.prototype;
+h.Cc=function(a){return a===this?0:1};h.Z=function(a){return a===this};h.A=function(){return this};h.M=function(){return C};h.e=function(){return!1};var Sd=new se,Qd=new E("[MIN_NAME]",C),Xd=new E("[MAX_NAME]",Sd);function Id(a,b){this.D=a;this.Ud=b}function Fd(a,b,c,d){return new Id(new sb(b,c,d),a.Ud)}function Jd(a){return a.D.$?a.D.j():null}Id.prototype.u=function(){return this.Ud};function tb(a){return a.Ud.$?a.Ud.j():null};function te(a,b){this.V=a;var c=a.o,d=new ld(c.g),c=de(c)?new ld(c.g):c.ia?new rd(c):new md(c);this.Gf=new zd(c);var e=b.u(),f=b.D,g=d.ta(C,e.j(),null),k=c.ta(C,f.j(),null);this.Ka=new Id(new sb(k,f.$,c.Ga()),new sb(g,e.$,d.Ga()));this.Za=[];this.ig=new dd(a)}function ue(a){return a.V}h=te.prototype;h.u=function(){return this.Ka.u().j()};h.hb=function(a){var b=tb(this.Ka);return b&&(de(this.V.o)||!a.e()&&!b.M(O(a)).e())?b.oa(a):null};h.e=function(){return 0===this.Za.length};h.Ob=function(a){this.Za.push(a)};
+h.kb=function(a,b){var c=[];if(b){J(null==a,"A cancel should cancel all event registrations.");var d=this.V.path;Oa(this.Za,function(a){(a=a.ff(b,d))&&c.push(a)})}if(a){for(var e=[],f=0;f<this.Za.length;++f){var g=this.Za[f];if(!g.matches(a))e.push(g);else if(a.sf()){e=e.concat(this.Za.slice(f+1));break}}this.Za=e}else this.Za=[];return c};
+h.bb=function(a,b,c){a.type===Cd&&null!==a.source.Ib&&(J(tb(this.Ka),"We should always have a full cache before handling merges"),J(Jd(this.Ka),"Missing event cache, even though we have a server cache"));var d=this.Ka;a=this.Gf.bb(d,a,b,c);b=this.Gf;c=a.he;J(c.D.j().Ic(b.I.g),"Event snap not indexed");J(c.u().j().Ic(b.I.g),"Server snap not indexed");J(Hb(a.he.u())||!Hb(d.u()),"Once a server snap is complete, it should never go back");this.Ka=a.he;return ve(this,a.cg,a.he.D.j(),null)};
+function we(a,b){var c=a.Ka.D,d=[];c.j().N()||c.j().U(M,function(a,b){d.push(new D("child_added",b,a))});c.$&&d.push(Db(c.j()));return ve(a,d,c.j(),b)}function ve(a,b,c,d){return ed(a.ig,b,c,d?[d]:a.Za)};function xe(a,b,c){this.type=Cd;this.source=a;this.path=b;this.children=c}xe.prototype.Wc=function(a){if(this.path.e())return a=this.children.subtree(new K(a)),a.e()?null:a.value?new Ub(this.source,F,a.value):new xe(this.source,F,a);J(O(this.path)===a,"Can't get a merge for a child not on the path of the operation");return new xe(this.source,G(this.path),this.children)};xe.prototype.toString=function(){return"Operation("+this.path+": "+this.source.toString()+" merge: "+this.children.toString()+")"};var Vb=0,Cd=1,Xb=2,$b=3;function ye(a,b,c,d){this.ve=a;this.of=b;this.Ib=c;this.af=d;J(!d||b,"Tagged queries must be from server.")}var Yb=new ye(!0,!1,null,!1),ze=new ye(!1,!0,null,!1);ye.prototype.toString=function(){return this.ve?"user":this.af?"server(queryID="+this.Ib+")":"server"};function Ae(a,b){this.f=Oc("p:rest:");this.H=a;this.Gb=b;this.Fa=null;this.aa={}}function Be(a,b){if(n(b))return"tag$"+b;var c=a.o;J(de(c)&&c.g==M,"should have a tag if it's not a default query.");return a.path.toString()}h=Ae.prototype;
+h.xf=function(a,b,c,d){var e=a.path.toString();this.f("Listen called for "+e+" "+a.wa());var f=Be(a,c),g={};this.aa[f]=g;a=ee(a.o);var k=this;Ce(this,e+".json",a,function(a,b){var v=b;404===a&&(a=v=null);null===a&&k.Gb(e,v,!1,c);w(k.aa,f)===g&&d(a?401==a?"permission_denied":"rest_error:"+a:"ok",null)})};h.Of=function(a,b){var c=Be(a,b);delete this.aa[c]};h.P=function(a,b){this.Fa=a;var c=ad(a),d=c.data,c=c.Ac&&c.Ac.exp;b&&b("ok",{auth:d,expires:c})};h.ee=function(a){this.Fa=null;a("ok",null)};
+h.Le=function(){};h.Bf=function(){};h.Gd=function(){};h.put=function(){};h.yf=function(){};h.Te=function(){};
+function Ce(a,b,c,d){c=c||{};c.format="export";a.Fa&&(c.auth=a.Fa);var e=(a.H.lb?"https://":"http://")+a.H.host+b+"?"+jb(c);a.f("Sending REST request for "+e);var f=new XMLHttpRequest;f.onreadystatechange=function(){if(d&&4===f.readyState){a.f("REST Response for "+e+" received. status:",f.status,"response:",f.responseText);var b=null;if(200<=f.status&&300>f.status){try{b=mb(f.responseText)}catch(c){Q("Failed to parse JSON response for "+e+": "+f.responseText)}d(null,b)}else 401!==f.status&&404!==
+f.status&&Q("Got unsuccessful REST response for "+e+" Status: "+f.status),d(f.status);d=null}};f.open("GET",e,!0);f.send()};function De(a,b){this.value=a;this.children=b||Ee}var Ee=new ac(function(a,b){return a===b?0:a<b?-1:1});function Fe(a){var b=Nd;r(a,function(a,d){b=b.set(new K(d),a)});return b}h=De.prototype;h.e=function(){return null===this.value&&this.children.e()};function Ge(a,b,c){if(null!=a.value&&c(a.value))return{path:F,value:a.value};if(b.e())return null;var d=O(b);a=a.children.get(d);return null!==a?(b=Ge(a,G(b),c),null!=b?{path:(new K(d)).w(b.path),value:b.value}:null):null}
+function He(a,b){return Ge(a,b,function(){return!0})}h.subtree=function(a){if(a.e())return this;var b=this.children.get(O(a));return null!==b?b.subtree(G(a)):Nd};h.set=function(a,b){if(a.e())return new De(b,this.children);var c=O(a),d=(this.children.get(c)||Nd).set(G(a),b),c=this.children.Na(c,d);return new De(this.value,c)};
+h.remove=function(a){if(a.e())return this.children.e()?Nd:new De(null,this.children);var b=O(a),c=this.children.get(b);return c?(a=c.remove(G(a)),b=a.e()?this.children.remove(b):this.children.Na(b,a),null===this.value&&b.e()?Nd:new De(this.value,b)):this};h.get=function(a){if(a.e())return this.value;var b=this.children.get(O(a));return b?b.get(G(a)):null};
+function Md(a,b,c){if(b.e())return c;var d=O(b);b=Md(a.children.get(d)||Nd,G(b),c);d=b.e()?a.children.remove(d):a.children.Na(d,b);return new De(a.value,d)}function Ie(a,b){return Je(a,F,b)}function Je(a,b,c){var d={};a.children.ha(function(a,f){d[a]=Je(f,b.w(a),c)});return c(b,a.value,d)}function Ke(a,b,c){return Le(a,b,F,c)}function Le(a,b,c,d){var e=a.value?d(c,a.value):!1;if(e)return e;if(b.e())return null;e=O(b);return(a=a.children.get(e))?Le(a,G(b),c.w(e),d):null}
+function Me(a,b,c){var d=F;if(!b.e()){var e=!0;a.value&&(e=c(d,a.value));!0===e&&(e=O(b),(a=a.children.get(e))&&Ne(a,G(b),d.w(e),c))}}function Ne(a,b,c,d){if(b.e())return a;a.value&&d(c,a.value);var e=O(b);return(a=a.children.get(e))?Ne(a,G(b),c.w(e),d):Nd}function Kd(a,b){Oe(a,F,b)}function Oe(a,b,c){a.children.ha(function(a,e){Oe(e,b.w(a),c)});a.value&&c(b,a.value)}function Pe(a,b){a.children.ha(function(a,d){d.value&&b(a,d.value)})}var Nd=new De(null);
+De.prototype.toString=function(){var a={};Kd(this,function(b,c){a[b.toString()]=c.toString()});return B(a)};function Qe(a){this.W=a}var Re=new Qe(new De(null));function Se(a,b,c){if(b.e())return new Qe(new De(c));var d=He(a.W,b);if(null!=d){var e=d.path,d=d.value;b=N(e,b);d=d.G(b,c);return new Qe(a.W.set(e,d))}a=Md(a.W,b,new De(c));return new Qe(a)}function Te(a,b,c){var d=a;hb(c,function(a,c){d=Se(d,b.w(a),c)});return d}Qe.prototype.Od=function(a){if(a.e())return Re;a=Md(this.W,a,Nd);return new Qe(a)};function Ue(a,b){var c=He(a.W,b);return null!=c?a.W.get(c.path).oa(N(c.path,b)):null}
+function Ve(a){var b=[],c=a.W.value;null!=c?c.N()||c.U(M,function(a,c){b.push(new E(a,c))}):a.W.children.ha(function(a,c){null!=c.value&&b.push(new E(a,c.value))});return b}function We(a,b){if(b.e())return a;var c=Ue(a,b);return null!=c?new Qe(new De(c)):new Qe(a.W.subtree(b))}Qe.prototype.e=function(){return this.W.e()};Qe.prototype.apply=function(a){return Xe(F,this.W,a)};
+function Xe(a,b,c){if(null!=b.value)return c.G(a,b.value);var d=null;b.children.ha(function(b,f){".priority"===b?(J(null!==f.value,"Priority writes must always be leaf nodes"),d=f.value):c=Xe(a.w(b),f,c)});c.oa(a).e()||null===d||(c=c.G(a.w(".priority"),d));return c};function Ye(){this.T=Re;this.za=[];this.Lc=-1}h=Ye.prototype;
+h.Od=function(a){var b=Ua(this.za,function(b){return b.ie===a});J(0<=b,"removeWrite called with nonexistent writeId.");var c=this.za[b];this.za.splice(b,1);for(var d=c.visible,e=!1,f=this.za.length-1;d&&0<=f;){var g=this.za[f];g.visible&&(f>=b&&Ze(g,c.path)?d=!1:c.path.contains(g.path)&&(e=!0));f--}if(d){if(e)this.T=$e(this.za,af,F),this.Lc=0<this.za.length?this.za[this.za.length-1].ie:-1;else if(c.Ia)this.T=this.T.Od(c.path);else{var k=this;r(c.children,function(a,b){k.T=k.T.Od(c.path.w(b))})}return c.path}return null};
+h.ua=function(a,b,c,d){if(c||d){var e=We(this.T,a);return!d&&e.e()?b:d||null!=b||null!=Ue(e,F)?(e=$e(this.za,function(b){return(b.visible||d)&&(!c||!(0<=Na(c,b.ie)))&&(b.path.contains(a)||a.contains(b.path))},a),b=b||C,e.apply(b)):null}e=Ue(this.T,a);if(null!=e)return e;e=We(this.T,a);return e.e()?b:null!=b||null!=Ue(e,F)?(b=b||C,e.apply(b)):null};
+h.xc=function(a,b){var c=C,d=Ue(this.T,a);if(d)d.N()||d.U(M,function(a,b){c=c.Q(a,b)});else if(b){var e=We(this.T,a);b.U(M,function(a,b){var d=We(e,new K(a)).apply(b);c=c.Q(a,d)});Oa(Ve(e),function(a){c=c.Q(a.name,a.S)})}else e=We(this.T,a),Oa(Ve(e),function(a){c=c.Q(a.name,a.S)});return c};h.hd=function(a,b,c,d){J(c||d,"Either existingEventSnap or existingServerSnap must exist");a=a.w(b);if(null!=Ue(this.T,a))return null;a=We(this.T,a);return a.e()?d.oa(b):a.apply(d.oa(b))};
+h.Xa=function(a,b,c){a=a.w(b);var d=Ue(this.T,a);return null!=d?d:rb(c,b)?We(this.T,a).apply(c.j().M(b)):null};h.sc=function(a){return Ue(this.T,a)};h.me=function(a,b,c,d,e,f){var g;a=We(this.T,a);g=Ue(a,F);if(null==g)if(null!=b)g=a.apply(b);else return[];g=g.mb(f);if(g.e()||g.N())return[];b=[];a=ud(f);e=e?g.Zb(c,f):g.Xb(c,f);for(f=H(e);f&&b.length<d;)0!==a(f,c)&&b.push(f),f=H(e);return b};
+function Ze(a,b){return a.Ia?a.path.contains(b):!!ua(a.children,function(c,d){return a.path.w(d).contains(b)})}function af(a){return a.visible}
+function $e(a,b,c){for(var d=Re,e=0;e<a.length;++e){var f=a[e];if(b(f)){var g=f.path;if(f.Ia)c.contains(g)?(g=N(c,g),d=Se(d,g,f.Ia)):g.contains(c)&&(g=N(g,c),d=Se(d,F,f.Ia.oa(g)));else if(f.children)if(c.contains(g))g=N(c,g),d=Te(d,g,f.children);else{if(g.contains(c))if(g=N(g,c),g.e())d=Te(d,F,f.children);else if(f=w(f.children,O(g)))f=f.oa(G(g)),d=Se(d,F,f)}else throw Hc("WriteRecord should have .snap or .children");}}return d}function bf(a,b){this.Mb=a;this.W=b}h=bf.prototype;
+h.ua=function(a,b,c){return this.W.ua(this.Mb,a,b,c)};h.xc=function(a){return this.W.xc(this.Mb,a)};h.hd=function(a,b,c){return this.W.hd(this.Mb,a,b,c)};h.sc=function(a){return this.W.sc(this.Mb.w(a))};h.me=function(a,b,c,d,e){return this.W.me(this.Mb,a,b,c,d,e)};h.Xa=function(a,b){return this.W.Xa(this.Mb,a,b)};h.w=function(a){return new bf(this.Mb.w(a),this.W)};function cf(){this.ya={}}h=cf.prototype;h.e=function(){return wa(this.ya)};h.bb=function(a,b,c){var d=a.source.Ib;if(null!==d)return d=w(this.ya,d),J(null!=d,"SyncTree gave us an op for an invalid query."),d.bb(a,b,c);var e=[];r(this.ya,function(d){e=e.concat(d.bb(a,b,c))});return e};h.Ob=function(a,b,c,d,e){var f=a.wa(),g=w(this.ya,f);if(!g){var g=c.ua(e?d:null),k=!1;g?k=!0:(g=d instanceof T?c.xc(d):C,k=!1);g=new te(a,new Id(new sb(g,k,!1),new sb(d,e,!1)));this.ya[f]=g}g.Ob(b);return we(g,b)};
+h.kb=function(a,b,c){var d=a.wa(),e=[],f=[],g=null!=df(this);if("default"===d){var k=this;r(this.ya,function(a,d){f=f.concat(a.kb(b,c));a.e()&&(delete k.ya[d],de(a.V.o)||e.push(a.V))})}else{var l=w(this.ya,d);l&&(f=f.concat(l.kb(b,c)),l.e()&&(delete this.ya[d],de(l.V.o)||e.push(l.V)))}g&&null==df(this)&&e.push(new U(a.k,a.path));return{Hg:e,jg:f}};function ef(a){return Pa(ra(a.ya),function(a){return!de(a.V.o)})}h.hb=function(a){var b=null;r(this.ya,function(c){b=b||c.hb(a)});return b};
+function ff(a,b){if(de(b.o))return df(a);var c=b.wa();return w(a.ya,c)}function df(a){return va(a.ya,function(a){return de(a.V.o)})||null};function gf(a){this.sa=Nd;this.Hb=new Ye;this.$e={};this.kc={};this.Mc=a}function hf(a,b,c,d,e){var f=a.Hb,g=e;J(d>f.Lc,"Stacking an older write on top of newer ones");n(g)||(g=!0);f.za.push({path:b,Ia:c,ie:d,visible:g});g&&(f.T=Se(f.T,b,c));f.Lc=d;return e?jf(a,new Ub(Yb,b,c)):[]}function kf(a,b,c,d){var e=a.Hb;J(d>e.Lc,"Stacking an older merge on top of newer ones");e.za.push({path:b,children:c,ie:d,visible:!0});e.T=Te(e.T,b,c);e.Lc=d;c=Fe(c);return jf(a,new xe(Yb,b,c))}
+function lf(a,b,c){c=c||!1;b=a.Hb.Od(b);return null==b?[]:jf(a,new Wb(b,c))}function mf(a,b,c){c=Fe(c);return jf(a,new xe(ze,b,c))}function nf(a,b,c,d){d=of(a,d);if(null!=d){var e=pf(d);d=e.path;e=e.Ib;b=N(d,b);c=new Ub(new ye(!1,!0,e,!0),b,c);return qf(a,d,c)}return[]}function rf(a,b,c,d){if(d=of(a,d)){var e=pf(d);d=e.path;e=e.Ib;b=N(d,b);c=Fe(c);c=new xe(new ye(!1,!0,e,!0),b,c);return qf(a,d,c)}return[]}
+gf.prototype.Ob=function(a,b){var c=a.path,d=null,e=!1;Me(this.sa,c,function(a,b){var f=N(a,c);d=b.hb(f);e=e||null!=df(b);return!d});var f=this.sa.get(c);f?(e=e||null!=df(f),d=d||f.hb(F)):(f=new cf,this.sa=this.sa.set(c,f));var g;null!=d?g=!0:(g=!1,d=C,Pe(this.sa.subtree(c),function(a,b){var c=b.hb(F);c&&(d=d.Q(a,c))}));var k=null!=ff(f,a);if(!k&&!de(a.o)){var l=sf(a);J(!(l in this.kc),"View does not exist, but we have a tag");var m=tf++;this.kc[l]=m;this.$e["_"+m]=l}g=f.Ob(a,b,new bf(c,this.Hb),
+d,g);k||e||(f=ff(f,a),g=g.concat(uf(this,a,f)));return g};
+gf.prototype.kb=function(a,b,c){var d=a.path,e=this.sa.get(d),f=[];if(e&&("default"===a.wa()||null!=ff(e,a))){f=e.kb(a,b,c);e.e()&&(this.sa=this.sa.remove(d));e=f.Hg;f=f.jg;b=-1!==Ua(e,function(a){return de(a.o)});var g=Ke(this.sa,d,function(a,b){return null!=df(b)});if(b&&!g&&(d=this.sa.subtree(d),!d.e()))for(var d=vf(d),k=0;k<d.length;++k){var l=d[k],m=l.V,l=wf(this,l);this.Mc.Xe(m,xf(this,m),l.ud,l.J)}if(!g&&0<e.length&&!c)if(b)this.Mc.Zd(a,null);else{var v=this;Oa(e,function(a){a.wa();var b=v.kc[sf(a)];
+v.Mc.Zd(a,b)})}yf(this,e)}return f};gf.prototype.ua=function(a,b){var c=this.Hb,d=Ke(this.sa,a,function(b,c){var d=N(b,a);if(d=c.hb(d))return d});return c.ua(a,d,b,!0)};function vf(a){return Ie(a,function(a,c,d){if(c&&null!=df(c))return[df(c)];var e=[];c&&(e=ef(c));r(d,function(a){e=e.concat(a)});return e})}function yf(a,b){for(var c=0;c<b.length;++c){var d=b[c];if(!de(d.o)){var d=sf(d),e=a.kc[d];delete a.kc[d];delete a.$e["_"+e]}}}
+function uf(a,b,c){var d=b.path,e=xf(a,b);c=wf(a,c);b=a.Mc.Xe(b,e,c.ud,c.J);d=a.sa.subtree(d);if(e)J(null==df(d.value),"If we're adding a query, it shouldn't be shadowed");else for(e=Ie(d,function(a,b,c){if(!a.e()&&b&&null!=df(b))return[ue(df(b))];var d=[];b&&(d=d.concat(Qa(ef(b),function(a){return a.V})));r(c,function(a){d=d.concat(a)});return d}),d=0;d<e.length;++d)c=e[d],a.Mc.Zd(c,xf(a,c));return b}
+function wf(a,b){var c=b.V,d=xf(a,c);return{ud:function(){return(b.u()||C).hash()},J:function(b){if("ok"===b){if(d){var f=c.path;if(b=of(a,d)){var g=pf(b);b=g.path;g=g.Ib;f=N(b,f);f=new Zb(new ye(!1,!0,g,!0),f);b=qf(a,b,f)}else b=[]}else b=jf(a,new Zb(ze,c.path));return b}f="Unknown Error";"too_big"===b?f="The data requested exceeds the maximum size that can be accessed with a single request.":"permission_denied"==b?f="Client doesn't have permission to access the desired data.":"unavailable"==b&&
+(f="The service is unavailable");f=Error(b+": "+f);f.code=b.toUpperCase();return a.kb(c,null,f)}}}function sf(a){return a.path.toString()+"$"+a.wa()}function pf(a){var b=a.indexOf("$");J(-1!==b&&b<a.length-1,"Bad queryKey.");return{Ib:a.substr(b+1),path:new K(a.substr(0,b))}}function of(a,b){var c=a.$e,d="_"+b;return d in c?c[d]:void 0}function xf(a,b){var c=sf(b);return w(a.kc,c)}var tf=1;
+function qf(a,b,c){var d=a.sa.get(b);J(d,"Missing sync point for query tag that we're tracking");return d.bb(c,new bf(b,a.Hb),null)}function jf(a,b){return zf(a,b,a.sa,null,new bf(F,a.Hb))}function zf(a,b,c,d,e){if(b.path.e())return Af(a,b,c,d,e);var f=c.get(F);null==d&&null!=f&&(d=f.hb(F));var g=[],k=O(b.path),l=b.Wc(k);if((c=c.children.get(k))&&l)var m=d?d.M(k):null,k=e.w(k),g=g.concat(zf(a,l,c,m,k));f&&(g=g.concat(f.bb(b,e,d)));return g}
+function Af(a,b,c,d,e){var f=c.get(F);null==d&&null!=f&&(d=f.hb(F));var g=[];c.children.ha(function(c,f){var m=d?d.M(c):null,v=e.w(c),y=b.Wc(c);y&&(g=g.concat(Af(a,y,f,m,v)))});f&&(g=g.concat(f.bb(b,e,d)));return g};function Bf(){this.children={};this.kd=0;this.value=null}function Cf(a,b,c){this.Dd=a?a:"";this.Yc=b?b:null;this.B=c?c:new Bf}function Df(a,b){for(var c=b instanceof K?b:new K(b),d=a,e;null!==(e=O(c));)d=new Cf(e,d,w(d.B.children,e)||new Bf),c=G(c);return d}h=Cf.prototype;h.Ba=function(){return this.B.value};function Ef(a,b){J("undefined"!==typeof b,"Cannot set value to undefined");a.B.value=b;Ff(a)}h.clear=function(){this.B.value=null;this.B.children={};this.B.kd=0;Ff(this)};
+h.td=function(){return 0<this.B.kd};h.e=function(){return null===this.Ba()&&!this.td()};h.U=function(a){var b=this;r(this.B.children,function(c,d){a(new Cf(d,b,c))})};function Gf(a,b,c,d){c&&!d&&b(a);a.U(function(a){Gf(a,b,!0,d)});c&&d&&b(a)}function Hf(a,b){for(var c=a.parent();null!==c&&!b(c);)c=c.parent()}h.path=function(){return new K(null===this.Yc?this.Dd:this.Yc.path()+"/"+this.Dd)};h.name=function(){return this.Dd};h.parent=function(){return this.Yc};
+function Ff(a){if(null!==a.Yc){var b=a.Yc,c=a.Dd,d=a.e(),e=u(b.B.children,c);d&&e?(delete b.B.children[c],b.B.kd--,Ff(b)):d||e||(b.B.children[c]=a.B,b.B.kd++,Ff(b))}};function If(a){J(ea(a)&&0<a.length,"Requires a non-empty array");this.Uf=a;this.Nc={}}If.prototype.de=function(a,b){for(var c=this.Nc[a]||[],d=0;d<c.length;d++)c[d].yc.apply(c[d].Ma,Array.prototype.slice.call(arguments,1))};If.prototype.Eb=function(a,b,c){Jf(this,a);this.Nc[a]=this.Nc[a]||[];this.Nc[a].push({yc:b,Ma:c});(a=this.ze(a))&&b.apply(c,a)};If.prototype.gc=function(a,b,c){Jf(this,a);a=this.Nc[a]||[];for(var d=0;d<a.length;d++)if(a[d].yc===b&&(!c||c===a[d].Ma)){a.splice(d,1);break}};
+function Jf(a,b){J(Ta(a.Uf,function(a){return a===b}),"Unknown event: "+b)};var Kf=function(){var a=0,b=[];return function(c){var d=c===a;a=c;for(var e=Array(8),f=7;0<=f;f--)e[f]="-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(c%64),c=Math.floor(c/64);J(0===c,"Cannot push at time == 0");c=e.join("");if(d){for(f=11;0<=f&&63===b[f];f--)b[f]=0;b[f]++}else for(f=0;12>f;f++)b[f]=Math.floor(64*Math.random());for(f=0;12>f;f++)c+="-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(b[f]);J(20===c.length,"nextPushId: Length should be 20.");
+return c}}();function Lf(){If.call(this,["online"]);this.ic=!0;if("undefined"!==typeof window&&"undefined"!==typeof window.addEventListener){var a=this;window.addEventListener("online",function(){a.ic||(a.ic=!0,a.de("online",!0))},!1);window.addEventListener("offline",function(){a.ic&&(a.ic=!1,a.de("online",!1))},!1)}}ma(Lf,If);Lf.prototype.ze=function(a){J("online"===a,"Unknown event type: "+a);return[this.ic]};ca(Lf);function Mf(){If.call(this,["visible"]);var a,b;"undefined"!==typeof document&&"undefined"!==typeof document.addEventListener&&("undefined"!==typeof document.hidden?(b="visibilitychange",a="hidden"):"undefined"!==typeof document.mozHidden?(b="mozvisibilitychange",a="mozHidden"):"undefined"!==typeof document.msHidden?(b="msvisibilitychange",a="msHidden"):"undefined"!==typeof document.webkitHidden&&(b="webkitvisibilitychange",a="webkitHidden"));this.uc=!0;if(b){var c=this;document.addEventListener(b,
+function(){var b=!document[a];b!==c.uc&&(c.uc=b,c.de("visible",b))},!1)}}ma(Mf,If);Mf.prototype.ze=function(a){J("visible"===a,"Unknown event type: "+a);return[this.uc]};ca(Mf);var Nf=/[\[\].#$\/\u0000-\u001F\u007F]/,Of=/[\[\].#$\u0000-\u001F\u007F]/,Pf=/^[a-zA-Z][a-zA-Z._\-+]+$/;function Qf(a){return p(a)&&0!==a.length&&!Nf.test(a)}function Rf(a){return null===a||p(a)||ga(a)&&!Sc(a)||ia(a)&&u(a,".sv")}function Sf(a,b,c,d){d&&!n(b)||Tf(z(a,1,d),b,c)}
+function Tf(a,b,c){c instanceof K&&(c=new wc(c,a));if(!n(b))throw Error(a+"contains undefined "+zc(c));if(ha(b))throw Error(a+"contains a function "+zc(c)+" with contents: "+b.toString());if(Sc(b))throw Error(a+"contains "+b.toString()+" "+zc(c));if(p(b)&&b.length>10485760/3&&10485760<xc(b))throw Error(a+"contains a string greater than 10485760 utf8 bytes "+zc(c)+" ('"+b.substring(0,50)+"...')");if(ia(b)){var d=!1,e=!1;hb(b,function(b,g){if(".value"===b)d=!0;else if(".priority"!==b&&".sv"!==b&&(e=
+!0,!Qf(b)))throw Error(a+" contains an invalid key ("+b+") "+zc(c)+'. Keys must be non-empty strings and can\'t contain ".", "#", "$", "/", "[", or "]"');c.push(b);Tf(a,g,c);c.pop()});if(d&&e)throw Error(a+' contains ".value" child '+zc(c)+" in addition to actual children.");}}
+function Uf(a,b,c){if(!ia(b)||ea(b))throw Error(z(a,1,!1)+" must be an Object containing the children to replace.");if(u(b,".value"))throw Error(z(a,1,!1)+' must not contain ".value". To overwrite with a leaf value, just use .set() instead.');Sf(a,b,c,!1)}
+function Vf(a,b,c){if(Sc(c))throw Error(z(a,b,!1)+"is "+c.toString()+", but must be a valid Firebase priority (a string, finite number, server value, or null).");if(!Rf(c))throw Error(z(a,b,!1)+"must be a valid Firebase priority (a string, finite number, server value, or null).");}
+function Wf(a,b,c){if(!c||n(b))switch(b){case "value":case "child_added":case "child_removed":case "child_changed":case "child_moved":break;default:throw Error(z(a,1,c)+'must be a valid event type: "value", "child_added", "child_removed", "child_changed", or "child_moved".');}}function Xf(a,b,c,d){if((!d||n(c))&&!Qf(c))throw Error(z(a,b,d)+'was an invalid key: "'+c+'". Firebase keys must be non-empty strings and can\'t contain ".", "#", "$", "/", "[", or "]").');}
+function Yf(a,b){if(!p(b)||0===b.length||Of.test(b))throw Error(z(a,1,!1)+'was an invalid path: "'+b+'". Paths must be non-empty strings and can\'t contain ".", "#", "$", "[", or "]"');}function Zf(a,b){if(".info"===O(b))throw Error(a+" failed: Can't modify data under /.info/");}function $f(a,b){if(!p(b))throw Error(z(a,1,!1)+"must be a valid credential (a string).");}function ag(a,b,c){if(!p(c))throw Error(z(a,b,!1)+"must be a valid string.");}
+function bg(a,b){ag(a,1,b);if(!Pf.test(b))throw Error(z(a,1,!1)+"'"+b+"' is not a valid authentication provider.");}function cg(a,b,c,d){if(!d||n(c))if(!ia(c)||null===c)throw Error(z(a,b,d)+"must be a valid object.");}function dg(a,b,c){if(!ia(b)||!u(b,c))throw Error(z(a,1,!1)+'must contain the key "'+c+'"');if(!p(w(b,c)))throw Error(z(a,1,!1)+'must contain the key "'+c+'" with type "string"');};function eg(){this.set={}}h=eg.prototype;h.add=function(a,b){this.set[a]=null!==b?b:!0};h.contains=function(a){return u(this.set,a)};h.get=function(a){return this.contains(a)?this.set[a]:void 0};h.remove=function(a){delete this.set[a]};h.clear=function(){this.set={}};h.e=function(){return wa(this.set)};h.count=function(){return pa(this.set)};function fg(a,b){r(a.set,function(a,d){b(d,a)})}h.keys=function(){var a=[];r(this.set,function(b,c){a.push(c)});return a};function qc(){this.m=this.C=null}qc.prototype.find=function(a){if(null!=this.C)return this.C.oa(a);if(a.e()||null==this.m)return null;var b=O(a);a=G(a);return this.m.contains(b)?this.m.get(b).find(a):null};qc.prototype.mc=function(a,b){if(a.e())this.C=b,this.m=null;else if(null!==this.C)this.C=this.C.G(a,b);else{null==this.m&&(this.m=new eg);var c=O(a);this.m.contains(c)||this.m.add(c,new qc);c=this.m.get(c);a=G(a);c.mc(a,b)}};
+function gg(a,b){if(b.e())return a.C=null,a.m=null,!0;if(null!==a.C){if(a.C.N())return!1;var c=a.C;a.C=null;c.U(M,function(b,c){a.mc(new K(b),c)});return gg(a,b)}return null!==a.m?(c=O(b),b=G(b),a.m.contains(c)&&gg(a.m.get(c),b)&&a.m.remove(c),a.m.e()?(a.m=null,!0):!1):!0}function rc(a,b,c){null!==a.C?c(b,a.C):a.U(function(a,e){var f=new K(b.toString()+"/"+a);rc(e,f,c)})}qc.prototype.U=function(a){null!==this.m&&fg(this.m,function(b,c){a(b,c)})};var hg="auth.firebase.com";function ig(a,b,c){this.ld=a||{};this.ce=b||{};this.ab=c||{};this.ld.remember||(this.ld.remember="default")}var jg=["remember","redirectTo"];function kg(a){var b={},c={};hb(a||{},function(a,e){0<=Na(jg,a)?b[a]=e:c[a]=e});return new ig(b,{},c)};function lg(a,b){this.Pe=["session",a.Ld,a.Cb].join(":");this.$d=b}lg.prototype.set=function(a,b){if(!b)if(this.$d.length)b=this.$d[0];else throw Error("fb.login.SessionManager : No storage options available!");b.set(this.Pe,a)};lg.prototype.get=function(){var a=Qa(this.$d,q(this.ng,this)),a=Pa(a,function(a){return null!==a});Xa(a,function(a,c){return bd(c.token)-bd(a.token)});return 0<a.length?a.shift():null};lg.prototype.ng=function(a){try{var b=a.get(this.Pe);if(b&&b.token)return b}catch(c){}return null};
+lg.prototype.clear=function(){var a=this;Oa(this.$d,function(b){b.remove(a.Pe)})};function mg(){return"undefined"!==typeof navigator&&"string"===typeof navigator.userAgent?navigator.userAgent:""}function ng(){return"undefined"!==typeof window&&!!(window.cordova||window.phonegap||window.PhoneGap)&&/ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(mg())}function og(){return"undefined"!==typeof location&&/^file:\//.test(location.href)}
+function pg(a){var b=mg();if(""===b)return!1;if("Microsoft Internet Explorer"===navigator.appName){if((b=b.match(/MSIE ([0-9]{1,}[\.0-9]{0,})/))&&1<b.length)return parseFloat(b[1])>=a}else if(-1<b.indexOf("Trident")&&(b=b.match(/rv:([0-9]{2,2}[\.0-9]{0,})/))&&1<b.length)return parseFloat(b[1])>=a;return!1};function qg(){var a=window.opener.frames,b;for(b=a.length-1;0<=b;b--)try{if(a[b].location.protocol===window.location.protocol&&a[b].location.host===window.location.host&&"__winchan_relay_frame"===a[b].name)return a[b]}catch(c){}return null}function rg(a,b,c){a.attachEvent?a.attachEvent("on"+b,c):a.addEventListener&&a.addEventListener(b,c,!1)}function sg(a,b,c){a.detachEvent?a.detachEvent("on"+b,c):a.removeEventListener&&a.removeEventListener(b,c,!1)}
+function tg(a){/^https?:\/\//.test(a)||(a=window.location.href);var b=/^(https?:\/\/[\-_a-zA-Z\.0-9:]+)/.exec(a);return b?b[1]:a}function ug(a){var b="";try{a=a.replace("#","");var c=kb(a);c&&u(c,"__firebase_request_key")&&(b=w(c,"__firebase_request_key"))}catch(d){}return b}function vg(){var a=Rc(hg);return a.scheme+"://"+a.host+"/v2"}function wg(a){return vg()+"/"+a+"/auth/channel"};function xg(a){var b=this;this.zc=a;this.ae="*";pg(8)?this.Qc=this.wd=qg():(this.Qc=window.opener,this.wd=window);if(!b.Qc)throw"Unable to find relay frame";rg(this.wd,"message",q(this.hc,this));rg(this.wd,"message",q(this.Af,this));try{yg(this,{a:"ready"})}catch(c){rg(this.Qc,"load",function(){yg(b,{a:"ready"})})}rg(window,"unload",q(this.yg,this))}function yg(a,b){b=B(b);pg(8)?a.Qc.doPost(b,a.ae):a.Qc.postMessage(b,a.ae)}
+xg.prototype.hc=function(a){var b=this,c;try{c=mb(a.data)}catch(d){}c&&"request"===c.a&&(sg(window,"message",this.hc),this.ae=a.origin,this.zc&&setTimeout(function(){b.zc(b.ae,c.d,function(a,c){b.ag=!c;b.zc=void 0;yg(b,{a:"response",d:a,forceKeepWindowOpen:c})})},0))};xg.prototype.yg=function(){try{sg(this.wd,"message",this.Af)}catch(a){}this.zc&&(yg(this,{a:"error",d:"unknown closed window"}),this.zc=void 0);try{window.close()}catch(b){}};xg.prototype.Af=function(a){if(this.ag&&"die"===a.data)try{window.close()}catch(b){}};function zg(a){this.oc=Ga()+Ga()+Ga();this.Df=a}zg.prototype.open=function(a,b){P.set("redirect_request_id",this.oc);P.set("redirect_request_id",this.oc);b.requestId=this.oc;b.redirectTo=b.redirectTo||window.location.href;a+=(/\?/.test(a)?"":"?")+jb(b);window.location=a};zg.isAvailable=function(){return!og()&&!ng()};zg.prototype.Bc=function(){return"redirect"};var Ag={NETWORK_ERROR:"Unable to contact the Firebase server.",SERVER_ERROR:"An unknown server error occurred.",TRANSPORT_UNAVAILABLE:"There are no login transports available for the requested method.",REQUEST_INTERRUPTED:"The browser redirected the page before the login request could complete.",USER_CANCELLED:"The user cancelled authentication."};function Bg(a){var b=Error(w(Ag,a),a);b.code=a;return b};function Cg(a){var b;(b=!a.window_features)||(b=mg(),b=-1!==b.indexOf("Fennec/")||-1!==b.indexOf("Firefox/")&&-1!==b.indexOf("Android"));b&&(a.window_features=void 0);a.window_name||(a.window_name="_blank");this.options=a}
+Cg.prototype.open=function(a,b,c){function d(a){g&&(document.body.removeChild(g),g=void 0);v&&(v=clearInterval(v));sg(window,"message",e);sg(window,"unload",d);if(m&&!a)try{m.close()}catch(b){k.postMessage("die",l)}m=k=void 0}function e(a){if(a.origin===l)try{var b=mb(a.data);"ready"===b.a?k.postMessage(y,l):"error"===b.a?(d(!1),c&&(c(b.d),c=null)):"response"===b.a&&(d(b.forceKeepWindowOpen),c&&(c(null,b.d),c=null))}catch(e){}}var f=pg(8),g,k;if(!this.options.relay_url)return c(Error("invalid arguments: origin of url and relay_url must match"));
+var l=tg(a);if(l!==tg(this.options.relay_url))c&&setTimeout(function(){c(Error("invalid arguments: origin of url and relay_url must match"))},0);else{f&&(g=document.createElement("iframe"),g.setAttribute("src",this.options.relay_url),g.style.display="none",g.setAttribute("name","__winchan_relay_frame"),document.body.appendChild(g),k=g.contentWindow);a+=(/\?/.test(a)?"":"?")+jb(b);var m=window.open(a,this.options.window_name,this.options.window_features);k||(k=m);var v=setInterval(function(){m&&m.closed&&
+(d(!1),c&&(c(Bg("USER_CANCELLED")),c=null))},500),y=B({a:"request",d:b});rg(window,"unload",d);rg(window,"message",e)}};
+Cg.isAvailable=function(){var a;if(a="postMessage"in window&&!og())(a=ng()||"undefined"!==typeof navigator&&(!!mg().match(/Windows Phone/)||!!window.Windows&&/^ms-appx:/.test(location.href)))||(a=mg(),a="undefined"!==typeof navigator&&"undefined"!==typeof window&&!!(a.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i)||a.match(/CriOS/)||a.match(/Twitter for iPhone/)||a.match(/FBAN\/FBIOS/)||window.navigator.standalone)),a=!a;return a&&!mg().match(/PhantomJS/)};Cg.prototype.Bc=function(){return"popup"};function Dg(a){a.method||(a.method="GET");a.headers||(a.headers={});a.headers.content_type||(a.headers.content_type="application/json");a.headers.content_type=a.headers.content_type.toLowerCase();this.options=a}
+Dg.prototype.open=function(a,b,c){function d(){c&&(c(Bg("REQUEST_INTERRUPTED")),c=null)}var e=new XMLHttpRequest,f=this.options.method.toUpperCase(),g;rg(window,"beforeunload",d);e.onreadystatechange=function(){if(c&&4===e.readyState){var a;if(200<=e.status&&300>e.status){try{a=mb(e.responseText)}catch(b){}c(null,a)}else 500<=e.status&&600>e.status?c(Bg("SERVER_ERROR")):c(Bg("NETWORK_ERROR"));c=null;sg(window,"beforeunload",d)}};if("GET"===f)a+=(/\?/.test(a)?"":"?")+jb(b),g=null;else{var k=this.options.headers.content_type;
+"application/json"===k&&(g=B(b));"application/x-www-form-urlencoded"===k&&(g=jb(b))}e.open(f,a,!0);a={"X-Requested-With":"XMLHttpRequest",Accept:"application/json;text/plain"};za(a,this.options.headers);for(var l in a)e.setRequestHeader(l,a[l]);e.send(g)};Dg.isAvailable=function(){var a;if(a=!!window.XMLHttpRequest)a=mg(),a=!(a.match(/MSIE/)||a.match(/Trident/))||pg(10);return a};Dg.prototype.Bc=function(){return"json"};function Eg(a){this.oc=Ga()+Ga()+Ga();this.Df=a}
+Eg.prototype.open=function(a,b,c){function d(){c&&(c(Bg("USER_CANCELLED")),c=null)}var e=this,f=Rc(hg),g;b.requestId=this.oc;b.redirectTo=f.scheme+"://"+f.host+"/blank/page.html";a+=/\?/.test(a)?"":"?";a+=jb(b);(g=window.open(a,"_blank","location=no"))&&ha(g.addEventListener)?(g.addEventListener("loadstart",function(a){var b;if(b=a&&a.url)a:{try{var m=document.createElement("a");m.href=a.url;b=m.host===f.host&&"/blank/page.html"===m.pathname;break a}catch(v){}b=!1}b&&(a=ug(a.url),g.removeEventListener("exit",
+d),g.close(),a=new ig(null,null,{requestId:e.oc,requestKey:a}),e.Df.requestWithCredential("/auth/session",a,c),c=null)}),g.addEventListener("exit",d)):c(Bg("TRANSPORT_UNAVAILABLE"))};Eg.isAvailable=function(){return ng()};Eg.prototype.Bc=function(){return"redirect"};function Fg(a){a.callback_parameter||(a.callback_parameter="callback");this.options=a;window.__firebase_auth_jsonp=window.__firebase_auth_jsonp||{}}
+Fg.prototype.open=function(a,b,c){function d(){c&&(c(Bg("REQUEST_INTERRUPTED")),c=null)}function e(){setTimeout(function(){window.__firebase_auth_jsonp[f]=void 0;wa(window.__firebase_auth_jsonp)&&(window.__firebase_auth_jsonp=void 0);try{var a=document.getElementById(f);a&&a.parentNode.removeChild(a)}catch(b){}},1);sg(window,"beforeunload",d)}var f="fn"+(new Date).getTime()+Math.floor(99999*Math.random());b[this.options.callback_parameter]="__firebase_auth_jsonp."+f;a+=(/\?/.test(a)?"":"?")+jb(b);
+rg(window,"beforeunload",d);window.__firebase_auth_jsonp[f]=function(a){c&&(c(null,a),c=null);e()};Gg(f,a,c)};
+function Gg(a,b,c){setTimeout(function(){try{var d=document.createElement("script");d.type="text/javascript";d.id=a;d.async=!0;d.src=b;d.onerror=function(){var b=document.getElementById(a);null!==b&&b.parentNode.removeChild(b);c&&c(Bg("NETWORK_ERROR"))};var e=document.getElementsByTagName("head");(e&&0!=e.length?e[0]:document.documentElement).appendChild(d)}catch(f){c&&c(Bg("NETWORK_ERROR"))}},0)}Fg.isAvailable=function(){return"undefined"!==typeof document&&null!=document.createElement};
+Fg.prototype.Bc=function(){return"json"};function Hg(a,b,c,d){If.call(this,["auth_status"]);this.H=a;this.df=b;this.Sg=c;this.Ke=d;this.rc=new lg(a,[Dc,P]);this.nb=null;this.Re=!1;Ig(this)}ma(Hg,If);h=Hg.prototype;h.we=function(){return this.nb||null};function Ig(a){P.get("redirect_request_id")&&Jg(a);var b=a.rc.get();b&&b.token?(Kg(a,b),a.df(b.token,function(c,d){Lg(a,c,d,!1,b.token,b)},function(b,d){Mg(a,"resumeSession()",b,d)})):Kg(a,null)}
+function Ng(a,b,c,d,e,f){"firebaseio-demo.com"===a.H.domain&&Q("Firebase authentication is not supported on demo Firebases (*.firebaseio-demo.com). To secure your Firebase, create a production Firebase at https://www.firebase.com.");a.df(b,function(f,k){Lg(a,f,k,!0,b,c,d||{},e)},function(b,c){Mg(a,"auth()",b,c,f)})}function Og(a,b){a.rc.clear();Kg(a,null);a.Sg(function(a,d){if("ok"===a)R(b,null);else{var e=(a||"error").toUpperCase(),f=e;d&&(f+=": "+d);f=Error(f);f.code=e;R(b,f)}})}
+function Lg(a,b,c,d,e,f,g,k){"ok"===b?(d&&(b=c.auth,f.auth=b,f.expires=c.expires,f.token=cd(e)?e:"",c=null,b&&u(b,"uid")?c=w(b,"uid"):u(f,"uid")&&(c=w(f,"uid")),f.uid=c,c="custom",b&&u(b,"provider")?c=w(b,"provider"):u(f,"provider")&&(c=w(f,"provider")),f.provider=c,a.rc.clear(),cd(e)&&(g=g||{},c=Dc,"sessionOnly"===g.remember&&(c=P),"none"!==g.remember&&a.rc.set(f,c)),Kg(a,f)),R(k,null,f)):(a.rc.clear(),Kg(a,null),f=a=(b||"error").toUpperCase(),c&&(f+=": "+c),f=Error(f),f.code=a,R(k,f))}
+function Mg(a,b,c,d,e){Q(b+" was canceled: "+d);a.rc.clear();Kg(a,null);a=Error(d);a.code=c.toUpperCase();R(e,a)}function Pg(a,b,c,d,e){Qg(a);c=new ig(d||{},{},c||{});Rg(a,[Dg,Fg],"/auth/"+b,c,e)}
+function Sg(a,b,c,d){Qg(a);var e=[Cg,Eg];c=kg(c);"anonymous"===b||"password"===b?setTimeout(function(){R(d,Bg("TRANSPORT_UNAVAILABLE"))},0):(c.ce.window_features="menubar=yes,modal=yes,alwaysRaised=yeslocation=yes,resizable=yes,scrollbars=yes,status=yes,height=625,width=625,top="+("object"===typeof screen?.5*(screen.height-625):0)+",left="+("object"===typeof screen?.5*(screen.width-625):0),c.ce.relay_url=wg(a.H.Cb),c.ce.requestWithCredential=q(a.pc,a),Rg(a,e,"/auth/"+b,c,d))}
+function Jg(a){var b=P.get("redirect_request_id");if(b){var c=P.get("redirect_client_options");P.remove("redirect_request_id");P.remove("redirect_client_options");var d=[Dg,Fg],b={requestId:b,requestKey:ug(document.location.hash)},c=new ig(c,{},b);a.Re=!0;try{document.location.hash=document.location.hash.replace(/&__firebase_request_key=([a-zA-z0-9]*)/,"")}catch(e){}Rg(a,d,"/auth/session",c,function(){this.Re=!1}.bind(a))}}
+h.re=function(a,b){Qg(this);var c=kg(a);c.ab._method="POST";this.pc("/users",c,function(a,c){a?R(b,a):R(b,a,c)})};h.Se=function(a,b){var c=this;Qg(this);var d="/users/"+encodeURIComponent(a.email),e=kg(a);e.ab._method="DELETE";this.pc(d,e,function(a,d){!a&&d&&d.uid&&c.nb&&c.nb.uid&&c.nb.uid===d.uid&&Og(c);R(b,a)})};h.oe=function(a,b){Qg(this);var c="/users/"+encodeURIComponent(a.email)+"/password",d=kg(a);d.ab._method="PUT";d.ab.password=a.newPassword;this.pc(c,d,function(a){R(b,a)})};
+h.ne=function(a,b){Qg(this);var c="/users/"+encodeURIComponent(a.oldEmail)+"/email",d=kg(a);d.ab._method="PUT";d.ab.email=a.newEmail;d.ab.password=a.password;this.pc(c,d,function(a){R(b,a)})};h.Ue=function(a,b){Qg(this);var c="/users/"+encodeURIComponent(a.email)+"/password",d=kg(a);d.ab._method="POST";this.pc(c,d,function(a){R(b,a)})};h.pc=function(a,b,c){Tg(this,[Dg,Fg],a,b,c)};
+function Rg(a,b,c,d,e){Tg(a,b,c,d,function(b,c){!b&&c&&c.token&&c.uid?Ng(a,c.token,c,d.ld,function(a,b){a?R(e,a):R(e,null,b)}):R(e,b||Bg("UNKNOWN_ERROR"))})}
+function Tg(a,b,c,d,e){b=Pa(b,function(a){return"function"===typeof a.isAvailable&&a.isAvailable()});0===b.length?setTimeout(function(){R(e,Bg("TRANSPORT_UNAVAILABLE"))},0):(b=new (b.shift())(d.ce),d=ib(d.ab),d.v="js-2.2.7",d.transport=b.Bc(),d.suppress_status_codes=!0,a=vg()+"/"+a.H.Cb+c,b.open(a,d,function(a,b){if(a)R(e,a);else if(b&&b.error){var c=Error(b.error.message);c.code=b.error.code;c.details=b.error.details;R(e,c)}else R(e,null,b)}))}
+function Kg(a,b){var c=null!==a.nb||null!==b;a.nb=b;c&&a.de("auth_status",b);a.Ke(null!==b)}h.ze=function(a){J("auth_status"===a,'initial event must be of type "auth_status"');return this.Re?null:[this.nb]};function Qg(a){var b=a.H;if("firebaseio.com"!==b.domain&&"firebaseio-demo.com"!==b.domain&&"auth.firebase.com"===hg)throw Error("This custom Firebase server ('"+a.H.domain+"') does not support delegated login.");};function Ug(a){this.hc=a;this.Kd=[];this.Qb=0;this.pe=-1;this.Fb=null}function Vg(a,b,c){a.pe=b;a.Fb=c;a.pe<a.Qb&&(a.Fb(),a.Fb=null)}function Wg(a,b,c){for(a.Kd[b]=c;a.Kd[a.Qb];){var d=a.Kd[a.Qb];delete a.Kd[a.Qb];for(var e=0;e<d.length;++e)if(d[e]){var f=a;Cb(function(){f.hc(d[e])})}if(a.Qb===a.pe){a.Fb&&(clearTimeout(a.Fb),a.Fb(),a.Fb=null);break}a.Qb++}};function Xg(a,b,c){this.qe=a;this.f=Oc(a);this.ob=this.pb=0;this.Va=Ob(b);this.Vd=c;this.Gc=!1;this.gd=function(a){b.host!==b.Oa&&(a.ns=b.Cb);var c=[],f;for(f in a)a.hasOwnProperty(f)&&c.push(f+"="+a[f]);return(b.lb?"https://":"http://")+b.Oa+"/.lp?"+c.join("&")}}var Yg,Zg;
+Xg.prototype.open=function(a,b){this.gf=0;this.ka=b;this.zf=new Ug(a);this.zb=!1;var c=this;this.rb=setTimeout(function(){c.f("Timed out trying to connect.");c.ib();c.rb=null},Math.floor(3E4));Tc(function(){if(!c.zb){c.Ta=new $g(function(a,b,d,k,l){ah(c,arguments);if(c.Ta)if(c.rb&&(clearTimeout(c.rb),c.rb=null),c.Gc=!0,"start"==a)c.id=b,c.Ff=d;else if("close"===a)b?(c.Ta.Td=!1,Vg(c.zf,b,function(){c.ib()})):c.ib();else throw Error("Unrecognized command received: "+a);},function(a,b){ah(c,arguments);
+Wg(c.zf,a,b)},function(){c.ib()},c.gd);var a={start:"t"};a.ser=Math.floor(1E8*Math.random());c.Ta.fe&&(a.cb=c.Ta.fe);a.v="5";c.Vd&&(a.s=c.Vd);"undefined"!==typeof location&&location.href&&-1!==location.href.indexOf("firebaseio.com")&&(a.r="f");a=c.gd(a);c.f("Connecting via long-poll to "+a);bh(c.Ta,a,function(){})}})};
+Xg.prototype.start=function(){var a=this.Ta,b=this.Ff;a.rg=this.id;a.sg=b;for(a.ke=!0;ch(a););a=this.id;b=this.Ff;this.fc=document.createElement("iframe");var c={dframe:"t"};c.id=a;c.pw=b;this.fc.src=this.gd(c);this.fc.style.display="none";document.body.appendChild(this.fc)};
+Xg.isAvailable=function(){return Yg||!Zg&&"undefined"!==typeof document&&null!=document.createElement&&!("object"===typeof window&&window.chrome&&window.chrome.extension&&!/^chrome/.test(window.location.href))&&!("object"===typeof Windows&&"object"===typeof Windows.Ug)};h=Xg.prototype;h.Bd=function(){};h.cd=function(){this.zb=!0;this.Ta&&(this.Ta.close(),this.Ta=null);this.fc&&(document.body.removeChild(this.fc),this.fc=null);this.rb&&(clearTimeout(this.rb),this.rb=null)};
+h.ib=function(){this.zb||(this.f("Longpoll is closing itself"),this.cd(),this.ka&&(this.ka(this.Gc),this.ka=null))};h.close=function(){this.zb||(this.f("Longpoll is being closed."),this.cd())};h.send=function(a){a=B(a);this.pb+=a.length;Lb(this.Va,"bytes_sent",a.length);a=Kc(a);a=fb(a,!0);a=Xc(a,1840);for(var b=0;b<a.length;b++){var c=this.Ta;c.$c.push({Jg:this.gf,Rg:a.length,jf:a[b]});c.ke&&ch(c);this.gf++}};function ah(a,b){var c=B(b).length;a.ob+=c;Lb(a.Va,"bytes_received",c)}
+function $g(a,b,c,d){this.gd=d;this.jb=c;this.Oe=new eg;this.$c=[];this.se=Math.floor(1E8*Math.random());this.Td=!0;this.fe=Gc();window["pLPCommand"+this.fe]=a;window["pRTLPCB"+this.fe]=b;a=document.createElement("iframe");a.style.display="none";if(document.body){document.body.appendChild(a);try{a.contentWindow.document||Bb("No IE domain setting required")}catch(e){a.src="javascript:void((function(){document.open();document.domain='"+document.domain+"';document.close();})())"}}else throw"Document body has not initialized. Wait to initialize Firebase until after the document is ready.";
+a.contentDocument?a.gb=a.contentDocument:a.contentWindow?a.gb=a.contentWindow.document:a.document&&(a.gb=a.document);this.Ca=a;a="";this.Ca.src&&"javascript:"===this.Ca.src.substr(0,11)&&(a='<script>document.domain="'+document.domain+'";\x3c/script>');a="<html><body>"+a+"</body></html>";try{this.Ca.gb.open(),this.Ca.gb.write(a),this.Ca.gb.close()}catch(f){Bb("frame writing exception"),f.stack&&Bb(f.stack),Bb(f)}}
+$g.prototype.close=function(){this.ke=!1;if(this.Ca){this.Ca.gb.body.innerHTML="";var a=this;setTimeout(function(){null!==a.Ca&&(document.body.removeChild(a.Ca),a.Ca=null)},Math.floor(0))}var b=this.jb;b&&(this.jb=null,b())};
+function ch(a){if(a.ke&&a.Td&&a.Oe.count()<(0<a.$c.length?2:1)){a.se++;var b={};b.id=a.rg;b.pw=a.sg;b.ser=a.se;for(var b=a.gd(b),c="",d=0;0<a.$c.length;)if(1870>=a.$c[0].jf.length+30+c.length){var e=a.$c.shift(),c=c+"&seg"+d+"="+e.Jg+"&ts"+d+"="+e.Rg+"&d"+d+"="+e.jf;d++}else break;dh(a,b+c,a.se);return!0}return!1}function dh(a,b,c){function d(){a.Oe.remove(c);ch(a)}a.Oe.add(c,1);var e=setTimeout(d,Math.floor(25E3));bh(a,b,function(){clearTimeout(e);d()})}
+function bh(a,b,c){setTimeout(function(){try{if(a.Td){var d=a.Ca.gb.createElement("script");d.type="text/javascript";d.async=!0;d.src=b;d.onload=d.onreadystatechange=function(){var a=d.readyState;a&&"loaded"!==a&&"complete"!==a||(d.onload=d.onreadystatechange=null,d.parentNode&&d.parentNode.removeChild(d),c())};d.onerror=function(){Bb("Long-poll script failed to load: "+b);a.Td=!1;a.close()};a.Ca.gb.body.appendChild(d)}}catch(e){}},Math.floor(1))};var eh=null;"undefined"!==typeof MozWebSocket?eh=MozWebSocket:"undefined"!==typeof WebSocket&&(eh=WebSocket);function fh(a,b,c){this.qe=a;this.f=Oc(this.qe);this.frames=this.Jc=null;this.ob=this.pb=this.bf=0;this.Va=Ob(b);this.fb=(b.lb?"wss://":"ws://")+b.Oa+"/.ws?v=5";"undefined"!==typeof location&&location.href&&-1!==location.href.indexOf("firebaseio.com")&&(this.fb+="&r=f");b.host!==b.Oa&&(this.fb=this.fb+"&ns="+b.Cb);c&&(this.fb=this.fb+"&s="+c)}var gh;
+fh.prototype.open=function(a,b){this.jb=b;this.wg=a;this.f("Websocket connecting to "+this.fb);this.Gc=!1;Dc.set("previous_websocket_failure",!0);try{this.va=new eh(this.fb)}catch(c){this.f("Error instantiating WebSocket.");var d=c.message||c.data;d&&this.f(d);this.ib();return}var e=this;this.va.onopen=function(){e.f("Websocket connected.");e.Gc=!0};this.va.onclose=function(){e.f("Websocket connection was disconnected.");e.va=null;e.ib()};this.va.onmessage=function(a){if(null!==e.va)if(a=a.data,e.ob+=
+a.length,Lb(e.Va,"bytes_received",a.length),hh(e),null!==e.frames)ih(e,a);else{a:{J(null===e.frames,"We already have a frame buffer");if(6>=a.length){var b=Number(a);if(!isNaN(b)){e.bf=b;e.frames=[];a=null;break a}}e.bf=1;e.frames=[]}null!==a&&ih(e,a)}};this.va.onerror=function(a){e.f("WebSocket error. Closing connection.");(a=a.message||a.data)&&e.f(a);e.ib()}};fh.prototype.start=function(){};
+fh.isAvailable=function(){var a=!1;if("undefined"!==typeof navigator&&navigator.userAgent){var b=navigator.userAgent.match(/Android ([0-9]{0,}\.[0-9]{0,})/);b&&1<b.length&&4.4>parseFloat(b[1])&&(a=!0)}return!a&&null!==eh&&!gh};fh.responsesRequiredToBeHealthy=2;fh.healthyTimeout=3E4;h=fh.prototype;h.Bd=function(){Dc.remove("previous_websocket_failure")};function ih(a,b){a.frames.push(b);if(a.frames.length==a.bf){var c=a.frames.join("");a.frames=null;c=mb(c);a.wg(c)}}
+h.send=function(a){hh(this);a=B(a);this.pb+=a.length;Lb(this.Va,"bytes_sent",a.length);a=Xc(a,16384);1<a.length&&this.va.send(String(a.length));for(var b=0;b<a.length;b++)this.va.send(a[b])};h.cd=function(){this.zb=!0;this.Jc&&(clearInterval(this.Jc),this.Jc=null);this.va&&(this.va.close(),this.va=null)};h.ib=function(){this.zb||(this.f("WebSocket is closing itself"),this.cd(),this.jb&&(this.jb(this.Gc),this.jb=null))};h.close=function(){this.zb||(this.f("WebSocket is being closed"),this.cd())};
+function hh(a){clearInterval(a.Jc);a.Jc=setInterval(function(){a.va&&a.va.send("0");hh(a)},Math.floor(45E3))};function jh(a){kh(this,a)}var lh=[Xg,fh];function kh(a,b){var c=fh&&fh.isAvailable(),d=c&&!(Dc.uf||!0===Dc.get("previous_websocket_failure"));b.Tg&&(c||Q("wss:// URL used, but browser isn't known to support websockets. Trying anyway."),d=!0);if(d)a.ed=[fh];else{var e=a.ed=[];Yc(lh,function(a,b){b&&b.isAvailable()&&e.push(b)})}}function mh(a){if(0<a.ed.length)return a.ed[0];throw Error("No transports available");};function nh(a,b,c,d,e,f){this.id=a;this.f=Oc("c:"+this.id+":");this.hc=c;this.Vc=d;this.ka=e;this.Me=f;this.H=b;this.Jd=[];this.ef=0;this.Nf=new jh(b);this.Ua=0;this.f("Connection created");oh(this)}
+function oh(a){var b=mh(a.Nf);a.L=new b("c:"+a.id+":"+a.ef++,a.H);a.Qe=b.responsesRequiredToBeHealthy||0;var c=ph(a,a.L),d=qh(a,a.L);a.fd=a.L;a.bd=a.L;a.F=null;a.Ab=!1;setTimeout(function(){a.L&&a.L.open(c,d)},Math.floor(0));b=b.healthyTimeout||0;0<b&&(a.vd=setTimeout(function(){a.vd=null;a.Ab||(a.L&&102400<a.L.ob?(a.f("Connection exceeded healthy timeout but has received "+a.L.ob+" bytes. Marking connection healthy."),a.Ab=!0,a.L.Bd()):a.L&&10240<a.L.pb?a.f("Connection exceeded healthy timeout but has sent "+
+a.L.pb+" bytes. Leaving connection alive."):(a.f("Closing unhealthy connection after timeout."),a.close()))},Math.floor(b)))}function qh(a,b){return function(c){b===a.L?(a.L=null,c||0!==a.Ua?1===a.Ua&&a.f("Realtime connection lost."):(a.f("Realtime connection failed."),"s-"===a.H.Oa.substr(0,2)&&(Dc.remove("host:"+a.H.host),a.H.Oa=a.H.host)),a.close()):b===a.F?(a.f("Secondary connection lost."),c=a.F,a.F=null,a.fd!==c&&a.bd!==c||a.close()):a.f("closing an old connection")}}
+function ph(a,b){return function(c){if(2!=a.Ua)if(b===a.bd){var d=Vc("t",c);c=Vc("d",c);if("c"==d){if(d=Vc("t",c),"d"in c)if(c=c.d,"h"===d){var d=c.ts,e=c.v,f=c.h;a.Vd=c.s;Fc(a.H,f);0==a.Ua&&(a.L.start(),rh(a,a.L,d),"5"!==e&&Q("Protocol version mismatch detected"),c=a.Nf,(c=1<c.ed.length?c.ed[1]:null)&&sh(a,c))}else if("n"===d){a.f("recvd end transmission on primary");a.bd=a.F;for(c=0;c<a.Jd.length;++c)a.Fd(a.Jd[c]);a.Jd=[];th(a)}else"s"===d?(a.f("Connection shutdown command received. Shutting down..."),
+a.Me&&(a.Me(c),a.Me=null),a.ka=null,a.close()):"r"===d?(a.f("Reset packet received. New host: "+c),Fc(a.H,c),1===a.Ua?a.close():(uh(a),oh(a))):"e"===d?Pc("Server Error: "+c):"o"===d?(a.f("got pong on primary."),vh(a),wh(a)):Pc("Unknown control packet command: "+d)}else"d"==d&&a.Fd(c)}else if(b===a.F)if(d=Vc("t",c),c=Vc("d",c),"c"==d)"t"in c&&(c=c.t,"a"===c?xh(a):"r"===c?(a.f("Got a reset on secondary, closing it"),a.F.close(),a.fd!==a.F&&a.bd!==a.F||a.close()):"o"===c&&(a.f("got pong on secondary."),
+a.Lf--,xh(a)));else if("d"==d)a.Jd.push(c);else throw Error("Unknown protocol layer: "+d);else a.f("message on old connection")}}nh.prototype.Da=function(a){yh(this,{t:"d",d:a})};function th(a){a.fd===a.F&&a.bd===a.F&&(a.f("cleaning up and promoting a connection: "+a.F.qe),a.L=a.F,a.F=null)}
+function xh(a){0>=a.Lf?(a.f("Secondary connection is healthy."),a.Ab=!0,a.F.Bd(),a.F.start(),a.f("sending client ack on secondary"),a.F.send({t:"c",d:{t:"a",d:{}}}),a.f("Ending transmission on primary"),a.L.send({t:"c",d:{t:"n",d:{}}}),a.fd=a.F,th(a)):(a.f("sending ping on secondary."),a.F.send({t:"c",d:{t:"p",d:{}}}))}nh.prototype.Fd=function(a){vh(this);this.hc(a)};function vh(a){a.Ab||(a.Qe--,0>=a.Qe&&(a.f("Primary connection is healthy."),a.Ab=!0,a.L.Bd()))}
+function sh(a,b){a.F=new b("c:"+a.id+":"+a.ef++,a.H,a.Vd);a.Lf=b.responsesRequiredToBeHealthy||0;a.F.open(ph(a,a.F),qh(a,a.F));setTimeout(function(){a.F&&(a.f("Timed out trying to upgrade."),a.F.close())},Math.floor(6E4))}function rh(a,b,c){a.f("Realtime connection established.");a.L=b;a.Ua=1;a.Vc&&(a.Vc(c),a.Vc=null);0===a.Qe?(a.f("Primary connection is healthy."),a.Ab=!0):setTimeout(function(){wh(a)},Math.floor(5E3))}
+function wh(a){a.Ab||1!==a.Ua||(a.f("sending ping on primary."),yh(a,{t:"c",d:{t:"p",d:{}}}))}function yh(a,b){if(1!==a.Ua)throw"Connection is not connected";a.fd.send(b)}nh.prototype.close=function(){2!==this.Ua&&(this.f("Closing realtime connection."),this.Ua=2,uh(this),this.ka&&(this.ka(),this.ka=null))};function uh(a){a.f("Shutting down all connections");a.L&&(a.L.close(),a.L=null);a.F&&(a.F.close(),a.F=null);a.vd&&(clearTimeout(a.vd),a.vd=null)};function zh(a,b,c,d){this.id=Ah++;this.f=Oc("p:"+this.id+":");this.wf=this.De=!1;this.aa={};this.pa=[];this.Xc=0;this.Uc=[];this.ma=!1;this.$a=1E3;this.Cd=3E5;this.Gb=b;this.Tc=c;this.Ne=d;this.H=a;this.We=null;this.Qd={};this.Ig=0;this.mf=!0;this.Kc=this.Fe=null;Bh(this,0);Mf.ub().Eb("visible",this.zg,this);-1===a.host.indexOf("fblocal")&&Lf.ub().Eb("online",this.xg,this)}var Ah=0,Ch=0;h=zh.prototype;
+h.Da=function(a,b,c){var d=++this.Ig;a={r:d,a:a,b:b};this.f(B(a));J(this.ma,"sendRequest call when we're not connected not allowed.");this.Sa.Da(a);c&&(this.Qd[d]=c)};h.xf=function(a,b,c,d){var e=a.wa(),f=a.path.toString();this.f("Listen called for "+f+" "+e);this.aa[f]=this.aa[f]||{};J(!this.aa[f][e],"listen() called twice for same path/queryId.");a={J:d,ud:b,Fg:a,tag:c};this.aa[f][e]=a;this.ma&&Dh(this,a)};
+function Dh(a,b){var c=b.Fg,d=c.path.toString(),e=c.wa();a.f("Listen on "+d+" for "+e);var f={p:d};b.tag&&(f.q=ce(c.o),f.t=b.tag);f.h=b.ud();a.Da("q",f,function(f){var k=f.d,l=f.s;if(k&&"object"===typeof k&&u(k,"w")){var m=w(k,"w");ea(m)&&0<=Na(m,"no_index")&&Q("Using an unspecified index. Consider adding "+('".indexOn": "'+c.o.g.toString()+'"')+" at "+c.path.toString()+" to your security rules for better performance")}(a.aa[d]&&a.aa[d][e])===b&&(a.f("listen response",f),"ok"!==l&&Eh(a,d,e),b.J&&
+b.J(l,k))})}h.P=function(a,b,c){this.Fa={fg:a,nf:!1,yc:b,jd:c};this.f("Authenticating using credential: "+a);Fh(this);(b=40==a.length)||(a=ad(a).Ac,b="object"===typeof a&&!0===w(a,"admin"));b&&(this.f("Admin auth credential detected. Reducing max reconnect time."),this.Cd=3E4)};h.ee=function(a){delete this.Fa;this.ma&&this.Da("unauth",{},function(b){a(b.s,b.d)})};
+function Fh(a){var b=a.Fa;a.ma&&b&&a.Da("auth",{cred:b.fg},function(c){var d=c.s;c=c.d||"error";"ok"!==d&&a.Fa===b&&delete a.Fa;b.nf?"ok"!==d&&b.jd&&b.jd(d,c):(b.nf=!0,b.yc&&b.yc(d,c))})}h.Of=function(a,b){var c=a.path.toString(),d=a.wa();this.f("Unlisten called for "+c+" "+d);if(Eh(this,c,d)&&this.ma){var e=ce(a.o);this.f("Unlisten on "+c+" for "+d);c={p:c};b&&(c.q=e,c.t=b);this.Da("n",c)}};h.Le=function(a,b,c){this.ma?Gh(this,"o",a,b,c):this.Uc.push({Zc:a,action:"o",data:b,J:c})};
+h.Bf=function(a,b,c){this.ma?Gh(this,"om",a,b,c):this.Uc.push({Zc:a,action:"om",data:b,J:c})};h.Gd=function(a,b){this.ma?Gh(this,"oc",a,null,b):this.Uc.push({Zc:a,action:"oc",data:null,J:b})};function Gh(a,b,c,d,e){c={p:c,d:d};a.f("onDisconnect "+b,c);a.Da(b,c,function(a){e&&setTimeout(function(){e(a.s,a.d)},Math.floor(0))})}h.put=function(a,b,c,d){Hh(this,"p",a,b,c,d)};h.yf=function(a,b,c,d){Hh(this,"m",a,b,c,d)};
+function Hh(a,b,c,d,e,f){d={p:c,d:d};n(f)&&(d.h=f);a.pa.push({action:b,If:d,J:e});a.Xc++;b=a.pa.length-1;a.ma?Ih(a,b):a.f("Buffering put: "+c)}function Ih(a,b){var c=a.pa[b].action,d=a.pa[b].If,e=a.pa[b].J;a.pa[b].Gg=a.ma;a.Da(c,d,function(d){a.f(c+" response",d);delete a.pa[b];a.Xc--;0===a.Xc&&(a.pa=[]);e&&e(d.s,d.d)})}h.Te=function(a){this.ma&&(a={c:a},this.f("reportStats",a),this.Da("s",a,function(a){"ok"!==a.s&&this.f("reportStats","Error sending stats: "+a.d)}))};
+h.Fd=function(a){if("r"in a){this.f("from server: "+B(a));var b=a.r,c=this.Qd[b];c&&(delete this.Qd[b],c(a.b))}else{if("error"in a)throw"A server-side error has occurred: "+a.error;"a"in a&&(b=a.a,c=a.b,this.f("handleServerMessage",b,c),"d"===b?this.Gb(c.p,c.d,!1,c.t):"m"===b?this.Gb(c.p,c.d,!0,c.t):"c"===b?Jh(this,c.p,c.q):"ac"===b?(a=c.s,b=c.d,c=this.Fa,delete this.Fa,c&&c.jd&&c.jd(a,b)):"sd"===b?this.We?this.We(c):"msg"in c&&"undefined"!==typeof console&&console.log("FIREBASE: "+c.msg.replace("\n",
+"\nFIREBASE: ")):Pc("Unrecognized action received from server: "+B(b)+"\nAre you using the latest client?"))}};h.Vc=function(a){this.f("connection ready");this.ma=!0;this.Kc=(new Date).getTime();this.Ne({serverTimeOffset:a-(new Date).getTime()});this.mf&&(a={},a["sdk.js."+"2.2.7".replace(/\./g,"-")]=1,ng()&&(a["framework.cordova"]=1),this.Te(a));Kh(this);this.mf=!1;this.Tc(!0)};
+function Bh(a,b){J(!a.Sa,"Scheduling a connect when we're already connected/ing?");a.Sb&&clearTimeout(a.Sb);a.Sb=setTimeout(function(){a.Sb=null;Lh(a)},Math.floor(b))}h.zg=function(a){a&&!this.uc&&this.$a===this.Cd&&(this.f("Window became visible. Reducing delay."),this.$a=1E3,this.Sa||Bh(this,0));this.uc=a};h.xg=function(a){a?(this.f("Browser went online."),this.$a=1E3,this.Sa||Bh(this,0)):(this.f("Browser went offline. Killing connection."),this.Sa&&this.Sa.close())};
+h.Cf=function(){this.f("data client disconnected");this.ma=!1;this.Sa=null;for(var a=0;a<this.pa.length;a++){var b=this.pa[a];b&&"h"in b.If&&b.Gg&&(b.J&&b.J("disconnect"),delete this.pa[a],this.Xc--)}0===this.Xc&&(this.pa=[]);this.Qd={};Mh(this)&&(this.uc?this.Kc&&(3E4<(new Date).getTime()-this.Kc&&(this.$a=1E3),this.Kc=null):(this.f("Window isn't visible. Delaying reconnect."),this.$a=this.Cd,this.Fe=(new Date).getTime()),a=Math.max(0,this.$a-((new Date).getTime()-this.Fe)),a*=Math.random(),this.f("Trying to reconnect in "+
+a+"ms"),Bh(this,a),this.$a=Math.min(this.Cd,1.3*this.$a));this.Tc(!1)};function Lh(a){if(Mh(a)){a.f("Making a connection attempt");a.Fe=(new Date).getTime();a.Kc=null;var b=q(a.Fd,a),c=q(a.Vc,a),d=q(a.Cf,a),e=a.id+":"+Ch++;a.Sa=new nh(e,a.H,b,c,d,function(b){Q(b+" ("+a.H.toString()+")");a.wf=!0})}}h.yb=function(){this.De=!0;this.Sa?this.Sa.close():(this.Sb&&(clearTimeout(this.Sb),this.Sb=null),this.ma&&this.Cf())};h.qc=function(){this.De=!1;this.$a=1E3;this.Sa||Bh(this,0)};
+function Jh(a,b,c){c=c?Qa(c,function(a){return Wc(a)}).join("$"):"default";(a=Eh(a,b,c))&&a.J&&a.J("permission_denied")}function Eh(a,b,c){b=(new K(b)).toString();var d;n(a.aa[b])?(d=a.aa[b][c],delete a.aa[b][c],0===pa(a.aa[b])&&delete a.aa[b]):d=void 0;return d}function Kh(a){Fh(a);r(a.aa,function(b){r(b,function(b){Dh(a,b)})});for(var b=0;b<a.pa.length;b++)a.pa[b]&&Ih(a,b);for(;a.Uc.length;)b=a.Uc.shift(),Gh(a,b.action,b.Zc,b.data,b.J)}function Mh(a){var b;b=Lf.ub().ic;return!a.wf&&!a.De&&b};var V={lg:function(){Yg=gh=!0}};V.forceLongPolling=V.lg;V.mg=function(){Zg=!0};V.forceWebSockets=V.mg;V.Mg=function(a,b){a.k.Ra.We=b};V.setSecurityDebugCallback=V.Mg;V.Ye=function(a,b){a.k.Ye(b)};V.stats=V.Ye;V.Ze=function(a,b){a.k.Ze(b)};V.statsIncrementCounter=V.Ze;V.pd=function(a){return a.k.pd};V.dataUpdateCount=V.pd;V.pg=function(a,b){a.k.Ce=b};V.interceptServerData=V.pg;V.vg=function(a){new xg(a)};V.onPopupOpen=V.vg;V.Kg=function(a){hg=a};V.setAuthenticationServer=V.Kg;function S(a,b,c){this.B=a;this.V=b;this.g=c}S.prototype.K=function(){x("Firebase.DataSnapshot.val",0,0,arguments.length);return this.B.K()};S.prototype.val=S.prototype.K;S.prototype.lf=function(){x("Firebase.DataSnapshot.exportVal",0,0,arguments.length);return this.B.K(!0)};S.prototype.exportVal=S.prototype.lf;S.prototype.kg=function(){x("Firebase.DataSnapshot.exists",0,0,arguments.length);return!this.B.e()};S.prototype.exists=S.prototype.kg;
+S.prototype.w=function(a){x("Firebase.DataSnapshot.child",0,1,arguments.length);ga(a)&&(a=String(a));Yf("Firebase.DataSnapshot.child",a);var b=new K(a),c=this.V.w(b);return new S(this.B.oa(b),c,M)};S.prototype.child=S.prototype.w;S.prototype.Ha=function(a){x("Firebase.DataSnapshot.hasChild",1,1,arguments.length);Yf("Firebase.DataSnapshot.hasChild",a);var b=new K(a);return!this.B.oa(b).e()};S.prototype.hasChild=S.prototype.Ha;
+S.prototype.A=function(){x("Firebase.DataSnapshot.getPriority",0,0,arguments.length);return this.B.A().K()};S.prototype.getPriority=S.prototype.A;S.prototype.forEach=function(a){x("Firebase.DataSnapshot.forEach",1,1,arguments.length);A("Firebase.DataSnapshot.forEach",1,a,!1);if(this.B.N())return!1;var b=this;return!!this.B.U(this.g,function(c,d){return a(new S(d,b.V.w(c),M))})};S.prototype.forEach=S.prototype.forEach;
+S.prototype.td=function(){x("Firebase.DataSnapshot.hasChildren",0,0,arguments.length);return this.B.N()?!1:!this.B.e()};S.prototype.hasChildren=S.prototype.td;S.prototype.name=function(){Q("Firebase.DataSnapshot.name() being deprecated. Please use Firebase.DataSnapshot.key() instead.");x("Firebase.DataSnapshot.name",0,0,arguments.length);return this.key()};S.prototype.name=S.prototype.name;S.prototype.key=function(){x("Firebase.DataSnapshot.key",0,0,arguments.length);return this.V.key()};
+S.prototype.key=S.prototype.key;S.prototype.Db=function(){x("Firebase.DataSnapshot.numChildren",0,0,arguments.length);return this.B.Db()};S.prototype.numChildren=S.prototype.Db;S.prototype.lc=function(){x("Firebase.DataSnapshot.ref",0,0,arguments.length);return this.V};S.prototype.ref=S.prototype.lc;function Nh(a,b){this.H=a;this.Va=Ob(a);this.ea=new ub;this.Ed=1;this.Ra=null;b||0<=("object"===typeof window&&window.navigator&&window.navigator.userAgent||"").search(/googlebot|google webmaster tools|bingbot|yahoo! slurp|baiduspider|yandexbot|duckduckbot/i)?(this.ca=new Ae(this.H,q(this.Gb,this)),setTimeout(q(this.Tc,this,!0),0)):this.ca=this.Ra=new zh(this.H,q(this.Gb,this),q(this.Tc,this),q(this.Ne,this));this.Pg=Pb(a,q(function(){return new Jb(this.Va,this.ca)},this));this.tc=new Cf;this.Be=
+new nb;var c=this;this.zd=new gf({Xe:function(a,b,f,g){b=[];f=c.Be.j(a.path);f.e()||(b=jf(c.zd,new Ub(ze,a.path,f)),setTimeout(function(){g("ok")},0));return b},Zd:ba});Oh(this,"connected",!1);this.ka=new qc;this.P=new Hg(a,q(this.ca.P,this.ca),q(this.ca.ee,this.ca),q(this.Ke,this));this.pd=0;this.Ce=null;this.O=new gf({Xe:function(a,b,f,g){c.ca.xf(a,f,b,function(b,e){var f=g(b,e);zb(c.ea,a.path,f)});return[]},Zd:function(a,b){c.ca.Of(a,b)}})}h=Nh.prototype;
+h.toString=function(){return(this.H.lb?"https://":"http://")+this.H.host};h.name=function(){return this.H.Cb};function Ph(a){a=a.Be.j(new K(".info/serverTimeOffset")).K()||0;return(new Date).getTime()+a}function Qh(a){a=a={timestamp:Ph(a)};a.timestamp=a.timestamp||(new Date).getTime();return a}
+h.Gb=function(a,b,c,d){this.pd++;var e=new K(a);b=this.Ce?this.Ce(a,b):b;a=[];d?c?(b=na(b,function(a){return L(a)}),a=rf(this.O,e,b,d)):(b=L(b),a=nf(this.O,e,b,d)):c?(d=na(b,function(a){return L(a)}),a=mf(this.O,e,d)):(d=L(b),a=jf(this.O,new Ub(ze,e,d)));d=e;0<a.length&&(d=Rh(this,e));zb(this.ea,d,a)};h.Tc=function(a){Oh(this,"connected",a);!1===a&&Sh(this)};h.Ne=function(a){var b=this;Yc(a,function(a,d){Oh(b,d,a)})};h.Ke=function(a){Oh(this,"authenticated",a)};
+function Oh(a,b,c){b=new K("/.info/"+b);c=L(c);var d=a.Be;d.Sd=d.Sd.G(b,c);c=jf(a.zd,new Ub(ze,b,c));zb(a.ea,b,c)}h.Kb=function(a,b,c,d){this.f("set",{path:a.toString(),value:b,Xg:c});var e=Qh(this);b=L(b,c);var e=sc(b,e),f=this.Ed++,e=hf(this.O,a,e,f,!0);vb(this.ea,e);var g=this;this.ca.put(a.toString(),b.K(!0),function(b,c){var e="ok"===b;e||Q("set at "+a+" failed: "+b);e=lf(g.O,f,!e);zb(g.ea,a,e);Th(d,b,c)});e=Uh(this,a);Rh(this,e);zb(this.ea,e,[])};
+h.update=function(a,b,c){this.f("update",{path:a.toString(),value:b});var d=!0,e=Qh(this),f={};r(b,function(a,b){d=!1;var c=L(a);f[b]=sc(c,e)});if(d)Bb("update() called with empty data. Don't do anything."),Th(c,"ok");else{var g=this.Ed++,k=kf(this.O,a,f,g);vb(this.ea,k);var l=this;this.ca.yf(a.toString(),b,function(b,d){var e="ok"===b;e||Q("update at "+a+" failed: "+b);var e=lf(l.O,g,!e),f=a;0<e.length&&(f=Rh(l,a));zb(l.ea,f,e);Th(c,b,d)});b=Uh(this,a);Rh(this,b);zb(this.ea,a,[])}};
+function Sh(a){a.f("onDisconnectEvents");var b=Qh(a),c=[];rc(pc(a.ka,b),F,function(b,e){c=c.concat(jf(a.O,new Ub(ze,b,e)));var f=Uh(a,b);Rh(a,f)});a.ka=new qc;zb(a.ea,F,c)}h.Gd=function(a,b){var c=this;this.ca.Gd(a.toString(),function(d,e){"ok"===d&&gg(c.ka,a);Th(b,d,e)})};function Vh(a,b,c,d){var e=L(c);a.ca.Le(b.toString(),e.K(!0),function(c,g){"ok"===c&&a.ka.mc(b,e);Th(d,c,g)})}function Wh(a,b,c,d,e){var f=L(c,d);a.ca.Le(b.toString(),f.K(!0),function(c,d){"ok"===c&&a.ka.mc(b,f);Th(e,c,d)})}
+function Xh(a,b,c,d){var e=!0,f;for(f in c)e=!1;e?(Bb("onDisconnect().update() called with empty data. Don't do anything."),Th(d,"ok")):a.ca.Bf(b.toString(),c,function(e,f){if("ok"===e)for(var l in c){var m=L(c[l]);a.ka.mc(b.w(l),m)}Th(d,e,f)})}function Yh(a,b,c){c=".info"===O(b.path)?a.zd.Ob(b,c):a.O.Ob(b,c);xb(a.ea,b.path,c)}h.yb=function(){this.Ra&&this.Ra.yb()};h.qc=function(){this.Ra&&this.Ra.qc()};
+h.Ye=function(a){if("undefined"!==typeof console){a?(this.Yd||(this.Yd=new Ib(this.Va)),a=this.Yd.get()):a=this.Va.get();var b=Ra(sa(a),function(a,b){return Math.max(b.length,a)},0),c;for(c in a){for(var d=a[c],e=c.length;e<b+2;e++)c+=" ";console.log(c+d)}}};h.Ze=function(a){Lb(this.Va,a);this.Pg.Mf[a]=!0};h.f=function(a){var b="";this.Ra&&(b=this.Ra.id+":");Bb(b,arguments)};
+function Th(a,b,c){a&&Cb(function(){if("ok"==b)a(null);else{var d=(b||"error").toUpperCase(),e=d;c&&(e+=": "+c);e=Error(e);e.code=d;a(e)}})};function Zh(a,b,c,d,e){function f(){}a.f("transaction on "+b);var g=new U(a,b);g.Eb("value",f);c={path:b,update:c,J:d,status:null,Ef:Gc(),cf:e,Kf:0,ge:function(){g.gc("value",f)},je:null,Aa:null,md:null,nd:null,od:null};d=a.O.ua(b,void 0)||C;c.md=d;d=c.update(d.K());if(n(d)){Tf("transaction failed: Data returned ",d,c.path);c.status=1;e=Df(a.tc,b);var k=e.Ba()||[];k.push(c);Ef(e,k);"object"===typeof d&&null!==d&&u(d,".priority")?(k=w(d,".priority"),J(Rf(k),"Invalid priority returned by transaction. Priority must be a valid string, finite number, server value, or null.")):
+k=(a.O.ua(b)||C).A().K();e=Qh(a);d=L(d,k);e=sc(d,e);c.nd=d;c.od=e;c.Aa=a.Ed++;c=hf(a.O,b,e,c.Aa,c.cf);zb(a.ea,b,c);$h(a)}else c.ge(),c.nd=null,c.od=null,c.J&&(a=new S(c.md,new U(a,c.path),M),c.J(null,!1,a))}function $h(a,b){var c=b||a.tc;b||ai(a,c);if(null!==c.Ba()){var d=bi(a,c);J(0<d.length,"Sending zero length transaction queue");Sa(d,function(a){return 1===a.status})&&ci(a,c.path(),d)}else c.td()&&c.U(function(b){$h(a,b)})}
+function ci(a,b,c){for(var d=Qa(c,function(a){return a.Aa}),e=a.O.ua(b,d)||C,d=e,e=e.hash(),f=0;f<c.length;f++){var g=c[f];J(1===g.status,"tryToSendTransactionQueue_: items in queue should all be run.");g.status=2;g.Kf++;var k=N(b,g.path),d=d.G(k,g.nd)}d=d.K(!0);a.ca.put(b.toString(),d,function(d){a.f("transaction put response",{path:b.toString(),status:d});var e=[];if("ok"===d){d=[];for(f=0;f<c.length;f++){c[f].status=3;e=e.concat(lf(a.O,c[f].Aa));if(c[f].J){var g=c[f].od,k=new U(a,c[f].path);d.push(q(c[f].J,
+null,null,!0,new S(g,k,M)))}c[f].ge()}ai(a,Df(a.tc,b));$h(a);zb(a.ea,b,e);for(f=0;f<d.length;f++)Cb(d[f])}else{if("datastale"===d)for(f=0;f<c.length;f++)c[f].status=4===c[f].status?5:1;else for(Q("transaction at "+b.toString()+" failed: "+d),f=0;f<c.length;f++)c[f].status=5,c[f].je=d;Rh(a,b)}},e)}function Rh(a,b){var c=di(a,b),d=c.path(),c=bi(a,c);ei(a,c,d);return d}
+function ei(a,b,c){if(0!==b.length){for(var d=[],e=[],f=Qa(b,function(a){return a.Aa}),g=0;g<b.length;g++){var k=b[g],l=N(c,k.path),m=!1,v;J(null!==l,"rerunTransactionsUnderNode_: relativePath should not be null.");if(5===k.status)m=!0,v=k.je,e=e.concat(lf(a.O,k.Aa,!0));else if(1===k.status)if(25<=k.Kf)m=!0,v="maxretry",e=e.concat(lf(a.O,k.Aa,!0));else{var y=a.O.ua(k.path,f)||C;k.md=y;var I=b[g].update(y.K());n(I)?(Tf("transaction failed: Data returned ",I,k.path),l=L(I),"object"===typeof I&&null!=
+I&&u(I,".priority")||(l=l.da(y.A())),y=k.Aa,I=Qh(a),I=sc(l,I),k.nd=l,k.od=I,k.Aa=a.Ed++,Va(f,y),e=e.concat(hf(a.O,k.path,I,k.Aa,k.cf)),e=e.concat(lf(a.O,y,!0))):(m=!0,v="nodata",e=e.concat(lf(a.O,k.Aa,!0)))}zb(a.ea,c,e);e=[];m&&(b[g].status=3,setTimeout(b[g].ge,Math.floor(0)),b[g].J&&("nodata"===v?(k=new U(a,b[g].path),d.push(q(b[g].J,null,null,!1,new S(b[g].md,k,M)))):d.push(q(b[g].J,null,Error(v),!1,null))))}ai(a,a.tc);for(g=0;g<d.length;g++)Cb(d[g]);$h(a)}}
+function di(a,b){for(var c,d=a.tc;null!==(c=O(b))&&null===d.Ba();)d=Df(d,c),b=G(b);return d}function bi(a,b){var c=[];fi(a,b,c);c.sort(function(a,b){return a.Ef-b.Ef});return c}function fi(a,b,c){var d=b.Ba();if(null!==d)for(var e=0;e<d.length;e++)c.push(d[e]);b.U(function(b){fi(a,b,c)})}function ai(a,b){var c=b.Ba();if(c){for(var d=0,e=0;e<c.length;e++)3!==c[e].status&&(c[d]=c[e],d++);c.length=d;Ef(b,0<c.length?c:null)}b.U(function(b){ai(a,b)})}
+function Uh(a,b){var c=di(a,b).path(),d=Df(a.tc,b);Hf(d,function(b){gi(a,b)});gi(a,d);Gf(d,function(b){gi(a,b)});return c}
+function gi(a,b){var c=b.Ba();if(null!==c){for(var d=[],e=[],f=-1,g=0;g<c.length;g++)4!==c[g].status&&(2===c[g].status?(J(f===g-1,"All SENT items should be at beginning of queue."),f=g,c[g].status=4,c[g].je="set"):(J(1===c[g].status,"Unexpected transaction status in abort"),c[g].ge(),e=e.concat(lf(a.O,c[g].Aa,!0)),c[g].J&&d.push(q(c[g].J,null,Error("set"),!1,null))));-1===f?Ef(b,null):c.length=f+1;zb(a.ea,b.path(),e);for(g=0;g<d.length;g++)Cb(d[g])}};function W(){this.nc={};this.Pf=!1}ca(W);W.prototype.yb=function(){for(var a in this.nc)this.nc[a].yb()};W.prototype.interrupt=W.prototype.yb;W.prototype.qc=function(){for(var a in this.nc)this.nc[a].qc()};W.prototype.resume=W.prototype.qc;W.prototype.ue=function(){this.Pf=!0};function X(a,b){this.ad=a;this.qa=b}X.prototype.cancel=function(a){x("Firebase.onDisconnect().cancel",0,1,arguments.length);A("Firebase.onDisconnect().cancel",1,a,!0);this.ad.Gd(this.qa,a||null)};X.prototype.cancel=X.prototype.cancel;X.prototype.remove=function(a){x("Firebase.onDisconnect().remove",0,1,arguments.length);Zf("Firebase.onDisconnect().remove",this.qa);A("Firebase.onDisconnect().remove",1,a,!0);Vh(this.ad,this.qa,null,a)};X.prototype.remove=X.prototype.remove;
+X.prototype.set=function(a,b){x("Firebase.onDisconnect().set",1,2,arguments.length);Zf("Firebase.onDisconnect().set",this.qa);Sf("Firebase.onDisconnect().set",a,this.qa,!1);A("Firebase.onDisconnect().set",2,b,!0);Vh(this.ad,this.qa,a,b)};X.prototype.set=X.prototype.set;
+X.prototype.Kb=function(a,b,c){x("Firebase.onDisconnect().setWithPriority",2,3,arguments.length);Zf("Firebase.onDisconnect().setWithPriority",this.qa);Sf("Firebase.onDisconnect().setWithPriority",a,this.qa,!1);Vf("Firebase.onDisconnect().setWithPriority",2,b);A("Firebase.onDisconnect().setWithPriority",3,c,!0);Wh(this.ad,this.qa,a,b,c)};X.prototype.setWithPriority=X.prototype.Kb;
+X.prototype.update=function(a,b){x("Firebase.onDisconnect().update",1,2,arguments.length);Zf("Firebase.onDisconnect().update",this.qa);if(ea(a)){for(var c={},d=0;d<a.length;++d)c[""+d]=a[d];a=c;Q("Passing an Array to Firebase.onDisconnect().update() is deprecated. Use set() if you want to overwrite the existing data, or an Object with integer keys if you really do want to only update some of the children.")}Uf("Firebase.onDisconnect().update",a,this.qa);A("Firebase.onDisconnect().update",2,b,!0);
+Xh(this.ad,this.qa,a,b)};X.prototype.update=X.prototype.update;function Y(a,b,c,d){this.k=a;this.path=b;this.o=c;this.jc=d}
+function hi(a){var b=null,c=null;a.la&&(b=od(a));a.na&&(c=qd(a));if(a.g===Vd){if(a.la){if("[MIN_NAME]"!=nd(a))throw Error("Query: When ordering by key, you may only pass one argument to startAt(), endAt(), or equalTo().");if("string"!==typeof b)throw Error("Query: When ordering by key, the argument passed to startAt(), endAt(),or equalTo() must be a string.");}if(a.na){if("[MAX_NAME]"!=pd(a))throw Error("Query: When ordering by key, you may only pass one argument to startAt(), endAt(), or equalTo().");if("string"!==
+typeof c)throw Error("Query: When ordering by key, the argument passed to startAt(), endAt(),or equalTo() must be a string.");}}else if(a.g===M){if(null!=b&&!Rf(b)||null!=c&&!Rf(c))throw Error("Query: When ordering by priority, the first argument passed to startAt(), endAt(), or equalTo() must be a valid priority value (null, a number, or a string).");}else if(J(a.g instanceof Rd||a.g===Yd,"unknown index type."),null!=b&&"object"===typeof b||null!=c&&"object"===typeof c)throw Error("Query: First argument passed to startAt(), endAt(), or equalTo() cannot be an object.");
+}function ii(a){if(a.la&&a.na&&a.ia&&(!a.ia||""===a.Nb))throw Error("Query: Can't combine startAt(), endAt(), and limit(). Use limitToFirst() or limitToLast() instead.");}function ji(a,b){if(!0===a.jc)throw Error(b+": You can't combine multiple orderBy calls.");}Y.prototype.lc=function(){x("Query.ref",0,0,arguments.length);return new U(this.k,this.path)};Y.prototype.ref=Y.prototype.lc;
+Y.prototype.Eb=function(a,b,c,d){x("Query.on",2,4,arguments.length);Wf("Query.on",a,!1);A("Query.on",2,b,!1);var e=ki("Query.on",c,d);if("value"===a)Yh(this.k,this,new jd(b,e.cancel||null,e.Ma||null));else{var f={};f[a]=b;Yh(this.k,this,new kd(f,e.cancel,e.Ma))}return b};Y.prototype.on=Y.prototype.Eb;
+Y.prototype.gc=function(a,b,c){x("Query.off",0,3,arguments.length);Wf("Query.off",a,!0);A("Query.off",2,b,!0);lb("Query.off",3,c);var d=null,e=null;"value"===a?d=new jd(b||null,null,c||null):a&&(b&&(e={},e[a]=b),d=new kd(e,null,c||null));e=this.k;d=".info"===O(this.path)?e.zd.kb(this,d):e.O.kb(this,d);xb(e.ea,this.path,d)};Y.prototype.off=Y.prototype.gc;
+Y.prototype.Ag=function(a,b){function c(g){f&&(f=!1,e.gc(a,c),b.call(d.Ma,g))}x("Query.once",2,4,arguments.length);Wf("Query.once",a,!1);A("Query.once",2,b,!1);var d=ki("Query.once",arguments[2],arguments[3]),e=this,f=!0;this.Eb(a,c,function(b){e.gc(a,c);d.cancel&&d.cancel.call(d.Ma,b)})};Y.prototype.once=Y.prototype.Ag;
+Y.prototype.Ge=function(a){Q("Query.limit() being deprecated. Please use Query.limitToFirst() or Query.limitToLast() instead.");x("Query.limit",1,1,arguments.length);if(!ga(a)||Math.floor(a)!==a||0>=a)throw Error("Query.limit: First argument must be a positive integer.");if(this.o.ia)throw Error("Query.limit: Limit was already set (by another call to limit, limitToFirst, orlimitToLast.");var b=this.o.Ge(a);ii(b);return new Y(this.k,this.path,b,this.jc)};Y.prototype.limit=Y.prototype.Ge;
+Y.prototype.He=function(a){x("Query.limitToFirst",1,1,arguments.length);if(!ga(a)||Math.floor(a)!==a||0>=a)throw Error("Query.limitToFirst: First argument must be a positive integer.");if(this.o.ia)throw Error("Query.limitToFirst: Limit was already set (by another call to limit, limitToFirst, or limitToLast).");return new Y(this.k,this.path,this.o.He(a),this.jc)};Y.prototype.limitToFirst=Y.prototype.He;
+Y.prototype.Ie=function(a){x("Query.limitToLast",1,1,arguments.length);if(!ga(a)||Math.floor(a)!==a||0>=a)throw Error("Query.limitToLast: First argument must be a positive integer.");if(this.o.ia)throw Error("Query.limitToLast: Limit was already set (by another call to limit, limitToFirst, or limitToLast).");return new Y(this.k,this.path,this.o.Ie(a),this.jc)};Y.prototype.limitToLast=Y.prototype.Ie;
+Y.prototype.Bg=function(a){x("Query.orderByChild",1,1,arguments.length);if("$key"===a)throw Error('Query.orderByChild: "$key" is invalid. Use Query.orderByKey() instead.');if("$priority"===a)throw Error('Query.orderByChild: "$priority" is invalid. Use Query.orderByPriority() instead.');if("$value"===a)throw Error('Query.orderByChild: "$value" is invalid. Use Query.orderByValue() instead.');Xf("Query.orderByChild",1,a,!1);ji(this,"Query.orderByChild");var b=be(this.o,new Rd(a));hi(b);return new Y(this.k,
+this.path,b,!0)};Y.prototype.orderByChild=Y.prototype.Bg;Y.prototype.Cg=function(){x("Query.orderByKey",0,0,arguments.length);ji(this,"Query.orderByKey");var a=be(this.o,Vd);hi(a);return new Y(this.k,this.path,a,!0)};Y.prototype.orderByKey=Y.prototype.Cg;Y.prototype.Dg=function(){x("Query.orderByPriority",0,0,arguments.length);ji(this,"Query.orderByPriority");var a=be(this.o,M);hi(a);return new Y(this.k,this.path,a,!0)};Y.prototype.orderByPriority=Y.prototype.Dg;
+Y.prototype.Eg=function(){x("Query.orderByValue",0,0,arguments.length);ji(this,"Query.orderByValue");var a=be(this.o,Yd);hi(a);return new Y(this.k,this.path,a,!0)};Y.prototype.orderByValue=Y.prototype.Eg;
+Y.prototype.Xd=function(a,b){x("Query.startAt",0,2,arguments.length);Sf("Query.startAt",a,this.path,!0);Xf("Query.startAt",2,b,!0);var c=this.o.Xd(a,b);ii(c);hi(c);if(this.o.la)throw Error("Query.startAt: Starting point was already set (by another call to startAt or equalTo).");n(a)||(b=a=null);return new Y(this.k,this.path,c,this.jc)};Y.prototype.startAt=Y.prototype.Xd;
+Y.prototype.qd=function(a,b){x("Query.endAt",0,2,arguments.length);Sf("Query.endAt",a,this.path,!0);Xf("Query.endAt",2,b,!0);var c=this.o.qd(a,b);ii(c);hi(c);if(this.o.na)throw Error("Query.endAt: Ending point was already set (by another call to endAt or equalTo).");return new Y(this.k,this.path,c,this.jc)};Y.prototype.endAt=Y.prototype.qd;
+Y.prototype.hg=function(a,b){x("Query.equalTo",1,2,arguments.length);Sf("Query.equalTo",a,this.path,!1);Xf("Query.equalTo",2,b,!0);if(this.o.la)throw Error("Query.equalTo: Starting point was already set (by another call to endAt or equalTo).");if(this.o.na)throw Error("Query.equalTo: Ending point was already set (by another call to endAt or equalTo).");return this.Xd(a,b).qd(a,b)};Y.prototype.equalTo=Y.prototype.hg;
+Y.prototype.toString=function(){x("Query.toString",0,0,arguments.length);for(var a=this.path,b="",c=a.Y;c<a.n.length;c++)""!==a.n[c]&&(b+="/"+encodeURIComponent(String(a.n[c])));return this.k.toString()+(b||"/")};Y.prototype.toString=Y.prototype.toString;Y.prototype.wa=function(){var a=Wc(ce(this.o));return"{}"===a?"default":a};
+function ki(a,b,c){var d={cancel:null,Ma:null};if(b&&c)d.cancel=b,A(a,3,d.cancel,!0),d.Ma=c,lb(a,4,d.Ma);else if(b)if("object"===typeof b&&null!==b)d.Ma=b;else if("function"===typeof b)d.cancel=b;else throw Error(z(a,3,!0)+" must either be a cancel callback or a context object.");return d};var Z={};Z.vc=zh;Z.DataConnection=Z.vc;zh.prototype.Og=function(a,b){this.Da("q",{p:a},b)};Z.vc.prototype.simpleListen=Z.vc.prototype.Og;zh.prototype.gg=function(a,b){this.Da("echo",{d:a},b)};Z.vc.prototype.echo=Z.vc.prototype.gg;zh.prototype.interrupt=zh.prototype.yb;Z.Sf=nh;Z.RealTimeConnection=Z.Sf;nh.prototype.sendRequest=nh.prototype.Da;nh.prototype.close=nh.prototype.close;
+Z.og=function(a){var b=zh.prototype.put;zh.prototype.put=function(c,d,e,f){n(f)&&(f=a());b.call(this,c,d,e,f)};return function(){zh.prototype.put=b}};Z.hijackHash=Z.og;Z.Rf=Ec;Z.ConnectionTarget=Z.Rf;Z.wa=function(a){return a.wa()};Z.queryIdentifier=Z.wa;Z.qg=function(a){return a.k.Ra.aa};Z.listens=Z.qg;Z.ue=function(a){a.ue()};Z.forceRestClient=Z.ue;function U(a,b){var c,d,e;if(a instanceof Nh)c=a,d=b;else{x("new Firebase",1,2,arguments.length);d=Rc(arguments[0]);c=d.Qg;"firebase"===d.domain&&Qc(d.host+" is no longer supported. Please use <YOUR FIREBASE>.firebaseio.com instead");c&&"undefined"!=c||Qc("Cannot parse Firebase url. Please use https://<YOUR FIREBASE>.firebaseio.com");d.lb||"undefined"!==typeof window&&window.location&&window.location.protocol&&-1!==window.location.protocol.indexOf("https:")&&Q("Insecure Firebase access from a secure page. Please use https in calls to new Firebase().");
+c=new Ec(d.host,d.lb,c,"ws"===d.scheme||"wss"===d.scheme);d=new K(d.Zc);e=d.toString();var f;!(f=!p(c.host)||0===c.host.length||!Qf(c.Cb))&&(f=0!==e.length)&&(e&&(e=e.replace(/^\/*\.info(\/|$)/,"/")),f=!(p(e)&&0!==e.length&&!Of.test(e)));if(f)throw Error(z("new Firebase",1,!1)+'must be a valid firebase URL and the path can\'t contain ".", "#", "$", "[", or "]".');if(b)if(b instanceof W)e=b;else if(p(b))e=W.ub(),c.Ld=b;else throw Error("Expected a valid Firebase.Context for second argument to new Firebase()");
+else e=W.ub();f=c.toString();var g=w(e.nc,f);g||(g=new Nh(c,e.Pf),e.nc[f]=g);c=g}Y.call(this,c,d,$d,!1)}ma(U,Y);var li=U,mi=["Firebase"],ni=aa;mi[0]in ni||!ni.execScript||ni.execScript("var "+mi[0]);for(var oi;mi.length&&(oi=mi.shift());)!mi.length&&n(li)?ni[oi]=li:ni=ni[oi]?ni[oi]:ni[oi]={};U.prototype.name=function(){Q("Firebase.name() being deprecated. Please use Firebase.key() instead.");x("Firebase.name",0,0,arguments.length);return this.key()};U.prototype.name=U.prototype.name;
+U.prototype.key=function(){x("Firebase.key",0,0,arguments.length);return this.path.e()?null:vc(this.path)};U.prototype.key=U.prototype.key;U.prototype.w=function(a){x("Firebase.child",1,1,arguments.length);if(ga(a))a=String(a);else if(!(a instanceof K))if(null===O(this.path)){var b=a;b&&(b=b.replace(/^\/*\.info(\/|$)/,"/"));Yf("Firebase.child",b)}else Yf("Firebase.child",a);return new U(this.k,this.path.w(a))};U.prototype.child=U.prototype.w;
+U.prototype.parent=function(){x("Firebase.parent",0,0,arguments.length);var a=this.path.parent();return null===a?null:new U(this.k,a)};U.prototype.parent=U.prototype.parent;U.prototype.root=function(){x("Firebase.ref",0,0,arguments.length);for(var a=this;null!==a.parent();)a=a.parent();return a};U.prototype.root=U.prototype.root;
+U.prototype.set=function(a,b){x("Firebase.set",1,2,arguments.length);Zf("Firebase.set",this.path);Sf("Firebase.set",a,this.path,!1);A("Firebase.set",2,b,!0);this.k.Kb(this.path,a,null,b||null)};U.prototype.set=U.prototype.set;
+U.prototype.update=function(a,b){x("Firebase.update",1,2,arguments.length);Zf("Firebase.update",this.path);if(ea(a)){for(var c={},d=0;d<a.length;++d)c[""+d]=a[d];a=c;Q("Passing an Array to Firebase.update() is deprecated. Use set() if you want to overwrite the existing data, or an Object with integer keys if you really do want to only update some of the children.")}Uf("Firebase.update",a,this.path);A("Firebase.update",2,b,!0);this.k.update(this.path,a,b||null)};U.prototype.update=U.prototype.update;
+U.prototype.Kb=function(a,b,c){x("Firebase.setWithPriority",2,3,arguments.length);Zf("Firebase.setWithPriority",this.path);Sf("Firebase.setWithPriority",a,this.path,!1);Vf("Firebase.setWithPriority",2,b);A("Firebase.setWithPriority",3,c,!0);if(".length"===this.key()||".keys"===this.key())throw"Firebase.setWithPriority failed: "+this.key()+" is a read-only object.";this.k.Kb(this.path,a,b,c||null)};U.prototype.setWithPriority=U.prototype.Kb;
+U.prototype.remove=function(a){x("Firebase.remove",0,1,arguments.length);Zf("Firebase.remove",this.path);A("Firebase.remove",1,a,!0);this.set(null,a)};U.prototype.remove=U.prototype.remove;
+U.prototype.transaction=function(a,b,c){x("Firebase.transaction",1,3,arguments.length);Zf("Firebase.transaction",this.path);A("Firebase.transaction",1,a,!1);A("Firebase.transaction",2,b,!0);if(n(c)&&"boolean"!=typeof c)throw Error(z("Firebase.transaction",3,!0)+"must be a boolean.");if(".length"===this.key()||".keys"===this.key())throw"Firebase.transaction failed: "+this.key()+" is a read-only object.";"undefined"===typeof c&&(c=!0);Zh(this.k,this.path,a,b||null,c)};U.prototype.transaction=U.prototype.transaction;
+U.prototype.Lg=function(a,b){x("Firebase.setPriority",1,2,arguments.length);Zf("Firebase.setPriority",this.path);Vf("Firebase.setPriority",1,a);A("Firebase.setPriority",2,b,!0);this.k.Kb(this.path.w(".priority"),a,null,b)};U.prototype.setPriority=U.prototype.Lg;
+U.prototype.push=function(a,b){x("Firebase.push",0,2,arguments.length);Zf("Firebase.push",this.path);Sf("Firebase.push",a,this.path,!0);A("Firebase.push",2,b,!0);var c=Ph(this.k),c=Kf(c),c=this.w(c);"undefined"!==typeof a&&null!==a&&c.set(a,b);return c};U.prototype.push=U.prototype.push;U.prototype.jb=function(){Zf("Firebase.onDisconnect",this.path);return new X(this.k,this.path)};U.prototype.onDisconnect=U.prototype.jb;
+U.prototype.P=function(a,b,c){Q("FirebaseRef.auth() being deprecated. Please use FirebaseRef.authWithCustomToken() instead.");x("Firebase.auth",1,3,arguments.length);$f("Firebase.auth",a);A("Firebase.auth",2,b,!0);A("Firebase.auth",3,b,!0);Ng(this.k.P,a,{},{remember:"none"},b,c)};U.prototype.auth=U.prototype.P;U.prototype.ee=function(a){x("Firebase.unauth",0,1,arguments.length);A("Firebase.unauth",1,a,!0);Og(this.k.P,a)};U.prototype.unauth=U.prototype.ee;
+U.prototype.we=function(){x("Firebase.getAuth",0,0,arguments.length);return this.k.P.we()};U.prototype.getAuth=U.prototype.we;U.prototype.ug=function(a,b){x("Firebase.onAuth",1,2,arguments.length);A("Firebase.onAuth",1,a,!1);lb("Firebase.onAuth",2,b);this.k.P.Eb("auth_status",a,b)};U.prototype.onAuth=U.prototype.ug;U.prototype.tg=function(a,b){x("Firebase.offAuth",1,2,arguments.length);A("Firebase.offAuth",1,a,!1);lb("Firebase.offAuth",2,b);this.k.P.gc("auth_status",a,b)};U.prototype.offAuth=U.prototype.tg;
+U.prototype.Wf=function(a,b,c){x("Firebase.authWithCustomToken",2,3,arguments.length);$f("Firebase.authWithCustomToken",a);A("Firebase.authWithCustomToken",2,b,!1);cg("Firebase.authWithCustomToken",3,c,!0);Ng(this.k.P,a,{},c||{},b)};U.prototype.authWithCustomToken=U.prototype.Wf;U.prototype.Xf=function(a,b,c){x("Firebase.authWithOAuthPopup",2,3,arguments.length);bg("Firebase.authWithOAuthPopup",a);A("Firebase.authWithOAuthPopup",2,b,!1);cg("Firebase.authWithOAuthPopup",3,c,!0);Sg(this.k.P,a,c,b)};
+U.prototype.authWithOAuthPopup=U.prototype.Xf;U.prototype.Yf=function(a,b,c){x("Firebase.authWithOAuthRedirect",2,3,arguments.length);bg("Firebase.authWithOAuthRedirect",a);A("Firebase.authWithOAuthRedirect",2,b,!1);cg("Firebase.authWithOAuthRedirect",3,c,!0);var d=this.k.P;Qg(d);var e=[zg],f=kg(c);"anonymous"===a||"firebase"===a?R(b,Bg("TRANSPORT_UNAVAILABLE")):(P.set("redirect_client_options",f.ld),Rg(d,e,"/auth/"+a,f,b))};U.prototype.authWithOAuthRedirect=U.prototype.Yf;
+U.prototype.Zf=function(a,b,c,d){x("Firebase.authWithOAuthToken",3,4,arguments.length);bg("Firebase.authWithOAuthToken",a);A("Firebase.authWithOAuthToken",3,c,!1);cg("Firebase.authWithOAuthToken",4,d,!0);p(b)?(ag("Firebase.authWithOAuthToken",2,b),Pg(this.k.P,a+"/token",{access_token:b},d,c)):(cg("Firebase.authWithOAuthToken",2,b,!1),Pg(this.k.P,a+"/token",b,d,c))};U.prototype.authWithOAuthToken=U.prototype.Zf;
+U.prototype.Vf=function(a,b){x("Firebase.authAnonymously",1,2,arguments.length);A("Firebase.authAnonymously",1,a,!1);cg("Firebase.authAnonymously",2,b,!0);Pg(this.k.P,"anonymous",{},b,a)};U.prototype.authAnonymously=U.prototype.Vf;
+U.prototype.$f=function(a,b,c){x("Firebase.authWithPassword",2,3,arguments.length);cg("Firebase.authWithPassword",1,a,!1);dg("Firebase.authWithPassword",a,"email");dg("Firebase.authWithPassword",a,"password");A("Firebase.authWithPassword",2,b,!1);cg("Firebase.authWithPassword",3,c,!0);Pg(this.k.P,"password",a,c,b)};U.prototype.authWithPassword=U.prototype.$f;
+U.prototype.re=function(a,b){x("Firebase.createUser",2,2,arguments.length);cg("Firebase.createUser",1,a,!1);dg("Firebase.createUser",a,"email");dg("Firebase.createUser",a,"password");A("Firebase.createUser",2,b,!1);this.k.P.re(a,b)};U.prototype.createUser=U.prototype.re;U.prototype.Se=function(a,b){x("Firebase.removeUser",2,2,arguments.length);cg("Firebase.removeUser",1,a,!1);dg("Firebase.removeUser",a,"email");dg("Firebase.removeUser",a,"password");A("Firebase.removeUser",2,b,!1);this.k.P.Se(a,b)};
+U.prototype.removeUser=U.prototype.Se;U.prototype.oe=function(a,b){x("Firebase.changePassword",2,2,arguments.length);cg("Firebase.changePassword",1,a,!1);dg("Firebase.changePassword",a,"email");dg("Firebase.changePassword",a,"oldPassword");dg("Firebase.changePassword",a,"newPassword");A("Firebase.changePassword",2,b,!1);this.k.P.oe(a,b)};U.prototype.changePassword=U.prototype.oe;
+U.prototype.ne=function(a,b){x("Firebase.changeEmail",2,2,arguments.length);cg("Firebase.changeEmail",1,a,!1);dg("Firebase.changeEmail",a,"oldEmail");dg("Firebase.changeEmail",a,"newEmail");dg("Firebase.changeEmail",a,"password");A("Firebase.changeEmail",2,b,!1);this.k.P.ne(a,b)};U.prototype.changeEmail=U.prototype.ne;
+U.prototype.Ue=function(a,b){x("Firebase.resetPassword",2,2,arguments.length);cg("Firebase.resetPassword",1,a,!1);dg("Firebase.resetPassword",a,"email");A("Firebase.resetPassword",2,b,!1);this.k.P.Ue(a,b)};U.prototype.resetPassword=U.prototype.Ue;U.goOffline=function(){x("Firebase.goOffline",0,0,arguments.length);W.ub().yb()};U.goOnline=function(){x("Firebase.goOnline",0,0,arguments.length);W.ub().qc()};
+function Nc(a,b){J(!b||!0===a||!1===a,"Can't turn on custom loggers persistently.");!0===a?("undefined"!==typeof console&&("function"===typeof console.log?Ab=q(console.log,console):"object"===typeof console.log&&(Ab=function(a){console.log(a)})),b&&P.set("logging_enabled",!0)):a?Ab=a:(Ab=null,P.remove("logging_enabled"))}U.enableLogging=Nc;U.ServerValue={TIMESTAMP:{".sv":"timestamp"}};U.SDK_VERSION="2.2.7";U.INTERNAL=V;U.Context=W;U.TEST_ACCESS=Z;})();
+
diff --git a/polymer_1.0.4/bower_components/font-roboto/.bower.json b/polymer_1.0.4/bower_components/font-roboto/.bower.json
new file mode 100644
index 0000000..8bf1d8d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/font-roboto/.bower.json
@@ -0,0 +1,13 @@
+{
+ "name": "font-roboto",
+ "homepage": "https://github.com/PolymerElements/font-roboto",
+ "_release": "6f59e45de7",
+ "_resolution": {
+ "type": "branch",
+ "branch": "master",
+ "commit": "6f59e45de7dd0291fb8d698bf003defba6bd924d"
+ },
+ "_source": "git://github.com/PolymerElements/font-roboto.git",
+ "_target": "master",
+ "_originalSource": "PolymerElements/font-roboto"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/font-roboto/README.md b/polymer_1.0.4/bower_components/font-roboto/README.md
new file mode 100644
index 0000000..61c6394
--- /dev/null
+++ b/polymer_1.0.4/bower_components/font-roboto/README.md
@@ -0,0 +1 @@
+# font-roboto
diff --git a/polymer_1.0.4/bower_components/font-roboto/roboto.html b/polymer_1.0.4/bower_components/font-roboto/roboto.html
new file mode 100644
index 0000000..848d1da
--- /dev/null
+++ b/polymer_1.0.4/bower_components/font-roboto/roboto.html
@@ -0,0 +1,10 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,500,500italic,700,700italic">
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/.bower.json b/polymer_1.0.4/bower_components/ga-api-utils/.bower.json
new file mode 100644
index 0000000..7abf4ea
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/.bower.json
@@ -0,0 +1,14 @@
+{
+ "name": "ga-api-utils",
+ "homepage": "https://github.com/googleanalytics/javascript-api-utils",
+ "version": "0.2.0",
+ "_release": "0.2.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "0.2.0",
+ "commit": "02695569180f830a1e43d32a112cda32843641cc"
+ },
+ "_source": "git://github.com/googleanalytics/javascript-api-utils.git",
+ "_target": "^0.2.0",
+ "_originalSource": "googleanalytics/javascript-api-utils"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/.gitignore b/polymer_1.0.4/bower_components/ga-api-utils/.gitignore
new file mode 100644
index 0000000..0558273
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/.gitignore
@@ -0,0 +1,5 @@
+# OS or Editor folders
+.DS_Store
+
+# Depedencies
+node_modules
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/.jshintrc b/polymer_1.0.4/bower_components/ga-api-utils/.jshintrc
new file mode 100644
index 0000000..0d21e96
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/.jshintrc
@@ -0,0 +1,7 @@
+{
+ "browser": true,
+ "boss": true,
+ "expr": true,
+ "node": true,
+ "quotmark": "single"
+}
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/CHANGELOG.md b/polymer_1.0.4/bower_components/ga-api-utils/CHANGELOG.md
new file mode 100644
index 0000000..eaad9ac
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/CHANGELOG.md
@@ -0,0 +1,3 @@
+### 0.1.0 (October 16, 2014)
+
+* Initial release.
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/CONTRIBUTING.md b/polymer_1.0.4/bower_components/ga-api-utils/CONTRIBUTING.md
new file mode 100644
index 0000000..1ba8539
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/CONTRIBUTING.md
@@ -0,0 +1,24 @@
+Want to contribute? Great! First, read this page (including the small print at the end).
+
+### Before you contribute
+Before we can use your code, you must sign the
+[Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1)
+(CLA), which you can do online. The CLA is necessary mainly because you own the
+copyright to your changes, even after your contribution becomes part of our
+codebase, so we need your permission to use and distribute your code. We also
+need to be sure of various other things—for instance that you'll tell us if you
+know that your code infringes on other people's patents. You don't have to sign
+the CLA until after you've submitted your code for review and a member has
+approved it, but you must do it before we can put your code into our codebase.
+Before you start working on a larger contribution, you should get in touch with
+us first through the issue tracker with your idea so that we can help out and
+possibly guide you. Coordinating up front makes it much easier to avoid
+frustration later on.
+
+### Code reviews
+All submissions, including submissions by project members, require review. We
+use Github pull requests for this purpose.
+
+### The small print
+Contributions made by corporations are covered by a different agreement than
+the one above, the Software Grant and Corporate Contributor License Agreement.
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/LICENSE b/polymer_1.0.4/bower_components/ga-api-utils/LICENSE
new file mode 100644
index 0000000..a6fe877
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2015 Google Inc. All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/Makefile b/polymer_1.0.4/bower_components/ga-api-utils/Makefile
new file mode 100644
index 0000000..d1e18da
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/Makefile
@@ -0,0 +1,22 @@
+bin_path := ./node_modules/.bin
+
+all: build
+
+install:
+ @ npm install
+
+lint:
+ @ $(bin_path)/jshint --show-non-errors lib test
+
+test:
+ @ $(bin_path)/mocha --reporter spec --recursive test
+
+test_debug:
+ @ $(bin_path)/mocha --debug-brk --reporter spec --recursive test
+
+build: install lint test
+ @ $(bin_path)/browserify lib \
+ -s gaApiUtils \
+ | $(bin_path)/uglifyjs -o build/ga-api-utils.js
+
+.PHONY: all install lint test test_debug build
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/README.md b/polymer_1.0.4/bower_components/ga-api-utils/README.md
new file mode 100644
index 0000000..6ea8e7b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/README.md
@@ -0,0 +1,51 @@
+Google Analytics JavaScript API Utilities
+=========================================
+
+This repository is a place to find utility modules for interacting with the Google Analytics APIs. The source files are available as node-style modules (in the [/lib](https://github.com/googleanalytics/javascript-api-utils/tree/master/lib) folder) and as standalone browser scripts (in the [build](https://github.com/googleanalytics/javascript-api-utils/tree/master/build) folder). The browser versions are built with [browserify](http://browserify.org/) and can be accessed from the global object `window.gaApiUtils` or by using an AMD module loader.
+
+## Installation
+
+```sh
+# Install via npm
+npm install git+https://git@github.com/googleanalytics/javascript-api-utils.git
+
+# Install via bower
+npm install googleanalytics/javascript-api-utils
+```
+
+## Usage Examples:
+
+**Note**: all the examples below assume the user is authenticated and `gapi.client.analytics` is loaded on the page using the [Google APIs client library](https://developers.google.com/api-client-library/javascript/start/start-js).
+
+The easiest way to load the client library and authorize the current user is to use the [Google Analytics Embed API](https://developers.google.com/analytics/devguides/reporting/embed/).
+
+### Account Summaries
+
+```js
+var accountSummaries = require('javascript-api-utils/lib/account-summaries');
+
+// Log a list of all the user's Google Analytics views to the console.
+accountSummaries.get().then(function(summaries) {
+ console.log(summaries.allViews());
+});
+```
+
+To see a demo of the account summaries module, run the [demo file](https://github.com/googleanalytics/javascript-api-utils/blob/master/build/demo.html) on a local server on port 8080.
+
+## Contributing
+
+If you'd like to contribute modules to this repository please follow the [Google JavaScript style guide](https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml) and make sure to include relevant tests with any pull requests. Also include demos where appropriate.
+
+### Running the tests
+
+```sh
+make test
+```
+
+### Building the browser versions
+
+```sh
+make build
+```
+
+
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/build/demo.html b/polymer_1.0.4/bower_components/ga-api-utils/build/demo.html
new file mode 100644
index 0000000..23ec919
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/build/demo.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Google Analytics JavaScript API Untilities Demo</title>
+</head>
+<body>
+
+<div id="embed-api-auth-container"></div>
+<pre id="account-summaries-output"></pre>
+
+<!-- Load the account summaries module, it will be at:
+ `window.gaApiUtils.accountSummaries` -->
+<script src="ga-api-utils.js"></script>
+
+<script>
+// Use the Embed API to authorize the user.
+(function(w,d,s,g,js,fs){
+ g=w.gapi||(w.gapi={});g.analytics={q:[],ready:function(f){this.q.push(f);}};
+ js=d.createElement(s);fs=d.getElementsByTagName(s)[0];
+ js.src='https://apis.google.com/js/platform.js';
+ fs.parentNode.insertBefore(js,fs);js.onload=function(){g.load('analytics');};
+}(window,document,'script'));
+
+gapi.analytics.ready(function() {
+
+ // Run the demo once the user is authorized.
+ gapi.analytics.auth.on('success', gaApiUtilsDemo);
+
+ // This client ID will work at http://localhost:8080.
+ // To run this demo on other hosts or ports, you must use your own client ID.
+ gapi.analytics.auth.authorize({
+ container: 'embed-api-auth-container',
+ clientid: '793177639245-olst43lspv93vkoql0b9l26hmpf9kfmv.apps.googleusercontent.com',
+ });
+});
+
+function gaApiUtilsDemo() {
+ var output = document.getElementById('account-summaries-output');
+ gaApiUtils.accountSummaries.get().then(
+ function onResolved(summaries) {
+ output.innerText = JSON.stringify(summaries.all(), null, 2);
+ },
+ function onRejected(error) {
+ output.innerText = error.message;
+ }
+ );
+}
+</script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/build/ga-api-utils.js b/polymer_1.0.4/bower_components/ga-api-utils/build/ga-api-utils.js
new file mode 100644
index 0000000..a25822d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/build/ga-api-utils.js
@@ -0,0 +1 @@
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.gaApiUtils=e()}}(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){function AccountSummaries(accounts){this.accounts_=accounts;this.webProperties_=[];this.profiles_=[];this.accountsById_={};this.webPropertiesById_=this.propertiesById_={};this.profilesById_=this.viewsById_={};for(var i=0,account;account=this.accounts_[i];i++){this.accountsById_[account.id]={self:account};if(!account.webProperties)continue;alias(account,"webProperties","properties");for(var j=0,webProperty;webProperty=account.webProperties[j];j++){this.webProperties_.push(webProperty);this.webPropertiesById_[webProperty.id]={self:webProperty,parent:account};if(!webProperty.profiles)continue;alias(webProperty,"profiles","views");for(var k=0,profile;profile=webProperty.profiles[k];k++){this.profiles_.push(profile);this.profilesById_[profile.id]={self:profile,parent:webProperty,grandParent:account}}}}}AccountSummaries.prototype.all=function(){return this.accounts_};alias(AccountSummaries.prototype,"all","allAccounts");AccountSummaries.prototype.allWebProperties=function(){return this.webProperties_};alias(AccountSummaries.prototype,"allWebProperties","allProperties");AccountSummaries.prototype.allProfiles=function(){return this.profiles_};alias(AccountSummaries.prototype,"allProfiles","allViews");AccountSummaries.prototype.get=function(obj){if(!!obj.accountId+!!obj.webPropertyId+!!obj.propertyId+!!obj.profileId+!!obj.viewId>1){throw new Error("get() only accepts an object with a single "+'property: either "accountId", "webPropertyId", "propertyId", '+'"profileId" or "viewId"')}return this.getProfile(obj.profileId||obj.viewId)||this.getWebProperty(obj.webPropertyId||obj.propertyId)||this.getAccount(obj.accountId)};AccountSummaries.prototype.getAccount=function(accountId){return this.accountsById_[accountId]&&this.accountsById_[accountId].self};AccountSummaries.prototype.getWebProperty=function(webPropertyId){return this.webPropertiesById_[webPropertyId]&&this.webPropertiesById_[webPropertyId].self};alias(AccountSummaries.prototype,"getWebProperty","getProperty");AccountSummaries.prototype.getProfile=function(profileId){return this.profilesById_[profileId]&&this.profilesById_[profileId].self};alias(AccountSummaries.prototype,"getProfile","getView");AccountSummaries.prototype.getAccountByProfileId=function(profileId){return this.profilesById_[profileId]&&this.profilesById_[profileId].grandParent};alias(AccountSummaries.prototype,"getAccountByProfileId","getAccountByViewId");AccountSummaries.prototype.getWebPropertyByProfileId=function(profileId){return this.profilesById_[profileId]&&this.profilesById_[profileId].parent};alias(AccountSummaries.prototype,"getWebPropertyByProfileId","getPropertyByViewId");AccountSummaries.prototype.getAccountByWebPropertyId=function(webPropertyId){return this.webPropertiesById_[webPropertyId]&&this.webPropertiesById_[webPropertyId].parent};alias(AccountSummaries.prototype,"getAccountByWebPropertyId","getAccountByPropertyId");function alias(object,referenceProp,aliasName){if(Object.defineProperty){Object.defineProperty(object,aliasName,{get:function(){return object[referenceProp]}})}else{object[aliasName]=object[referenceProp]}}module.exports=AccountSummaries},{}],2:[function(require,module,exports){var AccountSummaries=require("./account-summaries");var cache;function requestAccountSummaries(){var promise=gapi.client.analytics.management.accountSummaries.list().then(function(resp){return resp});return new promise.constructor(function(resolve,reject){var summaries=[];promise.then(function fn(resp){var result=resp.result;if(result.items){summaries=summaries.concat(result.items)}else{reject(new Error("You do not have any Google Analytics accounts. "+"Go to http://google.com/analytics to sign up."))}if(result.startIndex+result.itemsPerPage<=result.totalResults){gapi.client.analytics.management.accountSummaries.list({"start-index":result.startIndex+result.itemsPerPage}).then(fn)}else{resolve(new AccountSummaries(summaries))}}).then(null,reject)})}module.exports={get:function(noCache){if(noCache)cache=null;return cache||(cache=requestAccountSummaries())}}},{"./account-summaries":1}],3:[function(require,module,exports){var Metadata=require("./metadata");var cache;function requestMetadata(){var promise=gapi.client.analytics.metadata.columns.list({reportType:"ga"}).then(function(resp){return resp});return new promise.constructor(function(resolve,reject){promise.then(function(resp){resolve(new Metadata(resp.result.items))}).then(null,reject)})}module.exports={get:function(noCache){if(noCache)cache=null;return cache||(cache=requestMetadata())}}},{"./metadata":4}],4:[function(require,module,exports){function Metadata(columns){this._columns=columns;this._metrics=[];this._dimensions=[];this._ids={};this._columns.forEach(function(column){this._ids[column.id]=column.attributes;if(column.attributes.type=="METRIC"){this._metrics.push(column)}else if(column.attributes.type=="DIMENSION"){this._dimensions.push(column)}}.bind(this))}Metadata.prototype.all=function(status){return!status?this._columns:this._columns.filter(function(column){return column.attributes.status.toLowerCase()===status.toLowerCase()})};Metadata.prototype.allMetrics=function(status){return!status?this._metrics:this._metrics.filter(function(metric){return metric.attributes.status.toLowerCase()===status.toLowerCase()})};Metadata.prototype.allDimensions=function(status){return!status?this._dimensions:this._dimensions.filter(function(dimension){return dimension.attributes.status.toLowerCase()===status.toLowerCase()})};Metadata.prototype.get=function(id){return this._ids[id]};module.exports=Metadata},{}],5:[function(require,module,exports){module.exports={accountSummaries:require("./account-summaries"),metadata:require("./metadata")}},{"./account-summaries":2,"./metadata":3}]},{},[5])(5)});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/lib/account-summaries/account-summaries.js b/polymer_1.0.4/bower_components/ga-api-utils/lib/account-summaries/account-summaries.js
new file mode 100644
index 0000000..3e6113e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/lib/account-summaries/account-summaries.js
@@ -0,0 +1,261 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+/**
+ * @constuctor AccountSummaries
+ *
+ * Takes an array of accounts and writes the following new properties:
+ * `accounts_`, `webProperties_`, `profiles_`, `accountsById_`,
+ * `webPropertiesById_`, and `profilesById_`.
+ * Each of the ___ById properties contains an array of objects where the
+ * key is the entity ID and the value is an object containing the entity and
+ * the entity's parents. For example, an object in the `profilesById_` array
+ * might look like this:
+ * {
+ * "1234": {
+ * self: {...},
+ * parent: {...},
+ * grandParent: {...}
+ * }
+ * }
+ *
+ * It also aliases the properties `webProperties` to `properties` and
+ * `profiles` to `views` within the `accounts` array tree.
+
+ * @param {Array} accounts A list of accounts in the format returned by the
+ * management API's accountSummaries#list method.
+ * @returns {AccountSummaries}
+ */
+function AccountSummaries(accounts) {
+
+ this.accounts_ = accounts;
+ this.webProperties_ = [];
+ this.profiles_ = [];
+
+ this.accountsById_ = {};
+ this.webPropertiesById_ = this.propertiesById_ = {};
+ this.profilesById_ = this.viewsById_ = {};
+
+ for (var i = 0, account; account = this.accounts_[i]; i++) {
+
+ this.accountsById_[account.id] = {
+ self: account
+ };
+
+ if (!account.webProperties) continue;
+
+ // Add aliases.
+ alias(account, 'webProperties', 'properties');
+
+ for (var j = 0, webProperty; webProperty = account.webProperties[j]; j++) {
+
+ this.webProperties_.push(webProperty);
+ this.webPropertiesById_[webProperty.id] = {
+ self: webProperty,
+ parent: account
+ };
+
+ if (!webProperty.profiles) continue;
+
+ // Add aliases.
+ alias(webProperty, 'profiles', 'views');
+
+ for (var k = 0, profile; profile = webProperty.profiles[k]; k++) {
+
+ this.profiles_.push(profile);
+ this.profilesById_[profile.id] = {
+ self: profile,
+ parent: webProperty,
+ grandParent: account
+ };
+ }
+ }
+ }
+}
+
+
+/**
+ * Return a list of all accounts this user has access to.
+ * Since the accounts contain the web properties and the web properties contain
+ * the profiles, this list contains everything.
+ * @return {Array}
+ */
+AccountSummaries.prototype.all = function() {
+ return this.accounts_;
+};
+
+alias(AccountSummaries.prototype, 'all',
+ 'allAccounts');
+
+
+/**
+ * Return a list of all web properties this user has access to.
+ * @return {Array}
+ */
+AccountSummaries.prototype.allWebProperties = function() {
+ return this.webProperties_;
+};
+
+alias(AccountSummaries.prototype, 'allWebProperties',
+ 'allProperties');
+
+
+/**
+ * Return a list of all profiles this user has access to.
+ * @return {Array}
+ */
+AccountSummaries.prototype.allProfiles = function() {
+ return this.profiles_;
+};
+
+alias(AccountSummaries.prototype, 'allProfiles',
+ 'allViews');
+
+
+/**
+ * Returns an account, web property or profile given the passed ID in the
+ * `idData` object. The ID data object can contain only one of the
+ * following properties: "accountId", "webPropertyId", "propertyId",
+ * "profileId", or "viewId". If more than one key is passed, an error is
+ * thrown.
+ *
+ * @param {Object} obj An object with no more than one of the following
+ * keys: "accountId", "webPropertyId", "propertyId", "profileId" or
+ * "viewId".
+ * @return {Object|undefined} The matching account, web property, or
+ * profile. If none are found, undefined is returned.
+ */
+AccountSummaries.prototype.get = function(obj) {
+ if (!!obj.accountId +
+ !!obj.webPropertyId +
+ !!obj.propertyId +
+ !!obj.profileId +
+ !!obj.viewId > 1) {
+
+ throw new Error('get() only accepts an object with a single ' +
+ 'property: either "accountId", "webPropertyId", "propertyId", ' +
+ '"profileId" or "viewId"');
+ }
+ return this.getProfile(obj.profileId || obj.viewId) ||
+ this.getWebProperty(obj.webPropertyId || obj.propertyId) ||
+ this.getAccount(obj.accountId);
+};
+
+
+/**
+ * Get an account given its ID.
+ * @param {string|number} accountId
+ * @return {Object} The account with the given ID.
+ */
+AccountSummaries.prototype.getAccount = function(accountId) {
+ return this.accountsById_[accountId] &&
+ this.accountsById_[accountId].self;
+};
+
+
+/**
+ * Get a web property given its ID.
+ * @param {string} webPropertyId
+ * @return {Object} The web property with the given ID.
+ */
+AccountSummaries.prototype.getWebProperty = function(webPropertyId) {
+ return this.webPropertiesById_[webPropertyId] &&
+ this.webPropertiesById_[webPropertyId].self;
+};
+
+alias(AccountSummaries.prototype, 'getWebProperty',
+ 'getProperty');
+
+
+/**
+ * Get a profile given its ID.
+ * @param {string|number} profileId
+ * @return {Object} The profile with the given ID.
+ */
+AccountSummaries.prototype.getProfile = function(profileId) {
+ return this.profilesById_[profileId] &&
+ this.profilesById_[profileId].self;
+};
+
+alias(AccountSummaries.prototype, 'getProfile',
+ 'getView');
+
+
+/**
+ * Get an account given the ID of one of its profiles.
+ * @param {string|number} profileId
+ * @return {Object} The account containing this profile.
+ */
+AccountSummaries.prototype.getAccountByProfileId = function(profileId) {
+ return this.profilesById_[profileId] &&
+ this.profilesById_[profileId].grandParent;
+};
+
+
+alias(AccountSummaries.prototype, 'getAccountByProfileId',
+ 'getAccountByViewId');
+
+
+
+/**
+ * Get a web property given the ID of one of its profile.
+ * @param {string|number} profileId
+ * @return {Object} The web property containing this profile.
+ */
+AccountSummaries.prototype.getWebPropertyByProfileId = function(profileId) {
+ return this.profilesById_[profileId] &&
+ this.profilesById_[profileId].parent;
+};
+
+alias(AccountSummaries.prototype, 'getWebPropertyByProfileId',
+ 'getPropertyByViewId');
+
+
+/**
+ * Get an account given the ID of one of its web properties.
+ * @param {string|number} webPropertyId
+ * @return {Object} The account containing this web property.
+ */
+AccountSummaries.prototype.getAccountByWebPropertyId = function(webPropertyId) {
+ return this.webPropertiesById_[webPropertyId] &&
+ this.webPropertiesById_[webPropertyId].parent;
+};
+
+alias(AccountSummaries.prototype, 'getAccountByWebPropertyId',
+ 'getAccountByPropertyId');
+
+
+/**
+ * Alias a property of an object using es5 getters. If es5 getters are not
+ * supported, just add the aliased property directly to the object.
+ * @param {Object} object The object for which you want to alias properties.
+ * @param {string} referenceProp The reference property.
+ * @param {string} aliasName The reference property's alias name.
+ */
+function alias(object, referenceProp, aliasName) {
+ if (Object.defineProperty) {
+ Object.defineProperty(object, aliasName, {
+ get: function() {
+ return object[referenceProp];
+ }
+ });
+ }
+ else {
+ object[aliasName] = object[referenceProp];
+ }
+}
+
+
+module.exports = AccountSummaries;
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/lib/account-summaries/index.js b/polymer_1.0.4/bower_components/ga-api-utils/lib/account-summaries/index.js
new file mode 100644
index 0000000..7c7afef
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/lib/account-summaries/index.js
@@ -0,0 +1,95 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+/* global gapi */
+
+var AccountSummaries = require('./account-summaries');
+
+
+/**
+ * Store the accountSummaries result in a promise so the API isn't
+ * queried unneccesarily.
+ */
+var cache;
+
+
+/**
+ * Make a request to the Management API's accountSummaries#list method.
+ * If the requests returns a partial, paginated response, query again
+ * until the full summaries are retrieved.
+ * @return {goog.Promise} A promise that will be resolved with an
+ * AccountSummaries object.
+ */
+function requestAccountSummaries() {
+
+ var promise = gapi.client.analytics.management.accountSummaries.list()
+ // An extra `then` is needed here because `.list` doesn't return a
+ // "real" promise, just a thenable. Calling `.then` gets us access
+ // to the underlying goog.Promise instance and thus its constructor.
+ .then(function(resp) { return resp; });
+
+ return new promise.constructor(function(resolve, reject) {
+
+ // Store the summaries array in the closure so multiple requests can
+ // concat to it.
+ var summaries = [];
+
+ promise.then(function fn(resp) {
+ var result = resp.result;
+ if (result.items) {
+ summaries = summaries.concat(result.items);
+ }
+ else {
+ reject(new Error('You do not have any Google Analytics accounts. ' +
+ 'Go to http://google.com/analytics to sign up.'));
+ }
+
+ if (result.startIndex + result.itemsPerPage <= result.totalResults) {
+ gapi.client.analytics.management.accountSummaries
+ .list({'start-index': result.startIndex + result.itemsPerPage})
+ // Recursively call this function until the full results are in.
+ .then(fn);
+ }
+ else {
+ resolve(new AccountSummaries(summaries));
+ }
+ })
+ // Reject the promise if there are any uncaught errors;
+ .then(null, reject);
+ });
+}
+
+
+/**
+ * @module accountSummaries
+ *
+ * This module requires the `gapi.client.analytics` library to be installed
+ * and the user to be authenticated.
+ */
+module.exports = {
+
+ /**
+ * Return the `requestAccountSummaries` promise. If the promise exists,
+ * return it to avoid multiple requests. If the promise does not exist,
+ * initiate the request and cache the promise.
+ *
+ * @param {boolean} noCache When true make a request no matter what.
+ * @return {Promise} A promise fulfilled with an AccountSummaries instance.
+ */
+ get: function(noCache) {
+ if (noCache) cache = null;
+ return cache || (cache = requestAccountSummaries());
+ }
+};
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/lib/index.js b/polymer_1.0.4/bower_components/ga-api-utils/lib/index.js
new file mode 100644
index 0000000..d3e7066
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/lib/index.js
@@ -0,0 +1,18 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+module.exports = {
+ accountSummaries: require('./account-summaries'),
+ metadata: require('./metadata')
+};
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/lib/metadata/index.js b/polymer_1.0.4/bower_components/ga-api-utils/lib/metadata/index.js
new file mode 100644
index 0000000..41478d3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/lib/metadata/index.js
@@ -0,0 +1,72 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+/* global gapi */
+
+var Metadata = require('./metadata');
+
+
+/**
+ * Store the metadata result in a promise so the API isn't
+ * queried unneccesarily.
+ */
+var cache;
+
+
+/**
+ * Make a request to the Metadata API's columns#list method.
+ * @return {goog.Promise} A promise that will be resolved with a
+ * Metadata object.
+ */
+function requestMetadata() {
+
+ var promise = gapi.client.analytics.metadata.columns.list({reportType: 'ga'})
+ // An extra `then` is needed here because `.list` doesn't return a
+ // "real" promise, just a thenable. Calling `.then` gets us access
+ // to the underlying goog.Promise instance and thus its constructor.
+ .then(function(resp) { return resp; });
+
+ return new promise.constructor(function(resolve, reject) {
+
+ promise.then(function(resp) {
+ resolve(new Metadata(resp.result.items));
+ })
+ // Reject the promise if there are any uncaught errors;
+ .then(null, reject);
+ });
+}
+
+
+/**
+ * @module metadata
+ *
+ * This module requires the `gapi.client.analytics` library to be installed
+ * and the user to be authenticated.
+ */
+module.exports = {
+
+ /**
+ * Return the `requestMetadata` promise. If the promise exists,
+ * return it to avoid multiple requests. If the promise does not exist,
+ * initiate the request and cache the promise.
+ *
+ * @param {boolean} noCache When true make a request no matter what.
+ * @return {Promise} A promise fulfilled with a Metadata instance.
+ */
+ get: function(noCache) {
+ if (noCache) cache = null;
+ return cache || (cache = requestMetadata());
+ }
+};
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/lib/metadata/metadata.js b/polymer_1.0.4/bower_components/ga-api-utils/lib/metadata/metadata.js
new file mode 100644
index 0000000..bae9c24
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/lib/metadata/metadata.js
@@ -0,0 +1,97 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+/**
+ * @constuctor Metadata
+ *
+ * Takes an array of metadata columns...
+
+ * @param {Array} columns A list of columns in the format returned by the
+ * metadata API's column#list method.
+ * @returns {AccountSummaries}
+ */
+function Metadata(columns) {
+ this._columns = columns;
+
+ this._metrics = [];
+ this._dimensions = [];
+ this._ids = {};
+
+ this._columns.forEach(function(column) {
+ this._ids[column.id] = column.attributes;
+
+ if (column.attributes.type == 'METRIC') {
+ this._metrics.push(column);
+ }
+ else if (column.attributes.type == 'DIMENSION') {
+ this._dimensions.push(column);
+ }
+ }.bind(this));
+}
+
+
+/**
+ * Get an array of all columns, optionally filtering by status.
+ * @param {string|undefined} status The status to filter by. The status options
+ * are 'public' or 'deprecated'. Not setting a status returns all coluns.
+ * @return {Array} A list of column passing the status filter.
+ */
+Metadata.prototype.all = function(status) {
+ return !status ? this._columns : this._columns.filter(function(column) {
+ return column.attributes.status.toLowerCase() === status.toLowerCase();
+ });
+};
+
+
+/**
+ * Get an array of all metrics, optionally filtering by status.
+ * @param {string|undefined} status The status to filter by. The status
+ * options are 'public' or 'deprecated'. Not setting a status returns all
+ * metrics.
+ * @return {Array} A list of column passing the status filter.
+ */
+Metadata.prototype.allMetrics = function(status) {
+ return !status ? this._metrics : this._metrics.filter(function(metric) {
+ return metric.attributes.status.toLowerCase() === status.toLowerCase();
+ });
+};
+
+
+/**
+ * Get an array of all dimensions, optionally filtering by status.
+ * @param {string|undefined} status The status to filter by. The status
+ * options are 'public' or 'deprecated'. Not setting a status returns all
+ * dimensions.
+ * @return {Array} A list of column passing the status filter.
+ */
+Metadata.prototype.allDimensions = function(status) {
+ return !status ?
+ this._dimensions : this._dimensions.filter(function(dimension) {
+ return dimension.attributes.status.toLowerCase() === status.toLowerCase();
+ });
+};
+
+
+/**
+ * Get the attributs object of a column given the passed ID.
+ * @param {string} id The column ID.
+ * @return {Object} The column attributes object.
+ */
+Metadata.prototype.get = function(id) {
+ return this._ids[id];
+};
+
+
+module.exports = Metadata;
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/package.json b/polymer_1.0.4/bower_components/ga-api-utils/package.json
new file mode 100644
index 0000000..08581c7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "javascript-api-utils",
+ "version": "0.2.0",
+ "description": "A collection of utility modules built on top of the gapi client library.",
+ "scripts": {
+ "test": "make"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/googleanalytics/javascript-api-utils.git"
+ },
+ "keywords": [
+ "analytics",
+ "utilities",
+ "gapi",
+ "google"
+ ],
+ "author": "philipwalton",
+ "license": "Apache2",
+ "bugs": {
+ "url": "https://github.com/googleanalytics/javascript-api-utils/issues"
+ },
+ "homepage": "https://github.com/googleanalytics/javascript-api-utils",
+ "devDependencies": {
+ "browserify": "^6.0.3",
+ "jshint": "^2.5.6",
+ "mocha": "^1.21.4",
+ "mout": "^0.11.0",
+ "native-promise-only": "^0.7.6-a",
+ "sinon": "^1.10.3",
+ "uglify-js": "^2.4.15"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/account-summaries.js b/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/account-summaries.js
new file mode 100644
index 0000000..3fb0ff7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/account-summaries.js
@@ -0,0 +1,199 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+/* global describe, it */
+
+var AccountSummaries = require('../../lib/account-summaries/account-summaries');
+var assert = require('assert');
+var fixtureAccounts = require('./fixtures').get().items;
+
+var fixtureWebProperties = fixtureAccounts
+ .reduce(function(webProperties, account) {
+ return account.webProperties ?
+ webProperties.concat(account.webProperties) :
+ webProperties;
+ }, []);
+
+var fixtureProfiles = fixtureWebProperties
+ .reduce(function(profiles, webProperty) {
+ return webProperty.profiles ?
+ profiles.concat(webProperty.profiles) :
+ profiles;
+ }, []);
+
+require('native-promise-only');
+require('./stubs/gapi');
+
+describe('AccountSummaries', function() {
+
+ var summaries = new AccountSummaries(fixtureAccounts);
+
+ describe('#all', function() {
+ it('returns the full list of accounts the user has access to.', function() {
+ assert.deepEqual(summaries.all(), fixtureAccounts);
+ });
+ });
+
+ describe('#allAccounts', function() {
+ it('returns the full list of accounts the user has access to.', function() {
+ assert.deepEqual(summaries.all(), fixtureAccounts);
+ });
+ });
+
+ describe('#allWebProperties', function() {
+ it('returns the full list of web properties the user has access to.',
+ function() {
+ assert.deepEqual(summaries.allWebProperties(), fixtureWebProperties);
+ });
+ });
+
+ describe('#allProperties', function() {
+ it('returns the full list of properties the user has access to.',
+ function() {
+ assert.deepEqual(summaries.allProperties(), fixtureWebProperties);
+ });
+ });
+
+ describe('#allProfiles', function() {
+ it('returns the full list of profiles the user has access to.', function() {
+ assert.deepEqual(summaries.allProfiles(), fixtureProfiles);
+ });
+ });
+
+ describe('#allViews', function() {
+ it('returns the full list of views the user has access to.', function() {
+ assert.deepEqual(summaries.allViews(), fixtureProfiles);
+ });
+ });
+
+ describe('#get', function() {
+ it('returns an account when passed an accountId param.', function() {
+ var account = summaries.get({accountId: 1002});
+ assert.equal(account.name, 'Account B');
+ });
+ it('returns a webProperty when passed a webPropertyId param.', function() {
+ var webProperty = summaries.get({webPropertyId: 'UA-1003-1'});
+ assert.equal(webProperty.name, 'WebProperty C.A');
+ });
+ it('returns a webProperty when passed a propertyId param.', function() {
+ var webProperty = summaries.get({propertyId: 'UA-1003-1'});
+ assert.equal(webProperty.name, 'WebProperty C.A');
+ });
+ it('returns a profile when passed a profileId param.', function() {
+ var profile = summaries.get({profileId: 2006});
+ assert.equal(profile.name, 'Profile A.B.C');
+ });
+ it('returns a profile when passed a viewId param.', function() {
+ var profile = summaries.get({viewId: 2006});
+ assert.equal(profile.name, 'Profile A.B.C');
+ });
+ it('throws when passing more than one ID, even if the IDs are for the ' +
+ 'same entity.', function() {
+
+ assert.throws(function() {
+ summaries.get({webPropertyId: 'UA-1003-1', profileId: 3005});
+ });
+ assert.throws(function() {
+ // The profile with id "2001" belongs to the account with ID "1001".
+ summaries.get({accountId: 1001, profileId: 2001});
+ });
+ });
+ });
+
+ describe('#getAccount', function() {
+ it('returns the account with the specified ID.', function() {
+ assert.equal(summaries.getAccount(1003).name, 'Account C');
+ });
+ });
+
+ describe('#getWebProperty', function() {
+ it('returns the web property with the specified ID.', function() {
+ assert.equal(
+ summaries.getWebProperty('UA-1005-1').name,
+ 'WebProperty E.A (View-less)');
+ });
+ });
+
+ describe('#getProperty', function() {
+ it('returns the property with the specified ID.', function() {
+ assert.equal(
+ summaries.getProperty('UA-1005-1').name,
+ 'WebProperty E.A (View-less)');
+ });
+ });
+
+ describe('#getProfile', function() {
+ it('returns the profile with the specified ID.', function() {
+ assert.equal(summaries.getProfile(2010).name, 'Profile B.A.A');
+ });
+ });
+
+ describe('#getView', function() {
+ it('returns the view with the specified ID.', function() {
+ assert.equal(summaries.getView(2010).name, 'Profile B.A.A');
+ });
+ });
+
+ describe('#getAccountByProfileId', function() {
+ it('returns the account that contains the specified profile ID.',
+ function() {
+ assert.equal(summaries.getAccountByViewId(2008).name, 'Account A');
+ });
+ });
+
+ describe('#getAccountByViewId', function() {
+ it('returns the account that contains the specified view ID.',
+ function() {
+ assert.equal(summaries.getAccountByViewId(2008).name, 'Account A');
+ });
+ });
+
+ describe('#getWebPropertyByProfileId', function() {
+ it('returns the web property that contains the specified profile ID.',
+ function() {
+ assert.equal(
+ summaries.getWebPropertyByProfileId(2011).name,
+ 'WebProperty C.A');
+ });
+ });
+
+ describe('#getPropertyByViewId', function() {
+ it('returns the property that contains the specified view ID.',
+ function() {
+ assert.equal(
+ summaries.getPropertyByViewId(2011).name,
+ 'WebProperty C.A');
+ });
+ });
+
+ describe('#getAccountByWebPropertyId', function() {
+ it('returns the account that contains the specified web property ID.',
+ function() {
+ assert.equal(
+ summaries.getAccountByWebPropertyId('UA-1001-3').name,
+ 'Account A');
+ });
+ });
+
+ describe('#getAccountByPropertyId', function() {
+ it('returns the account that contains the specified property ID.',
+ function() {
+ assert.equal(
+ summaries.getAccountByPropertyId('UA-1001-3').name,
+ 'Account A');
+ });
+ });
+
+});
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/fixtures/account-summaries-with-accounts.json b/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/fixtures/account-summaries-with-accounts.json
new file mode 100644
index 0000000..f7becbe
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/fixtures/account-summaries-with-accounts.json
@@ -0,0 +1,166 @@
+{
+ "kind": "analytics#accountSummaries",
+ "username": "joe@gmail.com",
+ "totalResults": 5,
+ "startIndex": 1,
+ "itemsPerPage": 1000,
+ "items": [
+ {
+ "id": "1001",
+ "kind": "analytics#accountSummary",
+ "name": "Account A",
+ "webProperties": [
+ {
+ "kind": "analytics#webPropertySummary",
+ "id": "UA-1001-1",
+ "name": "WebProperty A.A",
+ "internalWebPropertyId": "3001",
+ "level": "STANDARD",
+ "websiteUrl": "http://example.com",
+ "profiles": [
+ {
+ "kind": "analytics#profileSummary",
+ "id": "2001",
+ "name": "Profile A.A.A",
+ "type": "WEB"
+ },
+ {
+ "kind": "analytics#profileSummary",
+ "id": "2002",
+ "name": "Profile A.A.B",
+ "type": "WEB"
+ },
+ {
+ "kind": "analytics#profileSummary",
+ "id": "2003",
+ "name": "Profile A.A.C",
+ "type": "WEB"
+ }
+ ]
+ },
+ {
+ "kind": "analytics#webPropertySummary",
+ "id": "UA-1001-2",
+ "name": "WebProperty A.B",
+ "internalWebPropertyId": "3002",
+ "level": "STANDARD",
+ "websiteUrl": "http://example.com",
+ "profiles": [
+ {
+ "kind": "analytics#profileSummary",
+ "id": "2004",
+ "name": "Profile A.B.A",
+ "type": "WEB"
+ },
+ {
+ "kind": "analytics#profileSummary",
+ "id": "2005",
+ "name": "Profile A.B.B",
+ "type": "WEB"
+ },
+ {
+ "kind": "analytics#profileSummary",
+ "id": "2006",
+ "name": "Profile A.B.C",
+ "type": "WEB"
+ }
+ ]
+ },
+ {
+ "kind": "analytics#webPropertySummary",
+ "id": "UA-1001-3",
+ "name": "WebProperty A.C",
+ "internalWebPropertyId": "3003",
+ "level": "STANDARD",
+ "websiteUrl": "http://example.com",
+ "profiles": [
+ {
+ "kind": "analytics#profileSummary",
+ "id": "2007",
+ "name": "Profile A.C.A",
+ "type": "WEB"
+ },
+ {
+ "kind": "analytics#profileSummary",
+ "id": "2008",
+ "name": "Profile A.C.B",
+ "type": "WEB"
+ },
+ {
+ "kind": "analytics#profileSummary",
+ "id": "2009",
+ "name": "Profile A.C.C",
+ "type": "WEB"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": "1002",
+ "kind": "analytics#accountSummary",
+ "name": "Account B",
+ "webProperties": [
+ {
+ "kind": "analytics#webPropertySummary",
+ "id": "UA-1002-1",
+ "name": "WebProperty B.A",
+ "internalWebPropertyId": "3002",
+ "level": "STANDARD",
+ "websiteUrl": "http://example.com",
+ "profiles": [
+ {
+ "kind": "analytics#profileSummary",
+ "id": "2010",
+ "name": "Profile B.A.A",
+ "type": "WEB"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": "1003",
+ "kind": "analytics#accountSummary",
+ "name": "Account C",
+ "webProperties": [
+ {
+ "kind": "analytics#webPropertySummary",
+ "id": "UA-1003-1",
+ "name": "WebProperty C.A",
+ "internalWebPropertyId": "3003",
+ "level": "STANDARD",
+ "websiteUrl": "http://example.com",
+ "profiles": [
+ {
+ "kind": "analytics#profileSummary",
+ "id": "2011",
+ "name": "Profile C.A.A",
+ "type": "WEB"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": "1004",
+ "kind": "analytics#accountSummary",
+ "name": "Account D (Property-less)"
+ },
+ {
+ "id": "1005",
+ "kind": "analytics#accountSummary",
+ "name": "Account E (View-less)",
+ "webProperties": [
+ {
+ "kind": "analytics#webPropertySummary",
+ "id": "UA-1005-1",
+ "name": "WebProperty E.A (View-less)",
+ "internalWebPropertyId": "3005",
+ "level": "STANDARD",
+ "websiteUrl": "http://example.com"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/fixtures/account-summaries-without-accounts.json b/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/fixtures/account-summaries-without-accounts.json
new file mode 100644
index 0000000..cfb2cc6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/fixtures/account-summaries-without-accounts.json
@@ -0,0 +1,7 @@
+{
+ "kind": "analytics#accountSummaries",
+ "username": "no-accounts-man@gmail.com",
+ "totalResults": 0,
+ "startIndex": 1,
+ "itemsPerPage": 1000
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/fixtures/index.js b/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/fixtures/index.js
new file mode 100644
index 0000000..1673d68
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/fixtures/index.js
@@ -0,0 +1,33 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+var accountSummariesFixtureWithAccounts =
+ require('./account-summaries-with-accounts');
+
+var accountSummariesFixtureWithoutAccounts =
+ require('./account-summaries-without-accounts');
+
+var currentFixture = accountSummariesFixtureWithAccounts;
+
+module.exports = {
+ get: function() {
+ return JSON.parse(JSON.stringify(currentFixture));
+ },
+ set: function(choice) {
+ currentFixture = (choice == 'with-accounts') ?
+ accountSummariesFixtureWithAccounts :
+ accountSummariesFixtureWithoutAccounts;
+ }
+};
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/index.js b/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/index.js
new file mode 100644
index 0000000..9a82dad
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/index.js
@@ -0,0 +1,137 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+/* global describe, gapi, it */
+
+var accountSummaries = require('../../lib/account-summaries');
+var assert = require('assert');
+var fixtures = require('./fixtures');
+var sinon = require('sinon');
+
+require('./stubs/gapi');
+
+describe('accountSummaries', function() {
+
+ describe('.get', function() {
+
+ it('returns a "thenable" that is resolved with an account summaries array.',
+ function(done) {
+
+ var returnValue = accountSummaries.get();
+ assert('then' in returnValue);
+
+ returnValue.then(function(summaries) {
+ assert.deepEqual(summaries.all(), fixtures.get().items);
+ done();
+ })
+ .catch(done);
+
+ });
+
+ it('does not query the API more than once, even with multiple calls.',
+ function(done) {
+
+ var listSpy =
+ sinon.spy(gapi.client.analytics.management.accountSummaries, 'list');
+
+ accountSummaries.get().then(function(summaries1) {
+ accountSummaries.get().then(function(summaries2) {
+ accountSummaries.get().then(function(summaries3) {
+
+ assert(listSpy.callCount === 0);
+ assert.equal(summaries1, summaries2);
+ assert.equal(summaries2, summaries3);
+ assert.deepEqual(summaries3.all(), fixtures.get().items);
+
+ listSpy.restore();
+ done();
+ })
+ .catch(done);
+ });
+ });
+ });
+
+ it('accepts an optional parameter to clear the cache.', function(done) {
+
+ var listSpy =
+ sinon.spy(gapi.client.analytics.management.accountSummaries, 'list');
+
+ accountSummaries.get(true).then(function(summaries1) {
+ accountSummaries.get(true).then(function(summaries2) {
+ accountSummaries.get(true).then(function(summaries3) {
+ assert.equal(listSpy.callCount, 3);
+
+ // When clearing the cache these should be deepEqual but
+ // not the same object.
+ assert.notEqual(summaries1, summaries2);
+ assert.notEqual(summaries2, summaries3);
+ assert.deepEqual(summaries1, summaries2);
+ assert.deepEqual(summaries2, summaries3);
+
+ assert.deepEqual(summaries3.all(), fixtures.get().items);
+
+ listSpy.restore();
+ done();
+ })
+ .catch(done);
+ });
+ });
+
+ });
+
+ it('returns the full account summaries list, not a paginatated one.',
+ function(done) {
+
+ var originalListMethod =
+ gapi.client.analytics.management.accountSummaries.list;
+
+ var listStub = sinon.stub(
+ gapi.client.analytics.management.accountSummaries, 'list',
+ function(options) {
+ options = options || {};
+ // Add `max-results: 2` to force pagination.
+ options['max-results'] = 2;
+ return originalListMethod(options);
+ });
+
+ accountSummaries.get(true).then(function(summaries) {
+ assert.equal(listStub.callCount, 3);
+ assert.deepEqual(summaries.all(), fixtures.get().items);
+
+ listStub.restore();
+ done();
+ })
+ .catch(done);
+
+ });
+
+ it('throws if the user requesting the summares does not have any ' +
+ 'Google Analytics accounts.', function(done) {
+
+ fixtures.set('without-account');
+
+ accountSummaries.get(true).catch(function(err) {
+ assert.equal(err.message, 'You do not have any Google Analytics ' +
+ 'accounts. Go to http://google.com/analytics to sign up.');
+
+ // Restore the original fixtures.
+ fixtures.set('with-account');
+ done();
+ });
+ });
+
+ });
+
+});
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/stubs/gapi.js b/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/stubs/gapi.js
new file mode 100644
index 0000000..faf5ba5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/test/account-summaries/stubs/gapi.js
@@ -0,0 +1,47 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+/* global gapi:true, Promise:true */
+
+var fixtures = require('../fixtures');
+var namespace = require('mout/object/namespace');
+
+// Polyfill Promises for node.
+Promise = require('native-promise-only');
+
+// Assign this globally because that's how it is IRL.
+namespace(global, 'gapi.client.analytics.management.accountSummaries');
+
+gapi.client.analytics.management.accountSummaries.list = function(options) {
+
+ options = options || {};
+
+ var response = { result: fixtures.get() };
+
+ response.result.startIndex = options['start-index'] || 1;
+ response.result.itemsPerPage = options['max-results'] || 1000;
+
+ // If a user has no accounts, items will not be defined.
+ if (response.result.items) {
+ response.result.items = response.result.items.splice(
+ response.result.startIndex - 1, response.result.itemsPerPage);
+ }
+
+ return {
+ then: function(fn) {
+ return Promise.resolve(fn(response));
+ }
+ };
+};
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/test/metadata/fixtures/columns.json b/polymer_1.0.4/bower_components/ga-api-utils/test/metadata/fixtures/columns.json
new file mode 100644
index 0000000..835e930
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/test/metadata/fixtures/columns.json
@@ -0,0 +1,4993 @@
+{
+ "kind": "analytics#columns",
+ "etag": "\"gUXd2oJOIvAWr2KnYegR9N0sJ7c/Duhub3vzRGEQ1SK4h3jlmcENHac\"",
+ "totalResults": 424,
+ "attributeNames": ["replacedBy", "type", "dataType", "group", "status", "uiName", "appUiName", "description", "calculation", "minTemplateIndex", "maxTemplateIndex", "premiumMinTemplateIndex", "premiumMaxTemplateIndex", "allowedInSegments"],
+ "items": [{
+ "id": "ga:userType",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "User",
+ "status": "PUBLIC",
+ "uiName": "User Type",
+ "description": "A boolean indicating if a user is new or returning. Possible values: New Visitor, Returning Visitor.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:visitorType",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:userType",
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "User",
+ "status": "DEPRECATED",
+ "uiName": "User Type",
+ "description": "A boolean indicating if a user is new or returning. Possible values: New Visitor, Returning Visitor.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:sessionCount",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "User",
+ "status": "PUBLIC",
+ "uiName": "Count of Sessions",
+ "description": "The session index for a user to your property. Each session from a unique user will get its own incremental index starting from 1 for the first session. Subsequent sessions do not change previous session indicies. For example, if a certain user has 4 sessions to your website, sessionCount for that user will have 4 distinct values of '1' through '4'.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:visitCount",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:sessionCount",
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "User",
+ "status": "DEPRECATED",
+ "uiName": "Count of Sessions",
+ "description": "The session index for a user to your property. Each session from a unique user will get its own incremental index starting from 1 for the first session. Subsequent sessions do not change previous session indicies. For example, if a certain user has 4 sessions to your website, sessionCount for that user will have 4 distinct values of '1' through '4'.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:daysSinceLastSession",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "User",
+ "status": "PUBLIC",
+ "uiName": "Days Since Last Session",
+ "description": "The number of days elapsed since users last visited your property. Used to calculate user loyalty.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:daysSinceLastVisit",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:daysSinceLastSession",
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "User",
+ "status": "DEPRECATED",
+ "uiName": "Days Since Last Session",
+ "description": "The number of days elapsed since users last visited your property. Used to calculate user loyalty.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:userDefinedValue",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "User",
+ "status": "PUBLIC",
+ "uiName": "User Defined Value",
+ "description": "The value provided when you define custom user segments for your property.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:users",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "User",
+ "status": "PUBLIC",
+ "uiName": "Users",
+ "description": "Total number of users to your property for the requested time period."
+ }
+ }, {
+ "id": "ga:visitors",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:users",
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "User",
+ "status": "DEPRECATED",
+ "uiName": "Users",
+ "description": "Total number of users to your property for the requested time period."
+ }
+ }, {
+ "id": "ga:newUsers",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "User",
+ "status": "PUBLIC",
+ "uiName": "New Users",
+ "description": "The number of users whose session on your property was marked as a first-time session.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:newVisits",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:newUsers",
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "User",
+ "status": "DEPRECATED",
+ "uiName": "New Users",
+ "description": "The number of users whose session on your property was marked as a first-time session.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:percentNewSessions",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "User",
+ "status": "PUBLIC",
+ "uiName": "% New Sessions",
+ "description": "The percentage of sessions by people who had never visited your property before.",
+ "calculation": "ga:newUsers / ga:sessions"
+ }
+ }, {
+ "id": "ga:percentNewVisits",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:percentNewSessions",
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "User",
+ "status": "DEPRECATED",
+ "uiName": "% New Sessions",
+ "description": "The percentage of sessions by people who had never visited your property before.",
+ "calculation": "ga:newUsers / ga:sessions"
+ }
+ }, {
+ "id": "ga:sessionDurationBucket",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Session",
+ "status": "PUBLIC",
+ "uiName": "Session Duration",
+ "description": "The length of a session on your property measured in seconds and reported in second increments. The value returned is a string.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:visitLength",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:sessionDurationBucket",
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Session",
+ "status": "DEPRECATED",
+ "uiName": "Session Duration",
+ "description": "The length of a session on your property measured in seconds and reported in second increments. The value returned is a string.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:sessions",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Session",
+ "status": "PUBLIC",
+ "uiName": "Sessions",
+ "description": "Counts the total number of sessions.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:visits",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:sessions",
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Session",
+ "status": "DEPRECATED",
+ "uiName": "Sessions",
+ "description": "Counts the total number of sessions.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:bounces",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Session",
+ "status": "PUBLIC",
+ "uiName": "Bounces",
+ "description": "The total number of single page (or single engagement hit) sessions for your property.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:entranceBounceRate",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:bounceRate",
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Session",
+ "status": "DEPRECATED",
+ "uiName": "Bounce Rate",
+ "description": "This dimension is deprecated and will be removed soon. Please use ga:bounceRate instead.",
+ "calculation": "ga:bounces / ga:entrances"
+ }
+ }, {
+ "id": "ga:bounceRate",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Session",
+ "status": "PUBLIC",
+ "uiName": "Bounce Rate",
+ "description": "The percentage of single-page session (i.e., session in which the person left your property from the first page).",
+ "calculation": "ga:bounces / ga:sessions"
+ }
+ }, {
+ "id": "ga:visitBounceRate",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:bounceRate",
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Session",
+ "status": "DEPRECATED",
+ "uiName": "Bounce Rate",
+ "description": "The percentage of single-page session (i.e., session in which the person left your property from the first page).",
+ "calculation": "ga:bounces / ga:sessions"
+ }
+ }, {
+ "id": "ga:sessionDuration",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "TIME",
+ "group": "Session",
+ "status": "PUBLIC",
+ "uiName": "Session Duration",
+ "description": "The total duration of user sessions represented in total seconds.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:timeOnSite",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:sessionDuration",
+ "type": "METRIC",
+ "dataType": "TIME",
+ "group": "Session",
+ "status": "DEPRECATED",
+ "uiName": "Session Duration",
+ "description": "The total duration of user sessions represented in total seconds.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:avgSessionDuration",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "TIME",
+ "group": "Session",
+ "status": "PUBLIC",
+ "uiName": "Avg. Session Duration",
+ "description": "The average duration of user sessions represented in total seconds.",
+ "calculation": "ga:sessionDuration / ga:sessions"
+ }
+ }, {
+ "id": "ga:avgTimeOnSite",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:avgSessionDuration",
+ "type": "METRIC",
+ "dataType": "TIME",
+ "group": "Session",
+ "status": "DEPRECATED",
+ "uiName": "Avg. Session Duration",
+ "description": "The average duration of user sessions represented in total seconds.",
+ "calculation": "ga:sessionDuration / ga:sessions"
+ }
+ }, {
+ "id": "ga:referralPath",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Traffic Sources",
+ "status": "PUBLIC",
+ "uiName": "Referral Path",
+ "description": "The path of the referring URL (e.g. document.referrer). If someone places a link to your property on their website, this element contains the path of the page that contains the referring link.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:fullReferrer",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Traffic Sources",
+ "status": "PUBLIC",
+ "uiName": "Full Referrer",
+ "description": "The full referring URL including the hostname and path."
+ }
+ }, {
+ "id": "ga:campaign",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Traffic Sources",
+ "status": "PUBLIC",
+ "uiName": "Campaign",
+ "description": "When using manual campaign tracking, the value of the utm_campaign campaign tracking parameter. When using AdWords autotagging, the name(s) of the online ad campaign that you use for your property. Otherwise the value (not set) is used.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:source",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Traffic Sources",
+ "status": "PUBLIC",
+ "uiName": "Source",
+ "description": "The source of referrals to your property. When using manual campaign tracking, the value of the utm_source campaign tracking parameter. When using AdWords autotagging, the value is google. Otherwise the domain of the source referring the user to your property (e.g. document.referrer). The value may also contain a port address. If the user arrived without a referrer, the value is (direct)",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:medium",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Traffic Sources",
+ "status": "PUBLIC",
+ "uiName": "Medium",
+ "description": "The type of referrals to your property. When using manual campaign tracking, the value of the utm_medium campaign tracking parameter. When using AdWords autotagging, the value is ppc. If the user comes from a search engine detected by Google Analytics, the value is organic. If the referrer is not a search engine, the value is referral. If the users came directly to the property, and document.referrer is empty, the value is (none).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:sourceMedium",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Traffic Sources",
+ "status": "PUBLIC",
+ "uiName": "Source / Medium",
+ "description": "Combined values of ga:source and ga:medium.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:keyword",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Traffic Sources",
+ "status": "PUBLIC",
+ "uiName": "Keyword",
+ "description": "When using manual campaign tracking, the value of the utm_term campaign tracking parameter. When using AdWords autotagging or if a user used organic search to reach your property, the keywords used by users to reach your property. Otherwise the value is (not set).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:adContent",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Traffic Sources",
+ "status": "PUBLIC",
+ "uiName": "Ad Content",
+ "description": "When using manual campaign tracking, the value of the utm_content campaign tracking parameter. When using AdWords autotagging, the first line of the text for your online Ad campaign. If you are using mad libs for your AdWords content, this field displays the keywords you provided for the mad libs keyword match. Otherwise the value is (not set)",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:socialNetwork",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Traffic Sources",
+ "status": "PUBLIC",
+ "uiName": "Social Network",
+ "description": "Name of the social network. This can be related to the referring social network for traffic sources, or to the social network for social data hub activities. E.g. Google+, Blogger, etc."
+ }
+ }, {
+ "id": "ga:hasSocialSourceReferral",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Traffic Sources",
+ "status": "PUBLIC",
+ "uiName": "Social Source Referral",
+ "description": "Indicates sessions that arrived to the property from a social source. The possible values are Yes or No where the first letter is capitalized."
+ }
+ }, {
+ "id": "ga:organicSearches",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Traffic Sources",
+ "status": "PUBLIC",
+ "uiName": "Organic Searches",
+ "description": "The number of organic searches that happened within a session. This metric is search engine agnostic."
+ }
+ }, {
+ "id": "ga:adGroup",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Ad Group",
+ "description": "The name of your AdWords ad group.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:adSlot",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Ad Slot",
+ "description": "The location of the advertisement on the hosting page (Top, RHS, or not set).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:adSlotPosition",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Ad Slot Position",
+ "description": "The ad slot positions in which your AdWords ads appeared (1-8).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:adDistributionNetwork",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Ad Distribution Network",
+ "description": "The networks used to deliver your ads (Content, Search, Search partners, etc.)."
+ }
+ }, {
+ "id": "ga:adMatchType",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Query Match Type",
+ "description": "The match types applied for the search term the user had input(Phrase, Exact, Broad, etc.). Ads on the content network are identified as \"Content network\". Details: https://support.google.com/adwords/answer/2472708?hl=en"
+ }
+ }, {
+ "id": "ga:adKeywordMatchType",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Keyword Match Type",
+ "description": "The match types applied to your keywords (Phrase, Exact, Broad). Details: https://support.google.com/adwords/answer/2472708?hl=en"
+ }
+ }, {
+ "id": "ga:adMatchedQuery",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Matched Search Query",
+ "description": "The search queries that triggered impressions of your AdWords ads."
+ }
+ }, {
+ "id": "ga:adPlacementDomain",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Placement Domain",
+ "description": "The domains where your ads on the content network were placed."
+ }
+ }, {
+ "id": "ga:adPlacementUrl",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Placement URL",
+ "description": "The URLs where your ads on the content network were placed."
+ }
+ }, {
+ "id": "ga:adFormat",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Ad Format",
+ "description": "Your AdWords ad formats (Text, Image, Flash, Video, etc.)."
+ }
+ }, {
+ "id": "ga:adTargetingType",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Targeting Type",
+ "description": "How your AdWords ads were targeted (keyword, placement, and vertical targeting, etc.)."
+ }
+ }, {
+ "id": "ga:adTargetingOption",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Placement Type",
+ "description": "How you manage your ads on the content network. Values are Automatic placements or Managed placements."
+ }
+ }, {
+ "id": "ga:adDisplayUrl",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Display URL",
+ "description": "The URLs your AdWords ads displayed."
+ }
+ }, {
+ "id": "ga:adDestinationUrl",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Destination URL",
+ "description": "The URLs to which your AdWords ads referred traffic."
+ }
+ }, {
+ "id": "ga:adwordsCustomerID",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "AdWords Customer ID",
+ "description": "A string. Corresponds to AdWords API AccountInfo.customerId."
+ }
+ }, {
+ "id": "ga:adwordsCampaignID",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "AdWords Campaign ID",
+ "description": "A string. Corresponds to AdWords API Campaign.id."
+ }
+ }, {
+ "id": "ga:adwordsAdGroupID",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "AdWords Ad Group ID",
+ "description": "A string. Corresponds to AdWords API AdGroup.id."
+ }
+ }, {
+ "id": "ga:adwordsCreativeID",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "AdWords Creative ID",
+ "description": "A string. Corresponds to AdWords API Ad.id."
+ }
+ }, {
+ "id": "ga:adwordsCriteriaID",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "AdWords Criteria ID",
+ "description": "A string. Corresponds to AdWords API Criterion.id."
+ }
+ }, {
+ "id": "ga:impressions",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Impressions",
+ "description": "Total number of campaign impressions."
+ }
+ }, {
+ "id": "ga:adClicks",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Clicks",
+ "description": "The total number of times users have clicked on an ad to reach your property."
+ }
+ }, {
+ "id": "ga:adCost",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Cost",
+ "description": "Derived cost for the advertising campaign. The currency for this value is based on the currency that you set in your AdWords account."
+ }
+ }, {
+ "id": "ga:CPM",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "CPM",
+ "description": "Cost per thousand impressions.",
+ "calculation": "ga:adCost / (ga:impressions / 1000)"
+ }
+ }, {
+ "id": "ga:CPC",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "CPC",
+ "description": "Cost to advertiser per click.",
+ "calculation": "ga:adCost / ga:adClicks"
+ }
+ }, {
+ "id": "ga:CTR",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "CTR",
+ "description": "Click-through-rate for your ad. This is equal to the number of clicks divided by the number of impressions for your ad (e.g. how many times users clicked on one of your ads where that ad appeared).",
+ "calculation": "ga:adClicks / ga:impressions"
+ }
+ }, {
+ "id": "ga:costPerTransaction",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Cost per Transaction",
+ "description": "The cost per transaction for your property.",
+ "calculation": "(ga:adCost) / (ga:transactions)"
+ }
+ }, {
+ "id": "ga:costPerGoalConversion",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Cost per Goal Conversion",
+ "description": "The cost per goal conversion for your property.",
+ "calculation": "(ga:adCost) / (ga:goalCompletionsAll)"
+ }
+ }, {
+ "id": "ga:costPerConversion",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "Cost per Conversion",
+ "description": "The cost per conversion (including ecommerce and goal conversions) for your property.",
+ "calculation": "(ga:adCost) / (ga:transactions + ga:goalCompletionsAll)"
+ }
+ }, {
+ "id": "ga:RPC",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "RPC",
+ "description": "RPC or revenue-per-click is the average revenue (from ecommerce sales and/or goal value) you received for each click on one of your search ads.",
+ "calculation": "(ga:transactionRevenue + ga:goalValueAll) / ga:adClicks"
+ }
+ }, {
+ "id": "ga:ROI",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Adwords",
+ "status": "DEPRECATED",
+ "uiName": "ROI",
+ "description": "This metric is deprecated and will be removed soon. Please use ga:ROAS instead.",
+ "calculation": "(ga:transactionRevenue + ga:goalValueAll - ga:adCost) / ga:adCost"
+ }
+ }, {
+ "id": "ga:margin",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Adwords",
+ "status": "DEPRECATED",
+ "uiName": "Margin",
+ "description": "This metric is deprecated and will be removed soon. Please use ga:ROAS instead.",
+ "calculation": "(ga:transactionRevenue + ga:goalValueAll - ga:adCost) / (ga:transactionRevenue + ga:goalValueAll)"
+ }
+ }, {
+ "id": "ga:ROAS",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "ROAS",
+ "description": "Return On Ad Spend (ROAS) is the total transaction revenue and goal value divided by derived advertising cost.",
+ "calculation": "(ga:transactionRevenue + ga:goalValueAll) / ga:adCost"
+ }
+ }, {
+ "id": "ga:goalCompletionLocation",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Goal Completion Location",
+ "description": "The page path or screen name that matched any destination type goal completion."
+ }
+ }, {
+ "id": "ga:goalPreviousStep1",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Goal Previous Step - 1",
+ "description": "The page path or screen name that matched any destination type goal, one step prior to the goal completion location."
+ }
+ }, {
+ "id": "ga:goalPreviousStep2",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Goal Previous Step - 2",
+ "description": "The page path or screen name that matched any destination type goal, two steps prior to the goal completion location."
+ }
+ }, {
+ "id": "ga:goalPreviousStep3",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Goal Previous Step - 3",
+ "description": "The page path or screen name that matched any destination type goal, three steps prior to the goal completion location."
+ }
+ }, {
+ "id": "ga:goalXXStarts",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Goal XX Starts",
+ "description": "The total number of starts for the requested goal number.",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "20",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:goalStartsAll",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Goal Starts",
+ "description": "The total number of starts for all goals defined for your profile.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:goalXXCompletions",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Goal XX Completions",
+ "description": "The total number of completions for the requested goal number.",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "20",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:goalCompletionsAll",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Goal Completions",
+ "description": "The total number of completions for all goals defined for your profile.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:goalXXValue",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Goal XX Value",
+ "description": "The total numeric value for the requested goal number.",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "20",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:goalValueAll",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Goal Value",
+ "description": "The total numeric value for all goals defined for your profile.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:goalValuePerSession",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Per Session Goal Value",
+ "description": "The average goal value of a session on your property.",
+ "calculation": "ga:goalValueAll / ga:sessions"
+ }
+ }, {
+ "id": "ga:goalValuePerVisit",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:goalValuePerSession",
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Goal Conversions",
+ "status": "DEPRECATED",
+ "uiName": "Per Session Goal Value",
+ "description": "The average goal value of a session on your property.",
+ "calculation": "ga:goalValueAll / ga:sessions"
+ }
+ }, {
+ "id": "ga:goalXXConversionRate",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Goal XX Conversion Rate",
+ "description": "The percentage of sessions which resulted in a conversion to the requested goal number.",
+ "calculation": "ga:goalXXCompletions / ga:sessions",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "20"
+ }
+ }, {
+ "id": "ga:goalConversionRateAll",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Goal Conversion Rate",
+ "description": "The percentage of sessions which resulted in a conversion to at least one of your goals.",
+ "calculation": "ga:goalCompletionsAll / ga:sessions"
+ }
+ }, {
+ "id": "ga:goalXXAbandons",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Goal XX Abandoned Funnels",
+ "description": "The number of times users started conversion activity on the requested goal number without actually completing it.",
+ "calculation": "(ga:goalXXStarts - ga:goalXXCompletions)",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "20"
+ }
+ }, {
+ "id": "ga:goalAbandonsAll",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Abandoned Funnels",
+ "description": "The overall number of times users started goals without actually completing them.",
+ "calculation": "(ga:goalStartsAll - ga:goalCompletionsAll)"
+ }
+ }, {
+ "id": "ga:goalXXAbandonRate",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Goal XX Abandonment Rate",
+ "description": "The rate at which the requested goal number was abandoned.",
+ "calculation": "((ga:goalXXStarts - ga:goalXXCompletions)) / (ga:goalXXStarts)",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "20"
+ }
+ }, {
+ "id": "ga:goalAbandonRateAll",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Goal Conversions",
+ "status": "PUBLIC",
+ "uiName": "Total Abandonment Rate",
+ "description": "The rate at which goals were abandoned.",
+ "calculation": "((ga:goalStartsAll - ga:goalCompletionsAll)) / (ga:goalStartsAll)"
+ }
+ }, {
+ "id": "ga:browser",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Platform or Device",
+ "status": "PUBLIC",
+ "uiName": "Browser",
+ "description": "The names of browsers used by users to your website. For example, Internet Explorer or Firefox.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:browserVersion",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Platform or Device",
+ "status": "PUBLIC",
+ "uiName": "Browser Version",
+ "description": "The browser versions used by users to your website. For example, 2.0.0.14",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:operatingSystem",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Platform or Device",
+ "status": "PUBLIC",
+ "uiName": "Operating System",
+ "description": "The operating system used by your users. For example, Windows, Linux , Macintosh, iPhone, iPod.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:operatingSystemVersion",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Platform or Device",
+ "status": "PUBLIC",
+ "uiName": "Operating System Version",
+ "description": "The version of the operating system used by your users, such as XP for Windows or PPC for Macintosh.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:isMobile",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Platform or Device",
+ "status": "DEPRECATED",
+ "uiName": "Mobile (Including Tablet)",
+ "description": "This dimension is deprecated and will be removed soon. Please use ga:deviceCategory instead (e.g., ga:deviceCategory==mobile).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:isTablet",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Platform or Device",
+ "status": "DEPRECATED",
+ "uiName": "Tablet",
+ "description": "This dimension is deprecated and will be removed soon. Please use ga:deviceCategory instead (e.g., ga:deviceCategory==tablet).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:mobileDeviceBranding",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Platform or Device",
+ "status": "PUBLIC",
+ "uiName": "Mobile Device Branding",
+ "description": "Mobile manufacturer or branded name.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:mobileDeviceModel",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Platform or Device",
+ "status": "PUBLIC",
+ "uiName": "Mobile Device Model",
+ "description": "Mobile device model",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:mobileInputSelector",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Platform or Device",
+ "status": "PUBLIC",
+ "uiName": "Mobile Input Selector",
+ "description": "Selector used on the mobile device (e.g.: touchscreen, joystick, clickwheel, stylus).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:mobileDeviceInfo",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Platform or Device",
+ "status": "PUBLIC",
+ "uiName": "Mobile Device Info",
+ "description": "The branding, model, and marketing name used to identify the mobile device.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:mobileDeviceMarketingName",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Platform or Device",
+ "status": "PUBLIC",
+ "uiName": "Mobile Device Marketing Name",
+ "description": "The marketing name used for the mobile device.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:deviceCategory",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Platform or Device",
+ "status": "PUBLIC",
+ "uiName": "Device Category",
+ "description": "The type of device: desktop, tablet, or mobile.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:continent",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Geo Network",
+ "status": "PUBLIC",
+ "uiName": "Continent",
+ "description": "The continents of property users, derived from IP addresses.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:subContinent",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Geo Network",
+ "status": "PUBLIC",
+ "uiName": "Sub Continent",
+ "description": "The sub-continent of users, derived from IP addresses. For example, Polynesia or Northern Europe.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:country",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Geo Network",
+ "status": "PUBLIC",
+ "uiName": "Country",
+ "description": "The country of users, derived from IP addresses.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:region",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Geo Network",
+ "status": "PUBLIC",
+ "uiName": "Region",
+ "description": "The region of users to your property, derived from IP addresses. In the U.S., a region is a state, such as New York.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:metro",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Geo Network",
+ "status": "PUBLIC",
+ "uiName": "Metro",
+ "description": "The Designated Market Area (DMA) from where traffic arrived on your property.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:city",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Geo Network",
+ "status": "PUBLIC",
+ "uiName": "City",
+ "description": "The cities of property users, derived from IP addresses.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:latitude",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Geo Network",
+ "status": "PUBLIC",
+ "uiName": "Latitude",
+ "description": "The approximate latitude of the user's city. Derived from IP address. Locations north of the equator are represented by positive values and locations south of the equator by negative values."
+ }
+ }, {
+ "id": "ga:longitude",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Geo Network",
+ "status": "PUBLIC",
+ "uiName": "Longitude",
+ "description": "The approximate longitude of the user's city. Derived from IP address. Locations east of the meridian are represented by positive values and locations west of the meridian by negative values."
+ }
+ }, {
+ "id": "ga:networkDomain",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Geo Network",
+ "status": "PUBLIC",
+ "uiName": "Network Domain",
+ "description": "The domain name of the ISPs used by users to your property. This is derived from the domain name registered to the IP address.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:networkLocation",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Geo Network",
+ "status": "PUBLIC",
+ "uiName": "Service Provider",
+ "description": "The name of service providers used to reach your property. For example, if most users to your website come via the major service providers for cable internet, you will see the names of those cable service providers in this element.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:flashVersion",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "System",
+ "status": "PUBLIC",
+ "uiName": "Flash Version",
+ "description": "The versions of Flash supported by users' browsers, including minor versions.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:javaEnabled",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "System",
+ "status": "PUBLIC",
+ "uiName": "Java Support",
+ "description": "Indicates Java support for users' browsers. The possible values are Yes or No where the first letter must be capitalized.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:language",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "System",
+ "status": "PUBLIC",
+ "uiName": "Language",
+ "description": "The language provided by the HTTP Request for the browser. Values are given as an ISO-639 code (e.g. en-gb for British English).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:screenColors",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "System",
+ "status": "PUBLIC",
+ "uiName": "Screen Colors",
+ "description": "The color depth of users' monitors, as retrieved from the DOM of the user's browser. For example 4-bit, 8-bit, 24-bit, or undefined-bit.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:sourcePropertyDisplayName",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "System",
+ "status": "PUBLIC",
+ "uiName": "Source Property Display Name",
+ "description": "Source property display name of roll-up properties. This is valid only for roll-up properties.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:sourcePropertyTrackingId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "System",
+ "status": "PUBLIC",
+ "uiName": "Source Property Tracking ID",
+ "description": "Source property tracking ID of roll-up properties. This is valid only for roll-up properties.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:screenResolution",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "System",
+ "status": "PUBLIC",
+ "uiName": "Screen Resolution",
+ "description": "The screen resolution of users' screens. For example: 1024x738.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:socialActivityEndorsingUrl",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Activities",
+ "status": "PUBLIC",
+ "uiName": "Endorsing URL",
+ "description": "For a social data hub activity, this value represents the URL of the social activity (e.g. the Google+ post URL, the blog comment URL, etc.)"
+ }
+ }, {
+ "id": "ga:socialActivityDisplayName",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Activities",
+ "status": "PUBLIC",
+ "uiName": "Display Name",
+ "description": "For a social data hub activity, this value represents the title of the social activity posted by the social network user."
+ }
+ }, {
+ "id": "ga:socialActivityPost",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Activities",
+ "status": "PUBLIC",
+ "uiName": "Social Activity Post",
+ "description": "For a social data hub activity, this value represents the content of the social activity posted by the social network user (e.g. The message content of a Google+ post)"
+ }
+ }, {
+ "id": "ga:socialActivityTimestamp",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Activities",
+ "status": "PUBLIC",
+ "uiName": "Social Activity Timestamp",
+ "description": "For a social data hub activity, this value represents when the social activity occurred on the social network."
+ }
+ }, {
+ "id": "ga:socialActivityUserHandle",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Activities",
+ "status": "PUBLIC",
+ "uiName": "Social User Handle",
+ "description": "For a social data hub activity, this value represents the social network handle (e.g. name or ID) of the user who initiated the social activity."
+ }
+ }, {
+ "id": "ga:socialActivityUserPhotoUrl",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Activities",
+ "status": "PUBLIC",
+ "uiName": "User Photo URL",
+ "description": "For a social data hub activity, this value represents the URL of the photo associated with the user's social network profile."
+ }
+ }, {
+ "id": "ga:socialActivityUserProfileUrl",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Activities",
+ "status": "PUBLIC",
+ "uiName": "User Profile URL",
+ "description": "For a social data hub activity, this value represents the URL of the associated user's social network profile."
+ }
+ }, {
+ "id": "ga:socialActivityContentUrl",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Activities",
+ "status": "PUBLIC",
+ "uiName": "Shared URL",
+ "description": "For a social data hub activity, this value represents the URL shared by the associated social network user."
+ }
+ }, {
+ "id": "ga:socialActivityTagsSummary",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Activities",
+ "status": "PUBLIC",
+ "uiName": "Social Tags Summary",
+ "description": "For a social data hub activity, this is a comma-separated set of tags associated with the social activity."
+ }
+ }, {
+ "id": "ga:socialActivityAction",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Activities",
+ "status": "PUBLIC",
+ "uiName": "Originating Social Action",
+ "description": "For a social data hub activity, this value represents the type of social action associated with the activity (e.g. vote, comment, +1, etc.)."
+ }
+ }, {
+ "id": "ga:socialActivityNetworkAction",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Activities",
+ "status": "PUBLIC",
+ "uiName": "Social Network and Action",
+ "description": "For a social data hub activity, this value represents the type of social action and the social network where the activity originated."
+ }
+ }, {
+ "id": "ga:socialActivities",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Social Activities",
+ "status": "PUBLIC",
+ "uiName": "Data Hub Activities",
+ "description": "The count of activities where a content URL was shared / mentioned on a social data hub partner network."
+ }
+ }, {
+ "id": "ga:hostname",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Hostname",
+ "description": "The hostname from which the tracking request was made.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:pagePath",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Page",
+ "description": "A page on your website specified by path and/or query parameters. Use in conjunction with hostname to get the full URL of the page.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:pagePathLevel1",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Page path level 1",
+ "description": "This dimension rolls up all the page paths in the first hierarchical level in pagePath."
+ }
+ }, {
+ "id": "ga:pagePathLevel2",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Page path level 2",
+ "description": "This dimension rolls up all the page paths in the second hierarchical level in pagePath."
+ }
+ }, {
+ "id": "ga:pagePathLevel3",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Page path level 3",
+ "description": "This dimension rolls up all the page paths in the third hierarchical level in pagePath."
+ }
+ }, {
+ "id": "ga:pagePathLevel4",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Page path level 4",
+ "description": "This dimension rolls up all the page paths into hierarchical levels. Up to 4 pagePath levels maybe specified. All additional levels in the pagePath hierarchy are also rolled up in this dimension."
+ }
+ }, {
+ "id": "ga:pageTitle",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Page Title",
+ "description": "The title of a page. Keep in mind that multiple pages might have the same page title.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:landingPagePath",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Landing Page",
+ "description": "The first page in a user's session, or landing page.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:secondPagePath",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Second Page",
+ "description": "The second page in a user's session."
+ }
+ }, {
+ "id": "ga:exitPagePath",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Exit Page",
+ "description": "The last page in a user's session, or exit page.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:previousPagePath",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Previous Page Path",
+ "description": "A page on your property that was visited before another page on the same property. Typically used with the pagePath dimension."
+ }
+ }, {
+ "id": "ga:nextPagePath",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Next Page Path",
+ "description": "A page on your website that was visited after another page on your website. Typically used with the previousPagePath dimension."
+ }
+ }, {
+ "id": "ga:pageDepth",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Page Depth",
+ "description": "The number of pages visited by users during a session. The value is a histogram that counts pageviews across a range of possible values. In this calculation, all sessions will have at least one pageview, and some percentage of sessions will have more.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:pageValue",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Page Value",
+ "description": "The average value of this page or set of pages. Page Value is (ga:transactionRevenue + ga:goalValueAll) / ga:uniquePageviews (for the page or set of pages)."
+ }
+ }, {
+ "id": "ga:entrances",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Entrances",
+ "description": "The number of entrances to your property measured as the first pageview in a session. Typically used with landingPagePath",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:entranceRate",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Entrances / Pageviews",
+ "description": "The percentage of pageviews in which this page was the entrance.",
+ "calculation": "ga:entrances / ga:pageviews"
+ }
+ }, {
+ "id": "ga:pageviews",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Pageviews",
+ "description": "The total number of pageviews for your property.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:pageviewsPerSession",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Pages / Session",
+ "description": "The average number of pages viewed during a session on your property. Repeated views of a single page are counted.",
+ "calculation": "ga:pageviews / ga:sessions"
+ }
+ }, {
+ "id": "ga:pageviewsPerVisit",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:pageviewsPerSession",
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Page Tracking",
+ "status": "DEPRECATED",
+ "uiName": "Pages / Session",
+ "description": "The average number of pages viewed during a session on your property. Repeated views of a single page are counted.",
+ "calculation": "ga:pageviews / ga:sessions"
+ }
+ }, {
+ "id": "ga:contentGroupUniqueViewsXX",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Content Grouping",
+ "status": "PUBLIC",
+ "uiName": "Unique Views",
+ "description": "The number of different (unique) pages within a session for the specified content group. This takes into account both the pagePath and pageTitle to determine uniqueness.",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "5"
+ }
+ }, {
+ "id": "ga:uniquePageviews",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Unique Pageviews",
+ "description": "The number of different (unique) pages within a session. This takes into account both the pagePath and pageTitle to determine uniqueness.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:timeOnPage",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "TIME",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Time on Page",
+ "description": "How long a user spent on a particular page in seconds. Calculated by subtracting the initial view time for a particular page from the initial view time for a subsequent page. Thus, this metric does not apply to exit pages for your property.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:avgTimeOnPage",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "TIME",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Avg. Time on Page",
+ "description": "The average amount of time users spent viewing this page or a set of pages.",
+ "calculation": "ga:timeOnPage / (ga:pageviews - ga:exits)"
+ }
+ }, {
+ "id": "ga:exits",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "Exits",
+ "description": "The number of exits from your property.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:exitRate",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Page Tracking",
+ "status": "PUBLIC",
+ "uiName": "% Exit",
+ "description": "The percentage of exits from your property that occurred out of the total page views.",
+ "calculation": "ga:exits / (ga:pageviews + ga:screenviews)"
+ }
+ }, {
+ "id": "ga:searchUsed",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Site Search Status",
+ "description": "A boolean to distinguish whether internal search was used in a session. Values are Visits With Site Search and Visits Without Site Search.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:searchKeyword",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Search Term",
+ "description": "Search terms used by users within your property.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:searchKeywordRefinement",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Refined Keyword",
+ "description": "Subsequent keyword search terms or strings entered by users after a given initial string search.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:searchCategory",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Site Search Category",
+ "description": "The categories used for the internal search if you have this enabled for your profile. For example, you might have product categories such as electronics, furniture, or clothing.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:searchStartPage",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Start Page",
+ "description": "A page where the user initiated an internal search on your property."
+ }
+ }, {
+ "id": "ga:searchDestinationPage",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Destination Page",
+ "description": "The page the user immediately visited after performing an internal search on your site. (Usually the search results page)."
+ }
+ }, {
+ "id": "ga:searchResultViews",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Results Pageviews",
+ "description": "The number of times a search result page was viewed after performing a search."
+ }
+ }, {
+ "id": "ga:searchUniques",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Total Unique Searches",
+ "description": "The total number of unique keywords from internal searches within a session. For example if \"shoes\" was searched for 3 times in a session, it will be only counted once.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:avgSearchResultViews",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Results Pageviews / Search",
+ "description": "The average number of times people viewed a search results page after performing a search.",
+ "calculation": "ga:searchResultViews / ga:searchUniques"
+ }
+ }, {
+ "id": "ga:searchSessions",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Sessions with Search",
+ "description": "The total number of sessions that included an internal search",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:searchVisits",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:searchSessions",
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Internal Search",
+ "status": "DEPRECATED",
+ "uiName": "Sessions with Search",
+ "description": "The total number of sessions that included an internal search",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:percentSessionsWithSearch",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "% Sessions with Search",
+ "description": "The percentage of sessions with search.",
+ "calculation": "ga:searchSessions / ga:sessions"
+ }
+ }, {
+ "id": "ga:percentVisitsWithSearch",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:percentSessionsWithSearch",
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Internal Search",
+ "status": "DEPRECATED",
+ "uiName": "% Sessions with Search",
+ "description": "The percentage of sessions with search.",
+ "calculation": "ga:searchSessions / ga:sessions"
+ }
+ }, {
+ "id": "ga:searchDepth",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Search Depth",
+ "description": "The average number of subsequent page views made on your property after a use of your internal search feature.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:avgSearchDepth",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Average Search Depth",
+ "description": "The average number of pages people viewed after performing a search on your property.",
+ "calculation": "ga:searchDepth / ga:searchUniques"
+ }
+ }, {
+ "id": "ga:searchRefinements",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Search Refinements",
+ "description": "The total number of times a refinement (transition) occurs between internal search keywords within a session. For example if the sequence of keywords is: \"shoes\", \"shoes\", \"pants\", \"pants\", this metric will be one because the transition between \"shoes\" and \"pants\" is different.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:percentSearchRefinements",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "% Search Refinements",
+ "description": "The percentage of number of times a refinement (i.e., transition) occurs between internal search keywords within a session.",
+ "calculation": "ga:searchRefinements / ga:searchResultViews"
+ }
+ }, {
+ "id": "ga:searchDuration",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "TIME",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Time after Search",
+ "description": "The session duration on your property where a use of your internal search feature occurred.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:avgSearchDuration",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "TIME",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Time after Search",
+ "description": "The average amount of time people spent on your property after searching.",
+ "calculation": "ga:searchDuration / ga:searchUniques"
+ }
+ }, {
+ "id": "ga:searchExits",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Search Exits",
+ "description": "The number of exits on your site that occurred following a search result from your internal search feature.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:searchExitRate",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "% Search Exits",
+ "description": "The percentage of searches that resulted in an immediate exit from your property.",
+ "calculation": "ga:searchExits / ga:searchUniques"
+ }
+ }, {
+ "id": "ga:searchGoalXXConversionRate",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Site Search Goal XX Conversion Rate",
+ "description": "The percentage of search sessions (i.e., sessions that included at least one search) which resulted in a conversion to the requested goal number.",
+ "calculation": "ga:goalXXCompletions / ga:searchUniques",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "20"
+ }
+ }, {
+ "id": "ga:searchGoalConversionRateAll",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Site Search Goal Conversion Rate",
+ "description": "The percentage of search sessions (i.e., sessions that included at least one search) which resulted in a conversion to at least one of your goals.",
+ "calculation": "ga:goalCompletionsAll / ga:searchUniques"
+ }
+ }, {
+ "id": "ga:goalValueAllPerSearch",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Internal Search",
+ "status": "PUBLIC",
+ "uiName": "Per Search Goal Value",
+ "description": "The average goal value of a search on your property.",
+ "calculation": "ga:goalValueAll / ga:searchUniques"
+ }
+ }, {
+ "id": "ga:pageLoadTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Page Load Time (ms)",
+ "description": "Total Page Load Time is the amount of time (in milliseconds) it takes for pages from the sample set to load, from initiation of the pageview (e.g. click on a page link) to load completion in the browser."
+ }
+ }, {
+ "id": "ga:pageLoadSample",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Page Load Sample",
+ "description": "The sample set (or count) of pageviews used to calculate the average page load time."
+ }
+ }, {
+ "id": "ga:avgPageLoadTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Avg. Page Load Time (sec)",
+ "description": "The average amount of time (in seconds) it takes for pages from the sample set to load, from initiation of the pageview (e.g. click on a page link) to load completion in the browser.",
+ "calculation": "(ga:pageLoadTime / ga:pageLoadSample / 1000)"
+ }
+ }, {
+ "id": "ga:domainLookupTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Domain Lookup Time (ms)",
+ "description": "The total amount of time (in milliseconds) spent in DNS lookup for this page among all samples."
+ }
+ }, {
+ "id": "ga:avgDomainLookupTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Avg. Domain Lookup Time (sec)",
+ "description": "The average amount of time (in seconds) spent in DNS lookup for this page.",
+ "calculation": "(ga:domainLookupTime / ga:speedMetricsSample / 1000)"
+ }
+ }, {
+ "id": "ga:pageDownloadTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Page Download Time (ms)",
+ "description": "The total amount of time (in milliseconds) to download this page among all samples."
+ }
+ }, {
+ "id": "ga:avgPageDownloadTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Avg. Page Download Time (sec)",
+ "description": "The average amount of time (in seconds) to download this page.",
+ "calculation": "(ga:pageDownloadTime / ga:speedMetricsSample / 1000)"
+ }
+ }, {
+ "id": "ga:redirectionTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Redirection Time (ms)",
+ "description": "The total amount of time (in milliseconds) spent in redirects before fetching this page among all samples. If there are no redirects, the value for this metric is expected to be 0."
+ }
+ }, {
+ "id": "ga:avgRedirectionTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Avg. Redirection Time (sec)",
+ "description": "The average amount of time (in seconds) spent in redirects before fetching this page. If there are no redirects, the value for this metric is expected to be 0.",
+ "calculation": "(ga:redirectionTime / ga:speedMetricsSample / 1000)"
+ }
+ }, {
+ "id": "ga:serverConnectionTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Server Connection Time (ms)",
+ "description": "The total amount of time (in milliseconds) spent in establishing TCP connection for this page among all samples."
+ }
+ }, {
+ "id": "ga:avgServerConnectionTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Avg. Server Connection Time (sec)",
+ "description": "The average amount of time (in seconds) spent in establishing TCP connection for this page.",
+ "calculation": "(ga:serverConnectionTime / ga:speedMetricsSample / 1000)"
+ }
+ }, {
+ "id": "ga:serverResponseTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Server Response Time (ms)",
+ "description": "The total amount of time (in milliseconds) your server takes to respond to a user request among all samples, including the network time from user's location to your server."
+ }
+ }, {
+ "id": "ga:avgServerResponseTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Avg. Server Response Time (sec)",
+ "description": "The average amount of time (in seconds) your server takes to respond to a user request, including the network time from user's location to your server.",
+ "calculation": "(ga:serverResponseTime / ga:speedMetricsSample / 1000)"
+ }
+ }, {
+ "id": "ga:speedMetricsSample",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Speed Metrics Sample",
+ "description": "The sample set (or count) of pageviews used to calculate the averages for site speed metrics. This metric is used in all site speed average calculations including avgDomainLookupTime, avgPageDownloadTime, avgRedirectionTime, avgServerConnectionTime, and avgServerResponseTime."
+ }
+ }, {
+ "id": "ga:domInteractiveTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Document Interactive Time (ms)",
+ "description": "The time the browser takes (in milliseconds) to parse the document (DOMInteractive), including the network time from the user's location to your server. At this time, the user can interact with the Document Object Model even though it is not fully loaded."
+ }
+ }, {
+ "id": "ga:avgDomInteractiveTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Avg. Document Interactive Time (sec)",
+ "description": "The average time (in seconds) it takes the browser to parse the document and execute deferred and parser-inserted scripts including the network time from the user's location to your server.",
+ "calculation": "(ga:domInteractiveTime / ga:domLatencyMetricsSample / 1000)"
+ }
+ }, {
+ "id": "ga:domContentLoadedTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Document Content Loaded Time (ms)",
+ "description": "The time the browser takes (in milliseconds) to parse the document and execute deferred and parser-inserted scripts (DOMContentLoaded), including the network time from the user's location to your server. Parsing of the document is finished, the Document Object Model is ready, but referenced style sheets, images, and subframes may not be finished loading. This event is often the starting point for javascript framework execution, e.g., JQuery's onready() callback, etc."
+ }
+ }, {
+ "id": "ga:avgDomContentLoadedTime",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "Avg. Document Content Loaded Time (sec)",
+ "description": "The average time (in seconds) it takes the browser to parse the document.",
+ "calculation": "(ga:domContentLoadedTime / ga:domLatencyMetricsSample / 1000)"
+ }
+ }, {
+ "id": "ga:domLatencyMetricsSample",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Site Speed",
+ "status": "PUBLIC",
+ "uiName": "DOM Latency Metrics Sample",
+ "description": "The sample set (or count) of pageviews used to calculate the averages for site speed DOM metrics. This metric is used in the avgDomContentLoadedTime and avgDomInteractiveTime calculations."
+ }
+ }, {
+ "id": "ga:appInstallerId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "App Tracking",
+ "status": "PUBLIC",
+ "uiName": "App Installer ID",
+ "description": "ID of the installer (e.g., Google Play Store) from which the app was downloaded. By default, the app installer id is set based on the PackageManager#getInstallerPackageName method.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:appVersion",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "App Tracking",
+ "status": "PUBLIC",
+ "uiName": "App Version",
+ "description": "The version of the application.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:appName",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "App Tracking",
+ "status": "PUBLIC",
+ "uiName": "App Name",
+ "description": "The name of the application.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:appId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "App Tracking",
+ "status": "PUBLIC",
+ "uiName": "App ID",
+ "description": "The ID of the application.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:screenName",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "App Tracking",
+ "status": "PUBLIC",
+ "uiName": "Screen Name",
+ "description": "The name of the screen.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:screenDepth",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "App Tracking",
+ "status": "PUBLIC",
+ "uiName": "Screen Depth",
+ "description": "The number of screenviews per session reported as a string. Can be useful for historgrams.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:landingScreenName",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "App Tracking",
+ "status": "PUBLIC",
+ "uiName": "Landing Screen",
+ "description": "The name of the first screen viewed.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:exitScreenName",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "App Tracking",
+ "status": "PUBLIC",
+ "uiName": "Exit Screen",
+ "description": "The name of the screen when the user exited the application.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:screenviews",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "App Tracking",
+ "status": "PUBLIC",
+ "uiName": "Screen Views",
+ "description": "The total number of screenviews.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:appviews",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:screenviews",
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "App Tracking",
+ "status": "DEPRECATED",
+ "uiName": "Screen Views",
+ "description": "The total number of screenviews.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:uniqueScreenviews",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "App Tracking",
+ "status": "PUBLIC",
+ "uiName": "Unique Screen Views",
+ "description": "The number of different (unique) screenviews within a session.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:uniqueAppviews",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:uniqueScreenviews",
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "App Tracking",
+ "status": "DEPRECATED",
+ "uiName": "Unique Screen Views",
+ "description": "The number of different (unique) screenviews within a session.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:screenviewsPerSession",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "App Tracking",
+ "status": "PUBLIC",
+ "uiName": "Screens / Session",
+ "description": "The average number of screenviews per session.",
+ "calculation": "ga:screenviews / ga:sessions"
+ }
+ }, {
+ "id": "ga:appviewsPerVisit",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:screenviewsPerSession",
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "App Tracking",
+ "status": "DEPRECATED",
+ "uiName": "Screens / Session",
+ "description": "The average number of screenviews per session.",
+ "calculation": "ga:screenviews / ga:sessions"
+ }
+ }, {
+ "id": "ga:timeOnScreen",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "TIME",
+ "group": "App Tracking",
+ "status": "PUBLIC",
+ "uiName": "Time on Screen",
+ "description": "The time spent viewing the current screen.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:avgScreenviewDuration",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "TIME",
+ "group": "App Tracking",
+ "status": "PUBLIC",
+ "uiName": "Avg. Time on Screen",
+ "description": "The average amount of time users spent on a screen in seconds."
+ }
+ }, {
+ "id": "ga:eventCategory",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Event Tracking",
+ "status": "PUBLIC",
+ "uiName": "Event Category",
+ "description": "The category of the event.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:eventAction",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Event Tracking",
+ "status": "PUBLIC",
+ "uiName": "Event Action",
+ "description": "The action of the event.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:eventLabel",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Event Tracking",
+ "status": "PUBLIC",
+ "uiName": "Event Label",
+ "description": "The label of the event.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:totalEvents",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Event Tracking",
+ "status": "PUBLIC",
+ "uiName": "Total Events",
+ "description": "The total number of events for the profile, across all categories.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:uniqueEvents",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Event Tracking",
+ "status": "PUBLIC",
+ "uiName": "Unique Events",
+ "description": "The total number of unique events for the profile, across all categories."
+ }
+ }, {
+ "id": "ga:eventValue",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Event Tracking",
+ "status": "PUBLIC",
+ "uiName": "Event Value",
+ "description": "The total value of events for the profile.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:avgEventValue",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Event Tracking",
+ "status": "PUBLIC",
+ "uiName": "Avg. Value",
+ "description": "The average value of an event.",
+ "calculation": "ga:eventValue / ga:totalEvents"
+ }
+ }, {
+ "id": "ga:sessionsWithEvent",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Event Tracking",
+ "status": "PUBLIC",
+ "uiName": "Sessions with Event",
+ "description": "The total number of sessions with events.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:visitsWithEvent",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:sessionsWithEvent",
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Event Tracking",
+ "status": "DEPRECATED",
+ "uiName": "Sessions with Event",
+ "description": "The total number of sessions with events.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:eventsPerSessionWithEvent",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Event Tracking",
+ "status": "PUBLIC",
+ "uiName": "Events / Session with Event",
+ "description": "The average number of events per session with event.",
+ "calculation": "ga:totalEvents / ga:sessionsWithEvent"
+ }
+ }, {
+ "id": "ga:eventsPerVisitWithEvent",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:eventsPerSessionWithEvent",
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Event Tracking",
+ "status": "DEPRECATED",
+ "uiName": "Events / Session with Event",
+ "description": "The average number of events per session with event.",
+ "calculation": "ga:totalEvents / ga:sessionsWithEvent"
+ }
+ }, {
+ "id": "ga:transactionId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Transaction ID",
+ "description": "The transaction ID for the shopping cart purchase as supplied by your ecommerce tracking method.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:affiliation",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Affiliation",
+ "description": "Typically used to designate a supplying company or brick and mortar location; product affiliation.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:sessionsToTransaction",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Sessions to Transaction",
+ "description": "The number of sessions between users' purchases and the related campaigns that lead to the purchases.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:visitsToTransaction",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:sessionsToTransaction",
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "DEPRECATED",
+ "uiName": "Sessions to Transaction",
+ "description": "The number of sessions between users' purchases and the related campaigns that lead to the purchases.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:daysToTransaction",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Days to Transaction",
+ "description": "The number of days between users' purchases and the related campaigns that lead to the purchases.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productSku",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product SKU",
+ "description": "The product sku for purchased items as you have defined them in your ecommerce tracking application.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productName",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product",
+ "description": "The product name for purchased items as supplied by your ecommerce tracking application.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productCategory",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product Category",
+ "description": "Any product variations (size, color) for purchased items as supplied by your ecommerce application. Not compatible with Enhanced Ecommerce.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:currencyCode",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Currency Code",
+ "description": "The local currency code of the transaction based on ISO 4217 standard."
+ }
+ }, {
+ "id": "ga:transactions",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Transactions",
+ "description": "The total number of transactions.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:transactionsPerSession",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Ecommerce Conversion Rate",
+ "description": "The average number of transactions for a session on your property.",
+ "calculation": "ga:transactions / ga:sessions"
+ }
+ }, {
+ "id": "ga:transactionsPerVisit",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:transactionsPerSession",
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Ecommerce",
+ "status": "DEPRECATED",
+ "uiName": "Ecommerce Conversion Rate",
+ "description": "The average number of transactions for a session on your property.",
+ "calculation": "ga:transactions / ga:sessions"
+ }
+ }, {
+ "id": "ga:transactionRevenue",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Revenue",
+ "description": "The total sale revenue provided in the transaction excluding shipping and tax.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:revenuePerTransaction",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Average Order Value",
+ "description": "The average revenue for an e-commerce transaction.",
+ "calculation": "ga:transactionRevenue / ga:transactions"
+ }
+ }, {
+ "id": "ga:transactionRevenuePerSession",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Per Session Value",
+ "description": "Average transaction revenue for a session on your property.",
+ "calculation": "ga:transactionRevenue / ga:sessions"
+ }
+ }, {
+ "id": "ga:transactionRevenuePerVisit",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:transactionRevenuePerSession",
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "DEPRECATED",
+ "uiName": "Per Session Value",
+ "description": "Average transaction revenue for a session on your property.",
+ "calculation": "ga:transactionRevenue / ga:sessions"
+ }
+ }, {
+ "id": "ga:transactionShipping",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Shipping",
+ "description": "The total cost of shipping.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:transactionTax",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Tax",
+ "description": "The total amount of tax.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:totalValue",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Total Value",
+ "description": "Total value for your property (including total revenue and total goal value).",
+ "calculation": "(ga:transactionRevenue + ga:goalValueAll)"
+ }
+ }, {
+ "id": "ga:itemQuantity",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Quantity",
+ "description": "The total number of items purchased. For example, if users purchase 2 frisbees and 5 tennis balls, 7 items have been purchased.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:uniquePurchases",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Unique Purchases",
+ "description": "The number of product sets purchased. For example, if users purchase 2 frisbees and 5 tennis balls from your site, 2 unique products have been purchased.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:revenuePerItem",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Average Price",
+ "description": "The average revenue per item.",
+ "calculation": "ga:itemRevenue / ga:itemQuantity"
+ }
+ }, {
+ "id": "ga:itemRevenue",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product Revenue",
+ "description": "The total revenue from purchased product items on your property.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:itemsPerPurchase",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Average QTY",
+ "description": "The average quantity of this item (or group of items) sold per purchase.",
+ "calculation": "ga:itemQuantity / ga:uniquePurchases"
+ }
+ }, {
+ "id": "ga:localTransactionRevenue",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Local Revenue",
+ "description": "Transaction revenue in local currency."
+ }
+ }, {
+ "id": "ga:localTransactionShipping",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Local Shipping",
+ "description": "Transaction shipping cost in local currency."
+ }
+ }, {
+ "id": "ga:localTransactionTax",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Local Tax",
+ "description": "Transaction tax in local currency."
+ }
+ }, {
+ "id": "ga:localItemRevenue",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Local Product Revenue",
+ "description": "Product revenue in local currency.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:socialInteractionNetwork",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Interactions",
+ "status": "PUBLIC",
+ "uiName": "Social Source",
+ "description": "For social interactions, a value representing the social network being tracked."
+ }
+ }, {
+ "id": "ga:socialInteractionAction",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Interactions",
+ "status": "PUBLIC",
+ "uiName": "Social Action",
+ "description": "For social interactions, a value representing the social action being tracked (e.g. +1, bookmark)"
+ }
+ }, {
+ "id": "ga:socialInteractionNetworkAction",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Interactions",
+ "status": "PUBLIC",
+ "uiName": "Social Source and Action",
+ "description": "For social interactions, a value representing the concatenation of the socialInteractionNetwork and socialInteractionAction action being tracked at this hit level (e.g. Google: +1)"
+ }
+ }, {
+ "id": "ga:socialInteractionTarget",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Interactions",
+ "status": "PUBLIC",
+ "uiName": "Social Entity",
+ "description": "For social interactions, a value representing the URL (or resource) which receives the social network action."
+ }
+ }, {
+ "id": "ga:socialEngagementType",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Social Interactions",
+ "status": "PUBLIC",
+ "uiName": "Social Type",
+ "description": "Engagement type. Possible values are \"Socially Engaged\" or \"Not Socially Engaged\"."
+ }
+ }, {
+ "id": "ga:socialInteractions",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Social Interactions",
+ "status": "PUBLIC",
+ "uiName": "Social Actions",
+ "description": "The total number of social interactions on your property."
+ }
+ }, {
+ "id": "ga:uniqueSocialInteractions",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Social Interactions",
+ "status": "PUBLIC",
+ "uiName": "Unique Social Actions",
+ "description": "The number of sessions during which the specified social action(s) occurred at least once. This is based on the the unique combination of socialInteractionNetwork, socialInteractionAction, and socialInteractionTarget."
+ }
+ }, {
+ "id": "ga:socialInteractionsPerSession",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Social Interactions",
+ "status": "PUBLIC",
+ "uiName": "Actions Per Social Session",
+ "description": "The number of social interactions per session on your property.",
+ "calculation": "ga:socialInteractions / ga:uniqueSocialInteractions"
+ }
+ }, {
+ "id": "ga:socialInteractionsPerVisit",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:socialInteractionsPerSession",
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "Social Interactions",
+ "status": "DEPRECATED",
+ "uiName": "Actions Per Social Session",
+ "description": "The number of social interactions per session on your property.",
+ "calculation": "ga:socialInteractions / ga:uniqueSocialInteractions"
+ }
+ }, {
+ "id": "ga:userTimingCategory",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "User Timings",
+ "status": "PUBLIC",
+ "uiName": "Timing Category",
+ "description": "A string for categorizing all user timing variables into logical groups for easier reporting purposes.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:userTimingLabel",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "User Timings",
+ "status": "PUBLIC",
+ "uiName": "Timing Label",
+ "description": "The name of the resource's action being tracked.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:userTimingVariable",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "User Timings",
+ "status": "PUBLIC",
+ "uiName": "Timing Variable",
+ "description": "A value that can be used to add flexibility in visualizing user timings in the reports.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:userTimingValue",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "User Timings",
+ "status": "PUBLIC",
+ "uiName": "User Timing (ms)",
+ "description": "The total number of milliseconds for a user timing."
+ }
+ }, {
+ "id": "ga:userTimingSample",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "User Timings",
+ "status": "PUBLIC",
+ "uiName": "User Timing Sample",
+ "description": "The number of hits that were sent for a particular userTimingCategory, userTimingLabel, and userTimingVariable."
+ }
+ }, {
+ "id": "ga:avgUserTimingValue",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "FLOAT",
+ "group": "User Timings",
+ "status": "PUBLIC",
+ "uiName": "Avg. User Timing (sec)",
+ "description": "The average amount of elapsed time.",
+ "calculation": "(ga:userTimingValue / ga:userTimingSample / 1000)"
+ }
+ }, {
+ "id": "ga:exceptionDescription",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Exceptions",
+ "status": "PUBLIC",
+ "uiName": "Exception Description",
+ "description": "The description for the exception.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:exceptions",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Exceptions",
+ "status": "PUBLIC",
+ "uiName": "Exceptions",
+ "description": "The number of exceptions that were sent to Google Analytics.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:exceptionsPerScreenview",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Exceptions",
+ "status": "PUBLIC",
+ "uiName": "Exceptions / Screen",
+ "description": "The number of exceptions thrown divided by the number of screenviews.",
+ "calculation": "ga:exceptions / ga:screenviews"
+ }
+ }, {
+ "id": "ga:fatalExceptions",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Exceptions",
+ "status": "PUBLIC",
+ "uiName": "Crashes",
+ "description": "The number of exceptions where isFatal is set to true.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:fatalExceptionsPerScreenview",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Exceptions",
+ "status": "PUBLIC",
+ "uiName": "Crashes / Screen",
+ "description": "The number of fatal exceptions thrown divided by the number of screenviews.",
+ "calculation": "ga:fatalExceptions / ga:screenviews"
+ }
+ }, {
+ "id": "ga:experimentId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Content Experiments",
+ "status": "PUBLIC",
+ "uiName": "Experiment ID",
+ "description": "The user-scoped id of the content experiment that the user was exposed to when the metrics were reported.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:experimentVariant",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Content Experiments",
+ "status": "PUBLIC",
+ "uiName": "Variation",
+ "description": "The user-scoped id of the particular variation that the user was exposed to during a content experiment.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:dimensionXX",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Custom Variables or Columns",
+ "status": "PUBLIC",
+ "uiName": "Custom Dimension XX",
+ "description": "The name of the requested custom dimension, where XX refers the number/index of the custom dimension.",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "20",
+ "premiumMinTemplateIndex": "1",
+ "premiumMaxTemplateIndex": "200",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:customVarNameXX",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Custom Variables or Columns",
+ "status": "PUBLIC",
+ "uiName": "Custom Variable (Key XX)",
+ "description": "The name for the requested custom variable.",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "5",
+ "premiumMinTemplateIndex": "1",
+ "premiumMaxTemplateIndex": "50",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:metricXX",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Custom Variables or Columns",
+ "status": "PUBLIC",
+ "uiName": "Custom Metric XX Value",
+ "description": "The name of the requested custom metric, where XX refers the number/index of the custom metric.",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "20",
+ "premiumMinTemplateIndex": "1",
+ "premiumMaxTemplateIndex": "200",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:customVarValueXX",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Custom Variables or Columns",
+ "status": "PUBLIC",
+ "uiName": "Custom Variable (Value XX)",
+ "description": "The value for the requested custom variable.",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "5",
+ "premiumMinTemplateIndex": "1",
+ "premiumMaxTemplateIndex": "50",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:date",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Date",
+ "description": "The date of the session formatted as YYYYMMDD."
+ }
+ }, {
+ "id": "ga:year",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Year",
+ "description": "The year of the session. A four-digit year from 2005 to the current year."
+ }
+ }, {
+ "id": "ga:month",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Month of the year",
+ "description": "The month of the session. A two digit integer from 01 to 12."
+ }
+ }, {
+ "id": "ga:week",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Week of the Year",
+ "description": "The week of the session. A two-digit number from 01 to 53. Each week starts on Sunday."
+ }
+ }, {
+ "id": "ga:day",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Day of the month",
+ "description": "The day of the month. A two-digit number from 01 to 31."
+ }
+ }, {
+ "id": "ga:hour",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Hour",
+ "description": "A two-digit hour of the day ranging from 00-23 in the timezone configured for the account. This value is also corrected for daylight savings time, adhering to all local rules for daylight savings time. If your timezone follows daylight savings time, there will be an apparent bump in the number of sessions during the change-over hour (e.g. between 1:00 and 2:00) for the day per year when that hour repeats. A corresponding hour with zero sessions will occur at the opposite changeover. (Google Analytics does not track user time more precisely than hours.)",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:minute",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Minute",
+ "description": "Returns the minute in the hour. The possible values are between 00 and 59.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:nthMonth",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Month Index",
+ "description": "Index for each month in the specified date range. Index for the first month in the date range is 0, 1 for the second month, and so on. The index corresponds to month entries."
+ }
+ }, {
+ "id": "ga:nthWeek",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Week Index",
+ "description": "Index for each week in the specified date range. Index for the first week in the date range is 0, 1 for the second week, and so on. The index corresponds to week entries."
+ }
+ }, {
+ "id": "ga:nthDay",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Day Index",
+ "description": "Index for each day in the specified date range. Index for the first day (i.e., start-date) in the date range is 0, 1 for the second day, and so on."
+ }
+ }, {
+ "id": "ga:nthMinute",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Minute Index",
+ "description": "Index for each minute in the specified date range. Index for the first minute of first day (i.e., start-date) in the date range is 0, 1 for the next minute, and so on."
+ }
+ }, {
+ "id": "ga:dayOfWeek",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Day of Week",
+ "description": "The day of the week. A one-digit number from 0 (Sunday) to 6 (Saturday)."
+ }
+ }, {
+ "id": "ga:dayOfWeekName",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Day of Week Name",
+ "description": "The name of the day of the week (in English)."
+ }
+ }, {
+ "id": "ga:dateHour",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Hour of Day",
+ "description": "Combined values of ga:date and ga:hour."
+ }
+ }, {
+ "id": "ga:yearMonth",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Month of Year",
+ "description": "Combined values of ga:year and ga:month."
+ }
+ }, {
+ "id": "ga:yearWeek",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Week of Year",
+ "description": "Combined values of ga:year and ga:week."
+ }
+ }, {
+ "id": "ga:isoWeek",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "ISO Week of the Year",
+ "description": "The ISO week number, where each week starts with a Monday. Details: http://en.wikipedia.org/wiki/ISO_week_date. ga:isoWeek should only be used with ga:isoYear since ga:year represents gregorian calendar."
+ }
+ }, {
+ "id": "ga:isoYear",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "ISO Year",
+ "description": "The ISO year of the session. Details: http://en.wikipedia.org/wiki/ISO_week_date. ga:isoYear should only be used with ga:isoWeek since ga:week represents gregorian calendar."
+ }
+ }, {
+ "id": "ga:isoYearIsoWeek",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "ISO Week of ISO Year",
+ "description": "Combined values of ga:isoYear and ga:isoWeek."
+ }
+ }, {
+ "id": "ga:dcmClickAd",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Ad (GA Model)",
+ "description": "DCM ad name of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickAdId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Ad ID (GA Model)",
+ "description": "DCM ad ID of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickAdType",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Ad Type (GA Model)",
+ "description": "DCM ad type name of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickAdTypeId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Ad Type ID",
+ "description": "DCM ad type ID of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickAdvertiser",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Advertiser (GA Model)",
+ "description": "DCM advertiser name of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickAdvertiserId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Advertiser ID (GA Model)",
+ "description": "DCM advertiser ID of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickCampaign",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Campaign (GA Model)",
+ "description": "DCM campaign name of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickCampaignId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Campaign ID (GA Model)",
+ "description": "DCM campaign ID of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickCreativeId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Creative ID (GA Model)",
+ "description": "DCM creative ID of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickCreative",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Creative (GA Model)",
+ "description": "DCM creative name of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickRenderingId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Rendering ID (GA Model)",
+ "description": "DCM rendering ID of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickCreativeType",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Creative Type (GA Model)",
+ "description": "DCM creative type name of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickCreativeTypeId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Creative Type ID (GA Model)",
+ "description": "DCM creative type ID of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickCreativeVersion",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Creative Version (GA Model)",
+ "description": "DCM creative version of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickSite",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Site (GA Model)",
+ "description": "Site name where the DCM creative was shown and clicked on for the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickSiteId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Site ID (GA Model)",
+ "description": "DCM site ID where the DCM creative was shown and clicked on for the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickSitePlacement",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Placement (GA Model)",
+ "description": "DCM site placement name of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickSitePlacementId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Placement ID (GA Model)",
+ "description": "DCM site placement ID of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClickSpotId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Floodlight Configuration ID (GA Model)",
+ "description": "DCM Floodlight configuration ID of the DCM click matching the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmFloodlightActivity",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Activity",
+ "description": "DCM Floodlight activity name associated with the floodlight conversion (premium only)."
+ }
+ }, {
+ "id": "ga:dcmFloodlightActivityAndGroup",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Activity and Group",
+ "description": "DCM Floodlight activity name and group name associated with the floodlight conversion (premium only)."
+ }
+ }, {
+ "id": "ga:dcmFloodlightActivityGroup",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Activity Group",
+ "description": "DCM Floodlight activity group name associated with the floodlight conversion (premium only)."
+ }
+ }, {
+ "id": "ga:dcmFloodlightActivityGroupId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Activity Group ID",
+ "description": "DCM Floodlight activity group ID associated with the floodlight conversion (premium only)."
+ }
+ }, {
+ "id": "ga:dcmFloodlightActivityId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Activity ID",
+ "description": "DCM Floodlight activity ID associated with the floodlight conversion (premium only)."
+ }
+ }, {
+ "id": "ga:dcmFloodlightAdvertiserId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Advertiser ID",
+ "description": "DCM Floodlight advertiser ID associated with the floodlight conversion (premium only)."
+ }
+ }, {
+ "id": "ga:dcmFloodlightSpotId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Floodlight Configuration ID",
+ "description": "DCM Floodlight configuration ID associated with the floodlight conversion (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventAd",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Ad",
+ "description": "DCM ad name of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventAdId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Ad ID (DFA Model)",
+ "description": "DCM ad ID of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventAdType",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Ad Type (DFA Model)",
+ "description": "DCM ad type name of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventAdTypeId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Ad Type ID (DFA Model)",
+ "description": "DCM ad type ID of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventAdvertiser",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Advertiser (DFA Model)",
+ "description": "DCM advertiser name of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventAdvertiserId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Advertiser ID (DFA Model)",
+ "description": "DCM advertiser ID of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventAttributionType",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Attribution Type (DFA Model)",
+ "description": "There are two possible values: ClickThrough and ViewThrough. If the last DCM event associated with the Google Analytics session was a click, then the value will be ClickThrough. If the last DCM event associated with the Google Analytics session was an ad impression, then the value will be ViewThrough (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventCampaign",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Campaign (DFA Model)",
+ "description": "DCM campaign name of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventCampaignId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Campaign ID (DFA Model)",
+ "description": "DCM campaign ID of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventCreativeId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Creative ID (DFA Model)",
+ "description": "DCM creative ID of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventCreative",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Creative (DFA Model)",
+ "description": "DCM creative name of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventRenderingId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Rendering ID (DFA Model)",
+ "description": "DCM rendering ID of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventCreativeType",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Creative Type (DFA Model)",
+ "description": "DCM creative type name of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventCreativeTypeId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Creative Type ID (DFA Model)",
+ "description": "DCM creative type ID of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventCreativeVersion",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Creative Version (DFA Model)",
+ "description": "DCM creative version of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventSite",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Site (DFA Model)",
+ "description": "Site name where the DCM creative was shown and clicked on for the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventSiteId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Site ID (DFA Model)",
+ "description": "DCM site ID where the DCM creative was shown and clicked on for the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventSitePlacement",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Placement (DFA Model)",
+ "description": "DCM site placement name of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventSitePlacementId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Placement ID (DFA Model)",
+ "description": "DCM site placement ID of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmLastEventSpotId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Floodlight Configuration ID (DFA Model)",
+ "description": "DCM Floodlight configuration ID of the last DCM event (impression or click within the DCM lookback window) associated with the Google Analytics session (premium only)."
+ }
+ }, {
+ "id": "ga:dcmFloodlightQuantity",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Conversions",
+ "description": "The number of DCM Floodlight conversions (premium only)."
+ }
+ }, {
+ "id": "ga:dcmFloodlightRevenue",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Revenue",
+ "description": "DCM Floodlight revenue (premium only)."
+ }
+ }, {
+ "id": "ga:landingContentGroupXX",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Content Grouping",
+ "status": "PUBLIC",
+ "uiName": "Landing Page Group XX",
+ "description": "The first matching content group in a user's session.",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "5",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:previousContentGroupXX",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Content Grouping",
+ "status": "PUBLIC",
+ "uiName": "Previous Page Group XX",
+ "description": "Refers to content group that was visited before another content group.",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "5",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:contentGroupXX",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Content Grouping",
+ "status": "PUBLIC",
+ "uiName": "Page Group XX",
+ "description": "Content group on a property. A content group is a collection of content providing a logical structure that can be determined by tracking code or page title/url regex match, or predefined rules.",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "5",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:nextContentGroupXX",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Content Grouping",
+ "status": "PUBLIC",
+ "uiName": "Next Page Group XX",
+ "description": "Refers to content group that was visited after another content group.",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "5",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:userAgeBracket",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Audience",
+ "status": "PUBLIC",
+ "uiName": "Age",
+ "description": "Age bracket of user.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:visitorAgeBracket",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:userAgeBracket",
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Audience",
+ "status": "DEPRECATED",
+ "uiName": "Age",
+ "description": "Age bracket of user.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:userGender",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Audience",
+ "status": "PUBLIC",
+ "uiName": "Gender",
+ "description": "Gender of user.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:visitorGender",
+ "kind": "analytics#column",
+ "attributes": {
+ "replacedBy": "ga:userGender",
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Audience",
+ "status": "DEPRECATED",
+ "uiName": "Gender",
+ "description": "Gender of user.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:interestOtherCategory",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Audience",
+ "status": "PUBLIC",
+ "uiName": "Other Category",
+ "description": "Indicates that users are more likely to be interested in learning about the specified category, and more likely to be ready to purchase.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:interestAffinityCategory",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Audience",
+ "status": "PUBLIC",
+ "uiName": "Affinity Category (reach)",
+ "description": "Indicates that users are more likely to be interested in learning about the specified category.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:interestInMarketCategory",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Audience",
+ "status": "PUBLIC",
+ "uiName": "In-Market Segment",
+ "description": "Indicates that users are more likely to be ready to purchase products or services in the specified category.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:adsenseRevenue",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Adsense",
+ "status": "PUBLIC",
+ "uiName": "AdSense Revenue",
+ "description": "The total revenue from AdSense ads.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:adsenseAdUnitsViewed",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Adsense",
+ "status": "PUBLIC",
+ "uiName": "AdSense Ad Units Viewed",
+ "description": "The number of AdSense ad units viewed. An Ad unit is a set of ads displayed as a result of one piece of the AdSense ad code. Details: https://support.google.com/adsense/answer/32715?hl=en",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:adsenseAdsViewed",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Adsense",
+ "status": "PUBLIC",
+ "uiName": "AdSense Impressions",
+ "description": "The number of AdSense ads viewed. Multiple ads can be displayed within an Ad Unit.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:adsenseAdsClicks",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Adsense",
+ "status": "PUBLIC",
+ "uiName": "AdSense Ads Clicked",
+ "description": "The number of times AdSense ads on your site were clicked.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:adsensePageImpressions",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Adsense",
+ "status": "PUBLIC",
+ "uiName": "AdSense Page Impressions",
+ "description": "The number of pageviews during which an AdSense ad was displayed. A page impression can have multiple Ad Units.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:adsenseCTR",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Adsense",
+ "status": "PUBLIC",
+ "uiName": "AdSense CTR",
+ "description": "The percentage of page impressions that resulted in a click on an AdSense ad.",
+ "calculation": "ga:adsenseAdsClicks/ga:adsensePageImpressions"
+ }
+ }, {
+ "id": "ga:adsenseECPM",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Adsense",
+ "status": "PUBLIC",
+ "uiName": "AdSense eCPM",
+ "description": "The estimated cost per thousand page impressions. It is your AdSense Revenue per 1000 page impressions.",
+ "calculation": "ga:adsenseRevenue/(ga:adsensePageImpressions/1000)"
+ }
+ }, {
+ "id": "ga:adsenseExits",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Adsense",
+ "status": "PUBLIC",
+ "uiName": "AdSense Exits",
+ "description": "The number of sessions that ended due to a user clicking on an AdSense ad.",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:adsenseViewableImpressionPercent",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Adsense",
+ "status": "PUBLIC",
+ "uiName": "AdSense Viewable Impression %",
+ "description": "The percentage of impressions that were viewable."
+ }
+ }, {
+ "id": "ga:adsenseCoverage",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Adsense",
+ "status": "PUBLIC",
+ "uiName": "AdSense Coverage",
+ "description": "The percentage of ad requests that returned at least one ad."
+ }
+ }, {
+ "id": "ga:campaignCode",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Traffic Sources",
+ "status": "PUBLIC",
+ "uiName": "Campaign Code",
+ "description": "When using manual campaign tracking, the value of the utm_id campaign tracking parameter."
+ }
+ }, {
+ "id": "ga:channelGrouping",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Channel Grouping",
+ "status": "PUBLIC",
+ "uiName": "Default Channel Grouping",
+ "description": "The default channel grouping that is shared within the View (Profile).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:checkoutOptions",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Checkout Options",
+ "description": "User options specified during the checkout process, e.g., FedEx, DHL, UPS for delivery options or Visa, MasterCard, AmEx for payment options. This dimension should be used along with ga:shoppingStage (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:correlationModelId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Related Products",
+ "status": "PUBLIC",
+ "uiName": "Correlation Model ID",
+ "description": "Correlation Model ID for related products."
+ }
+ }, {
+ "id": "ga:internalPromotionCreative",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Internal Promotion Creative",
+ "description": "The creative content designed for a promotion (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:internalPromotionId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Internal Promotion ID",
+ "description": "The ID of the promotion (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:internalPromotionName",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Internal Promotion Name",
+ "description": "The name of the promotion (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:internalPromotionPosition",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Internal Promotion Position",
+ "description": "The position of the promotion on the web page or application screen (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:isTrueViewVideoAd",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Adwords",
+ "status": "PUBLIC",
+ "uiName": "TrueView Video Ad",
+ "description": "'Yes' or 'No' - Indicates whether the ad is an AdWords TrueView video ad."
+ }
+ }, {
+ "id": "ga:nthHour",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Time",
+ "status": "PUBLIC",
+ "uiName": "Hour Index",
+ "description": "Index for each hour in the specified date range. Index for the first hour of first day (i.e., start-date) in the date range is 0, 1 for the next hour, and so on."
+ }
+ }, {
+ "id": "ga:orderCouponCode",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Order Coupon Code",
+ "description": "Code for the order-level coupon (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productBrand",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product Brand",
+ "description": "The brand name under which the product is sold (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productCategoryHierarchy",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product Category (Enhanced Ecommerce)",
+ "description": "The hierarchical category in which the product is classified (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productCategoryLevelXX",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product Category Level XX",
+ "description": "Level (1-5) in the product category hierarchy, starting from the top (Enhanced Ecommerce).",
+ "minTemplateIndex": "1",
+ "maxTemplateIndex": "5",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productCouponCode",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product Coupon Code",
+ "description": "Code for the product-level coupon (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productListName",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product List Name",
+ "description": "The name of the product list in which the product appears (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productListPosition",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product List Position",
+ "description": "The position of the product in the product list (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productVariant",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product Variant",
+ "description": "The specific variation of a product, e.g., XS, S, M, L for size or Red, Blue, Green, Black for color (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:queryProductId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Related Products",
+ "status": "PUBLIC",
+ "uiName": "Queried Product ID",
+ "description": "ID of the product being queried."
+ }
+ }, {
+ "id": "ga:queryProductName",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Related Products",
+ "status": "PUBLIC",
+ "uiName": "Queried Product Name",
+ "description": "Name of the product being queried."
+ }
+ }, {
+ "id": "ga:queryProductVariation",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Related Products",
+ "status": "PUBLIC",
+ "uiName": "Queried Product Variation",
+ "description": "Variation of the product being queried."
+ }
+ }, {
+ "id": "ga:relatedProductId",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Related Products",
+ "status": "PUBLIC",
+ "uiName": "Related Product ID",
+ "description": "ID of the related product."
+ }
+ }, {
+ "id": "ga:relatedProductName",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Related Products",
+ "status": "PUBLIC",
+ "uiName": "Related Product Name",
+ "description": "Name of the related product."
+ }
+ }, {
+ "id": "ga:relatedProductVariation",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Related Products",
+ "status": "PUBLIC",
+ "uiName": "Related Product Variation",
+ "description": "Variation of the related product."
+ }
+ }, {
+ "id": "ga:shoppingStage",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "DIMENSION",
+ "dataType": "STRING",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Shopping Stage",
+ "description": "Various stages of the shopping experience that users completed in a session, e.g., PRODUCT_VIEW, ADD_TO_CART, CHECKOUT, etc. (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:buyToDetailRate",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Buy-to-Detail Rate",
+ "description": "Unique purchases divided by views of product detail pages (Enhanced Ecommerce)."
+ }
+ }, {
+ "id": "ga:cartToDetailRate",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Cart-to-Detail Rate",
+ "description": "Product adds divided by views of product details (Enhanced Ecommerce)."
+ }
+ }, {
+ "id": "ga:correlationScore",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Related Products",
+ "status": "PUBLIC",
+ "uiName": "Correlation Score",
+ "description": "Correlation Score for related products."
+ }
+ }, {
+ "id": "ga:dcmCPC",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA CPC",
+ "description": "DCM Cost Per Click (premium only)."
+ }
+ }, {
+ "id": "ga:dcmCTR",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA CTR",
+ "description": "DCM Click Through Rate (premium only)."
+ }
+ }, {
+ "id": "ga:dcmClicks",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Clicks",
+ "description": "DCM Total Clicks (premium only)."
+ }
+ }, {
+ "id": "ga:dcmCost",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Cost",
+ "description": "DCM Total Cost (premium only)."
+ }
+ }, {
+ "id": "ga:dcmImpressions",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Impressions",
+ "description": "DCM Total Impressions (premium only)."
+ }
+ }, {
+ "id": "ga:dcmMargin",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA Margin",
+ "description": "DCM Margin (premium only)."
+ }
+ }, {
+ "id": "ga:dcmROI",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA ROI",
+ "description": "DCM Return On Investment (premium only)."
+ }
+ }, {
+ "id": "ga:dcmRPC",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "DoubleClick Campaign Manager",
+ "status": "PUBLIC",
+ "uiName": "DFA RPC",
+ "description": "DCM Revenue Per Click (premium only)."
+ }
+ }, {
+ "id": "ga:hits",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Session",
+ "status": "PUBLIC",
+ "uiName": "Hits",
+ "description": "Total number of hits sent to Google Analytics. This metric sums all hit types (e.g. pageview, event, timing, etc.).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:internalPromotionCTR",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Internal Promotion CTR",
+ "description": "The rate at which users clicked through to view the internal promotion (ga:internalPromotionClicks / ga:internalPromotionViews) - (Enhanced Ecommerce).",
+ "calculation": "ga:internalPromotionClicks / ga:internalPromotionViews"
+ }
+ }, {
+ "id": "ga:internalPromotionClicks",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Internal Promotion Clicks",
+ "description": "The number of clicks on an internal promotion (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:internalPromotionViews",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Internal Promotion Views",
+ "description": "The number of views of an internal promotion (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:localProductRefundAmount",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Local Product Refund Amount",
+ "description": "Refund amount for a given product in the local currency (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:localRefundAmount",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Local Refund Amount",
+ "description": "Total refund amount for the transaction in the local currency (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productAddsToCart",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product Adds To Cart",
+ "description": "Number of times the product was added to the shopping cart (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productCheckouts",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product Checkouts",
+ "description": "Number of times the product was included in the check-out process (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productDetailViews",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product Detail Views",
+ "description": "Number of times users viewed the product-detail page (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productListCTR",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "PERCENT",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product List CTR",
+ "description": "The rate at which users clicked through on the product in a product list (ga:productListClicks / ga:productListViews) - (Enhanced Ecommerce).",
+ "calculation": "ga:productListClicks / ga:productListViews"
+ }
+ }, {
+ "id": "ga:productListClicks",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product List Clicks",
+ "description": "Number of times users clicked the product when it appeared in the product list (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productListViews",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product List Views",
+ "description": "Number of times the product appeared in a product list (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productRefundAmount",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product Refund Amount",
+ "description": "Total refund amount associated with the product (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productRefunds",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product Refunds",
+ "description": "Number of times a refund was issued for the product (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productRemovesFromCart",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product Removes From Cart",
+ "description": "Number of times the product was removed from shopping cart (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:productRevenuePerPurchase",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Product Revenue per Purchase",
+ "description": "Average product revenue per purchase (commonly used with Product Coupon Code) (ga:itemRevenue / ga:uniquePurchases) - (Enhanced Ecommerce).",
+ "calculation": "ga:itemRevenue / ga:uniquePurchases"
+ }
+ }, {
+ "id": "ga:quantityAddedToCart",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Quantity Added To Cart",
+ "description": "Number of product units added to the shopping cart (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:quantityCheckedOut",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Quantity Checked Out",
+ "description": "Number of product units included in check out (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:quantityRefunded",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Quantity Refunded",
+ "description": "Number of product units refunded (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:quantityRemovedFromCart",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Quantity Removed From Cart",
+ "description": "Number of product units removed from cart (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:queryProductQuantity",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Related Products",
+ "status": "PUBLIC",
+ "uiName": "Queried Product Quantity",
+ "description": "Quantity of the product being queried."
+ }
+ }, {
+ "id": "ga:refundAmount",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "CURRENCY",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Refund Amount",
+ "description": "Currency amount refunded for a transaction (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }, {
+ "id": "ga:relatedProductQuantity",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Related Products",
+ "status": "PUBLIC",
+ "uiName": "Related Product Quantity",
+ "description": "Quantity of the related product."
+ }
+ }, {
+ "id": "ga:totalRefunds",
+ "kind": "analytics#column",
+ "attributes": {
+ "type": "METRIC",
+ "dataType": "INTEGER",
+ "group": "Ecommerce",
+ "status": "PUBLIC",
+ "uiName": "Refunds",
+ "description": "Number of refunds that have been issued (Enhanced Ecommerce).",
+ "allowedInSegments": "true"
+ }
+ }]
+}
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/test/metadata/index.js b/polymer_1.0.4/bower_components/ga-api-utils/test/metadata/index.js
new file mode 100644
index 0000000..fc53de2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/test/metadata/index.js
@@ -0,0 +1,96 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+/* global describe, gapi, it */
+
+var metadata = require('../../lib/metadata');
+var assert = require('assert');
+var fixtures = require('./fixtures/columns.json');
+var sinon = require('sinon');
+
+require('./stubs/gapi');
+
+describe('metadata', function() {
+
+ describe('.get', function() {
+
+ it('returns a "thenable" that is resolved with an account summaries array.',
+ function(done) {
+
+ var returnValue = metadata.get();
+ assert('then' in returnValue);
+
+ returnValue.then(function(metadata) {
+ assert.deepEqual(metadata.all(), fixtures.items);
+ done();
+ })
+ .catch(done);
+
+ });
+
+ it('does not query the API more than once, even with multiple calls.',
+ function(done) {
+
+ var listSpy =
+ sinon.spy(gapi.client.analytics.metadata.columns, 'list');
+
+ metadata.get().then(function(metadata1) {
+ metadata.get().then(function(metadata2) {
+ metadata.get().then(function(metadata3) {
+
+ assert(listSpy.callCount === 0);
+ assert.equal(metadata1, metadata2);
+ assert.equal(metadata2, metadata3);
+ assert.deepEqual(metadata3.all(), fixtures.items);
+
+ listSpy.restore();
+ done();
+ })
+ .catch(done);
+ });
+ });
+ });
+
+ it('accepts an optional parameter to clear the cache.', function(done) {
+
+ var listSpy =
+ sinon.spy(gapi.client.analytics.metadata.columns, 'list');
+
+ metadata.get(true).then(function(metadata1) {
+ metadata.get(true).then(function(metadata2) {
+ metadata.get(true).then(function(metadata3) {
+ assert.equal(listSpy.callCount, 3);
+
+ // When clearing the cache these should be deepEqual but
+ // not the same object.
+ assert.notEqual(metadata1, metadata2);
+ assert.notEqual(metadata2, metadata3);
+ assert.deepEqual(metadata1, metadata2);
+ assert.deepEqual(metadata2, metadata3);
+
+ assert.deepEqual(metadata3.all(), fixtures.items);
+
+ listSpy.restore();
+ done();
+ })
+ .catch(done);
+ });
+ });
+
+ });
+
+ });
+
+});
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/test/metadata/metadata.js b/polymer_1.0.4/bower_components/ga-api-utils/test/metadata/metadata.js
new file mode 100644
index 0000000..39e38fb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/test/metadata/metadata.js
@@ -0,0 +1,82 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+/* global describe, it */
+
+require('native-promise-only');
+require('./stubs/gapi');
+
+var Metadata = require('../../lib/metadata/metadata');
+var assert = require('assert');
+
+var columns = require('./fixtures/columns.json').items;
+var metrics = columns.filter(function(column) {
+ return column.attributes.type == 'METRIC';
+});
+var publicMetrics = metrics.filter(function(metric) {
+ return metric.attributes.status == 'PUBLIC';
+});
+var deprecatedMetrics = metrics.filter(function(metric) {
+ return metric.attributes.status == 'DEPRECATED';
+});
+var dimensions = columns.filter(function(column) {
+ return column.attributes.type == 'DIMENSION';
+});
+var publicDimensions = dimensions.filter(function(dimension) {
+ return dimension.attributes.status == 'PUBLIC';
+});
+var deprecatedDimensions = dimensions.filter(function(dimension) {
+ return dimension.attributes.status == 'DEPRECATED';
+});
+
+
+describe('Metadata', function() {
+
+ var metadata = new Metadata(columns);
+
+ describe('#all', function() {
+ it('returns the full list of columns.', function() {
+ assert.deepEqual(metadata.all(), columns);
+ });
+ });
+
+ describe('#allMetrics', function() {
+ it('gets only the columns that are metrics, optionally filtered' +
+ 'by a status parameter.', function() {
+
+ assert.deepEqual(metadata.allMetrics(), metrics);
+ assert.deepEqual(metadata.allMetrics('public'), publicMetrics);
+ assert.deepEqual(metadata.allMetrics('deprecated'), deprecatedMetrics);
+ });
+ });
+
+ describe('#allDimensions', function() {
+ it('gets only the columns that are dimensions, optionally filtered' +
+ 'by a status parameter.', function() {
+
+ assert.deepEqual(metadata.allDimensions(), dimensions);
+ assert.deepEqual(metadata.allDimensions('public'), publicDimensions);
+ assert.deepEqual(metadata.allDimensions('deprecated'),
+ deprecatedDimensions);
+ });
+ });
+
+ describe('#get', function() {
+ it('gets the attributes object of a column given an ID.', function() {
+ assert.deepEqual(metadata.get('ga:users'), columns[7].attributes);
+ });
+ });
+
+});
diff --git a/polymer_1.0.4/bower_components/ga-api-utils/test/metadata/stubs/gapi.js b/polymer_1.0.4/bower_components/ga-api-utils/test/metadata/stubs/gapi.js
new file mode 100644
index 0000000..a80612f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/ga-api-utils/test/metadata/stubs/gapi.js
@@ -0,0 +1,36 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+/* global gapi:true, Promise:true */
+
+var fixtures = require('../fixtures/columns.json');
+var namespace = require('mout/object/namespace');
+
+// Polyfill Promises for node.
+Promise = require('native-promise-only');
+
+// Assign this globally because that's how it is IRL.
+namespace(global, 'gapi.client.analytics.metadata.columns');
+
+gapi.client.analytics.metadata.columns.list = function() {
+
+ var response = { result: fixtures };
+
+ return {
+ then: function(fn) {
+ return Promise.resolve(fn(response));
+ }
+ };
+};
diff --git a/polymer_1.0.4/bower_components/gold-cc-cvc-input/.bower.json b/polymer_1.0.4/bower_components/gold-cc-cvc-input/.bower.json
new file mode 100644
index 0000000..ea55207
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-cvc-input/.bower.json
@@ -0,0 +1,48 @@
+{
+ "name": "gold-cc-cvc-input",
+ "version": "1.0.2",
+ "description": "Provides an input field for a credit card cvc number",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "gold",
+ "input"
+ ],
+ "main": [
+ "gold-cc-cvc-input.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/gold-cc-cvc-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/gold-cc-cvc-input",
+ "ignore": [],
+ "dependencies": {
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "b2c2bbfd4638b891449560a0313208d5fcfff697"
+ },
+ "_source": "git://github.com/PolymerElements/gold-cc-cvc-input.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/gold-cc-cvc-input"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/gold-cc-cvc-input/.gitignore b/polymer_1.0.4/bower_components/gold-cc-cvc-input/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-cvc-input/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/gold-cc-cvc-input/README.md b/polymer_1.0.4/bower_components/gold-cc-cvc-input/README.md
new file mode 100644
index 0000000..4a668a0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-cvc-input/README.md
@@ -0,0 +1,24 @@
+# gold-cc-cvc-input
+
+`gold-cc-cvc-input` is a single-line text field with Material Design styling
+for entering a credit card's CVC (Card Verification Code). It supports both
+4-digit Amex CVCs and non-Amex 3-digit CVCs.
+
+```html
+ <gold-cc-cvc-input></gold-cc-cvc-input>
+
+ <gold-cc-cvc-input card-type="amex"></gold-cc-cvc-input>
+```
+
+It may include an optional label, which by default is "CVC".
+
+```html
+ <gold-cc-cvc-input label="Card Verification Value"></gold-cc-cvc-input>
+```
+
+It can be used together with a `gold-cc-input` by binding the `cardType` property:
+
+```html
+ <gold-cc-input card-type="{{cardType}}"></gold-cc-input>
+ <gold-cc-cvc-input card-type="[[cardType]]"></gold-cc-cvc-input>
+```
diff --git a/polymer_1.0.4/bower_components/gold-cc-cvc-input/bower.json b/polymer_1.0.4/bower_components/gold-cc-cvc-input/bower.json
new file mode 100644
index 0000000..0a93922
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-cvc-input/bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "gold-cc-cvc-input",
+ "version": "1.0.2",
+ "description": "Provides an input field for a credit card cvc number",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "gold",
+ "input"
+ ],
+ "main": [
+ "gold-cc-cvc-input.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/gold-cc-cvc-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/gold-cc-cvc-input",
+ "ignore": [],
+ "dependencies": {
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/gold-cc-cvc-input/cvc_hint.png b/polymer_1.0.4/bower_components/gold-cc-cvc-input/cvc_hint.png
new file mode 100644
index 0000000..81ab3ca
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-cvc-input/cvc_hint.png
Binary files differ
diff --git a/polymer_1.0.4/bower_components/gold-cc-cvc-input/cvc_hint_amex.png b/polymer_1.0.4/bower_components/gold-cc-cvc-input/cvc_hint_amex.png
new file mode 100644
index 0000000..443dd8e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-cvc-input/cvc_hint_amex.png
Binary files differ
diff --git a/polymer_1.0.4/bower_components/gold-cc-cvc-input/demo/index.html b/polymer_1.0.4/bower_components/gold-cc-cvc-input/demo/index.html
new file mode 100644
index 0000000..e6ddd59
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-cvc-input/demo/index.html
@@ -0,0 +1,54 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>gold-cc-cvc-input demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../gold-cc-cvc-input.html">
+
+ <link rel="stylesheet" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+</head>
+<style>
+ gold-cc-cvc-input {
+ width: 80px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+</style>
+<body>
+ <div class="vertical-section-container centered">
+ <h4>Standard</h4>
+ <div class="vertical-section layout horizontal">
+ <gold-cc-cvc-input class="small"></gold-cc-cvc-input>
+ <gold-cc-cvc-input class="small" label="AMEX" card-type="amex"></gold-cc-cvc-input>
+ <gold-cc-cvc-input auto-validate label="Auto"></gold-cc-cvc-input>
+ </div>
+
+ <h4>Pre-validated</h4>
+ <div class="vertical-section layout horizontal">
+ <gold-cc-cvc-input required auto-validate value="123"></gold-cc-cvc-input>
+ <gold-cc-cvc-input required auto-validate card-type="amex" value="1234"></gold-cc-cvc-input>
+ <gold-cc-cvc-input required auto-validate value="12"></gold-cc-cvc-input>
+ </div>
+
+ <h4>Custom error message</h4>
+ <div class="vertical-section">
+ <gold-cc-cvc-input required auto-validate error-message="Please enter a valid CVC"></gold-cc-cvc-input>
+ </div>
+ </div>
+</body>
diff --git a/polymer_1.0.4/bower_components/gold-cc-cvc-input/gold-cc-cvc-input.html b/polymer_1.0.4/bower_components/gold-cc-cvc-input/gold-cc-cvc-input.html
new file mode 100644
index 0000000..4ad9dda
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-cvc-input/gold-cc-cvc-input.html
@@ -0,0 +1,195 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-input/paper-input-behavior.html">
+<link rel="import" href="../paper-input/paper-input-container.html">
+<link rel="import" href="../paper-input/paper-input-error.html">
+<link rel="import" href="../iron-input/iron-input.html">
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
+<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+
+<!--
+`gold-cc-cvc-input` is a single-line text field with Material Design styling
+for entering a credit card's CVC (Card Verification Code). It supports both
+4-digit Amex CVCs and non-Amex 3-digit CVCs
+
+ <gold-cc-cvc-input></gold-cc-cvc-input>
+
+ <gold-cc-cvc-input card-type="amex"></gold-cc-cvc-input>
+
+It may include an optional label, which by default is "CVC".
+
+ <gold-cc-cvc-input label="Card Verification Value"></gold-cc-cvc-input>
+
+It can be used together with a `gold-cc-input` by binding the `cardType` property:
+
+ <gold-cc-input card-type="{{cardType}}"></gold-cc-input>
+ <gold-cc-cvc-input card-type="[[cardType]]"></gold-cc-cvc-input>
+
+### Validation
+
+The input considers a valid amex CVC to be 4 digits long, and 3 digits otherwise.
+The `amex` attribute can also be bound to a `gold-cc-input`'s `card-type` attribute.
+
+The input can be automatically validated as the user is typing by using
+the `auto-validate` and `required` attributes. For manual validation, the
+element also has a `validate()` method, which returns the validity of the
+input as well sets any appropriate error messages and styles.
+
+See `Polymer.PaperInputBehavior` for more API docs.
+
+### Styling
+
+See `Polymer.PaperInputContainer` for a list of custom properties used to
+style this element.
+
+@group Gold Elements
+@hero hero.svg
+@class gold-cc-cvc-input
+@demo demo/index.html
+-->
+
+<dom-module id="gold-cc-cvc-input">
+ <style>
+ :host {
+ display: block;
+ }
+
+ iron-icon {
+ margin-left: 10px;
+ }
+ </style>
+
+ <template>
+ <paper-input-container id="container"
+ disabled$="[[disabled]]"
+ no-label-float="[[noLabelFloat]]"
+ always-float-label="[[_computeAlwaysFloatLabel(alwaysFloatLabel,placeholder)]]"
+ invalid="[[invalid]]">
+
+ <label hidden$="[[!label]]">[[label]]</label>
+
+ <div class="horizontal layout">
+ <input is="iron-input" id="input" class="flex"
+ aria-labelledby$="[[_ariaLabelledBy]]"
+ aria-describedby$="[[_ariaDescribedBy]]"
+ bind-value="{{value}}"
+ prevent-invalid-input allowed-pattern="[0-9]"
+ required$="[[required]]"
+ type="tel"
+ maxlength$="[[_requiredLength]]"
+ autocomplete="cc-csc"
+ name$="[[name]]"
+ disabled$="[[disabled]]"
+ invalid="{{invalid}}"
+ autofocus$="[[autofocus]]"
+ inputmode$="[[inputmode]]"
+ placeholder$="[[placeholder]]"
+ readonly$="[[readonly]]"
+ size$="[[size]]">
+
+ <iron-icon id="icon" src="cvc_hint.png" hidden$="[[_amex]]" alt="cvc"></iron-icon>
+ <iron-icon id="amexIcon" hidden$="[[!_amex]]" src="cvc_hint_amex.png" alt="amex cvc"></iron-icon>
+ </div>
+
+ <template is="dom-if" if="[[errorMessage]]">
+ <paper-input-error>[[errorMessage]]</paper-input-error>
+ </template>
+
+ </paper-input-container>
+ </template>
+</dom-module>
+
+<script>
+(function() {
+ Polymer({
+
+ is: 'gold-cc-cvc-input',
+
+ properties: {
+
+ /**
+ * The label for this input.
+ */
+ label: {
+ type: String,
+ value: 'CVC'
+ },
+
+ /**
+ * The type of card that the CVC is for.
+ */
+ cardType: {
+ type: String,
+ value: ''
+ },
+
+ _requiredLength: {
+ type: Number,
+ computed: '_computeRequiredLength(cardType)'
+ },
+
+ _amex: {
+ type: Boolean,
+ computed: '_computeIsAmex(cardType)'
+ }
+ },
+
+ behaviors: [
+ Polymer.PaperInputBehavior,
+ Polymer.IronFormElementBehavior
+ ],
+
+ listeners: {
+ 'input': '_onInput'
+ },
+
+ ready: function() {
+ this._onInput();
+ },
+
+ _onInput: function() {
+ if (this.autoValidate) {
+ this.validate();
+ }
+ },
+
+ _computeRequiredLength: function(cardType) {
+ return this._computeIsAmex(cardType) ? 4 : 3;
+ },
+
+ _computeIsAmex: function(cardType) {
+ return cardType.toLowerCase() == 'amex';
+ },
+
+ validate: function() {
+ // Empty, non-required input is valid.
+ if (!this.required && this.value == '') {
+ return true;
+ }
+
+ var valid = this.value.length == this._requiredLength;
+
+ // Update the container and its addons (i.e. the custom error-message).
+ this.$.container.invalid = !valid;
+ this.$.container.updateAddons({
+ inputElement: this.$.input,
+ value: this.value,
+ invalid: !valid
+ });
+
+ return valid;
+ }
+ })
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/gold-cc-cvc-input/hero.svg b/polymer_1.0.4/bower_components/gold-cc-cvc-input/hero.svg
new file mode 100755
index 0000000..06aeaf0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-cvc-input/hero.svg
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <rect x="100" y="67" width="26" height="2"/>
+ <g>
+ <path d="M102.2,62h1.9v-6.6l-2,0.7V55l3.2-1.2h0.1V62h1.8v1.1h-5V62z"/>
+ <path d="M115.4,63.1h-6.1v-0.9l3-3.4c0.3-0.3,0.5-0.6,0.7-0.8c0.2-0.2,0.3-0.4,0.4-0.6c0.1-0.2,0.2-0.4,0.2-0.5
+ c0-0.2,0.1-0.3,0.1-0.5c0-0.2,0-0.4-0.1-0.6c-0.1-0.2-0.2-0.4-0.3-0.5c-0.1-0.1-0.3-0.3-0.5-0.3s-0.4-0.1-0.6-0.1
+ c-0.3,0-0.6,0-0.8,0.1s-0.4,0.2-0.6,0.4c-0.2,0.2-0.3,0.4-0.3,0.6s-0.1,0.5-0.1,0.8h-1.3c0-0.4,0.1-0.8,0.2-1.1s0.3-0.6,0.6-0.9
+ c0.3-0.3,0.6-0.5,1-0.6c0.4-0.2,0.8-0.2,1.3-0.2c0.4,0,0.8,0.1,1.1,0.2c0.3,0.1,0.6,0.3,0.9,0.5s0.4,0.5,0.5,0.8s0.2,0.7,0.2,1
+ c0,0.3,0,0.5-0.1,0.8c-0.1,0.3-0.2,0.5-0.4,0.8c-0.2,0.3-0.3,0.5-0.5,0.8c-0.2,0.3-0.4,0.5-0.7,0.8l-2.5,2.7h4.6V63.1z"/>
+ <path d="M118.9,57.9h0.9c0.3,0,0.6,0,0.8-0.1s0.4-0.2,0.5-0.3c0.1-0.1,0.3-0.3,0.3-0.5c0.1-0.2,0.1-0.4,0.1-0.6
+ c0-1.1-0.5-1.6-1.5-1.6c-0.2,0-0.5,0-0.7,0.1c-0.2,0.1-0.4,0.2-0.5,0.3c-0.1,0.1-0.2,0.3-0.3,0.5s-0.1,0.4-0.1,0.6h-1.3
+ c0-0.3,0.1-0.7,0.2-1s0.3-0.6,0.6-0.8c0.2-0.2,0.6-0.4,0.9-0.5c0.4-0.1,0.7-0.2,1.2-0.2c0.4,0,0.8,0.1,1.1,0.2s0.6,0.3,0.9,0.5
+ c0.2,0.2,0.4,0.5,0.6,0.8s0.2,0.7,0.2,1.1c0,0.2,0,0.3-0.1,0.5s-0.1,0.4-0.2,0.6s-0.3,0.3-0.4,0.5c-0.2,0.2-0.4,0.3-0.6,0.4
+ c0.3,0.1,0.6,0.2,0.8,0.4c0.2,0.2,0.3,0.3,0.5,0.5s0.2,0.4,0.2,0.6c0,0.2,0.1,0.4,0.1,0.6c0,0.4-0.1,0.8-0.2,1.2
+ c-0.2,0.3-0.4,0.6-0.6,0.9s-0.6,0.4-0.9,0.5c-0.4,0.1-0.8,0.2-1.2,0.2c-0.4,0-0.8-0.1-1.1-0.2c-0.4-0.1-0.7-0.3-0.9-0.5
+ s-0.5-0.5-0.6-0.8s-0.2-0.7-0.2-1.1h1.3c0,0.2,0,0.4,0.1,0.6c0.1,0.2,0.2,0.4,0.3,0.5c0.1,0.1,0.3,0.2,0.5,0.3s0.4,0.1,0.7,0.1
+ c0.3,0,0.5,0,0.7-0.1c0.2-0.1,0.4-0.2,0.5-0.3c0.1-0.1,0.3-0.3,0.3-0.5c0.1-0.2,0.1-0.5,0.1-0.7c0-0.3,0-0.5-0.1-0.7
+ s-0.2-0.4-0.4-0.5c-0.2-0.1-0.4-0.2-0.6-0.3c-0.2-0.1-0.5-0.1-0.8-0.1h-0.9V57.9z"/>
+ </g>
+ <path d="M151,77H73V44h78V77z M75,75h74V46H75V75z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/gold-cc-cvc-input/index.html b/polymer_1.0.4/bower_components/gold-cc-cvc-input/index.html
new file mode 100644
index 0000000..487bb5c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-cvc-input/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-cc-cvc-input/test/basic.html b/polymer_1.0.4/bower_components/gold-cc-cvc-input/test/basic.html
new file mode 100644
index 0000000..4b25287
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-cvc-input/test/basic.html
@@ -0,0 +1,125 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>gold-cc-cvc-input tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <script src="../../iron-test-helpers/test-helpers.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../gold-cc-cvc-input.html">
+
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <gold-cc-cvc-input></gold-cc-cvc-input>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="amex">
+ <template>
+ <gold-cc-cvc-input card-type="amex" required error-message="error"></gold-cc-cvc-input>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="required">
+ <template>
+ <gold-cc-cvc-input auto-validate required error-message="error"></gold-cc-cvc-input>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+
+ test('max length for a non-amex cc is 3', function() {
+ var input = fixture('basic');
+ assert.equal(input.inputElement.maxLength, 3);
+ });
+
+ test('max length for an amex cc is 4', function() {
+ var input = fixture('amex');
+ assert.equal(input.inputElement.maxLength, 4);
+ });
+
+ test('valid input is ok', function() {
+ var input = fixture('required');
+ input.value='123';
+ input._onInput();
+ forceXIfStamp(input);
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isFalse(container.invalid);
+ });
+
+ test('invalid input is not ok', function() {
+ var input = fixture('required');
+ input.value='13';
+ input._onInput();
+ forceXIfStamp(input);
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isTrue(container.invalid);
+ });
+
+ test('empty required input shows error', function() {
+ var input = fixture('required');
+ forceXIfStamp(input);
+ var error = Polymer.dom(input.root).querySelector('paper-input-error');
+ assert.ok(error, 'paper-input-error exists');
+ assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
+ });
+
+ test('invalid input shows error message after manual validation', function() {
+ var input = fixture('amex');
+ forceXIfStamp(input);
+ var error = Polymer.dom(input.root).querySelector('paper-input-error');
+ assert.ok(error, 'paper-input-error exists');
+
+ // The error message is only displayed after manual validation.
+ assert.equal(getComputedStyle(error).display, 'none', 'error is not display:none');
+ input.validate();
+ assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
+ });
+ });
+
+ suite('a11y', function() {
+
+ test('has aria-labelledby', function() {
+ var input = fixture('basic');
+ assert.isTrue(input.inputElement.hasAttribute('aria-labelledby'))
+ assert.equal(input.inputElement.getAttribute('aria-labelledby'), Polymer.dom(input.root).querySelector('label').id, 'aria-labelledby points to the label');
+ });
+
+ test('required and error has aria-labelledby', function() {
+ var input = fixture('required');
+ assert.isTrue(input.inputElement.hasAttribute('aria-labelledby'))
+ assert.equal(input.inputElement.getAttribute('aria-labelledby'), Polymer.dom(input.root).querySelector('label').id, 'aria-labelledby points to the label');
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-cc-cvc-input/test/index.html b/polymer_1.0.4/bower_components/gold-cc-cvc-input/test/index.html
new file mode 100644
index 0000000..13a0383
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-cvc-input/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>gold-cc-cvc-input tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-cc-expiration-input/.bower.json b/polymer_1.0.4/bower_components/gold-cc-expiration-input/.bower.json
new file mode 100644
index 0000000..f572c2a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-expiration-input/.bower.json
@@ -0,0 +1,49 @@
+{
+ "name": "gold-cc-expiration-input",
+ "version": "1.0.2",
+ "description": "A validating input for a credit card expiration date",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "gold",
+ "input"
+ ],
+ "main": [
+ "gold-cc-expiration-input.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/gold-cc-expiration-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/gold-cc-expiration-input",
+ "ignore": [],
+ "dependencies": {
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
+ "iron-validatable-behavior": "PolymerElements/iron-validatable-behavior#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "0f4b5d39cccb4b59250475ceb8d54cb56b5c5896"
+ },
+ "_source": "git://github.com/PolymerElements/gold-cc-expiration-input.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/gold-cc-expiration-input"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/gold-cc-expiration-input/.gitignore b/polymer_1.0.4/bower_components/gold-cc-expiration-input/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-expiration-input/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/gold-cc-expiration-input/README.md b/polymer_1.0.4/bower_components/gold-cc-expiration-input/README.md
new file mode 100644
index 0000000..d72bc9c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-expiration-input/README.md
@@ -0,0 +1,10 @@
+# gold-cc-expiration-input
+
+`gold-cc-expiration-input` is a Material Design field for entering a valid,
+future date representing a credit card's expiration date.
+Example:
+
+```html
+<gold-cc-expiration-input></gold-cc-expiration-input>
+<gold-cc-expiration-input value="11/15"></gold-cc-expiration-input>
+```
diff --git a/polymer_1.0.4/bower_components/gold-cc-expiration-input/bower.json b/polymer_1.0.4/bower_components/gold-cc-expiration-input/bower.json
new file mode 100644
index 0000000..6956bfc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-expiration-input/bower.json
@@ -0,0 +1,40 @@
+{
+ "name": "gold-cc-expiration-input",
+ "version": "1.0.2",
+ "description": "A validating input for a credit card expiration date",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "gold",
+ "input"
+ ],
+ "main": [
+ "gold-cc-expiration-input.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/gold-cc-expiration-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/gold-cc-expiration-input",
+ "ignore": [],
+ "dependencies": {
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
+ "iron-validatable-behavior": "PolymerElements/iron-validatable-behavior#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/gold-cc-expiration-input/date-input.html b/polymer_1.0.4/bower_components/gold-cc-expiration-input/date-input.html
new file mode 100644
index 0000000..08a9848
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-expiration-input/date-input.html
@@ -0,0 +1,157 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-input/iron-input.html">
+<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="../iron-validatable-behavior/iron-validatable-behavior.html">
+<link rel="import" href="date-validator.html">
+
+<dom-module id="date-input">
+
+ <style>
+ :host {
+ display: inline-block;
+ }
+
+ span {
+ @apply(--paper-input-container-font);
+ opacity: 0.33;
+ text-align: center;
+ }
+
+ input {
+ position: relative; /* to make a stacking context */
+ outline: none;
+ box-shadow: none;
+ padding: 0;
+ width: 100%;
+ background: transparent;
+ border: none;
+ color: var(--paper-input-container-input-color, --primary-text-color);
+ text-align: center;
+
+ @apply(--paper-font-subhead);
+ @apply(--paper-input-container-input);
+ }
+
+ </style>
+
+ <template>
+ <date-validator id="validator"></date-validator>
+
+ <span aria-hidden id="monthLabel" hidden>Month</span>
+ <span aria-hidden id="yearLabel" hidden>Year</span>
+
+ <div class="horizontal layout">
+ <input is="iron-input"
+ aria-labelledby$="[[_computeAriaLabel(ariaLabelPrefix,'monthLabel')]]"
+ required$="[[required]]"
+ maxlength="2"
+ bind-value="{{month}}"
+ placeholder="MM"
+ allowed-pattern="[0-9]"
+ prevent-invalid-input
+ autocomplete="cc-exp-month"
+ type="tel"
+ class="flex">
+ <span>/</span>
+ <input is="iron-input"
+ aria-labelledby$="[[_computeAriaLabel(ariaLabelPrefix,'yearLabel')]]"
+ required$="[[required]]"
+ maxlength="2"
+ bind-value="{{year}}"
+ placeholder="YY"
+ allowed-pattern="[0-9]"
+ prevent-invalid-input
+ autocomplete="cc-exp-year"
+ type="tel"
+ class="flex">
+ </div>
+ </template>
+
+</dom-module>
+
+<script>
+ Polymer({
+
+ is: 'date-input',
+
+ behaviors: [
+ Polymer.IronValidatableBehavior
+ ],
+
+ properties: {
+ /**
+ * Set to true to mark the input as required.
+ */
+ required: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The month component of the date displayed.
+ */
+ month: {
+ type: String
+ },
+
+ /**
+ * The year component of the date displayed.
+ */
+ year: {
+ type: String
+ },
+
+ /**
+ * The date object used by the validator. Has two properties, month and year.
+ */
+ date: {
+ notify: true,
+ type: Object
+ },
+
+ validator: {
+ type: String,
+ value: 'date-validator'
+ },
+
+ ariaLabelPrefix: {
+ type:String
+ }
+
+ },
+
+ observers: [
+ '_computeDate(month,year)'
+ ],
+
+ _computeDate: function(month, year) {
+ // Months are 0-11.
+ this.date = {month: month, year: year};
+ this.fire('dateChanged', this.date);
+ },
+
+ validate: function() {
+ // Empty, non-required input is valid.
+ if (!this.required && this.month == '' && this.year == '') {
+ return true;
+ }
+ this.invalid = !this.$.validator.validate(this.date);
+ this.fire('iron-input-validate');
+ return !this.invalid;
+ },
+
+ _computeAriaLabel: function(dateLabel, monthLabel) {
+ return dateLabel + ' ' + monthLabel;
+ }
+
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/gold-cc-expiration-input/date-validator.html b/polymer_1.0.4/bower_components/gold-cc-expiration-input/date-validator.html
new file mode 100644
index 0000000..d1a7de2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-expiration-input/date-validator.html
@@ -0,0 +1,38 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-validator-behavior/iron-validator-behavior.html">
+
+<script>
+
+ Polymer({
+
+ is: 'date-validator',
+
+ behaviors: [
+ Polymer.IronValidatorBehavior
+ ],
+
+ validate: function(date) {
+ if (!date)
+ return false;
+
+ if (date.month > 11 || date.month < 0)
+ return false;
+
+ var then = new Date ('20' + date.year, date.month);
+ var now = new Date();
+ return (then > now);
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/gold-cc-expiration-input/demo/index.html b/polymer_1.0.4/bower_components/gold-cc-expiration-input/demo/index.html
new file mode 100644
index 0000000..8d05fd6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-expiration-input/demo/index.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>gold-cc-expiration-input demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../gold-cc-expiration-input.html">
+
+ <link rel="stylesheet" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+</head>
+<style>
+ gold-cc-expiration-input {
+ width: 200px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+</style>
+<body>
+ <div class="vertical-section-container centered">
+ <h4>Standard</h4>
+ <div class="vertical-section">
+ <gold-cc-expiration-input></gold-cc-expiration-input>
+ <gold-cc-expiration-input label="Auto-validating" auto-validate></gold-cc-expiration-input>
+ </div>
+
+ <h4>Pre-validated</h4>
+ <div class="vertical-section">
+ <gold-cc-expiration-input auto-validate value="11/15"></gold-cc-expiration-input>
+ <gold-cc-expiration-input auto-validate value="31/23"></gold-cc-expiration-input>
+ <gold-cc-expiration-input auto-validate value="11/"></gold-cc-expiration-input>
+ </div>
+
+ <h4>Custom error message</h4>
+ <div class="vertical-section">
+ <gold-cc-expiration-input required auto-validate error-message="Please enter a valid date" label="Credit Card Expiration"></gold-cc-expiration-input>
+ </div>
+ </div>
+</body>
diff --git a/polymer_1.0.4/bower_components/gold-cc-expiration-input/gold-cc-expiration-input.html b/polymer_1.0.4/bower_components/gold-cc-expiration-input/gold-cc-expiration-input.html
new file mode 100644
index 0000000..40f47c3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-expiration-input/gold-cc-expiration-input.html
@@ -0,0 +1,131 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-input/paper-input-behavior.html">
+<link rel="import" href="../paper-input/paper-input-container.html">
+<link rel="import" href="../paper-input/paper-input-error.html">
+<link rel="import" href="../iron-input/iron-input.html">
+<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
+
+<link rel="import" href="date-input.html">
+
+<!--
+`gold-cc-expiration-input` is a single-line text field with Material Design styling
+for entering a credit card's expiration date
+
+ <gold-cc-expiration-input></gold-cc-expiration-input>
+ <gold-cc-expiration-input value="11/15"></gold-cc-expiration-input>
+
+It may include an optional label, which by default is "Expiration Date".
+
+ <gold-cc-expiration-input label="Date"></gold-cc-expiration-input>
+
+
+### Validation
+
+The input can check whether the entered date is a valid, future date.
+
+The input can be automatically validated as the user is typing by using
+the `auto-validate` and `required` attributes. For manual validation, the
+element also has a `validate()` method, which returns the validity of the
+input as well sets any appropriate error messages and styles.
+
+See `Polymer.PaperInputBehavior` for more API docs.
+
+### Styling
+
+See `Polymer.PaperInputContainer` for a list of custom properties used to
+style this element.
+
+@group Gold Elements
+@hero hero.svg
+@demo demo/index.html
+@class gold-cc-expiration-input
+-->
+
+<dom-module id="gold-cc-expiration-input">
+ <style>
+ :host {
+ display: block;
+ }
+ </style>
+
+ <template>
+
+ <paper-input-container id="container"
+ always-float-label
+ auto-validate="[[autoValidate]]"
+ attr-for-value="date">
+
+ <label hidden$="[[!label]]">[[label]]</label>
+
+ <date-input class="paper-input-input" id="input"
+ aria-label-prefix="[[_ariaLabelledBy]]"
+ required$="[[required]]"
+ month="[[_computeMonth(value)]]"
+ year="[[_computeYear(value)]]"
+ autocomplete$="[[autocomplete]]">
+ </date-input>
+
+ <template is="dom-if" if="[[errorMessage]]">
+ <paper-input-error>[[errorMessage]]</paper-input-error>
+ </template>
+
+ </paper-input-container>
+ </template>
+
+</dom-module>
+
+<script>
+(function() {
+
+ Polymer({
+
+ is: 'gold-cc-expiration-input',
+
+ behaviors: [
+ Polymer.PaperInputBehavior,
+ Polymer.IronFormElementBehavior
+ ],
+
+ properties: {
+ /**
+ * The label for this input.
+ */
+ label: {
+ type: String,
+ value: "Expiration Date"
+ }
+ },
+
+ listeners: {
+ 'dateChanged': '_dateChanged'
+ },
+
+ _dateChanged: function(event) {
+ if (event.detail.month && event.detail.year)
+ this.value = event.detail.month + '/' + event.detail.year;
+ },
+
+ _computeMonth: function(value) {
+ // Date is in MM/YY format.
+ return value.split('/')[0];
+ },
+
+ _computeYear: function(value) {
+ // Date is in MM/YY format.
+ return value.split('/')[1];
+ }
+
+ })
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/gold-cc-expiration-input/hero.svg b/polymer_1.0.4/bower_components/gold-cc-expiration-input/hero.svg
new file mode 100755
index 0000000..b5c2f2f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-expiration-input/hero.svg
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <rect x="64" y="67" width="24" height="2"/>
+ <g>
+ <path d="M73.9,59.6c0,0.6-0.1,1.1-0.2,1.6c-0.1,0.5-0.3,0.8-0.6,1.1c-0.3,0.3-0.6,0.5-0.9,0.7s-0.8,0.2-1.3,0.2
+ c-0.5,0-0.9-0.1-1.3-0.2c-0.4-0.2-0.7-0.4-0.9-0.7c-0.3-0.3-0.5-0.7-0.6-1.1s-0.2-1-0.2-1.6v-2.2c0-0.6,0.1-1.1,0.2-1.6
+ s0.3-0.8,0.6-1.1c0.3-0.3,0.6-0.5,0.9-0.7s0.8-0.2,1.2-0.2c0.5,0,0.9,0.1,1.3,0.2s0.7,0.4,0.9,0.7c0.3,0.3,0.5,0.7,0.6,1.1
+ s0.2,1,0.2,1.6V59.6z M69.2,59.2l3.5-2.6c-0.1-1.3-0.7-1.9-1.7-1.9c-0.6,0-1,0.2-1.3,0.6c-0.3,0.4-0.4,1-0.4,1.8V59.2z M72.7,57.8
+ l-3.5,2.6c0.1,0.6,0.2,1.1,0.5,1.4c0.3,0.3,0.7,0.5,1.2,0.5c0.6,0,1-0.2,1.3-0.6c0.3-0.4,0.4-1,0.4-1.8V57.8z"/>
+ <path d="M80.2,53.8v1.1h-0.1c-0.6,0-1.1,0.1-1.5,0.3c-0.4,0.2-0.7,0.4-0.9,0.7s-0.4,0.6-0.5,1c-0.1,0.4-0.2,0.7-0.2,1.1
+ c0.1-0.1,0.2-0.2,0.4-0.3c0.1-0.1,0.3-0.2,0.5-0.3c0.2-0.1,0.3-0.1,0.5-0.2s0.4-0.1,0.6-0.1c0.5,0,0.9,0.1,1.2,0.3
+ c0.3,0.2,0.6,0.4,0.8,0.7c0.2,0.3,0.4,0.6,0.5,1s0.2,0.7,0.2,1.1c0,0.4-0.1,0.9-0.2,1.2s-0.3,0.7-0.5,1s-0.5,0.5-0.9,0.7
+ c-0.4,0.2-0.8,0.2-1.3,0.2c-0.3,0-0.6,0-0.9-0.1c-0.3-0.1-0.5-0.2-0.8-0.4c-0.2-0.2-0.4-0.4-0.6-0.6c-0.2-0.2-0.3-0.5-0.4-0.7
+ c-0.1-0.3-0.2-0.5-0.2-0.8c-0.1-0.3-0.1-0.6-0.1-0.9v-0.5c0-0.4,0-0.8,0.1-1.3c0-0.4,0.1-0.8,0.3-1.2c0.1-0.4,0.3-0.8,0.5-1.1
+ s0.5-0.6,0.8-0.9s0.7-0.5,1.2-0.6c0.5-0.1,1-0.2,1.6-0.2H80.2z M78.7,58.1c-0.2,0-0.4,0-0.5,0.1c-0.2,0.1-0.3,0.1-0.5,0.3
+ s-0.3,0.2-0.4,0.4C77.1,59,77,59.1,77,59.3v0.4c0,0.4,0,0.8,0.1,1.1c0.1,0.3,0.2,0.6,0.4,0.8c0.2,0.2,0.3,0.4,0.5,0.5
+ c0.2,0.1,0.4,0.2,0.6,0.2c0.3,0,0.5,0,0.7-0.1c0.2-0.1,0.4-0.2,0.5-0.4c0.1-0.2,0.2-0.4,0.3-0.6c0.1-0.2,0.1-0.5,0.1-0.8
+ c0-0.3,0-0.5-0.1-0.8c-0.1-0.2-0.2-0.5-0.3-0.7s-0.3-0.4-0.5-0.5S79,58.1,78.7,58.1z"/>
+ </g>
+ <rect x="120" y="67" width="43" height="2"/>
+ <g>
+ <path d="M131.8,63.1h-6.1v-0.9l3-3.4c0.3-0.3,0.5-0.6,0.7-0.8c0.2-0.2,0.3-0.4,0.4-0.6c0.1-0.2,0.2-0.4,0.2-0.5
+ c0-0.2,0.1-0.3,0.1-0.5c0-0.2,0-0.4-0.1-0.6c-0.1-0.2-0.2-0.4-0.3-0.5c-0.1-0.1-0.3-0.3-0.5-0.3c-0.2-0.1-0.4-0.1-0.6-0.1
+ c-0.3,0-0.6,0-0.8,0.1c-0.2,0.1-0.4,0.2-0.6,0.4c-0.2,0.2-0.3,0.4-0.3,0.6c-0.1,0.2-0.1,0.5-0.1,0.8h-1.3c0-0.4,0.1-0.8,0.2-1.1
+ c0.1-0.3,0.3-0.6,0.6-0.9c0.3-0.3,0.6-0.5,1-0.6s0.8-0.2,1.3-0.2c0.4,0,0.8,0.1,1.1,0.2c0.3,0.1,0.6,0.3,0.9,0.5
+ c0.2,0.2,0.4,0.5,0.5,0.8s0.2,0.7,0.2,1c0,0.3,0,0.5-0.1,0.8s-0.2,0.5-0.4,0.8c-0.2,0.3-0.3,0.5-0.5,0.8s-0.4,0.5-0.7,0.8
+ l-2.5,2.7h4.6V63.1z"/>
+ <path d="M139.7,59.6c0,0.6-0.1,1.1-0.2,1.6c-0.1,0.5-0.3,0.8-0.6,1.1s-0.6,0.5-0.9,0.7c-0.4,0.2-0.8,0.2-1.3,0.2
+ c-0.5,0-0.9-0.1-1.3-0.2s-0.7-0.4-0.9-0.7c-0.3-0.3-0.5-0.7-0.6-1.1c-0.1-0.5-0.2-1-0.2-1.6v-2.2c0-0.6,0.1-1.1,0.2-1.6
+ c0.1-0.5,0.3-0.8,0.6-1.1c0.3-0.3,0.6-0.5,0.9-0.7c0.4-0.2,0.8-0.2,1.2-0.2c0.5,0,0.9,0.1,1.3,0.2c0.4,0.2,0.7,0.4,0.9,0.7
+ c0.3,0.3,0.5,0.7,0.6,1.1c0.1,0.5,0.2,1,0.2,1.6V59.6z M135,59.2l3.5-2.6c-0.1-1.3-0.7-1.9-1.7-1.9c-0.6,0-1,0.2-1.3,0.6
+ c-0.3,0.4-0.4,1-0.4,1.8V59.2z M138.5,57.8l-3.5,2.6c0.1,0.6,0.2,1.1,0.5,1.4s0.7,0.5,1.2,0.5c0.6,0,1-0.2,1.3-0.6
+ c0.3-0.4,0.4-1,0.4-1.8V57.8z"/>
+ <path d="M142,62h1.9v-6.6l-2,0.7V55l3.2-1.2h0.1V62h1.8v1.1h-5V62z"/>
+ <path d="M149.9,58.5l0.5-4.6h4.8V55h-3.7l-0.3,2.4c0.2-0.1,0.4-0.2,0.6-0.3s0.5-0.1,0.9-0.1c0.4,0,0.8,0.1,1.2,0.2
+ c0.3,0.1,0.6,0.4,0.9,0.6c0.2,0.3,0.4,0.6,0.5,1s0.2,0.8,0.2,1.3c0,0.4-0.1,0.9-0.2,1.2c-0.1,0.4-0.3,0.7-0.5,1
+ c-0.2,0.3-0.5,0.5-0.9,0.6s-0.8,0.2-1.3,0.2c-0.4,0-0.7-0.1-1.1-0.2c-0.3-0.1-0.6-0.3-0.9-0.5s-0.5-0.5-0.6-0.8s-0.3-0.7-0.3-1.1
+ h1.2c0.1,0.5,0.3,0.9,0.6,1.2c0.3,0.3,0.7,0.4,1.2,0.4c0.3,0,0.5,0,0.7-0.1c0.2-0.1,0.4-0.2,0.5-0.4s0.2-0.4,0.3-0.6
+ c0.1-0.3,0.1-0.5,0.1-0.8c0-0.3,0-0.5-0.1-0.8c-0.1-0.2-0.2-0.5-0.3-0.6s-0.3-0.3-0.6-0.4c-0.2-0.1-0.5-0.2-0.8-0.2
+ c-0.2,0-0.4,0-0.5,0c-0.1,0-0.3,0.1-0.4,0.1c-0.1,0-0.2,0.1-0.3,0.2c-0.1,0.1-0.2,0.2-0.3,0.2L149.9,58.5z"/>
+ </g>
+ <path d="M102,77H49V44h53V77z M51,75h49V46H51V75z"/>
+ <path d="M175,77h-68V44h68V77z M109,75h64V46h-64V75z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/gold-cc-expiration-input/index.html b/polymer_1.0.4/bower_components/gold-cc-expiration-input/index.html
new file mode 100644
index 0000000..4ecb058
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-expiration-input/index.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <title>gold-cc-expiration-input</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-cc-expiration-input/test/basic.html b/polymer_1.0.4/bower_components/gold-cc-expiration-input/test/basic.html
new file mode 100644
index 0000000..d969839
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-expiration-input/test/basic.html
@@ -0,0 +1,126 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>gold-cc-expiration-input tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <script src="../../iron-test-helpers/test-helpers.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../gold-cc-expiration-input.html">
+
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <gold-cc-expiration-input auto-validate required error-message="error"></gold-cc-expiration-input>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+ test('invalid input is not ok', function() {
+ var input = fixture('basic');
+ input.value='1234';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isTrue(container.invalid);
+ });
+
+ test('misformed dates are not ok', function() {
+ var input = fixture('basic');
+ input.value='33/33';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isTrue(container.invalid);
+ });
+
+ test('past dates are not ok', function() {
+ var input = fixture('basic');
+ input.value='11/00';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isTrue(container.invalid);
+ });
+
+ test('future dates are ok', function() {
+ var input = fixture('basic');
+ // Note: this test will start failing in 2099. Apologies, future maintainers.
+ input.value='11/99';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isFalse(container.invalid);
+ assert.equal(input.value, '11/99')
+ });
+
+ test('value is updated correctly ', function() {
+ var input = fixture('basic');
+ input.querySelector('.paper-input-input').month = 11;
+ input.querySelector('.paper-input-input').year = 15;
+ assert.equal(input.value, '11/15');
+ });
+
+ test('empty required input shows error', function() {
+ var input = fixture('basic');
+ forceXIfStamp(input);
+
+ var error = Polymer.dom(input.root).querySelector('paper-input-error');
+ assert.ok(error, 'paper-input-error exists');
+ assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
+ });
+
+ });
+
+ suite('a11y', function() {
+
+ test('has aria-labelledby', function() {
+ var input = fixture('basic');
+ var month = input.querySelectorAll('input')[0];
+ var year = input.querySelectorAll('input')[1];
+ var label = Polymer.dom(input.root).querySelector('label').id;
+
+ assert.ok(month);
+ assert.ok(year);
+
+ assert.isTrue(month.hasAttribute('aria-labelledby'));
+ assert.isTrue(year.hasAttribute('aria-labelledby'));
+
+ assert.equal(month.getAttribute('aria-labelledby'), label + ' monthLabel');
+ assert.equal(year.getAttribute('aria-labelledby'), label + ' yearLabel');
+ });
+
+ });
+
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-cc-expiration-input/test/index.html b/polymer_1.0.4/bower_components/gold-cc-expiration-input/test/index.html
new file mode 100644
index 0000000..1b7ce28
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-expiration-input/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>gold-cc-expiration-input tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/.bower.json b/polymer_1.0.4/bower_components/gold-cc-input/.bower.json
new file mode 100644
index 0000000..070d4cd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/.bower.json
@@ -0,0 +1,48 @@
+{
+ "name": "gold-cc-input",
+ "version": "1.0.4",
+ "description": "A credit card input field",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "input"
+ ],
+ "main": [
+ "gold-cc-input.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/gold-cc-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/gold-cc-input",
+ "ignore": [],
+ "dependencies": {
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.4",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.4",
+ "commit": "5282b72cb5f403cee3b6494a06b9b5cef76165c9"
+ },
+ "_source": "git://github.com/PolymerElements/gold-cc-input.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/gold-cc-input"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/.gitignore b/polymer_1.0.4/bower_components/gold-cc-input/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/README.md b/polymer_1.0.4/bower_components/gold-cc-input/README.md
new file mode 100644
index 0000000..e20976a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/README.md
@@ -0,0 +1,9 @@
+# gold-cc-input
+
+`gold-cc-input` is a Material Design field for entering a credit card number.
+
+Example:
+
+```html
+<gold-cc-input></gold-cc-input>
+```
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/bower.json b/polymer_1.0.4/bower_components/gold-cc-input/bower.json
new file mode 100644
index 0000000..4a17fd3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "gold-cc-input",
+ "version": "1.0.4",
+ "description": "A credit card input field",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "input"
+ ],
+ "main": [
+ "gold-cc-input.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/gold-cc-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/gold-cc-input",
+ "ignore": [],
+ "dependencies": {
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/cc-validator.js b/polymer_1.0.4/bower_components/gold-cc-input/cc-validator.js
new file mode 100644
index 0000000..58d67e6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/cc-validator.js
@@ -0,0 +1,192 @@
+/*
+jQuery Credit Card Validator 1.0
+
+Copyright 2012-2015 Pawel Decowski
+
+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.
+ */
+
+ (function(global) {
+ 'use strict';
+
+ function validateCreditCard (input) {
+ var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+ var bind, card, card_type, card_types, get_card_type, is_valid_length, is_valid_luhn, normalize, validate, validate_number, _i, _len, _ref;
+ card_types = [
+ {
+ name: 'amex',
+ icon: 'images/amex.png',
+ pattern: /^3[47]/,
+ valid_length: [15]
+ }, {
+ name: 'diners_club',
+ icon: 'images/diners_club.png',
+ pattern: /^30[0-5]/,
+ valid_length: [14]
+ }, {
+ name: 'diners_club',
+ icon: 'images/diners_club.png',
+ pattern: /^36/,
+ valid_length: [14]
+ }, {
+ name: 'jcb',
+ icon: 'images/jcb.png',
+ pattern: /^35(2[89]|[3-8][0-9])/,
+ valid_length: [16]
+ }, {
+ name: 'laser',
+ pattern: /^(6304|670[69]|6771)/,
+ valid_length: [16, 17, 18, 19]
+ }, {
+ name: 'visa_electron',
+ pattern: /^(4026|417500|4508|4844|491(3|7))/,
+ valid_length: [16]
+ }, {
+ name: 'visa',
+ icon: 'images/visa.png',
+ pattern: /^4/,
+ valid_length: [16]
+ }, {
+ name: 'mastercard',
+ icon: 'images/mastercard.png',
+ pattern: /^5[1-5]/,
+ valid_length: [16]
+ }, {
+ name: 'maestro',
+ pattern: /^(5018|5020|5038|6304|6759|676[1-3])/,
+ valid_length: [12, 13, 14, 15, 16, 17, 18, 19]
+ }, {
+ name: 'discover',
+ icon: 'images/discover.png',
+ pattern: /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/,
+ valid_length: [16]
+ }
+ ];
+
+ var options = {};
+
+ if (options.accept == null) {
+ options.accept = (function() {
+ var _i, _len, _results;
+ _results = [];
+ for (_i = 0, _len = card_types.length; _i < _len; _i++) {
+ card = card_types[_i];
+ _results.push(card.name);
+ }
+ return _results;
+ })();
+ }
+ _ref = options.accept;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ card_type = _ref[_i];
+ if (__indexOf.call((function() {
+ var _j, _len1, _results;
+ _results = [];
+ for (_j = 0, _len1 = card_types.length; _j < _len1; _j++) {
+ card = card_types[_j];
+ _results.push(card.name);
+ }
+ return _results;
+ })(), card_type) < 0) {
+ throw "Credit card type '" + card_type + "' is not supported";
+ }
+ }
+
+ get_card_type = function(number) {
+ var _j, _len1, _ref1;
+ _ref1 = (function() {
+ var _k, _len1, _ref1, _results;
+ _results = [];
+ for (_k = 0, _len1 = card_types.length; _k < _len1; _k++) {
+ card = card_types[_k];
+ if (_ref1 = card.name, __indexOf.call(options.accept, _ref1) >= 0) {
+ _results.push(card);
+ }
+ }
+ return _results;
+ })();
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ card_type = _ref1[_j];
+ if (number.match(card_type.pattern)) {
+ return card_type;
+ }
+ }
+ return null;
+ };
+
+ is_valid_luhn = function(number) {
+ var digit, n, sum, _j, _len1, _ref1;
+ sum = 0;
+ _ref1 = number.split('').reverse();
+ for (n = _j = 0, _len1 = _ref1.length; _j < _len1; n = ++_j) {
+ digit = _ref1[n];
+ digit = +digit;
+ if (n % 2) {
+ digit *= 2;
+ if (digit < 10) {
+ sum += digit;
+ } else {
+ sum += digit - 9;
+ }
+ } else {
+ sum += digit;
+ }
+ }
+ return sum % 10 === 0;
+ };
+
+ is_valid_length = function(number, card_type) {
+ var _ref1;
+ return _ref1 = number.length, __indexOf.call(card_type.valid_length, _ref1) >= 0;
+ };
+
+ validate_number = (function(_this) {
+ return function(number) {
+ var length_valid, luhn_valid;
+ card_type = get_card_type(number);
+ luhn_valid = false;
+ length_valid = false;
+ if (card_type != null) {
+ luhn_valid = is_valid_luhn(number);
+ length_valid = is_valid_length(number, card_type);
+ }
+ return {
+ card_type: card_type,
+ valid: luhn_valid && length_valid,
+ luhn_valid: luhn_valid,
+ length_valid: length_valid
+ };
+ };
+ })(this);
+
+ normalize = function(number) {
+ return number.replace(/[ -]/g, '');
+ };
+
+ validate = (function(_this) {
+ return function() {
+ return validate_number(normalize(input));
+ };
+ })(this);
+
+ return validate(input);
+ };
+
+ global.CreditCardValidator = {
+ validate: validateCreditCard
+ };
+ })(this);
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/demo/index.html b/polymer_1.0.4/bower_components/gold-cc-input/demo/index.html
new file mode 100644
index 0000000..10dee07
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/demo/index.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>gold-cc-input demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../gold-cc-input.html">
+
+ <link rel="stylesheet" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+
+</head>
+<body>
+ <div class="vertical-section-container centered">
+ <h4>Standard</h4>
+ <div class="vertical-section">
+ <gold-cc-input></gold-cc-input>
+ <gold-cc-input auto-validate label="Auto-validating"></gold-cc-input>
+ </div>
+
+ <h4>Pre-validated</h4>
+ <div class="vertical-section">
+ <gold-cc-input label="Visa" value="4000 0000 0000 0002" auto-validate></gold-cc-input>
+ <gold-cc-input label= "MasterCard" value="5100 0000 0000 0008" auto-validate></gold-cc-input>
+ <gold-cc-input label="Discover" value="6011 0000 0000 0004" auto-validate></gold-cc-input>
+ <gold-cc-input label="Invalid Discover Card" value="6011 0000 0000 1233" auto-validate></gold-cc-input>
+ </div>
+
+ <h4>Custom error message</h4>
+ <div class="vertical-section">
+ <gold-cc-input auto-validate label="Cats only" error-message="needs more cats" required></gold-cc-input>
+ <div>
+ </div>
+</body>
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/gold-cc-input.html b/polymer_1.0.4/bower_components/gold-cc-input/gold-cc-input.html
new file mode 100644
index 0000000..74fbbb7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/gold-cc-input.html
@@ -0,0 +1,210 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="../paper-input/paper-input-behavior.html">
+<link rel="import" href="../paper-input/paper-input-container.html">
+<link rel="import" href="../paper-input/paper-input-error.html">
+<link rel="import" href="../iron-input/iron-input.html">
+<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
+<link rel="import" href="../iron-icon/iron-icon.html">
+
+<script src="cc-validator.js"></script>
+
+<!--
+`gold-cc-input` is a single-line text field with Material Design styling
+for entering a credit card number. As the user types, the number will be
+formatted by adding a space every 4 digits.
+
+ <gold-cc-input></gold-cc-input>
+
+It may include an optional label, which by default is "Card number".
+
+ <gold-cc-input label="CC"></gold-cc-input>
+
+### Validation
+
+The input can detect whether a credit card number is valid, and the type
+of credit card it is, using the Luhn checksum. See `http://jquerycreditcardvalidator.com/`
+for more information.
+
+The input can be automatically validated as the user is typing by using
+the `auto-validate` and `required` attributes. For manual validation, the
+element also has a `validate()` method, which returns the validity of the
+input as well sets any appropriate error messages and styles.
+
+See `Polymer.PaperInputBehavior` for more API docs.
+
+### Styling
+
+See `Polymer.PaperInputContainer` for a list of custom properties used to
+style this element.
+
+@group Gold Elements
+@hero hero.svg
+@demo demo/index.html
+@class gold-cc-input
+-->
+
+<dom-module id="gold-cc-input">
+ <style>
+ :host {
+ display: block;
+ }
+
+ /* Use a container so that when hiding the icon, the layout doesn't jump around. */
+ .icon-container {
+ margin-left: 10px;
+ height: 27px;
+ }
+
+ iron-icon {
+ --iron-icon-width: 40px;
+ --iron-icon-height: 24px;
+ }
+ </style>
+
+ <template>
+
+ <paper-input-container id="container"
+ disabled$="[[disabled]]"
+ no-label-float="[[noLabelFloat]]"
+ always-float-label="[[_computeAlwaysFloatLabel(alwaysFloatLabel,placeholder)]]"
+ invalid="[[invalid]]">
+
+ <label hidden$="[[!label]]">[[label]]</label>
+
+ <div class="horizontal layout">
+ <input is="iron-input" id="input"
+ aria-labelledby$="[[_ariaLabelledBy]]"
+ aria-describedby$="[[_ariaDescribedBy]]"
+ bind-value="{{value}}"
+ type="tel"
+ maxlength="30"
+ required$="[[required]]"
+ allowed-pattern="[0-9 ]"
+ prevent-invalid-input
+ autocomplete="cc-number"
+ name$="[[name]]"
+ disabled$="[[disabled]]"
+ invalid="{{invalid}}"
+ autofocus$="[[autofocus]]"
+ inputmode$="[[inputmode]]"
+ placeholder$="[[placeholder]]"
+ readonly$="[[readonly]]"
+ size$="[[size]]">
+ <div class="icon-container"><iron-icon id="icon"></iron-icon></div>
+ </div>
+
+ <template is="dom-if" if="[[errorMessage]]">
+ <paper-input-error>[[errorMessage]]</paper-input-error>
+ </template>
+
+ </paper-input-container>
+ </template>
+
+</dom-module>
+
+<script>
+(function() {
+ Polymer({
+
+ is: 'gold-cc-input',
+
+ behaviors: [
+ Polymer.PaperInputBehavior,
+ Polymer.IronValidatableBehavior,
+ Polymer.IronFormElementBehavior
+ ],
+
+ properties: {
+ /**
+ * The label for this input.
+ */
+ label: {
+ type: String,
+ value: "Card number"
+ },
+
+ /**
+ * The type of the credit card, if it is valid. Empty otherwise.
+ */
+ cardType: {
+ type: String,
+ notify: true
+ },
+ },
+
+ observers: [
+ '_computeValue(value)'
+ ],
+
+ _computeValue: function(value) {
+ var start = this.$.input.selectionStart;
+ var previousCharASpace = this.value.charAt(start - 1) == ' ';
+
+ value = value.replace(/\s+/g, '');
+ var formattedValue = '';
+ for (var i = 0; i < value.length; i++) {
+ // Add a space after every 4 characters.
+ if ((i != 0) && (i % 4 == 0)) {
+ formattedValue += ' ';
+ }
+ formattedValue += value[i];
+ }
+ this.updateValueAndPreserveCaret(formattedValue.trim());
+
+ if (this.autoValidate)
+ this.validate();
+
+ // If the character right before the selection is a newly inserted
+ // space, we need to advance the selection to maintain the caret position.
+ if (!previousCharASpace && this.value.charAt(start - 1) == ' ') {
+ this.$.input.selectionStart = start+1;
+ this.$.input.selectionEnd = start+1;
+ }
+ },
+
+ validate: function() {
+ // Empty, non-required input is valid.
+ if (!this.required && this.value == '') {
+ return true;
+ }
+
+ var result = CreditCardValidator.validate(this.value);
+ var valid = result.valid && result.length_valid;
+ this.cardType = valid ? result.card_type.name : '';
+
+ // Update the container and its addons (i.e. the custom error-message).
+ this.$.container.invalid = !valid;
+ this.$.container.updateAddons({
+ inputElement: this.$.input,
+ value: this.value,
+ invalid: !valid
+ });
+
+ // We don't have icons for all the card types.
+ if (valid && result.card_type.icon) {
+ this.$.icon.src = this.resolveUrl(result.card_type.icon);
+ this.$.icon.alt = this.cardType;
+ this.$.icon.hidden = false;
+ } else {
+ this.$.icon.src = null;
+ this.$.icon.alt = '';
+ this.$.icon.hidden = true;
+ }
+
+ return valid;
+ }
+ })
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/hero.svg b/polymer_1.0.4/bower_components/gold-cc-input/hero.svg
new file mode 100755
index 0000000..6c3910e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/hero.svg
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <rect x="38" y="68" width="33" height="2"/>
+ <rect x="77" y="68" width="33" height="2"/>
+ <rect x="116" y="68" width="33" height="2"/>
+ <rect x="155" y="68" width="33" height="2"/>
+ <g>
+ <path d="M42.3,58.4l2-3.6h1.5l-2.8,4.6l2.9,4.7h-1.5l-2.1-3.6l-2.1,3.6h-1.5l2.9-4.7l-2.8-4.6h1.5L42.3,58.4z"/>
+ <path d="M50.1,58.4l2-3.6h1.5l-2.8,4.6l2.9,4.7h-1.5l-2.1-3.6l-2.1,3.6h-1.5l2.9-4.7l-2.8-4.6h1.5L50.1,58.4z"/>
+ <path d="M57.9,58.4l2-3.6h1.5l-2.8,4.6l2.9,4.7H60L58,60.5l-2.1,3.6h-1.5l2.9-4.7l-2.8-4.6h1.5L57.9,58.4z"/>
+ <path d="M65.7,58.4l2-3.6h1.5l-2.8,4.6l2.9,4.7h-1.5l-2.1-3.6l-2.1,3.6h-1.5l2.9-4.7l-2.8-4.6h1.5L65.7,58.4z"/>
+ <path d="M81.3,58.4l2-3.6h1.5l-2.8,4.6l2.9,4.7h-1.5l-2.1-3.6l-2.1,3.6h-1.5l2.9-4.7l-2.8-4.6h1.5L81.3,58.4z"/>
+ <path d="M89.1,58.4l2-3.6h1.5l-2.8,4.6l2.9,4.7h-1.5l-2.1-3.6l-2.1,3.6h-1.5l2.9-4.7l-2.8-4.6h1.5L89.1,58.4z"/>
+ <path d="M96.9,58.4l2-3.6h1.5l-2.8,4.6l2.9,4.7H99L97,60.5l-2.1,3.6h-1.5l2.9-4.7l-2.8-4.6h1.5L96.9,58.4z"/>
+ <path d="M104.7,58.4l2-3.6h1.5l-2.8,4.6l2.9,4.7h-1.5l-2.1-3.6l-2.1,3.6h-1.5l2.9-4.7l-2.8-4.6h1.5L104.7,58.4z"/>
+ <path d="M120.3,58.4l2-3.6h1.5l-2.8,4.6l2.9,4.7h-1.5l-2.1-3.6l-2.1,3.6h-1.5l2.9-4.7l-2.8-4.6h1.5L120.3,58.4z"/>
+ <path d="M128.1,58.4l2-3.6h1.5l-2.8,4.6l2.9,4.7h-1.5l-2.1-3.6l-2.1,3.6h-1.5l2.9-4.7l-2.8-4.6h1.5L128.1,58.4z"/>
+ <path d="M135.9,58.4l2-3.6h1.5l-2.8,4.6l2.9,4.7H138l-2.1-3.6l-2.1,3.6h-1.5l2.9-4.7l-2.8-4.6h1.5L135.9,58.4z"/>
+ <path d="M143.7,58.4l2-3.6h1.5l-2.8,4.6l2.9,4.7h-1.5l-2.1-3.6l-2.1,3.6h-1.5l2.9-4.7l-2.8-4.6h1.5L143.7,58.4z"/>
+ <path d="M156.8,63h1.9v-6.6l-2,0.7V56l3.2-1.2h0.1V63h1.8v1.1h-5V63z"/>
+ <path d="M170,64.1h-6.1v-0.9l3-3.4c0.3-0.3,0.5-0.6,0.7-0.8c0.2-0.2,0.3-0.4,0.4-0.6c0.1-0.2,0.2-0.4,0.2-0.5
+ c0-0.2,0.1-0.3,0.1-0.5c0-0.2,0-0.4-0.1-0.6c-0.1-0.2-0.2-0.4-0.3-0.5c-0.1-0.1-0.3-0.3-0.5-0.3s-0.4-0.1-0.6-0.1
+ c-0.3,0-0.6,0-0.8,0.1s-0.4,0.2-0.6,0.4c-0.2,0.2-0.3,0.4-0.3,0.6s-0.1,0.5-0.1,0.8h-1.3c0-0.4,0.1-0.8,0.2-1.1s0.3-0.6,0.6-0.9
+ c0.3-0.3,0.6-0.5,1-0.6c0.4-0.2,0.8-0.2,1.3-0.2c0.4,0,0.8,0.1,1.1,0.2c0.3,0.1,0.6,0.3,0.9,0.5s0.4,0.5,0.5,0.8s0.2,0.7,0.2,1
+ c0,0.3,0,0.5-0.1,0.8c-0.1,0.3-0.2,0.5-0.4,0.8c-0.2,0.3-0.3,0.5-0.5,0.8c-0.2,0.3-0.4,0.5-0.7,0.8l-2.5,2.7h4.6V64.1z"/>
+ <path d="M173.5,58.9h0.9c0.3,0,0.6,0,0.8-0.1s0.4-0.2,0.5-0.3c0.1-0.1,0.3-0.3,0.3-0.5c0.1-0.2,0.1-0.4,0.1-0.6
+ c0-1.1-0.5-1.6-1.5-1.6c-0.2,0-0.5,0-0.7,0.1c-0.2,0.1-0.4,0.2-0.5,0.3c-0.1,0.1-0.2,0.3-0.3,0.5s-0.1,0.4-0.1,0.6h-1.3
+ c0-0.3,0.1-0.7,0.2-1s0.3-0.6,0.6-0.8c0.2-0.2,0.6-0.4,0.9-0.5c0.4-0.1,0.7-0.2,1.2-0.2c0.4,0,0.8,0.1,1.1,0.2s0.6,0.3,0.9,0.5
+ c0.2,0.2,0.4,0.5,0.6,0.8s0.2,0.7,0.2,1.1c0,0.2,0,0.3-0.1,0.5s-0.1,0.4-0.2,0.6s-0.3,0.3-0.4,0.5c-0.2,0.2-0.4,0.3-0.6,0.4
+ c0.3,0.1,0.6,0.2,0.8,0.4c0.2,0.2,0.3,0.3,0.5,0.5s0.2,0.4,0.2,0.6c0,0.2,0.1,0.4,0.1,0.6c0,0.4-0.1,0.8-0.2,1.2
+ c-0.2,0.3-0.4,0.6-0.6,0.9s-0.6,0.4-0.9,0.5c-0.4,0.1-0.8,0.2-1.2,0.2c-0.4,0-0.8-0.1-1.1-0.2c-0.4-0.1-0.7-0.3-0.9-0.5
+ s-0.5-0.5-0.6-0.8s-0.2-0.7-0.2-1.1h1.3c0,0.2,0,0.4,0.1,0.6c0.1,0.2,0.2,0.4,0.3,0.5c0.1,0.1,0.3,0.2,0.5,0.3s0.4,0.1,0.7,0.1
+ c0.3,0,0.5,0,0.7-0.1c0.2-0.1,0.4-0.2,0.5-0.3c0.1-0.1,0.3-0.3,0.3-0.5c0.1-0.2,0.1-0.5,0.1-0.7c0-0.3,0-0.5-0.1-0.7
+ s-0.2-0.4-0.4-0.5c-0.2-0.1-0.4-0.2-0.6-0.3c-0.2-0.1-0.5-0.1-0.8-0.1h-0.9V58.9z"/>
+ <path d="M184.7,61h1.3v1h-1.3v2.1h-1.3V62h-4.2v-0.7l4.1-6.4h1.3V61z M180.7,61h2.8v-4.4l-0.2,0.3L180.7,61z"/>
+ </g>
+ <path d="M194,78H31V44h163V78z M33,76h159V46H33V76z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/images/amex.png b/polymer_1.0.4/bower_components/gold-cc-input/images/amex.png
new file mode 100644
index 0000000..c526a17
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/images/amex.png
Binary files differ
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/images/diners_club.png b/polymer_1.0.4/bower_components/gold-cc-input/images/diners_club.png
new file mode 100644
index 0000000..7b1683c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/images/diners_club.png
Binary files differ
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/images/discover.png b/polymer_1.0.4/bower_components/gold-cc-input/images/discover.png
new file mode 100644
index 0000000..2a5eef7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/images/discover.png
Binary files differ
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/images/jcb.png b/polymer_1.0.4/bower_components/gold-cc-input/images/jcb.png
new file mode 100644
index 0000000..5f8f3fd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/images/jcb.png
Binary files differ
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/images/mastercard.png b/polymer_1.0.4/bower_components/gold-cc-input/images/mastercard.png
new file mode 100644
index 0000000..7872601
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/images/mastercard.png
Binary files differ
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/images/visa.png b/polymer_1.0.4/bower_components/gold-cc-input/images/visa.png
new file mode 100644
index 0000000..a5ecbb3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/images/visa.png
Binary files differ
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/index.html b/polymer_1.0.4/bower_components/gold-cc-input/index.html
new file mode 100644
index 0000000..7476ae7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/index.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <title>gold-cc-input</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/test/basic.html b/polymer_1.0.4/bower_components/gold-cc-input/test/basic.html
new file mode 100644
index 0000000..a21fb48
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/test/basic.html
@@ -0,0 +1,136 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>gold-cc-input tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <script src="../../iron-test-helpers/test-helpers.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../gold-cc-input.html">
+
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <gold-cc-input></gold-cc-input>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="ErrorWithoutAutoValidate">
+ <template>
+ <gold-cc-input required error-message="error"></gold-cc-input>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="required">
+ <template>
+ <gold-cc-input auto-validate required error-message="error"></gold-cc-input>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+ test('input is spaced out correctly', function() {
+ var input = fixture('basic');
+ input.value='12345678';
+ assert.equal(input.value, '1234 5678');
+ });
+
+ test('invalid input is not ok', function() {
+ var input = fixture('required');
+ input.value='1234';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isTrue(container.invalid);
+ assert.equal(input.cardType, '');
+ });
+
+ test('valid input is ok', function() {
+ var input = fixture('required');
+ input.value='4000000000000002';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isFalse(container.invalid);
+ assert.equal(input.cardType, 'visa');
+ });
+
+ test('empty required input shows error', function() {
+ var input = fixture('required');
+ forceXIfStamp(input);
+
+ var error = Polymer.dom(input.root).querySelector('paper-input-error');
+ assert.ok(error, 'paper-input-error exists');
+ assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
+ });
+
+ test('invalid input shows error message after manual validation', function() {
+ var input = fixture('ErrorWithoutAutoValidate');
+ forceXIfStamp(input);
+ var error = Polymer.dom(input.root).querySelector('paper-input-error');
+ assert.ok(error, 'paper-input-error exists');
+
+ // The error message is only displayed after manual validation.
+ assert.equal(getComputedStyle(error).display, 'none', 'error is not display:none');
+ input.validate();
+ assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
+ });
+
+ test('caret position is preserved', function() {
+ var input = fixture('required');
+ var ironInput = Polymer.dom(input.root).querySelector('input[is="iron-input"]');
+ input.value='1111 1111';
+ ironInput.selectionStart = 2;
+ ironInput.selectionEnd = 2;
+ input._computeValue('1122 1111 11');
+
+ assert.equal(ironInput.selectionStart, 2, 'selectionStart is preserved');
+ assert.equal(ironInput.selectionEnd, 2, 'selectionEnd is preserved');
+ });
+
+ });
+
+ suite('a11y', function() {
+
+ test('has aria-labelledby', function() {
+ var input = fixture('basic');
+ assert.isTrue(input.inputElement.hasAttribute('aria-labelledby'))
+ assert.equal(input.inputElement.getAttribute('aria-labelledby'), Polymer.dom(input.root).querySelector('label').id, 'aria-labelledby points to the label');
+ });
+
+ test('required and error has aria-labelledby', function() {
+ var input = fixture('required');
+ assert.isTrue(input.inputElement.hasAttribute('aria-labelledby'))
+ assert.equal(input.inputElement.getAttribute('aria-labelledby'), Polymer.dom(input.root).querySelector('label').id, 'aria-labelledby points to the label');
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-cc-input/test/index.html b/polymer_1.0.4/bower_components/gold-cc-input/test/index.html
new file mode 100644
index 0000000..fd1213d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-cc-input/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>gold-cc-input tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-elements/.bower.json b/polymer_1.0.4/bower_components/gold-elements/.bower.json
new file mode 100644
index 0000000..498b737
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-elements/.bower.json
@@ -0,0 +1,43 @@
+{
+ "name": "gold-elements",
+ "version": "1.0.1",
+ "homepage": "https://github.com/PolymerElements/gold-elements",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "The gold elements are built for e-commerce use-cases like checkout flows.",
+ "main": "gold-elements.html",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "google",
+ "ecommerce",
+ "checkout"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "gold-cc-cvc-input": "PolymerElements/gold-cc-cvc-input#^1.0.0",
+ "gold-cc-expiration-input": "PolymerElements/gold-cc-expiration-input#^1.0.0",
+ "gold-cc-input": "PolymerElements/gold-cc-input#^1.0.0",
+ "gold-email-input": "PolymerElements/gold-email-input#^1.0.0",
+ "gold-phone-input": "PolymerElements/gold-phone-input#^1.0.0",
+ "gold-zip-input": "PolymerElements/gold-zip-input#^1.0.0"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "fa713d5a3a275fe86e9961d595f1cdc6e92f2645"
+ },
+ "_source": "git://github.com/PolymerElements/gold-elements.git",
+ "_target": "~1.0.1",
+ "_originalSource": "PolymerElements/gold-elements",
+ "_direct": true
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/gold-elements/README.md b/polymer_1.0.4/bower_components/gold-elements/README.md
new file mode 100644
index 0000000..ba4f883
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-elements/README.md
@@ -0,0 +1,15 @@
+# gold-elements
+Elements built for e-commerce-specific use-cases, like checkout flows.
+
+Current elements include:
+* `gold-cc-cvc-input`: A credit card verification input field
+* `gold-cc-expiration-input`: A field for a credit card expiration date
+* `gold-cc-input`: An input field for a credit card number
+* `gold-email-input`: An input field for an email address
+* `gold-phone-input`: An input field for a phone number
+* `gold-zip-input`: An input field for a zip
+
+[Here](https://github.com/notwaldorf/polymer-gold-elements-demo) is a demo of
+different checkout forms using all of the available gold elements.
+
+
diff --git a/polymer_1.0.4/bower_components/gold-elements/bower.json b/polymer_1.0.4/bower_components/gold-elements/bower.json
new file mode 100644
index 0000000..eefbaa4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-elements/bower.json
@@ -0,0 +1,33 @@
+{
+ "name": "gold-elements",
+ "version": "1.0.1",
+ "homepage": "https://github.com/PolymerElements/gold-elements",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "The gold elements are built for e-commerce use-cases like checkout flows.",
+ "main": "gold-elements.html",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "google",
+ "ecommerce",
+ "checkout"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "gold-cc-cvc-input": "PolymerElements/gold-cc-cvc-input#^1.0.0",
+ "gold-cc-expiration-input": "PolymerElements/gold-cc-expiration-input#^1.0.0",
+ "gold-cc-input": "PolymerElements/gold-cc-input#^1.0.0",
+ "gold-email-input": "PolymerElements/gold-email-input#^1.0.0",
+ "gold-phone-input": "PolymerElements/gold-phone-input#^1.0.0",
+ "gold-zip-input": "PolymerElements/gold-zip-input#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/gold-elements/screenshot.png b/polymer_1.0.4/bower_components/gold-elements/screenshot.png
new file mode 100644
index 0000000..2bd552f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-elements/screenshot.png
Binary files differ
diff --git a/polymer_1.0.4/bower_components/gold-email-input/.bower.json b/polymer_1.0.4/bower_components/gold-email-input/.bower.json
new file mode 100644
index 0000000..8760ef0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-email-input/.bower.json
@@ -0,0 +1,49 @@
+{
+ "name": "gold-email-input",
+ "version": "1.0.2",
+ "description": "An email input field",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "gold",
+ "input"
+ ],
+ "main": [
+ "gold-email-input.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/gold-email-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/gold-email-input",
+ "ignore": [],
+ "dependencies": {
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "9689d879d066beb5d1fed42b205d1c1afa8b11a8"
+ },
+ "_source": "git://github.com/PolymerElements/gold-email-input.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/gold-email-input"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/gold-email-input/.gitignore b/polymer_1.0.4/bower_components/gold-email-input/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-email-input/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/gold-email-input/README.md b/polymer_1.0.4/bower_components/gold-email-input/README.md
new file mode 100644
index 0000000..02ae113
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-email-input/README.md
@@ -0,0 +1,8 @@
+# gold-email-input
+
+`gold-email-input` is a Material Design field for entering a valid email.
+Example:
+
+```html
+<gold-email-input></gold-email-input>
+```
diff --git a/polymer_1.0.4/bower_components/gold-email-input/bower.json b/polymer_1.0.4/bower_components/gold-email-input/bower.json
new file mode 100644
index 0000000..89dee9d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-email-input/bower.json
@@ -0,0 +1,40 @@
+{
+ "name": "gold-email-input",
+ "version": "1.0.2",
+ "description": "An email input field",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "gold",
+ "input"
+ ],
+ "main": [
+ "gold-email-input.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/gold-email-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/gold-email-input",
+ "ignore": [],
+ "dependencies": {
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/gold-email-input/demo/index.html b/polymer_1.0.4/bower_components/gold-email-input/demo/index.html
new file mode 100644
index 0000000..7151276
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-email-input/demo/index.html
@@ -0,0 +1,46 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>gold-email-input demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../gold-email-input.html">
+
+ <link rel="stylesheet" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+
+</head>
+<body>
+ <div class="vertical-section-container centered">
+ <h4>Standard</h4>
+ <div class="vertical-section">
+ <gold-email-input></gold-email-input>
+ <gold-email-input label="Auto-validating" auto-validate></gold-email-input>
+ </div>
+
+ <h4>Pre-validated</h4>
+ <div class="vertical-section">
+ <gold-email-input auto-validate value="batman@gotham.org"></gold-email-input>
+ <gold-email-input auto-validate value="not-a-thing.email"></gold-email-input>
+ </div>
+
+ <h4>Custom error message</h4>
+ <div class="vertical-section">
+ <gold-email-input required auto-validate error-message="Please enter a valid email" label="Email contact"></gold-email-input>
+ </div>
+ </div>
+</body>
diff --git a/polymer_1.0.4/bower_components/gold-email-input/email-validator.html b/polymer_1.0.4/bower_components/gold-email-input/email-validator.html
new file mode 100644
index 0000000..490f6ae
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-email-input/email-validator.html
@@ -0,0 +1,31 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-validator-behavior/iron-validator-behavior.html">
+
+<script>
+
+ Polymer({
+
+ is: 'email-validator',
+
+ behaviors: [
+ Polymer.IronValidatorBehavior
+ ],
+
+ validate: function(value) {
+ var re = /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i;
+ return re.test(value);
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/gold-email-input/gold-email-input.html b/polymer_1.0.4/bower_components/gold-email-input/gold-email-input.html
new file mode 100644
index 0000000..417e4a3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-email-input/gold-email-input.html
@@ -0,0 +1,119 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-input/paper-input-behavior.html">
+<link rel="import" href="../paper-input/paper-input-container.html">
+<link rel="import" href="../paper-input/paper-input-error.html">
+<link rel="import" href="../iron-input/iron-input.html">
+<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
+<link rel="import" href="email-validator.html">
+
+<!--
+`<gold-email-input>` is a single-line text field with Material Design styling
+for entering an email address.
+
+ <gold-email-input></gold-email-input>
+
+It may include an optional label, which by default is "Email".
+
+ <gold-email-input label="your email address"></gold-email-input>
+
+### Validation
+
+The input can be automatically validated as the user is typing by using
+the `auto-validate` and `required` attributes. For manual validation, the
+element also has a `validate()` method, which returns the validity of the
+input as well sets any appropriate error messages and styles.
+
+See `Polymer.PaperInputBehavior` for more API docs.
+
+### Styling
+
+See `Polymer.PaperInputContainer` for a list of custom properties used to
+style this element.
+
+@group Gold Elements
+@hero hero.svg
+@demo demo/index.html
+@class gold-email-input
+-->
+
+<dom-module id="gold-email-input">
+ <style>
+ :host {
+ display: block;
+ }
+ </style>
+
+ <template>
+
+ <paper-input-container id="container"
+ disabled$="[[disabled]]"
+ auto-validate="[[autoValidate]]"
+ attr-for-value="bind-value"
+ no-label-float="[[noLabelFloat]]"
+ always-float-label="[[_computeAlwaysFloatLabel(alwaysFloatLabel,placeholder)]]"
+ invalid="[[invalid]]">
+
+ <label hidden$="[[!label]]">[[label]]</label>
+
+ <email-validator></email-validator>
+
+ <input is="iron-input" id="input"
+ required$="[[required]]"
+ disabled$="[[disabled]]"
+ aria-labelledby$="[[_ariaLabelledBy]]"
+ aria-describedby$="[[_ariaDescribedBy]]"
+ validator="email-validator"
+ bind-value="{{value}}"
+ autocomplete="email"
+ name$="[[name]]"
+ invalid="{{invalid}}"
+ autofocus$="[[autofocus]]"
+ inputmode$="[[inputmode]]"
+ placeholder$="[[placeholder]]"
+ readonly$="[[readonly]]"
+ size$="[[size]]">
+
+ <template is="dom-if" if="[[errorMessage]]">
+ <paper-input-error id="error">[[errorMessage]]</paper-input-error>
+ </template>
+
+ </paper-input-container>
+ </template>
+
+</dom-module>
+
+<script>
+(function() {
+ Polymer({
+
+ is: 'gold-email-input',
+
+ behaviors: [
+ Polymer.PaperInputBehavior,
+ Polymer.IronFormElementBehavior
+ ],
+
+ properties: {
+ /**
+ * The label for this input.
+ */
+ label: {
+ type: String,
+ value: "Email"
+ }
+ }
+
+ })
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/gold-email-input/hero.svg b/polymer_1.0.4/bower_components/gold-email-input/hero.svg
new file mode 100755
index 0000000..fbd9dbc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-email-input/hero.svg
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <polygon points="69,67.7 63,59.7 57,67.7 50.2,58.6 51.8,57.4 57,64.3 63,56.3 69,64.3 75.1,56.3 81.9,65.4 80.3,66.6 75.1,59.7
+ "/>
+ <g>
+ <path d="M98.6,62.8c0,0.3-0.1,0.7-0.1,1s-0.1,0.7-0.3,1s-0.3,0.6-0.4,0.9s-0.4,0.5-0.6,0.7s-0.5,0.4-0.8,0.5S95.7,67,95.3,67
+ c-0.5,0-0.9-0.1-1.2-0.3s-0.6-0.5-0.7-0.9c-0.3,0.4-0.6,0.7-0.9,0.9S91.7,67,91.3,67s-0.7-0.1-1-0.2s-0.5-0.4-0.7-0.7
+ s-0.3-0.7-0.4-1.1s-0.1-0.9,0-1.4c0.1-0.7,0.2-1.3,0.4-1.8s0.5-1,0.8-1.4s0.7-0.7,1.1-0.9s0.8-0.3,1.2-0.3c0.3,0,0.5,0,0.8,0.1
+ s0.4,0.1,0.6,0.2s0.4,0.2,0.5,0.3s0.3,0.2,0.5,0.3l-0.4,4.4c0,0.3,0,0.6,0,0.8s0.1,0.4,0.2,0.5s0.2,0.2,0.3,0.2s0.2,0.1,0.4,0.1
+ c0.3,0,0.5-0.1,0.8-0.2s0.4-0.4,0.6-0.7s0.3-0.6,0.4-1s0.1-0.8,0.2-1.2c0-0.9,0-1.7-0.2-2.5s-0.5-1.4-0.9-1.9s-0.9-0.9-1.5-1.2
+ s-1.4-0.4-2.3-0.4c-0.8,0-1.5,0.2-2.2,0.5s-1.2,0.7-1.7,1.3s-0.8,1.2-1.1,2s-0.4,1.6-0.4,2.5c0,1,0,1.8,0.2,2.6s0.5,1.4,0.9,1.9
+ s0.9,0.9,1.6,1.2s1.3,0.4,2.2,0.4c0.2,0,0.5,0,0.7,0s0.5-0.1,0.7-0.1s0.4-0.1,0.6-0.2s0.4-0.1,0.6-0.2l0.3,1.1
+ c-0.2,0.1-0.4,0.2-0.6,0.3s-0.5,0.2-0.7,0.2s-0.5,0.1-0.8,0.1s-0.5,0-0.8,0c-1,0-1.9-0.2-2.7-0.5s-1.4-0.8-2-1.4s-0.9-1.4-1.2-2.3
+ s-0.4-1.9-0.3-3.1c0-0.7,0.1-1.4,0.3-2s0.4-1.2,0.7-1.8s0.6-1.1,1-1.5s0.8-0.8,1.3-1.1s1-0.6,1.6-0.7s1.2-0.3,1.9-0.3
+ c1,0,1.9,0.2,2.7,0.5s1.4,0.8,1.9,1.4s0.9,1.4,1.1,2.2S98.6,61.7,98.6,62.8z M90.7,63.5c-0.1,0.7,0,1.2,0.2,1.6s0.5,0.6,0.9,0.6
+ c0.1,0,0.2,0,0.4-0.1s0.2-0.1,0.4-0.2s0.2-0.3,0.4-0.4s0.2-0.4,0.3-0.7l0.4-3.9c-0.1,0-0.2-0.1-0.4-0.1s-0.3,0-0.4,0
+ c-0.6,0-1,0.3-1.4,0.8S90.8,62.5,90.7,63.5z"/>
+ </g>
+ <g>
+ <path d="M140,65.8c0-0.2,0-0.3,0.1-0.5s0.1-0.3,0.2-0.4s0.2-0.2,0.4-0.2s0.3-0.1,0.5-0.1s0.4,0,0.5,0.1s0.3,0.1,0.4,0.2
+ s0.2,0.2,0.2,0.4s0.1,0.3,0.1,0.5s0,0.3-0.1,0.4s-0.1,0.3-0.2,0.4s-0.2,0.2-0.4,0.2s-0.3,0.1-0.5,0.1s-0.4,0-0.5-0.1
+ s-0.3-0.1-0.4-0.2s-0.2-0.2-0.2-0.4S140,66,140,65.8z"/>
+ <path d="M150.8,65.7c0.2,0,0.5,0,0.7-0.1s0.5-0.2,0.6-0.3s0.3-0.3,0.4-0.5s0.2-0.4,0.2-0.6h1.5c0,0.4-0.1,0.7-0.3,1.1
+ s-0.4,0.6-0.8,0.9s-0.7,0.5-1.1,0.6s-0.9,0.2-1.3,0.2c-0.6,0-1.2-0.1-1.7-0.3s-0.9-0.5-1.2-0.9s-0.6-0.8-0.7-1.3s-0.2-1-0.2-1.6
+ v-0.3c0-0.6,0.1-1.1,0.2-1.6s0.4-1,0.7-1.3s0.7-0.7,1.2-0.9s1-0.3,1.7-0.3c0.5,0,1,0.1,1.4,0.2s0.8,0.4,1.1,0.7s0.5,0.6,0.7,1
+ s0.3,0.8,0.3,1.2h-1.5c0-0.2-0.1-0.5-0.2-0.7s-0.2-0.4-0.4-0.6s-0.4-0.3-0.6-0.4s-0.5-0.1-0.8-0.1c-0.4,0-0.8,0.1-1.1,0.3
+ s-0.5,0.4-0.7,0.7s-0.3,0.6-0.4,1s-0.1,0.7-0.1,1.1v0.3c0,0.4,0,0.7,0.1,1.1s0.2,0.7,0.4,1s0.4,0.5,0.7,0.7S150.4,65.7,150.8,65.7
+ z"/>
+ <path d="M156.4,62.5c0-0.6,0.1-1.2,0.3-1.7s0.4-1,0.8-1.4s0.7-0.7,1.2-0.9s1-0.3,1.6-0.3c0.6,0,1.1,0.1,1.6,0.3s0.9,0.5,1.2,0.9
+ s0.6,0.8,0.8,1.4s0.3,1.1,0.3,1.7v0.2c0,0.6-0.1,1.2-0.3,1.7s-0.4,1-0.8,1.4s-0.7,0.7-1.2,0.9s-1,0.3-1.6,0.3s-1.1-0.1-1.6-0.3
+ s-0.9-0.5-1.2-0.9s-0.6-0.8-0.8-1.4s-0.3-1.1-0.3-1.7V62.5z M158,62.7c0,0.4,0,0.8,0.1,1.2s0.2,0.7,0.4,1s0.4,0.5,0.7,0.7
+ s0.6,0.2,1,0.2c0.4,0,0.7-0.1,1-0.2s0.5-0.4,0.7-0.7s0.3-0.6,0.4-1s0.1-0.8,0.1-1.2v-0.2c0-0.4,0-0.8-0.1-1.2s-0.2-0.7-0.4-1
+ s-0.4-0.5-0.7-0.7s-0.6-0.2-1-0.2c-0.4,0-0.7,0.1-1,0.2s-0.5,0.4-0.7,0.7s-0.3,0.6-0.4,1s-0.1,0.8-0.1,1.2V62.7z"/>
+ <path d="M167.2,58.4l0.1,0.8c0.2-0.3,0.4-0.6,0.6-0.7s0.6-0.3,1-0.3c0.4,0,0.7,0.1,0.9,0.2s0.5,0.4,0.6,0.7
+ c0.2-0.3,0.4-0.5,0.6-0.7s0.6-0.3,1-0.3c0.3,0,0.6,0.1,0.8,0.2s0.4,0.3,0.6,0.5s0.3,0.5,0.4,0.8s0.1,0.7,0.1,1.2v6h-1.6v-6
+ c0-0.2,0-0.5-0.1-0.6s-0.1-0.3-0.2-0.4s-0.2-0.2-0.3-0.2s-0.2-0.1-0.4-0.1c-0.1,0-0.3,0-0.4,0.1s-0.2,0.1-0.3,0.2
+ s-0.1,0.2-0.2,0.3s-0.1,0.2-0.1,0.4v6.3h-1.6v-6c0-0.5-0.1-0.8-0.2-1s-0.3-0.3-0.6-0.3c-0.2,0-0.4,0.1-0.6,0.2s-0.2,0.2-0.3,0.4
+ v6.8h-1.6v-8.5H167.2z"/>
+ </g>
+ <path d="M134,68c-2,0-3.2-2.5-4-4.6c-0.6-1.6-1.3-3.4-2.2-3.4s-1.6,1.8-2.2,3.4c-0.8,2.2-1.8,4.6-4,4.6c-2.2,0-3.2-2.5-4-4.6
+ c-0.6-1.6-1.3-3.4-2.2-3.4c-0.9,0-1.5,1.8-2.1,3.4c-0.8,2.2-1.8,4.6-4,4.6c-2.2,0-3.2-2.5-4.1-4.6c-0.6-1.6-1.2-3.4-2.2-3.4v-2
+ c2,0,3.2,2.5,4.1,4.6c0.6,1.6,1.3,3.4,2.2,3.4c0.9,0,1.6-1.8,2.2-3.4c0.8-2.2,1.8-4.6,4-4.6c2.2,0,3.2,2.5,4,4.6
+ c0.6,1.6,1.3,3.4,2.2,3.4c0.9,0,1.5-1.8,2.2-3.4c0.8-2.2,1.8-4.6,4-4.6s3.2,2.5,4,4.6c0.6,1.6,1.2,3.4,2.2,3.4V68z"/>
+ <path d="M188,78H37V44h151V78z M39,76h147V46H39V76z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/gold-email-input/index.html b/polymer_1.0.4/bower_components/gold-email-input/index.html
new file mode 100644
index 0000000..00186a4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-email-input/index.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <title>gold-email-input</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-email-input/test/basic.html b/polymer_1.0.4/bower_components/gold-email-input/test/basic.html
new file mode 100644
index 0000000..43fbfe6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-email-input/test/basic.html
@@ -0,0 +1,216 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>gold-email-input tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <script src="../../iron-test-helpers/test-helpers.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../gold-email-input.html">
+
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <gold-email-input auto-validate required error-message="error"></gold-email-input>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+ test('invalid input shows error', function() {
+ var input = fixture('basic');
+ input.value='1234';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isTrue(container.invalid);
+
+ var error = Polymer.dom(input.root).querySelector('paper-input-error');
+ assert.ok(error, 'paper-input-error exists');
+ assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
+ });
+
+ test('valid input does not show error', function() {
+ var input = fixture('basic');
+ input.value='batman@gotham.org';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isFalse(container.invalid);
+
+ var error = Polymer.dom(input.root).querySelector('paper-input-error');
+ assert.ok(error, 'paper-input-error exists');
+ assert.equal(getComputedStyle(error).display, 'none', 'error is display:none');
+ });
+
+ test('empty required input shows error', function() {
+ var input = fixture('basic');
+ forceXIfStamp(input);
+
+ var error = Polymer.dom(input.root).querySelector('paper-input-error');
+ assert.ok(error, 'paper-input-error exists');
+ assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
+ });
+
+ });
+
+ suite('a11y', function() {
+
+ test('has aria-labelledby', function() {
+ var input = fixture('basic');
+ assert.isTrue(input.inputElement.hasAttribute('aria-labelledby'))
+ assert.equal(input.inputElement.getAttribute('aria-labelledby'), Polymer.dom(input.root).querySelector('label').id, 'aria-labelledby points to the label');
+ });
+
+ });
+
+ function testEmail(address, valid) {
+ var input = fixture('basic');
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+
+ input.value = address;
+ var errorString = address + ' should be ' + (valid ? 'valid' : 'invalid');
+ assert.equal(container.invalid, !valid, errorString);
+ }
+
+ suite('valid email address validation', function() {
+
+ test('valid email', function() {
+ testEmail('email@domain.com', true);
+ });
+
+ test('email with a dot in the address field', function() {
+ testEmail('firstname.lastname@domain.com', true);
+ });
+
+ test('email with a subdomain', function() {
+ testEmail('email@subdomain.domain.com', true);
+ });
+
+ test('weird tlds', function() {
+ testEmail('testing+contact@subdomain.domain.pizza', true);
+ });
+
+ test('plus sign is ok', function() {
+ testEmail('firstname+lastname@domain.com', true);
+ });
+
+ test('domain is valid ip', function() {
+ testEmail('email@123.123.123.123', true);
+ });
+
+ test('digits in address', function() {
+ testEmail('1234567890@domain.com', true);
+ });
+
+ test('dash in domain name', function() {
+ testEmail('email@domain-one.com', true);
+ });
+
+ test('dash in address field', function() {
+ testEmail('firstname-lastname@domain.com', true);
+ });
+
+ test('underscore in address field', function() {
+ testEmail('_______@domain-one.com', true);
+ });
+
+ test('dot in tld', function() {
+ testEmail('email@domain.co.jp', true);
+ });
+ });
+
+ suite('invalid email address validation', function() {
+ test('missing @ and domain', function() {
+ testEmail('plainaddress', false);
+ });
+
+ test('missing @', function() {
+ testEmail('email.domain.com', false);
+ });
+
+ test('garbage', function() {
+ testEmail('#@%^%#$@#$@#.com', false);
+ });
+
+ test('missing username', function() {
+ testEmail('@domain.com', false);
+ });
+
+ test('has spaces', function() {
+ testEmail('firstname lastname@domain.com', false);
+ });
+
+ test('encoded html', function() {
+ testEmail('Joe Smith <email@domain.com>', false);
+ });
+
+ test('two @ signs', function() {
+ testEmail('email@domain@domain.com', false);
+ });
+
+ test('leading . in address', function() {
+ testEmail('.email@domain.com', false);
+ });
+
+ test('trailing . in address', function() {
+ testEmail('email.@domain.com', false);
+ });
+
+ test('multiple . in address', function() {
+ testEmail('email..email@domain.com', false);
+ });
+
+ test('unicode in address', function() {
+ testEmail('あいうえお@domain.com', false);
+ });
+
+ test('text after address', function() {
+ testEmail('email@domain.com (Joe Smith)', false);
+ });
+
+ test('missing tld', function() {
+ testEmail('email@domain', false);
+ });
+
+ test('leading dash in front of tld', function() {
+ testEmail('email@-domain', false);
+ });
+
+ test('multiple dots in domain', function() {
+ testEmail('email@domain..com', false);
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-email-input/test/index.html b/polymer_1.0.4/bower_components/gold-email-input/test/index.html
new file mode 100644
index 0000000..feb2634
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-email-input/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>gold-email-input tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-phone-input/.bower.json b/polymer_1.0.4/bower_components/gold-phone-input/.bower.json
new file mode 100644
index 0000000..c399973
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-phone-input/.bower.json
@@ -0,0 +1,48 @@
+{
+ "name": "gold-phone-input",
+ "version": "1.0.3",
+ "description": "A validating input for a phone number",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "gold",
+ "input"
+ ],
+ "main": [
+ "gold-phone-input.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/gold-phone-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/gold-phone-input",
+ "ignore": [],
+ "dependencies": {
+ "iron-input": "PolymerElements/iron-input#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.3",
+ "commit": "fe00c1c940664f4f33e7a166547e2b8f4488fb65"
+ },
+ "_source": "git://github.com/PolymerElements/gold-phone-input.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/gold-phone-input"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/gold-phone-input/.gitignore b/polymer_1.0.4/bower_components/gold-phone-input/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-phone-input/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/gold-phone-input/README.md b/polymer_1.0.4/bower_components/gold-phone-input/README.md
new file mode 100644
index 0000000..7a037a6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-phone-input/README.md
@@ -0,0 +1,13 @@
+# gold-phone-input
+
+`gold-phone-input` is a Material Design field for entering and formatting a
+phone number.
+
+Example:
+
+```html
+<gold-phone-input></gold-phone-input>
+
+<gold-phone-input country-code="33" phone-number-pattern="X-XX-XX-XX-XX">
+</gold-phone-input>
+```
diff --git a/polymer_1.0.4/bower_components/gold-phone-input/bower.json b/polymer_1.0.4/bower_components/gold-phone-input/bower.json
new file mode 100644
index 0000000..c95ca70
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-phone-input/bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "gold-phone-input",
+ "version": "1.0.3",
+ "description": "A validating input for a phone number",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "gold",
+ "input"
+ ],
+ "main": [
+ "gold-phone-input.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/gold-phone-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/gold-phone-input",
+ "ignore": [],
+ "dependencies": {
+ "iron-input": "PolymerElements/iron-input#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/gold-phone-input/demo/index.html b/polymer_1.0.4/bower_components/gold-phone-input/demo/index.html
new file mode 100644
index 0000000..f3bb2cf
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-phone-input/demo/index.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>gold-phone-input demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../gold-phone-input.html">
+
+ <link rel="stylesheet" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+</head>
+<body>
+ <div class="vertical-section-container centered">
+ <h4>Standard</h4>
+ <div class="vertical-section">
+ <gold-phone-input></gold-phone-input>
+ <gold-phone-input auto-validate label="Auto-validating"></gold-phone-input>
+ <gold-phone-input
+ label="France phone number"
+ country-code="33"
+ phone-number-pattern="X-XX-XX-XX-XX"
+ auto-validate
+ required>
+ </gold-phone-input>
+ </div>
+
+ <h4>Pre-validated</h4>
+ <div class="vertical-section">
+ <gold-phone-input country-code="44" auto-validate required></gold-phone-input>
+ <gold-phone-input label="Valid US number" value="415-111-1111" auto-validate></gold-phone-input>
+ <gold-phone-input label="Invalid US number" value="415-111-111" auto-validate></gold-phone-input>
+ </div>
+
+ <h4>Custom error message</h4>
+ <div class="vertical-section">
+ <gold-phone-input auto-validate label="Cats only" error-message="needs more cats" required></gold-phone-input>
+ </div>
+ </div>
+</body>
diff --git a/polymer_1.0.4/bower_components/gold-phone-input/gold-phone-input.html b/polymer_1.0.4/bower_components/gold-phone-input/gold-phone-input.html
new file mode 100644
index 0000000..ef6bfa1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-phone-input/gold-phone-input.html
@@ -0,0 +1,209 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-input/paper-input-behavior.html">
+<link rel="import" href="../paper-input/paper-input-container.html">
+<link rel="import" href="../paper-input/paper-input-error.html">
+<link rel="import" href="../iron-input/iron-input.html">
+<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
+<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+
+<!--
+`<gold-phone-input>` is a single-line text field with Material Design styling
+for entering a phone number.
+
+ <gold-phone-input></gold-phone-input>
+
+It may include an optional label, which by default is "Phone number".
+
+ <gold-phone-input label="call this"></gold-phone-input>
+
+### Validation
+
+By default, the phone number is considered to be a US phone number, and
+will be validated according to the pattern `XXX-XXX-XXXX`, where `X` is a
+digit, and `-` is the separating dash. If you want to customize the input
+for a different area code or number pattern, use the `country-code` and
+`phone-number-pattern` attributes
+
+ <gold-phone-input
+ country-code="33"
+ phone-number-pattern="X-XX-XX-XX-XX">
+ </gold-phone-input>
+
+The input can be automatically validated as the user is typing by using
+the `auto-validate` and `required` attributes. For manual validation, the
+element also has a `validate()` method, which returns the validity of the
+input as well sets any appropriate error messages and styles.
+
+See `Polymer.PaperInputBehavior` for more API docs.
+
+### Styling
+
+See `Polymer.PaperInputContainer` for a list of custom properties used to
+style this element.
+
+@group Gold Elements
+@hero hero.svg
+@demo demo/index.html
+@class gold-phone-input
+-->
+
+<dom-module id="gold-phone-input">
+ <style>
+ :host {
+ display: block;
+ }
+
+ /* TODO: This should be a dropdown */
+ span {
+ @apply(--paper-font-subhead);
+ @apply(--paper-input-container-input);
+ width: 40px;
+ }
+
+ </style>
+
+ <template>
+ <paper-input-container id="container" auto-validate="[[autoValidate]]"
+ disabled$="[[disabled]]"
+ no-label-float="[[noLabelFloat]]"
+ always-float-label="[[_computeAlwaysFloatLabel(alwaysFloatLabel,placeholder)]]"
+ invalid="[[invalid]]">
+
+ <label style="left:40px;" hidden$="[[!label]]">[[label]]</label>
+
+ <div class="horizontal layout">
+ <span>+<span>[[countryCode]]</span></span>
+
+ <input is="iron-input" id="input" class="flex"
+ aria-labelledby$="[[_ariaLabelledBy]]"
+ aria-describedby$="[[_ariaDescribedBy]]"
+ required$="[[required]]"
+ bind-value="{{value}}"
+ name$="[[name]]"
+ allowed-pattern="[0-9\-]"
+ autocomplete="tel"
+ type="tel"
+ prevent-invalid-input
+ disabled$="[[disabled]]"
+ invalid="{{invalid}}"
+ autofocus$="[[autofocus]]"
+ inputmode$="[[inputmode]]"
+ placeholder$="[[placeholder]]"
+ readonly$="[[readonly]]"
+ size$="[[size]]">
+ </div>
+
+ <template is="dom-if" if="[[errorMessage]]">
+ <paper-input-error id="error">[[errorMessage]]</paper-input-error>
+ </template>
+
+ </paper-input-container>
+ </template>
+
+</dom-module>
+
+<script>
+(function() {
+ Polymer({
+
+ is: 'gold-phone-input',
+
+ behaviors: [
+ Polymer.PaperInputBehavior,
+ Polymer.IronFormElementBehavior
+ ],
+
+ properties: {
+ /**
+ * The label for this input.
+ */
+ label: {
+ type: String,
+ value: 'Phone number'
+ },
+
+ /*
+ * The country code that should be recognized and parsed.
+ */
+ countryCode: {
+ type: String,
+ value: '1'
+ },
+
+ /*
+ * The format of a valid phone number, including formatting but excluding
+ * the country code. Use 'X' to denote the digits separated by dashes.
+ */
+ phoneNumberPattern: {
+ type: String,
+ value: 'XXX-XXX-XXXX',
+ observer: '_phoneNumberPatternChanged'
+ }
+ },
+
+ observers: [
+ '_computeValue(value)'
+ ],
+
+ _phoneNumberPatternChanged: function() {
+ // Transform the pattern into a regex the iron-input understands.
+ var regex = '';
+ regex = this.phoneNumberPattern.replace(/\s/g, '\\s');
+ regex = regex.replace(/X/gi, '\\d');
+ regex = regex.replace(/\+/g, '\\+');
+ this.$.input.pattern = regex;
+
+ if (this.autoValidate) {
+ this.$.container.invalid = !this.$.input.validate();
+ }
+ },
+
+ _computeValue: function(value) {
+ var start = this.$.input.selectionStart;
+ var previousCharADash = this.value.charAt(start - 1) == '-';
+
+ // Remove any already-applied formatting.
+ value = value.replace(/-/g, '');
+ var shouldFormat = value.length <= this.phoneNumberPattern.replace(/-/g, '').length;
+ var formattedValue = '';
+
+ // Fill in the dashes according to the specified pattern.
+ var currentDashIndex = 0;
+ var totalDashesAdded = 0;
+ for (var i = 0; i < value.length; i++) {
+ currentDashIndex = this.phoneNumberPattern.indexOf('-', currentDashIndex);
+
+ // Since we remove any formatting first, we need to account added dashes
+ // when counting the position of new dashes in the pattern.
+ if (shouldFormat && i == (currentDashIndex - totalDashesAdded)) {
+ formattedValue += '-';
+ currentDashIndex++;
+ totalDashesAdded++;
+ }
+
+ formattedValue += value[i];
+ }
+ this.updateValueAndPreserveCaret(formattedValue.trim());
+
+ // If the character right before the selection is a newly inserted
+ // dash, we need to advance the selection to maintain the caret position.
+ if (!previousCharADash && this.value.charAt(start - 1) == '-') {
+ this.$.input.selectionStart = start + 1;
+ this.$.input.selectionEnd = start + 1;
+ }
+ }
+
+ })
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/gold-phone-input/hero.svg b/polymer_1.0.4/bower_components/gold-phone-input/hero.svg
new file mode 100755
index 0000000..c6ca9dc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-phone-input/hero.svg
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <rect x="43" y="68" width="33" height="2"/>
+ <rect x="89" y="68" width="33" height="2"/>
+ <rect x="135" y="68" width="42" height="2"/>
+ <g>
+ <path d="M51.9,61h1.3v1h-1.3v2.1h-1.3V62h-4.2v-0.7l4.1-6.4h1.3V61z M47.9,61h2.8v-4.4l-0.2,0.3L47.9,61z"/>
+ <path d="M55.2,63h1.9v-6.6l-2,0.7V56l3.2-1.2h0.1V63h1.8v1.1h-5V63z"/>
+ <path d="M63.1,59.5l0.5-4.6h4.8V56h-3.7l-0.3,2.4c0.2-0.1,0.4-0.2,0.6-0.3s0.5-0.1,0.9-0.1c0.4,0,0.8,0.1,1.2,0.2
+ c0.3,0.1,0.6,0.4,0.9,0.6c0.2,0.3,0.4,0.6,0.5,1s0.2,0.8,0.2,1.3c0,0.4-0.1,0.9-0.2,1.2c-0.1,0.4-0.3,0.7-0.5,1
+ c-0.2,0.3-0.5,0.5-0.9,0.6s-0.8,0.2-1.3,0.2c-0.4,0-0.7-0.1-1.1-0.2c-0.3-0.1-0.6-0.3-0.9-0.5s-0.5-0.5-0.6-0.8s-0.3-0.7-0.3-1.1
+ H64c0.1,0.5,0.3,0.9,0.6,1.2c0.3,0.3,0.7,0.4,1.2,0.4c0.3,0,0.5,0,0.7-0.1c0.2-0.1,0.4-0.2,0.5-0.4s0.2-0.4,0.3-0.6
+ c0.1-0.3,0.1-0.5,0.1-0.8c0-0.3,0-0.5-0.1-0.8c-0.1-0.2-0.2-0.5-0.3-0.6s-0.3-0.3-0.6-0.4c-0.2-0.1-0.5-0.2-0.8-0.2
+ c-0.2,0-0.4,0-0.5,0c-0.1,0-0.3,0.1-0.4,0.1c-0.1,0-0.2,0.1-0.3,0.2s-0.2,0.2-0.3,0.2L63.1,59.5z"/>
+ <path d="M83.5,60.6h-4.9v-1h4.9V60.6z"/>
+ <path d="M94.3,59.5l0.5-4.6h4.8V56h-3.7l-0.3,2.4c0.2-0.1,0.4-0.2,0.6-0.3s0.5-0.1,0.9-0.1c0.4,0,0.8,0.1,1.2,0.2
+ c0.3,0.1,0.6,0.4,0.9,0.6c0.2,0.3,0.4,0.6,0.5,1s0.2,0.8,0.2,1.3c0,0.4-0.1,0.9-0.2,1.2c-0.1,0.4-0.3,0.7-0.5,1
+ c-0.2,0.3-0.5,0.5-0.9,0.6s-0.8,0.2-1.3,0.2c-0.4,0-0.7-0.1-1.1-0.2c-0.3-0.1-0.6-0.3-0.9-0.5s-0.5-0.5-0.6-0.8S94,62.1,94,61.7
+ h1.2c0.1,0.5,0.3,0.9,0.6,1.2c0.3,0.3,0.7,0.4,1.2,0.4c0.3,0,0.5,0,0.7-0.1c0.2-0.1,0.4-0.2,0.5-0.4s0.2-0.4,0.3-0.6
+ c0.1-0.3,0.1-0.5,0.1-0.8c0-0.3,0-0.5-0.1-0.8c-0.1-0.2-0.2-0.5-0.3-0.6s-0.3-0.3-0.6-0.4c-0.2-0.1-0.5-0.2-0.8-0.2
+ c-0.2,0-0.4,0-0.5,0c-0.1,0-0.3,0.1-0.4,0.1c-0.1,0-0.2,0.1-0.3,0.2s-0.2,0.2-0.3,0.2L94.3,59.5z"/>
+ <path d="M102.1,59.5l0.5-4.6h4.8V56h-3.7l-0.3,2.4c0.2-0.1,0.4-0.2,0.6-0.3s0.5-0.1,0.9-0.1c0.4,0,0.8,0.1,1.2,0.2
+ c0.3,0.1,0.6,0.4,0.9,0.6c0.2,0.3,0.4,0.6,0.5,1s0.2,0.8,0.2,1.3c0,0.4-0.1,0.9-0.2,1.2c-0.1,0.4-0.3,0.7-0.5,1
+ c-0.2,0.3-0.5,0.5-0.9,0.6s-0.8,0.2-1.3,0.2c-0.4,0-0.7-0.1-1.1-0.2c-0.3-0.1-0.6-0.3-0.9-0.5s-0.5-0.5-0.6-0.8s-0.3-0.7-0.3-1.1
+ h1.2c0.1,0.5,0.3,0.9,0.6,1.2c0.3,0.3,0.7,0.4,1.2,0.4c0.3,0,0.5,0,0.7-0.1c0.2-0.1,0.4-0.2,0.5-0.4s0.2-0.4,0.3-0.6
+ c0.1-0.3,0.1-0.5,0.1-0.8c0-0.3,0-0.5-0.1-0.8c-0.1-0.2-0.2-0.5-0.3-0.6s-0.3-0.3-0.6-0.4c-0.2-0.1-0.5-0.2-0.8-0.2
+ c-0.2,0-0.4,0-0.5,0c-0.1,0-0.3,0.1-0.4,0.1c-0.1,0-0.2,0.1-0.3,0.2s-0.2,0.2-0.3,0.2L102.1,59.5z"/>
+ <path d="M109.9,59.5l0.5-4.6h4.8V56h-3.7l-0.3,2.4c0.2-0.1,0.4-0.2,0.6-0.3s0.5-0.1,0.9-0.1c0.4,0,0.8,0.1,1.2,0.2
+ c0.3,0.1,0.6,0.4,0.9,0.6c0.2,0.3,0.4,0.6,0.5,1s0.2,0.8,0.2,1.3c0,0.4-0.1,0.9-0.2,1.2c-0.1,0.4-0.3,0.7-0.5,1
+ c-0.2,0.3-0.5,0.5-0.9,0.6s-0.8,0.2-1.3,0.2c-0.4,0-0.7-0.1-1.1-0.2c-0.3-0.1-0.6-0.3-0.9-0.5s-0.5-0.5-0.6-0.8s-0.3-0.7-0.3-1.1
+ h1.2c0.1,0.5,0.3,0.9,0.6,1.2c0.3,0.3,0.7,0.4,1.2,0.4c0.3,0,0.5,0,0.7-0.1c0.2-0.1,0.4-0.2,0.5-0.4s0.2-0.4,0.3-0.6
+ c0.1-0.3,0.1-0.5,0.1-0.8c0-0.3,0-0.5-0.1-0.8c-0.1-0.2-0.2-0.5-0.3-0.6s-0.3-0.3-0.6-0.4c-0.2-0.1-0.5-0.2-0.8-0.2
+ c-0.2,0-0.4,0-0.5,0c-0.1,0-0.3,0.1-0.4,0.1c-0.1,0-0.2,0.1-0.3,0.2s-0.2,0.2-0.3,0.2L109.9,59.5z"/>
+ <path d="M130.3,60.6h-4.9v-1h4.9V60.6z"/>
+ <path d="M141,63h1.9v-6.6l-2,0.7V56l3.2-1.2h0.1V63h1.8v1.1h-5V63z"/>
+ <path d="M154.2,64.1h-6.1v-0.9l3-3.4c0.3-0.3,0.5-0.6,0.7-0.8c0.2-0.2,0.3-0.4,0.4-0.6c0.1-0.2,0.2-0.4,0.2-0.5
+ c0-0.2,0.1-0.3,0.1-0.5c0-0.2,0-0.4-0.1-0.6c-0.1-0.2-0.2-0.4-0.3-0.5c-0.1-0.1-0.3-0.3-0.5-0.3s-0.4-0.1-0.6-0.1
+ c-0.3,0-0.6,0-0.8,0.1c-0.2,0.1-0.4,0.2-0.6,0.4c-0.2,0.2-0.3,0.4-0.3,0.6c-0.1,0.2-0.1,0.5-0.1,0.8H148c0-0.4,0.1-0.8,0.2-1.1
+ s0.3-0.6,0.6-0.9c0.3-0.3,0.6-0.5,1-0.6s0.8-0.2,1.3-0.2c0.4,0,0.8,0.1,1.1,0.2c0.3,0.1,0.6,0.3,0.9,0.5c0.2,0.2,0.4,0.5,0.5,0.8
+ s0.2,0.7,0.2,1c0,0.3,0,0.5-0.1,0.8s-0.2,0.5-0.4,0.8c-0.2,0.3-0.3,0.5-0.5,0.8s-0.4,0.5-0.7,0.8l-2.5,2.7h4.6V64.1z"/>
+ <path d="M156.6,63h1.9v-6.6l-2,0.7V56l3.2-1.2h0.1V63h1.8v1.1h-5V63z"/>
+ <path d="M169.8,64.1h-6.1v-0.9l3-3.4c0.3-0.3,0.5-0.6,0.7-0.8c0.2-0.2,0.3-0.4,0.4-0.6c0.1-0.2,0.2-0.4,0.2-0.5
+ c0-0.2,0.1-0.3,0.1-0.5c0-0.2,0-0.4-0.1-0.6c-0.1-0.2-0.2-0.4-0.3-0.5c-0.1-0.1-0.3-0.3-0.5-0.3s-0.4-0.1-0.6-0.1
+ c-0.3,0-0.6,0-0.8,0.1c-0.2,0.1-0.4,0.2-0.6,0.4c-0.2,0.2-0.3,0.4-0.3,0.6c-0.1,0.2-0.1,0.5-0.1,0.8h-1.3c0-0.4,0.1-0.8,0.2-1.1
+ s0.3-0.6,0.6-0.9c0.3-0.3,0.6-0.5,1-0.6s0.8-0.2,1.3-0.2c0.4,0,0.8,0.1,1.1,0.2c0.3,0.1,0.6,0.3,0.9,0.5c0.2,0.2,0.4,0.5,0.5,0.8
+ s0.2,0.7,0.2,1c0,0.3,0,0.5-0.1,0.8s-0.2,0.5-0.4,0.8c-0.2,0.3-0.3,0.5-0.5,0.8s-0.4,0.5-0.7,0.8l-2.5,2.7h4.6V64.1z"/>
+ </g>
+ <path d="M188,78H37V44h151V78z M39,76h147V46H39V76z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/gold-phone-input/index.html b/polymer_1.0.4/bower_components/gold-phone-input/index.html
new file mode 100644
index 0000000..71f22bb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-phone-input/index.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <title>gold-phone-input</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-phone-input/test/basic.html b/polymer_1.0.4/bower_components/gold-phone-input/test/basic.html
new file mode 100644
index 0000000..6016863
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-phone-input/test/basic.html
@@ -0,0 +1,117 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>gold-phone-input tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <script src="../../iron-test-helpers/test-helpers.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../gold-phone-input.html">
+
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <gold-phone-input></gold-phone-input>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="required">
+ <template>
+ <gold-phone-input auto-validate required error-message="error"></gold-phone-input>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+ test('input is spaced out correctly', function() {
+ var input = fixture('basic');
+ input.value='1231112222';
+ assert.equal(input.value, '123-111-2222');
+ });
+
+ test('invalid input is not ok', function() {
+ var input = fixture('required');
+ input.value='1234';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isTrue(container.invalid);
+ });
+
+ test('valid input is ok', function() {
+ var input = fixture('required');
+ input.value='1231112222';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isFalse(container.invalid);
+ });
+
+ test('empty required input shows error', function() {
+ var input = fixture('required');
+ forceXIfStamp(input);
+
+ var error = Polymer.dom(input.root).querySelector('paper-input-error');
+ assert.ok(error, 'paper-input-error exists');
+ assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
+ });
+
+ test('caret position is preserved', function() {
+ var input = fixture('required');
+ var ironInput = Polymer.dom(input.root).querySelector('input[is="iron-input"]');
+ input.value='111-111-1';
+ ironInput.selectionStart = 2;
+ ironInput.selectionEnd = 2;
+ input._computeValue('112-111-11');
+
+ assert.equal(ironInput.selectionStart, 2, 'selectionStart is preserved');
+ assert.equal(ironInput.selectionEnd, 2, 'selectionEnd is preserved');
+ });
+
+ suite('a11y', function() {
+
+ test('has aria-labelledby', function() {
+ var input = fixture('basic');
+ assert.isTrue(input.inputElement.hasAttribute('aria-labelledby'))
+ assert.equal(input.inputElement.getAttribute('aria-labelledby'), Polymer.dom(input.root).querySelector('label').id, 'aria-labelledby points to the label');
+ });
+
+ test('required and error has aria-labelledby', function() {
+ var input = fixture('required');
+ assert.isTrue(input.inputElement.hasAttribute('aria-labelledby'))
+ assert.equal(input.inputElement.getAttribute('aria-labelledby'), Polymer.dom(input.root).querySelector('label').id, 'aria-labelledby points to the label');
+ });
+
+ });
+
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-phone-input/test/index.html b/polymer_1.0.4/bower_components/gold-phone-input/test/index.html
new file mode 100644
index 0000000..5640b1e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-phone-input/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>gold-phone-input tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-zip-input/.bower.json b/polymer_1.0.4/bower_components/gold-zip-input/.bower.json
new file mode 100644
index 0000000..1a0e19a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-zip-input/.bower.json
@@ -0,0 +1,49 @@
+{
+ "name": "gold-zip-input",
+ "version": "1.0.1",
+ "description": "An input field for a zip code",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "gold",
+ "input"
+ ],
+ "main": [
+ "gold-zip-input.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/gold-zip-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/gold-zip-input",
+ "ignore": [],
+ "dependencies": {
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "fbd0d914987360f5242e7baf9fac23f329dc4cce"
+ },
+ "_source": "git://github.com/PolymerElements/gold-zip-input.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/gold-zip-input"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/gold-zip-input/.gitignore b/polymer_1.0.4/bower_components/gold-zip-input/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-zip-input/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/gold-zip-input/README.md b/polymer_1.0.4/bower_components/gold-zip-input/README.md
new file mode 100644
index 0000000..f577dee
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-zip-input/README.md
@@ -0,0 +1,8 @@
+# gold-zip-input
+
+`gold-zip-input` is a Material Design field for entering a valid US zip code.
+Example:
+
+```html
+<gold-zip-input></gold-zip-input>
+```
diff --git a/polymer_1.0.4/bower_components/gold-zip-input/bower.json b/polymer_1.0.4/bower_components/gold-zip-input/bower.json
new file mode 100644
index 0000000..2f5017a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-zip-input/bower.json
@@ -0,0 +1,40 @@
+{
+ "name": "gold-zip-input",
+ "version": "1.0.1",
+ "description": "An input field for a zip code",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "gold",
+ "input"
+ ],
+ "main": [
+ "gold-zip-input.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/gold-zip-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/gold-zip-input",
+ "ignore": [],
+ "dependencies": {
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/gold-zip-input/demo/index.html b/polymer_1.0.4/bower_components/gold-zip-input/demo/index.html
new file mode 100644
index 0000000..8ea4ae8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-zip-input/demo/index.html
@@ -0,0 +1,54 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>gold-zip-input demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../gold-zip-input.html">
+
+ <link rel="stylesheet" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+</head>
+<style>
+ gold-zip-input {
+ width: 200px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+</style>
+<body>
+
+ <div class="vertical-section-container centered">
+ <h4>Standard</h4>
+ <div class="vertical-section">
+ <gold-zip-input></gold-zip-input>
+ <gold-zip-input label="Auto-validating" auto-validate></gold-zip-input>
+ </div>
+
+ <h4>Pre-validated</h4>
+ <div class="vertical-section">
+ <gold-zip-input auto-validate value="90210"></gold-zip-input>
+ <gold-zip-input auto-validate value="90210-9999"></gold-zip-input>
+ <gold-zip-input auto-validate value="123"></gold-zip-input>
+ </div>
+
+ <h4>Custom error message</h4>
+ <div class="vertical-section">
+ <gold-zip-input required auto-validate error-message="Please enter a valid US zip code" label="Zippety Zip"></gold-zip-input>
+ </div>
+ </div>
+</body>
diff --git a/polymer_1.0.4/bower_components/gold-zip-input/gold-zip-input.html b/polymer_1.0.4/bower_components/gold-zip-input/gold-zip-input.html
new file mode 100644
index 0000000..d31b3a0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-zip-input/gold-zip-input.html
@@ -0,0 +1,113 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-input/paper-input-behavior.html">
+<link rel="import" href="../paper-input/paper-input-container.html">
+<link rel="import" href="../paper-input/paper-input-error.html">
+<link rel="import" href="../iron-input/iron-input.html">
+<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
+<link rel="import" href="zip-validator.html">
+
+<!--
+`gold-zip-input` is a single-line text field with Material Design styling
+for entering a US zip code.
+
+ <gold-zip-input></gold-zip-input>
+
+It may include an optional label, which by default is "Zip Code".
+
+ <gold-zip-input label="Mailing zip code"></gold-zip-input>
+
+### Validation
+
+The input supports both 5 digit zip codes (90210) or the full 9 digit ones,
+separated by a dash (90210-9999).
+
+The input can be automatically validated as the user is typing by using
+the `auto-validate` and `required` attributes. For manual validation, the
+element also has a `validate()` method, which returns the validity of the
+input as well sets any appropriate error messages and styles.
+
+See `Polymer.PaperInputBehavior` for more API docs.
+
+### Styling
+
+See `Polymer.PaperInputContainer` for a list of custom properties used to
+style this element.
+
+@group Gold Elements
+@hero hero.svg
+@demo demo/index.html
+@class gold-zip-input
+-->
+
+<dom-module id="gold-zip-input">
+ <style>
+ :host {
+ display: block;
+ }
+ </style>
+
+ <template>
+
+ <paper-input-container id="container"
+ auto-validate="[[autoValidate]]"
+ attr-for-value="bind-value">
+
+ <label hidden$="[[!label]]">[[label]]</label>
+
+ <zip-validator></zip-validator>
+
+ <input is="iron-input" id="input"
+ aria-labelledby$="[[_ariaLabelledBy]]"
+ aria-describedby$="[[_ariaDescribedBy]]"
+ required$="[[required]]"
+ validator="zip-validator"
+ type="tel"
+ maxlength="10"
+ bind-value="{{value}}"
+ autocomplete="postal-code"
+ name$="[[name]]">
+
+ <template is="dom-if" if="[[errorMessage]]">
+ <paper-input-error id="error">[[errorMessage]]</paper-input-error>
+ </template>
+
+ </paper-input-container>
+ </template>
+
+</dom-module>
+
+<script>
+(function() {
+ Polymer({
+
+ is: 'gold-zip-input',
+
+ behaviors: [
+ Polymer.PaperInputBehavior,
+ Polymer.IronFormElementBehavior
+ ],
+
+ properties: {
+ /**
+ * The label for this input.
+ */
+ label: {
+ type: String,
+ value: "Zip Code"
+ }
+ }
+
+ })
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/gold-zip-input/hero.svg b/polymer_1.0.4/bower_components/gold-zip-input/hero.svg
new file mode 100755
index 0000000..60ee87b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-zip-input/hero.svg
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <rect x="88" y="67" width="49" height="2"/>
+ <g>
+ <path d="M92.4,62h1.9v-6.6l-2,0.7V55l3.2-1.2h0.1V62h1.8v1.1h-5V62z"/>
+ <path d="M105.6,63.1h-6.1v-0.9l3-3.4c0.3-0.3,0.5-0.6,0.7-0.8c0.2-0.2,0.3-0.4,0.4-0.6c0.1-0.2,0.2-0.4,0.2-0.5
+ c0-0.2,0.1-0.3,0.1-0.5c0-0.2,0-0.4-0.1-0.6c-0.1-0.2-0.2-0.4-0.3-0.5c-0.1-0.1-0.3-0.3-0.5-0.3s-0.4-0.1-0.6-0.1
+ c-0.3,0-0.6,0-0.8,0.1c-0.2,0.1-0.4,0.2-0.6,0.4c-0.2,0.2-0.3,0.4-0.3,0.6c-0.1,0.2-0.1,0.5-0.1,0.8h-1.3c0-0.4,0.1-0.8,0.2-1.1
+ s0.3-0.6,0.6-0.9c0.3-0.3,0.6-0.5,1-0.6s0.8-0.2,1.3-0.2c0.4,0,0.8,0.1,1.1,0.2c0.3,0.1,0.6,0.3,0.9,0.5c0.2,0.2,0.4,0.5,0.5,0.8
+ s0.2,0.7,0.2,1c0,0.3,0,0.5-0.1,0.8s-0.2,0.5-0.4,0.8c-0.2,0.3-0.3,0.5-0.5,0.8s-0.4,0.5-0.7,0.8l-2.5,2.7h4.6V63.1z"/>
+ <path d="M109.1,57.9h0.9c0.3,0,0.6,0,0.8-0.1c0.2-0.1,0.4-0.2,0.5-0.3c0.1-0.1,0.3-0.3,0.3-0.5c0.1-0.2,0.1-0.4,0.1-0.6
+ c0-1.1-0.5-1.6-1.5-1.6c-0.2,0-0.5,0-0.7,0.1c-0.2,0.1-0.4,0.2-0.5,0.3c-0.1,0.1-0.2,0.3-0.3,0.5s-0.1,0.4-0.1,0.6h-1.3
+ c0-0.3,0.1-0.7,0.2-1s0.3-0.6,0.6-0.8s0.6-0.4,0.9-0.5c0.4-0.1,0.7-0.2,1.2-0.2c0.4,0,0.8,0.1,1.1,0.2c0.3,0.1,0.6,0.3,0.9,0.5
+ c0.2,0.2,0.4,0.5,0.6,0.8s0.2,0.7,0.2,1.1c0,0.2,0,0.3-0.1,0.5s-0.1,0.4-0.2,0.6s-0.3,0.3-0.4,0.5c-0.2,0.2-0.4,0.3-0.6,0.4
+ c0.3,0.1,0.6,0.2,0.7,0.4s0.3,0.3,0.5,0.5s0.2,0.4,0.2,0.6s0.1,0.4,0.1,0.6c0,0.4-0.1,0.8-0.2,1.2c-0.2,0.3-0.4,0.6-0.6,0.9
+ s-0.6,0.4-0.9,0.5c-0.4,0.1-0.7,0.2-1.2,0.2c-0.4,0-0.8-0.1-1.1-0.2c-0.4-0.1-0.7-0.3-0.9-0.5s-0.5-0.5-0.6-0.8s-0.2-0.7-0.2-1.1
+ h1.3c0,0.2,0,0.4,0.1,0.6c0.1,0.2,0.2,0.4,0.3,0.5c0.1,0.1,0.3,0.2,0.5,0.3c0.2,0.1,0.4,0.1,0.7,0.1s0.5,0,0.7-0.1
+ c0.2-0.1,0.4-0.2,0.5-0.3c0.1-0.1,0.3-0.3,0.3-0.5c0.1-0.2,0.1-0.5,0.1-0.7c0-0.3,0-0.5-0.1-0.7s-0.2-0.4-0.4-0.5
+ c-0.2-0.1-0.4-0.2-0.6-0.3s-0.5-0.1-0.8-0.1h-0.9V57.9z"/>
+ <path d="M120.3,60h1.3v1h-1.3v2.1h-1.3V61h-4.2v-0.7l4.1-6.4h1.3V60z M116.3,60h2.8v-4.4l-0.2,0.3L116.3,60z"/>
+ <path d="M123.7,58.5l0.5-4.6h4.8V55h-3.7l-0.3,2.4c0.2-0.1,0.4-0.2,0.6-0.3s0.5-0.1,0.9-0.1c0.4,0,0.8,0.1,1.2,0.2
+ c0.3,0.1,0.6,0.4,0.9,0.6c0.2,0.3,0.4,0.6,0.5,1s0.2,0.8,0.2,1.3c0,0.4-0.1,0.9-0.2,1.2c-0.1,0.4-0.3,0.7-0.5,1
+ c-0.2,0.3-0.5,0.5-0.9,0.6s-0.8,0.2-1.3,0.2c-0.4,0-0.7-0.1-1.1-0.2c-0.3-0.1-0.6-0.3-0.9-0.5s-0.5-0.5-0.6-0.8s-0.3-0.7-0.3-1.1
+ h1.2c0.1,0.5,0.3,0.9,0.6,1.2c0.3,0.3,0.7,0.4,1.2,0.4c0.3,0,0.5,0,0.7-0.1c0.2-0.1,0.4-0.2,0.5-0.4s0.2-0.4,0.3-0.6
+ c0.1-0.3,0.1-0.5,0.1-0.8c0-0.3,0-0.5-0.1-0.8c-0.1-0.2-0.2-0.5-0.3-0.6s-0.3-0.3-0.6-0.4c-0.2-0.1-0.5-0.2-0.8-0.2
+ c-0.2,0-0.4,0-0.5,0c-0.1,0-0.3,0.1-0.4,0.1c-0.1,0-0.2,0.1-0.3,0.2s-0.2,0.2-0.3,0.2L123.7,58.5z"/>
+ </g>
+ <path d="M151,77H73V44h78V77z M75,75h74V46H75V75z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/gold-zip-input/index.html b/polymer_1.0.4/bower_components/gold-zip-input/index.html
new file mode 100644
index 0000000..2b52979
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-zip-input/index.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <title>gold-zip-input</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-zip-input/test/basic.html b/polymer_1.0.4/bower_components/gold-zip-input/test/basic.html
new file mode 100644
index 0000000..9774615
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-zip-input/test/basic.html
@@ -0,0 +1,116 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>gold-zip-input tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <script src="../../iron-test-helpers/test-helpers.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../gold-zip-input.html">
+
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <gold-zip-input auto-validate required error-message="error"></gold-zip-input>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+ test('invalid input is not ok', function() {
+ var input = fixture('basic');
+ input.value='1234';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isTrue(container.invalid);
+ });
+
+ test('too many dashes are not ok', function() {
+ var input = fixture('basic');
+ input.value='90210--1111';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isTrue(container.invalid);
+ });
+
+ test('spaces instead of dashes are not ok', function() {
+ var input = fixture('basic');
+ input.value='90210 1111';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isTrue(container.invalid);
+ });
+
+ test('short zipcodes are ok', function() {
+ var input = fixture('basic');
+ input.value='94109';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isFalse(container.invalid);
+ });
+
+ test('full zipcodes are ok', function() {
+ var input = fixture('basic');
+ input.value='94109-1234';
+ forceXIfStamp(input);
+
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ assert.ok(container, 'paper-input-container exists');
+ assert.isFalse(container.invalid);
+ });
+
+ test('empty required input shows error', function() {
+ var input = fixture('basic');
+ forceXIfStamp(input);
+
+ var error = Polymer.dom(input.root).querySelector('paper-input-error');
+ assert.ok(error, 'paper-input-error exists');
+ assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
+ });
+
+ });
+
+ suite('a11y', function() {
+
+ test('has aria-labelledby', function() {
+ var input = fixture('basic');
+ assert.isTrue(input.inputElement.hasAttribute('aria-labelledby'))
+ assert.equal(input.inputElement.getAttribute('aria-labelledby'), Polymer.dom(input.root).querySelector('label').id, 'aria-labelledby points to the label');
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-zip-input/test/index.html b/polymer_1.0.4/bower_components/gold-zip-input/test/index.html
new file mode 100644
index 0000000..b71c68b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-zip-input/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>gold-zip-input tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/gold-zip-input/zip-validator.html b/polymer_1.0.4/bower_components/gold-zip-input/zip-validator.html
new file mode 100644
index 0000000..c2e3592
--- /dev/null
+++ b/polymer_1.0.4/bower_components/gold-zip-input/zip-validator.html
@@ -0,0 +1,32 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-validator-behavior/iron-validator-behavior.html">
+
+<script>
+
+ Polymer({
+
+ is: 'zip-validator',
+
+ behaviors: [
+ Polymer.IronValidatorBehavior
+ ],
+
+ validate: function(value) {
+ // A valid zipcode is 5 digits or 5 digits, a dash, and 4 more digits.
+ var re = /^\d{5}(?:-\d{4})?$/;
+ return re.test(value);
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/google-analytics/.bower.json b/polymer_1.0.4/bower_components/google-analytics/.bower.json
new file mode 100644
index 0000000..4f7e137
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/.bower.json
@@ -0,0 +1,42 @@
+{
+ "name": "google-analytics",
+ "version": "1.0.2",
+ "description": "Encapsulates Google Analytics dashboard features into web components",
+ "homepage": "https://googlewebcomponents.github.io/google-analytics",
+ "authors": [
+ "Philip Walton <philip@philipwalton.com>"
+ ],
+ "main": "google-analytics.html",
+ "license": "Apache2",
+ "keywords": [
+ "google",
+ "analytics",
+ "dashboard",
+ "polymer",
+ "web-component",
+ "web-components"
+ ],
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "promise-polyfill": "PolymerLabs/promise-polyfill#^1.0.0",
+ "ga-api-utils": "googleanalytics/javascript-api-utils#^0.2.0",
+ "google-chart": "GoogleWebComponents/google-chart#^1.0.0",
+ "google-signin": "GoogleWebComponents/google-signin#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "c6af2b375596f235406af06a220cf8a6cc08c6d4"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-analytics.git",
+ "_target": "^1.0.0",
+ "_originalSource": "GoogleWebComponents/google-analytics"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-analytics/LICENSE b/polymer_1.0.4/bower_components/google-analytics/LICENSE
new file mode 100644
index 0000000..52aea39
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2014 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/polymer_1.0.4/bower_components/google-analytics/README.md b/polymer_1.0.4/bower_components/google-analytics/README.md
new file mode 100755
index 0000000..a333c73
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/README.md
@@ -0,0 +1,4 @@
+google-analytics
+================
+
+See the [component page](https://googlewebcomponents.github.io/google-analytics) for more information.
diff --git a/polymer_1.0.4/bower_components/google-analytics/account-summaries-import.html b/polymer_1.0.4/bower_components/google-analytics/account-summaries-import.html
new file mode 100644
index 0000000..e0ebceb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/account-summaries-import.html
@@ -0,0 +1 @@
+<script src="../ga-api-utils/build/ga-api-utils.js"></script>
diff --git a/polymer_1.0.4/bower_components/google-analytics/bower.json b/polymer_1.0.4/bower_components/google-analytics/bower.json
new file mode 100755
index 0000000..f15db7b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/bower.json
@@ -0,0 +1,33 @@
+{
+ "name": "google-analytics",
+ "version": "1.0.2",
+ "description": "Encapsulates Google Analytics dashboard features into web components",
+ "homepage": "https://googlewebcomponents.github.io/google-analytics",
+ "authors": [
+ "Philip Walton <philip@philipwalton.com>"
+ ],
+ "main": "google-analytics.html",
+ "license": "Apache2",
+ "keywords": [
+ "google",
+ "analytics",
+ "dashboard",
+ "polymer",
+ "web-component",
+ "web-components"
+ ],
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "promise-polyfill": "PolymerLabs/promise-polyfill#^1.0.0",
+ "ga-api-utils": "googleanalytics/javascript-api-utils#^0.2.0",
+ "google-chart": "GoogleWebComponents/google-chart#^1.0.0",
+ "google-signin": "GoogleWebComponents/google-signin#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-analytics/demo/demo.css b/polymer_1.0.4/bower_components/google-analytics/demo/demo.css
new file mode 100644
index 0000000..0ef5069
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/demo/demo.css
@@ -0,0 +1,150 @@
+body {
+ background: #eee;
+ color: #222;
+ font: 13px/1.3 'Open Sans', sans-serif;
+ margin: 0;
+ padding: 0;
+}
+
+header {
+ background-color: #333;
+ box-sizing: border-box;
+ color: #eee;
+ display: table;
+ padding: 1.2em 1.5em;
+ width: 100%;
+}
+header > h1 {
+ display: table-cell;
+ font-size: 1.667em;
+ font-weight: 400;
+ margin: 0;
+ vertical-align: middle;
+ width: 100%;
+}
+header > h1 em {
+ font-weight: 300;
+ font-size: .8em;
+ font-style: normal;
+ margin-left: .5em;
+ opacity: .6;
+}
+header > google-signin {
+ display: table-cell;
+ vertical-align: middle;
+ white-space: nowrap;
+}
+
+/**
+ * .control styles.
+ */
+ google-analytics-view-selector::shadow .control,
+ google-analytics-date-selector::shadow .control {
+ display: inline-block;
+ margin: 0 1em 1.5em 0;
+}
+google-analytics-view-selector::shadow .control:last-child,
+google-analytics-date-selector::shadow .control:last-child {
+ margin-right: 0;
+}
+google-analytics-view-selector::shadow .control > label,
+google-analytics-date-selector::shadow .control > label {
+ display: block;
+ padding: 0 0 .4em 2px;
+}
+
+/**
+ * Common styles.
+ */
+google-analytics-view-selector,
+google-analytics-date-selector {
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ background: #fff;
+ float: left;
+ margin: 0 1.5em 1.5em 0;
+ padding: 1.5em 1.5em 0;
+}
+google-analytics-chart {
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ background: #fff;
+ float: left;
+ margin: 0 1.5em 1.5em 0;
+ padding: 1.5em;
+ position: relative;
+ transition: opacity .2s ease;
+}
+google-analytics-chart:not([rendered]) {
+ display: none;
+}
+
+google-analytics-chart:first-of-type {
+ clear: both;
+}
+google-analytics-chart h3 {
+ border: 0;
+ font-size: 1.3em;
+ font-weight: 300;
+ margin: 0;
+ padding: 0;
+}
+
+
+/**
+ * <google-analytics-view-selector> styles.
+ */
+google-analytics-dashboard {
+ display: block;
+ padding: 1.5em;
+ transition: opacity .3s ease;
+}
+google-analytics-dashboard:not([authorized]) {
+ opacity: .4;
+ pointer-events: none;
+}
+
+/**
+ * <google-analytics-view-selector> styles.
+ */
+google-analytics-view-selector::shadow label {
+ font-weight: bold;
+}
+google-analytics-view-selector::shadow select {
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ box-sizing: border-box;
+ height: 34px;
+ line-height: 20px;
+ min-width: 160px;
+ padding: 6px 12px;
+}
+google-analytics-view-selector::shadow select:focus {
+ border-color: #4d90fe;
+ outline: 0;
+}
+google-analytics-view-selector::shadow label {
+ font-weight: bold;
+}
+
+/**
+ * <google-analytics-date-selector> styles.
+ */
+google-analytics-date-selector::shadow label {
+ font-weight: bold;
+}
+google-analytics-date-selector::shadow input {
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ box-sizing: border-box;
+ font: inherit;
+ font-weight: 400;
+ height: 34px;
+ line-height: 20px;
+ min-width: 160px;
+ padding: 6px;
+}
+google-analytics-date-selector::shadow input:focus {
+ border-color: #4d90fe;
+ outline: 0;
+}
diff --git a/polymer_1.0.4/bower_components/google-analytics/demo/index.html b/polymer_1.0.4/bower_components/google-analytics/demo/index.html
new file mode 100755
index 0000000..1400e40
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/demo/index.html
@@ -0,0 +1,213 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Google Analytics Polymer Elements Demo</title>
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans:700,400,300">
+ <link rel="import" href="../../google-signin/google-signin.html">
+ <link rel="import" href="../google-analytics.html">
+
+</head>
+<body>
+<style is="custom-style">
+ body {
+ background: #eee;
+ color: #222;
+ font: 13px/1.3 'Open Sans', sans-serif;
+ margin: 0;
+ padding: 0;
+ }
+
+ header {
+ background-color: #333;
+ box-sizing: border-box;
+ color: #eee;
+ display: table;
+ padding: 1.2em 1.5em;
+ width: 100%;
+ }
+ header > h1 {
+ display: table-cell;
+ font-size: 1.667em;
+ font-weight: 400;
+ margin: 0;
+ vertical-align: middle;
+ width: 100%;
+ }
+ header > h1 em {
+ font-weight: 300;
+ font-size: .8em;
+ font-style: normal;
+ margin-left: .5em;
+ opacity: .6;
+ }
+ header > google-signin {
+ display: table-cell;
+ vertical-align: middle;
+ white-space: nowrap;
+ }
+
+ /**
+ * .control styles.
+ */
+ google-analytics-view-selector::shadow .control,
+ google-analytics-date-selector::shadow .control {
+ display: inline-block;
+ margin: 0 1em 1.5em 0;
+ }
+ google-analytics-view-selector::shadow .control:last-child,
+ google-analytics-date-selector::shadow .control:last-child {
+ margin-right: 0;
+ }
+ google-analytics-view-selector::shadow .control > label,
+ google-analytics-date-selector::shadow .control > label {
+ display: block;
+ padding: 0 0 .4em 2px;
+ }
+
+ /**
+ * Common styles.
+ */
+ google-analytics-view-selector,
+ google-analytics-date-selector {
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ background: #fff;
+ float: left;
+ margin: 0 1.5em 1.5em 0;
+ padding: 1.5em 1.5em 0;
+ }
+ google-analytics-chart {
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ background: #fff;
+ float: left;
+ margin: 0 1.5em 1.5em 0;
+ padding: 1.5em;
+ position: relative;
+ transition: opacity .2s ease;
+ }
+ google-analytics-chart:not([rendered]) {
+ display: none;
+ }
+
+ google-analytics-chart:first-of-type {
+ clear: both;
+ }
+ google-analytics-chart h3 {
+ border: 0;
+ font-size: 1.3em;
+ font-weight: 300;
+ margin: 0;
+ padding: 0;
+ }
+
+
+ /**
+ * <google-analytics-dashboard> styles.
+ */
+ google-analytics-dashboard {
+ display: block;
+ padding: 1.5em;
+ transition: opacity .3s ease;
+ }
+ google-analytics-dashboard:not([authorized]) {
+ opacity: .4;
+ pointer-events: none;
+ }
+
+ /**
+ * <google-analytics-view-selector> styles.
+ */
+ google-analytics-view-selector::shadow label {
+ font-weight: bold;
+ }
+ google-analytics-view-selector::shadow select {
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ box-sizing: border-box;
+ height: 34px;
+ line-height: 20px;
+ min-width: 160px;
+ padding: 6px 12px;
+ }
+ google-analytics-view-selector::shadow select:focus {
+ border-color: #4d90fe;
+ outline: 0;
+ }
+ google-analytics-view-selector::shadow label {
+ font-weight: bold;
+ }
+
+ /**
+ * <google-analytics-date-selector> styles.
+ */
+ google-analytics-date-selector::shadow label {
+ font-weight: bold;
+ }
+ google-analytics-date-selector::shadow input {
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ box-sizing: border-box;
+ font: inherit;
+ font-weight: 400;
+ height: 34px;
+ line-height: 20px;
+ min-width: 160px;
+ padding: 6px;
+ }
+ google-analytics-date-selector::shadow input:focus {
+ border-color: #4d90fe;
+ outline: 0;
+ }
+
+ </style>
+ <header>
+ <h1>Google Analytics <em>Polymer Elements Demo</em></h1>
+ <google-signin
+ client-id="1054047045356-j8pgqgls9vdef3rl09hapoicumbte0bo.apps.googleusercontent.com"
+ </google-signin>
+ </header>
+
+
+ <google-analytics-dashboard>
+
+ <google-analytics-view-selector></google-analytics-view-selector>
+ <google-analytics-date-selector></google-analytics-date-selector>
+
+ <google-analytics-chart
+ type="area"
+ metrics="ga:sessions"
+ dimensions="ga:date">
+ <h3>Site Traffic</h3>
+ </google-analytics-chart>
+
+ <google-analytics-chart
+ type="column"
+ metrics="ga:avgPageLoadTime"
+ dimensions="ga:date">
+ <h3>Average Page Load Times</h3>
+ </google-analytics-chart>
+
+ <google-analytics-chart
+ type="geo"
+ metrics="ga:users"
+ dimensions="ga:country">
+ <h3>Users by Country</h3>
+ </google-analytics-chart>
+
+ <google-analytics-chart
+ type="pie"
+ metrics="ga:pageviews"
+ dimensions="ga:browser"
+ sort="-ga:pageviews"
+ max-results="5">
+ <h3>Pageviews by Browser</h3>
+ </google-analytics-chart>
+
+ </google-analytics-dashboard>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-analytics/google-analytics-chart.html b/polymer_1.0.4/bower_components/google-analytics/google-analytics-chart.html
new file mode 100644
index 0000000..dc2b156
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/google-analytics-chart.html
@@ -0,0 +1,431 @@
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../google-chart/google-chart.html">
+<link rel="import" href="../promise-polyfill/promise-polyfill-lite.html">
+<link rel="import" href="google-analytics-query.html">
+<link rel="import" href="google-analytics-loader.html">
+
+<!--
+Element for displaying the results of a Google Analytics query in a
+Google Chart.
+
+##### Example
+
+ <google-analytics-chart
+ type="column"
+ ids="ga:1174"
+ metrics="ga:sessions"
+ dimensions="ga:country"
+ sort="-ga:sessions"
+ maxResults="5">
+ </google-analytics-chart>
+
+@element google-analytics-chart
+@demo
+-->
+
+<dom-module is="google-analytics-chart">
+ <template>
+ <google-analytics-loader all-ready="{{setupReady}}"></google-analytics-loader>
+ <google-analytics-query id="query"
+ loading="{{loading}}"
+ get-data-response-handler="{{_boundResponseHandler}}"
+ data="{{data}}"
+ ids="{{ids}}"
+ start-date="{{startDate}}"
+ end-date="{{endDate}}"
+ metrics="{{metrics}}"
+ dimensions="{{dimensions}}"
+ sort="{{sort}}"
+ filters="{{filters}}"
+ segment="{{segment}}"
+ sampling-level="{{samplingLevel}}"
+ start-index="{{startIndex}}"
+ max-results="{{maxResults}}"
+ output="dataTable"
+ src-param="gwc-ga-chart"
+ ></google-analytics-query>
+ <content select="header,h1,h2,h3,h4,h5,h6"></content>
+ <google-chart id="chart"
+ type="{{type}}"
+ width="{{width}}"
+ height="{{height}}"
+ data="{{data.dataTable}}">
+ </google-chart>
+ <content select="footer"></content>
+ </template>
+</dom-module>
+
+<script>
+
+ (function() {
+
+ 'use strict';
+
+ Polymer({
+
+ is: 'google-analytics-chart',
+
+ properties: {
+
+ /**
+ * Sets the type of the chart.
+ *
+ * Should be one of:
+ * - `area`, `bar`, `column`, `line`, `pie`, `geo`.
+ *
+ * @attribute type
+ * @default 'area'
+ * @type string
+ */
+ type: {
+ type: String,
+ value: 'area'
+ },
+
+ /**
+ * Sets the width of the chart on the page.
+ *
+ * @attribute width
+ * @default 480
+ * @type number of string
+ */
+ width: {
+ type: Number,
+ value: 480
+ },
+
+ /**
+ * Sets the height of the chart on the page.
+ *
+ * @attribute height
+ * @default 320
+ * @type number or string
+ */
+ height: {
+ type: Number,
+ value: 320,
+ },
+
+ /**
+ * Sets the options for the chart.
+ *
+ * Example:
+ * <pre>{
+ * title: "Chart title goes here",
+ * hAxis: {title: "Categories"},
+ * vAxis: {title: "Values", minValue: 0, maxValue: 2},
+ * legend: "none"
+ * };</pre>
+ * See <a href="https://google-developers.appspot.com/chart/interactive/docs/gallery">Google Visualization API reference (Chart Gallery)</a>
+ * for the options available to each chart type.
+ *
+ * @attribute options
+ * @default null
+ * @type object
+ */
+ options: {
+ type: Object,
+ value: function() { return null; }
+ },
+
+ /**
+ * True after the chart has been rendered for the first time.
+ *
+ * @attribute rendered
+ * @type boolean
+ */
+ rendered: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ reflectToAttribute: true
+ },
+
+ /**
+ * True if the chart is currently loading data.
+ *
+ * @attribute loading
+ * @type boolean
+ */
+ loading: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ reflectToAttribute: true
+ },
+
+ /**
+ * True if setup is ready
+ *
+ * @attribute setupReady
+ * @type Boolean
+ */
+ setupReady: {
+ type: Boolean,
+ observer: 'setupReadyChanged'
+ },
+
+ /**
+ * google-analytics-query passthrough properties
+ * See google-analytics-query for documentation
+ * startDate, endDate, data, ids, metrics, dimensions, sort, filters, segment, samplingLevel, startIndex, maxResults
+ */
+ startDate: {
+ type: String,
+ },
+
+ endDate: {
+ type: String
+ },
+
+ data: {
+ type: Object
+ },
+
+ ids: {
+ type: String
+ },
+
+ metrics: {
+ type: String
+ },
+
+ dimensions: {
+ type: String
+ },
+
+ sort: {
+ type: String
+ },
+
+ filters: {
+ type: String
+ },
+
+ segment: {
+ type: String
+ },
+
+ samplingLevel: {
+ type: String
+ },
+
+ startIndex: {
+ type: Number
+ },
+
+ maxResults: {
+ type: Number
+ }
+
+ },
+
+ ready: function() {
+ this._boundResponseHandler = this.handleResponse.bind(this);
+ merge(this.$.chart.options, getChartOptions(this.type), this.options);
+ },
+
+ setupReadyChanged: function(newVal, oldVal) {
+ if (newVal) {
+ metadata.get();
+ }
+ },
+
+ handleResponse: function(response) {
+ this.rendered = true;
+
+ metadata.get().then(function(map) {
+ switchApiNamesToDisplayNames(response.dataTable, map);
+ ensureProperDataTableTypes(response.dataTable);
+ this.$.query.setData(response);
+ }.bind(this));
+ }
+ });
+
+ /**
+ * @module metadata
+ */
+ var metadata = (function() {
+ var promise;
+ function queryMetadataAPI() {
+ if (!gapi || !gapi.client || !gapi.client.analytics) {
+ console.warn("Library not loaded yet!");
+ return;
+ }
+ return new Promise(function(resolve, reject) {
+ gapi.client.analytics
+ gapi.client.analytics.metadata.columns
+ .list({
+ reportType: 'ga',
+ _src: 'gwc-ga-chart'
+ })
+ .execute(function(response) {
+ if (response.error) {
+ reject(response.error);
+ }
+ else {
+ var map = {};
+ response.items.forEach(function(item) {
+ map[item.id] = item.attributes.uiName;
+ });
+ resolve(map);
+ }
+ });
+ });
+ }
+ return {
+ /**
+ * Return the `queryMetadataAPI` promise. If the promise exists,
+ * return it to avoid multiple requests. If the promise does not
+ * exist, initiate the request and cache the promise.
+ */
+ get: function() {
+ promise = promise || queryMetadataAPI();
+ return promise.catch(function(err) {
+ console.error(err.stack || err);
+ });
+ }
+ };
+ }());
+
+ /**
+ * Return an options object for the specified chart type.
+ * These are options suitable to pass to a Google Chart instance.
+ * @return {Object} The chart options.
+ */
+ function getChartOptions(type) {
+ var chartOptions = {
+ base: {
+ fontSize: 11,
+ chartArea: {
+ width: '100%'
+ },
+ legend: {
+ position: 'top',
+ alignment: 'start'
+ }
+ },
+ area: {
+ pointSize: 6,
+ lineWidth: 4,
+ areaOpacity: 0.1,
+ colors: ['#058dc7', '#aadff3'],
+ hAxis: {
+ format: 'MMM d',
+ gridlines: {
+ color: 'transparent'
+ },
+ baselineColor: 'transparent'
+ },
+ vAxis: {
+ gridlines: {
+ color: '#e8e8e8',
+ logScale: true,
+ count: 3
+ },
+ textPosition: 'in'
+ }
+ },
+ bar: {
+ colors: ['#058dc7', '#50b432', '#ed561b'],
+ hAxis: {
+ gridlines: {
+ color: '#e8e8e8'
+ }
+ },
+ vAxis: {
+ textPosition: 'in',
+ textStyle: {
+ strokeWidth: 4,
+ }
+ }
+ },
+ column: {
+ colors: ['#058dc7', '#50b432', '#ed561b'],
+ hAxis: {
+ gridlines: {
+ color: 'transparent'
+ },
+ baselineColor: 'transparent'
+ },
+ vAxis: {
+ gridlines: {
+ color: '#e8e8e8',
+ },
+ textPosition: 'in'
+ },
+
+ },
+ geo: {
+ colorAxis: {
+ minValue: 0,
+ colors: ['#aadff3', '#058dc7']
+ }
+ }
+ };
+ return merge({}, chartOptions.base, chartOptions[type]);
+ }
+
+ /**
+ * Use data from the Metadata API to change api names
+ * (e.g. `ga:sessions`) to their display names (e.g. "Sessions").
+ * @param {Object} dataTable - The dataTable data.
+ * @param {Object} map - A key/value store where the keys are the
+ * api names and the values are the display names.
+ */
+ function switchApiNamesToDisplayNames(dataTable, map) {
+ dataTable.cols.forEach(function(col) {
+ col.label = map[col.id] || col.label;
+ });
+ }
+
+ /**
+ * The analytics api erroneously return some values as strings that are
+ * supposed to be numbers. This function fixes that.
+ * @param {Object} dataTable - The dataTable data.
+ */
+ function ensureProperDataTableTypes(dataTable) {
+ for (var i = 0; i < dataTable.rows.length; i++) {
+ var row = dataTable.rows[i];
+ for (var j = 0; j < row.c.length; j++) {
+ if (dataTable.cols[j].type === 'number') {
+ row.c[j].v = Number(row.c[j].v);
+ }
+ }
+ }
+ }
+
+ /**
+ * Merge the source objects, in order, onto the destination object.
+ * Recursively merge nested, plain objects, everything else copy by
+ * reference.
+ * @param {Object} target - The object to receive the merged values.
+ * @param {...Object} source - The object(s) to provide values to the
+ * target. Later sources override previous sources.
+ * @return {Object} The merged target object.
+ */
+ function merge(target) {
+ var sources = Array.prototype.slice.call(arguments, 1);
+ sources.forEach(function(source) {
+ // Only merge objects.
+ if (!(source && typeof sources == 'object')) return;
+
+ Object.keys(source).forEach(function(key) {
+ // If the source's key is a 'plain' object, recursively merge.
+ if (typeof source[key] == 'object' &&
+ Object.getPrototypeOf(source[key]) == Object.prototype) {
+ target[key] = target[key] == null ?
+ merge({}, source[key]) : merge(target[key], source[key]);
+ }
+ // Otherwise just copy by reference.
+ else if (typeof source[key] != 'undefined') {
+ target[key] = source[key];
+ }
+ });
+ });
+ return target;
+ }
+ }());
+
+</script>
+
diff --git a/polymer_1.0.4/bower_components/google-analytics/google-analytics-dashboard.html b/polymer_1.0.4/bower_components/google-analytics/google-analytics-dashboard.html
new file mode 100644
index 0000000..9d3b3e0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/google-analytics-dashboard.html
@@ -0,0 +1,126 @@
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../google-signin/google-signin-aware.html">
+<!--
+Element for grouping Google Analytics elements together.
+
+`<google-analytics-chart>` elements inside a `<google-analytics-dashboard>`
+element will automatically update as control elements (e.g.
+`<google-analytics-view-selector>` or `<google-analytics-date-selector>`)
+update query parameters.
+
+##### Example
+
+ <google-analytics-dashboard>
+
+ <google-analytics-view-selector></google-analytics-view-selector>
+ <google-analytics-date-selector></google-analytics-date-selector>
+
+ <google-analytics-chart
+ metrics="ga:sessions"
+ dimensions="ga:country"
+ sort="-ga:sessions"
+ maxResults="5"
+ chartType="column">
+ </google-analytics-chart>
+
+ </google-analytics-dashboard>
+
+-->
+
+
+<dom-module id="google-analytics-dashboard">
+ <template>
+ <google-signin-aware
+ on-google-signin-aware-success="_signedIn"
+ on-google-signin-aware-signed-out="_signedOut"></google-signin-aware>
+ <content id="content"></content>
+ </template>
+</dom-module>
+<script>
+
+ (function() {
+ 'use strict';
+
+ Polymer({
+
+ is: 'google-analytics-dashboard',
+
+ properties: {
+ /**
+ * The `query` attribute represents the internal query object of this
+ * dashboard. It is updated when control elements fire the
+ * `analytics-dashboard-control-change` event and pass along query data.
+ */
+ query: {
+ type: Object,
+ value: function() { return {}; }
+ },
+
+ /**
+ * True if user has been authorized
+ */
+ authorized: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true
+ }
+
+ },
+
+ listeners: {
+ 'analytics-dashboard-control-change': 'queryUpdated'
+ },
+
+ ready: function() {
+ this.updateChildren();
+ },
+
+ /**
+ * The `queryUpdated` method is the callback for whenever the
+ * `analytics-dashboard-control-change` event is fired. It updates the
+ * query attribute, which is then sent to child charts.
+ *
+ * @method queryUpdated
+ * @param {CustomEvent} event - The event with the query data.
+ */
+ queryUpdated: function(event) {
+ // Update `this.query` with the passed event data.
+ Object.keys(event.detail).forEach(function(key) {
+ this.query[key] = event.detail[key];
+ }.bind(this))
+
+ this.updateChildren();
+ },
+
+ /**
+ * The `updateChildren` method updates each of this dashboards
+ * `<google-analytics-chart>` element with its current query value.
+ *
+ * @method updateChildren
+ */
+ updateChildren: function() {
+ if (!this.authorized) {
+ return;
+ }
+ var charts = Polymer.dom(this).querySelectorAll('google-analytics-chart');
+ for (var i = 0, chart; chart = charts[i]; i++) {
+ Object.keys(this.query).forEach(function(key) {
+ chart[key] = this.query[key];
+ }.bind(this));
+ }
+ },
+
+ _signedIn: function() {
+ this.authorized = true;
+ this.updateChildren();
+ },
+
+ _signedOut: function() {
+ this.authorized = false;
+ }
+
+ });
+
+ })();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/google-analytics/google-analytics-date-selector.html b/polymer_1.0.4/bower_components/google-analytics/google-analytics-date-selector.html
new file mode 100644
index 0000000..890fa0d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/google-analytics-date-selector.html
@@ -0,0 +1,203 @@
+<link rel="import" href="../polymer/polymer.html">
+<!--
+Element for selecting the start and end date values for queries inside a
+`<google-analytics-dashboard>` element.
+
+##### Example
+
+ <google-analytics-dashboard>
+
+ <google-analytics-date-selector
+ startDate="30daysAgo"
+ endDate="today">
+ </google-analytics-date-selector>
+
+ <google-analytics-chart
+ ids="ga:1174"
+ metrics="ga:sessions"
+ dimensions="ga:date">
+ </google-analytics-chart>
+
+ </google-analytics-dashboard>
+
+@element google-analytics-date-selector
+@extends google-analytics-base
+@blurb Element for selecting the start and end date values for Google Analytics queries
+@status alpha
+@homepage https://googlewebcomponents.github.io/google-analytics
+-->
+
+<dom-module id="google-analytics-date-selector">
+ <style>
+ input {
+ color: inherit;
+ font: inherit;
+ margin: 0;
+ }
+ </style>
+ <template>
+ <span class="control">
+ <label for="startDate">Start Date</label>
+ <input
+ id="startDate"
+ type="date"
+ value="{{startDate::change}}"
+ min="{{minStartDate}}"
+ max="{{endDate}}">
+ </span>
+ <span class="control">
+ <label for="endDate">End Date</label>
+ <input
+ id="endDate"
+ type="date"
+ value="{{endDate::change}}"
+ min="{{startDate}}"
+ max="{{maxEndDate}}">
+ </span>
+ </template>
+</dom-module>
+<script>
+
+ (function() {
+
+ 'use strict';
+
+ /**
+ * Fired when the users changes the start or end date.
+ *
+ * @param {Object} query The updated query params.
+ * @event analytics-dashboard-control-change
+ */
+
+
+ var nDaysAgo = /(\d+)daysAgo/;
+ var dateFormat = /\d{4}\-\d{2}\-\d{2}/;
+
+ /**
+ * Convert a date acceptable to the Core Reporting API (e.g. `today`,
+ * `yesterday` or `NdaysAgo`) into the format YYYY-MM-DD. Dates
+ * already in that format are simply returned.
+ * @return {string} The formatted date.
+ */
+ function convertDate(str) {
+ // If str is in the proper format, do nothing.
+ if (dateFormat.test(str)) return str
+
+ var match = nDaysAgo.exec(str);
+ if (match) {
+ return daysAgo(+match[1])
+ } else if (str == 'today') {
+ return daysAgo(0)
+ } else if (str == 'yesterday') {
+ return daysAgo(1)
+ } else {
+ throw new Error('Cannot convert date ' + str);
+ }
+ }
+
+ /**
+ * Accept a number and return a date formatted as YYYY-MM-DD that
+ * represents that many days ago.
+ * @return {string} The formatted date.
+ */
+ function daysAgo(numDays) {
+ var date = new Date();
+ date.setDate(date.getDate() - numDays);
+ var month = String(date.getMonth() + 1);
+ month = month.length == 1 ? '0' + month: month;
+ var day = String(date.getDate());
+ day = day.length == 1 ? '0' + day: day;
+ return date.getFullYear() + '-' + month + '-' + day;
+ }
+
+ Polymer({
+
+ is: 'google-analytics-date-selector',
+
+ properties: {
+ /**
+ * The `startDate` attribute is the start date for fetching Analytics
+ * data. Requests can specify a start date formatted as YYYY-MM-DD, or
+ * as a relative date (e.g., today, yesterday, or NdaysAgo where N is a
+ * positive integer).
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#startDate">Core Reporting API parameter reference</a> for more details.
+ *
+ * @attribute startDate
+ * @default '7daysAgo'
+ * @type string
+ */
+ startDate: {
+ type: String,
+ value: convertDate('7daysAgo'),
+ observer: 'startDateChanged',
+ notify: true
+ },
+
+ /**
+ * The `endDate` attribute is the end date for fetching Analytics
+ * data. Requests can specify an end date formatted as YYYY-MM-DD, or
+ * as a relative date (e.g., today, yesterday, or NdaysAgo where N is a
+ * positive integer).
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#endDate">Core Reporting API parameter reference</a> for more details.
+ *
+ * @attribute endDate
+ * @default 'yesterday'
+ * @type string
+ */
+ endDate: {
+ type: String,
+ value: convertDate('yesterday'),
+ observer: 'endDateChanged',
+ notify: true
+ },
+
+ /**
+ * The `minStartDate` attribute is used as the `min` attribute on the
+ * start date `<input>`.
+ *
+ * @attribute minStartDate
+ * @default '2005-01-01'
+ * @type string
+ */
+ minStartDate: {
+ type: String,
+ value: '2005-01-01'
+ },
+
+ /**
+ * The `maxEndDate` attribute is used as the `max` attribute on the
+ * end date `<input>`.
+ *
+ * @attribute maxEndDate
+ * @default 'today'
+ * @type string
+ */
+ maxEndDate: {
+ type: String,
+ value: convertDate('today')
+ }
+ },
+
+ startDateChanged: function(cur, old) {
+ this.startDate = convertDate(cur);
+ this.$.startDate.value = this.startDate;
+ this.fire('analytics-dashboard-control-change', {
+ startDate: this.startDate
+ });
+ },
+
+ endDateChanged: function(cur, old) {
+ this.endDate = convertDate(cur);
+ this.$.endDate.value = this.endDate;
+ this.fire('analytics-dashboard-control-change', {
+ endDate: this.endDate
+ });
+ }
+ });
+
+ }());
+
+</script>
+
diff --git a/polymer_1.0.4/bower_components/google-analytics/google-analytics-loader.html b/polymer_1.0.4/bower_components/google-analytics/google-analytics-loader.html
new file mode 100644
index 0000000..22a56e3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/google-analytics-loader.html
@@ -0,0 +1,96 @@
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../google-signin/google-signin-aware.html">
+<link rel="import" href="../google-apis/google-client-loader.html">
+<link rel="import" href="../promise-polyfill/promise-polyfill-lite.html">
+
+<!--
+google-analytics-loader is used internally by elements that need to know api state, and user state.
+
+Loads gapi.client.analytics, and watches user signed-in state.
+
+@element google-analytics-loader
+@homepage https://googlewebcomponents.github.io/google-analytics
+-->
+<dom-module id="google-analytics-loader">
+ <template>
+ <google-client-loader id="api"
+ name="analytics"
+ version="v3"
+ on-google-api-load="handleApiLoad"
+ on-google-api-load-error="handleApiFailedToLoad"></google-client-loader>
+ <google-signin-aware
+ scopes="https://www.googleapis.com/auth/analytics.readonly"
+ on-google-signin-aware-success="handleAuthSuccess"
+ on-google-signin-aware-signed-out="handleAuthSignout"></google-signin-aware>
+ </template>
+</dom-module>
+
+<script>
+ (function() {
+
+ 'use strict';
+
+ Polymer({
+
+ is: 'google-analytics-loader',
+
+ properties: {
+ /**
+ * True when user is authorized, and api is loaded
+ * @attribute allReady
+ * @type {Boolean}
+ */
+ allReady: {
+ type: Boolean,
+ computed: 'computeAllReady(apiReady, authorized)',
+ notify: true
+ },
+ /**
+ * True when api is loaded
+ * @attribute apiReady
+ * @type {Boolean}
+ */
+ apiReady: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ readOnly: true
+ },
+ /**
+ * True when user is authorized
+ * @attribute authorized
+ * @type {Boolean}
+ */
+ authorized: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ readOnly: true
+ }
+ },
+
+ computeAllReady: function(apiReady, authorized) {
+ return apiReady && authorized;
+ },
+
+ handleApiLoad: function() {
+ this._setApiReady(true);
+ },
+
+ handleApiFailedToLoad: function(ev, detail) {
+ this._setApiReady(false);
+ console.error("Api failed to load: ", this.$.api.name, this.$.api.version);
+ },
+
+ handleAuthSuccess: function() {
+ this._setAuthorized(true);
+ },
+
+ handleAuthSignout: function() {
+ this._setAuthorized(false);
+ }
+ });
+
+ })();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/google-analytics/google-analytics-query.html b/polymer_1.0.4/bower_components/google-analytics/google-analytics-query.html
new file mode 100644
index 0000000..30a81d6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/google-analytics-query.html
@@ -0,0 +1,389 @@
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="google-analytics-loader.html">
+
+<!--
+Element for querying the Google Analytics Core Reporting API.
+
+##### Example
+
+ <google-analytics-query
+ ids="ga:1174"
+ metrics="ga:sessions"
+ dimensions="ga:country"
+ sort="-ga:sessions"
+ maxResults="5">
+ </google-analytics-query>
+
+@element google-analytics-query
+@extends google-analytics-base
+@blurb Element for querying the Google Analytics Core Reporting API.
+@status alpha
+@homepage https://googlewebcomponents.github.io/google-analytics
+-->
+
+
+<dom-module id="google-analytics-query">
+ <template>
+ <google-analytics-loader all-ready="{{setupReady}}"></google-analytics-loader>
+ </template>
+</dom-module>
+<script>
+
+ (function() {
+
+ 'use strict';
+
+ Polymer({
+
+ is: 'google-analytics-query',
+ /**
+ * Fired when a query is successfully run and data has been stored.
+ *
+ * @event analytics-query-success
+ */
+
+ /**
+ * Fired when an error occurs while running a query.
+ *
+ * @event analytics-query-error
+ */
+
+ properties: {
+
+ /**
+ * The `data` attribute is the response from a query to the Google
+ * Analytics Core Reporting API. This value will be updated as
+ * subsequent requests are made.
+ *
+ * @attribute data
+ * @type object
+ */
+ data: {
+ type: Object,
+ value: function() { return {}},
+ notify: true
+ },
+
+ /**
+ * The `ids` attribute is the unique table ID of the form ga:XXXX,
+ * where XXXX is the Analytics view (profile) ID for which the query
+ * will retrieve the data.
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#ids">Core Reporting API parameter reference</a> for more details.
+ *
+ * Note: you can find out the `ids` value for any of your Google Analytics account using the <a href="https://ga-dev-tools.appspot.com/explorer/">Google Analytics query explorer</a>.
+ *
+ * @attribute ids
+ * @type string
+ */
+ ids: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * The `startDate` attribute is the start date for fetching Analytics
+ * data. Requests can specify a start date formatted as YYYY-MM-DD, or
+ * as a relative date (e.g., today, yesterday, or NdaysAgo where N is a
+ * positive integer).
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#startDate">Core Reporting API parameter reference</a> for more details.
+ *
+ * @attribute startDate
+ * @default '7daysAgo'
+ * @type string
+ */
+ startDate: {
+ type: String,
+ value: '7daysAgo'
+ },
+
+ /**
+ * The `endDate` attribute is the end date for fetching Analytics
+ * data. Requests can specify an end date formatted as YYYY-MM-DD, or
+ * as a relative date (e.g., today, yesterday, or NdaysAgo where N is a
+ * positive integer).
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#endDate">Core Reporting API parameter reference</a> for more details.
+ *
+ * @attribute endDate
+ * @default 'yesterday'
+ * @type string
+ */
+ endDate: {
+ type: String,
+ value: 'yesterday'
+ },
+
+ /**
+ * The `metrics` attribute is a list of comma-separated metrics,
+ * such as ga:sessions,ga:bounces.
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#metrics">Core Reporting API parameter reference</a> for more details.
+ *
+ * @attribute metrics
+ * @type string
+ */
+ metrics: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * The `dimensions` attribute is a list of comma-separated dimensions
+ * for your Analytics data, such as ga:browser,ga:city.
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#dimensions">Core Reporting API parameter reference</a> for more details.
+ *
+ * @attribute dimensions
+ * @type string
+ */
+ dimensions: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * The `sort` attribute is a list of comma-separated dimensions
+ * and metrics indicating the sorting order and sorting direction for
+ * the returned data.
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#sort">Core Reporting API parameter reference</a> for more details.
+ *
+ * @attribute sort
+ * @type string
+ */
+
+ sort: {
+ type: String,
+ value: ''
+ },
+ /**
+ * The `filters` attribute is dimension or metric filters that restrict
+ * the data returned for your request.
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#filters">Core Reporting API parameter reference</a> for more details.
+ *
+ * @attribute filters
+ * @type string
+ */
+ filters: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * The `segment` attribute segments the data returned for your
+ * request.
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#segment">Core Reporting API parameter reference</a> for more details.
+ *
+ * @attribute segment
+ * @type string
+ */
+ segment: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * The `samplingLevel` attribute sets the desired sampling level.
+ * Allowed Values: `DEFAULT`, `FASTER`, `HIGHER_PRECISION`.
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#samplingLevel">Core Reporting API parameter reference</a> for more details.
+ *
+ * @attribute samplingLevel
+ * @type string
+ */
+
+ samplingLevel: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * The `startIndex` attribute sets the first row of data to retrieve,
+ * starting at 1. Use this parameter as a pagination mechanism along
+ * with the max-results parameter.
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#startIndex">Core Reporting API parameter reference</a> for more details.
+ *
+ * @attribute startIndex
+ * @type integer
+ */
+ startIndex: {
+ type: Number,
+ value: 0
+ },
+
+ /**
+ * The `maxResults` attribute is the maximum number of rows to include
+ * in the response.
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#maxResults">Core Reporting API parameter reference</a> for more details.
+ *
+ * @attribute maxResults
+ * @type integer
+ */
+ maxResults: {
+ type: Number,
+ value: 0
+ },
+
+ /**
+ * The `output` attribute sets the desired output type for the
+ * Analytics data returned in the response. Acceptable values are json
+ * and dataTable.
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#output">Core Reporting API parameter reference</a> for more details.
+ *
+ * @attribute output
+ * @type string
+ */
+ output: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * The `fields` attribute is a selector specifying a subset of
+ * fields to include in the response.
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#fields">Core Reporting API parameter reference</a> for more details.
+ *
+ * @attribute fields
+ * @type string
+ */
+ fields: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * GA team internal variable for analytics purposes.
+ */
+ _srcParam: {
+ type: String,
+ value: 'gwc-ga-query'
+ },
+
+ /**
+ * true if data is getting loaded
+ * @attribute loading
+ * @type Boolean
+ */
+ loading: {
+ type: Boolean,
+ value: false,
+ notify: true
+ },
+
+ /**
+ *
+ *
+ * @attribute getDataResponseHandler
+ * @type Function
+ */
+ getDataResponseHandler: {
+ type: Function
+ },
+
+ /**
+ * True if setup is ready
+ *
+ * @attribute setupReady
+ * @type Boolean
+ */
+ setupReady: {
+ type: Boolean,
+ observer: '_setupReadyChanged'
+ }
+
+ },
+
+ observers: [
+ 'getData(ids,startDate,endDate,metrics,dimensions,sort,filters,segment,samplingLevel,startIndex,maxResults,output,fields)'
+ ],
+
+ _setupReadyChanged: function(newVal) {
+ if (newVal)
+ this.getData();
+ else
+ this.data = null;
+ },
+
+ /**
+ * Query the Google Analytics Core Reporting API.
+ *
+ * @method getData
+ */
+ getData: function() {
+ if (this.setupReady && this._hasRequiredParams) {
+ this.loading = true;
+ // Required parameters.
+ var query = {
+ 'ids': this.ids,
+ 'start-date': this.startDate,
+ 'end-date': this.endDate,
+ 'metrics': this.metrics,
+ '_src': this._srcParam
+ };
+
+ // Optional parameters.
+ if (this.dimensions) query.dimensions = this.dimensions;
+ if (this.sort) query.sort = this.sort;
+ if (this.filters) query.filters = this.filters;
+ if (this.segment) query.segment = this.segment;
+ if (this.samplingLevel) query.samplingLevel = this.samplingLevel;
+ if (this.startIndex) query['start-index'] = this.startIndex;
+ if (this.maxResults) query['max-results'] = this.maxResults;
+ if (this.output) query.output = this.output;
+ if (this.fields) query.fields = this.fields;
+
+ gapi.client.analytics.data.ga.get(query)
+ .execute(this.handleResponse.bind(this));
+
+ return true;
+ }
+ },
+
+ /**
+ * setData sets data fetched by getData.
+ * Use it if you override getData response processing
+ * @method setData
+ */
+ setData: function(data) {
+ this.data = data;
+ this.fire('analytics-query-success', data);
+ },
+
+ /**
+ * The callback for the query run in `getData`. This is a separate
+ * function so subclasses can alter how the response is handled.
+ *
+ * @method handleResponse
+ */
+ handleResponse: function(response) {
+ this.loading = false;
+
+ if (response.error) {
+ this.fire('analytics-query-error', response.error);
+ }
+ else {
+ if (this.getDataResponseHandler)
+ this.getDataResponseHandler(response)
+ else
+ this.setData(response);
+ }
+ },
+
+ get _hasRequiredParams() {
+ return !!(this.ids && this.metrics && this.startDate && this.endDate);
+ },
+
+ });
+
+ }());
+
+</script>
+
diff --git a/polymer_1.0.4/bower_components/google-analytics/google-analytics-view-selector.html b/polymer_1.0.4/bower_components/google-analytics/google-analytics-view-selector.html
new file mode 100644
index 0000000..8f3b026
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/google-analytics-view-selector.html
@@ -0,0 +1,275 @@
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="account-summaries-import.html">
+<link rel="import" href="google-analytics-loader.html">
+
+<!--
+Element for selecting the view ID (ids) value for queries inside a
+`<google-analytics-dashboard>` element.
+
+##### Example
+
+ <google-analytics-dashboard>
+
+ <google-analytics-view-selector></google-analytics-view-selector>
+
+ <google-analytics-chart
+ metrics="ga:sessions"
+ dimensions="ga:date">
+ </google-analytics-chart>
+
+ </google-analytics-dashboard>
+
+@element google-analytics-view-selector
+@extends google-analytics-base
+@blurb Element for selecting the ids value for Google Analytics queries
+@status alpha
+@homepage https://googlewebcomponents.github.io/google-analytics
+-->
+
+<dom-module id="google-analytics-view-selector">
+ <style>
+ select {
+ color: inherit;
+ font: inherit;
+ margin: 0;
+ }
+ </style>
+ <template>
+ <google-analytics-loader all-ready="{{setupReady}}"></google-analytics-loader>
+ <span class="control">
+ <label for="account">Account</label>
+ <select id="account"
+ on-change="updateAccount"
+ value="{{account.id}}">
+ <template is="dom-repeat" items="{{accounts}}">
+ <option value="{{item.id}}">{{item.name}}</option>
+ </template>
+ </select>
+ </span>
+ <span class="control">
+ <label>Property</label>
+ <select id="property"
+ on-change="updateProperty"
+ value="{{property.id}}">
+ <template is="dom-repeat" items="{{account.properties}}">
+ <option value="{{item.id}}">{{item.name}}</option>
+ </template>
+ </select>
+ </span>
+ <span class="control">
+ <label>View</label>
+ <select id="view"
+ on-change="updateView"
+ value="{{view.id}}">
+ <template is="dom-repeat" items="{{property.views}}">
+ <option value="{{item.id}}">{{item.name}}</option>
+ </template>
+ </select>
+ </span>
+ </template>
+</dom-module>
+<script>
+
+ (function() {
+ 'use strict';
+
+ Polymer({
+
+ is: 'google-analytics-view-selector',
+
+ /**
+ * Fired when the users changes the view
+ *
+ * @param {Object} query The updated query params.
+ * @event analytics-dashboard-control-change
+ */
+
+ properties: {
+
+ /**
+ * The `ids` attribute, when found is used to preselect the chosen
+ * account, property, and view.
+ *
+ * See the <a href="https://developers.google.com/analytics/devguides/reporting/core/v3/reference#ids">Core Reporting API parameter reference</a> for more details.
+ *
+ * @property ids
+ * @type string
+ */
+ ids: {
+ type: String,
+ observer: 'idsChanged',
+ notify: true
+ },
+
+ /**
+ * The `summaries` attribute contains an account summaries utility object
+ * with various helper methods for quickly getting account data.
+ *
+ * See the <a href="https://github.com/googleanalytics/javascript-api-utils">Github repo</a> for more details.
+ *
+ * @property summaries
+ * @type Object
+ */
+ summaries: {
+ type: Object,
+ value: null
+ },
+
+ /**
+ * The `account` attribute is the currently selected account.
+ *
+ * @property account
+ * @type Object
+ */
+ account: {
+ type: Object,
+ observer: 'accountChanged'
+ },
+
+ /**
+ * The `property` attribute is the currently selected property.
+ *
+ * @property property
+ * @type Object
+ */
+ property: {
+ type: Object,
+ observer: 'propertyChanged'
+ },
+
+ /**
+ * The `view` attribute is the currently selected view.
+ *
+ * @property view
+ * @type Object
+ */
+ view: {
+ type: Object,
+ observer: 'viewChanged'
+ },
+
+ /**
+ * True if setup is ready
+ *
+ * @attribute setupReady
+ * @type Boolean
+ */
+ setupReady: {
+ type: Boolean,
+ observer: 'setupReadyChanged'
+ }
+
+ },
+
+ setupReadyChanged: function(newVal, oldVal) {
+ if (newVal) {
+ gaApiUtils.accountSummaries.get().then(function(accountSummaries) {
+ this.summaries = accountSummaries;
+ this.accounts = accountSummaries.all();
+
+ if (this.ids) {
+ // Manually call `idsChanged` here. The first change event will
+ // likely happen prior to fetching the accountSummaries data.
+ this.idsChanged(null, this.ids);
+ } else {
+ // When there's no `ids` set, just select the first account,
+ // which will trigger change events and set the property and view.
+ this.account = this.accounts[0];
+ }
+ }.bind(this));
+ }
+ else {
+ this.summaries = null;
+ this.accounts = null;
+ this.account = null;
+ this.property = null;
+ this.view = null;
+ this.ids = null;
+ }
+ },
+
+ /**
+ * The `updateAccount` method is bound to the change event on the
+ * account `<select>`. It updates the property and view `<select>`s based
+ * on the new account data. It also updates the `ids` attribute.
+ */
+ updateAccount: function() {
+ this.account = this.summaries.getAccount(this.$.account.value);
+ },
+
+ /**
+ * The `updateProperty` method is bound to the change event on the
+ * property `<select>`. It updates the view `<select>` based
+ * on the new property data. It also updates the `ids` attribute.
+ */
+ updateProperty: function() {
+ this.property = this.summaries.getProperty(this.$.property.value);
+ },
+
+ /**
+ * The `updateView` method is bound to the change event on the
+ * view `<select>`. It updates the `ids` attribute.
+ */
+ updateView: function() {
+ this.view = this.summaries.getView(this.$.view.value);
+ },
+
+ accountChanged: function(newAccount, oldAccount) {
+ if (newAccount) {
+ this.property = newAccount.properties[0];
+ }
+ },
+
+ propertyChanged: function(newProperty, oldProperty) {
+ if (newProperty) {
+ this.view = newProperty.views[0];
+ // this.view = Path.get('views[0]').getValueFrom(newProperty);
+ }
+ },
+
+ viewChanged: function(newView, oldView) {
+ this.ids = newView && 'ga:' + newView.id;
+ },
+
+ idsChanged: function(newIds, oldIds) {
+ // When `ids` is set or updated prior to fetching the account
+ // summaries, do nothing.
+ if (!this.summaries) return;
+
+ var viewId = newIds && newIds.slice(3);
+ var account = this.summaries.getAccountByViewId(viewId);
+ var property = this.summaries.getPropertyByViewId(viewId);
+ var view = this.summaries.getView(viewId);
+
+ // Make sure the account data is valid before firing any events.
+ if (account && property && view) {
+ this.account = account;
+ this.property = property;
+ this.view = view;
+
+ this.fireChangeEvent();
+ }
+ // If the account data isn't valid, and there's no previous value
+ // to fall back to, default to the first account.
+ else if (!oldIds) {
+ this.account = this.summaries.all()[0];
+ }
+ },
+
+ /**
+ * Fire a change event passing all the currently stored data.
+ */
+ fireChangeEvent: function() {
+ this.fire('analytics-dashboard-control-change', {
+ ids: this.ids,
+ account: this.account,
+ property: this.property,
+ view: this.view
+ });
+ }
+
+ });
+
+ })();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/google-analytics/google-analytics.html b/polymer_1.0.4/bower_components/google-analytics/google-analytics.html
new file mode 100755
index 0000000..9b113e5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/google-analytics.html
@@ -0,0 +1,6 @@
+<!-- Load all google-analytics elements. -->
+<link rel="import" href="google-analytics-query.html">
+<link rel="import" href="google-analytics-chart.html">
+<link rel="import" href="google-analytics-view-selector.html">
+<link rel="import" href="google-analytics-date-selector.html">
+<link rel="import" href="google-analytics-dashboard.html">
diff --git a/polymer_1.0.4/bower_components/google-analytics/index.html b/polymer_1.0.4/bower_components/google-analytics/index.html
new file mode 100755
index 0000000..0e66730
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-analytics/index.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-apis/.bower.json b/polymer_1.0.4/bower_components/google-apis/.bower.json
new file mode 100644
index 0000000..e5adb7d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-apis/.bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "google-apis",
+ "version": "1.0.2",
+ "description": "Web components to load Google API libraries",
+ "homepage": "https://googlewebcomponents.github.io/google-apis",
+ "main": "google-apis.html",
+ "authors": [
+ "Scott Miles <sjmiles@google.com>",
+ "Eric Bidelman <ebidel@gmail.com>"
+ ],
+ "license": "Apache2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "google",
+ "apis"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-jsonp-library": "PolymerElements/iron-jsonp-library#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "7e8a931dd8ad48adc9d82dfe6e6f8a60b7c946c4"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-apis.git",
+ "_target": "^1.0.0",
+ "_originalSource": "GoogleWebComponents/google-apis"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-apis/LICENSE b/polymer_1.0.4/bower_components/google-apis/LICENSE
new file mode 100644
index 0000000..3dde500
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-apis/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2015 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/polymer_1.0.4/bower_components/google-apis/README.md b/polymer_1.0.4/bower_components/google-apis/README.md
new file mode 100644
index 0000000..bb329af
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-apis/README.md
@@ -0,0 +1,4 @@
+google-apis
+===========
+
+See the [component landing page](https://googlewebcomponents.github.io/google-apis) for more information.
diff --git a/polymer_1.0.4/bower_components/google-apis/bower.json b/polymer_1.0.4/bower_components/google-apis/bower.json
new file mode 100644
index 0000000..fb83a99
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-apis/bower.json
@@ -0,0 +1,30 @@
+{
+ "name": "google-apis",
+ "version": "1.0.2",
+ "description": "Web components to load Google API libraries",
+ "homepage": "https://googlewebcomponents.github.io/google-apis",
+ "main": "google-apis.html",
+ "authors": [
+ "Scott Miles <sjmiles@google.com>",
+ "Eric Bidelman <ebidel@gmail.com>"
+ ],
+ "license": "Apache2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "google",
+ "apis"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-jsonp-library": "PolymerElements/iron-jsonp-library#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-apis/demo/index.html b/polymer_1.0.4/bower_components/google-apis/demo/index.html
new file mode 100644
index 0000000..a93fc19
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-apis/demo/index.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>google-apis Demo</title>
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../google-apis.html">
+</head>
+<body>
+ <div id="messages"></div>
+
+ <template id="t" is="dom-bind">
+
+ <google-client-loader id="shortener"
+ name="urlshortener"
+ version="v1"
+ on-google-api-load="loadedShortener"></google-client-loader>
+ <google-js-api on-js-api-load="loaded"></google-js-api>
+ <google-plusone-api on-api-load="loaded"></google-plusone-api>
+ <google-realtime-api on-api-load="loaded"></google-realtime-api>
+ <google-maps-api on-api-load="loaded"></google-maps-api>
+ <google-youtube-api on-api-load="loaded"></google-youtube-api>
+ <google-legacy-loader on-api-load="loaded"></google-legacy-loader>
+
+ </template>
+
+ <script>
+ var t = document.querySelector('#t');
+
+ t.loadedShortener = function(event) {
+ var request = event.target.api.url.get({
+ shortUrl: 'http://goo.gl/fbsS'
+ })
+ request.execute(function(resp) {
+ console.log(resp);
+ });
+ };
+
+ t.loaded = function(e) {
+ document.querySelector('#messages').innerHTML +=
+ e.target.localName + ' loaded' + '<br>';
+ console.log(e.target.localName + ' loaded', event.target.api);
+ };
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-apis/google-apis.html b/polymer_1.0.4/bower_components/google-apis/google-apis.html
new file mode 100644
index 0000000..29f9883
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-apis/google-apis.html
@@ -0,0 +1,16 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at https://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at https://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at https://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at https://polymer.github.io/PATENTS.txt
+-->
+
+<!-- Load all Google APIs, for backwards compatibility -->
+<link rel="import" href="google-client-loader.html">
+<link rel="import" href="google-legacy-loader.html">
+<link rel="import" href="google-maps-api.html">
+<link rel="import" href="google-plusone-api.html">
+<link rel="import" href="google-realtime-api.html">
+<link rel="import" href="google-youtube-api.html">
diff --git a/polymer_1.0.4/bower_components/google-apis/google-client-loader.html b/polymer_1.0.4/bower_components/google-apis/google-client-loader.html
new file mode 100644
index 0000000..94c2b66
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-apis/google-client-loader.html
@@ -0,0 +1,227 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at https://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at https://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at https://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at https://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="google-js-api.html">
+
+<!--
+Element for loading a specific client Google API with the JavaScript client library.
+
+For loading `gapi.client` libraries
+
+##### Example
+
+ <google-client-loader id="shortener"
+ name="urlshortener"
+ version="v1"></google-client-loader>
+
+ <script>
+ var shortener = document.getElementById('shortener');
+ shortener.addEventListener('google-api-load', function(event) {
+ var request = shortener.api.url.get({
+ shortUrl: 'http://goo.gl/fbsS'
+ });
+ request.execute(function(resp) {
+ console.log(resp);
+ });
+ });
+ </script>
+
+@demo
+-->
+<dom-module id="google-client-loader">
+ <template>
+ <google-js-api on-js-api-load="_loadClient"></google-js-api>
+ </template>
+</dom-module>
+
+<script>
+ (function() {
+ 'use strict';
+
+ // Stores whether the API client is done loading.
+ var _clientLoaded = false;
+
+ // Loaders and loading statuses for all APIs, indexed by API name.
+ // This helps prevent multiple loading requests being fired at the same time
+ // by multiple google-api-loader elements.
+ var _statuses = {};
+ var _loaders = {};
+
+ Polymer({
+
+ is: 'google-client-loader',
+
+ /**
+ * Fired when the requested API is loaded. Override this name
+ * by setting `successEventName`.
+ * @event google-api-load
+ */
+
+ /**
+ * Fired if an error occurs while loading the requested API. Override this name
+ * by setting `errorEventName`.
+ * @event google-api-load-error
+ */
+
+ properties: {
+ /**
+ * Name of the API to load, e.g. 'urlshortener'.
+ *
+ * You can find the full list of APIs on the
+ * <a href="https://developers.google.com/apis-explorer"> Google APIs
+ * Explorer</a>.
+ * @required
+ */
+ name: String,
+
+ /**
+ * Version of the API to load, e.g. 'v1'.
+ * @required
+ */
+ version: String,
+
+ /**
+ * App Engine application ID for loading a Google Cloud Endpoints API.
+ */
+ appId: String,
+
+ /**
+ * Root URL where to load the API from, e.g. 'http://host/apis'.
+ * For App Engine dev server this would be something like:
+ * 'http://localhost:8080/_ah/api'.
+ * Overrides 'appId' if both are specified.
+ */
+ apiRoot: String,
+
+ /**
+ * Name of the event fired when API library is loaded.
+ */
+ successEventName: {
+ type: String,
+ value: 'google-api-load'
+ },
+
+ /**
+ * Name of the event fired when there is an error loading the library.
+ */
+ errorEventName: {
+ type: String,
+ value: 'google-api-load-error'
+ }
+ },
+
+ // Used to fix events potentially being fired multiple times by
+ // iron-jsonp-library.
+ _waiting: false,
+
+ /**
+ * Returns the loaded API.
+ * @type gapi.client
+ */
+ get api() {
+ if (window.gapi && window.gapi.client &&
+ window.gapi.client[this.name]) {
+ return window.gapi.client[this.name];
+ } else {
+ return undefined;
+ }
+ },
+
+ /**
+ * Wrapper for `gapi.auth`.
+ */
+ get auth() {
+ return gapi.auth;
+ },
+
+ _loadClient: function() {
+ gapi.load('client', this._doneLoadingClient.bind(this));
+ },
+
+ _handleLoadResponse: function(response) {
+ if (response && response.error) {
+ _statuses[this.name] = 'error';
+ this._fireError(response);
+ } else {
+ _statuses[this.name] = 'loaded';
+ this._fireSuccess();
+ }
+ },
+
+ _fireSuccess: function() {
+ this.fire(this.successEventName,
+ { 'name': this.name, 'version': this.version });
+ },
+
+ _fireError: function(response) {
+ if (response && response.error) {
+ this.fire(this.errorEventName, {
+ 'name': this.name,
+ 'version': this.version,
+ 'error': response.error });
+ } else {
+ this.fire(this.errorEventName, {
+ 'name': this.name,
+ 'version': this.version });
+ }
+ },
+
+ _doneLoadingClient: function() {
+ _clientLoaded = true;
+ // Fix for API client load event being fired multiple times by
+ // iron-jsonp-library.
+ if (!this._waiting) {
+ this._loadApi();
+ }
+ },
+
+ _createSelfRemovingListener: function(eventName) {
+ var handler = function () {
+ _loaders[this.name].removeEventListener(eventName, handler);
+ this._loadApi();
+ }.bind(this);
+
+ return handler;
+ },
+
+ _loadApi: function() {
+ if (_clientLoaded && this.name && this.version) {
+ this._waiting = false;
+ // Is this API already loaded?
+ if (_statuses[this.name] == 'loaded') {
+ this._fireSuccess();
+ // Is a different google-api-loader already loading this API?
+ } else if (_statuses[this.name] == 'loading') {
+ this._waiting = true;
+ _loaders[this.name].addEventListener(this.successEventName,
+ this._createSelfRemovingListener(this.successEventName));
+ _loaders[this.name].addEventListener(this.errorEventName,
+ this._createSelfRemovingListener(this.errorEventName));
+ // Did we get an error when we tried to load this API before?
+ } else if (_statuses[this.name] == 'error') {
+ this._fireError();
+ // Otherwise, looks like we're loading a new API.
+ } else {
+ var root;
+ if (this.apiRoot) {
+ root = this.apiRoot;
+ } else if (this.appId) {
+ root = 'https://' + this.appId + '.appspot.com/_ah/api';
+ }
+ _statuses[this.name] = 'loading';
+ _loaders[this.name] = this;
+ gapi.client.load(this.name, this.version,
+ this._handleLoadResponse.bind(this), root);
+ }
+ }
+ }
+ });
+ })();
+</script>
diff --git a/polymer_1.0.4/bower_components/google-apis/google-js-api.html b/polymer_1.0.4/bower_components/google-apis/google-js-api.html
new file mode 100644
index 0000000..d9c77c8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-apis/google-js-api.html
@@ -0,0 +1,64 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at https://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at https://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at https://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at https://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-jsonp-library/iron-jsonp-library.html">
+
+<script>
+/**
+Dynamically loads Google JavaScript API `gapi`, firing the `js-api-load` event when ready.
+
+Any number of components can use `<google-js-api>` elements, and the library will only be loaded once.
+
+##### Example
+
+ <google-js-api></google-js-api>
+ <script>
+ var api = document.querySelector('google-js-api');
+ api.addEventListener('js-api-load', function(e) {
+ console.log('API loaded', gapi);
+ });
+ < /script>
+
+*/
+ Polymer({
+
+ is: 'google-js-api',
+
+ behaviors: [
+ Polymer.IronJsonpLibraryBehavior
+ ],
+
+ properties: {
+
+ /** @private */
+ libraryUrl: {
+ type: String,
+ value: 'https://apis.google.com/js/api.js?onload=%%callback%%'
+ },
+
+ /**
+ * Fired when the API library is loaded and available.
+ * @event js-api-load
+ */
+ /**
+ * Name of event fired when library is loaded and available.
+ */
+ notifyEvent: {
+ type: String,
+ value: 'js-api-load'
+ },
+ },
+
+ get api() {
+ return gapi;
+ }
+
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/google-apis/google-legacy-loader.html b/polymer_1.0.4/bower_components/google-apis/google-legacy-loader.html
new file mode 100644
index 0000000..1129d2a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-apis/google-legacy-loader.html
@@ -0,0 +1,55 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at https://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at https://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at https://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at https://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-jsonp-library/iron-jsonp-library.html">
+
+<script>
+/**
+Dynamically loads the legacy Google JavaScript API Loader (https://developers.google.com/loader/).
+
+Fires `api-load` event when ready.
+*/
+ Polymer({
+
+ is: 'google-legacy-loader',
+
+ behaviors: [
+ Polymer.IronJsonpLibraryBehavior
+ ],
+
+ properties: {
+
+ /** @private */
+ libraryUrl: {
+ type: String,
+ value: 'https://www.google.com/jsapi?callback=%%callback%%'
+ },
+
+ /**
+ * Fired when the API library is loaded and available.
+ * @event js-api-load
+ */
+ /**
+ * Name of event fired when library is loaded and available.
+ */
+ notifyEvent: {
+ type: String,
+ value: 'api-load'
+ }
+ },
+
+ /**
+ * Wrapper for `google` API namespace.
+ */
+ get api() {
+ return google;
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/google-apis/google-maps-api.html b/polymer_1.0.4/bower_components/google-apis/google-maps-api.html
new file mode 100644
index 0000000..14598c5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-apis/google-maps-api.html
@@ -0,0 +1,150 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at https://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at https://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at https://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at https://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-jsonp-library/iron-jsonp-library.html">
+
+<script>
+/**
+Dynamically loads the Google Maps JavaScript API, firing the `api-load` event when ready.
+
+#### Example
+
+ <google-maps-api apiKey="abc123" version="3.exp"></google-maps-api>
+ <script>
+ var mapsAPI = document.querySelector('google-maps-api');
+ mapsAPI.addEventListener('api-load', function(e) {
+ // this.api === google.maps
+ });
+ <script>
+
+Any number of components can use `<google-maps-api>` elements, and the library will only be loaded once.
+
+@blurb Element wrapper around Google Maps API.
+
+ */
+ Polymer({
+
+ is: 'google-maps-api',
+
+ behaviors: [
+ Polymer.IronJsonpLibraryBehavior
+ ],
+
+ properties: {
+
+ /** @private */
+ mapsUrl: {
+ type: String,
+ value: 'https://maps.googleapis.com/maps/api/js?callback=%%callback%%'
+ },
+
+ /**
+ * A Maps API key. To obtain an API key, see developers.google.com/maps/documentation/javascript/tutorial#api_key.
+ */
+ apiKey: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * A Maps API for Business Client ID. To obtain a Maps API for Business Client ID, see developers.google.com/maps/documentation/business/.
+ * If set, a Client ID will take precedence over an API Key.
+ */
+ clientId: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * The libraries to load with this map. Defaults to "places". For more information
+ * see https://developers.google.com/maps/documentation/javascript/libraries.
+ */
+ libraries: {
+ type: String,
+ value: 'places'
+ },
+
+ /**
+ * Version of the Maps API to use.
+ */
+ version: {
+ type: String,
+ value: '3.exp'
+ },
+
+ /**
+ * The localized language to load the Maps API with. For more information
+ * see https://developers.google.com/maps/documentation/javascript/basics#Language
+ *
+ * Note: the Maps API defaults to the preffered language setting of the browser.
+ * Use this parameter to override that behavior.
+ */
+ language: {
+ type: String,
+ value: ''
+ },
+ /**
+ * If true, sign-in is enabled.
+ * See https://developers.google.com/maps/documentation/javascript/signedin#enable_sign_in
+ */
+ signedIn: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Fired when the Maps API library is loaded and ready.
+ * @event api-load
+ */
+ /**
+ * Name of event fired when library is loaded and available.
+ */
+ notifyEvent: {
+ type: String,
+ value: 'api-load'
+ },
+
+ /** @private */
+ libraryUrl: {
+ type: String,
+ computed: '_computeUrl(mapsUrl, version, libraries, apiKey, clientId, language, signedIn)'
+ }
+ },
+
+ _computeUrl: function(mapsUrl, version, libraries, apiKey, clientId, language, signedIn) {
+ var url = mapsUrl + '&v=' + version;
+ url += "&libraries=" + libraries;
+
+ if (apiKey && !clientId) {
+ url += '&key=' + apiKey;
+ }
+
+ if (clientId) {
+ url += '&client=' + clientId;
+ }
+
+ if (language) {
+ url += '&language=' + language;
+ }
+
+ if (signedIn) {
+ url += '&signed_in=' + signedIn;
+ }
+ return url;
+ },
+
+ /**
+ * Provides the google.maps JS API namespace.
+ */
+ get api() {
+ return google.maps;
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/google-apis/google-plusone-api.html b/polymer_1.0.4/bower_components/google-apis/google-plusone-api.html
new file mode 100644
index 0000000..ab2aad2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-apis/google-plusone-api.html
@@ -0,0 +1,54 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at https://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at https://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at https://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at https://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-jsonp-library/iron-jsonp-library.html">
+
+<script>
+/**
+Dynamically loads the Google+ JavaScript API, firing the `api-load` event when ready.
+
+Any number of components can use `<google-plusone-api>` elements, and the library will only be loaded once.
+*/
+ Polymer({
+
+ is: 'google-plusone-api',
+
+ behaviors: [
+ Polymer.IronJsonpLibraryBehavior
+ ],
+
+ properties: {
+
+ /** @private */
+ libraryUrl: {
+ type: String,
+ value: 'https://apis.google.com/js/plusone.js?onload=%%callback%%'
+ },
+
+ /**
+ * Fired when the API library is loaded and available.
+ * @event js-api-load
+ */
+ /**
+ * Name of event fired when library is loaded and available.
+ */
+ notifyEvent: {
+ type: String,
+ value: 'api-load'
+ }
+
+ },
+
+ get api() {
+ return gapi;
+ }
+
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/google-apis/google-realtime-api.html b/polymer_1.0.4/bower_components/google-apis/google-realtime-api.html
new file mode 100644
index 0000000..5788fc6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-apis/google-realtime-api.html
@@ -0,0 +1,58 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at https://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at https://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at https://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at https://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-jsonp-library/iron-jsonp-library.html">
+
+<script>
+/**
+Dynamically loads the Google Drive Realtime API, firing the `api-load` event when ready.
+
+Any number of components can use `<google-realtime-api>` elements, and the library will only be loaded once.
+
+*/
+ Polymer({
+
+ is: 'google-realtime-api',
+
+ behaviors: [
+ Polymer.IronJsonpLibraryBehavior
+ ],
+
+ properties: {
+
+ /** @private */
+ libraryUrl: {
+ type: String,
+ value: 'https://apis.google.com/js/drive-realtime.js?onload=%%callback%%'
+ },
+
+ /**
+ * Fired when the API library is loaded and available.
+ * @event api-load
+ */
+ /**
+ * Name of event fired when library is loaded and available.
+ */
+ notifyEvent: {
+ type: String,
+ value: 'api-load'
+ }
+
+ },
+
+ /**
+ * Returns `gapi.drive.realtime`
+ */
+ get api() {
+ return gapi.drive.realtime;
+ }
+
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/google-apis/google-youtube-api.html b/polymer_1.0.4/bower_components/google-apis/google-youtube-api.html
new file mode 100644
index 0000000..81f5dc1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-apis/google-youtube-api.html
@@ -0,0 +1,61 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at https://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at https://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at https://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at https://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-jsonp-library/iron-jsonp-library.html">
+
+<script>
+/**
+Dynamically loads the Google Youtube Iframe API, firing the `api-load` event when ready.
+
+Any number of components can use `<google-youtube-api>` elements, and the library will only be loaded once.
+
+https://developers.google.com/youtube/iframe_api_reference
+ */
+ Polymer({
+
+ is: 'google-youtube-api',
+
+ behaviors: [
+ Polymer.IronJsonpLibraryBehavior
+ ],
+
+ properties: {
+
+ /** @private */
+ libraryUrl: {
+ type: String,
+ value: 'https://www.youtube.com/iframe_api'
+ },
+
+ /**
+ * Fired when the API library is loaded and available.
+ * @event api-load
+ */
+ /**
+ * Name of event fired when library loads.
+ */
+ notifyEvent: {
+ type: String,
+ value: 'api-load'
+ },
+
+ callbackName: {
+ type: String,
+ value: 'onYouTubeIframeAPIReady'
+ }
+
+ },
+
+ get api() {
+ return YT;
+ }
+
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/google-apis/index.html b/polymer_1.0.4/bower_components/google-apis/index.html
new file mode 100644
index 0000000..203f4fa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-apis/index.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-calendar/.bower.json b/polymer_1.0.4/bower_components/google-calendar/.bower.json
new file mode 100644
index 0000000..c01cfba
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-calendar/.bower.json
@@ -0,0 +1,40 @@
+{
+ "name": "google-calendar",
+ "version": "1.0.1",
+ "homepage": "https://googlewebcomponents.github.io/google-calendar",
+ "description": "Web components for working with Google Calendar",
+ "main": "google-calendar.html",
+ "authors": [
+ "Ewa Gasperowicz"
+ ],
+ "license": "Apache2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "calendar",
+ "google"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0",
+ "google-signin": "GoogleWebComponents/google-signin#^1.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "ba1807e1698ef901c104c8908318e887dd049fff"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-calendar.git",
+ "_target": "^1.0.0",
+ "_originalSource": "GoogleWebComponents/google-calendar"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-calendar/LICENSE b/polymer_1.0.4/bower_components/google-calendar/LICENSE
new file mode 100644
index 0000000..78fbda7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-calendar/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2015 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/polymer_1.0.4/bower_components/google-calendar/README.md b/polymer_1.0.4/bower_components/google-calendar/README.md
new file mode 100644
index 0000000..8c948b0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-calendar/README.md
@@ -0,0 +1,4 @@
+google-calendar
+================
+
+See the [component page](http://googlewebcomponents.github.io/google-calendar) for more information.
diff --git a/polymer_1.0.4/bower_components/google-calendar/bower.json b/polymer_1.0.4/bower_components/google-calendar/bower.json
new file mode 100644
index 0000000..d692c90
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-calendar/bower.json
@@ -0,0 +1,31 @@
+{
+ "name": "google-calendar",
+ "version": "1.0.1",
+ "homepage": "https://googlewebcomponents.github.io/google-calendar",
+ "description": "Web components for working with Google Calendar",
+ "main": "google-calendar.html",
+ "authors": [
+ "Ewa Gasperowicz"
+ ],
+ "license": "Apache2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "calendar",
+ "google"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0",
+ "google-signin": "GoogleWebComponents/google-signin#^1.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-calendar/demo/index.html b/polymer_1.0.4/bower_components/google-calendar/demo/index.html
new file mode 100644
index 0000000..20a83f9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-calendar/demo/index.html
@@ -0,0 +1,54 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>google-calendar Demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <link rel="import" href="../../google-signin/google-signin.html">
+ <link rel="import" href="../google-calendar.html">
+
+ <style>
+ #calendarId {
+ vertical-align: top;
+ line-height: 20px;
+ width: 330px;
+ }
+ </style>
+
+</head>
+<body>
+
+ <google-signin
+ client-id="1054047045356-j8pgqgls9vdef3rl09hapoicumbte0bo.apps.googleusercontent.com">
+ </google-signin>
+
+ <p>A <code><google-calendar-list></code> looks like this:</p>
+ <google-calendar-list title="What I'm up to"></google-calendar-list>
+
+ <p>A <code><google-calendar-busy></code> looks like this:</p>
+
+ <google-calendar-busy-now
+ calendar-id="85rssq4g28omn1j1t8s4d4f06g@group.calendar.google.com"
+ api-key="AIzaSyDc30ApZEjTsanMI_YRByA8skglMNU6dXM"
+ busy-label="Do not disturb"
+ free-label="I'm free, talk to me!">
+ </google-calendar-busy-now>
+ <hr>
+ <div>
+ <!-- Just for demonstration purposes -->
+ Another calendar id:<input type="text" id="calendarId"
+ placeholder="Provide calendar ID to check availability"
+ value="85rssq4g28omn1j1t8s4d4f06g@group.calendar.google.com">
+ </div>
+ <script>
+ var input = document.querySelector("#calendarId");
+ input.disabled = false;
+ input.onchange = function() {
+ var t = document.querySelector("google-calendar-busy-now");
+ t.calendarId = this.value;
+ }
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-calendar/google-calendar.html b/polymer_1.0.4/bower_components/google-calendar/google-calendar.html
new file mode 100644
index 0000000..a7a871c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-calendar/google-calendar.html
@@ -0,0 +1,309 @@
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../google-signin/google-signin-aware.html">
+<link rel="import" href="../google-apis/google-client-loader.html">
+
+
+<!--
+Element providing a list of Google Calendars for a signed in user.
+Needs a google-signin element included somewhere on the same page
+that handles authentication.
+
+##### Example
+
+ <google-calendar-list title="What I'm up to"></google-calendar-list>
+
+@demo
+-->
+<dom-module id="google-calendar-list">
+ <style>
+ :host, span {
+ display: inline-block;
+ }
+ ul {
+ list-style: none;
+ padding: 0;
+ }
+
+ li {
+ font-family: Arial, sans-serif;
+ display: block;
+ list-style: none;
+ width: 300px;
+ border-radius: .2em;
+ padding: .2em;
+ margin: .2em;
+ overflow: hidden;
+ }
+
+ li a {
+ color: inherit;
+ display: block;
+ text-decoration: none;
+ }
+ </style>
+ <template>
+ <google-client-loader id="calendar" name="calendar" version="v3"
+ on-google-api-load="displayCalendars"></google-client-loader>
+ <google-signin-aware
+ scopes="https://www.googleapis.com/auth/calendar.readonly"
+ is-authorized="{{_signedIn}}"></google-signin-aware>
+
+ <ul id="calendars">
+ <li>{{title}}</li>
+ <template is="dom-repeat" items="{{calendars}}">
+ <li style$="{{_computeCalStyle(item.backgroundColor)}}">
+ <a href="{{_computeCalHref(item.id, item.timeZone)}}" target="_blank">{{item.summary}}</a>
+ </li>
+ </template>
+ </ul>
+ </template>
+</dom-module>
+
+<script>
+ Polymer({
+
+ is: 'google-calendar-list',
+
+ properties: {
+ _signedIn: {
+ type: Boolean,
+ value: false,
+ observer: '_signInChanged'
+ },
+ /**
+ * A title to be displayed on top of the calendar list.
+ */
+ title: {
+ type: String,
+ value: 'My calendars'
+ },
+ /**
+ * List of calendars
+ */
+ calendars: {
+ type: Array,
+ value: function() { return []; },
+ readOnly: true
+ }
+ },
+
+ _signInChanged: function(val) {
+ if (val) {
+ this.displayCalendars();
+ }
+ else {
+ this._setCalendars([]);
+ }
+ },
+
+ _computeCalStyle: function(backgroundColor) {
+ return 'background-color:' + (backgroundColor || 'gray');
+ },
+ _computeCalHref: function(calId, calTimeZone) {
+ return 'https://www.google.com/calendar/embed?src=' + calId + '&ctz=' + calTimeZone;
+ },
+ /**
+ * Displays the calendar list if the user is signed in to Google.
+ */
+ displayCalendars: function() {
+ if (this._signedIn && this.$.calendar.api) {
+ var request = this.$.calendar.api.calendarList.list({"key": ""});
+
+ // var request = this.$.calendar.api.calendarList.list({"key": ""});
+ request.execute(function(resp) {
+ if (resp.error) {
+ console.error("Error with calendarList.list", resp.message)
+ } else {
+ this._setCalendars(resp.items);
+ }
+ }.bind(this));
+ }
+ }
+ });
+</script>
+
+
+<dom-module id="google-calendar-busy-now">
+ <style>
+ span {
+ font-family: Arial, sans-serif;
+ display: inline-block;
+ border-radius: .2em;
+ padding: .2em;
+ margin: .2em;
+ overflow: hidden;
+ }
+
+ .busy {
+ background-color: #FA573C;
+ }
+
+ .free {
+ background-color: #7BD148;
+ }
+
+ .na {
+ background-color: #999;
+ }
+ </style>
+ <template>
+ <google-client-loader id="calendar" name="calendar" version="v3"
+ on-google-api-load="displayBusy"></google-client-loader>
+ <google-signin-aware
+ scopes="https://www.googleapis.com/auth/calendar.readonly"
+ is-authorized="{{_isAuthorized}}"></google-signin-aware>
+
+ <span class$="{{_labelClass}}">{{_label}}</span>
+ </template>
+</dom-template>
+<script>
+ (function() {
+ var MS_PER_MINUTE = 60000;
+ var TIME_SPAN = 30;
+
+/**
+A badge showing the free/busy status based on the events in a given calendar.
+
+##### Example
+
+ <google-calendar-busy-now
+ calendarId="YOUR_CAL_ID"
+ apiKey="YOUR_API_KEY"
+ busyLabel="Do not disturb"
+ freeLabel="I'm free, talk to me!">
+ </google-calendar-busy-now>
+
+*/
+ Polymer({
+ is: 'google-calendar-busy-now',
+
+ properties: {
+ /**
+ * Event from this calendar decide whether the status is free/busy.
+ */
+ calendarId: {
+ type: String,
+ value: null,
+ observer: '_calendarIdChanged'
+ },
+ /**
+ * API key to use with Calendar API requests.
+ */
+ apiKey: {
+ type: String,
+ value: null
+ },
+ /**
+ * Label to be displayed if the status is busy.
+ */
+ busyLabel: {
+ type: String,
+ value: "I'm busy"
+ },
+ /**
+ * Label to be displayed if the status is free.
+ */
+ freeLabel: {
+ type: String,
+ value: "I'm free"
+ },
+
+ _labelClass: {
+ type: String,
+ value: ''
+ },
+
+ _label: {
+ type: String,
+ value: ''
+ },
+
+ _isAuthorized: {
+ type: Boolean,
+ value: false,
+ observer: '_isAuthorizedChanged'
+ }
+ },
+
+ _calendarIdChanged: function() {
+ this.displayBusy();
+ },
+
+ _isAuthorizedChanged: function() {
+ this.displayBusy();
+ },
+
+ _setState: function(state) {
+ switch(state) {
+ case 'free':
+ this._label = this.freeLabel;
+ this._labelClass = 'free';
+ break;
+ case 'busy':
+ this._label = this.busyLabel;
+ this._labelClass = 'busy';
+ break;
+ case 'na':
+ this._label = 'n/a';
+ this._labelClass = 'na';
+ break;
+ };
+ },
+ /**
+ * Displays the busy/free status. Use it to refresh label state
+ */
+ displayBusy: function() {
+ if (!this.calendarId) {
+ console.log('CalendarId is required for this component');
+ return;
+ }
+ if (!this._isAuthorized) {
+ this._setState('na');
+ return;
+ }
+ if (this.$.calendar.api) {
+ if (this.apiKey) {
+ gapi.client.setApiKey(this.apiKey);
+ }
+ var now = new Date();
+ var query = {
+ timeMin: now.toISOString(),
+ timeMax: new Date(now.valueOf() + TIME_SPAN * MS_PER_MINUTE).toISOString(),
+ items: [
+ {
+ id: this.calendarId
+ }
+ ]
+ }
+ var request = this.$.calendar.api.freebusy.query(query);
+ request.execute(function(resp) {
+ if (!resp.calendars) {
+ if (resp.error) {
+ this._setState('na');
+ } else {
+ this._setState('free');
+ }
+ return;
+ }
+ if (resp.calendars[this.calendarId].errors) {
+ this._setState('na');
+ return;
+ }
+ var now = new Date();
+ var busyTimes = resp.calendars[this.calendarId];
+ for (var i = 0, busyTime; busyTime = busyTimes.busy[i]; i++) {
+ var start = new Date(busyTime.start);
+ var end = new Date(busyTime.end);
+ var busy = start < now && now < end;
+ this._setState( busy ? 'busy': 'free');
+ if (busy) {
+ break;
+ }
+ }
+ }.bind(this));
+ }
+ }
+ });
+ })();
+</script>
+
diff --git a/polymer_1.0.4/bower_components/google-calendar/index.html b/polymer_1.0.4/bower_components/google-calendar/index.html
new file mode 100644
index 0000000..203f4fa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-calendar/index.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-calendar/tests/google-calendar-list-basic.html b/polymer_1.0.4/bower_components/google-calendar/tests/google-calendar-list-basic.html
new file mode 100644
index 0000000..6d52247
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-calendar/tests/google-calendar-list-basic.html
@@ -0,0 +1,62 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name='viewport' content='width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes'>
+ <title>google-plusone Basic Tests</title>
+ <script src="../../webcomponentsjs/webcomponentsjs.min.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <link rel="import" href="../google-calendar.html">
+ </head>
+ <body>
+
+ <google-calendar-list title="What I'm up to"></google-calendar-list>
+
+ <script>
+
+ function testFetchesCalendars(calendarListEl) {
+ var testCalendar = {
+ 'kind': 'calendar#calendarListEntry',
+ 'id': 'test_id',
+ 'summary': 'test summary',
+ 'description': 'test description',
+ 'timeZone': 'Asia/Calcutta',
+ 'backgroundColor': '#000'
+ };
+
+ // Stub out calendar request call.
+ var api = calendarListEl.$.calendar.api;
+ var request = {
+ 'execute': function(callback) {
+ var resp = {
+ 'items': [testCalendar]
+ };
+ callback(resp);
+ }
+ };
+ sinon.stub(api.calendarList, 'list').returns(request);
+
+ calendarListEl.displayCalendars();
+ Platform.flush();
+
+ // Check if calendars get updated.
+ chai.expect(calendarListEl.calendars).to.eql([testCalendar]);
+ };
+
+ document.addEventListener('polymer-ready', function() {
+ var this = document.querySelector('google-calendar-list');
+
+ // Fake user's sign in.
+ var signin = cal.shadowRoot.querySelector('google-signin-aware');
+ signin.dispatchEvent(new Event('google-signin-aware-success'));
+
+ // Run tests.
+ this.addEventListener('google-api-load', function() {
+ testFetchesCalendars(this);
+ done();
+ });
+ });
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-calendar/tests/index.html b/polymer_1.0.4/bower_components/google-calendar/tests/index.html
new file mode 100755
index 0000000..72ae582
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-calendar/tests/index.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>google-calendar tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+ </head>
+ <body>
+ <script>
+ WCT.loadSuites([
+ 'google-calendar-list-basic.html'
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-calendar/tests/tests.html b/polymer_1.0.4/bower_components/google-calendar/tests/tests.html
new file mode 100755
index 0000000..d253628
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-calendar/tests/tests.html
@@ -0,0 +1,20 @@
+<link rel="import" href="../../polymer-test-tools/tools.html">
+
+<script src="../../polymer-test-tools/mocha-htmltest.js"></script>
+
+<script>
+
+ mocha.setup({ui: 'tdd', slow: 1000, timeout: 5000, htmlbase: ''});
+
+ // Below is a set of sample element test suites.
+ // Replace these with your own suites of tests.
+
+ htmlSuite('google-calendar-list', function() {
+ htmlTest('google-calendar-list-basic.html');
+ });
+
+ // End sample test suites
+
+ mocha.run();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/google-castable-video/.bower.json b/polymer_1.0.4/bower_components/google-castable-video/.bower.json
new file mode 100644
index 0000000..b7f667c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-castable-video/.bower.json
@@ -0,0 +1,36 @@
+{
+ "name": "google-castable-video",
+ "version": "1.0.1",
+ "authors": [
+ "Thorsten Schaeff <thorsten.schaeff@gmail.com>"
+ ],
+ "description": "HTML5 Video Element with extended Chromecast functionality.",
+ "keywords": [
+ "video",
+ "chromecast",
+ "polymer",
+ "web-components"
+ ],
+ "main": "google-castable-video.html",
+ "license": "Apache-2",
+ "homepage": "https://github.com/GoogleWebComponents/google-castable-video",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "c2a1b5e40c9fdd626da835e548600c139185133d"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-castable-video.git",
+ "_target": "^1.0.0",
+ "_originalSource": "GoogleWebComponents/google-castable-video"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-castable-video/LICENSE b/polymer_1.0.4/bower_components/google-castable-video/LICENSE
new file mode 100644
index 0000000..7ba0226
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-castable-video/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2014 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/polymer_1.0.4/bower_components/google-castable-video/README.md b/polymer_1.0.4/bower_components/google-castable-video/README.md
new file mode 100644
index 0000000..aacb050
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-castable-video/README.md
@@ -0,0 +1,6 @@
+google-castable-video
+======================
+
+See the [component landing page](http://googlewebcomponents.github.io/google-castable-video) for more information.
+
+Maintainer: [@tschaeff](http://github.com/tschaeff)
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-castable-video/bower.json b/polymer_1.0.4/bower_components/google-castable-video/bower.json
new file mode 100644
index 0000000..09d105e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-castable-video/bower.json
@@ -0,0 +1,27 @@
+{
+ "name": "google-castable-video",
+ "version": "1.0.1",
+ "authors": [
+ "Thorsten Schaeff <thorsten.schaeff@gmail.com>"
+ ],
+ "description": "HTML5 Video Element with extended Chromecast functionality.",
+ "keywords": [
+ "video",
+ "chromecast",
+ "polymer",
+ "web-components"
+ ],
+ "main": "google-castable-video.html",
+ "license": "Apache-2",
+ "homepage": "https://github.com/GoogleWebComponents/google-castable-video",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-castable-video/demo/index.html b/polymer_1.0.4/bower_components/google-castable-video/demo/index.html
new file mode 100644
index 0000000..b51ea06
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-castable-video/demo/index.html
@@ -0,0 +1,69 @@
+<!doctype html>
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>google-castable-video Demo</title>
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../google-castable-video.html">
+
+</head>
+<body>
+
+ <p>An example of using <code><google-castable-video></code>:</p>
+
+ <video is="google-castable-video" width="500">
+ <source src="http://commondatastorage.googleapis.com/gtv-videos-bucket/big_buck_bunny_1080p.mp4" type="video/mp4">
+ <source src="https://bennugd-vlc.googlecode.com/files/big_buck_bunny_480p.webm" type="video/webm"></source>
+ </video>
+
+ <div id="controls">
+ <button id="play">PLAY</button>
+ <button id="pause">PAUSE</button>
+ <button id="cast">START CASTING</button>
+ <input id="progress" type="range" min="0" max="100" value="0">
+ </div>
+
+ <script>
+ var vid = document.querySelector("video");
+ var playButton = document.querySelector("#play");
+ var pauseButton = document.querySelector("#pause");
+ var castButton = document.querySelector("#cast");
+ var progressSlider = document.querySelector("#progress");
+
+ playButton.addEventListener("click", function(){
+ vid.play();
+ });
+
+ pauseButton.addEventListener("click", function(){
+ vid.pause();
+ });
+
+ castButton.addEventListener("click", function(){
+ vid.launchSessionManager();
+ });
+
+ progressSlider.addEventListener("mouseup", function(){
+ var duration = vid.duration;
+ var newPosition = ( duration / 100 ) * this.value;
+ vid.currentTime = newPosition;
+ });
+
+ //IMPORTANT use this to get the currentTime even when casting
+ vid.addEventListener("google-castable-video-timeupdate",function(e){
+ var duration = vid.duration;
+ var currentTime = e.detail.currentTime;
+ progressSlider.value = currentTime * ( 100 / duration );
+ });
+
+ //listen for casting event to change icon
+ vid.addEventListener("google-castable-video-casting",function(e){
+ if (e.detail.casting) {
+ castButton.innerHTML = "STOP CASTING";
+ } else {
+ castButton.innerHTML = "START CASTING";
+ }
+ });
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-castable-video/google-cast-sender-api.html b/polymer_1.0.4/bower_components/google-castable-video/google-cast-sender-api.html
new file mode 100644
index 0000000..22a03be
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-castable-video/google-cast-sender-api.html
@@ -0,0 +1 @@
+<script src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js"></script>
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-castable-video/google-castable-video.html b/polymer_1.0.4/bower_components/google-castable-video/google-castable-video.html
new file mode 100644
index 0000000..2e420bd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-castable-video/google-castable-video.html
@@ -0,0 +1,390 @@
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="google-cast-sender-api.html">
+
+<!-- TODO(tschaeff):
+- ratechange to change playbackspeed (if even possible)
+-->
+<script>
+ (function() {
+ // Set static variable for the timeupdate delay.
+ var _GOOGLE_CASTABLE_VIDEO_TIMEUPDATE_DELAY = 250;
+/**
+The `google-castable-video` element enables your HTML5 videos to be casted to any Chromecast.
+
+It behaves exactly like an HTML5 video element except for some added methods and events.
+
+Instead of listening for the video element's `timeupdate` event please listen for the `google-castable-video-timeupdate` event. This event is fired if the video is playing locally and on the Chromecast device.
+
+##### Example
+
+ <video is="google-castable-video">
+ <source src="video.mp4" type="video/mp4">
+ </video>
+
+@demo
+*/
+ Polymer({
+
+ is: 'google-castable-video',
+
+ extends: 'video',
+
+ properties: {
+ /**
+ * The appId that references which receiver the Chromecast will load.
+ *
+ * @default chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
+ */
+ appId: {
+ type: String,
+ value: null
+ }
+ },
+
+ listeners: {
+ 'seeked': '_onSeeked',
+ 'volumechange': '_onVolumechange',
+ 'timeupdate': '_onTimeupdate'
+ },
+
+ /**
+ * The real paused state for local and cast playback.
+ *
+ * @property bothPaused
+ * @type bool
+ * @default true
+ */
+ _bothPaused: true,
+ get bothPaused() {
+ return this._bothPaused;
+ },
+
+ /**
+ * Sets or returns the current playback position (in seconds).
+ * Since the local video is paused when the video is playing on the Chromecast device
+ * the objects currentTime property doesn't represent the actual currentTime of the video
+ * playing on the Chromecast device. To always get the actual position please use bothCurrentTime.
+ *
+ * @property bothCurrentTime
+ * @type number
+ * @default 0
+ */
+ get bothCurrentTime() {
+ if (this._casting && this._castMedia) {
+ return this._castMedia.getEstimatedTime();
+ } else {
+ return this.currentTime;
+ }
+ },
+
+ set bothCurrentTime(val) {
+ return this.currentTime = val;
+ },
+
+ /**
+ * The mode state depending on whether the video is playing locally or on the cast device.
+ *
+ * @property casting
+ * @type bool
+ * @default false
+ */
+ _casting: false,
+ get casting() {
+ return this._casting;
+ },
+
+ /**
+ * Returns if any Chromecast is available.
+ *
+ * @property receiverAvailable
+ * @type bool
+ * @default false
+ */
+ _receiverAvailable: false,
+ get receiverAvailable() {
+ return this._receiverAvailable;
+ },
+
+ /**
+ * The `chrome.cast.Media` object.
+ *
+ * @property castMedia
+ * @type chrome.cast.Media
+ * @default null
+ */
+ _castMedia: null,
+ get castMedia() {
+ return this._castMedia;
+ },
+
+ /**
+ * The `chrome.cast.Session` object.
+ *
+ * @property session
+ * @type chrome.cast.Session
+ * @default null
+ */
+ _session: null,
+ get session() {
+ return this._session;
+ },
+
+ ready: function() {
+ // Initialize the cast api.
+ window['__onGCastApiAvailable'] = function(loaded, errorInfo) {
+ if (loaded) {
+ this._initializeCastApi();
+ } else {
+ this._triggerError('INITIALIZE_ERROR');
+ }
+ }.bind(this);
+ },
+
+ // Called internally when the cast sender api has been loaded.
+ _initializeCastApi: function() {
+ if (this.appId === null || typeof this.appId === "undefined") {
+ this.appId = chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID;
+ // TODO ... process for selecting styled media receiver
+ }
+ var sessionRequest = new chrome.cast.SessionRequest(this.appId);
+ var apiConfig = new chrome.cast.ApiConfig(sessionRequest,
+ function(e){
+ // The sessionListener.
+ this._triggerCasting(true);
+ this._session = e;
+ if (this._session.media.length) {
+ this._onMediaDiscovered.call(this, 'onRequestSessionSuccess', this._session.media[0]);
+ }
+ // Bind the session update listener.
+ this._session.addUpdateListener(this._sessionUpdateListener.bind(this));
+ // Set interval for cast timeupdate.
+ this._timeupdateInterval = setInterval(function(){
+ if (this._castMedia && this._castMedia.playerState === 'PLAYING') {
+ this._triggerTimeupdate(this._castMedia.getEstimatedTime());
+ this._bothPaused = false;
+ } else {
+ this._bothPaused = true;
+ }
+ }.bind(this), _GOOGLE_CASTABLE_VIDEO_TIMEUPDATE_DELAY);
+ // Start playing on cast if playing locally.
+ if (!this.paused) {
+ this.play();
+ this.pause(false);
+ }
+ }.bind(this),
+ function(e){
+ // The receiverListener
+ if (e === chrome.cast.ReceiverAvailability.AVAILABLE) {
+ this._triggerAvailability(true);
+ } else {
+ this._triggerAvailability(false);
+ }
+ }.bind(this));
+ chrome.cast.initialize(apiConfig, function(){
+ // The onInitSuccess method.
+ /**
+ * The `google-castable-video-initialized` event is fired when
+ * the cast client API has been initialized.
+ *
+ * @event google-castable-video-initialized
+ */
+ this.fire('google-castable-video-initialized');
+ }.bind(this), function(){
+ this._triggerError('INITIALIZE_ERROR');
+ });
+ },
+
+ /**
+ * Call this when the user clicks the cast icon.
+ * Opens the cast extension to create a session with the selected receiver.
+ *
+ * @method launchSessionManager
+ */
+ launchSessionManager: function(){
+ if (this._receiverAvailable) {
+ // Create the session with the receiver.
+ chrome.cast.requestSession(function(e){
+ // The onRequestSessionSuccess handler gets executed when we're connected.
+ this._triggerCasting(true);
+ this._session = e;
+ this._session.addUpdateListener(this._sessionUpdateListener.bind(this));
+ // If video is playing start playing on chromecast at same position.
+ if (!this.paused) {
+ this.play();
+ this.pause(false);
+ }
+ // Set interval for cast timeupdate.
+ this._timeupdateInterval = setInterval(function(){
+ if (this._castMedia && this._castMedia.playerState === 'PLAYING') {
+ this._triggerTimeupdate(this._castMedia.getEstimatedTime());
+ this._bothPaused = false;
+ } else {
+ this._bothPaused = true;
+ }
+ }.bind(this), _GOOGLE_CASTABLE_VIDEO_TIMEUPDATE_DELAY);
+ }.bind(this));
+ }
+ },
+
+ // Internal method gets called when the cast session status changes.
+ _sessionUpdateListener: function(isAlive){
+ if (!isAlive) {
+ this._triggerCasting(false);
+ this._synchronizeMedia(true);
+ // If video was playing on the receiver start playing locally.
+ if (this._castMedia.playerState === 'PLAYING') {
+ this.play();
+ }
+ this._castMedia = null;
+ this._session = null;
+ // The session died so remove the timeupdate interval.
+ clearInterval(this._timeupdateInterval);
+ }
+ },
+
+ // Internal method gets called when media was set through `launchsession`
+ // or was already playing on cast device.
+ _onMediaDiscovered: function(how, media) {
+ this._castMedia = media;
+ if (how === 'loadMedia') {
+ this._synchronizeMedia(false);
+ }
+ },
+
+ // Internal method to synchronize the media objects.
+ _synchronizeMedia: function(castMaster){
+ if (castMaster) {
+ var position = this._castMedia.getEstimatedTime();
+ this.currentTime = position;
+ } else {
+ var position = this.currentTime;
+ var req = new chrome.cast.media.SeekRequest();
+ req.currentTime = position;
+ this._castMedia.seek(req);
+ }
+ },
+ /**
+ * Call the `play` method from your controls.
+ *
+ * @method play
+ */
+ play: function(cast){
+ if ((cast != undefined && !cast) || (!cast && !this._casting)) {
+ Object.getPrototypeOf(Object.getPrototypeOf(this)).play.call(this);
+ // this.super();
+ } else {
+ // Handle cast media.
+ if (!this._castMedia) {
+ var mediaInfo = new chrome.cast.media.MediaInfo(this.currentSrc);
+ [].forEach.call( // loop through DOM video sources to find the contentType of the current source
+ document.querySelectorAll("video source"),
+ function(el) {
+ // the HTML5 video API resolves the DOM 'src' attribute to an absolute URL for the value of 'currentSrc'; to make it matchable, then, we can only rely on the last segment of the URL
+ if (el.getAttribute("src").split('/').pop()===this.currentSrc.split('/').pop()) {
+ mediaInfo.contentType = el.getAttribute('type');
+ }
+ }
+ );
+ var request = new chrome.cast.media.LoadRequest(mediaInfo);
+ this._session.loadMedia(request,
+ this._onMediaDiscovered.bind(this, 'loadMedia'),
+ function(e){
+ this._triggerError('LOAD_MEDIA_ERROR');
+ }.bind(this)
+ );
+ } else {
+ this._castMedia.play();
+ }
+ }
+ },
+
+ /**
+ * Call the `pause` method from your controls.
+ *
+ * @method pause
+ */
+ pause: function(cast){
+ if ((cast != undefined && !cast) || (!cast && !this._casting)) {
+ Object.getPrototypeOf(Object.getPrototypeOf(this)).pause.call(this);
+ // this.super();
+ } else {
+ this._castMedia.pause();
+ }
+ },
+
+ /**
+ * The `google-castable-video-timeupdate` event is fired whenever
+ * the video's playback position changes.
+ *
+ * @event google-castable-video-timeupdate
+ * @param {Object} detail
+ * @param {number} detail.currentTime The current video position.
+ */
+ _triggerTimeupdate: function(position) {
+ this.fire('google-castable-video-timeupdate', { currentTime: position });
+ },
+
+ /**
+ * The `google-castable-video-error` event is fired whenever
+ * an error occurs.
+ *
+ * @event google-castable-video-error
+ * @param {Object} detail
+ * @param {string} detail.error The error type.
+ */
+ _triggerError: function(description) {
+ this.fire('google-castable-video-error', { error: description });
+ },
+
+ /**
+ * The `google-castable-video-receiver-status` event is fired whenever
+ * the availability of Chromecasts changes. Use this to show or hide the cast icon.
+ *
+ * @event google-castable-video-receiver-status
+ * @param {Object} detail
+ * @param {bool} detail.available Shows if receivers are available.
+ */
+ _triggerAvailability: function(availability) {
+ this._receiverAvailable = availability;
+ this.fire('google-castable-video-receiver-status', { available: availability });
+ },
+
+ /**
+ * The `google-castable-video-casting` event is fired whenever the
+ * connection status to a Chromecast changes. Use this to change the cast icon.
+ *
+ * @event google-castable-video-casting
+ * @param {Object} detail
+ * @param {bool} detail.casting True if connected.
+ */
+ _triggerCasting: function(casting) {
+ this._casting = casting;
+ this.fire('google-castable-video-casting', { casting: casting });
+ },
+
+ // Redirecting `seeked` event to Chromecast.
+ _onSeeked: function(){
+ if (this._casting) {
+ var req = new chrome.cast.media.SeekRequest();
+ req.currentTime = this.currentTime;
+ this._castMedia.seek(req);
+ }
+ },
+
+ // Redirecting `volumechange` event to Chromecast.
+ _onVolumechange: function(){
+ if (this._casting) {
+ var volume = new chrome.cast.Volume(this.volume, this.muted);
+ var volumeRequest = new chrome.cast.media.VolumeRequest(volume);
+ this._castMedia.setVolume(volumeRequest);
+ }
+ },
+
+ // Redirecting `timeupdate` event to `google-castable-video-timeupdate`.
+ _onTimeupdate: function(){
+ this._triggerTimeupdate(this.currentTime);
+ this._bothPaused = this.paused;
+ }
+ });
+ })();
+</script>
diff --git a/polymer_1.0.4/bower_components/google-castable-video/index.html b/polymer_1.0.4/bower_components/google-castable-video/index.html
new file mode 100644
index 0000000..c784ea9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-castable-video/index.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-chart/.bower.json b/polymer_1.0.4/bower_components/google-chart/.bower.json
new file mode 100644
index 0000000..0e6b536
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-chart/.bower.json
@@ -0,0 +1,42 @@
+{
+ "name": "google-chart",
+ "version": "1.0.2",
+ "description": "Encapsulates Google Charts into a web component",
+ "homepage": "https://googlewebcomponents.github.io/google-chart",
+ "main": "google-chart.html",
+ "authors": [
+ "Sérgio Gomes"
+ ],
+ "license": "Apache2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "chart",
+ "charts",
+ "google-visualization",
+ "google"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0",
+ "iron-ajax": "PolymerElements/iron-ajax#1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2",
+ "web-component-tester": "*"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "3f814aaf86913b8fa19e860780e7a14f201f607e"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-chart.git",
+ "_target": "^1.0.0",
+ "_originalSource": "GoogleWebComponents/google-chart"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-chart/LICENSE b/polymer_1.0.4/bower_components/google-chart/LICENSE
new file mode 100644
index 0000000..52aea39
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-chart/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2014 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/polymer_1.0.4/bower_components/google-chart/README.md b/polymer_1.0.4/bower_components/google-chart/README.md
new file mode 100644
index 0000000..2fe6bd2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-chart/README.md
@@ -0,0 +1,6 @@
+google-chart
+============
+
+[Google Charts API](https://developers.google.com/chart/) web components.
+
+See the [component page](https://googlewebcomponents.github.io/google-chart/components/google-chart/) for more information.
diff --git a/polymer_1.0.4/bower_components/google-chart/bower.json b/polymer_1.0.4/bower_components/google-chart/bower.json
new file mode 100644
index 0000000..2cdd2c4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-chart/bower.json
@@ -0,0 +1,33 @@
+{
+ "name": "google-chart",
+ "version": "1.0.2",
+ "description": "Encapsulates Google Charts into a web component",
+ "homepage": "https://googlewebcomponents.github.io/google-chart",
+ "main": "google-chart.html",
+ "authors": [
+ "Sérgio Gomes"
+ ],
+ "license": "Apache2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "chart",
+ "charts",
+ "google-visualization",
+ "google"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0",
+ "iron-ajax": "PolymerElements/iron-ajax#1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2",
+ "web-component-tester": "*"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-chart/demo/chart-data.json b/polymer_1.0.4/bower_components/google-chart/demo/chart-data.json
new file mode 100644
index 0000000..7d9a9cb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-chart/demo/chart-data.json
@@ -0,0 +1 @@
+[["Bar", "Height", { "role": "style" } ], ["Bar 1", 10, "color: gray"], ["Bar 2", 14, "color: #76A7FA"], ["Bar 3", 16, "opacity: 0.2"], ["Bar 4", 22, "stroke-color: #703593; stroke-width: 4; fill-color: #C5A5CF"],["Bar 5", 28, "stroke-color: #871B47; stroke-opacity: 0.6; stroke-width: 8; fill-color: #BC5679; fill-opacity: 0.2"]]
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-chart/demo/country-data.json b/polymer_1.0.4/bower_components/google-chart/demo/country-data.json
new file mode 100644
index 0000000..b664776
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-chart/demo/country-data.json
@@ -0,0 +1,66 @@
+{
+ "cols": [
+ {
+ "id": "ga:country",
+ "label": "Country",
+ "type": "string"
+ },
+ {
+ "id": "ga:sessions",
+ "label": "Sessions",
+ "type": "number"
+ }
+ ],
+ "rows": [
+ {
+ "c": [
+ {
+ "v": "United States"
+ },
+ {
+ "v": 24748
+ }
+ ]
+ },
+ {
+ "c": [
+ {
+ "v": "Canada"
+ },
+ {
+ "v": 15232
+ }
+ ]
+ },
+ {
+ "c": [
+ {
+ "v": "India"
+ },
+ {
+ "v": 9100
+ }
+ ]
+ },
+ {
+ "c": [
+ {
+ "v": "Japan"
+ },
+ {
+ "v": 4845
+ }
+ ]
+ },
+ {
+ "c": [
+ {
+ "v": "United Kingdom"
+ },
+ {
+ "v": 2768
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-chart/demo/index.html b/polymer_1.0.4/bower_components/google-chart/demo/index.html
new file mode 100644
index 0000000..3c34444
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-chart/demo/index.html
@@ -0,0 +1,357 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>google-chart Demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../google-chart.html">
+ <style>
+ code {
+ color: #007000;
+ }
+
+ google-chart {
+ height: 300px;
+ width: 400px;
+ }
+
+ #selection-demo {
+ position: relative;
+ height: 300px;
+ }
+
+ #selection-chart {
+ float: left;
+ }
+
+ #selection-display {
+ display: inline-block;
+ position: relative;
+ top: 50%;
+ }
+ </style>
+
+</head>
+<body>
+
+ <p>A simple <code>google-chart</code> looks like this:</p>
+
+ <google-chart
+ cols='[{"label": "Data", "type": "string"},{"label": "Value", "type": "number"}]'
+ rows='[["Something", 1]]'>
+ </google-chart>
+
+ <p>Charts can be resized with CSS, but you'll need to call the <code>drawChart</code> method when the size changes.</p>
+ <p>Here's a basic responsive example using only CSS and JS. You could also use <code><iron-media-query></code>.</p>
+
+ <style>
+ /* Phone and tablet */
+ #resizing_chart {
+ height: 300px;
+ width: 400px;
+ }
+
+ /* Desktop */
+ @media screen and (min-width: 1024px) {
+ #resizing_chart {
+ width: 800px;
+ }
+ }
+ </style>
+
+ <script>
+ var media = window.matchMedia('(min-width: 1024px)');
+
+ media.addListener(function() {
+ document.getElementById('resizing_chart').drawChart();
+ });
+ </script>
+
+ <google-chart
+ id='resizing_chart'
+ type='column'
+ options='{"title": "Responsive chart",
+ "vAxis": {"minValue" : 0, "maxValue": 10}}'
+ cols='[{"label": "Data", "type": "string"},{"label": "Value", "type": "number"}]'
+ rows='[["Col1", 5.0],["Col2", 5.0],["Col3", 5.0]]'>
+ </google-chart>
+
+ <p>Here's a chart that changes data every 3 seconds:</p>
+
+ <google-chart
+ id='mutating_chart'
+ type='column'
+ options='{"title": "Random data",
+ "vAxis": {"minValue" : 0, "maxValue": 10},
+ "animation": {"duration": "1000"}}'
+ cols='[{"label": "Data", "type": "string"},{"label": "Value", "type": "number"}]'
+ rows='[["Col1", 5.0],["Col2", 5.0],["Col3", 5.0]]'>
+ </google-chart>
+
+ <script>
+ function getRandomValue() {
+ return Math.random() * 10;
+ }
+
+ window.setInterval(function() {
+ var chart = document.getElementById('mutating_chart');
+
+ chart.rows = [["Col1", getRandomValue()],
+ ["Col2", getRandomValue()],
+ ["Col3", getRandomValue()]];
+ }, 3000);
+ </script>
+
+ <p>Here's a pie chart with an area selection:</p>
+
+ <div id="selection-demo">
+ <google-chart
+ type="pie"
+ id="selection-chart"
+ options='{"title": "Distribution of days in 2001H1"}'
+ cols='[{"label": "Month", "type": "string"},{"label": "Days", "type": "number"}]'
+ rows='[["Jan", 31],["Feb", 28],["Mar", 31],["Apr", 30],["May", 31],["Jun", 30]]'>
+ </google-chart>
+ <div id="selection-display">
+ Selected row: <span id="selection-label">None</span>.
+ </div>
+ </div>
+
+ <script>
+ document.addEventListener('WebComponentsReady', function() {
+ var chart = document.querySelector('#selection-chart');
+ var label = document.querySelector('#selection-label');
+
+ chart.addEventListener('google-chart-render', function() {
+ chart.selection = [{row: 1, column: null}];
+ label.textContent = chart.selection[0].row;
+ });
+
+ document.addEventListener('google-chart-select', function(e) {
+ label.textContent =
+ chart.selection[0] ? chart.selection[0].row : 'None';
+ });
+ });
+ </script>
+
+ <p>Here's a chart defined using <code>data</code>, rather than <code>rows</code> and <code>cols</code>:</p>
+
+ <google-chart
+ type='column'
+ options='{"title": "Inventory"}'
+ data='[["Year", "Things", "Stuff"],
+ ["2004", 1000, 400],
+ ["2005", 1170, 460],
+ ["2006", 660, 1120],
+ ["2007", 1030, 540]]'>
+ </google-chart>
+
+ <p>And one with some pretty complicated styling, where the data is loaded from an external JSON resource using the <code>data</code> attribute:</p>
+
+ <google-chart
+ type='column'
+ options='{"title": "Bar height", "legend": "none"}'
+ data='chart-data.json'>
+ </google-chart>
+
+ <p>Website traffic data by country from an external JSON resource where the data is in raw DataTable format.</p>
+
+ <google-chart
+ type='column'
+ options='{"title": "Visitors by Country", "legend": "none"}'
+ data='country-data.json'>
+ </google-chart>
+
+ <h2>Chart gallery</h2>
+
+ <p>Here's an area chart:</p>
+
+ <google-chart
+ type='area'
+ options='{"title": "Days in a month"}'
+ cols='[{"label": "Month", "type": "string"},{"label": "Days", "type": "number"}]'
+ rows='[["Jan", 31],["Feb", 28],["Mar", 31],["Apr", 30],["May", 31],["Jun", 30]]'>
+ </google-chart>
+
+ <p>Here's a bar chart:</p>
+
+ <google-chart
+ type='bar'
+ options='{"title": "Days in a month"}'
+ cols='[{"label": "Month", "type": "string"},{"label": "Days", "type": "number"}]'
+ rows='[["Jan", 31],["Feb", 28],["Mar", 31],["Apr", 30],["May", 31],["Jun", 30]]'>
+ </google-chart>
+
+ <p>Here's a bubble chart:</p>
+
+ <google-chart
+ type='bubble'
+ options='{}'
+ data='[["ID", "Life Expectancy", "Fertility Rate", "Region", "Population"],
+ ["CAN", 80.66, 1.67, "North America", 33739900],
+ ["DEU", 79.84, 1.36, "Europe", 81902307],
+ ["DNK", 78.6, 1.84, "Europe", 5523095],
+ ["EGY", 72.73, 2.78, "Middle East", 79716203],
+ ["GBR", 80.05, 2, "Europe", 61801570],
+ ["IRN", 72.49, 1.7, "Middle East", 73137148],
+ ["IRQ", 68.09, 4.77, "Middle East", 31090763],
+ ["ISR", 81.55, 2.96, "Middle East", 7485600],
+ ["RUS", 68.6, 1.54, "Europe", 141850000],
+ ["USA", 78.09, 2.05, "North America", 307007000]]'>
+ </google-chart>
+
+ <p>Here's a candlestick chart:</p>
+
+ <google-chart
+ type='candlestick'
+ options='{"legend": "none"}'
+ data='[["Day", "low", "start", "end", "high"],
+ ["Mon", 20, 28, 38, 45],
+ ["Tue", 31, 38, 55, 66],
+ ["Wed", 50, 55, 77, 80],
+ ["Thu", 77, 77, 66, 50],
+ ["Fri", 68, 66, 22, 15]]'>
+ </google-chart>
+
+ <p>Here's a column chart:</p>
+
+ <google-chart
+ type='column'
+ options='{"title": "Days in a month"}'
+ cols='[{"label": "Month", "type": "string"},{"label": "Days", "type": "number"}]'
+ rows='[["Jan", 31],["Feb", 28],["Mar", 31],["Apr", 30],["May", 31],["Jun", 30]]'>
+ </google-chart>
+
+ <p>Here's a combo chart:</p>
+
+ <google-chart
+ type='combo'
+ options='{"seriesType": "bars", "series": {"2": {"type": "line"}}}'
+ data='[["Day", "A", "B", "C"],
+ ["Mon", 20, 45, 28],
+ ["Tue", 31, 66, 38],
+ ["Wed", 50, 80, 55],
+ ["Thu", 77, 50, 77],
+ ["Fri", 68, 15, 66]]'>
+ </google-chart>
+
+ <p>Here's a geo chart:</p>
+
+ <google-chart
+ type='geo'
+ data='[["Country", "Popularity"],
+ ["Germany", 200],
+ ["United States", 300],
+ ["Brazil", 400],
+ ["Canada", 500],
+ ["France", 600],
+ ["RU", 700]]'>
+ </google-chart>
+
+ <p>Here's a histogram:</p>
+
+ <google-chart
+ type='histogram'
+ options='{"title": "Days in a month", "legend": "none", "histogram": { "bucketSize": 1 }}'
+ cols='[{"label": "Month", "type": "string"},{"label": "Days", "type": "number"}]'
+ rows='[["Jan", 31],["Feb", 28],["Mar", 31],["Apr", 30],["May", 31],["Jun", 30]]'>
+ </google-chart>
+
+ <p>Here's a line chart:</p>
+
+ <google-chart
+ type='line'
+ options='{"title": "Days in a month"}'
+ cols='[{"label": "Month", "type": "string"},{"label": "Days", "type": "number"}]'
+ rows='[["Jan", 31],["Feb", 28],["Mar", 31],["Apr", 30],["May", 31],["Jun", 30]]'>
+ </google-chart>
+
+ <p>Here's a pie chart:</p>
+
+ <google-chart
+ type='pie'
+ options='{"title": "Distribution of days in 2001H1"}'
+ cols='[{"label": "Month", "type": "string"},{"label": "Days", "type": "number"}]'
+ rows='[["Jan", 31],["Feb", 28],["Mar", 31],["Apr", 30],["May", 31],["Jun", 30]]'>
+ </google-chart>
+
+ <p>Here's a scatter chart:</p>
+
+ <google-chart
+ type='scatter'
+ options='{"legend": "none"}'
+ data='[["A", "B"],
+ [20, 45],
+ [31, 66],
+ [50, 80],
+ [77, 50],
+ [68, 15]]'>
+ </google-chart>
+
+ <p>Here's a stepped area chart:</p>
+
+ <google-chart
+ type='stepped-area'
+ options='{"title": "Days in a month"}'
+ cols='[{"label": "Month", "type": "string"},{"label": "Days", "type": "number"}]'
+ rows='[["Jan", 31],["Feb", 28],["Mar", 31],["Apr", 30],["May", 31],["Jun", 30]]'>
+ </google-chart>
+
+ <p>Here's a table chart:</p>
+
+ <google-chart
+ type="table"
+ options='{"title": "Inventory"}'
+ data='[["Year", "Things", "Stuff"],
+ ["2004", 1000, 400],
+ ["2005", 1170, 460],
+ ["2006", 660, 1120],
+ ["2007", 1030, 540]]'>
+ </google-chart>
+
+ <p>Here are three gauges:</p>
+
+ <google-chart
+ type='gauge'
+ data='[["Label", "Value"],["Memory", 80],["CPU", 55],["Network", 68]]'
+ options='{"width": 400,
+ "height": 120,
+ "redFrom": 90,
+ "redTo": 100,
+ "yellowFrom":75,
+ "yellowTo": 90,
+ "minorTicks": 5}'>
+ </google-chart>
+
+ <p>Here are three gauges with random data that change every three seconds:</p>
+
+ <google-chart
+ id="mutating_gauge"
+ type="gauge"
+ data='[["Label", "Value"],["Memory", 80],["CPU", 55],["Network", 68]]'
+ options='{"width": 400,
+ "height": 120,
+ "redFrom": 90,
+ "redTo": 100,
+ "yellowFrom": 75,
+ "yellowTo": 90,
+ "minorTicks": 5}'>
+ </google-chart>
+
+ <script>
+ function getRandomGaugeValue(offset, factor) {
+ return offset + Math.round(factor * Math.random());
+ }
+
+ window.setInterval(function() {
+ var gauge = document.getElementById('mutating_gauge');
+
+ gauge.data = [["Label", "Value"],["Memory", getRandomGaugeValue(40, 60)],["CPU", getRandomGaugeValue(40, 60)],["Network", getRandomGaugeValue(60, 20)]];
+
+ }, 3000);
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-chart/google-chart.css b/polymer_1.0.4/bower_components/google-chart/google-chart.css
new file mode 100644
index 0000000..342c816
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-chart/google-chart.css
@@ -0,0 +1,13 @@
+:host {
+ display: -webkit-flex;
+ display: -ms-flex;
+ display: flex;
+ margin: 0;
+ padding: 0;
+ width: 400px;
+ height: 300px;
+}
+
+#chartdiv {
+ width: 100%;
+}
diff --git a/polymer_1.0.4/bower_components/google-chart/google-chart.html b/polymer_1.0.4/bower_components/google-chart/google-chart.html
new file mode 100644
index 0000000..dfec749
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-chart/google-chart.html
@@ -0,0 +1,386 @@
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-ajax/iron-ajax.html">
+<link rel="import" href="../google-apis/google-legacy-loader.html">
+
+<!--
+`google-chart` encapsulates Google Charts as a web component, allowing you to easily visualize
+data. From simple line charts to complex hierarchical tree maps, the chart element provides a
+number of ready-to-use chart types.
+
+ <google-chart
+ type='pie'
+ options='{"title": "Distribution of days in 2001Q1"}'
+ cols='[{"label":"Month", "type":"string"}, {"label":"Days", "type":"number"}]'
+ rows='[["Jan", 31],["Feb", 28],["Mar", 31]]'>
+ </google-chart>
+
+Height and width are specified as style attributes:
+
+ google-chart {
+ height: 300px;
+ width: 50em;
+ }
+
+Data can be provided in one of three ways:
+
+- Via the `cols` and `rows` attributes:
+
+ cols='[{"label":"Mth", "type":"string"}, {"label":"Days", "type":"number"}]'
+ rows='[["Jan", 31],["Feb", 28],["Mar", 31]]'
+
+- Via the `data` attribute, passing in the data directly:
+
+ data='[["Month", "Days"], ["Jan", 31], ["Feb", 28], ["Mar", 31]]'
+
+- Via the `data` attribute, passing in the URL to a resource containing the
+ data, in JSON format:
+
+ data='http://example.com/chart-data.json'
+@demo
+-->
+<dom-module id="google-chart">
+ <link rel="import" type="css" href="google-chart.css">
+ <template>
+ <iron-ajax id="ajax" handle-as="json" url="{{data}}"
+ on-response="_externalDataLoaded"></iron-ajax>
+ <div id="chartdiv"></div>
+ <google-legacy-loader on-api-load="_readyForAction"></google-legacy-loader>
+ </template>
+</dom-module>
+
+<script>
+(function() {
+ "use strict";
+
+ Polymer({
+
+ is: 'google-chart',
+
+ /**
+ * Fired when the graph is displayed.
+ *
+ * @event google-chart-render
+ */
+
+ /**
+ * Fired when the user makes a selection in the chart.
+ *
+ * @event google-chart-select
+ * @param {object} detail
+ * @param {array} detail.selection The user-defined selection.
+ */
+
+ properties: {
+ /**
+ * Sets the type of the chart.
+ *
+ * Should be one of:
+ * - `area`, `bar`, `bubble`, `candlestick`, `column`, `combo`, `geo`,
+ * `histogram`, `line`, `pie`, `scatter`, `stepped-area`
+ *
+ * See <a href="https://google-developers.appspot.com/chart/interactive/docs/gallery">Google Visualization API reference (Chart Gallery)</a> for details.
+ *
+ */
+ type: {
+ type: String,
+ value: 'column',
+ observer: '_typeChanged'
+ },
+
+ /**
+ * Sets the options for the chart.
+ *
+ * Example:
+ * <pre>{
+ * title: "Chart title goes here",
+ * hAxis: {title: "Categories"},
+ * vAxis: {title: "Values", minValue: 0, maxValue: 2},
+ * legend: "none"
+ * };</pre>
+ * See <a href="https://google-developers.appspot.com/chart/interactive/docs/gallery">Google Visualization API reference (Chart Gallery)</a>
+ * for the options available to each chart type.
+ *
+ */
+ options: {
+ type: Object,
+ value: function() { return {}; }
+ },
+
+ /**
+ * Sets the data columns for this object.
+ *
+ * When specifying data with `cols` you must also specify `rows`, and
+ * not specify `data`.
+ *
+ * Example:
+ * <pre>[{label: "Categories", type: "string"},
+ * {label: "Value", type: "number"}]</pre>
+ * See <a href="https://google-developers.appspot.com/chart/interactive/docs/reference#DataTable_addColumn">Google Visualization API reference (addColumn)</a>
+ * for column definition format.
+ *
+ * @attribute cols
+ * @type array
+ */
+ cols: {
+ type: Array,
+ value: function() { return []; }
+ },
+ /**
+ * Sets the data rows for this object.
+ *
+ * When specifying data with `rows` you must also specify `cols`, and
+ * not specify `data`.
+ *
+ * Example:
+ * <pre>[["Category 1", 1.0],
+ * ["Category 2", 1.1]]</pre>
+ * See <a href="https://google-developers.appspot.com/chart/interactive/docs/reference#addrow">Google Visualization API reference (addRow)</a>
+ * for row format.
+ *
+ * @attribute rows
+ * @type array
+ */
+ rows: {
+ type: Array,
+ value: function() { return []; }
+ },
+
+ /**
+ * Sets the entire dataset for this object.
+ * Can be used to provide the data directly, or to provide a URL from
+ * which to request the data.
+ *
+ * The data format can be a two-dimensional array or the DataTable format
+ * expected by Google Charts.
+ * See <a href="https://google-developers.appspot.com/chart/interactive/docs/reference#DataTable">Google Visualization API reference (DataTable constructor)</a>
+ * for data table format details.
+ *
+ * When specifying data with `data` you must not specify `cols` or `rows`.
+ *
+ * Example:
+ * <pre>[["Categories", "Value"],
+ * ["Category 1", 1.0],
+ * ["Category 2", 1.1]]</pre>
+ *
+ * @attribute data
+ * @type array, object, or string
+ */
+ data: {
+ type: Object, // or array, or object
+ value: function() { return []; }
+ },
+
+ /**
+ * Selected datapoint(s) in the map.
+ *
+ * An array of objects, each with a numeric row and/or column property.
+ * `row` and `column` are the zero-based row or column number of an item
+ * in the data table to select.
+ *
+ * To select a whole column, set row to null;
+ * to select a whole row, set column to null.
+ *
+ * Example:
+ * <pre>
+ * [{row:0,column:1}, {row:1, column:null}]
+ * </pre>
+ *
+ * @attribute selection
+ * @type array
+ */
+ selection: {
+ type: Array,
+ value: function() { return []; },
+ observer: '_selectionChanged'
+ },
+ },
+
+ observers: [
+ '_loadData(rows, cols, data)'
+ ],
+
+ _packages: null,
+
+ _chartObject: null,
+
+ _isReady: false,
+
+ _canDraw: false,
+
+ _dataTable: null,
+
+ _chartTypes: null,
+
+ _readyForAction: function(e, detail, sender) {
+ this._loadPackageByChartType();
+
+ google.load("visualization", "1", {
+ packages: this._packages[this.type],
+ callback: function() {
+ this._isReady = true;
+ this._loadChartTypes();
+ this._loadData();
+ }.bind(this)
+ });
+ },
+
+ _typeChanged: function() {
+ // Invalidate current chart object.
+ this._chartObject = null;
+ this._loadData();
+ },
+
+ _selectionChanged: function() {
+ if (this._chartObject && this.setSelection) {
+ this._chartObject.setSelection(this.selection);
+ }
+ },
+
+ /**
+ * Draws the chart.
+ *
+ * Called automatically on first load and whenever one of the attributes
+ * changes. Can be called manually to handle e.g. page resizes.
+ *
+ * @method drawChart
+ * @return {Object} Returns null.
+ */
+ drawChart: function() {
+ if (this._canDraw) {
+ if (!this.options) {
+ this.options = {};
+ }
+ if (!this._chartObject) {
+ var chartClass = this._chartTypes[this.type];
+ if (chartClass) {
+ this._chartObject = new chartClass(this.$.chartdiv);
+ }
+ }
+ if (this._chartObject) {
+ google.visualization.events.addOneTimeListener(this._chartObject,
+ 'ready', function() {
+ this.fire('google-chart-render');
+ }.bind(this));
+
+ google.visualization.events.addListener(this._chartObject,
+ 'select', function() {
+ this.selection = this._chartObject.getSelection();
+ this.fire('google-chart-select',
+ { selection: this._chartObject.getSelection() });
+ }.bind(this));
+
+
+ this._chartObject.draw(this._dataTable, this.options);
+
+ if (this._chartObject.setSelection){
+ this._chartObject.setSelection(this.selection);
+ }
+ } else {
+ this.$.chartdiv.innerHTML = 'Undefined chart type';
+ }
+ }
+ return null;
+ },
+
+ _loadChartTypes: function() {
+ this._chartTypes = {
+ 'area': google.visualization.AreaChart,
+ 'bar': google.visualization.BarChart,
+ 'bubble': google.visualization.BubbleChart,
+ 'candlestick': google.visualization.CandlestickChart,
+ 'column': google.visualization.ColumnChart,
+ 'combo': google.visualization.ComboChart,
+ 'geo': google.visualization.GeoChart,
+ 'histogram': google.visualization.Histogram,
+ 'line': google.visualization.LineChart,
+ 'pie': google.visualization.PieChart,
+ 'scatter': google.visualization.ScatterChart,
+ 'stepped-area': google.visualization.SteppedAreaChart,
+ 'table': google.visualization.Table,
+ 'gauge': google.visualization.Gauge
+ };
+ },
+
+ _loadPackageByChartType: function() {
+ this._packages = {
+ 'area': 'corechart',
+ 'bar': 'corechart',
+ 'bubble': 'corechart',
+ 'candlestick': 'corechart',
+ 'column': 'corechart',
+ 'combo': 'corechart',
+ 'geo': 'corechart',
+ 'histogram': 'corechart',
+ 'line': 'corechart',
+ 'pie': 'corechart',
+ 'scatter': 'corechart',
+ 'stepped-area': 'corechart',
+ 'table': 'table',
+ 'gauge': 'gauge'
+ };
+ },
+
+ _loadData: function() {
+ this._canDraw = false;
+ if (this._isReady) {
+ if (typeof this.data == 'string' || this.data instanceof String) {
+ // Load data asynchronously, from external URL.
+ this.$.ajax.generateRequest();
+ } else {
+ var dataTable = this._createDataTable();
+ this._canDraw = true;
+ if (dataTable) {
+ this._dataTable = dataTable;
+ this.drawChart();
+ }
+ }
+ }
+ },
+
+ _externalDataLoaded: function(e) {
+ var dataTable = this._createDataTable(e.detail.response);
+ this._canDraw = true;
+ this._dataTable = dataTable;
+ this.drawChart();
+ },
+
+ _createDataTable: function(data) {
+ var dataTable = null;
+
+ // If a data object was not passed to this function, default to the
+ // chart's data attribute. Passing a data object is necessary for
+ // cases when the data attribute is a URL pointing to an external
+ // data source.
+ if (!data) {
+ data = this.data;
+ }
+ if (!data)
+ data = [];
+
+ if (this.rows && this.rows.length > 0 && this.cols &&
+ this.cols.length > 0) {
+ // Create the data table from cols and rows.
+ dataTable = new google.visualization.DataTable();
+ dataTable.cols = this.cols;
+
+ for (var i = 0; i < this.cols.length; i++) {
+ dataTable.addColumn(this.cols[i]);
+ }
+
+ dataTable.addRows(this.rows);
+ } else {
+ // Create dataTable from the passed data or the data attribute.
+ // Data can be in the form of raw DataTable data or a two
+ // dimensional array.
+ if (data.rows && data.cols) {
+ dataTable = new google.visualization.DataTable(data);
+ } else if (data.length > 0) {
+ dataTable = google.visualization.arrayToDataTable(data);
+ }
+ }
+
+ return dataTable;
+ }
+ });
+})();
+</script>
diff --git a/polymer_1.0.4/bower_components/google-chart/index.html b/polymer_1.0.4/bower_components/google-chart/index.html
new file mode 100644
index 0000000..203f4fa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-chart/index.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-feeds/.bower.json b/polymer_1.0.4/bower_components/google-feeds/.bower.json
new file mode 100644
index 0000000..49a801a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-feeds/.bower.json
@@ -0,0 +1,34 @@
+{
+ "name": "google-feeds",
+ "version": "1.0.1",
+ "homepage": "https://github.com/GoogleWebComponents/google-feeds",
+ "authors": [
+ "Addy Osmani <addyosmani@gmail.com>"
+ ],
+ "description": "Google Feeds element for Polymer",
+ "main": "google-feeds.html",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "feeds",
+ "api"
+ ],
+ "license": "Apache-2",
+ "dependencies": {
+ "polymer": "polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0",
+ "iron-jsonp-library": "PolymerElements/iron-jsonp-library#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "9d731a368b3a2321280c9839f43573c843d20093"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-feeds.git",
+ "_target": "^1.0.0",
+ "_originalSource": "GoogleWebComponents/google-feeds"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-feeds/.gitignore b/polymer_1.0.4/bower_components/google-feeds/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-feeds/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/google-feeds/LICENSE b/polymer_1.0.4/bower_components/google-feeds/LICENSE
new file mode 100644
index 0000000..c174529
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-feeds/LICENSE
@@ -0,0 +1,24 @@
+Copyright (c) 2015, Google Web Components
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/polymer_1.0.4/bower_components/google-feeds/README.md b/polymer_1.0.4/bower_components/google-feeds/README.md
new file mode 100644
index 0000000..bf8dbc4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-feeds/README.md
@@ -0,0 +1,2 @@
+# google-feeds
+Polymer element for the [Google Feeds API](https://developers.google.com/feed/)
diff --git a/polymer_1.0.4/bower_components/google-feeds/bower.json b/polymer_1.0.4/bower_components/google-feeds/bower.json
new file mode 100644
index 0000000..7d5a2a3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-feeds/bower.json
@@ -0,0 +1,25 @@
+{
+ "name": "google-feeds",
+ "version": "1.0.1",
+ "homepage": "https://github.com/GoogleWebComponents/google-feeds",
+ "authors": [
+ "Addy Osmani <addyosmani@gmail.com>"
+ ],
+ "description": "Google Feeds element for Polymer",
+ "main": "google-feeds.html",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "feeds",
+ "api"
+ ],
+ "license": "Apache-2",
+ "dependencies": {
+ "polymer": "polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0",
+ "iron-jsonp-library": "PolymerElements/iron-jsonp-library#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-feeds/demo/index.html b/polymer_1.0.4/bower_components/google-feeds/demo/index.html
new file mode 100644
index 0000000..a0fb2bb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-feeds/demo/index.html
@@ -0,0 +1,43 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>google-feeds Demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../google-feeds.html">
+
+</head>
+<body>
+
+ <!-- Single feed query -->
+ <google-feeds feed="http://www.engadget.com/rss-full.xml">
+ </google-feeds>
+
+ <!-- Find feeds -->
+ <google-feeds query="gadgets" id="feedSearch"></google-feeds>
+
+ <!-- Multiple feeds query -->
+ <google-feeds id="feeder"></google-feeds>
+
+ <div></div>
+ <script>
+ var msg = document.querySelector('div');
+ window.addEventListener('google-feeds-response', function(e) {
+ msg.innerHTML += e.target.localName + ' loaded' + '<br>';
+ console.log(e.detail.feed);
+ });
+
+ window.addEventListener('google-feeds-queryresponse', function(e) {
+ console.log('findFeeds response:', e.detail.entries);
+ });
+
+ var feeder = document.getElementById("feeder");
+ feeder.feeds = ['https://news.ycombinator.com/rss',
+ 'http://feeds.bbci.co.uk/news/rss.xml'];
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-feeds/google-feeds.html b/polymer_1.0.4/bower_components/google-feeds/google-feeds.html
new file mode 100644
index 0000000..af404e0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-feeds/google-feeds.html
@@ -0,0 +1,222 @@
+<!--
+ Copyright 2015 The Polymer Authors. All rights reserved.
+ Use of this source code is governed by a BSD-style
+ license that can be found in the LICENSE file.
+-->
+<link rel='import' href='../polymer/polymer.html'>
+<link rel='import' href='../google-apis/google-legacy-loader.html'>
+
+<!--
+Exposes [Google Feeds API](https://developers.google.com/feed/)
+
+<b>Example</b>:
+
+ <template is='dom-bind'>
+ <google-feeds feed='http://www.engadget.com/rss-full.xml'
+ results='{{result}}'></google-feeds>
+ <p>Feed title: <span>{{result.title}}</span></p>
+ </template>
+
+@demo
+-->
+<dom-module id='google-feeds'>
+ <template>
+ <div id='content'></div>
+ </template>
+</dom-module>
+<script>
+(function() {
+ Polymer({
+
+ is: 'google-feeds',
+
+ /**
+ * Fired when feed has been loaded
+ * @param {object} feed feed object
+ * @event google-feeds-response
+ */
+ /**
+ * Fired when feed load fails
+ * @param {string} status load status
+ * @event google-feeds-error
+ */
+ /**
+ * Fired when multiple feeds have loaded successfully
+ * @param {object} feeds multiple feeds
+ * @event google-multi-feeds-response
+ */
+ /**
+ * Fired when feed query fails
+ * @param {string} status status
+ * @event google-feeds-queryerror
+ */
+ /**
+ * Fired when feed query succeeds
+ * @param {object} entries query results
+ * @event google-feeds-queryresponse
+ */
+
+ properties: {
+
+ /**
+ * url of the feed to fetch.
+ */
+ feed: {
+ type: String,
+ observer: '_feedChanged'
+ },
+
+ /**
+ * An array of multiple feeds. Feed will load, and report results in `google-feeds-response` event.
+ */
+ feeds: {
+ type: Array,
+ value: function() { return []; },
+ observer: '_feedsChanged'
+ },
+
+ /**
+ * Result of loading a single feed url
+ */
+ results: {
+ type: Object,
+ value: null,
+ notify: true
+ },
+
+ /**
+ * Query for google.feeds.findFeeds(). Query result will be reported through `google-feeds-queryresponse` event
+ */
+ query: {
+ type: String,
+ observer: '_queryChanged'
+ },
+
+ /**
+ * Number of feed items to fetch in fetchFeed
+ */
+ count: {
+ type: Number,
+ value: 32
+ },
+
+ /**
+ * True if feeds API is loading an item
+ */
+ loading: {
+ type: Boolean,
+ notify: true
+ }
+ },
+
+ attached: function() {
+ this.pendingFeeds = [];
+ },
+
+ _feedChanged: function() {
+ if (this.feed) {
+ this.loading = true;
+ // call fetchFeeds async to make sure any binding to count property
+ // is resolved before fetchFeeds is called
+ this._withFeedsApi(this._fetchFeeds.bind(this));
+ } else {
+ this.results = null;
+ }
+ },
+
+ _fetchFeeds: function() {
+ var feed = new google.feeds.Feed(this.feed);
+ feed.includeHistoricalEntries(); // tell the API we want to have old entries too
+ feed.setNumEntries(this.count); // we want this maximum number of entries, if they exist
+ feed.load(this._fetchFeedsDone.bind(this));
+ },
+
+ _fetchFeedsDone: function(results) {
+ this.loading = false;
+ if (results.error) {
+ this.results = {};
+ this.fire('google-feeds-error', {status: results.status});
+ } else {
+ this.results = results.feed;
+ this.fire('google-feeds-response', {feed: results.feed});
+ }
+ },
+
+ _feedsChanged: function() {
+ this._withFeedsApi(function(item) {
+ this._fetchMultipleFeeds(this.feeds, function(results) {
+ // TODO: Figure out why the onLoad callback
+ // isn't getting fired. Below isn't fired.
+ this.fire('google-multi-feeds-response', { feeds: results });
+ });
+ }.bind(this));
+ },
+
+ _fetchMultipleFeeds: function(feeds, onLoad) {
+ var feedControl = new google.feeds.FeedControl();
+ if (feeds) {
+ feeds.forEach(function(item) {
+ feedControl.addFeed(item);
+ });
+ feedControl.setNumEntries(this.count);
+ feedControl.draw(this.$.content);
+ google.setOnLoadCallback(onLoad);
+ }
+ },
+
+ _queryChanged: function() {
+ if (this.query) {
+ this.loading = true;
+ this._withFeedsApi(this._findFeeds.bind(this));
+ }
+ },
+
+ _findFeeds: function() {
+ google.feeds.findFeeds(this.query, this._findFeedsDone.bind(this));
+ },
+
+ _findFeedsDone: function(results) {
+ this.loading = false;
+ if (results.error) {
+ this.fire('google-feeds-queryerror', {status: results.status});
+ } else {
+ this.fire('google-feeds-queryresponse', {entries: results.entries});
+ }
+ },
+
+ // TODO(ffu): integrate the ability to load a specific api like feeds
+ // into google-jsapi.
+ _feedsCallbacks: [],
+
+ _feedsApiLoaded: function() {
+ while (this._feedsCallbacks.length) {
+ var fn = this._feedsCallbacks.shift();
+ fn();
+ }
+ },
+
+ _isApiLoaded: function() {
+ return !!(window.google && google.feeds && google.feeds.Feed);
+ },
+
+ _withFeedsApi: function(callback) {
+ if (this._isApiLoaded() && callback) {
+ callback();
+ } else {
+ if (!this.feedsApiLoading) {
+ var loaded = this._feedsApiLoaded.bind(this);
+ var loader = document.createElement('google-legacy-loader');
+ loader.addEventListener('api-load', function(e) {
+ google.load('feeds', '1', {callback: loaded});
+ });
+ this.feedsApiLoading = true;
+ }
+ if (callback) {
+ this._feedsCallbacks.push(callback);
+ }
+ }
+ }
+
+ });
+})();
+</script>
diff --git a/polymer_1.0.4/bower_components/google-feeds/index.html b/polymer_1.0.4/bower_components/google-feeds/index.html
new file mode 100644
index 0000000..d6d37f5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-feeds/index.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>Google Feeds</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-hangout-button/.bower.json b/polymer_1.0.4/bower_components/google-hangout-button/.bower.json
new file mode 100644
index 0000000..1a81002
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-hangout-button/.bower.json
@@ -0,0 +1,41 @@
+{
+ "name": "google-hangout-button",
+ "version": "1.0.1",
+ "homepage": "http://googlewebcomponents.github.io/google-hangout-button",
+ "description": "Google Hangout button web component",
+ "main": "google-hangout-button.html",
+ "authors": [
+ "Ewa Gasperowicz"
+ ],
+ "license": "Apache-2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "hangouts",
+ "google"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0"
+ },
+ "devDependencies": {
+ "polymer-test-tools": "Polymer/polymer-test-tools#~0.5.6",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2",
+ "sinon-browser-only": "~1.12.1"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "bead2dc203b4b6ddcf90c9dba3b72486113b7c66"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-hangout-button.git",
+ "_target": "^1.0.0",
+ "_originalSource": "GoogleWebComponents/google-hangout-button"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-hangout-button/LICENSE b/polymer_1.0.4/bower_components/google-hangout-button/LICENSE
new file mode 100644
index 0000000..369577e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-hangout-button/LICENSE
@@ -0,0 +1,14 @@
+Copyright 2014 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
diff --git a/polymer_1.0.4/bower_components/google-hangout-button/README.md b/polymer_1.0.4/bower_components/google-hangout-button/README.md
new file mode 100644
index 0000000..c2fcc2f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-hangout-button/README.md
@@ -0,0 +1,5 @@
+google-hangout-button
+=====================
+
+See the [component landing page](http://googlewebcomponents.github.io/google-hangout-button) for more information.
+
diff --git a/polymer_1.0.4/bower_components/google-hangout-button/bower.json b/polymer_1.0.4/bower_components/google-hangout-button/bower.json
new file mode 100644
index 0000000..b0067f1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-hangout-button/bower.json
@@ -0,0 +1,32 @@
+{
+ "name": "google-hangout-button",
+ "version": "1.0.1",
+ "homepage": "http://googlewebcomponents.github.io/google-hangout-button",
+ "description": "Google Hangout button web component",
+ "main": "google-hangout-button.html",
+ "authors": [
+ "Ewa Gasperowicz"
+ ],
+ "license": "Apache-2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "hangouts",
+ "google"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0"
+ },
+ "devDependencies": {
+ "polymer-test-tools": "Polymer/polymer-test-tools#~0.5.6",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2",
+ "sinon-browser-only": "~1.12.1"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-hangout-button/demo/index.html b/polymer_1.0.4/bower_components/google-hangout-button/demo/index.html
new file mode 100644
index 0000000..fd3c0b0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-hangout-button/demo/index.html
@@ -0,0 +1,46 @@
+<!doctype html>
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>google-hangout-button Demo</title>
+
+ <style>
+ section {
+ max-width: 500px;
+ }
+ section > div {
+ padding: 10px;
+ }
+ </style>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../google-hangout-button.html">
+ <link rel="import" href="../../iron-flex-layout/classes/iron-flex-layout.html">
+</head>
+<body>
+ <section>
+ <div class="layout horizontal center">
+ <span class="flex">Default button</span>
+ <span class="flex"><google-hangout-button></google-hangout-button></span>
+ </div>
+ <div class="layout horizontal center">
+ <span class="flex">Narrow button</span>
+ <span class="flex"><google-hangout-button width="72"></google-hangout-button></span>
+ </div>
+ <div class="layout horizontal center">
+ <span class="flex">Wide Hangout on Air button</span>
+ <span class="flex"><google-hangout-button type="onair" width="175"></google-hangout-button></span>
+ </div>
+ <div class="layout horizontal center">
+ <span class="flex">Automatically launch Hangout app</span>
+ <span class="flex">
+ <google-hangout-button
+ apps='[{"app_id" : "184219133185", "start_data" : "dQw4w9WgXcQ", "app_type" : "ROOM_APP" }]'
+ ></google-hangout-button>
+ </span>
+ </div>
+ </section>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-hangout-button/google-hangout-button.html b/polymer_1.0.4/bower_components/google-hangout-button/google-hangout-button.html
new file mode 100644
index 0000000..f8854ab
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-hangout-button/google-hangout-button.html
@@ -0,0 +1,142 @@
+<link rel="import" href="../polymer/polymer.html">
+
+<link rel="import" href="../google-apis/google-plusone-api.html">
+
+<!--
+Element providing a button to start a Google Hangout.
+
+##### Example
+
+ <google-hangout-button></google-hangout-button>
+
+@demo
+-->
+<dom-module id="google-hangout-button">
+ <style>
+ :host, span {
+ display: inline-block;
+ }
+ </style>
+ <template>
+ <google-plusone-api id="plusone" on-api-load="_load"></google-plusone-api>
+ <span id="container"></span>
+ </template>
+</dom-module>
+<script>
+ Polymer({
+ is: 'google-hangout-button',
+
+ /**
+ * Fired when the hangout api is loaded but before rendering the button.
+ *
+ * @event google-hangout-button-pregame
+ * @param {Object} e Event parameters.
+ */
+
+ /**
+ * Fired when the button is rendered and ready to use.
+ *
+ * @event google-hangout-button-ready
+ * @param {Object} e Event parameters.
+ */
+
+ properties: {
+
+ /**
+ * Specifies what type of Hangout should be started.
+ * Valid values are 'normal', 'onair', 'party' and 'moderated'
+ *
+ * See the [Hangout button parameter reference](https://developers.google.com/+/hangouts/button#hangout_button_parameters)
+ * for more details.
+ */
+ type: {
+ type: String,
+ value: 'normal'
+ },
+
+ /**
+ * Specifies the Google+ Hangout apps to launch when a user clicks the
+ * Hangout button. Invalid objects and parameters are ignored.
+ *
+ * See the [Initial app parameters reference](https://developers.google.com/+/hangouts/button#initial_app_parameters)
+ * for more details.
+ */
+ apps: {
+ type: Array,
+ value: function() { return []; }
+ },
+
+ /**
+ * Specifies the list of people to invite when the user clicks the
+ * Hangout button. Invalid objects and parameters are ignored.
+ *
+ * See the [Invite parameters reference](https://developers.google.com/+/hangouts/button#invite_parameters)
+ * for more details.
+ */
+ invites: {
+ type: Array,
+ value: function() { return []; }
+ },
+
+ /**
+ * Pre-populates the topic field for Hangouts on Air. Note that users can
+ * change the topic of the Hangout after they have joined.
+ */
+ topic: {
+ type: String,
+ value: null
+ },
+
+ /**
+ * Specifies the width of the button.
+ */
+ width: {
+ type: Number,
+ value: 136
+ },
+
+ _loaded: {
+ type: Boolean,
+ value: false
+ }
+ },
+
+ _load: function() {
+ // TODO(sjmiles): pre/post shenanigans required because gapi.hangout.render
+ // throws if not rendered into main document light-dom
+ var container = this._pregame();
+ this.$.plusone.api.hangout.render(container, {
+ 'render': 'createhangout',
+ 'hangout_type': this.type,
+ 'initial_apps': this.apps,
+ 'invites': this.invites,
+ 'topic': this.topic,
+ 'widget_size': this.width
+ });
+ this._postgame(container);
+ },
+ _pregame: function() {
+ var object = document.createElement('span');
+ document.body.appendChild(object);
+ this.fire('google-hangout-button-pregame');
+ return object;
+ },
+ _postgame: function(object) {
+ // when the iframe finishes it's dirty business, snarf it into the shadow-root
+ var iframe = object.firstElementChild;
+ iframe.addEventListener('load', function() {
+ if (!this._loaded) {
+ // TODO(sjmiles): appending directly to shadowRoot not working under polyfill
+ //this.shadowRoot.appendChild(object);
+ this.$.container.appendChild(object);
+ this._loaded = true;
+ this.fire('google-hangout-button-ready');
+ }
+ }.bind(this));
+ },
+ ready: function () {
+ this.apps = this.apps || [];
+ this.invites = this.invites || [];
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/google-hangout-button/index.html b/polymer_1.0.4/bower_components/google-hangout-button/index.html
new file mode 100644
index 0000000..203f4fa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-hangout-button/index.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-hangout-button/tests/google-hangout-button-basic.html b/polymer_1.0.4/bower_components/google-hangout-button/tests/google-hangout-button-basic.html
new file mode 100644
index 0000000..7eefd3c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-hangout-button/tests/google-hangout-button-basic.html
@@ -0,0 +1,73 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>google-plusone Basic Tests</title>
+ <script src="../../webcomponentsjs/webcomponents.min.js"></script>
+ <link rel="import" href="../../polymer-test-tools/tools.html">
+ <script src="../../polymer-test-tools/htmltest.js"></script>
+ <script src="../../sinon-browser-only/sinon.js"></script>
+ <link rel="import" href="../google-hangout-button.html">
+ </head>
+ <body>
+ <google-hangout-button
+ type="party"
+ apps="[{'app_id': '184219133185', 'start_data': 'dQw4w9WgXcQ', 'app_type': 'ROOM_APP' }]"
+ topic="test topic"
+ invites="[{ id: 'foo@example.com', invite_type: 'EMAIL' }]"
+ width="72">
+ </google-hangout-button>
+ <script>
+ function testIframeCreated(hangoutButton) {
+ chai.assert.ok(hangoutButton.shadowRoot.querySelector('iframe'));
+ }
+
+ function testHangoutArgumentsAreApplied(hangoutButton, apiSpy) {
+ chai.assert.ok(apiSpy.calledOnce);
+ chai.assert.ok(apiSpy.calledWith(sinon.match.any, sinon.match({
+ 'hangout_type': 'party'
+ })), 'Loaded hangout type different than requested type');
+
+ chai.assert.ok(apiSpy.calledWith(sinon.match.any, sinon.match({
+ 'initial_apps': "[{'app_id': '184219133185', 'start_data': " +
+ "'dQw4w9WgXcQ', 'app_type': 'ROOM_APP' }]"
+ })), 'Loaded apps different than requested apps');
+
+ chai.assert.ok(apiSpy.calledWith(sinon.match.any, sinon.match({
+ 'topic': "test topic"
+ })), 'Loaded topic different than requested topic');
+
+ chai.assert.ok(apiSpy.calledWith(sinon.match.any, sinon.match({
+ 'invites': "[{ id: 'foo@example.com', invite_type: 'EMAIL' }]"
+ })), 'Loaded invites different than requested invites');
+
+ chai.assert.ok(apiSpy.calledWith(sinon.match.any, sinon.match({
+ 'widget_size': 72
+ })), 'Loaded width different than requested width');
+ }
+
+ document.addEventListener('polymer-ready', function() {
+
+ var hg = document.querySelector('google-hangout-button');
+ var apiSpy;
+
+ // Set up Api spies.
+ hg.addEventListener('google-hangout-button-pregame', function() {
+ var yt = hg.shadowRoot.querySelector('google-plusone-api');
+ apiSpy = sinon.spy(yt.api.hangout, 'render');
+ });
+
+ hg.addEventListener('google-hangout-button-ready', function() {
+ // Check if element's arguments are applied.
+ testHangoutArgumentsAreApplied(hg, apiSpy);
+ // Check if the hangout button iframe is created.
+ testIframeCreated(hg);
+ // Reset spies.
+ apiSpy.reset();
+ done();
+ });
+ });
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-hangout-button/tests/index.html b/polymer_1.0.4/bower_components/google-hangout-button/tests/index.html
new file mode 100755
index 0000000..03bdafb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-hangout-button/tests/index.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Runs all tests</title>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <script src="../../webcomponentsjs/webcomponents.min.js"></script>
+ <link rel="import" href="tests.html">
+ </head>
+ <body>
+ <div id="mocha"></div>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-hangout-button/tests/tests.html b/polymer_1.0.4/bower_components/google-hangout-button/tests/tests.html
new file mode 100755
index 0000000..bebd7df
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-hangout-button/tests/tests.html
@@ -0,0 +1,13 @@
+<link rel="import" href="../../polymer-test-tools/tools.html">
+
+<script src="../../polymer-test-tools/mocha-htmltest.js"></script>
+
+<script>
+ mocha.setup({ui: 'tdd', slow: 1000, timeout: 5000, htmlbase: ''});
+
+ htmlSuite('google-hangout-button', function() {
+ htmlTest('google-hangout-button-basic.html');
+ });
+
+ mocha.run();
+</script>
diff --git a/polymer_1.0.4/bower_components/google-map/.bower.json b/polymer_1.0.4/bower_components/google-map/.bower.json
new file mode 100644
index 0000000..da78d28
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-map/.bower.json
@@ -0,0 +1,48 @@
+{
+ "name": "google-map",
+ "version": "1.0.3",
+ "description": "Google Maps web components",
+ "homepage": "https://googlewebcomponents.github.io/google-map",
+ "main": [
+ "google-map.html",
+ "google-map-search.html",
+ "google-map-marker.html",
+ "google-map-directions.html"
+ ],
+ "authors": [
+ "Frankie Fu <ffu@google.com>",
+ "Scott Miles <sjmiles@google.com>",
+ "Eric Bidelman <ebidel@gmail.com>"
+ ],
+ "license": "Apache-2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "google",
+ "apis",
+ "maps"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0",
+ "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2"
+ },
+ "_release": "1.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.3",
+ "commit": "18dc165f57be98dd15636da96df226ccf475e3c4"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-map.git",
+ "_target": "^1.0.0",
+ "_originalSource": "GoogleWebComponents/google-map"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-map/LICENSE b/polymer_1.0.4/bower_components/google-map/LICENSE
new file mode 100644
index 0000000..52aea39
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-map/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2014 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/polymer_1.0.4/bower_components/google-map/README.md b/polymer_1.0.4/bower_components/google-map/README.md
new file mode 100644
index 0000000..5448807
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-map/README.md
@@ -0,0 +1,5 @@
+google-map
+==========
+
+See the [component page](https://googlewebcomponents.github.io/google-map) for more information.
+
diff --git a/polymer_1.0.4/bower_components/google-map/bower.json b/polymer_1.0.4/bower_components/google-map/bower.json
new file mode 100644
index 0000000..72e45a2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-map/bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "google-map",
+ "version": "1.0.3",
+ "description": "Google Maps web components",
+ "homepage": "https://googlewebcomponents.github.io/google-map",
+ "main": [
+ "google-map.html",
+ "google-map-search.html",
+ "google-map-marker.html",
+ "google-map-directions.html"
+ ],
+ "authors": [
+ "Frankie Fu <ffu@google.com>",
+ "Scott Miles <sjmiles@google.com>",
+ "Eric Bidelman <ebidel@gmail.com>"
+ ],
+ "license": "Apache-2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "google",
+ "apis",
+ "maps"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0",
+ "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-map/demo/index.html b/polymer_1.0.4/bower_components/google-map/demo/index.html
new file mode 100644
index 0000000..43206a3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-map/demo/index.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>Google Map demo</title>
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../google-map.html">
+ <link rel="import" href="../google-map-marker.html">
+ <link rel="import" href="../google-map-directions.html">
+ <style>
+ body {
+ margin: 0;
+ height: 100vh;
+ }
+ #controlsToggle {
+ position: absolute;
+ left: 10%;
+ bottom: 10%;
+ }
+ </style>
+</head>
+<body fullbleed>
+
+<google-map latitude="37.779" longitude="-122.3892" min-zoom="9" max-zoom="11" language="en">
+ <google-map-marker latitude="37.779" longitude="-122.3892"
+ title="Go Giants!" draggable="true">
+ <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/49/San_Francisco_Giants_Cap_Insignia.svg/200px-San_Francisco_Giants_Cap_Insignia.svg.png" />
+ </google-map-marker>
+</google-map>
+
+<google-map-directions start-address="Oakland" end-address="Mountain View" language=
+"en"></google-map-directions>
+
+<button id="controlsToggle" onclick="toggleControls()">Toggle controls</button>
+
+<script>
+ var gmap = document.querySelector('google-map');
+ gmap.addEventListener('api-load', function(e) {
+ document.querySelector('google-map-directions').map = this.map;
+ });
+
+ function toggleControls() {
+ gmap.disableDefaultUi = !gmap.disableDefaultUi;
+ }
+</script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-map/google-map-directions.html b/polymer_1.0.4/bower_components/google-map/google-map-directions.html
new file mode 100644
index 0000000..88fb626
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-map/google-map-directions.html
@@ -0,0 +1,188 @@
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../google-apis/google-maps-api.html">
+
+<!--
+Provides the Google Maps API Directions Service to provide directions
+between a `startAddress` and `endAddress`.
+
+See https://developers.google.com/maps/documentation/javascript/directions for more
+information on the API.
+
+#### Example:
+
+ <template is="dom-bind">
+ <google-map-directions map="{{map}}"
+ start-address="San Francisco"
+ end-address="Mountain View"
+ travel-mode="TRANSIT"></google-map-directions>
+ <google-map map="{{map}}" latitude="37.779"
+ longitude="-122.3892"></google-map>
+ </template>
+
+-->
+
+<dom-module id="google-map-directions">
+ <style>
+ :host {
+ display: none;
+ }
+ </style>
+ <template>
+ <google-maps-api
+ api-key="[[apiKey]]"
+ libraries="[[libraries]]"
+ language="[[language]]"
+ on-api-load="_mapApiLoaded"></google-maps-api>
+ </template>
+</dom-module>
+
+<script>
+ Polymer({
+
+ is: 'google-map-directions',
+
+/**
+Fired whenever the directions service returns a result.
+
+@event google-map-response
+@param {Object} detail
+@param {object} detail.response The directions service response.
+*/
+ properties: {
+ /**
+ * A Maps API key. To obtain an API key, see developers.google.com/maps/documentation/javascript/tutorial#api_key.
+ */
+ apiKey: String,
+
+ /**
+ * The Google map object.
+ *
+ * @type google.maps.Map
+ */
+ map: {
+ type: Object,
+ observer: '_mapChanged'
+ },
+ /**
+ * Start address or latlng to get directions from.
+ *
+ * @type string|google.maps.LatLng
+ */
+ startAddress: {
+ type: String,
+ value: null
+ },
+
+ /**
+ * End address or latlng for directions to end.
+ *
+ * @type string|google.maps.LatLng
+ */
+ endAddress: {
+ type: String,
+ value: null
+ },
+
+ /**
+ * Travel mode to use. One of 'DRIVING', 'WALKING', 'BICYCLING', 'TRANSIT'.
+ */
+ travelMode: {
+ type: String,
+ value: 'DRIVING'
+ },
+
+ /**
+ * A comma separated list (e.g. "places,geometry") of libraries to load
+ * with this map. Defaults to "places". For more information see
+ * https://developers.google.com/maps/documentation/javascript/libraries.
+ *
+ * Note, this needs to be set to the same value as the one used on <google-map>.
+ * If you're overriding that element's `libraries` property, this one also
+ * needs to be set to the Maps API loads the library code.
+ */
+ libraries: {
+ type: String,
+ value: 'places'
+ },
+
+ /**
+ * The localized language to load the Maps API with. For more information
+ * see https://developers.google.com/maps/documentation/javascript/basics#Language
+ *
+ * Note: the Maps API defaults to the preffered language setting of the browser.
+ * Use this parameter to override that behavior.
+ */
+ language: {
+ type: String,
+ value: null
+ },
+
+ /**
+ * The response from the directions service.
+ *
+ */
+ response: {
+ type: Object,
+ observer: '_responseChanged',
+ notify: true
+ }
+ },
+
+ observers: [
+ '_route(startAddress, endAddress, travelMode)'
+ ],
+
+ _mapApiLoaded: function() {
+ this._route();
+ },
+
+ _responseChanged: function() {
+ if (this.directionsRenderer && this.response) {
+ this.directionsRenderer.setDirections(this.response);
+ }
+ },
+
+ _mapChanged: function() {
+ if (this.map && this.map instanceof google.maps.Map) {
+ if (!this.directionsRenderer) {
+ this.directionsRenderer = new google.maps.DirectionsRenderer();
+ }
+ this.directionsRenderer.setMap(this.map);
+ this._responseChanged();
+ } else {
+ // If there is no more map, remove the directionsRenderer from the map and delete it.
+ this.directionsRenderer.setMap(null);
+ this.directionsRenderer = null;
+ }
+ },
+
+ _route: function() {
+ // Abort attempts to _route if the API is not available yet or the
+ // required attributes are blank.
+ if (typeof google == 'undefined' || typeof google.maps == 'undefined' ||
+ !this.startAddress || !this.endAddress) {
+ return;
+ }
+
+ // Construct a directionsService if necessary.
+ // Wait until here where the maps api has loaded and directions are actually needed.
+ if (!this.directionsService) {
+ this.directionsService = new google.maps.DirectionsService();
+ }
+
+ var request = {
+ origin: this.startAddress,
+ destination: this.endAddress,
+ travelMode: this.travelMode
+ };
+ this.directionsService.route(request, function(response, status) {
+ if (status == google.maps.DirectionsStatus.OK) {
+ this.response = response;
+ this.fire('google-map-response', {response: response});
+ }
+ }.bind(this));
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/google-map/google-map-marker.html b/polymer_1.0.4/bower_components/google-map/google-map-marker.html
new file mode 100644
index 0000000..50aea9e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-map/google-map-marker.html
@@ -0,0 +1,354 @@
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../google-apis/google-maps-api.html">
+
+<!--
+The `google-map-marker` element represents a map marker. It is used as a
+child of `google-map`.
+
+<b>Example</b>:
+
+ <google-map latitude="37.77493" longitude="-122.41942">
+ <google-map-marker latitude="37.779" longitude="-122.3892"
+ title="Go Giants!"></google-map-marker>
+ </google-map>
+
+<b>Example</b> - marker with info window (children create the window content):
+
+ <google-map-marker latitude="37.77493" longitude="-122.41942">
+ <img src="image.png">
+ </google-map-marker>
+
+<b>Example</b> - a draggable marker:
+
+ <google-map-marker latitude="37.77493" longitude="-122.41942"
+ draggable="true"></google-map-marker>
+
+<b>Example</b> - hide a marker:
+
+ <google-map-marker latitude="37.77493" longitude="-122.41942"
+ hidden></google-map-marker>
+
+-->
+
+<dom-module id="google-map-marker">
+ <style>
+ :host {
+ display: none;
+ }
+ </style>
+ <template><content></content></template>
+</dom-module>
+
+<script>
+
+(function() {
+ Polymer({
+
+ is: 'google-map-marker',
+
+ /**
+ * Fired when the marker icon was clicked. Requires the clickEvents attribute to be true.
+ * @param {google.maps.MouseEvent} event The mouse event.
+ * @event google-map-marker-click
+ */
+ /**
+ * Fired when the marker icon was double clicked. Requires the clickEvents attribute to be true.
+ * @param {google.maps.MouseEvent} event The mouse event.
+ * @event google-map-marker-dblclick
+ */
+ /**
+ * Fired for a mousedown on the marker. Requires the mouseEvents attribute to be true.
+ * @event google-map-marker-mousedown
+ * @param {google.maps.MouseEvent} event The mouse event.
+ */
+ /**
+ * Fired when the DOM `mousemove` event is fired on the marker. Requires the mouseEvents
+ * attribute to be true.
+ * @event google-map-marker-mousemove
+ * @param {google.maps.MouseEvent} event The mouse event.
+ */
+ /**
+ * Fired when the mouse leaves the area of the marker icon. Requires the mouseEvents attribute to be
+ * true.
+ * @event google-map-marker-mouseout
+ * @param {google.maps.MouseEvent} event The mouse event.
+ */
+ /**
+ * Fired when the mouse enters the area of the marker icon. Requires the mouseEvents attribute to be
+ * true.
+ * @event google-map-marker-mouseover
+ * @param {google.maps.MouseEvent} event The mouse event.
+ */
+ /**
+ * Fired for a mouseup on the marker. Requires the mouseEvents attribute to be true.
+ *
+ * @event google-map-marker-mouseup
+ * @param {google.maps.MouseEvent} event The mouse event.
+ */
+ /**
+ * Fired for a rightclick on the marker. Requires the clickEvents attribute to be true.
+ * @event google-map-marker-rightclick
+ * @param {google.maps.MouseEvent} event The mouse event.
+ */
+ properties: {
+ /**
+ * A Google Maps marker object.
+ * @type google.maps.Marker
+ */
+ marker: Object,
+
+ /**
+ * The Google map object.
+ * @type google.maps.Map
+ */
+ map: {
+ type: Object,
+ observer: '_mapChanged'
+ },
+
+ /**
+ * A Google Map Infowindow object.
+ */
+ info: {
+ type: Object,
+ value: null
+ },
+
+ /**
+ * When true, marker *click events are automatically registered.
+ */
+ clickEvents: {
+ type: Boolean,
+ value: false,
+ observer: '_clickEventsChanged'
+ },
+
+ /**
+ * Image URL for the marker icon.
+ * @type string|google.maps.Icon|google.maps.Symbol
+ */
+ icon: {
+ type: Object,
+ value: null,
+ observer: '_iconChanged'
+ },
+
+ /**
+ * When true, marker mouse* events are automatically registered.
+ */
+ mouseEvents: {
+ type: Boolean,
+ value: false,
+ observer: '_mouseEventsChanged'
+ },
+
+ /**
+ * Z-index for the marker icon.
+ */
+ zIndex: {
+ type: Number,
+ value: 0,
+ observer: '_zIndexChanged'
+ },
+
+ /**
+ * The marker's longitude coordinate.
+ */
+ longitude: {
+ type: Number,
+ value: null,
+ reflectToAttribute: true
+ },
+ /**
+ * The marker's latitude coordinate.
+ */
+ latitude: {
+ type: Number,
+ value: null,
+ reflectToAttribute: true
+ }
+ },
+
+ observers: [
+ '_updatePosition(latitude, longitude)'
+ ],
+
+ detached: function() {
+ if (this.marker) {
+ this.marker.setMap(null);
+ }
+ if (this._contentObserver)
+ this._contentObserver.disconnect();
+ },
+
+ attached: function() {
+ // If element is added back to DOM, put it back on the map.
+ if (this.marker) {
+ this.marker.setMap(this.map);
+ }
+ },
+
+ _updatePosition: function() {
+ if (this.marker && this.latitude != null && this.longitude != null) {
+ this.marker.setPosition({
+ lat: parseFloat(this.latitude),
+ lng: parseFloat(this.longitude)
+ });
+ }
+ },
+
+ _clickEventsChanged: function() {
+ if (this.map) {
+ if (this.clickEvents) {
+ this._forwardEvent('click');
+ this._forwardEvent('dblclick');
+ this._forwardEvent('rightclick');
+ } else {
+ this._clearListener('click');
+ this._clearListener('dblclick');
+ this._clearListener('rightclick');
+ }
+ }
+ },
+
+ _mouseEventsChanged: function() {
+ if (this.map) {
+ if (this.mouseEvents) {
+ this._forwardEvent('mousedown');
+ this._forwardEvent('mousemove');
+ this._forwardEvent('mouseout');
+ this._forwardEvent('mouseover');
+ this._forwardEvent('mouseup');
+ } else {
+ this._clearListener('mousedown');
+ this._clearListener('mousemove');
+ this._clearListener('mouseout');
+ this._clearListener('mouseover');
+ this._clearListener('mouseup');
+ }
+ }
+ },
+
+ _iconChanged: function() {
+ if (this.marker) {
+ this.marker.setIcon(this.icon);
+ }
+ },
+
+ _zIndexChanged: function() {
+ if (this.marker) {
+ this.marker.setZIndex(this.zIndex);
+ }
+ },
+
+ _mapChanged: function() {
+ // Marker will be rebuilt, so disconnect existing one from old map and listeners.
+ if (this.marker) {
+ this.marker.setMap(null);
+ google.maps.event.clearInstanceListeners(this.marker);
+ }
+
+ if (this.map && this.map instanceof google.maps.Map) {
+ this._mapReady();
+ }
+ },
+
+ _contentChanged: function() {
+ if (this._contentObserver)
+ this._contentObserver.disconnect();
+ // Watch for future updates.
+ this._contentObserver = new MutationObserver( this._contentChanged.bind(this));
+ this._contentObserver.observe( this, {
+ childList: true,
+ subtree: true
+ });
+
+ var content = this.innerHTML.trim();
+ if (content) {
+ if (!this.info) {
+ // Create a new infowindow
+ this.info = new google.maps.InfoWindow();
+ this.infoHandler_ = google.maps.event.addListener(this.marker, 'click', function() {
+ this.info.open(this.map, this.marker);
+ }.bind(this));
+ }
+ this.info.setContent(content);
+ } else {
+ if (this.info) {
+ // Destroy the existing infowindow. It doesn't make sense to have an empty one.
+ google.maps.event.removeListener(this.infoHandler_);
+ this.info = null;
+ }
+ }
+ },
+
+ _mapReady: function() {
+ this._listeners = {};
+ this.marker = new google.maps.Marker({
+ map: this.map,
+ position: new google.maps.LatLng(this.latitude, this.longitude),
+ title: this.title,
+ draggable: this.draggable,
+ visible: !this.hidden,
+ icon: this.icon,
+ zIndex: this.zIndex
+ });
+ this._contentChanged();
+ this._clickEventsChanged();
+ this._contentChanged();
+ this._mouseEventsChanged();
+ setupDragHandler_.bind(this)();
+ },
+
+ _clearListener: function(name) {
+ if (this._listeners[name]) {
+ google.maps.event.removeListener(this._listeners[name]);
+ this._listeners[name] = null;
+ }
+ },
+
+ _forwardEvent: function(name) {
+ this._listeners[name] = google.maps.event.addListener(this.marker, name, function(event) {
+ this.fire('google-map-marker-' + name, event);
+ }.bind(this));
+ },
+
+ attributeChanged: function(attrName, oldVal, newVal) {
+ if (!this.marker) {
+ return;
+ }
+
+ // Cannot use *Changed watchers for native properties.
+ switch (attrName) {
+ case 'hidden':
+ this.marker.setVisible(!this.hidden);
+ break;
+ case 'draggable':
+ this.marker.setDraggable(this.draggable);
+ setupDragHandler_.bind(this)();
+ break;
+ case 'title':
+ this.marker.setTitle(this.title);
+ break;
+ }
+ }
+ });
+
+ function setupDragHandler_() {
+ if (this.draggable) {
+ this.dragHandler_ = google.maps.event.addListener(
+ this.marker, 'dragend', onDragEnd_.bind(this));
+ } else {
+ google.maps.event.removeListener(this.dragHandler_);
+ this.dragHandler_ = null;
+ }
+ }
+
+ function onDragEnd_(e, details, sender) {
+ this.latitude = e.latLng.lat();
+ this.longitude = e.latLng.lng();
+ }
+})();
+</script>
diff --git a/polymer_1.0.4/bower_components/google-map/google-map-search.html b/polymer_1.0.4/bower_components/google-map/google-map-search.html
new file mode 100644
index 0000000..a27947a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-map/google-map-search.html
@@ -0,0 +1,92 @@
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+
+<link rel="import" href="../polymer/polymer.html">
+
+
+<script>
+/**
+Provides Google Maps Places API functionality.
+
+See https://developers.google.com/maps/documentation/javascript/places for more
+information on the API.
+
+#### Example:
+
+ <template is="dom-bind">
+ <google-map-search map="{{map}}" query="Pizza"
+ result="{{result}}"></google-map-search>
+ <google-map map="{{map}}" latitude="37.779"
+ longitude="-122.3892"></google-map>
+ <div>Result:
+ <span>{{result.latitude}}</span>,
+ <span>{{result.longitude}}</span>
+ </div>
+ </template>
+ <script>
+ document.querySelector('google-map-search').search();
+ < /script>
+
+*/
+ Polymer({
+
+ is: 'google-map-search',
+
+/**
+Fired when the search element returns a result.
+
+@event google-map-search-result
+@param {Object} detail
+ @param {number} detail.latitude Latitude of the result.
+ @param {number} detail.longitude Longitude of the result.
+ @param {bool} detail.show Whether to show the result on the map.
+*/
+ properties: {
+ /**
+ * The Google map object.
+ */
+ map: {
+ type: Object,
+ value: null
+ },
+ /**
+ * The search query.
+ */
+ query: {
+ type: String,
+ value: null
+ },
+
+ /**
+ * The search result.
+ */
+ result: {
+ type: Object,
+ value: null,
+ notify: true
+ }
+ },
+
+ observers: [
+ 'search(query,map)'
+ ],
+
+ /**
+ * Performance a search using for `query` for the search term.
+ */
+ search: function() {
+ if (this.query && this.map) {
+ var places = new google.maps.places.PlacesService(this.map);
+ places.textSearch({query: this.query}, this._gotResults.bind(this));
+ }
+ },
+
+ _gotResults: function(results, status) {
+ this.result = {
+ latitude: results[0].geometry.location.lat(),
+ longitude: results[0].geometry.location.lng(),
+ show: true
+ }
+ this.fire('google-map-search-result', this.result);
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/google-map/google-map.html b/polymer_1.0.4/bower_components/google-map/google-map.html
new file mode 100644
index 0000000..a0ce5d4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-map/google-map.html
@@ -0,0 +1,671 @@
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../google-apis/google-maps-api.html">
+<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html">
+<link rel="import" href="google-map-marker.html">
+<!--
+The `google-map` element renders a Google Map.
+
+<b>Example</b>:
+
+ <style>
+ google-map {
+ height: 600px;
+ }
+ </style>
+ <google-map latitude="37.77493" longitude="-122.41942"></google-map>
+
+<b>Example</b> - add markers to the map and ensure they're in view:
+
+ <google-map latitude="37.77493" longitude="-122.41942" fit-to-markers>
+ <google-map-marker latitude="37.779" longitude="-122.3892"
+ draggable="true" title="Go Giants!"></google-map-marker>
+ <google-map-marker latitude="37.777" longitude="-122.38911"></google-map-marker>
+ </google-map>
+
+<b>Example</b>:
+
+ <google-map disable-default-ui zoom="15"></google-map>
+ <script>
+ var map = document.querySelector('google-map');
+ map.latitude = 37.77493;
+ map.longitude = -122.41942;
+ map.addEventListener('google-map-ready', function(e) {
+ alert('Map loaded!');
+ });
+ </script>
+
+<b>Example</b> - with Google directions, using data-binding inside another Polymer element
+
+ <google-map map="{{map}}"></google-map>
+ <google-map-directions map="{{map}}"
+ start-address="San Francisco" end-address="Mountain View">
+ </google-map-directions>
+
+@demo
+-->
+
+<dom-module id="google-map">
+
+ <style>
+ :host {
+ position: relative;
+ display: block;
+ height: 100%;
+ }
+
+ #map {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ }
+
+ </style>
+ <template>
+ <google-maps-api
+ api-key="[[apiKey]]"
+ client-id="[[clientId]]"
+ version="[[version]]"
+ libraries="[[libraries]]"
+ signed-in="[[signedIn]]"
+ language="[[language]]"
+ on-api-load="_mapApiLoaded"></google-maps-api>
+
+ <div id="map"></div>
+
+ <content id="markers" select="google-map-marker"></content>
+
+ </template>
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'google-map',
+
+
+ /**
+ * Fired when the Maps API has fully loaded.
+ * @event google-map-ready
+ */
+ /**
+ * Fired when the when the user clicks on the map (but not when they click on a marker, infowindow, or
+ * other object). Requires the clickEvents attribute to be true.
+ * @event google-map-click
+ * @param {google.maps.MouseEvent} event The mouse event.
+ */
+ /**
+ * Fired when the user double-clicks on the map. Note that the google-map-click event will also fire,
+ * right before this one. Requires the clickEvents attribute to be true.
+ * @event google-map-dblclick
+ * @param {google.maps.MouseEvent} event The mouse event.
+ */
+ /**
+ * Fired repeatedly while the user drags the map. Requires the dragEvents attribute to be true.
+ * @event google-map-drag
+ */
+ /**
+ * Fired when the user stops dragging the map. Requires the dragEvents attribute to be true.
+ * @event google-map-dragend
+ */
+ /**
+ * Fired when the user starts dragging the map. Requires the dragEvents attribute to be true.
+ * @event google-map-dragstart
+ */
+ /**
+ * Fired whenever the user's mouse moves over the map container. Requires the mouseEvents attribute to
+ * be true.
+ * @event google-map-mousemove
+ * @param {google.maps.MouseEvent} event The mouse event.
+ */
+ /**
+ * Fired when the user's mouse exits the map container. Requires the mouseEvents attribute to be true.
+ * @event google-map-mouseout
+ * @param {google.maps.MouseEvent} event The mouse event.
+ */
+ /**
+ * Fired when the user's mouse enters the map container. Requires the mouseEvents attribute to be true.
+ * @event google-map-mouseover
+ * @param {google.maps.MouseEvent} event The mouse event.
+ */
+ /**
+ * Fired when the DOM `contextmenu` event is fired on the map container. Requires the clickEvents
+ * attribute to be true.
+ * @event google-map-rightclick
+ * @param {google.maps.MouseEvent} event The mouse event.
+ */
+ properties: {
+ /**
+ * A Maps API key. To obtain an API key, see developers.google.com/maps/documentation/javascript/tutorial#api_key.
+ */
+ apiKey: String,
+
+ /**
+ * A Maps API for Business Client ID. To obtain a Maps API for Business Client ID, see developers.google.com/maps/documentation/business/.
+ * If set, a Client ID will take precedence over an API Key.
+ */
+ clientId: String,
+
+ /**
+ * A latitude to center the map on.
+ */
+ latitude: {
+ type: Number,
+ value: 37.77493,
+ notify: true,
+ reflectToAttribute: true
+ },
+
+ /**
+ * A Maps API object.
+ */
+ map: {
+ type: Object,
+ notify: true,
+ value: null
+ },
+
+ /**
+ * A comma separated list (e.g. "places,geometry") of libraries to load
+ * with this map. Defaults to "places". For more information see
+ * https://developers.google.com/maps/documentation/javascript/libraries.
+ */
+ libraries: {
+ type: String,
+ value: 'places'
+ },
+
+ /**
+ * A longitude to center the map on.
+ */
+ longitude: {
+ type: Number,
+ value: -122.41942,
+ notify: true,
+ reflectToAttribute: true
+ },
+
+ /**
+ * A zoom level to set the map to.
+ */
+ zoom: {
+ type: Number,
+ value: 10,
+ observer: '_zoomChanged'
+ },
+
+ /**
+ * When set, prevents the map from tilting (when the zoom level and viewport supports it).
+ */
+ noAutoTilt: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Map type to display. One of 'roadmap', 'satellite', 'hybrid', 'terrain'.
+ */
+ mapType: {
+ type: String,
+ value: 'roadmap', // roadmap, satellite, hybrid, terrain,
+ observer: '_mapTypeChanged'
+ },
+
+ /**
+ * Version of the Google Maps API to use.
+ */
+ version: {
+ type: String,
+ value: '3.exp'
+ },
+
+ /**
+ * If set, removes the map's default UI controls.
+ */
+ disableDefaultUi: {
+ type: Boolean,
+ value: false,
+ observer: '_disableDefaultUiChanged'
+ },
+
+ /**
+ * If set, the zoom level is set such that all markers (google-map-marker children) are brought into view.
+ */
+ fitToMarkers: {
+ type: Boolean,
+ value: false,
+ observer: '_fitToMarkersChanged'
+ },
+
+ /**
+ * If true, prevent the user from zooming the map interactively.
+ */
+ disableZoom: {
+ type: Boolean,
+ value: false,
+ observer: '_disableZoomChanged'
+ },
+
+ /**
+ * If set, custom styles can be applied to the map.
+ * For style documentation see developers.google.com/maps/documentation/javascript/reference#MapTypeStyle
+ */
+ styles: {
+ type: Object,
+ value: function() { return {}; }
+ },
+
+ /**
+ * A maximum zoom level which will be displayed on the map.
+ */
+ maxZoom: {
+ type: Number,
+ observer: '_maxZoomChanged'
+ },
+
+ /**
+ * A minimum zoom level which will be displayed on the map.
+ */
+ minZoom: {
+ type: Number,
+ observer: '_minZoomChanged'
+ },
+
+ /**
+ * If true, sign-in is enabled.
+ * See https://developers.google.com/maps/documentation/javascript/signedin#enable_sign_in
+ */
+ signedIn: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The localized language to load the Maps API with. For more information
+ * see https://developers.google.com/maps/documentation/javascript/basics#Language
+ *
+ * Note: the Maps API defaults to the preffered language setting of the browser.
+ * Use this parameter to override that behavior.
+ */
+ language: {
+ type: String
+ },
+
+ /**
+ * When true, map *click events are automatically registered.
+ */
+ clickEvents: {
+ type: Boolean,
+ value: false,
+ observer: '_clickEventsChanged'
+ },
+
+ /**
+ * When true, map drag* events are automatically registered.
+ */
+ dragEvents: {
+ type: Boolean,
+ value: false,
+ observer: '_dragEventsChanged'
+ },
+
+ /**
+ * When true, map mouse* events are automatically registered.
+ */
+ mouseEvents: {
+ type: Boolean,
+ value: false,
+ observer: '_mouseEventsChanged'
+ },
+
+ /**
+ * Additional map options for google.maps.Map constructor.
+ * Use to specify additional options we do not expose as
+ * properties.
+ * Ex: `<google-map additional-map-options='{"mapTypeId":"satellite"}'>`
+ */
+ additionalMapOptions: {
+ type: Object,
+ value: function() { return {}; }
+ }
+
+ },
+
+ behaviors: [
+ Polymer.IronResizableBehavior
+ ],
+
+ listeners: {
+ 'iron-resize': 'resize'
+ },
+
+ observers: [
+ '_debounceUpdateCenter(latitude, longitude)'
+ ],
+
+ created: function() {
+ this.markers = [];
+ },
+
+ attached: function() {
+ this._initGMap();
+ },
+
+ detached: function() {
+ if (this._mutationObserver) {
+ this._mutationObserver.disconnect();
+ this._mutationObserver = null;
+ }
+ },
+
+ _initGMap: function() {
+ if (this.map) {
+ return; // already initialized
+ }
+ if (!(window.google && window.google.maps)) {
+ return; // api not loaded
+ }
+ if (!this.isAttached) {
+ return; // not attached
+ }
+
+ this.map = new google.maps.Map(this.$.map, this._getMapOptions());
+ this._listeners = {};
+ this._updateCenter();
+ this._updateMarkers();
+ this._addMapListeners();
+ this.fire('google-map-ready');
+ },
+
+ _mapApiLoaded: function() {
+ this._initGMap();
+ },
+
+ _getMapOptions: function() {
+ var mapOptions = {
+ zoom: this.zoom,
+ tilt: this.noAutoTilt ? 0 : 45,
+ mapTypeId: this.mapType,
+ disableDefaultUI: this.disableDefaultUi,
+ disableDoubleClickZoom: this.disableZoom,
+ scrollwheel: !this.disableZoom,
+ styles: this.styles,
+ maxZoom: Number(this.maxZoom),
+ minZoom: Number(this.minZoom)
+ };
+
+ // Only override the default if set.
+ // We use getAttribute here because the default value of this.draggable = false even when not set.
+ if (this.getAttribute('draggable') != null) {
+ mapOptions.draggable = this.draggable
+ }
+ for (var p in this.additionalMapOptions)
+ mapOptions[p] = this.additionalMapOptions[p];
+
+ return mapOptions;
+ },
+
+ // watch for future updates
+ _observeMarkers: function() {
+ // Watch for future updates.
+ if (this._mutationObserver) {
+ return;
+ }
+ this._mutationObserver = new MutationObserver( this._updateMarkers.bind(this));
+ this._mutationObserver.observe(this, {
+ childList: true
+ });
+ },
+
+ _updateMarkers: function() {
+ var newMarkers = Array.prototype.slice.call(
+ Polymer.dom(this.$.markers).getDistributedNodes());
+
+ // do not recompute if markers have not been added or removed
+ if (newMarkers.length === this.markers.length) {
+ var added = newMarkers.filter(function(m) {
+ return this.markers && this.markers.indexOf(m) === -1;
+ }.bind(this));
+ if (added.length === 0) {
+ // set up observer first time around
+ if (!this._mutationObserver) {
+ this._observeMarkers();
+ }
+ return;
+ }
+ }
+
+ this._observeMarkers();
+
+ this.markers = newMarkers;
+
+ // Set the map on each marker and zoom viewport to ensure they're in view.
+ if (this.markers.length && this.map) {
+ for (var i = 0, m; m = this.markers[i]; ++i) {
+ m.map = this.map;
+ }
+ }
+ if (this.fitToMarkers) {
+ this._fitToMarkersChanged();
+ }
+ },
+
+ /**
+ * Clears all markers from the map.
+ *
+ * @method clear
+ */
+ clear: function() {
+ for (var i = 0, m; m = this.markers[i]; ++i) {
+ m.marker.setMap(null);
+ }
+ },
+
+ /**
+ * Explicitly resizes the map, updating its center. This is useful if the
+ * map does not show after you have unhidden it.
+ *
+ * @method resize
+ */
+ resize: function() {
+ if (this.map) {
+
+ // saves and restores latitude/longitude because resize can move the center
+ var oldLatitude = this.latitude;
+ var oldLongitude = this.longitude;
+ google.maps.event.trigger(this.map, 'resize');
+ this.latitude = oldLatitude; // restore because resize can move our center
+ this.longitude = oldLongitude;
+
+ if (this.fitToMarkers) { // we might not have a center if we are doing fit-to-markers
+ this._fitToMarkersChanged();
+ }
+ }
+ },
+
+ _debounceUpdateCenter: function() {
+ this.debounce('updateCenter', this._updateCenter);
+ },
+
+ _updateCenter: function() {
+ this.cancelDebouncer('updateCenter');
+
+ if (this.map && this.latitude !== undefined && this.longitude !== undefined) {
+ // allow for latitude and longitude to be String-typed, but still Number valued
+ var lati = Number(this.latitude);
+ if (isNaN(lati)) {
+ throw new TypeError('latitude must be a number');
+ }
+ var longi = Number(this.longitude);
+ if (isNaN(longi)) {
+ throw new TypeError('longitude must be a number');
+ }
+
+ var newCenter = new google.maps.LatLng(lati, longi);
+ var oldCenter = this.map.getCenter();
+
+ if (!oldCenter) {
+ // If the map does not have a center, set it right away.
+ this.map.setCenter(newCenter);
+ } else {
+ // Using google.maps.LatLng returns corrected lat/lngs.
+ oldCenter = new google.maps.LatLng(oldCenter.lat(), oldCenter.lng());
+
+ // If the map currently has a center, slowly pan to the new one.
+ if (!oldCenter.equals(newCenter)) {
+ this.map.panTo(newCenter);
+ }
+ }
+ }
+ },
+
+ _zoomChanged: function() {
+ if (this.map) {
+ this.map.setZoom(Number(this.zoom));
+ }
+ },
+
+ _clickEventsChanged: function() {
+ if (this.map) {
+ if (this.clickEvents) {
+ this._forwardEvent('click');
+ this._forwardEvent('dblclick');
+ this._forwardEvent('rightclick');
+ } else {
+ this._clearListener('click');
+ this._clearListener('dblclick');
+ this._clearListener('rightclick');
+ }
+ }
+ },
+
+ _dragEventsChanged: function() {
+ if (this.map) {
+ if (this.dragEvents) {
+ this._forwardEvent('drag');
+ this._forwardEvent('dragend');
+ this._forwardEvent('dragstart');
+ } else {
+ this._clearListener('drag');
+ this._clearListener('dragend');
+ this._clearListener('dragstart');
+ }
+ }
+ },
+
+ _mouseEventsChanged: function() {
+ if (this.map) {
+ if (this.mouseEvents) {
+ this._forwardEvent('mousemove');
+ this._forwardEvent('mouseout');
+ this._forwardEvent('mouseover');
+ } else {
+ this._clearListener('mousemove');
+ this._clearListener('mouseout');
+ this._clearListener('mouseover');
+ }
+ }
+ },
+
+ _maxZoomChanged: function() {
+ if (this.map) {
+ this.map.setOptions({maxZoom: Number(this.maxZoom)});
+ }
+ },
+
+ _minZoomChanged: function() {
+ if (this.map) {
+ this.map.setOptions({minZoom: Number(this.minZoom)});
+ }
+ },
+
+ _mapTypeChanged: function() {
+ if (this.map) {
+ this.map.setMapTypeId(this.mapType);
+ }
+ },
+
+ _disableDefaultUiChanged: function() {
+ if (!this.map) {
+ return;
+ }
+ this.map.setOptions({disableDefaultUI: this.disableDefaultUi});
+ },
+
+ _disableZoomChanged: function() {
+ if (!this.map) {
+ return;
+ }
+ this.map.setOptions({
+ disableDoubleClickZoom: this.disableZoom,
+ scrollwheel: !this.disableZoom
+ });
+ },
+
+ attributeChanged: function(attrName, oldVal, newVal) {
+ if (!this.map) {
+ return;
+ }
+ // Cannot use *Changed watchers for native properties.
+ switch (attrName) {
+ case 'draggable':
+ this.map.setOptions({draggable: this.draggable});
+ break;
+ }
+ },
+
+ _fitToMarkersChanged: function() {
+ // TODO(ericbidelman): respect user's zoom level.
+
+ if (this.map && this.fitToMarkers) {
+ var latLngBounds = new google.maps.LatLngBounds();
+ for (var i = 0, m; m = this.markers[i]; ++i) {
+ latLngBounds.extend(
+ new google.maps.LatLng(m.latitude, m.longitude));
+ }
+
+ // For one marker, don't alter zoom, just center it.
+ if (this.markers.length > 1) {
+ this.map.fitBounds(latLngBounds);
+ }
+
+ this.map.setCenter(latLngBounds.getCenter());
+ }
+ },
+
+ _addMapListeners: function() {
+ google.maps.event.addListener(this.map, 'center_changed', function() {
+ var center = this.map.getCenter();
+ this.latitude = center.lat();
+ this.longitude = center.lng();
+ }.bind(this));
+
+ google.maps.event.addListener(this.map, 'zoom_changed', function() {
+ this.zoom = this.map.getZoom();
+ }.bind(this));
+
+ this._clickEventsChanged();
+ this._dragEventsChanged();
+ this._mouseEventsChanged();
+ },
+
+ _clearListener: function(name) {
+ if (this._listeners[name]) {
+ google.maps.event.removeListener(this._listeners[name]);
+ this._listeners[name] = null;
+ }
+ },
+
+ _forwardEvent: function(name) {
+ this._listeners[name] = google.maps.event.addListener(this.map, name, function(event) {
+ this.fire('google-map-' + name, event);
+ }.bind(this));
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/google-map/index.html b/polymer_1.0.4/bower_components/google-map/index.html
new file mode 100644
index 0000000..c043544
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-map/index.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+<!-- FIXME rename sources to src,no multiple sources in iron-component-page yet-->
+ <iron-component-page sources='["google-map.html", "google-map-directions.html", "google-map-search.html"]'></iron-component-page>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-map/metadata.html b/polymer_1.0.4/bower_components/google-map/metadata.html
new file mode 100644
index 0000000..d67f827
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-map/metadata.html
@@ -0,0 +1,31 @@
+<x-meta id="google-map" label="Google Map">
+ <template>
+ <google-map style="width: 400px; height: 400px; display: block;"></google-map>
+ </template>
+ <property name="mapType" kind="select" options="roadmap,satellite,hybrid,terrain"></property>
+ <template id="imports">
+ <link rel="import" href="google-map.html">
+ </template>
+</x-meta>
+
+<x-meta id="google-map-directions" label="Google Map Directions">
+ <template>
+ <google-map-directions></google-map-directions>
+ </template>
+ <property name="map" kind="string"></property>
+ <property name="travelMode" kind="select" options="DRIVING,TRANSIT,WALKING,BICYCLING"></property>
+ <template id="imports">
+ <link rel="import" href="google-map-directions.html">
+ </template>
+</x-meta>
+
+<x-meta id="google-map-search" label="Google Map Search">
+ <template>
+ <google-map-search></google-map-search>
+ </template>
+ <property name="map" kind="string"></property>
+ <property name="query" kind="string"></property>
+ <template id="imports">
+ <link rel="import" href="google-map-search.html">
+ </template>
+</x-meta>
diff --git a/polymer_1.0.4/bower_components/google-sheets/.bower.json b/polymer_1.0.4/bower_components/google-sheets/.bower.json
new file mode 100644
index 0000000..577de5e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-sheets/.bower.json
@@ -0,0 +1,43 @@
+{
+ "name": "google-sheets",
+ "version": "1.0.3",
+ "homepage": "https://googlewebcomponents.github.io/google-sheets",
+ "description": "Web components to interact with Google Sheets",
+ "main": "google-sheets.html",
+ "authors": [
+ "Eric Bidelman <ebidel@gmail.com>"
+ ],
+ "license": "Apache2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "spreadsheets",
+ "google"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0",
+ "google-signin": "GoogleWebComponents/google-signin#^1.0.0",
+ "iron-ajax": "PolymerElements/iron-ajax#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "web-component-tester": "*",
+ "google-map": "GoogleWebComponents/google-map#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0"
+ },
+ "_release": "1.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "1.0.3",
+ "commit": "8c3f243c4aee30bc23f57cd52e7615354e17a202"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-sheets.git",
+ "_target": "^1.0.1",
+ "_originalSource": "GoogleWebComponents/google-sheets"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-sheets/LICENSE b/polymer_1.0.4/bower_components/google-sheets/LICENSE
new file mode 100644
index 0000000..52aea39
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-sheets/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2014 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/polymer_1.0.4/bower_components/google-sheets/README.md b/polymer_1.0.4/bower_components/google-sheets/README.md
new file mode 100755
index 0000000..119acf4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-sheets/README.md
@@ -0,0 +1,4 @@
+google-sheets
+================
+
+See the [component page](https://googlewebcomponents.github.io/google-sheets) for more information.
diff --git a/polymer_1.0.4/bower_components/google-sheets/bower.json b/polymer_1.0.4/bower_components/google-sheets/bower.json
new file mode 100755
index 0000000..54a3ad6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-sheets/bower.json
@@ -0,0 +1,34 @@
+{
+ "name": "google-sheets",
+ "version": "1.0.3",
+ "homepage": "https://googlewebcomponents.github.io/google-sheets",
+ "description": "Web components to interact with Google Sheets",
+ "main": "google-sheets.html",
+ "authors": [
+ "Eric Bidelman <ebidel@gmail.com>"
+ ],
+ "license": "Apache2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "spreadsheets",
+ "google"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0",
+ "google-signin": "GoogleWebComponents/google-signin#^1.0.0",
+ "iron-ajax": "PolymerElements/iron-ajax#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "web-component-tester": "*",
+ "google-map": "GoogleWebComponents/google-map#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-sheets/demo/demo-private.html b/polymer_1.0.4/bower_components/google-sheets/demo/demo-private.html
new file mode 100644
index 0000000..7235c8d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-sheets/demo/demo-private.html
@@ -0,0 +1,121 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>google-sheets private data demo</title>
+ <script src="../webcomponentsjs/webcomponents.min.js"></script>
+ <link rel="import" href="google-sheets.html">
+ <link rel="import" href="../google-map/google-map.html">
+ <link rel="import" href="../google-signin/google-signin.html">
+ <style>
+ * {
+ box-sizing: border-box;
+ }
+ body {
+ margin: 2em;
+ font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial;
+ font-weight: 300;
+ background-color: #f1f1f3;
+ }
+ a {
+ text-decoration: none;
+ color: blue;
+ }
+ ul {
+ padding-left: 0;
+ }
+ ul, li {
+ list-style: none;
+ font-size: 14px;
+ }
+ section {
+ border-radius: 3px;
+ box-shadow: 1px 1px 3px #ccc;
+ padding: 1em 2em;
+ background-color: white;
+ width: 500px;
+ min-height: 500px;
+ }
+ main {
+ justify-content: space-around;
+ margin-top: 2em;
+ }
+ </style>
+</head>
+<body unresolved>
+
+<google-signin
+ client-id="1054047045356-j8pgqgls9vdef3rl09hapoicumbte0bo.apps.googleusercontent.com"
+ scopes="https://spreadsheets.google.com/feeds">
+</google-signin>
+
+<p>A <code><google-sheets></code> element returning data from a <b>private</b> Google Spreadsheet:</p>
+
+<!-- Example: private spreadsheet -->
+<google-sheets id="sheet" tabid="1"
+ client-id="750497606405-1hq66meqmr4dp09dn54j9ggv85vbv0gp.apps.googleusercontent.com"
+ key="1QMGizivw3UJ3-R9BFK7sfrXE0RL87dygk2C0RcuKoDY"></google-sheets>
+
+<main layout horizontal>
+
+<section>
+
+ <heading>
+ <h3>List of spreadsheets</h3>
+ </heading>
+
+ <template id="spreadsheets" is="auto-binding">
+ <ul>
+ <template repeat="{{spreadsheets}}">
+ <li>{{title.$t}}</li>
+ </template>
+ </ul>
+ </template>
+
+</section>
+
+<section>
+
+ <template id="rows" bind>
+ <heading>
+ <h3>Spreadsheet rows:
+ <a href="{{openInGoogleDocsURL}}" target="_blank" title="Open in Google Docs →">
+ "{{tab.title}}" tab
+ </a>
+ </h3>
+ <h5>updated: {{tab.updated}}, by: <template repeat="{{rows.authors}}">{{name}} </template></h5>
+ </heading>
+ <ul>
+ <template repeat="{{rows}}">
+ <li>Name: {{gsx$name.$t}} ( lat: {{gsx$lat.$t}}, lng: {{gsx$lng.$t}} )</li>
+ </template>
+ </ul>
+ </template>
+
+</section>
+
+</main>
+
+<script>
+var sheet = document.querySelector('#sheet');
+
+sheet.addEventListener('google-sheet-data', function(e) {
+ switch (e.detail.type) {
+ case 'spreadsheets':
+ document.querySelector('#spreadsheets').spreadsheets = this.spreadsheets;
+ break;
+ case 'rows':
+ document.querySelector('#rows').model = this;
+ break;
+ default:
+ break;
+ }
+});
+
+sheet.addEventListener('core-error', function(e) {
+ alert(e.detail.response);
+});
+</script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-sheets/demo/index.html b/polymer_1.0.4/bower_components/google-sheets/demo/index.html
new file mode 100755
index 0000000..e9e8bab
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-sheets/demo/index.html
@@ -0,0 +1,105 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>google-sheets Demo</title>
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../iron-flex-layout/classes/iron-flex-layout.html">
+ <link rel="import" href="../google-sheets.html">
+ <link rel="import" href="../../google-map/google-map.html">
+ <style>
+ * {
+ box-sizing: border-box;
+ }
+ body {
+ margin: 2em;
+ font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial;
+ font-weight: 300;
+ background-color: #f1f1f3;
+ }
+ a {
+ text-decoration: none;
+ color: blue;
+ }
+ ul {
+ padding-left: 0;
+ }
+ ul, li {
+ list-style: none;
+ font-size: 14px;
+ }
+ section {
+ border-radius: 3px;
+ box-shadow: 1px 1px 3px #ccc;
+ padding: 1em 2em;
+ background-color: white;
+ width: 500px;
+ height: 500px;
+ }
+ google-map {
+ display: block;
+ height: 100%;
+ width: 100%;
+ }
+ main {
+ justify-content: space-around;
+ margin-top: 2em;
+ }
+ </style>
+</head>
+<body>
+
+<p>A <code><google-sheets></code> element returns data from a Google Spreadsheet:</p>
+
+<main class="layout horizontal">
+
+<template id="container" is="dom-bind">
+
+ <section>
+
+ <!-- Example: published spreadsheet -->
+ <google-sheets id="sheet" key="0Anye-JMjUkZZdDBkMVluMEhZMmFGeHpYdDJJV1FBRWc" tab-id="1"
+ published rows="{{rows}}" tab="{{tab}}" open-in-google-docs-url="{{openInGoogleDocsUrl}}"></google-sheets>
+
+ <heading>
+ <h3>Spreadsheet rows:
+ <a href="{{openInGoogleDocsUrl}}" target="_blank" title="Open in Google Docs →">
+ "<span>{{tab.title}}</span>" tab
+ </a>
+ </h3>
+ <h5>updated: <span>{{tab.updated}}</span>, by: <template is="dom-repeat" items="{{rows.authors}}">{{item.name}}</template></h5>
+ </heading>
+ <ul>
+ <template is="dom-repeat" items="[[rows]]">
+ <li>Name: <span>{{item.gsx$name.$t}}</span> ( lat: <span>{{item.gsx$lat.$t}}</span>, lng: <span>{{item.gsx$lng.$t}}</span> )</li>
+ </template>
+ </ul>
+
+ </section>
+
+ <section style="padding: 0;">
+
+ <google-map disable-default-ui fit-to-markers>
+ <template is="dom-repeat" items="[[rows]]">
+ <google-map-marker latitude="{{item.gsx$lat.$t}}" longitude="{{item.gsx$lng.$t}}"></google-map-marker>
+ </template>
+ </google-map>
+
+ <button on-click="useTab" data-tabid="1">View tab 1 data</button>
+ <button on-click="useTab" data-tabid="2">View tab 2 data</button>
+
+ </section>
+
+</template>
+</main>
+
+<script>
+var template = document.querySelector('#container');
+
+template.useTab = function(e, detail, sender) {
+ document.querySelector('#sheet').tabId = Number(e.currentTarget.dataset.tabid);
+};
+</script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-sheets/google-sheets.html b/polymer_1.0.4/bower_components/google-sheets/google-sheets.html
new file mode 100755
index 0000000..de2a5e8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-sheets/google-sheets.html
@@ -0,0 +1,412 @@
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-ajax/iron-ajax.html">
+<link rel="import" href="../google-signin/google-signin-aware.html">
+
+<!--
+Element for interacting with Google Sheets.
+
+`<google-sheets>` pulls cell data from the Google Sheet specified by `key`.
+A spreadsheet's key can be found in the URL when viewing it in google docs (e.g. `docs.google.com/spreadsheet/ccc?key=<KEY>#gid=12345`).
+
+Optionally, pass the `tab-id` attribute to specify a particular worksheet tab in the spreadsheet. For example, the first tab would be `tab-id="1"`. If `tab` is updated at a later time, the underlying data is also updated. **API calls are cached** as to not make extraneous calls.
+
+See [developers.google.com/google-apps/spreadsheets](https://developers.google.com/google-apps/spreadsheets) for full Spreadsheets API documentation.
+
+#### Example
+
+ <google-sheets key="..." tab-id="1" client-id="..."></google-sheets>
+
+ <script>
+ var sheet = document.querySelector('google-sheets');
+
+ sheet.addEventListener('google-sheet-data', function(e) {
+ // this.spreadsheets - list of the user's spreadsheets
+ // this.tab - information on the tab that was fetched
+ // this.rows - cell row information for the tab that was fetched
+ });
+
+ sheet.addEventListener('error', function(e) {
+ // e.detail.response
+ });
+ </script>
+
+<b>Example</b> - `published` is a perf optimization and hints that the spreadsheet has been published (public):
+
+ <google-sheets key="0Anye-JMjUkZZdDBkMVluMEhZMmFGeHpYdDJJV1FBRWc" published></google-sheets>
+
+<b>Example</b> - leaving off the `key` returns as list of the user's spreadsheets.
+
+ <google-sheets client-id="..."></google-sheets>
+
+<b>Example</b> - show a list of Map markers, using data-binding features inside Polymer:
+
+ <google-sheets
+ key="0Anye-JMjUkZZdDBkMVluMEhZMmFGeHpYdDJJV1FBRWc" tab-id="1" rows="{{rows}}"
+ client-id="...">
+ </google-sheets>
+ <google-map>
+ <template is="dom-bind">
+ <google-map-marker latitude="{{gsx$lat.$t}}" longitude="{{gsx$lng.$t}}">
+ </template>
+ </google-map>
+
+@demo
+-->
+
+
+<dom-module id="google-sheets">
+ <template>
+ <template if="{{!published}}">
+ <google-signin-aware client-id="{{clientId}}"
+ scopes="https://spreadsheets.google.com/feeds"
+ on-google-signin-aware-success="_onSignInSuccess"
+ on-google-signin-aware-signed-out="_onSignInFail"></google-signin-aware>
+ </template>
+
+ <iron-ajax id="publicajax" params='{"alt": "json"}' handle-as="json"
+ on-response="_onCellRows"></iron-ajax>
+ <iron-ajax id="listsheetsajax" params='{"alt": "json"}' handle-as="json"
+ on-response="_onSpreadsheetList"></iron-ajax>
+ <iron-ajax id="worksheetajax" params='{"alt": "json"}' handle-as="json"
+ on-response="_onWorksheet"></iron-ajax>
+ <iron-ajax id="cellrowsajax" params='{"alt": "json"}' handle-as="json"
+ on-response="_onCellRows"></iron-ajax>
+
+ </template>
+</dom-module>
+
+<script>
+(function() {
+ var SCOPE_ = 'https://spreadsheets.google.com/feeds';
+
+ // Minimal cache for worksheet row data. Shared across instances so subsequent
+ // accesses are fast and API calls only happen once.
+ var rowDataCache_ = {};
+
+ function generateCacheKey_() {
+ return this.worksheetId_ + '_'+ this.tabId;
+ }
+
+ function getLink_(rel, links) {
+ for (var i = 0, link; link = links[i]; ++i) {
+ if (link.rel === rel) {
+ return link;
+ }
+ }
+ return null;
+ }
+
+ // Conversion of Worksheet Ids to GIDs and vice versa
+ // od4 > 2
+ function wid_to_gid_(wid) {
+ return parseInt(String(wid), 36) ^ 31578;
+ }
+ // 2 > 0d4
+ function gid_to_wid_(gid) {
+ // (gid xor 31578) encoded in base 36
+ return parseInt((gid ^ 31578)).toString(36);
+ }
+
+ window.GoogleSheets = Polymer({
+
+ is: 'google-sheets',
+
+/**
+Fired when the spreadsheet's cell information is available.
+
+@event google-sheet-data
+@param {Object} detail
+@param {Object} detail.data The data returned by the Spreadsheet API.
+@param {string} detail.type The type of data that was fetched. One of 'spreadsheets', 'tab', 'rows' to correspond to the feed type.
+*/
+ properties: {
+ /**
+ * A Google Developers client ID. Obtain from [console.developers.google.com](https://console.developers.google.com). Required for accessing a private spreadsheet. Optional if accessing a public spreadsheet.
+ */
+ clientId: {
+ type: String,
+ value: '',
+ observer: '_configUpdate'
+ },
+
+ /**
+ * The key of the spreadsheet. This can be found in the URL when viewing
+ * the document is Google Docs (e.g. `docs.google.com/spreadsheet/ccc?key=<KEY>`).
+ *
+ * Leaving off this attribute still returns a list of the users spreadsheets in the `spreadsheets` property.
+ */
+ key: {
+ type: String,
+ value: '',
+ observer: '_keyChanged'
+ },
+
+ /**
+ * Tab within a spreadsheet. For example, the first tab in a spreadsheet
+ * would be `tab-id="1"`.
+ */
+ tabId: {
+ type: Number,
+ value: 1,
+ observer: '_configUpdate'
+ },
+
+ /**
+ * A hint that the spreadsheet is published publicly in Google Docs. Used as a performance optimization.
+ * Make sure the sheet is also publicly viewable by anyone in the Share settings.
+ *
+ * @attribute published
+ * @type boolean
+ * @default false
+ */
+ published: {
+ type: Boolean,
+ value: false,
+ observer: '_configUpdate'
+ },
+
+ _worksheetId: {
+ type: String,
+ value: null,
+ readOnly: true
+ },
+
+ /**
+ * The fetched sheet corresponding to the `key` attribute.
+ */
+ sheet: {
+ type: Object,
+ value: function() { return {}; },
+ readOnly: true,
+ notify: true,
+ observer: '_sheetChanged'
+ },
+
+ /**
+ * Meta data about the particular tab that was retrieved for the spreadsheet.
+ */
+ tab: {
+ type: Object,
+ value: function() { return {}; },
+ readOnly: true,
+ notify: true,
+ observer: '_tabChanged'
+ },
+
+ /**
+ * If a spreadsheet `key` is specified, returns a list of cell row data.
+ */
+ rows: {
+ type: Array,
+ value: function() { return []; },
+ readOnly: true,
+ notify: true
+ },
+
+ /**
+ * List of the user's spreadsheets. Shared across instances.
+ */
+ spreadsheets: {
+ type: Array,
+ readOnly: true,
+ value: function() { return []; }
+ },
+
+ /**
+ * The URL to open this spreadsheet in Google Sheets.
+ */
+ openInGoogleDocsUrl: {
+ type: String,
+ computed: '_computeGoogleDocsUrl(key)',
+ notify: true
+ }
+ },
+
+ _computeGoogleDocsUrl: function(key) {
+ var url = 'https://docs.google.com/spreadsheet/';
+ if (key) {
+ url += 'ccc?key=' + key;
+ }
+ return url;
+ },
+
+ _configUpdate: function(key, published, tabId, clientId) {
+ this._tabIdChanged();
+ },
+
+ _keyChanged: function(newValue, oldValue) {
+ // TODO(ericbidelman): need to better handle updates to the key attribute.
+ // Below doesn't account for private feeds.
+ if (this.published) {
+ var url = SCOPE_ + '/list/' + this.key + '/' +
+ this.tabId + '/public/values';
+ this.$.publicajax.url = url;
+ this.$.publicajax.generateRequest();
+ }
+ },
+
+ _tabIdChanged: function(newValue, oldValue) {
+ if (this.worksheetId_) {
+ this._getCellRows();
+ } else if (this.published) {
+ this._keyChanged();
+ }
+ },
+
+ _sheetChanged: function(newValue, oldValue) {
+ if (!this.sheet.title) {
+ return;
+ }
+
+ // Make metadata easily accessible on sheet object.
+ var authors = this.sheet.author && this.sheet.author.map(function(a) {
+ return {email: a.email.$t, name: a.name.$t};
+ });
+
+ this.set('sheet.title', this.sheet.title.$t);
+ this.set('sheet.updated', new Date(this.sheet.updated.$t));
+ this.set('sheet.authors', authors);
+
+ //this.worksheetId_ = this.sheet.id.$t.split('/').slice(-1)[0];
+ this._setWorksheetId_(this.sheet.id.$t.split('/').slice(-1)[0]);
+ this._getWorksheet();
+ },
+
+ _tabChanged: function(newValue, oldValue) {
+ if (!this.tab.title) {
+ return;
+ }
+
+ var authors = this.tab.authors = this.tab.author && this.tab.author.map(function(a) {
+ return {email: a.email.$t, name: a.name.$t};
+ });
+
+ this.set('tab.title', this.tab.title.$t);
+ this.set('tab.updated', new Date(this.tab.updated.$t));
+ this.set('tab.authors', authors);
+
+ this.fire('google-sheet-data', {
+ type: 'tab',
+ data: this.tab
+ });
+ },
+
+ _onSignInSuccess: function(e, detail) {
+ var oauthToken = gapi.auth.getToken();
+
+ var headers = {
+ 'Authorization': 'Bearer ' + oauthToken.access_token
+ };
+
+ this.$.listsheetsajax.headers = headers;
+ this.$.worksheetajax.headers = headers;
+ this.$.cellrowsajax.headers = headers;
+
+ // TODO(ericbidelman): don't make this call if this.spreadsheets is
+ // already populated from another instance.
+ this._listSpreadsheets();
+ },
+
+ _onSignInFail: function(e, detail) {
+ // TODO(ericbidelman): handle this in some way.
+ console.log(e, e.type);
+ },
+
+ _listSpreadsheets: function() {
+ var url = SCOPE_ + '/spreadsheets/private/full';
+ this.$.listsheetsajax.url = url;
+ this.$.listsheetsajax.generateRequest();
+ },
+
+ _onSpreadsheetList: function(e) {
+ e.stopPropagation();
+
+ var feed = e.target.lastResponse.feed;
+
+ this.spreadsheets = feed.entry;
+
+ this.fire('google-sheet-data', {
+ type: 'spreadsheets',
+ data: this.spreadsheets
+ });
+
+ // Fetch worksheet feed if key was given and worksheet exists.
+ if (this.key) {
+ for (var i = 0, entry; entry = feed.entry[i]; ++i) {
+ var altLink = getLink_('alternate', entry.link);
+ if (altLink && altLink.href.indexOf(this.key) != -1) {
+ this.sheet = entry;
+ break;
+ }
+ }
+ }
+ },
+
+ _getWorksheet: function() {
+ if (!this.worksheetId_) {
+ throw new Error('workesheetId was not given.');
+ }
+
+ var url = SCOPE_ + '/worksheets/' + this.worksheetId_ +
+ '/private/full/' + this.tabId;
+ this.$.worksheetajax.url = url;
+ this.$.worksheetajax.generateRequest();
+ },
+
+ _onWorksheet: function(e) {
+ e.stopPropagation();
+
+ // this.tab = e.target.lastResponse.entry;
+ this._setTab(e.target.lastResponse.entry);
+ this._getCellRows();
+ },
+
+ _getCellRows: function() {
+ // Use cached data if available.
+ var key = generateCacheKey_.call(this);
+ if (key in rowDataCache_) {
+ this._onCellRows(null, null, rowDataCache_[key]);
+
+ return;
+ }
+
+ var url = SCOPE_ + '/list/' +
+ this.worksheetId_ + '/' + this.tabId +
+ '/private/full';
+ this.$.cellrowsajax.url = url;
+ this.$.cellrowsajax.generateRequest();
+ },
+
+ _onCellRows: function(e) {
+ e.stopPropagation();
+
+ var feed = e.target.lastResponse.feed;
+
+ // Cache data if key doesn't exist.
+ var key = generateCacheKey_.call(this);
+ if (!(key in rowDataCache_)) {
+ rowDataCache_[key] = {response: {feed: feed}};
+ }
+
+ // this.rows = feed.entry;
+ this._setRows(feed.entry);
+ var authors = feed.author && feed.author.map(function(a) {
+ return {email: a.email.$t, name: a.name.$t};
+ });
+ this.set('rows.authors', authors);
+
+ if (this.published) {
+ // this.tab = feed;
+ this._setTab(feed);
+ }
+
+ this.fire('google-sheet-data', {
+ type: 'rows',
+ data: this.rows
+ });
+ }
+
+ });
+
+})();
+</script>
diff --git a/polymer_1.0.4/bower_components/google-sheets/index.html b/polymer_1.0.4/bower_components/google-sheets/index.html
new file mode 100755
index 0000000..203f4fa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-sheets/index.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-sheets/tests/google-sheet.html b/polymer_1.0.4/bower_components/google-sheets/tests/google-sheet.html
new file mode 100644
index 0000000..89d5895
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-sheets/tests/google-sheet.html
@@ -0,0 +1,46 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>google-sheet tests</title>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <script src="../../../platform/platform.js"></script>
+ <link rel="import" href="../../../polymer-test-tools/tools.html">
+ <script src="../../../polymer-test-tools/htmltest.js"></script>
+
+ <link rel="import" href="../google-sheets.html">
+</head>
+<body>
+
+<google-sheets id="sheet1"></google-sheets>
+
+<script>
+document.addEventListener('polymer-ready', function() {
+
+ (function() {
+ var sheet = document.querySelector('#sheet1');
+ var root = sheet.shadowRoot;
+
+ // Check defaults.
+ assert.lengthOf(sheet.spreadsheets, 0,
+ '.spreadsheets length should default to 0');
+ assert.lengthOf(sheet.rows, 0, '.rows length should default to 0');
+ assert.isObject(sheet.sheet, '.sheet should default to {}');
+ assert.isObject(sheet.tab, '.tab should default to {}');
+
+ assert.equal(sheet.key, '', ".key default is not ''");
+ assert.equal(sheet.gid, 0, '.gid default is not 0');
+ assert.isFalse(sheet.published, '.published does not default to false');
+ assert.isNotNull(root.querySelector('google-signin-aware'),
+ 'google-signin-aware should be created for non-public sheet');
+
+ done();
+
+ })();
+
+});
+</script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-sheets/tests/index.html b/polymer_1.0.4/bower_components/google-sheets/tests/index.html
new file mode 100644
index 0000000..2c08fd3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-sheets/tests/index.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Runs all tests</title>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <script src="../../platform/platform.js"></script>
+ <link rel="import" href="tests.html">
+ </head>
+ <body>
+ <div id="mocha"></div>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-sheets/tests/private.html b/polymer_1.0.4/bower_components/google-sheets/tests/private.html
new file mode 100644
index 0000000..c90c6f2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-sheets/tests/private.html
@@ -0,0 +1,81 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>google-sheet tests</title>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <script src="../../../platform/platform.js"></script>
+ <link rel="import" href="../../../polymer-test-tools/tools.html">
+ <script src="../../../polymer-test-tools/htmltest.js"></script>
+
+ <link rel="import" href="../google-sheets.html">
+</head>
+<body>
+
+<div>
+ <p>Tests live private spreadsheet data.</p>
+ <p>This test needs to be run manually, standalone in order to fetch an OAuth token.</p>
+
+ <b>NOTES:</b><br>
+ <li>run manually off of localhost:3000/google-sheets/tests/private.html. Can also run from port 8080.</li>
+ <li>use the account: webcomponents.test@gmail.com</li>
+</div>
+
+<google-sheets id="sheet" gid="1"
+ clientId="750497606405-1hq66meqmr4dp09dn54j9ggv85vbv0gp.apps.googleusercontent.com"
+ key="0AjqzxJ5RoRrWdGh2S0RRYURXTlNHdm9pQlFuM1ZwZWc"></google-sheets>
+
+<script>
+document.addEventListener('polymer-ready', function() {
+
+ (function() {
+ var sheet = document.querySelector('#sheet');
+ var root = sheet.shadowRoot;
+
+ // Test set attributes.
+ assert.equal(sheet.key,
+ '0AjqzxJ5RoRrWdGh2S0RRYURXTlNHdm9pQlFuM1ZwZWc', ".key was not updated");
+ assert.equal(sheet.gid, 1, '.gid was not updated');
+ assert.equal(sheet.clientId,
+ '750497606405-1hq66meqmr4dp09dn54j9ggv85vbv0gp.apps.googleusercontent.com', ".clientId was not set");
+
+ sheet.addEventListener('google-sheet-data', function(e) {
+
+ switch (e.detail.type) {
+ case 'spreadsheets':
+ assert.isTrue(this.spreadsheets.length > 0,
+ '.spreadsheets should be populated for private feeds.');
+ break;
+ case 'tab':
+ assert.equal(this.tab.title, 'SECONDTAB', '.tab.title is incorrect');
+ break;
+ case 'rows':
+ assert.lengthOf(this.rows.authors, 1, '.rows.authors array');
+
+ var name = this.rows.authors[0].name;
+ var email = this.rows.authors[0].email
+
+ assert.equal(email, 'webcomponents.test@gmail.com', 'author email not set correctly');
+ assert.equal(name, 'webcomponents.test', 'author name not set correctly');
+
+ assert.equal(this.rows[0].title.$t, 'FIRST NAME', '"name" column was incorrect');
+ assert.equal(this.rows[1].gsx$state.$t, 'OR', '"state" column was incorrect');
+
+ break;
+ default:
+ // Noop
+ }
+
+ done();
+
+ });
+
+ })();
+
+});
+</script>
+</body>
+</html>
+
diff --git a/polymer_1.0.4/bower_components/google-sheets/tests/published.html b/polymer_1.0.4/bower_components/google-sheets/tests/published.html
new file mode 100644
index 0000000..d7ff3f8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-sheets/tests/published.html
@@ -0,0 +1,51 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>google-sheet tests</title>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <script src="../../../platform/platform.js"></script>
+ <link rel="import" href="../../../polymer-test-tools/tools.html">
+ <script src="../../../polymer-test-tools/htmltest.js"></script>
+
+ <link rel="import" href="../google-sheets.html">
+</head>
+<body>
+
+<google-sheets id="sheet" key="0Anye-JMjUkZZdDBkMVluMEhZMmFGeHpYdDJJV1FBRWc"
+ published></google-sheets>
+
+<script>
+document.addEventListener('polymer-ready', function() {
+
+ var sheet = document.querySelector('#sheet');
+ var root = sheet.shadowRoot;
+
+ assert.isTrue(sheet.published);
+ assert.isNull(root.querySelector('google-signin-aware'),
+ 'google-signin-aware should not be created for a published sheet');
+
+ sheet.addEventListener('google-sheet-data', function(e) {
+
+ if (e.detail.type === 'tab') {
+ assert.equal(this.tab.title, 'Locations',
+ 'Published spreadsheet title is not correct.');
+ assert.isNotNull(this.tab.updated, '.tab.updated was not set');
+ assert.isTrue(this.tab.authors.length > 0, '.tab.authors was 0');
+ } else if (e.detail.type === 'rows') {
+ assert.lengthOf(this.spreadsheets, 0,
+ '.spreadsheets length should be 0 since spreadsheet key was given');
+ assert.isTrue(this.rows.length > 0, '.rows was not populated');
+ }
+
+ assert.equal(this.$.cellrowsajax.url, '',
+ '#cellrowsajax should not be invoked for a public spreadsheet');
+
+ done();
+ });
+});
+</script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-sheets/tests/tests.html b/polymer_1.0.4/bower_components/google-sheets/tests/tests.html
new file mode 100644
index 0000000..ca0055f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-sheets/tests/tests.html
@@ -0,0 +1,16 @@
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+
+<link rel="import" href="../../polymer-test-tools/tools.html">
+<script src="../../polymer-test-tools/mocha-htmltest.js"></script>
+
+<script>
+mocha.setup({ui: 'tdd', slow: 1000, timeout: 5000, htmlbase: ''});
+
+htmlSuite('google-sheet', function() {
+ htmlTest('google-sheet.html');
+ htmlTest('published.html');
+ htmlTest('private.html');
+});
+
+mocha.run();
+</script>
diff --git a/polymer_1.0.4/bower_components/google-signin/.bower.json b/polymer_1.0.4/bower_components/google-signin/.bower.json
new file mode 100644
index 0000000..d25ad69
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-signin/.bower.json
@@ -0,0 +1,46 @@
+{
+ "name": "google-signin",
+ "version": "1.0.2",
+ "description": "Web components to authenticate with Google services",
+ "homepage": "https://googlewebcomponents.github.io/google-signin",
+ "main": "google-signin.html",
+ "authors": [
+ "Addy Osmani",
+ "Randy Merrill"
+ ],
+ "license": "Apache-2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "sign-in",
+ "google",
+ "authentication"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "font-roboto": "PolymerElements/font-roboto#master",
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+ "paper-material": "PolymerElements/paper-material#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "2a5a20adf4b6f16afaf44812d20b34236154b6a6"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-signin.git",
+ "_target": "^1.0.0",
+ "_originalSource": "GoogleWebComponents/google-signin"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-signin/LICENSE b/polymer_1.0.4/bower_components/google-signin/LICENSE
new file mode 100644
index 0000000..52aea39
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-signin/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2014 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/polymer_1.0.4/bower_components/google-signin/README.md b/polymer_1.0.4/bower_components/google-signin/README.md
new file mode 100644
index 0000000..7c05417
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-signin/README.md
@@ -0,0 +1,4 @@
+google-signin
+================
+
+See the [component page](https://googlewebcomponents.github.io/google-signin) for more information.
diff --git a/polymer_1.0.4/bower_components/google-signin/bower.json b/polymer_1.0.4/bower_components/google-signin/bower.json
new file mode 100644
index 0000000..59610d4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-signin/bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "google-signin",
+ "version": "1.0.2",
+ "description": "Web components to authenticate with Google services",
+ "homepage": "https://googlewebcomponents.github.io/google-signin",
+ "main": "google-signin.html",
+ "authors": [
+ "Addy Osmani",
+ "Randy Merrill"
+ ],
+ "license": "Apache-2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "sign-in",
+ "google",
+ "authentication"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "font-roboto": "PolymerElements/font-roboto#master",
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+ "paper-material": "PolymerElements/paper-material#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-signin/demo/index.html b/polymer_1.0.4/bower_components/google-signin/demo/index.html
new file mode 100644
index 0000000..ee54ac2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-signin/demo/index.html
@@ -0,0 +1,142 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>google-signin Demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../google-signin.html">
+ <link rel="import" href="../google-signin-aware.html">
+
+ <!-- Demo only styles -->
+ <style>
+ body {
+ font-family: 'RobotoDraft', 'Roboto', sans-serif;
+ line-height:1.2;
+ vertical-align:middle;
+ background: rgba(204, 204, 204, 0.31);
+ }
+
+
+ .map {
+ background: whitesmoke;
+ margin: .5rem -1.5rem 0 -1.5rem;
+ padding: 0.5rem;
+ }
+
+ h1 {
+ font-size: 2rem;
+ font-weight:200;
+ clear: both;
+ }
+
+ h1 strong {
+ font-weight:300;
+ color:#539D00;
+ }
+
+ h2 {
+ font-size:.9rem;
+ line-height:2.5;
+ color:gray;
+ font-weight:400;
+ clear: both;
+ }
+
+ .showcase {
+ display: inline-block;
+ margin-right: 2rem;
+ float: left;
+ }
+ </style>
+
+</head>
+
+<body>
+ <p>A <code><google-signin></code> element looks like this button:</p>
+
+ <p><google-signin brand="google" client-id="1054047045356-j8pgqgls9vdef3rl09hapoicumbte0bo.apps.googleusercontent.com"></google-signin>
+or like this if plus scopes are present
+ <google-signin brand="google-plus"></google-signin>
+ </p>
+ <p>Signin button can vary its appearance:</p>
+ <p>Width:
+ <google-signin brand="google" width="wide"></google-signin>
+ <google-signin brand="google" width="iconOnly"></google-signin>
+ Height:
+ <google-signin brand="google" height="tall"></google-signin>
+ <google-signin brand="google" height="standard"></google-signin>
+ <google-signin brand="google" height="short"></google-signin>
+ </p>
+ <p>
+ Theme:
+ <google-signin brand="google" theme="dark"></google-signin>
+ <google-signin brand="google" theme="light"></google-signin>
+ <google-signin brand="google-plus" theme="light"></google-signin>
+ <google-signin brand="google-plus" theme="light" raised></google-signin>
+ </p>
+ <!-- Demo the ability to use the google-signin-aware element. -->
+ <p><code><google-signin-aware></code> is a companion element.</p>
+ <p>You can use it inside your components to request additional scopes.</p>
+ <p>Every signin button will request all the scopes present in the document,
+ and change its appearance to match</p>
+ <p>For example, here is a signin-aware scope. You can change its scopes via popup</p>
+ <template id="awareness" is="dom-bind">
+ <div><code><google-signin-aware
+ <div>scope=
+ <select value="{{scope::change}}">
+ <option value="">None</option>
+ <option value="https://www.googleapis.com/auth/analytics">Google Analytics</option>
+ <option value="https://www.googleapis.com/auth/plus.login">Google Plus view circles</option>
+ <option value="https://www.googleapis.com/auth/youtube">YouTube</option>
+ <option value="https://www.googleapis.com/auth/calendar">Calendar</option>
+ <option value="profile">Profile info</option>
+ </select>
+ </div>
+ <div>signedIn="<span>{{signedIn}}</span>"</div>
+ <div>isAuthorized="<span>{{isAuthorized}}</span>"</div>
+ <div>needAdditionalAuth:"<span>{{needAdditionalAuth}}</span>"></div>
+ </code></div>
+ <p>Every new scope you select will be added to requested scopes.</p>
+ <p>When you select a Google Plus scope, button will turn red.</p>
+ <google-signin></google-signin>
+ </p>
+ <google-signin-aware
+ scopes="{{scope}}"
+ signed-in="{{signedIn}}"
+ is-authorized="{{isAuthorized}}"
+ need-additional-auth="{{needAdditionalAuth}}"
+ on-google-signin-aware-success="handleSignIn"
+ on-google-signin-aware-signed-out="handleSignOut"></google-signin-aware>
+ <p>User name:<span>{{userName}}</span></p>
+ <p>Testing <code>google-signin-aware</code> events: <span>{{status}}</span></p>
+ <p><button on-click="disconnect">Disconnect to start over</button></p>
+ </template>
+ <script>
+ var aware = document.querySelector('#awareness');
+ aware.status = 'Not granted';
+ aware.userName = 'N/A';
+ aware.handleSignIn = function(response) {
+ this.status = 'Signin granted';
+ // console.log('[Aware] Signin Response', response);
+ this.userName = gapi.auth2.getAuthInstance().currentUser.get().getBasicProfile().getName();
+ };
+ aware.handleSignOut = function(response) {
+ this.status = 'Signed out';
+ // console.log('[Aware] Signout Response', response);
+ this.userName = 'N/A';
+ };
+ aware.disconnect = function() {
+ var b = document.querySelector('google-signin');
+ var currentUser = gapi.auth2.getAuthInstance().currentUser.get();
+ if (currentUser) {
+ currentUser.disconnect();
+ }
+ gapi.auth2.getAuthInstance().signOut();
+ };
+
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-signin/google-icons.html b/polymer_1.0.4/bower_components/google-signin/google-icons.html
new file mode 100644
index 0000000..a9a463c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-signin/google-icons.html
@@ -0,0 +1,17 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at https://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at https://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at https://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at https://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-iconset-svg/iron-iconset-svg.html">
+<iron-iconset-svg name="google" iconSize="24">
+<svg><defs>
+<g id="google"><path d="M16.3,13.4l-1.1-0.8c-0.4-0.3-0.8-0.7-0.8-1.4c0-0.7,0.5-1.3,1-1.6c1.3-1,2.6-2.1,2.6-4.3c0-2.1-1.3-3.3-2-3.9h1.7L18.9,0h-6.2C8.3,0,6.1,2.8,6.1,5.8c0,2.3,1.8,4.8,5,4.8h0.8c-0.1,0.3-0.4,0.8-0.4,1.3c0,1,0.4,1.4,0.9,2c-1.4,0.1-4,0.4-5.9,1.6c-1.8,1.1-2.3,2.6-2.3,3.7c0,2.3,2.1,4.5,6.6,4.5c5.4,0,8-3,8-5.9C18.8,15.7,17.7,14.6,16.3,13.4z M8.7,4.3c0-2.2,1.3-3.2,2.7-3.2c2.6,0,4,3.5,4,5.5c0,2.6-2.1,3.1-2.9,3.1C10,9.7,8.7,6.6,8.7,4.3z M12.3,22.3c-3.3,0-5.4-1.5-5.4-3.7c0-2.2,2-2.9,2.6-3.2c1.3-0.4,3-0.5,3.3-0.5c0.3,0,0.5,0,0.7,0c2.4,1.7,3.4,2.4,3.4,4C16.9,20.8,15,22.3,12.3,22.3z"/></g>
+<g id="google-plus"><path d="M21,10V7h-2v3h-3v2h3v3h2v-3h3v-2H21z M13.3,13.4l-1.1-0.8c-0.4-0.3-0.8-0.7-0.8-1.4c0-0.7,0.5-1.3,1-1.6c1.3-1,2.6-2.1,2.6-4.3c0-2.1-1.3-3.3-2-3.9h1.7L15.9,0H9.7C5.3,0,3.1,2.8,3.1,5.8c0,2.3,1.8,4.8,5,4.8h0.8c-0.1,0.3-0.4,0.8-0.4,1.3c0,1,0.4,1.4,0.9,2c-1.4,0.1-4,0.4-5.9,1.6c-1.8,1.1-2.3,2.6-2.3,3.7c0,2.3,2.1,4.5,6.6,4.5c5.4,0,8-3,8-5.9C15.8,15.7,14.7,14.6,13.3,13.4z M5.7,4.3c0-2.2,1.3-3.2,2.7-3.2c2.6,0,4,3.5,4,5.5c0,2.6-2.1,3.1-2.9,3.1C7,9.7,5.7,6.6,5.7,4.3z M9.3,22.3c-3.3,0-5.4-1.5-5.4-3.7c0-2.2,2-2.9,2.6-3.2c1.3-0.4,3-0.5,3.3-0.5c0.3,0,0.5,0,0.7,0c2.4,1.7,3.4,2.4,3.4,4C13.9,20.8,12,22.3,9.3,22.3z"/></g>
+</defs></svg>
+</iron-iconset-svg>
diff --git a/polymer_1.0.4/bower_components/google-signin/google-signin-aware.html b/polymer_1.0.4/bower_components/google-signin/google-signin-aware.html
new file mode 100644
index 0000000..ab8e045
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-signin/google-signin-aware.html
@@ -0,0 +1,539 @@
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../google-apis/google-js-api.html">
+
+<script>
+ (function() {
+
+ /**
+ * Enum of attributes to be passed through to the login API call.
+ * @readonly
+ * @enum {string}
+ */
+ var ProxyLoginAttributes = {
+ 'appPackageName': 'apppackagename',
+ 'clientId': 'clientid',
+ 'cookiePolicy': 'cookiepolicy',
+ 'requestVisibleActions': 'requestvisibleactions'
+ };
+
+ /**
+ * AuthEngine does all interactions with gapi.auth2
+ *
+ * It is tightly coupled with <google-signin-aware> element
+ * The elements configure AuthEngine.
+ * AuthEngine propagates all authentication events to all google-signin-aware elements
+ *
+ * API used: https://developers.google.com/identity/sign-in/web/reference
+ *
+ */
+ var AuthEngine = {
+
+ /**
+ * oauth2 argument, set by google-signin-aware
+ */
+ _clientId: null,
+
+ get clientId() {
+ return this._clientId;
+ },
+
+ set clientId(val) {
+ if (this._clientId && val && val != this._clientId) {
+ throw new Error('clientId cannot change. Values do not match. New: ' + val + ' Old:' + this._clientId);
+ }
+ if (val) {
+ this._clientId = val;
+ this.initAuth2();
+ }
+ },
+
+ /**
+ * oauth2 argument, set by google-signin-aware
+ */
+ _cookiePolicy: 'single_host_origin',
+
+ get cookiePolicy() {
+ return this._cookiePolicy;
+ },
+
+ set cookiePolicy(val) {
+ if (val) {
+ this._cookiePolicy = val;
+ }
+ },
+
+ /**
+ * oauth2 argument, set by google-signin-aware
+ */
+ _appPackageName: '',
+
+ get appPackageName() {
+ return this._appPackageName;
+ },
+
+ set appPackageName(val) {
+ if (this._appPackageName && val && val != this._appPackageName) {
+ throw new Error('appPackageName cannot change. Values do not match. New: ' + val + ' Old: ' + this._appPackageName);
+ }
+ if (val) {
+ this._appPackageName = val;
+ }
+ },
+
+ /**
+ * oauth2 argument, set by google-signin-aware
+ */
+ _requestVisibleActions: '',
+
+ get requestVisibleactions() {
+ return this._requestVisibleActions;
+ },
+
+ set requestVisibleactions(val) {
+ if (this._requestVisibleActions && val && val != this._requestVisibleActions) {
+ throw new Error('requestVisibleactions cannot change. Values do not match. New: ' + val + ' Old: ' + this._requestVisibleActions);
+ }
+ if (val)
+ this._requestVisibleActions = val;
+ },
+
+ /** <google-js-api> */
+ _apiLoader: null,
+
+ /** an array of wanted scopes. oauth2 argument */
+ _requestedScopeArray: [],
+
+ /** _requestedScopeArray as string */
+ get requestedScopes() {
+ return this._requestedScopeArray.join(' ');
+ },
+
+ /** Is user signed in? */
+ _signedIn: false,
+
+ /** Currently granted scopes */
+ _grantedScopeArray: [],
+
+ /** True if additional authorization is required */
+ _needAdditionalAuth: true,
+
+ /** True if have google+ scopes */
+ _hasPlusScopes: false,
+
+ /**
+ * array of <google-signin-aware>
+ * state changes are broadcast to them
+ */
+ signinAwares: [],
+
+ init: function() {
+ this._apiLoader = document.createElement('google-js-api');
+ this._apiLoader.addEventListener('js-api-load', this.loadAuth2.bind(this));
+ },
+
+ loadAuth2: function() {
+ gapi.load('auth2', this.initAuth2.bind(this));
+ },
+
+ initAuth2: function() {
+ if (!('gapi' in window) || !('auth2' in window.gapi) || !this.clientId) {
+ return;
+ }
+ var auth = gapi.auth2.init({
+ 'client_id': this.clientId,
+ 'cookie_policy': this.cookiePolicy,
+ 'scope': this.requestedScopes
+ });
+
+ auth.currentUser.listen(this.handleUserUpdate.bind(this));
+
+ auth.then(
+ function success() {
+ // Let the current user listener trigger the changes.
+ },
+ function error(error) {
+ console.error(error);
+ }
+ );
+ },
+
+ handleUserUpdate: function(newPrimaryUser) {
+ // update and broadcast currentUser
+ var isSignedIn = newPrimaryUser.isSignedIn();
+ if (isSignedIn != this._signedIn) {
+ this._signedIn = isSignedIn;
+ for (var i=0; i<this.signinAwares.length; i++) {
+ this.signinAwares[i]._setSignedIn(isSignedIn);
+ }
+ }
+
+ // update granted scopes
+ this._grantedScopeArray = this.strToScopeArray(
+ newPrimaryUser.getGrantedScopes());
+ // console.log(this._grantedScopeArray);
+ this.updateAdditionalAuth();
+
+ var response = newPrimaryUser.getAuthResponse();
+ for (var i=0; i<this.signinAwares.length; i++) {
+ this.signinAwares[i]._updateScopeStatus(response);
+ }
+ },
+
+ /** convert scope string to scope array */
+ strToScopeArray: function(str) {
+ if (!str) {
+ return [];
+ }
+ // remove extra spaces, then split
+ var scopes = str.replace(/\ +/g, ' ').trim().split(' ');
+ for (var i=0; i<scopes.length; i++) {
+ scopes[i] = scopes[i].toLowerCase();
+ // Handle scopes that will be deprecated but are still returned with their old value
+ if (scopes[i] === 'https://www.googleapis.com/auth/userinfo.profile') {
+ scopes[i] = 'profile';
+ }
+ if (scopes[i] === 'https://www.googleapis.com/auth/userinfo.email') {
+ scopes[i] = 'email';
+ }
+ }
+ // return with duplicates filtered out
+ return scopes.filter( function(value, index, self) {
+ return self.indexOf(value) === index;
+ });
+ },
+
+ /** true if scopes have google+ scopes */
+ isPlusScope: function(scope) {
+ return (scope.indexOf('/auth/games') > -1)
+ || (scope.indexOf('auth/plus.') > -1 && scope.indexOf('auth/plus.me') < 0);
+ },
+
+ /** true if scopes have been granted */
+ hasGrantedScopes: function(scopeStr) {
+ var scopes = this.strToScopeArray(scopeStr);
+ for (var i=0; i< scopes.length; i++) {
+ if (this._grantedScopeArray.indexOf(scopes[i]) === -1)
+ return false;
+ }
+ return true;
+ },
+
+ /** request additional scopes */
+ requestScopes: function(newScopeStr) {
+ var newScopes = this.strToScopeArray(newScopeStr);
+ var scopesUpdated = false;
+ for (var i=0; i<newScopes.length; i++) {
+ if (this._requestedScopeArray.indexOf(newScopes[i]) === -1) {
+ this._requestedScopeArray.push(newScopes[i]);
+ scopesUpdated = true;
+ }
+ }
+ if (scopesUpdated) {
+ this.updateAdditionalAuth();
+ this.updatePlusScopes();
+ }
+ },
+
+ /** update status of _needAdditionalAuth */
+ updateAdditionalAuth: function() {
+ var needMoreAuth = false;
+ for (var i=0; i<this._requestedScopeArray.length; i++) {
+ if (this._grantedScopeArray.indexOf(this._requestedScopeArray[i]) === -1) {
+ needMoreAuth = true;
+ break;
+ }
+ }
+ if (this._needAdditionalAuth != needMoreAuth) {
+ this._needAdditionalAuth = needMoreAuth;
+ // broadcast new value
+ for (var i=0; i<this.signinAwares.length; i++) {
+ this.signinAwares[i]._setNeedAdditionalAuth(needMoreAuth);
+ }
+ }
+ },
+
+ updatePlusScopes: function() {
+ var hasPlusScopes = false;
+ for (var i = 0; i < this._requestedScopeArray.length; i++) {
+ if (this.isPlusScope(this._requestedScopeArray[i])) {
+ hasPlusScopes = true;
+ break;
+ }
+ }
+ if (this._hasPlusScopes != hasPlusScopes) {
+ this._hasPlusScopes = hasPlusScopes;
+ for (var i=0; i<this.signinAwares.length; i++) {
+ this.signinAwares[i]._setHasPlusScopes(hasPlusScopes);
+ }
+ }
+ },
+ /**
+ * attached <google-signin-aware>
+ * @param {<google-signin-aware>} aware element to add
+ */
+ attachSigninAware: function(aware) {
+ if (this.signinAwares.indexOf(aware) == -1) {
+ this.signinAwares.push(aware);
+ // Initialize aware properties
+ aware._setNeedAdditionalAuth(this._needAdditionalAuth);
+ aware._setSignedIn(this._signedIn);
+ aware._setHasPlusScopes(this._hasPlusScopes);
+ } else {
+ console.warn('signinAware attached more than once', aware);
+ }
+ },
+
+ detachSigninAware: function(aware) {
+ var index = this.signinAwares.indexOf(aware);
+ if (index != -1) {
+ this.signinAwares.splice(index, 1);
+ } else {
+ console.warn('Trying to detach unattached signin-aware');
+ }
+ },
+
+ /** returns scopes not granted */
+ getMissingScopes: function() {
+ return this._requestedScopeArray.filter( function(scope) {
+ return this._grantedScopeArray.indexOf(scope) === -1;
+ }.bind(this)).join(' ');
+ },
+
+ assertAuthInitialized: function() {
+ if (!this.clientId) {
+ throw new Error("AuthEngine not initialized. clientId has not been configured.");
+ }
+ if (!('gapi' in window)) {
+ throw new Error("AuthEngine not initialized. gapi has not loaded.");
+ }
+ if (!('auth2' in window.gapi)) {
+ throw new Error("AuthEngine not initialized. auth2 not loaded.");
+ }
+ },
+
+ /** pops up sign-in dialog */
+ signIn: function() {
+ this.assertAuthInitialized();
+ var params = {
+ 'scope': this.getMissingScopes()
+ };
+
+ // Proxy specific attributes through to the signIn options.
+ Object.keys(ProxyLoginAttributes).forEach(function(key) {
+ if (this[key] && this[key] !== '') {
+ params[ProxyLoginAttributes[key]] = this[key];
+ }
+ }, this);
+
+ var promise;
+ var user = gapi.auth2.getAuthInstance().currentUser.get();
+ if (user.getGrantedScopes()) {
+ // additional auth, skip multiple account dialog
+ promise = user.grant(params);
+ } else {
+ // initial signin
+ promise = gapi.auth2.getAuthInstance().signIn(params);
+ }
+ promise.then(
+ function success(newUser) {
+ var authResponse = newUser.getAuthResponse();
+ // Let the current user listener trigger the changes.
+ },
+ function error(error) {
+ if ("Access denied." == error.reason) {
+ // Access denied is not an error, user hit cancel
+ return;
+ } else {
+ console.error(error);
+ }
+ }
+ );
+ },
+
+ /** signs user out */
+ signOut: function() {
+ this.assertAuthInitialized();
+ gapi.auth2.getAuthInstance().signOut().then(
+ function success() {
+ // Let the current user listener trigger the changes.
+ },
+ function error(error) {
+ console.error(error);
+ }
+ );
+ }
+ };
+
+ AuthEngine.init();
+
+/**
+`google-signin-aware` is used to enable authentication in custom elements by
+interacting with a google-signin element that needs to be present somewhere
+on the page.
+
+The `scopes` attribute allows you to specify which scope permissions are required
+(e.g do you want to allow interaction with the Google Drive API).
+
+The `google-signin-aware-success` event is triggered when a user successfully
+authenticates. The `google-signin-aware-signed-out` event is triggered
+when a user explicitely signs out via the google-signin element.
+
+You can bind to `isAuthorized` property to monitor authorization state.
+##### Example
+
+ <google-signin-aware scopes="https://www.googleapis.com/auth/drive"></google-signin-aware>
+*/
+ Polymer({
+
+ is: 'google-signin-aware',
+
+ /**
+ * Fired when this scope has been authorized
+ * @param {Object} result Authorization result.
+ * @event google-signin-aware-success
+ */
+ /**
+ * Fired when this scope is not authorized
+ * @event google-signin-aware-signed-out
+ */
+ properties: {
+ /**
+ * App package name for android over-the-air installs.
+ * See the relevant [docs](https://developers.google.com/+/web/signin/android-app-installs)
+ */
+ appPackageName: {
+ type: String,
+ observer: '_appPackageNameChanged'
+ },
+ /**
+ * a Google Developers clientId reference
+ */
+ clientId: {
+ type: String,
+ observer: '_clientIdChanged'
+ },
+
+ /**
+ * The cookie policy defines what URIs have access to the session cookie
+ * remembering the user's sign-in state.
+ * See the relevant [docs](https://developers.google.com/+/web/signin/reference#determining_a_value_for_cookie_policy) for more information.
+ * @default 'single_host_origin'
+ */
+ cookiePolicy: {
+ type: String,
+ observer: '_cookiePolicyChanged'
+ },
+
+ /**
+ * The app activity types you want to write on behalf of the user
+ * (e.g http://schemas.google.com/AddActivity)
+ *
+ */
+ requestVisibleActions: {
+ type: String,
+ observer: '_requestVisibleActionsChanged'
+ },
+
+ /**
+ * The scopes to provide access to (e.g https://www.googleapis.com/auth/drive)
+ * and should be space-delimited.
+ */
+ scopes: {
+ type: String,
+ value: 'profile',
+ observer: '_scopesChanged'
+ },
+
+ /**
+ * True if user is signed in
+ */
+ signedIn: {
+ type: Boolean,
+ notify: true,
+ readOnly: true
+ },
+
+ /**
+ * True if authorizations for *this* element have been granted
+ */
+ isAuthorized: {
+ type: Boolean,
+ notify: true,
+ readOnly: true,
+ value: false
+ },
+
+ /**
+ * True if additional authorizations for *any* element are required
+ */
+ needAdditionalAuth: {
+ type: Boolean,
+ notify: true,
+ readOnly: true
+ },
+
+ /**
+ * True if *any* element has google+ scopes
+ */
+ hasPlusScopes: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ readOnly: true
+ }
+ },
+
+ attached: function() {
+ AuthEngine.attachSigninAware(this);
+ },
+
+ detached: function() {
+ AuthEngine.detachSigninAware(this);
+ },
+
+ /** pops up the authorization dialog */
+ signIn: function() {
+ AuthEngine.signIn();
+ },
+
+ /** signs user out */
+ signOut: function() {
+ AuthEngine.signOut();
+ },
+
+ _appPackageNameChanged: function(newName, oldName) {
+ AuthEngine.appPackageName = newName;
+ },
+
+ _clientIdChanged: function(newId, oldId) {
+ AuthEngine.clientId = newId;
+ },
+
+ _cookiePolicyChanged: function(newPolicy, oldPolicy) {
+ AuthEngine.cookiePolicy = newPolicy;
+ },
+
+ _requestVisibleActionsChanged: function(newVal, oldVal) {
+ AuthEngine.requestVisibleActions = newVal;
+ },
+
+ _scopesChanged: function(newVal, oldVal) {
+ AuthEngine.requestScopes(newVal);
+ this._updateScopeStatus();
+ },
+
+ _updateScopeStatus: function(user) {
+ var newAuthorized = this.signedIn && AuthEngine.hasGrantedScopes(this.scopes);
+ if (newAuthorized !== this.isAuthorized) {
+ this._setIsAuthorized(newAuthorized);
+ if (newAuthorized) {
+ this.fire('google-signin-aware-success', user);
+ }
+ else {
+ this.fire('google-signin-aware-signed-out', user);
+ }
+ }
+ }
+ });
+ })();
+</script>
diff --git a/polymer_1.0.4/bower_components/google-signin/google-signin.css b/polymer_1.0.4/bower_components/google-signin/google-signin.css
new file mode 100644
index 0000000..2b98356
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-signin/google-signin.css
@@ -0,0 +1,231 @@
+:host {
+ display: inline-block;
+ position: relative;
+ box-sizing: border-box;
+ margin: 0 0.29em;
+ background: transparent;
+ text-align: center;
+ font: inherit;
+ outline: none;
+ border-radius: 3px;
+ -webkit-user-select: none;
+ user-select: none;
+ cursor: pointer;
+ z-index: 0;
+}
+
+:host([disabled]) {
+ cursor: auto;
+ pointer-events: none;
+}
+
+:host([disabled]) #button {
+ background: #eaeaea;
+ color: #a8a8a8;
+}
+
+#button {
+ position: relative;
+ outline: none;
+ font-size: 14px;
+ font-weight: 400;
+ font-family: 'RobotoDraft','Roboto',arial,sans-serif;
+ white-space: nowrap;
+ border-radius: inherit;
+}
+
+iron-icon {
+ width: 22px;
+ height: 22px;
+ margin: 6px;
+}
+
+.icon {
+ display: inline-block;
+ vertical-align: middle;
+}
+
+#shadow {
+ border-radius: inherit;
+}
+
+#ripple {
+ pointer-events: none;
+}
+
+.button-content {
+ outline: none;
+}
+
+.buttonText {
+ display: inline-block;
+ vertical-align: middle;
+ padding-right: .8em;
+}
+
+/*
+ * Dark Theme
+ */
+.theme-dark {
+ background: #da4336;
+ color: #ffffff;
+ border: 1px solid transparent;
+}
+
+.theme-dark.signedIn-true.additionalAuth-false {
+ background: #999;
+ border: 1px solid #888;
+}
+
+.theme-dark.signedIn-true.additionalAuth-false:hover,
+.theme-dark.signedIn-true.additionalAuth-false:focus {
+ background: #aaa;
+}
+
+:host([noink]) .theme-dark:hover,
+:host([noink]) .theme-dark:focus {
+ background: #e74b37;
+}
+
+:host([noink]) .theme-dark.signedIn-true.additionalAuth-false:hover,
+:host([noink]) .theme-dark.signedIn-true.additionalAuth-false:focus {
+ background: #aaa;
+}
+
+/*
+ * Light Theme
+ */
+.theme-light {
+ background: #fff;
+ color: #737373;
+ border: 1px solid #d9d9d9;
+}
+
+.theme-light.signedIn-true.additionalAuth-false {
+ background: #c0c0c0;
+ color: #fff;
+ border: #888 1px solid;
+}
+
+.theme-light.signedIn-true.additionalAuth-false:hover,
+.theme-light.signedIn-true.additionalAuth-false:focus {
+ background: #aaa;
+}
+
+:host([noink]) .theme-light .button-content:hover,
+:host([noink]) .theme-light:focus {
+ border: 1px solid #c0c0c0;
+}
+
+:host([noink]) .theme-light.signedIn-true.additionalAuth-false:hover,
+:host([noink]) .theme-light.signedIn-true.additionalAuth-false:focus {
+ background: #aaa;
+}
+
+/*
+ * Icon Only Width
+ */
+.width-iconOnly .buttonText {
+ display: none;
+}
+
+/*
+ * Tall Height
+ */
+.height-tall .buttonText {
+ font-size: 15px;
+ font-weight: 700;
+}
+
+.height-tall iron-icon {
+ width: 30px;
+ height: 30px;
+ margin: 8px;
+}
+
+/*
+ * Short Height
+ */
+.height-short .buttonText {
+ font-size: 11px;
+}
+
+.height-short iron-icon {
+ width: 16px;
+ height: 16px;
+ margin: 3px;
+}
+
+
+/*
+ * Branding
+ */
+
+/* Google Scopes */
+
+/* Dark Theme */
+.brand-google.theme-dark {
+ background: #4184F3;
+ color: #fff;
+ border: 1px solid #3266d5;
+}
+
+.brand-google.theme-dark #ripple {
+ color: #1b39a8;
+}
+
+:host([noink]) .brand-google.theme-dark:hover,
+:host([noink]) .brand-google.theme-dark:focus {
+ background: #e74b37;
+}
+
+.brand-google.theme-light .icon {
+ color: #4184F3;
+}
+
+.brand-google.theme-light.signedIn-true.additionalAuth-false .icon {
+ color: #fff;
+}
+
+.brand-google.theme-light #ripple {
+ color: #444;
+}
+
+:host([noink]) .brand-google.theme-light:hover,
+:host([noink]) .brand-google.theme-light:focus {
+ border: 1px solid #c0c0c0;
+}
+
+.brand-google-plus.theme-dark {
+ background: #da4336;
+ color: #fff;
+ border: 1px solid transparent;
+}
+
+.brand-google-plus.theme-dark #ripple {
+ color: #c43828;
+}
+
+/* Light Theme */
+.brand-google-plus.theme-light {
+ background: #fff;
+ color: #737373;
+ border: 1px solid #d9d9d9;
+}
+
+.brand-google-plus.theme-light .icon {
+ color: #e74b37;
+}
+
+.brand-google-plus.theme-light.signedIn-true.additionalAuth-false .icon {
+ color: #fff;
+}
+
+.brand-google-plus.theme-light #ripple {
+ color: #400;
+}
+
+:host([noink]) .brand-google-plus.theme-light:hover,
+:host([noink]) .brand-google-plus.theme-light:focus {
+ border: 1px solid #c0c0c0;
+}
diff --git a/polymer_1.0.4/bower_components/google-signin/google-signin.html b/polymer_1.0.4/bower_components/google-signin/google-signin.html
new file mode 100644
index 0000000..5bf7f95
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-signin/google-signin.html
@@ -0,0 +1,490 @@
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="google-signin-aware.html">
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-icons/iron-icons.html">
+<link rel="import" href="../font-roboto/roboto.html">
+<link rel="import" href="../google-apis/google-js-api.html">
+<link rel="import" href="../paper-ripple/paper-ripple.html">
+<link rel="import" href="../paper-material/paper-material.html">
+<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="google-icons.html">
+
+<dom-module id="google-signin">
+ <link rel="import" type="css" href="google-signin.css">
+ <template>
+ <google-signin-aware id="aware"
+ app-package-name="{{appPackageName}}"
+ client-id="{{clientId}}"
+ cookie-policy="{{cookiePolicy}}"
+ request-visible-actions="{{requestVisibleActions}}"
+ scopes="{{scopes}}"
+ signed-in="{{signedIn}}"
+ is-authorized="{{isAuthorized}}"
+ need-additional-auth="{{needAdditionalAuth}}"
+ has-plus-scopes="{{hasPlusScopes}}"></google-signin-aware>
+ <template is="dom-if" if="{{raised}}">
+ <paper-material id="shadow" class="fit" elevation="2" animated></paper-material>
+ </template>
+ <div id="button"
+ class$="[[_computeButtonClass(height, width, theme, signedIn, _brand, needAdditionalAuth)]]">
+
+ <paper-ripple id="ripple" class="fit"></paper-ripple>
+ <!-- this div is needed to position the ripple behind text content -->
+ <div relative layout horizontal center-center>
+ <template is="dom-if" if="{{_computeButtonIsSignIn(signedIn, needAdditionalAuth)}}">
+ <div class="button-content signIn" tabindex="0"
+ on-click="signIn" on-keydown="_signInKeyPress">
+ <span class="icon"><iron-icon icon="[[_brandIcon]]"></iron-icon></span>
+ <span class="buttonText">{{_labelSignin}}</span>
+ </div>
+ </template>
+ <template is="dom-if" if="{{_computeButtonIsSignOut(signedIn, needAdditionalAuth) }}">
+ <div class="button-content signOut" tabindex="0"
+ on-click="signOut" on-keydown="_signOutKeyPress">
+ <span class="icon"><iron-icon icon="[[_brandIcon]]"></iron-icon></span>
+ <span class="buttonText">{{labelSignout}}</span>
+ </div>
+ </template>
+ <template is="dom-if" if="{{_computeButtonIsSignOutAddl(signedIn, needAdditionalAuth) }}">
+ <div class="button-content signIn" tabindex="0"
+ on-click="signIn" on-keydown="_signInKeyPress">
+ <span class="icon"><iron-icon icon="[[_brandIcon]]"></iron-icon></span>
+ <span class="buttonText">{{labelAdditional}}</span>
+ </div>
+ </template>
+ </div>
+
+ </div>
+ </template>
+</dom-module>
+<script>
+ (function() {
+
+ /**
+ * Enum brand values.
+ * @readonly
+ * @enum {string}
+ */
+ var BrandValue = {
+ GOOGLE: 'google',
+ PLUS: 'google-plus'
+ };
+
+ /**
+ * Enum height values.
+ * @readonly
+ * @enum {string}
+ */
+ var HeightValue = {
+ SHORT: 'short',
+ STANDARD: 'standard',
+ TALL: 'tall'
+ };
+
+ /**
+ * Enum button label default values.
+ * @readonly
+ * @enum {string}
+ */
+ var LabelValue = {
+ STANDARD: 'Sign in',
+ WIDE: 'Sign in with Google',
+ WIDE_PLUS: 'Sign in with Google+'
+ };
+
+ /**
+ * Enum theme values.
+ * @readonly
+ * @enum {string}
+ */
+ var ThemeValue = {
+ LIGHT: 'light',
+ DARK: 'dark'
+ };
+
+ /**
+ * Enum width values.
+ * @readonly
+ * @enum {string}
+ */
+ var WidthValue = {
+ ICON_ONLY: 'iconOnly',
+ STANDARD: 'standard',
+ WIDE: 'wide'
+ };
+
+/**
+<google-signin> is used to authenticate with Google, allowing you to interact
+with other Google APIs such as Drive and Google+.
+
+<img style="max-width:100%;" src="https://cloud.githubusercontent.com/assets/107076/6791176/5c868822-d16a-11e4-918c-ec9b84a2db45.png"/>
+
+If you do not need to show the button, use companion `<google-signin-aware>` element to declare scopes, check authentication state.
+
+#### Examples
+
+ <google-signin client-id="..." scopes="https://www.googleapis.com/auth/drive"></google-signin>
+
+ <google-signin label-signin="Sign-in" client-id="..." scopes="https://www.googleapis.com/auth/drive"></google-signin>
+
+ <google-signin theme="dark" width="iconOnly" client-id="..." scopes="https://www.googleapis.com/auth/drive"></google-signin>
+
+
+#### Notes
+
+The attribute `clientId` is provided in your Google Developers Console
+(https://console.developers.google.com).
+
+The `scopes` attribute allows you to specify which scope permissions are required
+(e.g do you want to allow interaction with the Google Drive API). Many APIs also
+need to be enabled in the Google Developers Console before you can use them.
+
+The `requestVisibleActions` attribute is necessary if you want to write app
+activities (https://developers.google.com/+/web/app-activities/) on behalf of
+the user. Please note that this attribute is only valid in combination with the
+plus.login scope (https://www.googleapis.com/auth/plus.login).
+
+Use label properties to customize prompts.
+
+The button can be styled in using the `height`, `width`, and `theme` attributes.
+These attributes help you follow the Google+ Sign-In button branding guidelines
+(https://developers.google.com/+/branding-guidelines).
+
+The `google-signin-success` event is triggered when a user successfully authenticates
+and `google-signed-out` is triggered when user signeds out.
+You can also use `isAuthorized` attribute to observe user's authentication state.
+
+Additional events, such as `google-signout-attempted` are
+triggered when the user attempts to sign-out and successfully signs out.
+
+The `google-signin-necessary` event is fired when scopes requested via
+google-signin-aware elements require additional user permissions.
+
+#### Testing
+
+By default, the demo accompanying this element is setup to work on localhost with
+port 8080. That said, you *should* update the `clientId` to your own one for
+any apps you're building. See the Google Developers Console
+(https://console.developers.google.com) for more info.
+
+@demo
+*/
+
+ Polymer({
+
+ is: 'google-signin',
+
+ /**
+ * Fired when user is signed in.
+ * You can use auth2 api to retrieve current user: `gapi.auth2.getAuthInstance().currentUser.get();`
+ * @event google-signin-success
+ */
+
+ /**
+ * Fired when the user is signed-out.
+ * @event google-signed-out
+ */
+
+ /**
+ * Fired if user requires additional authorization
+ * @event google-signin-necessary
+ */
+
+ /**
+ * Fired when signed in, and scope has been authorized
+ * @param {Object} result Authorization result.
+ * @event google-signin-aware-success
+ */
+
+ /**
+ * Fired when this scope is not authorized
+ * @event google-signin-aware-signed-out
+ */
+ properties: {
+ /**
+ * App package name for android over-the-air installs.
+ * See the relevant [docs](https://developers.google.com/+/web/signin/android-app-installs)
+ */
+ appPackageName: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * The brand being used for logo and styling.
+ *
+ * @default 'google'
+ */
+ brand: {
+ type: String,
+ value: ''
+ },
+
+ /** @private */
+ _brand: {
+ type: String,
+ computed: '_computeBrand(brand, hasPlusScopes)'
+ },
+
+ /**
+ * a Google Developers clientId reference
+ */
+ clientId: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * The cookie policy defines what URIs have access to the session cookie
+ * remembering the user's sign-in state.
+ * See the relevant [docs](https://developers.google.com/+/web/signin/reference#determining_a_value_for_cookie_policy) for more information.
+ *
+ * @default 'single_host_origin'
+ */
+ cookiePolicy: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * The height to use for the button.
+ *
+ * Available options: short, standard, tall.
+ *
+ * @type {HeightValue}
+ */
+ height: {
+ type: String,
+ value: 'standard'
+ },
+
+ /**
+ * By default the ripple expands to fill the button. Set this to true to
+ * constrain the ripple to a circle within the button.
+ */
+ fill: {
+ type: Boolean,
+ value: true
+ },
+
+ /**
+ * An optional label for the button for additional permissions.
+ */
+ labelAdditional: {
+ type: String,
+ value: 'Additional permissions required'
+ },
+
+ /**
+ * An optional label for the sign-in button.
+ */
+ labelSignin: {
+ type: String,
+ value: ''
+ },
+
+ _labelSignin: {
+ type: String,
+ computed: '_computeSigninLabel(labelSignin, width, _brand)'
+ },
+ /**
+ * An optional label for the sign-out button.
+ */
+ labelSignout: {
+ type: String,
+ value: 'Sign out'
+ },
+
+ /**
+ * If true, the button will be styled with a shadow.
+ */
+ raised: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The app activity types you want to write on behalf of the user
+ * (e.g http://schemas.google.com/AddActivity)
+ */
+ requestVisibleActions: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * The scopes to provide access to (e.g https://www.googleapis.com/auth/drive)
+ * and should be space-delimited.
+ */
+ scopes: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * The theme to use for the button.
+ *
+ * Available options: light, dark.
+ *
+ * @attribute theme
+ * @type {ThemeValue}
+ * @default 'dark'
+ */
+ theme: {
+ type: String,
+ value: 'dark'
+ },
+
+ /**
+ * The width to use for the button.
+ *
+ * Available options: iconOnly, standard, wide.
+ *
+ * @type {WidthValue}
+ */
+ width: {
+ type: String,
+ value: 'standard'
+ },
+
+ _brandIcon: {
+ type: String,
+ computed: '_computeIcon(_brand)'
+ },
+
+ /**
+ * True if *any* element has google+ scopes
+ */
+ hasPlusScopes: {
+ type: Boolean,
+ notify: true,
+ value: false
+ },
+
+ /**
+ * True if additional authorization required globally
+ */
+ needAdditionalAuth: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Is user signed in?
+ */
+ signedIn: {
+ type: Boolean,
+ notify: true,
+ value: false,
+ observer: '_observeSignedIn'
+ },
+
+ /**
+ * True if authorizations for *this* element have been granted
+ */
+ isAuthorized: {
+ type: Boolean,
+ notify: true,
+ value: false
+ }
+
+ },
+
+ _computeButtonClass: function(height, width, theme, signedIn, brand, needAdditionalAuth) {
+ return "height-" + height + " width-" + width + " theme-" + theme + " signedIn-" + signedIn + " brand-" + brand + " additionalAuth-" + needAdditionalAuth;
+ },
+
+ _computeIcon: function(brand) {
+ return "google:" + brand;
+ },
+
+ /* Button state computed */
+ _computeButtonIsSignIn: function(signedIn, additionalAuth) {
+ return !signedIn;
+ },
+
+ _computeButtonIsSignOut: function(signedIn, additionalAuth) {
+ return signedIn && !additionalAuth;
+ },
+
+ _computeButtonIsSignOutAddl: function(signedIn, additionalAuth) {
+ return signedIn && additionalAuth;
+ },
+
+ _computeBrand: function(attrBrand, hasPlusScopes) {
+ var newBrand;
+ if (attrBrand) {
+ newBrand = attrBrand;
+ } else if (hasPlusScopes) {
+ newBrand = BrandValue.PLUS;
+ } else {
+ newBrand = BrandValue.GOOGLE;
+ };
+ return newBrand;
+ },
+
+ _observeSignedIn: function(newVal, oldVal) {
+ if (newVal) {
+ if (this.needAdditionalAuth)
+ this.fire('google-signin-necessary');
+ this.fire('google-signin-success');
+ }
+ else
+ this.fire('google-signed-out');
+ },
+
+ /**
+ * Determines the proper label based on the attributes.
+ */
+ _computeSigninLabel: function(labelSignin, width, _brand) {
+ if (labelSignin) {
+ return labelSignin;
+ } else {
+ switch(width) {
+
+ case WidthValue.WIDE:
+ return (_brand == BrandValue.PLUS) ?
+ LabelValue.WIDE_PLUS : LabelValue.WIDE;
+
+ case WidthValue.STANDARD:
+ return LabelValue.STANDARD;
+
+ case WidthValue.ICON_ONLY:
+ return '';
+
+ default:
+ console.warn("bad width value: ", width);
+ return LabelValue.STANDARD;
+ }
+ }
+ },
+
+ /** Sign in user. Opens the authorization dialog for signing in.
+ * The dialog will be blocked by a popup blocker unless called inside click handler.
+ */
+ signIn: function () {
+ this.$.aware.signIn();
+ },
+
+ _signInKeyPress: function (e) {
+ if (e.which == 13 || e.keyCode == 13 || e.which == 32 || e.keyCode == 32) {
+ e.preventDefault();
+ this.signIn();
+ }
+ },
+
+ /** Sign out the user */
+ signOut: function () {
+ this.fire('google-signout-attempted');
+ this.$.aware.signOut();
+ },
+
+ _signOutKeyPress: function (e) {
+ if (e.which == 13 || e.keyCode == 13 || e.which == 32 || e.keyCode == 32) {
+ e.preventDefault();
+ this.signOut();
+ }
+ }
+ });
+ }());
+</script>
diff --git a/polymer_1.0.4/bower_components/google-signin/index.html b/polymer_1.0.4/bower_components/google-signin/index.html
new file mode 100644
index 0000000..e8f85ae
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-signin/index.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-streetview-pano/.bower.json b/polymer_1.0.4/bower_components/google-streetview-pano/.bower.json
new file mode 100644
index 0000000..a879208
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-streetview-pano/.bower.json
@@ -0,0 +1,41 @@
+{
+ "name": "google-streetview-pano",
+ "version": "1.0.1",
+ "homepage": "https://googlewebcomponents.github.io/google-streetview-pano",
+ "description": "Google Maps street view web component",
+ "main": "google-streetview-pano.html",
+ "authors": [
+ "Rob Dodson"
+ ],
+ "license": "Apache2",
+ "ignore": [
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "streetview",
+ "apis",
+ "google-maps",
+ "google"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "ec92f64f57a44f758fc5952d6b14f51a376d7177"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-streetview-pano.git",
+ "_target": "^1.0.0",
+ "_originalSource": "GoogleWebComponents/google-streetview-pano"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-streetview-pano/.gitignore b/polymer_1.0.4/bower_components/google-streetview-pano/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-streetview-pano/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/google-streetview-pano/LICENSE b/polymer_1.0.4/bower_components/google-streetview-pano/LICENSE
new file mode 100644
index 0000000..7ba0226
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-streetview-pano/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2014 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/polymer_1.0.4/bower_components/google-streetview-pano/README.md b/polymer_1.0.4/bower_components/google-streetview-pano/README.md
new file mode 100644
index 0000000..adc1ba5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-streetview-pano/README.md
@@ -0,0 +1,4 @@
+google-streetview-pano
+================
+
+See the [component page](http://googlewebcomponents.github.io/google-streetview-pano) for more information.
diff --git a/polymer_1.0.4/bower_components/google-streetview-pano/bower.json b/polymer_1.0.4/bower_components/google-streetview-pano/bower.json
new file mode 100644
index 0000000..0363e49
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-streetview-pano/bower.json
@@ -0,0 +1,32 @@
+{
+ "name": "google-streetview-pano",
+ "version": "1.0.1",
+ "homepage": "https://googlewebcomponents.github.io/google-streetview-pano",
+ "description": "Google Maps street view web component",
+ "main": "google-streetview-pano.html",
+ "authors": [
+ "Rob Dodson"
+ ],
+ "license": "Apache2",
+ "ignore": [
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "streetview",
+ "apis",
+ "google-maps",
+ "google"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-streetview-pano/demo/index.html b/polymer_1.0.4/bower_components/google-streetview-pano/demo/index.html
new file mode 100644
index 0000000..002ba5a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-streetview-pano/demo/index.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>google-streetview-pano Demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../google-streetview-pano.html">
+ <style>
+ html, body {
+ margin: 0;
+ padding: 0;
+ height: 100%;
+ background: black;
+ }
+ google-streetview-pano {
+ display: block;
+ height: 80%;
+ }
+ </style>
+</head>
+
+<body>
+
+ <google-streetview-pano pano-id="RjEjGqu4ymMAAAAGOtaGAQ" heading="350" pitch="-2" zoom="0.8" disable-default-ui></google-streetview-pano>
+
+ <button onclick="showMachu();">Show me Machu Pichu</button>
+ <button onclick="showBrazil();">Show me Brazil</button>
+ <button onclick="showStatue();">Show me Statue of Vishnu</button>
+
+ <script>
+ var pano = document.querySelector('google-streetview-pano');
+ function showMachu() {
+ pano.heading = 330;
+ pano.pitch = -2;
+ pano.zoom = 0.8;
+ pano.panoId = 'VsCKIVGfvpEAAAQJKfdW1w';
+ }
+ function showBrazil() {
+ pano.heading = 210;
+ pano.pitch = 15;
+ pano.zoom = 0.2;
+ pano.panoId = 'CkmCkfwvIGUAAAQW-qy0KQ';
+ }
+ function showStatue() {
+ pano.heading = 80;
+ pano.pitch = 7;
+ pano.zoom = 0.2;
+ pano.panoId = 'pVFRQcvJ2IEAAAGuvUxa_w';
+ }
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-streetview-pano/google-streetview-pano.html b/polymer_1.0.4/bower_components/google-streetview-pano/google-streetview-pano.html
new file mode 100644
index 0000000..5aa0a1a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-streetview-pano/google-streetview-pano.html
@@ -0,0 +1,233 @@
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../google-apis/google-maps-api.html">
+
+<!--
+Element for generating a Google Maps Street View Panorama.
+
+##### Example
+
+ <google-streetview-pano
+ pano-id="CWskcsTEZBNXaD8gG-zATA"
+ heading="330"
+ pitch="-2"
+ zoom="0.8"
+ disable-default-ui>
+ </google-streetview-pano>
+
+There are tons of great panoramas on the [Google Maps | Views page](https://www.google.com/maps/views/home?gl=us)
+
+To grab a panorama, look at its url in the address bar. For example:
+
+google.com/maps/views/view/102684927602131521305/photo/**1szTnskrdKIAAAGuu3fZRw**
+
+The hash in bold is the `pano-id`. You'll often need to dial in the `heading`, `pitch` and `zoom` manually.
+
+@demo
+-->
+
+<dom-module id="google-streetview-pano">
+ <style>
+ :host {
+ display: block;
+ }
+ #pano {
+ height: 100%;
+ }
+ </style>
+ <template>
+ <google-maps-api api-key="{{apiKey}}" version="{{version}}"
+ libraries="{{libraries}}"
+ client-id="{{clientId}}"
+ language="{{language}}"
+ client
+ on-api-load="_mapApiLoaded"></google-maps-api>
+ <div id="pano" on-mouseenter="_autoStop"
+ on-mouseleave="_autoUpdate"></div>
+ </template>
+</dom-module>
+
+<script>
+ "use strict";
+
+ Polymer({
+ is: 'google-streetview-pano',
+ properties: {
+ /**
+ * A Maps API key. To obtain an API key, see developers.google.com/maps/documentation/javascript/tutorial#api_key.
+ */
+ apiKey: String,
+
+ /**
+ * A Maps API for Business Client ID. To obtain a Maps API for Business Client ID, see developers.google.com/maps/documentation/business/.
+ * If set, a Client ID will take precedence over an API Key.
+ */
+ clientId: String,
+
+ /**
+ * The localized language to load the Maps API with. For more information
+ * see https://developers.google.com/maps/documentation/javascript/basics#Language
+ *
+ * Note: the Maps API defaults to the preferred language setting of the browser.
+ * Use this parameter to override that behavior.
+ *
+ */
+ language: String,
+
+ /**
+ * A comma separated list (e.g. "places,geometry") of libraries to load
+ * with this map. Defaults to "places". For more information see
+ * https://developers.google.com/maps/documentation/javascript/libraries.
+ *
+ */
+ libraries: {
+ type: String,
+ value: "places"
+ },
+
+ /**
+ * Version of the Google Maps API to use.
+ *
+ */
+ version: {
+ type: String,
+ value: '3.exp'
+ },
+
+ /**
+ * Specifies which photosphere to load
+ *
+ * **Required**
+ */
+ panoId: {
+ type: String,
+ observer: '_panoIdChanged'
+ },
+
+ /**
+ * The camera heading in degrees relative to true north. True north is 0°, east is 90°, south is 180°, west is 270°.
+ */
+ heading: {
+ type: Number,
+ value: 45
+ },
+
+ /**
+ * The camera pitch in degrees, relative to the street view vehicle. Ranges from 90° (directly upwards) to -90° (directly downwards).
+ */
+ pitch: {
+ type: Number,
+ value: -2
+ },
+
+ /**
+ * Sets the zoom level of the panorama. Fully zoomed-out is level 0, where the field of view is 180 degrees.
+ */
+ zoom: {
+ type: Number,
+ value: 1
+ },
+
+ /**
+ * If true, disables all default UI.
+ */
+ disableDefaultUi: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, disables the auto panning animation
+ */
+ disableAutoPan: {
+ type: Boolean,
+ value: false
+ },
+
+ },
+
+ pano: null,
+ rAFid: null,
+ _mapApiLoaded: function() {
+ this.pano = new google.maps.StreetViewPanorama(
+ this.$.pano,
+ this._getPanoOptions());
+ this.pano.setVisible(true);
+
+ if (this.disableAutoPan) {
+ return;
+ }
+ // Kickoff the rotating animation
+ this.rAFid = requestAnimationFrame(this.update.bind(this));
+ },
+
+ /**
+ * Returns the an object with the current panorama configurations.
+ */
+ _getPanoOptions: function() {
+ var panoOptions = {
+ pano: this.panoId,
+ pov: {
+ heading: this.heading,
+ pitch: this.pitch
+ },
+ disableDefaultUI: this.disableDefaultUi,
+ zoom: this.zoom
+ };
+
+ return panoOptions;
+ },
+
+ /**
+ * Fired every rAF. Updates the heading to create a slow pan effect
+ * Will be canceled by mouse enter or calling stop()
+ */
+ update: function() {
+ this.rAFid = requestAnimationFrame(this.update.bind(this));
+ var pov = this.pano.getPov();
+ pov.heading += 0.03;
+ this.pano.setPov(pov);
+ },
+
+ _autoUpdate: function() {
+ if (this.disableAutoPan) {
+ return;
+ }
+
+ this.update();
+ },
+
+ /**
+ * Reset the pov for the panorama.
+ * @method reset
+ */
+ reset: function() {
+ var pov = this.pano.getPov();
+ pov.heading = this.heading;
+ pov.pitch = this.pitch;
+ this.pano.setPov(pov);
+ },
+
+ /**
+ * Cancel the slow panning animation.
+ * @method stop
+ */
+ stop: function() {
+ cancelAnimationFrame(this.rAFid);
+ },
+
+ _autoStop: function() {
+ if (this.disableAutoPan) {
+ return;
+ }
+
+ this.stop();
+ },
+
+ _panoIdChanged: function(newVal, oldVal) {
+ if (this.pano) {
+ this.pano.setPano(newVal);
+ this.reset();
+ }
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/google-streetview-pano/index.html b/polymer_1.0.4/bower_components/google-streetview-pano/index.html
new file mode 100644
index 0000000..203f4fa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-streetview-pano/index.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-url-shortener/.bower.json b/polymer_1.0.4/bower_components/google-url-shortener/.bower.json
new file mode 100644
index 0000000..ba8e061
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-url-shortener/.bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "google-url-shortener",
+ "version": "1.0.1",
+ "homepage": "https://googlewebcomponents.github.io/google-url-shortener",
+ "description": "Web component to shorten URLs with the Google URL Shortener API",
+ "main": "google-url-shortener.html",
+ "authors": [
+ "Sérgio Gomes"
+ ],
+ "license": "Apache2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "url-shortener",
+ "google"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "88233564df159dcea1db746ee81cbf9d57680806"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-url-shortener.git",
+ "_target": "^1.0.0",
+ "_originalSource": "GoogleWebComponents/google-url-shortener"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-url-shortener/README.md b/polymer_1.0.4/bower_components/google-url-shortener/README.md
new file mode 100644
index 0000000..498e589
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-url-shortener/README.md
@@ -0,0 +1,4 @@
+google-url-shortener
+================
+
+See the [component page](http://googlewebcomponents.github.io/google-url-shortener) for more information.
diff --git a/polymer_1.0.4/bower_components/google-url-shortener/bower.json b/polymer_1.0.4/bower_components/google-url-shortener/bower.json
new file mode 100644
index 0000000..74def29
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-url-shortener/bower.json
@@ -0,0 +1,30 @@
+{
+ "name": "google-url-shortener",
+ "version": "1.0.1",
+ "homepage": "https://googlewebcomponents.github.io/google-url-shortener",
+ "description": "Web component to shorten URLs with the Google URL Shortener API",
+ "main": "google-url-shortener.html",
+ "authors": [
+ "Sérgio Gomes"
+ ],
+ "license": "Apache2",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer",
+ "url-shortener",
+ "google"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-url-shortener/demo/index.html b/polymer_1.0.4/bower_components/google-url-shortener/demo/index.html
new file mode 100644
index 0000000..46e00af
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-url-shortener/demo/index.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>google-url-shortener Demo</title>
+
+ <link rel="import" href="../google-url-shortener.html">
+
+</head>
+<body>
+ <p>A `google-url-shortener` allows you to build this:</p>
+ <template is="dom-bind">
+ <google-url-shortener id="shortener"
+ long-url="{{longUrl}}"
+ short-url="{{shortUrl}}"
+ error="{{urlError}}"
+ auto>
+ </google-url-shortener>
+ <form on-submit="shorten">
+ <p>
+ <input type="url" id="longUrl"
+ placeholder="Input URL here:"
+ value="http://www.google.com/"
+ size="50">
+ <input type="submit" value="submit">
+ </p>
+ <p>
+ <strong>Short URL</strong>:
+ <a href="{{shortUrl}}" target="_blank">{{shortUrl}}</a>
+ </p>
+ <p>
+ <p><strong>Error: </strong><span style="color:red">{{urlError}}</span></p>
+ </p>
+ </form>
+ </template>
+ <script>
+ document.querySelector('template').shorten = function(e) {
+ e.preventDefault();
+ this.longUrl = this.$.longUrl.value;
+ };
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-url-shortener/google-url-shortener.html b/polymer_1.0.4/bower_components/google-url-shortener/google-url-shortener.html
new file mode 100644
index 0000000..711fa0d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-url-shortener/google-url-shortener.html
@@ -0,0 +1,163 @@
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../google-apis/google-client-loader.html">
+
+<!--
+`google-url-shortener` is a web component that shortens URLs with the
+<a href="https://developers.google.com/url-shortener/">Google URL Shortener API
+</a>.
+
+##### Example
+
+ <google-url-shortener id="shortener"></google-url-shortener>
+
+ <script>
+ var shortener = document.getElementById('shortener');
+
+ shortener.addEventListener('google-url-shorten', function(event) {
+ console.log(event.detail.shortUrl);
+ });
+
+ // Shorten the current page URL.
+ shortener.longUrl = document.URL;
+ shortener.shorten();
+ </script>
+
+##### Example using `auto` and binding.
+
+ <google-url-shortener id="shortener" longUrl="{{longUrl}}" auto>
+ </google-url-shortener>
+
+ <script>
+ var shortener = document.getElementById('shortener');
+
+ shortener.addEventListener('google-url-shorten', function(event) {
+ // This will be called automatically every time `longUrl` changes.
+ console.log(event.detail.shortUrl);
+ });
+ </script>
+
+@demo
+-->
+<dom-module id="google-url-shortener">
+ <template>
+ <google-client-loader id="urlshortener" name="urlshortener" version="v1"
+ on-google-api-load="_readyForAction"
+ on-google-api-load-error="_apiLoadError">
+ </google-api-loader>
+ </template>
+</dom-module>
+
+<script>
+
+ (function() {
+ 'use strict';
+
+ // Stores whether the URL Shortener API is done loading.
+ var apiLoaded_ = false;
+
+ Polymer({
+
+ is: 'google-url-shortener',
+
+ /**
+ * Fired when the component is ready for shortening.
+ *
+ * @event google-url-shortener-ready
+ */
+
+ /**
+ * Fired when the URL gets successfully shortened.
+ *
+ * @event google-url-shorten
+ */
+
+ /**
+ * Fired if an attempt to shorten a URL results in an error.
+ *
+ * @event google-url-shorten-error
+ */
+
+ properties: {
+ /**
+ * The URL to be shortened.
+ */
+ longUrl: {
+ type: String,
+ value: '',
+ observer: '_longUrlChanged'
+ },
+
+ /**
+ * Shortened URL
+ */
+ shortUrl: {
+ type: String,
+ value: '',
+ notify: true
+ },
+
+ /**
+ * Error when url was shortened
+ */
+ error: {
+ type: String,
+ value: '',
+ notify: true
+ },
+ /**
+ * If true, automatically performs the shortening request when `longUrl`
+ * changes.
+ */
+ auto: {
+ type: Boolean,
+ value: false
+ }
+ },
+
+ _readyForAction: function() {
+ apiLoaded_ = true;
+ this.fire('google-url-shortener-ready');
+ },
+
+ _apiLoadError: function(event) {
+ this.fire('api-error', {
+ 'error': {
+ 'message': 'Error loading URL Shortener API',
+ 'innerError': event.detail
+ }
+ });
+ },
+
+ _longUrlChanged: function() {
+ if (this.auto) {
+ this.shorten();
+ }
+ },
+
+ /**
+ * Shortens the URL in `longUrl`. Use if `auto` is not set.
+ */
+ shorten: function() {
+ if (apiLoaded_) {
+ if (this.longUrl) {
+ var request = this.$.urlshortener.api.url.insert(
+ {resource: {longUrl: this.longUrl}});
+
+ request.execute(function(response) {
+ if (response && response.id) {
+ this.shortUrl = response.id;
+ this.error = '';
+ this.fire('google-url-shorten', {shortUrl: response.id});
+ } else {
+ this.error = response && response.error ? response.error.message : 'Unknown error';
+ this.fire('google-url-shorten-error', {error: this.error});
+ }
+ }.bind(this));
+ }
+ }
+ }
+
+ });
+ })();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/google-url-shortener/index.html b/polymer_1.0.4/bower_components/google-url-shortener/index.html
new file mode 100644
index 0000000..203f4fa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-url-shortener/index.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-web-components/.bower.json b/polymer_1.0.4/bower_components/google-web-components/.bower.json
new file mode 100644
index 0000000..a876286
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-web-components/.bower.json
@@ -0,0 +1,48 @@
+{
+ "name": "google-web-components",
+ "version": "1.0.1",
+ "homepage": "https://github.com/GoogleWebComponents/google-web-components",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "Google Web Components",
+ "keywords": [
+ "google",
+ "services",
+ "sign-in",
+ "maps",
+ "hangouts",
+ "charts"
+ ],
+ "license": "BSD",
+ "dependencies": {
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0",
+ "google-feeds": "GoogleWebComponents/google-feeds#^1.0.0",
+ "google-map": "GoogleWebComponents/google-map#^1.0.0",
+ "google-signin": "GoogleWebComponents/google-signin#^1.0.0",
+ "google-sheets": "GoogleWebComponents/google-sheets#^1.0.1",
+ "google-youtube": "GoogleWebComponents/google-youtube#^1.1.0",
+ "google-analytics": "GoogleWebComponents/google-analytics#^1.0.0",
+ "google-calendar": "GoogleWebComponents/google-calendar#^1.0.0",
+ "google-chart": "GoogleWebComponents/google-chart#^1.0.0",
+ "google-castable-video": "GoogleWebComponents/google-castable-video#^1.0.0",
+ "google-hangout-button": "GoogleWebComponents/google-hangout-button#^1.0.0",
+ "google-url-shortener": "GoogleWebComponents/google-url-shortener#^1.0.0",
+ "google-youtube-upload": "GoogleWebComponents/google-youtube-upload#^1.0.0",
+ "google-streetview-pano": "GoogleWebComponents/google-streetview-pano#^1.0.0",
+ "firebase-element": "GoogleWebComponents/firebase-element#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "ef8594348ae69db818629db4599927ea187e596c"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-web-components.git",
+ "_target": "~1.0.1",
+ "_originalSource": "GoogleWebComponents/google-web-components",
+ "_direct": true
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-web-components/.gitignore b/polymer_1.0.4/bower_components/google-web-components/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-web-components/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/google-web-components/README.md b/polymer_1.0.4/bower_components/google-web-components/README.md
new file mode 100644
index 0000000..1211711
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-web-components/README.md
@@ -0,0 +1,3 @@
+# Google Web Components
+
+A collection of web components for Google APIs & services. Built with [Polymer 1.0](https://www.polymer-project.org/1.0/).
diff --git a/polymer_1.0.4/bower_components/google-web-components/bower.json b/polymer_1.0.4/bower_components/google-web-components/bower.json
new file mode 100644
index 0000000..770025f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-web-components/bower.json
@@ -0,0 +1,38 @@
+{
+ "name": "google-web-components",
+ "version": "1.0.1",
+ "homepage": "https://github.com/GoogleWebComponents/google-web-components",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "Google Web Components",
+ "keywords": [
+ "google",
+ "services",
+ "sign-in",
+ "maps",
+ "hangouts",
+ "charts"
+ ],
+ "license": "BSD",
+ "dependencies": {
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0",
+ "google-feeds": "GoogleWebComponents/google-feeds#^1.0.0",
+ "google-map": "GoogleWebComponents/google-map#^1.0.0",
+ "google-signin": "GoogleWebComponents/google-signin#^1.0.0",
+ "google-sheets": "GoogleWebComponents/google-sheets#^1.0.1",
+ "google-youtube": "GoogleWebComponents/google-youtube#^1.1.0",
+ "google-analytics": "GoogleWebComponents/google-analytics#^1.0.0",
+ "google-calendar": "GoogleWebComponents/google-calendar#^1.0.0",
+ "google-chart": "GoogleWebComponents/google-chart#^1.0.0",
+ "google-castable-video": "GoogleWebComponents/google-castable-video#^1.0.0",
+ "google-hangout-button": "GoogleWebComponents/google-hangout-button#^1.0.0",
+ "google-url-shortener": "GoogleWebComponents/google-url-shortener#^1.0.0",
+ "google-youtube-upload": "GoogleWebComponents/google-youtube-upload#^1.0.0",
+ "google-streetview-pano": "GoogleWebComponents/google-streetview-pano#^1.0.0",
+ "firebase-element": "GoogleWebComponents/firebase-element#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-web-components/google-web-components.html b/polymer_1.0.4/bower_components/google-web-components/google-web-components.html
new file mode 100755
index 0000000..6992798
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-web-components/google-web-components.html
@@ -0,0 +1,15 @@
+<link rel="import" href="../google-analytics/google-analytics.html">
+<link rel="import" href="../google-apis/google-apis.html">
+<link rel="import" href="../google-calendar/google-calendar.html">
+<link rel="import" href="../google-castable-video/google-castable-video.html">
+<link rel="import" href="../google-chart/google-chart.html">
+<!-- <link rel="import" href="../google-drive/google-drive.html"> -->
+<link rel="import" href="../google-feeds/google-feeds.html">
+<link rel="import" href="../google-hangout-button/google-hangout-button.html">
+<link rel="import" href="../google-map/google-map.html">
+<link rel="import" href="../google-sheets/google-sheets.html">
+<link rel="import" href="../google-signin/google-signin.html">
+<link rel="import" href="../google-streetview-pano/google-streetview-pano.html">
+<link rel="import" href="../google-url-shortener/google-url-shortener.html">
+<link rel="import" href="../google-youtube/google-youtube.html">
+<link rel="import" href="../google-youtube-upload/google-youtube-upload.html">
diff --git a/polymer_1.0.4/bower_components/google-web-components/index.html b/polymer_1.0.4/bower_components/google-web-components/index.html
new file mode 100755
index 0000000..840d229
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-web-components/index.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <!-- <iron-component-page no-demo></iron-component-page> -->
+ <iron-doc-viewer transitive no-demo></iron-doc-viewer>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-youtube-upload/.bower.json b/polymer_1.0.4/bower_components/google-youtube-upload/.bower.json
new file mode 100644
index 0000000..0e9c384
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube-upload/.bower.json
@@ -0,0 +1,41 @@
+{
+ "name": "google-youtube-upload",
+ "version": "1.1.2",
+ "description": "Upload videos to YouTube from your browser.",
+ "homepage": "https://googlewebcomponents.github.io/google-youtube-upload",
+ "main": "google-youtube-upload.html",
+ "authors": [
+ "Jeff Posnick <jeffy@google.com>"
+ ],
+ "license": "Apache-2.0",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "google",
+ "youtube",
+ "upload",
+ "polymer",
+ "web-components",
+ "web-component"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-signin": "GoogleWebComponents/google-signin#^1.0.0",
+ "cors-upload-sample": "googledrive/cors-upload-sample#master"
+ },
+ "devDependencies": {
+ "google-youtube": "GoogleWebComponents/google-youtube#^1.1.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
+ },
+ "_release": "1.1.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.1.2",
+ "commit": "6db46812d6146cb6bc4efbf295b2cf2511aba062"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-youtube-upload.git",
+ "_target": "^1.0.0",
+ "_originalSource": "GoogleWebComponents/google-youtube-upload"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-youtube-upload/LICENSE b/polymer_1.0.4/bower_components/google-youtube-upload/LICENSE
new file mode 100644
index 0000000..52aea39
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube-upload/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2014 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/polymer_1.0.4/bower_components/google-youtube-upload/README.md b/polymer_1.0.4/bower_components/google-youtube-upload/README.md
new file mode 100755
index 0000000..c0a45f3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube-upload/README.md
@@ -0,0 +1,4 @@
+google-youtube-upload
+=====================
+
+See the [component landing page](https://googlewebcomponents.github.io/google-youtube-upload) for more information.
diff --git a/polymer_1.0.4/bower_components/google-youtube-upload/bower.json b/polymer_1.0.4/bower_components/google-youtube-upload/bower.json
new file mode 100755
index 0000000..1203492
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube-upload/bower.json
@@ -0,0 +1,32 @@
+{
+ "name": "google-youtube-upload",
+ "version": "1.1.2",
+ "description": "Upload videos to YouTube from your browser.",
+ "homepage": "https://googlewebcomponents.github.io/google-youtube-upload",
+ "main": "google-youtube-upload.html",
+ "authors": [
+ "Jeff Posnick <jeffy@google.com>"
+ ],
+ "license": "Apache-2.0",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "google",
+ "youtube",
+ "upload",
+ "polymer",
+ "web-components",
+ "web-component"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-signin": "GoogleWebComponents/google-signin#^1.0.0",
+ "cors-upload-sample": "googledrive/cors-upload-sample#master"
+ },
+ "devDependencies": {
+ "google-youtube": "GoogleWebComponents/google-youtube#^1.1.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-youtube-upload/demo/demo.elements.html b/polymer_1.0.4/bower_components/google-youtube-upload/demo/demo.elements.html
new file mode 100644
index 0000000..d6c9188
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube-upload/demo/demo.elements.html
@@ -0,0 +1,223 @@
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../../google-youtube/google-youtube.html">
+<link rel="import" href="../google-youtube-upload.html">
+
+<dom-module id="youtube-upload-demo-element">
+ <style>
+ label {
+ display: block;
+ margin-top: 1em;
+ }
+
+ input {
+ font-size: 100%;
+ width: 50%;
+ }
+
+ textarea {
+ font-size: 100%;
+ width: 50%;
+ height: 6em;
+ }
+
+ google-youtube-upload {
+ margin-top: 1em;
+ }
+ </style>
+ <template>
+ <p>
+ Upload videos with a
+ <code><a href="index.html" target="_blank"><google-youtube-upload></a></code>
+ element!
+ </p>
+
+ <template is="dom-if" if="{{canShowPreUpload(state)}}">
+ <div>
+ <label for="video-title">Title:</label>
+ <input id="video-title" type="text" value="{{videoTitle::change}}">
+ </div>
+ <div>
+ <label for="description">Description:</label>
+ <textarea id="description" value="{{description::change}}"></textarea>
+ </div>
+ <div>
+ <label for="privacy-status">Privacy Status:</label>
+ <select id="privacy-status" value="{{privacyStatus::change}}">
+ <option>public</option>
+ <option>unlisted</option>
+ <option>private</option>
+ </select>
+ </div>
+ <google-youtube-upload
+ client-id="1054047045356-j8pgqgls9vdef3rl09hapoicumbte0bo.apps.googleusercontent.com"
+ video-title="{{videoTitle}}"
+ description="{{description}}"
+ privacy-status="{{privacyStatus}}"
+ video-id="{{videoId}}"
+ on-youtube-upload-start="handleYouTubeUploadStart"
+ on-youtube-upload-progress="handleYouTubeUploadProgress"
+ on-youtube-upload-complete="handleYouTubeUploadComplete"
+ on-youtube-upload-fail="handleYouTubeUploadFail"
+ on-youtube-processing-poll="handleYouTubeProcessingPoll"
+ on-youtube-processing-complete="handleYouTubeProcessingComplete"
+ on-youtube-processing-fail="handleYouTubeProcessingFail">
+ </google-youtube-upload>
+ </template>
+
+ <template is="dom-if" if="{{canShowUpload(state)}}">
+ <div>
+ Upload Progress:
+ <progress max="1" value="{{fractionComplete}}"></progress>
+ <span>{{computeProgressText(megabytesPerSecond, minutesRemaining, secondsRemaining)}}</span>
+ </div>
+ </template>
+
+ <template is="dom-if" if="{{canShowUploadComplete(state)}}">
+ <p>
+ Upload complete. Please wait while video id '<span>{{videoId}}</span>' is
+ <a href="https://support.google.com/youtube/answer/71674?ref_topic=2888603" target="_blank">processing</a><span>{{processingEllipses}}</span>
+ </p>
+ </template>
+
+ <template is="dom-if" if="{{canShowProcessingComplete(state)}}" restamp>
+ <p>
+ Processing complete. The video is available at
+ <a href$="{{videoUrl}}" target="_blank">{{videoUrl}}</a>
+ and embedded below:
+ </p>
+ <google-youtube video-id="{{videoId}}"></google-youtube>
+ </template>
+
+ <template is="dom-if" if="{{canShowError(state)}}">
+ <p>{{error}}</p>
+ </template>
+
+ </template>
+</dom-module>
+<script>
+ Polymer({
+ is: 'youtube-upload-demo-element',
+
+ properties: {
+ state: {
+ type: String,
+ value: 'pre-upload'
+ },
+ processingEllipses: {
+ type: String,
+ value: '...'
+ },
+ megabytesPerSecond: {
+ type: Number,
+ value: 0
+ },
+ minutesRemaining: {
+ type: Number,
+ value: 0
+ },
+ secondsRemaining: {
+ type: Number,
+ value: 0
+ },
+ fractionComplete: {
+ type: Number,
+ value: 0
+ },
+ error: {
+ type: String,
+ value: ''
+ },
+ videoTitle: {
+ type: String,
+ value: 'Untitled Video'
+ },
+ description: {
+ type: String,
+ value: 'Uploaded via a web component! Check out https://github.com/GoogleWebComponents/google-youtube-upload'
+ },
+ privacyStatus: {
+ type: String,
+ value: 'public'
+ },
+ videoId: {
+ type: String,
+ value: ''
+ },
+ videoUrl: {
+ type: String,
+ computed: 'computeVideoUrl(videoId)'
+ }
+ },
+
+ canShowPreUpload: function(state) {
+ return state === 'pre-upload';
+ },
+ canShowUpload: function(state) {
+ return state === 'upload'
+ },
+ canShowUploadComplete: function(state) {
+ return state === 'upload-complete';
+ },
+ canShowProcessingComplete: function(state) {
+ return state === 'processing-complete';
+ },
+ canShowError: function(state) {
+ return state === 'error';
+ },
+ computeProgressText: function( megabytesPerSecond, minutesRemaining, secondsRemaining) {
+ return megabytesPerSecond + "MB/s, " + minutesRemaining + "m" + secondsRemaining + "s remaining";
+ },
+ computeVideoUrl: function(videoId) {
+ return "https://youtu.be/" + videoId;
+ },
+ handleYouTubeUploadStart: function(e) {
+ this.state = 'upload';
+ },
+
+ handleYouTubeUploadProgress: function(e) {
+ this.megabytesPerSecond = (e.detail.bytesPerSecond / (1024 * 1024)).toFixed(2);
+ this.minutesRemaining = Math.floor(e.detail.estimatedSecondsRemaining / 60);
+ this.secondsRemaining = Math.round(e.detail.estimatedSecondsRemaining % 60);
+ this.fractionComplete = e.detail.fractionComplete;
+ },
+
+ handleYouTubeUploadComplete: function(e) {
+ this.state = 'upload-complete';
+ },
+
+ handleYouTubeUploadFail: function(e) {
+ this.error = e.detail;
+ this.state = 'error';
+ },
+
+ handleYouTubeProcessingPoll: function(e) {
+ this.processingEllipses += '.';
+ },
+
+ handleYouTubeProcessingComplete: function(e) {
+ this.state = 'processing-complete';
+ },
+
+ handleYouTubeProcessingFail: function(e) {
+ var error;
+ switch(e.detail.uploadStatus) {
+ case 'failed':
+ error = e.detail.failureReason || 'unknown error';
+ break;
+
+ case 'rejected':
+ error = e.detail.rejectionReason || 'unknown error';
+ break;
+
+ default:
+ error = 'unknown error';
+ break;
+ }
+
+ this.error = 'YouTube processing failed (' + error + ').';
+ this.state = 'error';
+ }
+ });
+
+
+</script>
diff --git a/polymer_1.0.4/bower_components/google-youtube-upload/demo/index.html b/polymer_1.0.4/bower_components/google-youtube-upload/demo/index.html
new file mode 100755
index 0000000..2353442
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube-upload/demo/index.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title><google-youtube-upload> Demo</title>
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="demo.elements.html">
+ <style>
+ body {
+ font-family: Helvetica, sans-serif;
+ }
+ </style>
+ </head>
+ <body>
+ <youtube-upload-demo-element></youtube-upload-demo-element>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-youtube-upload/google-youtube-upload.css b/polymer_1.0.4/bower_components/google-youtube-upload/google-youtube-upload.css
new file mode 100755
index 0000000..0720b9b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube-upload/google-youtube-upload.css
@@ -0,0 +1,24 @@
+:host {
+ display: block;
+}
+
+#login-logout {
+ margin-bottom: 1em;
+}
+
+#channel-image {
+ width: 2em;
+ height: 2em;
+ vertical-align: middle;
+}
+
+#channel-name {
+ margin-left: 0.2em;
+ margin-right: 0.2em;
+}
+
+#disclaimer {
+ font-size: 0.75em;
+ color: #aeaeae;
+ max-width: 350px;
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-youtube-upload/google-youtube-upload.html b/polymer_1.0.4/bower_components/google-youtube-upload/google-youtube-upload.html
new file mode 100755
index 0000000..f697068
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube-upload/google-youtube-upload.html
@@ -0,0 +1,467 @@
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../google-signin/google-signin.html">
+<link rel="import" href="../google-apis/google-client-loader.html">
+<!--
+Element enabling you to upload videos to YouTube.
+
+##### Examples
+
+Manual upload with a `Video Upload` button once a video file is selected:
+
+ <google-youtube-upload client-id="..."></google-youtube-upload>
+
+Automatic upload on video file select, with a custom title, and 'unlisted' privacy:
+
+ <google-youtube-upload
+ auto
+ video-title="My Awesome Video"
+ privacy-status="unlisted"
+ client-id="...">
+ </google-youtube-upload>
+
+@demo
+-->
+<dom-module id="google-youtube-upload">
+ <link rel="import" type="css" href="google-youtube-upload.css">
+ <template>
+ <script src="../cors-upload-sample/upload.js"></script>
+ <google-client-loader on-js-api-load="_clientLoaded"></google-client-loader>
+ <div id="login-logout">
+ <img id="channel-image" src="{{_channel.thumbnail}}" style$="{{_computeChannelImageStyle(_channel.thumbnail)}}">
+ <span id="channel-name">{{_channel.name}}</span>
+
+ <google-signin
+ client-id="{{clientId}}"
+ scopes="https://www.googleapis.com/auth/youtube.upload https://www.googleapis.com/auth/youtube.readonly">
+ </google-signin>
+ </div>
+
+ <div style="_computeUploadDivStyle(authenticated)}}">
+ <input type="file" id="file" class="button" accept="video/*" on-change="_handleFileChanged">
+
+ <button on-click="_handleUploadClicked" style$="{{_computeUploadButtonStyle(auto}}" disabled="{{!_selectedFile}}">Upload Video</button>
+
+ <p id="disclaimer">By uploading a video, you certify that you own all rights to the content or that you are authorized by the owner to make the content publicly available on YouTube, and that it otherwise complies with the YouTube Terms of Service located at <a href="http://www.youtube.com/t/terms" target="_blank">http://www.youtube.com/t/terms</a></p>
+ </div>
+ </template>
+</dom-module>
+<script>
+ (function() {
+ // One minute.
+ var STATUS_POLLING_ITERVAL_MILLIS = 60 * 1000;
+
+ Polymer( {
+
+ is: 'google-youtube-upload',
+ /**
+ * Fired when the upload begins.
+ *
+ * `e.detail` is set to the
+ * [file](https://developer.mozilla.org/en-US/docs/Web/API/File)
+ * being uploaded.
+ *
+ * @event youtube-upload-start
+ * @param {Object} e Event parameters.
+ */
+
+ /**
+ * Fired while the upload is in progress.
+ *
+ * `e.detail.progressEvent` is set to the corresponding
+ * [XMLHttpRequestProgressEvent](http://www.w3.org/TR/progress-events/).
+ *
+ * `e.detail.estimatedSecondsRemaining` is set to an estimate of the time remaining
+ * in the upload, based on the average upload speed so far.
+ *
+ * `e.detail.bytesPerSecond` is set to the average number of bytes sent per second
+ * sent so far.
+ *
+ * `e.fractionComplete` is set to the fraction of the upload that's complete, in the range [0, 1].
+ *
+ * @event youtube-upload-progress
+ * @param {Object} e Event parameters.
+ */
+
+ /**
+ * Fired when YouTube upload has failed.
+ *
+ * Since the actual upload failed, it's not possible for the YouTube server to attempt to
+ * process the video, and no `youtube-processing-poll` events will be fired.
+ *
+ * `e.detail` is set to a string explaining what went wrong.
+ *
+ * @event youtube-upload-fail
+ * @param {Object} e Event parameters
+ */
+
+ /**
+ * Fired when video upload has completed, and YouTube has begun processing the video.
+ *
+ * At this point, the video is not yet playable, and there is no guarantee that
+ * the server-side YouTube processing will succeed.
+ *
+ * One or more `youtube-processing-poll` events will then be fired after this event,
+ * followed by either a `youtube-processing-complete` or `youtube-processing-fail`.
+ *
+ * `e.detail` is set to the YouTube video id of the video.
+ *
+ * @event youtube-upload-complete
+ * @param {Object} e Event parameters.
+ */
+
+ /**
+ * Fired while server-side processing is in progress.
+ *
+ * Server-side processing can take an
+ * [unpredictable amount of time](https://support.google.com/youtube/answer/71674?hl=en&ref_topic=2888603),
+ * and these events will be periodically fired each time the processing status is polled.
+ *
+ * `e.detail` is set to a
+ * [status](https://developers.google.com/youtube/v3/docs/videos#status)
+ * object.
+ *
+ * @event youtube-processing-poll
+ * @param {Object} e Event parameters
+ */
+
+ /**
+ * Fired when server-side processing is successful and the video is
+ * available for playback on YouTube.
+ *
+ * The video can be played at `https://youtu.be/VIDEO_ID` and can be
+ * embedded using the
+ * [`google-youtube`](https://github.com/GoogleWebComponents/google-youtube) element.
+ *
+ * `e.detail` is set to the YouTube video id of the video.
+ *
+ * @event youtube-processing-complete
+ * @param {Object} e Event parameters
+ */
+
+ /**
+ * Fired when the video
+ * [failed transcoding](https://support.google.com/youtube/topic/2888603?hl=en&ref_topic=16547)
+ * and can't be played on YouTube.
+ *
+ * `e.detail` is set to a
+ * [status](https://developers.google.com/youtube/v3/docs/videos#status)
+ * object which has more details about the failure.
+ *
+ * @event youtube-processing-fail
+ * @param {Object} e Event parameters
+ */
+ properties: {
+ /**
+ * An OAuth 2 clientId reference, obtained from the
+ * [Google Developers Console](https://console.developers.google.com).
+ *
+ * Follow
+ * [the steps](https://developers.google.com/console/help/new/#generatingoauth2)
+ * for registering for OAuth 2, ensure that the
+ * [YouTube Data API v3](https://developers.google.com/youtube/registering_an_application)
+ * is enabled for your API project, and ensure that the JavaScript Origin
+ * is set to the domain hosting the page on which
+ * you'll be using this element.
+ *
+ * @attribute clientId
+ * @type string
+ * @default ''
+ */
+ clientId: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * Whether files should be automatically uploaded.
+ *
+ * @attribute auto
+ * @type boolean
+ * @default false
+ */
+ auto: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Whether the user has authenticated or not.
+ *
+ * @attribute authenticated
+ * @type boolean
+ */
+ authenticated: {
+ type: Boolean,
+ value: false,
+ readOnly: true
+ },
+
+ /**
+ * The title for the new YouTube video.
+ *
+ * @attribute videoTitle
+ * @type string
+ * @default 'Untitled Video'
+ */
+ videoTitle: {
+ type: String,
+ value: 'Untitled Video'
+ },
+
+ /**
+ * The description for the new YouTube video.
+ *
+ * @attribute description
+ * @type string
+ * @default 'Uploaded via a web component! Check out https://github.com/GoogleWebComponents/google-youtube-upload'
+ */
+ description: {
+ type: String,
+ value: 'Uploaded via a web component! Check out https://github.com/GoogleWebComponents/google-youtube-upload'
+ },
+
+ /**
+ * The array of tags for the new YouTube video.
+ *
+ * @attribute tags
+ * @type Array.<string>
+ * @default ['google-youtube-upload']
+ */
+ tags: {
+ type: Array,
+ value: function() { return ['google-youtube-upload']}
+ },
+
+ /**
+ * The numeric YouTube
+ * [cateogry id](https://developers.google.com/apis-explorer/#p/youtube/v3/youtube.videoCategories.list?part=snippet®ionCode=us).
+ *
+ * @attribute categoryId
+ * @type number
+ * @default 22
+ */
+ categoryId: {
+ type: Number,
+ value: 22
+ },
+
+ /**
+ * The [privacy setting](https://support.google.com/youtube/answer/157177?hl=en)
+ * for the new video.
+ *
+ * Valid values are 'public', 'private', and 'unlisted'.
+ *
+ * @attribute privacyStatus
+ * @type string
+ * @default 'public'
+ */
+ privacyStatus: {
+ type: String,
+ value: 'public'
+ },
+
+ /**
+ * The id of the new video.
+ *
+ * This is set as soon as a `youtube-upload-complete` event is fired.
+ *
+ * @attribute videoId
+ * @type string
+ * @default ''
+ */
+ videoId: {
+ type: String,
+ value: '',
+ readOnly: true,
+ notify: true
+ },
+
+ _channel: {
+ type: Object,
+ value: function() { return {
+ name: 'Not Logged In',
+ thumbnail: ''
+ };}
+ },
+ _selectedFile: {
+ type: Object,
+ value: null
+ }
+ },
+
+ _uploadStartTime: 0,
+
+ ready: function() {
+ document.addEventListener('google-signin-success', function(e) {
+
+ this.accessToken = gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().access_token;
+ this._setAuthenticated(true);
+ this._loadChannels();
+ }.bind(this));
+
+ document.addEventListener('google-signed-out', function(e) {
+ this._setAuthenticated(false);
+ this._loadChannelRequested = false;
+ this.set('_channel.name', 'Not Logged In');
+ this.set('_channel.thumbnail', '');
+ }.bind(this));
+ },
+
+ _clientLoaded: function() {
+ this._loadChannels();
+ },
+
+ _loadChannels: function() {
+ if (gapi && gapi.client && this.authenticated && !this._loadChannelRequested) {
+ this._loadChannelRequested = true;
+ gapi.client.request({
+ path: '/youtube/v3/channels',
+ params: {
+ part: 'snippet',
+ mine: true
+ },
+ callback: function(response) {
+ if (response.error) {
+ this.fire('youtube-upload-fail', response.error.message);
+ } else {
+ this.set('_channel.name', response.items[0].snippet.title);
+ this.set('_channel.thumbnail', response.items[0].snippet.thumbnails.default.url);
+ }
+ }.bind(this)
+ });
+ }
+ },
+ _computeChannelImageStyle: function(thumbnail) {
+ return 'display:' + (thumbnail ? 'inline' : 'none');
+ },
+
+ _computeUploadDivStyle: function(authenticated) {
+ return 'display:' + (authenticated ? 'block' : 'none');
+ },
+ _computeUploadButtonStyle: function(auto) {
+ return 'display:' + (auto ? 'none' : 'block');
+ },
+ /**
+ * Uploads a video file to YouTube.
+ *
+ * `this.accessToken` must already be set to a valid OAuth 2 access token.
+ *
+ * @method uploadFile
+ * @param {object} file File object corresponding to the video to upload.
+ */
+ uploadFile: function(file) {
+ var metadata = {
+ snippet: {
+ title: this.videoTitle,
+ description: this.description,
+ tags: this.tags,
+ categoryId: this.categoryId
+ },
+ status: {
+ privacyStatus: this.privacyStatus
+ }
+ };
+
+ var uploader = new MediaUploader({
+ baseUrl: 'https://www.googleapis.com/upload/youtube/v3/videos',
+ file: file,
+ token: this.accessToken,
+ metadata: metadata,
+ params: {
+ part: Object.keys(metadata).join(',')
+ },
+ onError: function(data) {
+ var message = data;
+
+ // Assuming the error is raised by the YouTube API, data will be
+ // a JSON string with error.message set. I am not 100% sure that's the
+ // only time onError will be raised, though.
+ try {
+ var errorResponse = JSON.parse(data);
+ message = errorResponse.error.message;
+ } finally {
+ this.fire('youtube-upload-fail', message);
+ }
+ }.bind(this),
+ onProgress: function(data) {
+ var currentTime = Date.now();
+ var bytesUploaded = data.loaded;
+ var totalBytes = data.total;
+
+ // The times are in millis, so we need to divide by 1000 to get seconds.
+ var bytesPerSecond = bytesUploaded / ((currentTime - this._uploadStartTime) / 1000);
+ var estimatedSecondsRemaining = (totalBytes - bytesUploaded) / bytesPerSecond;
+ var fractionComplete = bytesUploaded / totalBytes;
+
+ this.fire('youtube-upload-progress', {
+ progressEvent: data,
+ bytesPerSecond: bytesPerSecond,
+ estimatedSecondsRemaining: estimatedSecondsRemaining,
+ fractionComplete: fractionComplete
+ });
+ }.bind(this),
+ onComplete: function(data) {
+ var uploadResponse = JSON.parse(data);
+ this.fire('youtube-upload-complete', uploadResponse.id);
+ this._setVideoId(uploadResponse.id);
+
+ this._pollForVideoStatus();
+ }.bind(this)
+ });
+
+ this.fire('youtube-upload-start', file);
+ // This won't correspond to the *exact* start of the upload, but it should be close enough.
+ this._uploadStartTime = Date.now();
+ uploader.upload();
+ },
+
+ _handleFileChanged: function() {
+ this._selectedFile = this.$.file.files[0];
+
+ if (this.auto) {
+ this.uploadFile(this._selectedFile);
+ }
+ },
+
+ _handleUploadClicked: function() {
+ this.uploadFile(this._selectedFile);
+ },
+
+ _pollForVideoStatus: function() {
+ gapi.client.request({
+ path: '/youtube/v3/videos',
+ params: {
+ part: 'status',
+ id: this.videoId
+ },
+ callback: function(response) {
+ if (response.error) {
+ // Not exactly sure how to handle this one, since it means the status polling failed.
+ setTimeout(this._pollForVideoStatus.bind(this), STATUS_POLLING_ITERVAL_MILLIS);
+ } else {
+ var status = response.items[0].status;
+
+ switch (status.uploadStatus) {
+ // This is a non-final status, so we need to poll again.
+ case 'uploaded':
+ this.fire('youtube-processing-poll', status);
+ setTimeout(this._pollForVideoStatus.bind(this), STATUS_POLLING_ITERVAL_MILLIS);
+ break;
+
+ // The video was successfully transcoded and is available.
+ case 'processed':
+ this.fire('youtube-processing-complete', this.videoId);
+ break;
+
+ // All other statuses indicate a permanent transcoding failure.
+ default:
+ this.fire('youtube-processing-fail', status);
+ break;
+ }
+ }
+ }.bind(this)
+ });
+ }
+ });
+ })();
+</script>
diff --git a/polymer_1.0.4/bower_components/google-youtube-upload/index.html b/polymer_1.0.4/bower_components/google-youtube-upload/index.html
new file mode 100755
index 0000000..203f4fa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube-upload/index.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-youtube/.bower.json b/polymer_1.0.4/bower_components/google-youtube/.bower.json
new file mode 100644
index 0000000..858f5b4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube/.bower.json
@@ -0,0 +1,40 @@
+{
+ "name": "google-youtube",
+ "description": "YouTube video playback web component.",
+ "homepage": "https://googlewebcomponents.github.io/google-youtube",
+ "main": "google-youtube.html",
+ "version": "1.1.1",
+ "authors": [
+ "Jeff Posnick <jeffy@google.com>"
+ ],
+ "license": "Apache-2.0",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "google",
+ "youtube",
+ "polymer",
+ "web-components",
+ "web-component"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0",
+ "iron-localstorage": "PolymerElements/iron-localstorage#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
+ },
+ "_release": "1.1.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.1.1",
+ "commit": "8bc83a19b9b48335e408a59230a47eadce60a15e"
+ },
+ "_source": "git://github.com/GoogleWebComponents/google-youtube.git",
+ "_target": "^1.1.0",
+ "_originalSource": "GoogleWebComponents/google-youtube"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-youtube/LICENSE b/polymer_1.0.4/bower_components/google-youtube/LICENSE
new file mode 100644
index 0000000..377eaa0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2014 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-youtube/README.md b/polymer_1.0.4/bower_components/google-youtube/README.md
new file mode 100755
index 0000000..b1c3b76
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube/README.md
@@ -0,0 +1,4 @@
+google-youtube
+=====================
+
+See the [component landing page](https://googlewebcomponents.github.io/google-youtube) for more information.
diff --git a/polymer_1.0.4/bower_components/google-youtube/bower.json b/polymer_1.0.4/bower_components/google-youtube/bower.json
new file mode 100755
index 0000000..71aab92
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube/bower.json
@@ -0,0 +1,31 @@
+{
+ "name": "google-youtube",
+ "description": "YouTube video playback web component.",
+ "homepage": "https://googlewebcomponents.github.io/google-youtube",
+ "main": "google-youtube.html",
+ "version": "1.1.1",
+ "authors": [
+ "Jeff Posnick <jeffy@google.com>"
+ ],
+ "license": "Apache-2.0",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "keywords": [
+ "google",
+ "youtube",
+ "polymer",
+ "web-components",
+ "web-component"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "google-apis": "GoogleWebComponents/google-apis#^1.0.0",
+ "iron-localstorage": "PolymerElements/iron-localstorage#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/google-youtube/demo/demo.elements.html b/polymer_1.0.4/bower_components/google-youtube/demo/demo.elements.html
new file mode 100644
index 0000000..0820c23
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube/demo/demo.elements.html
@@ -0,0 +1,108 @@
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../google-youtube.html">
+
+
+<dom-module id="demo-element">
+ <template id="page-template">
+ <style>
+ div {
+ margin-bottom: 1em;
+ }
+ </style>
+ <h1><code><google-youtube></code> Demo</h1>
+ <h3>Full API Demo</h3>
+ <google-youtube id="googleYouTube"
+ playsupported="{{playSupported}}"
+ video-id="mN7IAaRdi_k"
+ state="{{state}}"
+ currenttime="{{currentTime}}"
+ currenttimeformatted="{{currentTimeFormatted}}"
+ duration="{{duration}}"
+ durationformatted="{{durationFormatted}}"
+ fractionloaded="{{fractionLoaded}}"
+ on-google-youtube-state-change="handleStateChange"
+ on-google-youtube-error="handleYouTubeError">
+ </google-youtube>
+
+ <div>
+ <p>Playback Progress: <span>{{currentTimeFormatted}}</span> / <span>{{durationFormatted}}</span> <progress max="1" value="{{computeProgress(currentTime, duration)}}"></progress></p>
+ </div>
+
+ <div>
+ <button id="play-video"
+ disabled="{{computePlayDisabled(state, playSupported)}}"
+ on-click="handlePlayVideo"
+ >Play</button>
+ <button id="pause-video"
+ disabled="{{computePauseDisabled(state)}}"
+ on-click="handlePauseVideo"
+ >Pause</button>
+ </div>
+
+ <div>
+ <label for="videoId">Video ID:</label>
+ <input id="videoId" value="M7lc1UVf-VE">
+ <button id="cue-video" on-click="handleCueVideo">Cue</button>
+ </div>
+
+ <div>
+ <p>Player Events:</p>
+ <ol>
+ <template is="dom-repeat" items="{{events}}">
+ <li>State change: <span>{{item.data}}</span></li>
+ </template>
+ </ol>
+ </div>
+
+ <h3>Custom Thumbnail Demo</h3>
+ <google-youtube video-id="yRbOSdAe_JU"
+ width="853px"
+ height="480px"
+ thumbnail="//www.polymer-project.org/images/logos/p-logo.svg">
+ </google-youtube>
+ </template>
+</dom-module>
+<script>
+ Polymer({
+ is: 'demo-element',
+ properties: {
+ playSupported: String,
+ state: String,
+ currentTime: Number,
+ currentTimeFormatted: String,
+ duration: Number,
+ durationFormatted: String,
+ fractionLoaded: Number,
+ events: {
+ type: Array,
+ value: []
+ }
+ },
+ computeProgress: function(currentTime, duration) {
+ return currentTime / duration;
+ },
+ computePlayDisabled: function(state, playSupported) {
+ return state == 1 || state == 3 || !playSupported;
+ },
+ computePauseDisabled: function(state) {
+ return state != 1 && state != 3;
+ },
+ handleStateChange: function(ev) {
+ this.events.push({data: ev.detail.data});
+ },
+ handleYouTubeError: function(ev) {
+ console.error('YouTube playback error', ev.detail);
+ },
+ handlePlayVideo: function(ev) {
+ this.$.googleYouTube.play();
+ },
+ handlePauseVideo: function(ev) {
+ this.$.googleYouTube.pause();
+ },
+ handleCueVideo: function(ev) {
+ this.$.googleYouTube.videoid = this.$.videoId.value;
+ }
+ });
+
+</script>
+
diff --git a/polymer_1.0.4/bower_components/google-youtube/demo/index.html b/polymer_1.0.4/bower_components/google-youtube/demo/index.html
new file mode 100755
index 0000000..be47bf3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube/demo/index.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title><google-youtube> Demo</title>
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <link rel="import" href="demo.elements.html">
+
+ <style>
+ body {
+ font-family: sans-serif;
+ background: rgba(204, 204, 204, 0.31);
+ }
+ </style>
+ </head>
+
+ <body>
+ <demo-element></demo-element>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-youtube/google-youtube.html b/polymer_1.0.4/bower_components/google-youtube/google-youtube.html
new file mode 100755
index 0000000..ae51698
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube/google-youtube.html
@@ -0,0 +1,659 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at https://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at https://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at https://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at https://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-localstorage/iron-localstorage.html">
+<link rel="import" href="../google-apis/google-youtube-api.html">
+
+<!--
+`google-youtube` encapsulates the YouTube player into a web component.
+
+ <google-youtube
+ video-id="..."
+ height="270px"
+ width="480px"
+ rel="0"
+ start="5"
+ autoplay="1">
+ </google-youtube>
+
+`google-youtube` supports all of the [embedded player parameters](https://developers.google.com/youtube/player_parameters). Each can be set as an attribute on `google-youtube`.
+
+The standard set of [YouTube player events](https://developers.google.com/youtube/iframe_api_reference#Events) are exposed, as well as methods for playing, pausing, seeking to a specific time, and loading a new video.
+
+@demo
+-->
+<dom-module id="google-youtube">
+ <template>
+ <style>
+ :host {
+ display: block;
+ }
+
+ :host([fluid]) {
+ width: 100%;
+ max-width: 100%;
+ position: relative;
+ }
+
+ :host([fluid]) iframe,
+ :host([fluid]) #thumbnail {
+ vertical-align: bottom;
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 100%;
+ }
+
+ #container {
+ max-width: 100%;
+ max-height: 100%;
+ }
+
+ #thumbnail {
+ width: 100%;
+ height: 100%;
+ cursor: pointer;
+ }
+
+ /* Some browsers will refuse to play videos with 'display: none' set, so position the video well offscreen instead. */
+ #playtest {
+ position: absolute;
+ top: -9999px;
+ left: -9999px;
+ }
+ </style>
+
+ <div id="container" style$="{{_computeContainerStyle(width, height)}}">
+ <template is="dom-if" if="{{thumbnail}}">
+ <img id="thumbnail"
+ src$="{{thumbnail}}"
+ title="YouTube video thumbnail."
+ alt="YouTube video thumbnail."
+ on-tap="_handleThumbnailTap">
+ </template>
+
+ <template is="dom-if" if="{{!thumbnail}}">
+ <google-youtube-api on-api-load="_apiLoad"></google-youtube-api>
+ </template>
+
+ <!-- Use this._playsupportedLocalStorage as the value, since this.playsupported is set to
+ true as soon as initial playback has started, and we don't want that cached. -->
+ <iron-localstorage name="google-youtube-playsupported"
+ value="_playsupportedLocalStorage"
+ on-iron-localstorage-load="_determinePlaySupported">
+ </iron-localstorage>
+
+ <div id="player"></div>
+ </div>
+ </template>
+</dom-module>
+
+<script>
+ Polymer({
+ is: 'google-youtube',
+ /**
+ * Fired when the YouTube player is fully initialized and ready for use.
+ *
+ * @event google-youtube-ready
+ */
+
+ /**
+ * Fired when the state of the player changes. `e.detail.data` is set to one of
+ * [the documented](https://developers.google.com/youtube/iframe_api_reference#onStateChange)
+ * states.
+ *
+ * @event google-youtube-state-change
+ * @param {Object} e Event parameters.
+ */
+
+ /**
+ * Fired when playback fails due to an error. `e.detail.data` is set to one of
+ * [the documented](https://developers.google.com/youtube/iframe_api_reference#onError)
+ * error codes.
+ *
+ * @event google-youtube-error
+ * @param {Object} e Event parameters.
+ */
+
+ properties: {
+ /**
+ * Sets the id of the video to play. Changing this attribute will trigger a call
+ * to load a new video into the player (if `this.autoplay` is set to `1` and `playsupported` is true)
+ * or cue a new video otherwise.
+ *
+ * You can [search for videos programmatically](https://developers.google.com/youtube/v3/docs/search/list)
+ * using the YouTube Data API, or just hardcode known video ids to display on your page.
+ */
+ videoId: {
+ type: String,
+ value: 'mN7IAaRdi_k',
+ observer: '_videoIdChanged'
+ },
+
+ /**
+ * Whether programmatic `<video>.play()` for initial playback is supported in the current browser.
+ *
+ * Most mobile browsers [do not support](https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html#//apple_ref/doc/uid/TP40009523-CH5-SW1) autoplaying or scripted playback of videos.
+ * If you attempt to automatically initiate playback of a `<google-youtube>`, e.g. by calling the `play()` method before
+ * playback has initially begun, the YouTube Player will enter an unrecoverable "stuck" state.
+ * To protect against this, check the value of `playsupported` and don't call `play()` if it is set to `false`.
+ * (You can hide/disable your custom play button, etc.)
+ *
+ * The `playsupported` value is determined at runtime, by dynamically creating a `<video>` element with an
+ * inlined data source and calling `play()` on it. (Inspired by [Modernizr](https://github.com/Modernizr/Modernizr/blob/master/feature-detects/video/autoplay.js).)
+ *
+ * If you would rather not incur the minimal overhead involved in going through this process, you can explicitly set
+ * `playsupported` to `true` or `false` when initializing `<google-youtube>`. This is only recommended if you know that
+ * your web app will never (or only) be used on mobile browsers.
+ */
+ playsupported: {
+ type: Boolean,
+ value: null,
+ notify: true
+ },
+
+ /**
+ * "1" if video should start automatically
+ */
+ autoplay: {
+ type: Number,
+ value: 0
+ },
+ /**
+ * Whether playback has started.
+ *
+ * This defaults to `false` and is set to `true` once the first 'playing' event is fired by
+ * the underlying YouTube Player API.
+ *
+ * Once set to `true`, it will remain that way indefinitely.
+ * Paused/buffering/ended events won't cause `playbackstarted` to reset to `false`.
+ * Nor will loading a new video into the player.
+ */
+ playbackstarted: {
+ type: Boolean,
+ value: false,
+ notify: true
+ },
+
+ /**
+ * Sets the height of the player on the page.
+ * Accepts anything valid for a CSS measurement, e.g. '200px' or '50%'.
+ * If the unit of measurement is left off, 'px' is assumed.
+ */
+ height: {
+ type: String,
+ value: '270px'
+ },
+
+ /**
+ * Sets the width of the player on the page.
+ * Accepts anything valid for a CSS measurement, e.g. '200px' or '50%'.
+ * If the unit of measurement is left off, 'px' is assumed.
+ */
+ width: {
+ type: String,
+ value:'480px'
+ },
+
+ /**
+ * Exposes the current player state.
+ * Using this attribute is an alternative to listening to `google-youtube-state-change` events,
+ * and can simplify the logic in templates with conditional binding.
+ *
+ * The [possible values](https://developers.google.com/youtube/iframe_api_reference#onStateChange):
+ * - -1 (unstarted)
+ * - 0 (ended)
+ * - 1 (playing)
+ * - 2 (paused)
+ * - 3 (buffering)
+ * - 5 (video cued)
+ */
+ state: {
+ type: Number,
+ value: -1,
+ notify: true
+ },
+
+ /**
+ * Exposes the current playback time, in seconds.
+ *
+ * You can divide this value by the `duration` to determine the playback percentage.
+ */
+ currenttime: {
+ type: Number,
+ value: 0,
+ notify: true
+ },
+
+ /**
+ * Exposes the video duration, in seconds.
+ *
+ * You can divide the `currenttime` to determine the playback percentage.
+ *
+ * @attribute duration
+ * @type number
+ */
+ duration: {
+ type: Number,
+ value: 1, // To avoid divide-by-zero errors if used before video is cued.
+ notify: true
+ },
+
+ /**
+ * Exposes the current playback time, formatted as a (HH:)MM:SS string.
+ */
+ currenttimeformatted: {
+ type: String,
+ value: '0:00',
+ notify: true
+ },
+
+ /**
+ * Exposes the video duration, formatted as a (HH:)MM:SS string.
+ */
+ durationformatted: {
+ type: String,
+ value: '0:00', // To avoid divide-by-zero errors if used before video is cued.
+ notify: true
+ },
+
+ /**
+ * The fraction of the bytes that have been loaded for the current video, in the range [0-1].
+ */
+ fractionloaded: {
+ type: Number,
+ value: 0,
+ notify: true
+ },
+
+ /**
+ * A shorthand to enable a set of player attributes that, used together, simulate a "chromeless" YouTube player.
+ *
+ * Equivalent to setting the following attributes:
+ * - `controls="0"`
+ * - `modestbranding="1"`
+ * - `showinfo="0"`
+ * - `iv_load_policy="3"`
+ * - `rel="0"`
+ *
+ * The "chromeless" player has minimal YouTube branding in cued state, and the native controls
+ * will be disabled during playback. Creating your own custom play/pause/etc. controls is recommended.
+ */
+ chromeless: {
+ type: Boolean,
+ value: false
+ },
+ /**
+ * The URL of an image to use as a custom thumbnail.
+ *
+ * This is optional; if not provided, the standard YouTube embed (which uses the thumbnail associated
+ * with the video on YouTube) will be used.
+ *
+ * If `thumbnail` is set, than an `<img>` containing the thumbnail will be used in lieu of the actual
+ * YouTube embed. When the thumbnail is clicked, the `<img>` is swapped out for the actual YouTube embed,
+ * which will have [`autoplay=1`](https://developers.google.com/youtube/player_parameters#autoplay) set by default (in additional to any other player parameters specified on this element).
+ *
+ * Please note that `autoplay=1` won't actually autoplay videos on mobile browsers, so two taps will be required
+ * to play the video there. Also, on desktop browsers, setting `autoplay=1` will prevent the playback
+ * from [incrementing the view count](https://support.google.com/youtube/answer/1714329) for the video.
+ */
+ thumbnail: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * If `fluid` is set, then the player will set its width to 100% to fill
+ * the parent container, while adding `padding-top` to preserve the
+ * aspect ratio provided by `width` and `height`. If `width` and `height`
+ * have not been set, the player will fall back to a 16:9 aspect ratio.
+ * This is useful for responsive designs where you don't want to
+ * introduce letterboxing on your video.
+ */
+ fluid: {
+ type: Boolean,
+ value: false
+ }
+
+ },
+
+ _computeContainerStyle: function(width, height) {
+ return 'width:' + width + '; height:' + height;
+ },
+ /**
+ * Detects whether programmatic <video>.play() is supported in the current browser.
+ *
+ * This is triggered via on-ironlocalstorage-load. The logic is:
+ * - If playsupported is explicitly set to true or false on the element, use that.
+ * - Otherwise, if there's a cached value in localStorage, use that.
+ * - Otherwise, create a hidden <video> element and call play() on it:
+ * - If playback starts, playsupported is true.
+ * - If playback doesn't start (within 500ms), playsupported is false.
+ * - Whatever happens, cache the result in localStorage.
+ */
+ _determinePlaySupported: function() {
+ // If playsupported isn't already being overridden by the page using this component, then attempt
+ // to determine if it's supported.
+ // This is deliberately checking with ==, to match either undefined or null.
+ if (this.playsupported == null) {
+ // If we don't have the results of a previous test cached in localStorage, then run a new playback test.
+ if (this._playsupportedLocalStorage == null) {
+ var timeout;
+ var videoElement = document.createElement('video');
+
+ if ('play' in videoElement) {
+ videoElement.id = 'playtest';
+
+ var mp4Source = document.createElement('source');
+ mp4Source.src = "data:video/mp4;base64,AAAAFGZ0eXBNU05WAAACAE1TTlYAAAOUbW9vdgAAAGxtdmhkAAAAAM9ghv7PYIb+AAACWAAACu8AAQAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAnh0cmFrAAAAXHRraGQAAAAHz2CG/s9ghv4AAAABAAAAAAAACu8AAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAFAAAAA4AAAAAAHgbWRpYQAAACBtZGhkAAAAAM9ghv7PYIb+AAALuAAANq8AAAAAAAAAIWhkbHIAAAAAbWhscnZpZGVBVlMgAAAAAAABAB4AAAABl21pbmYAAAAUdm1oZAAAAAAAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAVdzdGJsAAAAp3N0c2QAAAAAAAAAAQAAAJdhdmMxAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAFAAOABIAAAASAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGP//AAAAEmNvbHJuY2xjAAEAAQABAAAAL2F2Y0MBTUAz/+EAGGdNQDOadCk/LgIgAAADACAAAAMA0eMGVAEABGjuPIAAAAAYc3R0cwAAAAAAAAABAAAADgAAA+gAAAAUc3RzcwAAAAAAAAABAAAAAQAAABxzdHNjAAAAAAAAAAEAAAABAAAADgAAAAEAAABMc3RzegAAAAAAAAAAAAAADgAAAE8AAAAOAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAADQAAAA4AAAAOAAAAFHN0Y28AAAAAAAAAAQAAA7AAAAA0dXVpZFVTTVQh0k/Ou4hpXPrJx0AAAAAcTVREVAABABIAAAAKVcQAAAAAAAEAAAAAAAAAqHV1aWRVU01UIdJPzruIaVz6ycdAAAAAkE1URFQABAAMAAAAC1XEAAACHAAeAAAABBXHAAEAQQBWAFMAIABNAGUAZABpAGEAAAAqAAAAASoOAAEAZABlAHQAZQBjAHQAXwBhAHUAdABvAHAAbABhAHkAAAAyAAAAA1XEAAEAMgAwADAANQBtAGUALwAwADcALwAwADYAMAA2ACAAMwA6ADUAOgAwAAABA21kYXQAAAAYZ01AM5p0KT8uAiAAAAMAIAAAAwDR4wZUAAAABGjuPIAAAAAnZYiAIAAR//eBLT+oL1eA2Nlb/edvwWZflzEVLlhlXtJvSAEGRA3ZAAAACkGaAQCyJ/8AFBAAAAAJQZoCATP/AOmBAAAACUGaAwGz/wDpgAAAAAlBmgQCM/8A6YEAAAAJQZoFArP/AOmBAAAACUGaBgMz/wDpgQAAAAlBmgcDs/8A6YEAAAAJQZoIBDP/AOmAAAAACUGaCQSz/wDpgAAAAAlBmgoFM/8A6YEAAAAJQZoLBbP/AOmAAAAACkGaDAYyJ/8AFBAAAAAKQZoNBrIv/4cMeQ==";
+ videoElement.appendChild(mp4Source);
+
+ var webmSource = document.createElement('source');
+ webmSource.src = "data:video/webm;base64,GkXfo49CgoR3ZWJtQoeBAUKFgQEYU4BnAQAAAAAAF60RTZt0vE27jFOrhBVJqWZTrIIQA027jFOrhBZUrmtTrIIQbE27jFOrhBFNm3RTrIIXmU27jFOrhBxTu2tTrIIWs+xPvwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFUmpZuQq17GDD0JATYCjbGliZWJtbCB2MC43LjcgKyBsaWJtYXRyb3NrYSB2MC44LjFXQY9BVlNNYXRyb3NrYUZpbGVEiYRFnEAARGGIBc2Lz1QNtgBzpJCy3XZ0KNuKNZS4+fDpFxzUFlSua9iu1teBAXPFhL4G+bmDgQG5gQGIgQFVqoEAnIEAbeeBASMxT4Q/gAAAVe6BAIaFVl9WUDiqgQEj44OEE95DVSK1nIN1bmTgkbCBULqBPJqBAFSwgVBUuoE87EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB9DtnVB4eeBAKC4obaBAAAAkAMAnQEqUAA8AABHCIWFiIWEiAICAAamYnoOC6cfJa8f5Zvda4D+/7YOf//nNefQYACgnKGWgQFNANEBAAEQEAAYABhYL/QACIhgAPuC/rOgnKGWgQKbANEBAAEQEAAYABhYL/QACIhgAPuC/rKgnKGWgQPoANEBAAEQEAAYABhYL/QACIhgAPuC/rOgnKGWgQU1ANEBAAEQEAAYABhYL/QACIhgAPuC/rOgnKGWgQaDANEBAAEQEAAYABhYL/QACIhgAPuC/rKgnKGWgQfQANEBAAEQEAAYABhYL/QACIhgAPuC/rOgnKGWgQkdANEBAAEQEBRgAGFgv9AAIiGAAPuC/rOgnKGWgQprANEBAAEQEAAYABhYL/QACIhgAPuC/rKgnKGWgQu4ANEBAAEQEAAYABhYL/QACIhgAPuC/rOgnKGWgQ0FANEBAAEQEAAYABhYL/QACIhgAPuC/rOgnKGWgQ5TANEBAAEQEAAYABhYL/QACIhgAPuC/rKgnKGWgQ+gANEBAAEQEAAYABhYL/QACIhgAPuC/rOgnKGWgRDtANEBAAEQEAAYABhYL/QACIhgAPuC/rOgnKGWgRI7ANEBAAEQEAAYABhYL/QACIhgAPuC/rIcU7trQOC7jLOBALeH94EB8YIUzLuNs4IBTbeH94EB8YIUzLuNs4ICm7eH94EB8YIUzLuNs4ID6LeH94EB8YIUzLuNs4IFNbeH94EB8YIUzLuNs4IGg7eH94EB8YIUzLuNs4IH0LeH94EB8YIUzLuNs4IJHbeH94EB8YIUzLuNs4IKa7eH94EB8YIUzLuNs4ILuLeH94EB8YIUzLuNs4INBbeH94EB8YIUzLuNs4IOU7eH94EB8YIUzLuNs4IPoLeH94EB8YIUzLuNs4IQ7beH94EB8YIUzLuNs4ISO7eH94EB8YIUzBFNm3SPTbuMU6uEH0O2dVOsghTM";
+ videoElement.appendChild(webmSource);
+
+ document.body.appendChild(videoElement);
+
+ this.async(function() {
+ // Ideally, we'll get a 'playing' event if we're on a browser that supports programmatic play().
+ videoElement.onplaying = function(e) {
+ clearTimeout(timeout);
+
+ this.playsupported = (e && e.type === 'playing') || videoElement.currentTime !== 0;
+ this._playsupportedLocalStorage = this.playsupported;
+
+ videoElement.onplaying = null;
+
+ document.body.removeChild(videoElement);
+ }.bind(this);
+
+ // If we haven't received a 'playing' event within 500ms, then we're most likely on a browser that doesn't
+ // support programmatic plays. Do a final check after 500ms and set this.playsupported at that point.
+ timeout = setTimeout(videoElement.onplaying, 500);
+
+ // Try to initiate playback...
+ videoElement.play();
+ });
+ } else {
+ // If there's no play() method then we know that it's no supported.
+ this.playsupported = false;
+ this._playsupportedLocalStorage = false;
+ }
+ } else {
+ // If we do have the results of a previous test cached, then just use that.
+ // A browser's support for <video>.play() isn't likely to change.
+ this.playsupported = this._playsupportedLocalStorage;
+ }
+ }
+ },
+
+ /**
+ * Sets fluid width/height.
+ *
+ * If the fluid attribute is set, the aspect ratio of the video will
+ * be inferred (if set in pixels), or assumed to be 16:9. The element
+ * will give itself enough top padding to force the player to use the
+ * correct aspect ratio, even as the screen size changes.
+ *
+ */
+ ready: function() {
+ if (this.hasAttribute('fluid')) {
+ var ratio = parseInt(this.height, 10) / parseInt(this.width, 10);
+ if (isNaN(ratio)) {
+ ratio = 9/16;
+ }
+ ratio *= 100;
+ this.width = '100%';
+ this.height = 'auto';
+ this.style['padding-top'] = ratio + '%';
+ }
+ },
+
+ /**
+ * Clean up the underlying Player `<iframe>` when we're removed from the DOM.
+ */
+ detached: function() {
+ if (this._player) {
+ this._player.destroy();
+ }
+ },
+
+ /**
+ * Plays the current video.
+ *
+ * Note that on certain mobile browsers, playback
+ * [can't be initiated programmatically](https://developers.google.com/youtube/iframe_api_reference#Mobile_considerations).
+ *
+ * If `this.playsupported` is not `true`, calling `play()` will have no effect.
+ *
+ * @method play
+ */
+ play: function() {
+ if (this._player && this._player.playVideo && this.playsupported) {
+ this._player.playVideo();
+ }
+ },
+
+ /**
+ * Modifies the volume of the current video.
+ *
+ * Developers should take care not to break expected user experience by programmatically
+ * modifying the volume on mobile browsers.
+ * Note that the YouTube player, in addition, does not display volume controls in a
+ * mobile environment.
+ *
+ * @method setVolume
+ * @param {number} volume The new volume, an integer between 0 (muted) and 100 (loudest).
+ */
+ setVolume: function(volume) {
+ if (this._player && this._player.setVolume) {
+ this._player.setVolume(volume);
+ }
+ },
+
+ /**
+ * Mutes the current video.
+ *
+ * Developers should take care not to break expected user experience by programmatically
+ * modifying the volume on mobile browsers.
+ * Note that the YouTube player, in addition, does not display volume controls in a
+ * mobile environment.
+ *
+ * @method mute
+ */
+ mute: function() {
+ if (this._player && this._player.mute) {
+ this._player.mute();
+ }
+ },
+
+ /**
+ * Unmutes the current video.
+ *
+ * Developers should take care not to break expected user experience by programmatically
+ * modifying the volume on mobile browsers.
+ * Note that the YouTube player, in addition, does not display volume controls in a
+ * mobile environment.
+ *
+ * @method unMute
+ */
+ unMute: function() {
+ if (this._player && this._player.unMute) {
+ this._player.unMute();
+ }
+ },
+
+ /**
+ * Pauses the current video.
+ *
+ * @method pause
+ */
+ pause: function() {
+ if (this._player && this._player.pauseVideo) {
+ this._player.pauseVideo();
+ }
+ },
+
+ /**
+ * Skips ahead (or back) to the specified number of seconds.
+ *
+ * @method seekTo
+ * @param {number} seconds Number of seconds to seek to.
+ */
+ seekTo: function(seconds) {
+ if (this._player && this._player.seekTo) {
+ this._player.seekTo(seconds, true);
+
+ // Explicitly call _updatePlaybackStats() to ensure that the new playback info is
+ // reflected in the bound attributes.
+ // The 100ms delay is somewhat arbitrary, but the YouTube player does need time to
+ // update its internal state following the call to player.seekTo().
+ this.async(function() {
+ this._updatePlaybackStats();
+ }, null, 100);
+ }
+ },
+
+ _videoIdChanged: function() {
+ this.currenttime = 0;
+ this.currenttimeformatted = this._toHHMMSS(0);
+ this.fractionloaded = 0;
+ this.duration = 1;
+ this.durationformatted = this._toHHMMSS(0);
+
+ if (!this._player || !this._player.cueVideoById) {
+ this._pendingVideoId = this.videoId;
+ } else {
+ // Figure out whether we should cue or load (which will autoplay) the next video.
+ if (this.playsupported && this.attributes['autoplay'] && this.attributes['autoplay'].value == '1') {
+ this._player.loadVideoById(this.videoId);
+ } else {
+ this._player.cueVideoById(this.videoId);
+ }
+ }
+ },
+
+ _player: null,
+ __updatePlaybackStatsInterval: null,
+ _pendingVideoId: '',
+
+ _apiLoad: function() {
+ // Establish some defaults. Attributes set on the google-youtube element
+ // can override defaults, or specify additional player parameters. See
+ // https://developers.google.com/youtube/player_parameters
+ var playerVars = {
+ playsinline: 1,
+ controls: 2,
+ autohide: 1,
+ // This will (intentionally) be overwritten if this.attributes['autoplay'] is set.
+ autoplay: this.autoplay
+ };
+
+ if (this.chromeless) {
+ playerVars.controls = 0;
+ playerVars.modestbranding = 1;
+ playerVars.showinfo = 0;
+ // Disable annotations.
+ playerVars.iv_load_policy = 3;
+ // Disable related videos on the end screen.
+ playerVars.rel = 0;
+ }
+
+ for (var i = 0; i < this.attributes.length; i++) {
+ var attribute = this.attributes[i];
+ playerVars[attribute.nodeName] = attribute.value;
+ }
+
+ this._player = new YT.Player(this.$.player, {
+ videoId: this.videoId,
+ width: '100%',
+ height: '100%',
+ playerVars: playerVars,
+ events: {
+ onReady: function(e) {
+ if (this._pendingVideoId && this._pendingVideoId != this.videoId) {
+ this._player.cueVideoById(this._pendingVideoId);
+ this._pendingVideoId = '';
+ }
+
+ this.fire('google-youtube-ready', e);
+ }.bind(this),
+ onStateChange: function(e) {
+ this.state = e.data;
+
+ // The YouTube Player API only exposes playback data about a video once
+ // playback has begun.
+ if (this.state == 1) {
+ this.playbackstarted = true;
+
+ // After playback has begun, play() can always be used to resume playback if the video is paused.
+ this.playsupported = true;
+
+ this.duration = this._player.getDuration();
+ this.durationformatted = this._toHHMMSS(this.duration);
+
+ if (!this.__updatePlaybackStatsInterval) {
+ this.__updatePlaybackStatsInterval = setInterval(this._updatePlaybackStats.bind(this), 1000);
+ }
+ } else {
+ // We only need to update the stats if the video is playing.
+ if (this.__updatePlaybackStatsInterval) {
+ clearInterval(this.__updatePlaybackStatsInterval);
+ this.__updatePlaybackStatsInterval = null;
+ }
+ }
+
+ this.fire('google-youtube-state-change', e);
+ }.bind(this),
+ onError: function(e) {
+ // Set the player state to 0 ('ended'), since playback will have stopped.
+ this.state = 0;
+
+ this.fire('google-youtube-error', e);
+ }.bind(this)
+ }
+ });
+ },
+
+ _updatePlaybackStats: function() {
+ this.currenttime = Math.round(this._player.getCurrentTime());
+ this.currenttimeformatted = this._toHHMMSS(this.currenttime);
+ this.fractionloaded = this._player.getVideoLoadedFraction();
+ },
+
+ _toHHMMSS: function(totalSeconds) {
+ var hours = Math.floor(totalSeconds / 3600);
+ totalSeconds -= hours * 3600;
+ var minutes = Math.floor(totalSeconds / 60);
+ var seconds = Math.round(totalSeconds - (minutes * 60));
+
+ var hourPortion = '';
+ if (hours > 0) {
+ hourPortion += hours + ':';
+
+ if (minutes < 10) {
+ minutes = '0' + minutes;
+ }
+ }
+
+ if (seconds < 10) {
+ seconds = '0' + seconds;
+ }
+
+ return hourPortion + minutes + ':' + seconds;
+ },
+
+ _handleThumbnailTap: function() {
+ this.autoplay = 1;
+ this.thumbnail = '';
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/google-youtube/index.html b/polymer_1.0.4/bower_components/google-youtube/index.html
new file mode 100755
index 0000000..203f4fa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube/index.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. -->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-youtube/tests/google-youtube-basic.html b/polymer_1.0.4/bower_components/google-youtube/tests/google-youtube-basic.html
new file mode 100644
index 0000000..1bfc25c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube/tests/google-youtube-basic.html
@@ -0,0 +1,69 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>google-youtube Basic Tests</title>
+ <script src="../../platform/platform.js"></script>
+ <link rel="import" href="../../polymer-test-tools/tools.html">
+ <script src="../../polymer-test-tools/htmltest.js"></script>
+ <link rel="import" href="../google-youtube.html">
+ </head>
+ <body>
+ <google-youtube></google-youtube>
+
+ <script>
+ function testToHHMMSS(googleYouTube) {
+ // Durations in seconds and the formatted string that's expected for each.
+ var durationsToFormattedStrings = {
+ 0: '0:00',
+ 1: '0:01',
+ '5.4': '0:05',
+ '5.5': '0:06',
+ 10: '0:10',
+ 60: '1:00',
+ 601: '10:01',
+ 3600: '1:00:00',
+ 3661: '1:01:01',
+ 36000: '10:00:00'
+ };
+
+ Object.keys(durationsToFormattedStrings).forEach(function(seconds) {
+ assert.equal(durationsToFormattedStrings[seconds], googleYouTube.toHHMMSS(seconds));
+ });
+ }
+
+ function testPlayMethodAndStateTransitions(googleYouTube) {
+ // Expected state transitions: -1 (unstarted) -> 3 (buffering) -> 1 (playing)
+ var stateTransitions = [-1, 3, 1];
+
+ googleYouTube.addEventListener('google-youtube-state-change', function(e) {
+ // Test that the element's state property always is set to the same property in the event.
+ assert.equal(e.detail.data, googleYouTube.state);
+
+ // Test that the player goes through the expected sequence of state transitions.
+ assert.equal(e.detail.data, stateTransitions.shift());
+
+ // Once the array of expected state transitions have been exhausted, end the test.
+ if (stateTransitions.length == 0) {
+ done();
+ }
+ });
+
+ // Kick off playback.
+ googleYouTube.play();
+ }
+
+ document.addEventListener('polymer-ready', function() {
+ var googleYouTube = document.querySelector('google-youtube');
+
+ testToHHMMSS(googleYouTube);
+
+ // Playback can't be initiated until after the google-youtube-ready event is fired.
+ googleYouTube.addEventListener('google-youtube-ready', function() {
+ testPlayMethodAndStateTransitions(googleYouTube);
+ });
+ });
+ </script>
+ </body>
+</html>
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-youtube/tests/google-youtube-custom-thumbnail.html b/polymer_1.0.4/bower_components/google-youtube/tests/google-youtube-custom-thumbnail.html
new file mode 100644
index 0000000..9e6d0fb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube/tests/google-youtube-custom-thumbnail.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<!-- Copyright (c) 2014 Google Inc. All rights reserved. -->
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>google-youtube Basic Tests</title>
+ <script src="../../platform/platform.js"></script>
+ <link rel="import" href="../../polymer-test-tools/tools.html">
+ <script src="../../polymer-test-tools/htmltest.js"></script>
+ <link rel="import" href="../google-youtube.html">
+ </head>
+ <body>
+ <google-youtube thumbnail="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFElEQVQIHWP4z8DwHwyBNJDN8B8AQNEG+t5Ik2kAAAAASUVORK5CYII="></google-youtube>
+
+ <script>
+ function testThumbnailImgPresent(googleYouTube) {
+ assert.ok(googleYouTube.shadowRoot.querySelector('img'), 'thumbnail <img> is present.');
+ }
+
+ function testTapHandlerLoadsEmbed(googleYouTube) {
+ googleYouTube.addEventListener('google-youtube-ready', function(e) {
+ assert.notOk(googleYouTube.shadowRoot.querySelector('img'), 'thumbnail <img> is no longer present.');
+
+ assert.ok(googleYouTube.shadowRoot.querySelector('iframe'), 'YouTube embed <iframe> is present.');
+
+ done();
+ });
+
+ // Trigger the on-tap handler.
+ googleYouTube.handleThumbnailTap();
+ }
+
+ document.addEventListener('polymer-ready', function() {
+ var googleYouTube = document.querySelector('google-youtube');
+
+ testThumbnailImgPresent(googleYouTube);
+ testTapHandlerLoadsEmbed(googleYouTube);
+ });
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/google-youtube/tests/index.html b/polymer_1.0.4/bower_components/google-youtube/tests/index.html
new file mode 100644
index 0000000..29ab956
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube/tests/index.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>google-youtube Test Runner</title>
+ <meta charset="UTF-8">
+ <script src="../../platform/platform.js"></script>
+ <link rel="import" href="tests.html">
+ </head>
+ <body>
+ <div id="mocha"></div>
+ </body>
+</html>
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/google-youtube/tests/tests.html b/polymer_1.0.4/bower_components/google-youtube/tests/tests.html
new file mode 100644
index 0000000..6aec722
--- /dev/null
+++ b/polymer_1.0.4/bower_components/google-youtube/tests/tests.html
@@ -0,0 +1,13 @@
+<link rel="import" href="../../polymer-test-tools/tools.html">
+<script src="../../polymer-test-tools/mocha-htmltest.js"></script>
+
+<script>
+ mocha.setup({ui: 'tdd', slow: 5000, timeout: 10000, htmlbase: ''});
+
+ htmlSuite('google-youtube', function() {
+ htmlTest('google-youtube-basic.html');
+ htmlTest('google-youtube-custom-thumbnail.html');
+ });
+
+ mocha.run();
+</script>
diff --git a/polymer_1.0.4/bower_components/hydrolysis/.bower.json b/polymer_1.0.4/bower_components/hydrolysis/.bower.json
new file mode 100644
index 0000000..bff4230
--- /dev/null
+++ b/polymer_1.0.4/bower_components/hydrolysis/.bower.json
@@ -0,0 +1,33 @@
+{
+ "name": "hydrolysis",
+ "main": "hydrolysis.js",
+ "ignore": [
+ "lib/",
+ "examples/",
+ "demo/",
+ "test/",
+ ".gitignore",
+ "gulpfile.js",
+ "package.json"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/Polymer/hydrolysis.git"
+ },
+ "devDependencies": {
+ "polymer": "Polymer/polymer#^0.9.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "web-component-tester": "*"
+ },
+ "version": "1.15.1",
+ "homepage": "https://github.com/Polymer/hydrolysis",
+ "_release": "1.15.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.15.1",
+ "commit": "ee5fe9ba6735e18e0358f7946045515ac9e29313"
+ },
+ "_source": "git://github.com/Polymer/hydrolysis.git",
+ "_target": "^1.11",
+ "_originalSource": "Polymer/hydrolysis"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/hydrolysis/.editorconfig b/polymer_1.0.4/bower_components/hydrolysis/.editorconfig
new file mode 100644
index 0000000..99b8533
--- /dev/null
+++ b/polymer_1.0.4/bower_components/hydrolysis/.editorconfig
@@ -0,0 +1,19 @@
+# Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+# This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+# The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+# The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+# Code distributed by Google as part of the polymer project is also
+# subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+
+# Polymer EditorConfig
+
+root = true
+
+[*]
+charset = utf-8
+indent_size = 2
+indent_style = space
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/hydrolysis/.gitattributes b/polymer_1.0.4/bower_components/hydrolysis/.gitattributes
new file mode 100644
index 0000000..176a458
--- /dev/null
+++ b/polymer_1.0.4/bower_components/hydrolysis/.gitattributes
@@ -0,0 +1 @@
+* text=auto
diff --git a/polymer_1.0.4/bower_components/hydrolysis/API.md b/polymer_1.0.4/bower_components/hydrolysis/API.md
new file mode 100644
index 0000000..c12b949
--- /dev/null
+++ b/polymer_1.0.4/bower_components/hydrolysis/API.md
@@ -0,0 +1,360 @@
+## Objects
+<dl>
+<dt><a href="#hydrolysis">hydrolysis</a> : <code>object</code></dt>
+<dd><p>Static analysis for Polymer.</p>
+</dd>
+</dl>
+## Functions
+<dl>
+<dt><a href="#isSiblingOrAunt">isSiblingOrAunt()</a> ⇒ <code>boolean</code></dt>
+<dd><p>Returns true if <code>patha</code> is a sibling or aunt of <code>pathb</code>.</p>
+</dd>
+<dt><a href="#redirectSibling">redirectSibling()</a> ⇒ <code>string</code></dt>
+<dd><p>Change <code>localPath</code> from a sibling of <code>basePath</code> to be a child of
+<code>basePath</code> joined with <code>redirect</code>.</p>
+</dd>
+</dl>
+<a name="hydrolysis"></a>
+## hydrolysis : <code>object</code>
+Static analysis for Polymer.
+
+**Kind**: global namespace
+
+* [hydrolysis](#hydrolysis) : <code>object</code>
+ * [.Analyzer](#hydrolysis.Analyzer)
+ * [new Analyzer(attachAST, [loader])](#new_hydrolysis.Analyzer_new)
+ * _instance_
+ * [.elements](#hydrolysis.Analyzer#elements) : <code>Array.<ElementDescriptor></code>
+ * [.elementsByTagName](#hydrolysis.Analyzer#elementsByTagName) : <code>Object.<string, ElementDescriptor></code>
+ * [.features](#hydrolysis.Analyzer#features) : <code>Array.<FeatureDescriptor></code>
+ * [.behaviors](#hydrolysis.Analyzer#behaviors) : <code>Array.<BehaviorDescriptor></code>
+ * [.html](#hydrolysis.Analyzer#html) : <code>Object.<string, AnalyzedDocument></code>
+ * [.parsedDocuments](#hydrolysis.Analyzer#parsedDocuments) : <code>Object</code>
+ * [._getDependencies(href, [found], [transitive])](#hydrolysis.Analyzer#_getDependencies) ⇒ <code>Array.<string></code>
+ * [.metadataTree(href)](#hydrolysis.Analyzer#metadataTree) ⇒ <code>Promise</code>
+ * [.nodeWalkDocuments(predicate)](#hydrolysis.Analyzer#nodeWalkDocuments) ⇒ <code>Object</code>
+ * [.annotate()](#hydrolysis.Analyzer#annotate)
+ * [.clean()](#hydrolysis.Analyzer#clean)
+ * _static_
+ * [.analyze(href, [options])](#hydrolysis.Analyzer.analyze) ⇒ <code>Promise.<Analyzer></code>
+ * [.FileLoader](#hydrolysis.FileLoader)
+ * [new FileLoader()](#new_hydrolysis.FileLoader_new)
+ * [.addResolver(resolver)](#hydrolysis.FileLoader#addResolver)
+ * [.request(url)](#hydrolysis.FileLoader#request) ⇒ <code>Promise.<string></code>
+ * [.FSResolver](#hydrolysis.FSResolver)
+ * [new FSResolver(config)](#new_hydrolysis.FSResolver_new)
+ * [.NoopResolver](#hydrolysis.NoopResolver)
+ * [new NoopResolver(config)](#new_hydrolysis.NoopResolver_new)
+ * [.accept(uri, deferred)](#hydrolysis.NoopResolver#accept) ⇒ <code>boolean</code>
+ * [.XHRResolver](#hydrolysis.XHRResolver)
+ * [new XHRResolver(config)](#new_hydrolysis.XHRResolver_new)
+ * [.DocumentAST](#hydrolysis.DocumentAST) : <code>Object</code>
+ * [.ElementDescriptor](#hydrolysis.ElementDescriptor) : <code>Object</code>
+ * [.FeatureDescriptor](#hydrolysis.FeatureDescriptor) : <code>Object</code>
+ * [.BehaviorDescriptor](#hydrolysis.BehaviorDescriptor) : <code>Object</code>
+ * [.DocumentDescriptor](#hydrolysis.DocumentDescriptor) : <code>Object</code>
+ * [.AnalyzedDocument](#hydrolysis.AnalyzedDocument) : <code>Object</code>
+ * [.LoadOptions](#hydrolysis.LoadOptions) : <code>Object</code>
+ * [.Resolver](#hydrolysis.Resolver) : <code>Object</code>
+
+<a name="hydrolysis.Analyzer"></a>
+### hydrolysis.Analyzer
+**Kind**: static class of <code>[hydrolysis](#hydrolysis)</code>
+
+* [.Analyzer](#hydrolysis.Analyzer)
+ * [new Analyzer(attachAST, [loader])](#new_hydrolysis.Analyzer_new)
+ * _instance_
+ * [.elements](#hydrolysis.Analyzer#elements) : <code>Array.<ElementDescriptor></code>
+ * [.elementsByTagName](#hydrolysis.Analyzer#elementsByTagName) : <code>Object.<string, ElementDescriptor></code>
+ * [.features](#hydrolysis.Analyzer#features) : <code>Array.<FeatureDescriptor></code>
+ * [.behaviors](#hydrolysis.Analyzer#behaviors) : <code>Array.<BehaviorDescriptor></code>
+ * [.html](#hydrolysis.Analyzer#html) : <code>Object.<string, AnalyzedDocument></code>
+ * [.parsedDocuments](#hydrolysis.Analyzer#parsedDocuments) : <code>Object</code>
+ * [._getDependencies(href, [found], [transitive])](#hydrolysis.Analyzer#_getDependencies) ⇒ <code>Array.<string></code>
+ * [.metadataTree(href)](#hydrolysis.Analyzer#metadataTree) ⇒ <code>Promise</code>
+ * [.nodeWalkDocuments(predicate)](#hydrolysis.Analyzer#nodeWalkDocuments) ⇒ <code>Object</code>
+ * [.annotate()](#hydrolysis.Analyzer#annotate)
+ * [.clean()](#hydrolysis.Analyzer#clean)
+ * _static_
+ * [.analyze(href, [options])](#hydrolysis.Analyzer.analyze) ⇒ <code>Promise.<Analyzer></code>
+
+<a name="new_hydrolysis.Analyzer_new"></a>
+#### new Analyzer(attachAST, [loader])
+A database of Polymer metadata defined in HTML
+
+
+| Param | Type | Description |
+| --- | --- | --- |
+| attachAST | <code>boolean</code> | If true, attach a parse5 compliant AST |
+| [loader] | <code>FileLoader</code> | An optional `FileLoader` used to load external resources |
+
+<a name="hydrolysis.Analyzer#elements"></a>
+#### analyzer.elements : <code>Array.<ElementDescriptor></code>
+A list of all elements the `Analyzer` has metadata for.
+
+**Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
+<a name="hydrolysis.Analyzer#elementsByTagName"></a>
+#### analyzer.elementsByTagName : <code>Object.<string, ElementDescriptor></code>
+A view into `elements`, keyed by tag name.
+
+**Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
+<a name="hydrolysis.Analyzer#features"></a>
+#### analyzer.features : <code>Array.<FeatureDescriptor></code>
+A list of API features added to `Polymer.Base` encountered by the
+analyzer.
+
+**Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
+<a name="hydrolysis.Analyzer#behaviors"></a>
+#### analyzer.behaviors : <code>Array.<BehaviorDescriptor></code>
+The behaviors collected by the analysis pass.
+
+**Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
+<a name="hydrolysis.Analyzer#html"></a>
+#### analyzer.html : <code>Object.<string, AnalyzedDocument></code>
+A map, keyed by absolute path, of Document metadata.
+
+**Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
+<a name="hydrolysis.Analyzer#parsedDocuments"></a>
+#### analyzer.parsedDocuments : <code>Object</code>
+A map, keyed by path, of HTML document ASTs.
+
+**Kind**: instance property of <code>[Analyzer](#hydrolysis.Analyzer)</code>
+<a name="hydrolysis.Analyzer#_getDependencies"></a>
+#### analyzer._getDependencies(href, [found], [transitive]) ⇒ <code>Array.<string></code>
+List all the html dependencies for the document at `href`.
+
+**Kind**: instance method of <code>[Analyzer](#hydrolysis.Analyzer)</code>
+**Returns**: <code>Array.<string></code> - A list of all the html dependencies.
+
+| Param | Type | Description |
+| --- | --- | --- |
+| href | <code>string</code> | The href to get dependencies for. |
+| [found] | <code>Object.<string, boolean></code> | An object keyed by URL of the already resolved dependencies. |
+| [transitive] | <code>boolean</code> | Whether to load transitive dependencies. Defaults to true. |
+
+<a name="hydrolysis.Analyzer#metadataTree"></a>
+#### analyzer.metadataTree(href) ⇒ <code>Promise</code>
+Returns a promise that resolves to a POJO representation of the import
+tree, in a format that maintains the ordering of the HTML imports spec.
+
+**Kind**: instance method of <code>[Analyzer](#hydrolysis.Analyzer)</code>
+
+| Param | Type | Description |
+| --- | --- | --- |
+| href | <code>string</code> | the import to get metadata for. |
+
+<a name="hydrolysis.Analyzer#nodeWalkDocuments"></a>
+#### analyzer.nodeWalkDocuments(predicate) ⇒ <code>Object</code>
+Calls `dom5.nodeWalk` on each document that `Anayzler` has laoded.
+
+**Kind**: instance method of <code>[Analyzer](#hydrolysis.Analyzer)</code>
+
+| Param | Type | Description |
+| --- | --- | --- |
+| predicate | <code>Object</code> | A dom5 predicate. |
+
+<a name="hydrolysis.Analyzer#annotate"></a>
+#### analyzer.annotate()
+Annotates all loaded metadata with its documentation.
+
+**Kind**: instance method of <code>[Analyzer](#hydrolysis.Analyzer)</code>
+<a name="hydrolysis.Analyzer#clean"></a>
+#### analyzer.clean()
+Removes redundant properties from the collected descriptors.
+
+**Kind**: instance method of <code>[Analyzer](#hydrolysis.Analyzer)</code>
+<a name="hydrolysis.Analyzer.analyze"></a>
+#### Analyzer.analyze(href, [options]) ⇒ <code>Promise.<Analyzer></code>
+Shorthand for transitively loading and processing all imports beginning at
+`href`.
+
+In order to properly filter paths, `href` _must_ be an absolute URI.
+
+**Kind**: static method of <code>[Analyzer](#hydrolysis.Analyzer)</code>
+**Returns**: <code>Promise.<Analyzer></code> - A promise that will resolve once `href` and its
+ dependencies have been loaded and analyzed.
+
+| Param | Type | Description |
+| --- | --- | --- |
+| href | <code>string</code> | The root import to begin loading from. |
+| [options] | <code>LoadOptions</code> | Any additional options for the load. |
+
+<a name="hydrolysis.FileLoader"></a>
+### hydrolysis.FileLoader
+**Kind**: static class of <code>[hydrolysis](#hydrolysis)</code>
+
+* [.FileLoader](#hydrolysis.FileLoader)
+ * [new FileLoader()](#new_hydrolysis.FileLoader_new)
+ * [.addResolver(resolver)](#hydrolysis.FileLoader#addResolver)
+ * [.request(url)](#hydrolysis.FileLoader#request) ⇒ <code>Promise.<string></code>
+
+<a name="new_hydrolysis.FileLoader_new"></a>
+#### new FileLoader()
+A FileLoader lets you resolve URLs with a set of potential resolvers.
+
+<a name="hydrolysis.FileLoader#addResolver"></a>
+#### fileLoader.addResolver(resolver)
+Add an instance of a Resolver class to the list of url resolvers
+
+Ordering of resolvers is most to least recently added
+The first resolver to "accept" the url wins.
+
+**Kind**: instance method of <code>[FileLoader](#hydrolysis.FileLoader)</code>
+
+| Param | Type | Description |
+| --- | --- | --- |
+| resolver | <code>Resolver</code> | The resolver to add. |
+
+<a name="hydrolysis.FileLoader#request"></a>
+#### fileLoader.request(url) ⇒ <code>Promise.<string></code>
+Return a promise for an absolute url
+
+Url requests are deduplicated by the loader, returning the same Promise for
+identical urls
+
+**Kind**: instance method of <code>[FileLoader](#hydrolysis.FileLoader)</code>
+**Returns**: <code>Promise.<string></code> - A promise that resolves to the contents of the URL.
+
+| Param | Type | Description |
+| --- | --- | --- |
+| url | <code>string</code> | The absolute url to request. |
+
+<a name="hydrolysis.FSResolver"></a>
+### hydrolysis.FSResolver
+**Kind**: static class of <code>[hydrolysis](#hydrolysis)</code>
+<a name="new_hydrolysis.FSResolver_new"></a>
+#### new FSResolver(config)
+Resolves requests via the file system.
+
+
+| Param | Type | Description |
+| --- | --- | --- |
+| config | <code>Object</code> | configuration options. |
+| config.host | <code>string</code> | Hostname to match for absolute urls. Matches "/" by default |
+| config.basePath | <code>string</code> | Prefix directory for components in url. Defaults to "/". |
+| config.root | <code>string</code> | Filesystem root to search. Defaults to the current working directory. |
+| config.redirect | <code>string</code> | Where to redirect lookups to siblings. |
+
+<a name="hydrolysis.NoopResolver"></a>
+### hydrolysis.NoopResolver
+**Kind**: static class of <code>[hydrolysis](#hydrolysis)</code>
+
+* [.NoopResolver](#hydrolysis.NoopResolver)
+ * [new NoopResolver(config)](#new_hydrolysis.NoopResolver_new)
+ * [.accept(uri, deferred)](#hydrolysis.NoopResolver#accept) ⇒ <code>boolean</code>
+
+<a name="new_hydrolysis.NoopResolver_new"></a>
+#### new NoopResolver(config)
+A resolver that resolves to null any uri matching config.
+
+
+| Param | Type | Description |
+| --- | --- | --- |
+| config | <code>string</code> | The url to `accept`. |
+
+<a name="hydrolysis.NoopResolver#accept"></a>
+#### noopResolver.accept(uri, deferred) ⇒ <code>boolean</code>
+**Kind**: instance method of <code>[NoopResolver](#hydrolysis.NoopResolver)</code>
+**Returns**: <code>boolean</code> - Whether the URI is handled by this resolver.
+
+| Param | Type | Description |
+| --- | --- | --- |
+| uri | <code>string</code> | The absolute URI being requested. |
+| deferred | <code>Deferred</code> | The deferred promise that should be resolved if this resolver handles the URI. |
+
+<a name="hydrolysis.XHRResolver"></a>
+### hydrolysis.XHRResolver
+**Kind**: static class of <code>[hydrolysis](#hydrolysis)</code>
+<a name="new_hydrolysis.XHRResolver_new"></a>
+#### new XHRResolver(config)
+Construct a resolver that requests resources over XHR.
+
+
+| Param | Type | Description |
+| --- | --- | --- |
+| config | <code>Object</code> | configuration arguments. |
+| config.responseType | <code>string</code> | Type of object to be returned by the XHR. Defaults to 'text', accepts 'document', 'arraybuffer', and 'json'. |
+
+<a name="hydrolysis.DocumentAST"></a>
+### hydrolysis.DocumentAST : <code>Object</code>
+Parse5's representation of a parsed html document
+
+**Kind**: static typedef of <code>[hydrolysis](#hydrolysis)</code>
+<a name="hydrolysis.ElementDescriptor"></a>
+### hydrolysis.ElementDescriptor : <code>Object</code>
+The metadata for a single polymer element
+
+**Kind**: static typedef of <code>[hydrolysis](#hydrolysis)</code>
+<a name="hydrolysis.FeatureDescriptor"></a>
+### hydrolysis.FeatureDescriptor : <code>Object</code>
+The metadata for a Polymer feature.
+
+**Kind**: static typedef of <code>[hydrolysis](#hydrolysis)</code>
+<a name="hydrolysis.BehaviorDescriptor"></a>
+### hydrolysis.BehaviorDescriptor : <code>Object</code>
+The metadata for a Polymer behavior mixin.
+
+**Kind**: static typedef of <code>[hydrolysis](#hydrolysis)</code>
+<a name="hydrolysis.DocumentDescriptor"></a>
+### hydrolysis.DocumentDescriptor : <code>Object</code>
+The metadata for all features and elements defined in one document
+
+**Kind**: static typedef of <code>[hydrolysis](#hydrolysis)</code>
+**Properties**
+
+| Name | Type | Description |
+| --- | --- | --- |
+| elements | <code>Array.<ElementDescriptor></code> | The elements from the document |
+| features | <code>Array.<FeatureDescriptor></code> | The features from the document |
+| behaviors | <code>Array.<FeatureDescriptor></code> | The behaviors from the document |
+
+<a name="hydrolysis.AnalyzedDocument"></a>
+### hydrolysis.AnalyzedDocument : <code>Object</code>
+The metadata of an entire HTML document, in promises.
+
+**Kind**: static typedef of <code>[hydrolysis](#hydrolysis)</code>
+**Properties**
+
+| Name | Type | Description |
+| --- | --- | --- |
+| href | <code>string</code> | The url of the document. |
+| htmlLoaded | <code>Promise.<ParsedImport></code> | The parsed representation of the doc. Use the `ast` property to get the full `parse5` ast |
+| depsLoaded | <code>Promise.<Array.<string>></code> | Resolves to the list of this Document's transitive import dependencies |
+| depHrefs | <code>Array.<string></code> | The direct dependencies of the document. |
+| metadataLoaded | <code>Promise.<DocumentDescriptor></code> | Resolves to the list of this Document's import dependencies |
+
+<a name="hydrolysis.LoadOptions"></a>
+### hydrolysis.LoadOptions : <code>Object</code>
+Options for `Analyzer.analzye`
+
+**Kind**: static typedef of <code>[hydrolysis](#hydrolysis)</code>
+**Properties**
+
+| Name | Type | Description |
+| --- | --- | --- |
+| noAnnotations | <code>boolean</code> | Whether `annotate()` should be skipped. |
+| clean | <code>boolean</code> | Whether the generated descriptors should be cleaned of redundant data. |
+| filter | <code>function</code> | A predicate function that indicates which files should be ignored by the loader. By default all files not located under the dirname of `href` will be ignored. |
+
+<a name="hydrolysis.Resolver"></a>
+### hydrolysis.Resolver : <code>Object</code>
+An object that knows how to resolve resources.
+
+**Kind**: static typedef of <code>[hydrolysis](#hydrolysis)</code>
+**Properties**
+
+| Name | Type | Description |
+| --- | --- | --- |
+| accept | <code>function</code> | Attempt to resolve `deferred` with the contents the specified URL. Returns false if the Resolver is unable to resolve the URL. |
+
+<a name="isSiblingOrAunt"></a>
+## isSiblingOrAunt() ⇒ <code>boolean</code>
+Returns true if `patha` is a sibling or aunt of `pathb`.
+
+**Kind**: global function
+<a name="redirectSibling"></a>
+## redirectSibling() ⇒ <code>string</code>
+Change `localPath` from a sibling of `basePath` to be a child of
+`basePath` joined with `redirect`.
+
+**Kind**: global function
diff --git a/polymer_1.0.4/bower_components/hydrolysis/LICENSE b/polymer_1.0.4/bower_components/hydrolysis/LICENSE
new file mode 100644
index 0000000..6333a69
--- /dev/null
+++ b/polymer_1.0.4/bower_components/hydrolysis/LICENSE
@@ -0,0 +1,5 @@
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/hydrolysis/README.md b/polymer_1.0.4/bower_components/hydrolysis/README.md
new file mode 100644
index 0000000..571809e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/hydrolysis/README.md
@@ -0,0 +1,36 @@
+# hydrolysis
+
+Static anlaysis utilities for polymer.
+
+## Install
+```
+npm install hydrolysis
+```
+
+## Usage
+```js
+var hyd = require('hydrolysis');
+
+hyd.Analyzer.analyze('path-to-polymer-element.html')
+ .then(function(analyzer) {
+ console.log(analyzer.elementsByTagName['my-element'])
+ });
+```
+
+For more detail, see the [API Docs](API.md).
+
+
+## Developing
+You need [wct](https://github.com/Polymer/web-component-tester) to run the tests.
+
+Run a one-off build of the project:
+
+```sh
+npm run build
+```
+
+Or watch the source for changes, and rebuild each time a file is modified:
+
+```sh
+npm run watch
+```
diff --git a/polymer_1.0.4/bower_components/hydrolysis/bower.json b/polymer_1.0.4/bower_components/hydrolysis/bower.json
new file mode 100644
index 0000000..a5d507d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/hydrolysis/bower.json
@@ -0,0 +1,23 @@
+{
+ "name": "hydrolysis",
+ "main": "hydrolysis.js",
+ "ignore": [
+ "lib/",
+ "examples/",
+ "demo/",
+ "test/",
+ ".gitignore",
+ "gulpfile.js",
+ "package.json"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/Polymer/hydrolysis.git"
+ },
+ "devDependencies": {
+ "polymer": "Polymer/polymer#^0.9.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "web-component-tester": "*"
+ },
+ "version": "1.15.1"
+}
diff --git a/polymer_1.0.4/bower_components/hydrolysis/hydrolysis-analyzer.html b/polymer_1.0.4/bower_components/hydrolysis/hydrolysis-analyzer.html
new file mode 100644
index 0000000..1b38be5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/hydrolysis/hydrolysis-analyzer.html
@@ -0,0 +1,114 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="hydrolysis.html">
+
+<script>
+(function() {
+var hydrolysis = require('hydrolysis');
+
+ Polymer({
+
+ is: 'hydrolysis-analyzer',
+
+ properties: {
+
+ /**
+ * The URL to an import that declares (or transitively imports) the
+ * elements that you wish to see analyzed.
+ *
+ * If the URL is relative, it will be resolved relative to the master
+ * document.
+ *
+ * If you change this value after the `<hydrolysis-analyzer>` has been
+ * instantiated, you must call `analyze()`.
+ */
+ src: {
+ type: String,
+ },
+
+ /**
+ * Whether _all_ dependencies should be loaded and analyzed.
+ *
+ * Turning this on will probably slow down the load process dramatically.
+ */
+ transitive: {
+ type: Boolean,
+ },
+
+ /**
+ * Whether the hydrolysis descriptors should be cleaned of redundant
+ * properties.
+ */
+ clean: {
+ type: Boolean,
+ },
+
+ /** The resultant `Analyzer` object from Hydrolysis. */
+ analyzer: {
+ type: Object,
+ readOnly: true,
+ notify: true,
+ },
+
+ /** Whether the analyzer is loading/analyzing resources. */
+ loading: {
+ type: Boolean,
+ readOnly: true,
+ notify: true,
+ },
+
+ },
+
+ ready: function() {
+ this.analyze();
+ },
+
+ /**
+ * Begins loading the imports referenced by `src`.
+ *
+ * If you make changes to this element's configuration, you must call this
+ * function to kick off another analysis pass.
+ */
+ analyze: function() {
+ if (!this.src) {
+ return;
+ }
+ // We can implement request cancellation when someone needs it.
+ if (this.loading) {
+ console.error('Analyzer is already loading a document:', this);
+ return;
+ }
+ this._setLoading(true);
+
+ var options = {
+ clean: this.clean,
+ filter: this.transitive ? function() { return false; } : null,
+ attachAst: true,
+ };
+
+ var baseUri = this.ownerDocument.baseURI;
+ var srcUrl = new URL(this.src, baseUri).toString();
+ hydrolysis.Analyzer.analyze(srcUrl, options).then(function(analyzer) {
+ this._setLoading(false);
+ this._setAnalyzer(analyzer);
+ }.bind(this))
+ .catch(function(error) {
+ console.error('Failed to load source at:', this.src, error);
+ console.error(error.stack);
+ this._setLoading(false);
+ this._setAnalyzer(null);
+ }.bind(this));
+ },
+
+ });
+
+})();
+</script>
diff --git a/polymer_1.0.4/bower_components/hydrolysis/hydrolysis.html b/polymer_1.0.4/bower_components/hydrolysis/hydrolysis.html
new file mode 100644
index 0000000..fde7249
--- /dev/null
+++ b/polymer_1.0.4/bower_components/hydrolysis/hydrolysis.html
@@ -0,0 +1,10 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<script src="hydrolysis.js"></script>
diff --git a/polymer_1.0.4/bower_components/hydrolysis/hydrolysis.js b/polymer_1.0.4/bower_components/hydrolysis/hydrolysis.js
new file mode 100644
index 0000000..accca3b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/hydrolysis/hydrolysis.js
@@ -0,0 +1,25944 @@
+require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+(function (global){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// jshint node: true
+'use strict';
+// jshint -W079
+var Promise = global.Promise || require('es6-promise').Promise;
+require("setimmediate");
+// jshint +W079
+
+var dom5 = require('dom5');
+var url = require('url');
+
+var docs = require('./ast-utils/docs');
+var FileLoader = require('./loader/file-loader');
+var importParse = require('./ast-utils/import-parse');
+var jsParse = require('./ast-utils/js-parse');
+var NoopResolver = require('./loader/noop-resolver');
+
+function reduceMetadata(m1, m2) {
+ return {
+ elements: m1.elements.concat(m2.elements),
+ features: m1.features.concat(m2.features),
+ behaviors: m1.behaviors.concat(m2.behaviors),
+ };
+}
+
+var EMPTY_METADATA = {elements: [], features: [], behaviors: []};
+
+/**
+ * Parse5's representation of a parsed html document
+ * @typedef {Object} DocumentAST
+ * @memberof hydrolysis
+ */
+
+/**
+ * The metadata for a single polymer element
+ * @typedef {Object} ElementDescriptor
+ * @memberof hydrolysis
+ */
+
+/**
+ * The metadata for a Polymer feature.
+ * @typedef {Object} FeatureDescriptor
+ * @memberof hydrolysis
+ */
+
+/**
+ * The metadata for a Polymer behavior mixin.
+ * @typedef {Object} BehaviorDescriptor
+ * @memberof hydrolysis
+ */
+
+/**
+ * The metadata for all features and elements defined in one document
+ * @typedef {Object} DocumentDescriptor
+ * @memberof hydrolysis
+ * @property {Array<ElementDescriptor>} elements The elements from the document
+ * @property {Array<FeatureDescriptor>} features The features from the document
+ * @property {Array<FeatureDescriptor>} behaviors The behaviors from the document
+ */
+
+/**
+ * The metadata of an entire HTML document, in promises.
+ * @typedef {Object} AnalyzedDocument
+ * @memberof hydrolysis
+ * @property {string} href The url of the document.
+ * @property {Promise<ParsedImport>} htmlLoaded The parsed representation of
+ * the doc. Use the `ast` property to get the full `parse5` ast
+ *
+ * @property {Promise<Array<string>>} depsLoaded Resolves to the list of this
+ * Document's transitive import dependencies
+ *
+ * @property {Array<string>} depHrefs The direct dependencies of the document.
+ *
+ * @property {Promise<DocumentDescriptor>} metadataLoaded Resolves to the list of
+ * this Document's import dependencies
+ */
+
+/**
+ * A database of Polymer metadata defined in HTML
+ *
+ * @constructor
+ * @memberOf hydrolysis
+ * @param {boolean} attachAST If true, attach a parse5 compliant AST
+ * @param {FileLoader=} loader An optional `FileLoader` used to load external
+ * resources
+ */
+var Analyzer = function Analyzer(attachAST,
+ loader) {
+ this.loader = loader;
+
+ /**
+ * A list of all elements the `Analyzer` has metadata for.
+ * @member {Array.<ElementDescriptor>}
+ */
+ this.elements = [];
+
+ /**
+ * A view into `elements`, keyed by tag name.
+ * @member {Object.<string,ElementDescriptor>}
+ */
+ this.elementsByTagName = {};
+
+ /**
+ * A list of API features added to `Polymer.Base` encountered by the
+ * analyzer.
+ * @member {Array<FeatureDescriptor>}
+ */
+ this.features = [];
+
+ /**
+ * The behaviors collected by the analysis pass.
+ *
+ * @member {Array<BehaviorDescriptor>}
+ */
+ this.behaviors = [];
+
+ /**
+ * A map, keyed by absolute path, of Document metadata.
+ * @member {Object<string,AnalyzedDocument>}
+ */
+ this.html = {};
+
+ /**
+ * A map, keyed by path, of HTML document ASTs.
+ * @type {Object}
+ */
+ this.parsedDocuments = {};
+};
+
+/**
+ * Options for `Analyzer.analzye`
+ * @typedef {Object} LoadOptions
+ * @memberof hydrolysis
+ * @property {boolean} noAnnotations Whether `annotate()` should be skipped.
+ * @property {boolean} clean Whether the generated descriptors should be cleaned
+ * of redundant data.
+ * @property {function(string): boolean} filter A predicate function that
+ * indicates which files should be ignored by the loader. By default all
+ * files not located under the dirname of `href` will be ignored.
+ */
+
+/**
+ * Shorthand for transitively loading and processing all imports beginning at
+ * `href`.
+ *
+ * In order to properly filter paths, `href` _must_ be an absolute URI.
+ *
+ * @param {string} href The root import to begin loading from.
+ * @param {LoadOptions=} options Any additional options for the load.
+ * @return {Promise<Analyzer>} A promise that will resolve once `href` and its
+ * dependencies have been loaded and analyzed.
+ */
+Analyzer.analyze = function analyze(href, options) {
+ options = options || {};
+ options.filter = options.filter || _defaultFilter(href);
+
+ var loader = new FileLoader();
+ var PrimaryResolver = typeof window === 'undefined' ?
+ require('./loader/fs-resolver') :
+ require('./loader/xhr-resolver');
+ loader.addResolver(new PrimaryResolver(options));
+ loader.addResolver(new NoopResolver({test: options.filter}));
+
+ var analyzer = new this(null, loader);
+ return analyzer.metadataTree(href).then(function(root) {
+ if (!options.noAnnotations) {
+ analyzer.annotate();
+ }
+ if (options.clean) {
+ analyzer.clean();
+ }
+ return Promise.resolve(analyzer);
+ });
+};
+
+/**
+ * @private
+ * @param {string} href
+ * @return {function(string): boolean}
+ */
+function _defaultFilter(href) {
+ // Everything up to the last `/` or `\`.
+ var base = href.match(/^(.*?)[^\/\\]*$/)[1];
+ return function(uri) {
+ return uri.indexOf(base) !== 0;
+ };
+}
+
+Analyzer.prototype.load = function load(href) {
+ return this.loader.request(href).then(function(content) {
+ return new Promise(function(resolve, reject) {
+ setImmediate(function() {
+ resolve(this._parseHTML(content, href));
+ }.bind(this));
+ }.bind(this));
+ }.bind(this));
+};
+
+/**
+ * Returns an `AnalyzedDocument` representing the provided document
+ * @private
+ * @param {string} htmlImport Raw text of an HTML document
+ * @param {string} href The document's URL.
+ * @return {AnalyzedDocument} An `AnalyzedDocument`
+ */
+Analyzer.prototype._parseHTML = function _parseHTML(htmlImport,
+ href) {
+ if (href in this.html) {
+ return this.html[href];
+ }
+ var depsLoaded = [];
+ var depHrefs = [];
+ var metadataLoaded = Promise.resolve(EMPTY_METADATA);
+ var parsed;
+ try {
+ parsed = importParse(htmlImport, href);
+ } catch (err) {
+ console.error('Error parsing!');
+ throw err;
+ }
+ var htmlLoaded = Promise.resolve(parsed);
+ if (parsed.script) {
+ metadataLoaded = this._processScripts(parsed.script, href);
+ depsLoaded.push(metadataLoaded);
+ }
+
+ if (this.loader) {
+ var baseUri = href;
+ if (parsed.base.length > 1) {
+ console.error("Only one base tag per document!");
+ throw "Multiple base tags in " + href;
+ } else if (parsed.base.length == 1) {
+ var baseHref = dom5.getAttribute(parsed.base[0], "href");
+ if (baseHref) {
+ baseHref = baseHref + "/";
+ baseUri = url.resolve(baseUri, baseHref);
+ }
+ }
+ parsed.import.forEach(function(link) {
+ var linkurl = dom5.getAttribute(link, 'href');
+ if (linkurl) {
+ var resolvedUrl = url.resolve(baseUri, linkurl);
+ depHrefs.push(resolvedUrl);
+ depsLoaded.push(this._dependenciesLoadedFor(resolvedUrl, href));
+ }
+ }.bind(this));
+ }
+ depsLoaded = Promise.all(depsLoaded)
+ .then(function() {return depHrefs;})
+ .catch(function(err) {throw err;});
+ this.parsedDocuments[href] = parsed.ast;
+ this.html[href] = {
+ href: href,
+ htmlLoaded: htmlLoaded,
+ metadataLoaded: metadataLoaded,
+ depHrefs: depHrefs,
+ depsLoaded: depsLoaded
+ };
+ return this.html[href];
+};
+
+Analyzer.prototype._processScripts = function _processScripts(scripts, href) {
+ var scriptPromises = [];
+ scripts.forEach(function(script) {
+ scriptPromises.push(this._processScript(script, href));
+ }.bind(this));
+ return Promise.all(scriptPromises).then(function(metadataList) {
+ return metadataList.reduce(reduceMetadata, EMPTY_METADATA);
+ });
+};
+
+Analyzer.prototype._processScript = function _processScript(script, href) {
+ var src = dom5.getAttribute(script, 'src');
+ var parsedJs;
+ if (!src) {
+ try {
+ parsedJs = jsParse(script.childNodes[0].value);
+ } catch (err) {
+ // Figure out the correct line number for the error.
+ var line = 0;
+ var col = 0;
+ if (script.__ownerDocument && script.__ownerDocument == href) {
+ line = script.__locationDetail.line - 1;
+ col = script.__locationDetail.line - 1;
+ }
+ line += err.lineNumber;
+ col += err.column;
+ var message = "Error parsing script in " + href + " at " + line + ":" + col;
+ message += "\n" + err.description;
+ throw new Error(message);
+ }
+ if (parsedJs.elements) {
+ parsedJs.elements.forEach(function(element) {
+ element.scriptElement = script;
+ this.elements.push(element);
+ if (element.is in this.elementsByTagName) {
+ console.warn('Ignoring duplicate element definition: ' + element.is);
+ } else {
+ this.elementsByTagName[element.is] = element;
+ }
+ }.bind(this));
+ }
+ if (parsedJs.features) {
+ this.features = this.features.concat(parsedJs.features);
+ }
+ if (parsedJs.behaviors) {
+ this.behaviors = this.behaviors.concat(parsedJs.behaviors);
+ }
+ return parsedJs;
+ }
+ if (this.loader) {
+ var resolvedSrc = url.resolve(href, src);
+ return this.loader.request(resolvedSrc).then(function(content) {
+ var resolvedScript = Object.create(script);
+ resolvedScript.childNodes = [{value: content}];
+ resolvedScript.attrs = resolvedScript.attrs.slice();
+ dom5.removeAttribute(resolvedScript, 'src');
+ return this._processScript(resolvedScript, href);
+ }.bind(this)).catch(function(err) {throw err;});
+ } else {
+ return Promise.resolve(EMPTY_METADATA);
+ }
+};
+
+Analyzer.prototype._dependenciesLoadedFor = function _dependenciesLoadedFor(href, root) {
+ var found = {};
+ if (root !== undefined) {
+ found[root] = true;
+ }
+ return this._getDependencies(href, found).then(function(deps) {
+ var depMetadataLoaded = [];
+ var depPromises = deps.map(function(depHref){
+ return this.load(depHref).then(function(htmlMonomer) {
+ return htmlMonomer.metadataLoaded;
+ });
+ }.bind(this));
+ return Promise.all(depPromises);
+ }.bind(this));
+};
+
+/**
+ * List all the html dependencies for the document at `href`.
+ * @param {string} href The href to get dependencies for.
+ * @param {Object.<string,boolean>=} found An object keyed by URL of the
+ * already resolved dependencies.
+ * @param {boolean=} transitive Whether to load transitive
+ * dependencies. Defaults to true.
+ * @return {Array.<string>} A list of all the html dependencies.
+ */
+Analyzer.prototype._getDependencies = function _getDependencies(href, found, transitive) {
+ if (found === undefined) {
+ found = {};
+ found[href] = true;
+ }
+ if (transitive === undefined) {
+ transitive = true;
+ }
+ var deps = [];
+ return this.load(href).then(function(htmlMonomer) {
+ var transitiveDeps = [];
+ htmlMonomer.depHrefs.forEach(function(depHref){
+ if (found[depHref]) {
+ return;
+ }
+ deps.push(depHref);
+ found[depHref] = true;
+ if (transitive) {
+ transitiveDeps.push(this._getDependencies(depHref, found));
+ }
+ }.bind(this));
+ return Promise.all(transitiveDeps);
+ }.bind(this)).then(function(transitiveDeps) {
+ var alldeps = transitiveDeps.reduce(function(a, b) {
+ return a.concat(b);
+ }, []).concat(deps);
+ return alldeps;
+ });
+};
+
+/**
+ * Returns a promise that resolves to a POJO representation of the import
+ * tree, in a format that maintains the ordering of the HTML imports spec.
+ * @param {string} href the import to get metadata for.
+ * @return {Promise}
+ */
+Analyzer.prototype.metadataTree = function metadataTree(href) {
+ return this.load(href).then(function(monomer){
+ var loadedHrefs = {};
+ loadedHrefs[href] = true;
+ return this._metadataTree(monomer, loadedHrefs);
+ }.bind(this));
+};
+
+Analyzer.prototype._metadataTree = function _metadataTree(htmlMonomer,
+ loadedHrefs) {
+ if (loadedHrefs === undefined) {
+ loadedHrefs = {};
+ }
+ return htmlMonomer.metadataLoaded.then(function(metadata) {
+ metadata = {
+ elements: metadata.elements,
+ features: metadata.features,
+ href: htmlMonomer.href
+ };
+ return htmlMonomer.depsLoaded.then(function(hrefs) {
+ var depMetadata = [];
+ hrefs.forEach(function(href) {
+ var metadataPromise = Promise.resolve(true);
+ if (depMetadata.length > 0) {
+ metadataPromise = depMetadata[depMetadata.length - 1];
+ }
+ metadataPromise = metadataPromise.then(function() {
+ if (!loadedHrefs[href]) {
+ loadedHrefs[href] = true;
+ return this._metadataTree(this.html[href], loadedHrefs);
+ } else {
+ return Promise.resolve({});
+ }
+ }.bind(this));
+ depMetadata.push(metadataPromise);
+ }.bind(this));
+ return Promise.all(depMetadata).then(function(importMetadata) {
+ metadata.imports = importMetadata;
+ return htmlMonomer.htmlLoaded.then(function(parsedHtml) {
+ metadata.html = parsedHtml;
+ if (metadata.elements) {
+ metadata.elements.forEach(function(element) {
+ attachDomModule(parsedHtml, element);
+ });
+ }
+ return metadata;
+ });
+ });
+ }.bind(this));
+ }.bind(this));
+};
+
+/**
+ * Calls `dom5.nodeWalk` on each document that `Anayzler` has laoded.
+ * @param {Object} predicate A dom5 predicate.
+ * @return {Object}
+ */
+Analyzer.prototype.nodeWalkDocuments = function nodeWalkDocuments(predicate) {
+ var results = [];
+ for (var href in this.parsedDocuments) {
+ var newNodes = dom5.nodeWalkAll(this.parsedDocuments[href], predicate);
+ results = results.concat(newNodes);
+ }
+ return results;
+};
+
+/** Annotates all loaded metadata with its documentation. */
+Analyzer.prototype.annotate = function annotate() {
+ if (this.features.length > 0) {
+ var featureEl = docs.featureElement(this.features);
+ this.elements.unshift(featureEl);
+ this.elementsByTagName[featureEl.is] = featureEl;
+ }
+
+ this.elements.forEach(docs.annotateElement);
+ this.behaviors.forEach(docs.annotateElement); // Same shape.
+};
+
+function attachDomModule(parsedImport, element) {
+ var domModules = parsedImport['dom-module'];
+ for (var i = 0, domModule; i < domModules.length; i++) {
+ domModule = domModules[i];
+ if (dom5.getAttribute(domModule, 'id') === element.is) {
+ element.domModule = domModule;
+ return;
+ }
+ }
+}
+
+/** Removes redundant properties from the collected descriptors. */
+Analyzer.prototype.clean = function clean() {
+ this.elements.forEach(docs.cleanElement);
+};
+
+module.exports = Analyzer;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{"./ast-utils/docs":5,"./ast-utils/import-parse":10,"./ast-utils/js-parse":11,"./loader/file-loader":13,"./loader/fs-resolver":14,"./loader/noop-resolver":15,"./loader/xhr-resolver":16,"dom5":38,"es6-promise":60,"setimmediate":74,"url":26}],2:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// jshint node: true
+'use strict';
+
+var esutil = require('./esutil');
+var astValue = require('./ast-value');
+
+var analyzeProperties = function(node) {
+
+ var analyzedProps = [];
+
+ if (node.type != 'ObjectExpression') {
+ return analyzedProps;
+ }
+ for (var i = 0; i < node.properties.length; i++) {
+ var property = node.properties[i];
+ var prop = esutil.toPropertyDescriptor(property);
+ prop.published = true;
+
+ if (property.value.type == 'ObjectExpression') {
+ /**
+ * Parse the expression inside a property object block.
+ * property: {
+ * key: {
+ * type: String,
+ * notify: true,
+ * value: -1,
+ * readOnly: true,
+ * reflectToAttribute: true
+ * }
+ * }
+ */
+ for (var j = 0; j < property.value.properties.length; j++) {
+ var propertyArg = property.value.properties[j];
+ var propertyKey = esutil.objectKeyToString(propertyArg.key);
+
+ switch(propertyKey) {
+ case 'type': {
+ prop.type = esutil.objectKeyToString(propertyArg.value);
+ if (prop.type === undefined) {
+ throw {
+ message: 'Invalid type in property object.',
+ location: propertyArg.loc.start
+ };
+ }
+ }
+ break;
+ case 'notify': {
+ prop.notify = astValue.expressionToValue(propertyArg.value);
+ if (prop.notify === undefined)
+ prop.notify = astValue.CANT_CONVERT;
+ }
+ break;
+ case 'readOnly': {
+ prop.readOnly = astValue.expressionToValue(propertyArg.value);
+ if (prop.readOnly === undefined)
+ prop.readOnly = astValue.CANT_CONVERT;
+ }
+ break;
+ case 'reflectToAttribute': {
+ prop.reflectToAttribute = astValue.expressionToValue(propertyArg);
+ if (prop.reflectToAttribute === undefined)
+ prop.reflectToAttribute = astValue.CANT_CONVERT;
+ }
+ break;
+ case 'value': {
+ prop.default = astValue.expressionToValue(propertyArg.value);
+ if (prop.default === undefined)
+ prop.default = astValue.CANT_CONVERT;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (!prop.type) {
+ throw {
+ message: 'Unable to determine name for property key.',
+ location: node.loc.start
+ };
+ }
+
+ analyzedProps.push(prop);
+ }
+ return analyzedProps;
+};
+
+
+module.exports = analyzeProperties;
+
+
+},{"./ast-value":3,"./esutil":7}],3:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// jshint node: true
+'use strict';
+
+// useful tool to visualize AST: http://esprima.org/demo/parse.html
+
+/**
+ * converts literal: {"type": "Literal", "value": 5, "raw": "5" }
+ * to string
+ */
+function literalToValue(literal) {
+ return literal.value;
+}
+
+/**
+ * converts unary to string
+ * unary: { type: 'UnaryExpression', operator: '-', argument: { ... } }
+ */
+function unaryToValue(unary) {
+ var argValue = expressionToValue(unary.argument);
+ if (argValue === undefined)
+ return;
+ return unary.operator + argValue;
+}
+
+/**
+ * converts identifier to its value
+ * identifier { "type": "Identifier", "name": "Number }
+ */
+function identifierToValue(identifier) {
+ return identifier.name;
+}
+
+/**
+ * Function is a block statement.
+ */
+function functionDeclarationToValue(fn) {
+ if (fn.body.type == "BlockStatement")
+ return blockStatementToValue(fn.body);
+}
+
+function functionExpressionToValue(fn) {
+ if (fn.body.type == "BlockStatement")
+ return blockStatementToValue(fn.body);
+}
+/**
+ * Block statement: find last return statement, and return its value
+ */
+function blockStatementToValue(block) {
+ for (var i=block.body.length - 1; i>= 0; i--) {
+ if (block.body[i].type === "ReturnStatement")
+ return returnStatementToValue(block.body[i]);
+ }
+}
+
+/**
+ * Evaluates return's argument
+ */
+function returnStatementToValue(ret) {
+ return expressionToValue(ret.argument);
+}
+
+/**
+ * Enclose containing values in []
+ */
+function arrayExpressionToValue(arry) {
+ var value = '[';
+ for (var i=0; i<arry.elements.length; i++) {
+ var v = expressionToValue(arry.elements[i]);
+ if (v === undefined)
+ v = CANT_CONVERT;
+ if (i !== 0)
+ value += ', ';
+ value += v;
+ }
+ value += ']';
+ return value;
+}
+
+/**
+ * Make it look like an object
+ */
+function objectExpressionToValue(obj) {
+ var value = '{';
+ for (var i=0; i<obj.properties.length; i++) {
+ var k = expressionToValue(obj.properties[i].key);
+ var v = expressionToValue(obj.properties[i].value);
+ if (v === undefined)
+ v = CANT_CONVERT;
+ if (i !== 0)
+ value += ', ';
+ value += '"' + k + '": ' + v;
+ }
+ value += '}';
+ return value;
+}
+
+/**
+ * MemberExpression references a variable with name
+ */
+function memberExpressionToValue(member) {
+ return expressionToValue(member.object) + "." + expressionToValue(member.property);
+}
+
+/**
+ * Tries to get a value from expression. Handles Literal, UnaryExpression
+ * returns undefined on failure
+ * valueExpression example:
+ * { type: "Literal",
+ */
+function expressionToValue(valueExpression) {
+ switch(valueExpression.type) {
+ case 'Literal':
+ return literalToValue(valueExpression);
+ case 'UnaryExpression':
+ return unaryToValue(valueExpression);
+ case 'Identifier':
+ return identifierToValue(valueExpression);
+ case 'FunctionDeclaration':
+ return functionDeclarationToValue(valueExpression);
+ case 'FunctionExpression':
+ return functionExpressionToValue(valueExpression);
+ case 'ArrayExpression':
+ return arrayExpressionToValue(valueExpression);
+ case 'ObjectExpression':
+ return objectExpressionToValue(valueExpression);
+ case 'Identifier':
+ return identifierToValue(valueExpression);
+ case 'MemberExpression':
+ return memberExpressionToValue(valueExpression);
+ default:
+ return;
+ }
+}
+
+var CANT_CONVERT = 'UNKNOWN';
+module.exports = {
+ CANT_CONVERT: CANT_CONVERT,
+ expressionToValue: expressionToValue
+};
+
+},{}],4:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// jshint node: true
+'use strict';
+var estraverse = require('estraverse');
+
+var docs = require('./docs');
+var esutil = require('./esutil');
+var jsdoc = require('./jsdoc');
+var analyzeProperties = require('./analyze-properties');
+var astValue = require('./ast-value.js');
+
+var numFeatures = 0;
+
+module.exports = function behaviorFinder() {
+ /** @type {!Array<BehaviorDescriptor>} The behaviors we've found. */
+ var behaviors = [];
+
+ var currentBehavior = null;
+
+ /**
+ * special-case properties
+ */
+ var propertyHandlers = {
+ properties: function(node) {
+ var props = analyzeProperties(node);
+
+ for (var i=0; i < props.length; i++) {
+ currentBehavior.properties.push(props[i]);
+ }
+ }
+ };
+
+ /**
+ * merges behavior with preexisting behavior with the same name.
+ * here to support multiple @polymerBehavior tags referring
+ * to same behavior. See iron-multi-selectable for example.
+ */
+ function mergeBehavior(newBehavior) {
+ var isBehaviorImpl = function(b) { // filter out BehaviorImpl
+ return b.indexOf(newBehavior.is) === -1;
+ };
+ for (var i=0; i<behaviors.length; i++) {
+ if (newBehavior.is !== behaviors[i].is)
+ continue;
+ // merge desc, longest desc wins
+ if (newBehavior.desc) {
+ if (behaviors[i].desc) {
+ if (newBehavior.desc.length > behaviors[i].desc.length)
+ behaviors[i].desc = newBehavior.desc;
+ }
+ else {
+ behaviors[i].desc = newBehavior.desc;
+ }
+ }
+ // merge demos
+ behaviors[i].demos = (behaviors[i].demos || []).concat(newBehavior.demos || []);
+ // merge events,
+ behaviors[i].events = (behaviors[i].events || []).concat(newBehavior.events || []);
+ // merge properties
+ behaviors[i].properties = (behaviors[i].properties || []).concat(newBehavior.properties || []);
+ // merge behaviors
+ behaviors[i].behaviors =
+ (behaviors[i].behaviors || []).concat(newBehavior.behaviors || [])
+ .filter(isBehaviorImpl);
+ return behaviors[i];
+ }
+ return newBehavior;
+ }
+
+ var visitors = {
+
+ /**
+ * Look for object declarations with @behavior in the docs.
+ */
+ enterVariableDeclaration: function(node, parent) {
+ if (node.declarations.length !== 1) return; // Ambiguous.
+ this._initBehavior(node, function () {
+ return esutil.objectKeyToString(node.declarations[0].id);
+ });
+ },
+
+ /**
+ * Look for object assignments with @polymerBehavior in the docs.
+ */
+ enterAssignmentExpression: function(node, parent) {
+ this._initBehavior(parent, function () {
+ return esutil.objectKeyToString(node.left);
+ });
+ },
+
+ _parseChainedBehaviors: function(node) {
+ // if current behavior is part of an array, it gets extended by other behaviors
+ // inside the array. Ex:
+ // Polymer.IronMultiSelectableBehavior = [ {....}, Polymer.IronSelectableBehavior]
+ // We add these to behaviors array
+ var expression;
+ switch(node.type) {
+ case 'ExpressionStatement':
+ expression = node.expression.right;
+ break;
+ case 'VariableDeclaration':
+ expression = node.declarations.length > 0 ? node.declarations[0].init : null;
+ break;
+ }
+ var chained = [];
+ if (expression && expression.type === 'ArrayExpression') {
+ for (var i=0; i < expression.elements.length; i++) {
+ if (expression.elements[i].type === 'MemberExpression')
+ chained.push(astValue.expressionToValue(expression.elements[i]));
+ }
+ if (chained.length > 0)
+ currentBehavior.behaviors = chained;
+ }
+ },
+
+ _initBehavior: function(node, getName) {
+ var comment = esutil.getAttachedComment(node);
+ // Quickly filter down to potential candidates.
+ if (!comment || comment.indexOf('@polymerBehavior') === -1) return;
+
+
+ currentBehavior = {
+ type: 'behavior',
+ desc: comment,
+ events: esutil.getEventComments(node).map( function(event) {
+ return { desc: event};
+ })
+ };
+
+ docs.annotateBehavior(currentBehavior);
+ // Make sure that we actually parsed a behavior tag!
+ if (!jsdoc.hasTag(currentBehavior.jsdoc, 'polymerBehavior')) {
+ currentBehavior = null;
+ return;
+ }
+
+ var name = jsdoc.getTag(currentBehavior.jsdoc, 'polymerBehavior', 'name');
+ if (!name) {
+ name = getName();
+ }
+ if (!name) {
+ console.warn('Unable to determine name for @polymerBehavior:', comment);
+ }
+ currentBehavior.is = name;
+
+ this._parseChainedBehaviors(node);
+
+ currentBehavior = mergeBehavior(currentBehavior);
+ },
+
+ /**
+ * We assume that the object expression after such an assignment is the
+ * behavior's declaration. Seems to be a decent assumption for now.
+ */
+ enterObjectExpression: function(node, parent) {
+ if (!currentBehavior || currentBehavior.properties) return;
+
+ currentBehavior.properties = currentBehavior.properties || [];
+ for (var i = 0; i < node.properties.length; i++) {
+ var prop = node.properties[i];
+ var name = esutil.objectKeyToString(prop.key);
+ if (!name) {
+ throw {
+ message: 'Cant determine name for property key.',
+ location: node.loc.start
+ };
+ }
+ if (name in propertyHandlers) {
+ propertyHandlers[name](prop.value);
+ }
+ else {
+ currentBehavior.properties.push(esutil.toPropertyDescriptor(prop));
+ }
+ }
+ behaviors.push(currentBehavior);
+ currentBehavior = null;
+ },
+
+ };
+
+ return {visitors: visitors, behaviors: behaviors};
+};
+
+},{"./analyze-properties":2,"./ast-value.js":3,"./docs":5,"./esutil":7,"./jsdoc":12,"estraverse":72}],5:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+'use strict';
+
+// jshint node:true
+
+var jsdoc = require('./jsdoc');
+
+var dom5 = require('dom5');
+
+/** Properties on element prototypes that are purely configuration. */
+var ELEMENT_CONFIGURATION = [
+ 'attached',
+ 'attributeChanged',
+ 'configure',
+ 'constructor',
+ 'created',
+ 'detached',
+ 'enableCustomStyleProperties',
+ 'extends',
+ 'hostAttributes',
+ 'is',
+ 'listeners',
+ 'mixins',
+ 'observers',
+ 'properties',
+ 'ready',
+ 'registered'
+];
+
+/** Tags understood by the annotation process, to be removed during `clean`. */
+var HANDLED_TAGS = [
+ 'param',
+ 'return',
+ 'type',
+];
+
+/**
+ * Annotates Hydrolysis descriptors, processing any `desc` properties as JSDoc.
+ *
+ * You probably want to use a more specialized version of this, such as
+ * `annotateElement`.
+ *
+ * Processed JSDoc values will be made available via the `jsdoc` property on a
+ * descriptor node.
+ *
+ * @param {Object} descriptor The descriptor node to process.
+ * @return {Object} The descriptor that was given.
+ */
+function annotate(descriptor) {
+ if (!descriptor || descriptor.jsdoc) return descriptor;
+
+ if (typeof descriptor.desc === 'string') {
+ descriptor.jsdoc = jsdoc.parseJsdoc(descriptor.desc);
+ // We want to present the normalized form of a descriptor.
+ descriptor.jsdoc.orig = descriptor.desc;
+ descriptor.desc = descriptor.jsdoc.description;
+ }
+
+ return descriptor;
+}
+
+/**
+ * Annotates @event, @hero, & @demo tags
+ */
+function annotateElementHeader(descriptor) {
+ if (descriptor.events) {
+ descriptor.events.forEach(function(event) {
+ _annotateEvent(event);
+ });
+ descriptor.events.sort( function(a,b) {
+ return a.name.localeCompare(b.name);
+ });
+ }
+ descriptor.demos = [];
+ if (descriptor.jsdoc && descriptor.jsdoc.tags) {
+ descriptor.jsdoc.tags.forEach( function(tag) {
+ switch(tag.tag) {
+ case 'hero':
+ descriptor.hero = tag.name || 'hero.png';
+ break;
+ case 'demo':
+ descriptor.demos.push({
+ desc: tag.description || 'demo',
+ path: tag.name || 'demo/index.html'
+ });
+ }
+ });
+ }
+}
+
+/**
+ * Annotates documentation found within a Hydrolysis element descriptor. Also
+ * supports behaviors.
+ *
+ * If the element was processed via `hydrolize`, the element's documentation
+ * will also be extracted via its <dom-module>.
+ *
+ * @param {Object} descriptor The element descriptor.
+ * @return {Object} The descriptor that was given.
+ */
+function annotateElement(descriptor) {
+ if (!descriptor.desc && descriptor.type === 'element') {
+ descriptor.desc = _findElementDocs(descriptor.is,
+ descriptor.domModule,
+ descriptor.scriptElement);
+ }
+ annotate(descriptor);
+
+ // The `<dom-module>` is too low level for most needs, and it is _not_
+ // serializable. So we drop it now that we've extracted all the useful bits
+ // from it.
+ delete descriptor.domModule;
+
+ // Descriptors that should have their `desc` properties parsed as JSDoc.
+ descriptor.properties.forEach(function(property) {
+ // Feature properties are special, configuration is really just a matter of
+ // inheritance...
+ annotateProperty(property, descriptor.abstract);
+ });
+
+ // It may seem like overkill to always sort, but we have an assumption that
+ // these properties are typically being consumed by user-visible tooling.
+ // As such, it's good to have consistent output/ordering to aid the user.
+ descriptor.properties.sort(function(a, b) {
+ // Private properties are always last.
+ if (a.private && !b.private) {
+ return 1;
+ } else if (!a.private && b.private) {
+ return -1;
+ // Otherwise, we're just sorting alphabetically.
+ } else {
+ return a.name.localeCompare(b.name);
+ }
+ });
+
+ annotateElementHeader(descriptor);
+
+ return descriptor;
+}
+
+/**
+ * Annotates behavior descriptor.
+ * @param {Object} descriptor behavior descriptor
+ * @return {Object} descriptor passed in as param
+ */
+function annotateBehavior(descriptor) {
+ annotate(descriptor);
+
+ annotateElementHeader(descriptor);
+
+ return descriptor;
+}
+
+/**
+ * Annotates event documentation
+ */
+function _annotateEvent(descriptor) {
+ annotate(descriptor);
+ // process @event
+ var eventTag = jsdoc.getTag(descriptor.jsdoc, 'event');
+ descriptor.name = eventTag ? eventTag.description : "N/A";
+
+ // process @params
+ descriptor.params = (descriptor.jsdoc.tags || [])
+ .filter( function(tag) {
+ return tag.tag === 'param';
+ })
+ .map( function(tag) {
+ return {
+ type: tag.type || "N/A",
+ desc: tag.description,
+ name: tag.name || "N/A"
+ };
+ });
+ // process @params
+ return descriptor;
+}
+
+/**
+ * Annotates documentation found about a Hydrolysis property descriptor.
+ *
+ * @param {Object} descriptor The property descriptor.
+ * @param {boolean} ignoreConfiguration If true, `configuration` is not set.
+ * @return {Object} The descriptior that was given.
+ */
+function annotateProperty(descriptor, ignoreConfiguration) {
+ annotate(descriptor);
+ if (descriptor.name[0] === '_' || jsdoc.hasTag(descriptor.jsdoc, 'private')) {
+ descriptor.private = true;
+ }
+
+ if (!ignoreConfiguration && ELEMENT_CONFIGURATION.indexOf(descriptor.name) !== -1) {
+ descriptor.private = true;
+ descriptor.configuration = true;
+ }
+
+ // @type JSDoc wins
+ descriptor.type = jsdoc.getTag(descriptor.jsdoc, 'type', 'type') || descriptor.type;
+
+ if (descriptor.type.match(/^function/i)) {
+ _annotateFunctionProperty(descriptor);
+ }
+
+ // @default JSDoc wins
+ var defaultTag = jsdoc.getTag(descriptor.jsdoc, 'default');
+ if (defaultTag !== null) {
+ descriptor.default = (defaultTag.name || '') + (defaultTag.description || '');
+ }
+
+ return descriptor;
+}
+
+/** @param {Object} descriptor */
+function _annotateFunctionProperty(descriptor) {
+ descriptor.function = true;
+
+ var returnTag = jsdoc.getTag(descriptor.jsdoc, 'return');
+ if (returnTag) {
+ descriptor.return = {
+ type: returnTag.type,
+ desc: returnTag.description,
+ };
+ }
+
+ var paramsByName = {};
+ (descriptor.params || []).forEach(function(param) {
+ paramsByName[param.name] = param;
+ });
+ (descriptor.jsdoc && descriptor.jsdoc.tags || []).forEach(function(tag) {
+ if (tag.tag !== 'param') return;
+ var param = paramsByName[tag.name];
+ if (!param) {
+ return;
+ }
+
+ param.type = tag.type || param.type;
+ param.desc = tag.description;
+ });
+}
+
+/**
+ * Converts raw features into an abstract `Polymer.Base` element.
+ *
+ * Note that docs on this element _are not processed_. You must call
+ * `annotateElement` on it yourself if you wish that.
+ *
+ * @param {Array<FeatureDescriptor>} features
+ * @return {ElementDescriptor}
+ */
+function featureElement(features) {
+ var properties = features.reduce(function(result, feature) {
+ return result.concat(feature.properties);
+ }, []);
+
+ return {
+ type: 'element',
+ is: 'Polymer.Base',
+ abstract: true,
+ properties: properties,
+ desc: '`Polymer.Base` acts as a base prototype for all Polymer ' +
+ 'elements. It is composed via various calls to ' +
+ '`Polymer.Base._addFeature()`.\n' +
+ '\n' +
+ 'The properties reflected here are the combined view of all ' +
+ 'features found in this library. There may be more properties ' +
+ 'added via other libraries, as well.',
+ };
+}
+
+/**
+ * Cleans redundant properties from a descriptor, assuming that you have already
+ * called `annotate`.
+ *
+ * @param {Object} descriptor
+ */
+function clean(descriptor) {
+ if (!descriptor.jsdoc) return;
+ // The doctext was written to `descriptor.desc`
+ delete descriptor.jsdoc.description;
+ delete descriptor.jsdoc.orig;
+
+ var cleanTags = [];
+ (descriptor.jsdoc.tags || []).forEach(function(tag) {
+ // Drop any tags we've consumed.
+ if (HANDLED_TAGS.indexOf(tag.tag) !== -1) return;
+ cleanTags.push(tag);
+ });
+
+ if (cleanTags.length === 0) {
+ // No tags? no docs left!
+ delete descriptor.jsdoc;
+ } else {
+ descriptor.jsdoc.tags = cleanTags;
+ }
+}
+
+/**
+ * Cleans redundant properties from an element, assuming that you have already
+ * called `annotateElement`.
+ *
+ * @param {ElementDescriptor|BehaviorDescriptor} element
+ */
+function cleanElement(element) {
+ clean(element);
+ element.properties.forEach(cleanProperty);
+}
+
+/**
+ * Cleans redundant properties from a property, assuming that you have already
+ * called `annotateProperty`.
+ *
+ * @param {PropertyDescriptor} property
+ */
+function cleanProperty(property) {
+ clean(property);
+}
+
+/**
+ * @param {string} elementId
+ * @param {DocumentAST} domModule
+ * @param {DocumentAST} scriptElement The script that the element was defined in.
+ */
+function _findElementDocs(elementId, domModule, scriptElement) {
+ // Note that we concatenate docs from all sources if we find them.
+ // element can be defined in:
+ // html comment right before dom-module
+ // html commnet right before script defining the module, if dom-module is empty
+
+ var found = [];
+
+ // Do we have a HTML comment on the `<dom-module>` or `<script>`?
+ //
+ // Confusingly, with our current style, the comment will be attached to
+ // `<head>`, rather than being a sibling to the `<dom-module>`
+ var searchRoot = domModule || scriptElement;
+ var parents = dom5.nodeWalkAllPrior(searchRoot, dom5.isCommentNode);
+ var comment = parents.length > 0 ? parents[0] : null;
+ if (comment && comment.data) {
+ found.push(comment.data);
+ }
+ if (found.length === 0) return null;
+ return found
+ .filter(function(comment) {
+ // skip @license comments
+ if (comment && comment.indexOf('@license' === -1)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ })
+ .map(jsdoc.unindent).join('\n');
+}
+
+function _findLastChildNamed(name, parent) {
+ var children = parent.childNodes;
+ for (var i = children.length - 1, child; i >= 0; i--) {
+ child = children[i];
+ if (child.nodeName === name) return child;
+ }
+ return null;
+}
+
+// TODO(nevir): parse5-utils!
+function _getNodeAttribute(node, name) {
+ for (var i = 0, attr; i < node.attrs.length; i++) {
+ attr = node.attrs[i];
+ if (attr.name === name) {
+ return attr.value;
+ }
+ }
+}
+
+module.exports = {
+ annotate: annotate,
+ annotateElement: annotateElement,
+ annotateBehavior: annotateBehavior,
+ clean: clean,
+ cleanElement: cleanElement,
+ featureElement: featureElement,
+};
+
+},{"./jsdoc":12,"dom5":38}],6:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// jshint node: true
+'use strict';
+var estraverse = require('estraverse');
+
+var esutil = require('./esutil');
+var findAlias = require('./find-alias');
+var analyzeProperties = require('./analyze-properties');
+var astValue = require('./ast-value');
+
+var elementFinder = function elementFinder() {
+ /**
+ * The list of elements exported by each traversed script.
+ */
+ var elements = [];
+
+ /**
+ * The element being built during a traversal;
+ */
+ var element;
+
+ /**
+ * a set of special case properties. these should only be called
+ * when we know we're inside an element definition.
+ * @type {Object}
+ */
+ var propertyHandlers = {
+ is: function(node) {
+ if (node.type == 'Literal') {
+ element.is = node.value;
+ }
+ },
+ properties: function(node) {
+
+ var props = analyzeProperties(node);
+
+ for (var i=0; i<props.length; i++) {
+ element.properties.push(props[i]);
+ }
+ },
+ behaviors: function(node) {
+ if (node.type != 'ArrayExpression') {
+ return;
+ }
+ element.behaviors = [];
+
+ for (var i=0; i<node.elements.length; i++) {
+ var v = astValue.expressionToValue(node.elements[i]);
+ if (v === undefined)
+ v = astValue.CANT_CONVERT;
+ element.behaviors.push(v);
+ }
+ }
+ };
+
+ var visitors = {
+ enterCallExpression: function enterCallExpression(node, parent) {
+ var callee = node.callee;
+ if (callee.type == 'Identifier') {
+
+ if (callee.name == 'Polymer') {
+ element = {
+ type: 'element',
+ desc: esutil.getAttachedComment(parent),
+ events: esutil.getEventComments(parent).map( function(event) {
+ return {desc: event};
+ })
+ };
+ }
+ }
+ },
+ leaveCallExpression: function leaveCallExpression(node, parent) {
+ var callee = node.callee;
+ if (callee.type == 'Identifier') {
+ if (callee.name == 'Polymer') {
+ if (element) {
+ elements.push(element);
+ element = undefined;
+ }
+ }
+ }
+ },
+ enterObjectExpression: function enterObjectExpression(node, parent) {
+ if (element && !element.properties) {
+ element.properties = [];
+ for (var i = 0; i < node.properties.length; i++) {
+ var prop = node.properties[i];
+ var name = esutil.objectKeyToString(prop.key);
+ if (!name) {
+ throw {
+ message: 'Cant determine name for property key.',
+ location: node.loc.start
+ };
+ }
+
+ if (name in propertyHandlers) {
+ propertyHandlers[name](prop.value);
+ continue;
+ }
+ element.properties.push(esutil.toPropertyDescriptor(prop));
+ }
+ return estraverse.VisitorOption.Skip;
+ }
+ }
+ };
+ return {visitors: visitors, elements: elements};
+};
+
+module.exports = elementFinder;
+
+},{"./analyze-properties":2,"./ast-value":3,"./esutil":7,"./find-alias":9,"estraverse":72}],7:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// jshint node: true
+'use strict';
+var estraverse = require("estraverse");
+
+/**
+ * Returns whether an Espree node matches a particular object path.
+ *
+ * e.g. you have a MemberExpression node, and want to see whether it represents
+ * `Foo.Bar.Baz`:
+ *
+ * matchesCallExpression(node, ['Foo', 'Bar', 'Baz'])
+ *
+ * @param {Node} expression The Espree node to match against.
+ * @param {Array<string>} path The path to look for.
+ */
+function matchesCallExpression(expression, path) {
+ if (!expression.property || !expression.object) return;
+ console.assert(path.length >= 2);
+
+ // Unravel backwards, make sure properties match each step of the way.
+ if (expression.property.name !== path[path.length - 1]) return false;
+ // We've got ourselves a final member expression.
+ if (path.length == 2 && expression.object.type === 'Identifier') {
+ return expression.object.name === path[0];
+ }
+ // Nested expressions.
+ if (path.length > 2 && expression.object.type == 'MemberExpression') {
+ return matchesCallExpression(expression.object, path.slice(0, path.length - 1));
+ }
+
+ return false;
+}
+
+/**
+ * @param {Node} key The node representing an object key or expression.
+ * @return {string} The name of that key.
+ */
+function objectKeyToString(key) {
+ if (key.type == 'Identifier') {
+ return key.name;
+ }
+ if (key.type == 'Literal') {
+ return key.value;
+ }
+ if (key.type == 'MemberExpression') {
+ return objectKeyToString(key.object) + '.' + objectKeyToString(key.property);
+ }
+}
+
+var CLOSURE_CONSTRUCTOR_MAP = {
+ 'Boolean': 'boolean',
+ 'Number': 'number',
+ 'String': 'string',
+};
+
+/**
+ * AST expression -> Closure type.
+ *
+ * Accepts literal values, and native constructors.
+ *
+ * @param {Node} node An Espree expression node.
+ * @return {string} The type of that expression, in Closure terms.
+ */
+function closureType(node) {
+ if (node.type.match(/Expression$/)) {
+ return node.type.substr(0, node.type.length - 10);
+ } else if (node.type === 'Literal') {
+ return typeof node.value;
+ } else if (node.type === 'Identifier') {
+ return CLOSURE_CONSTRUCTOR_MAP[node.name] || node.name;
+ } else {
+ throw {
+ message: 'Unknown Closure type for node: ' + node.type,
+ location: node.loc.start,
+ };
+ }
+}
+
+/**
+ * @param {Node} node
+ * @return {?string}
+ */
+function getAttachedComment(node) {
+ var comments = getLeadingComments(node) || getLeadingComments(node.key);
+ if (!comments) {
+ return;
+ }
+ return comments[comments.length - 1];
+}
+
+/**
+ * Returns all comments from a tree defined with @event.
+ * @param {Node} node [description]
+ * @return {[type]} [description]
+ */
+function getEventComments(node) {
+ var eventComments = [];
+ estraverse.traverse(node, {
+ enter: function (node) {
+ var comments = (node.leadingComments || []).concat(node.trailingComments || [])
+ .map( function(commentAST) {
+ return commentAST.value;
+ })
+ .filter( function(comment) {
+ return comment.indexOf("@event") != -1;
+ });
+ eventComments = eventComments.concat(comments);
+ }
+ });
+ // dedup
+ return eventComments.filter( function(el, index, array) {
+ return array.indexOf(el) === index;
+ });
+}
+
+/**
+ * @param {Node} node
+ * @param
+ * @return {Array.<string>}
+ */
+function getLeadingComments(node) {
+ if (!node) {
+ return;
+ }
+ var comments = node.leadingComments;
+ if (!comments || comments.length === 0) return;
+ return comments.map(function(comment) {
+ return comment.value;
+ });
+}
+
+/**
+ * Converts a parse5 Property AST node into its Hydrolysis representation.
+ *
+ * @param {Node} node
+ * @return {PropertyDescriptor}
+ */
+function toPropertyDescriptor(node) {
+ var result = {
+ name: objectKeyToString(node.key),
+ type: closureType(node.value),
+ desc: getAttachedComment(node)
+ };
+
+ if (node.value.type === 'FunctionExpression') {
+ result.params = (node.value.params || []).map(function(param) {
+ return {name: param.name};
+ });
+ }
+
+ return result;
+}
+
+module.exports = {
+ closureType: closureType,
+ getAttachedComment: getAttachedComment,
+ getEventComments: getEventComments,
+ matchesCallExpression: matchesCallExpression,
+ objectKeyToString: objectKeyToString,
+ toPropertyDescriptor: toPropertyDescriptor,
+};
+
+},{"estraverse":72}],8:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// jshint node: true
+'use strict';
+var estraverse = require('estraverse');
+
+var esutil = require('./esutil');
+
+var numFeatures = 0;
+
+module.exports = function featureFinder() {
+ /** @type {!Array<FeatureDescriptor>} The features we've found. */
+ var features = [];
+
+ var visitors = {
+
+ enterCallExpression: function enterCallExpression(node, parent) {
+ if (!esutil.matchesCallExpression(node.callee, ['Polymer', 'Base', '_addFeature'])) {
+ return;
+ }
+ /** @type {!FeatureDescriptor} */
+ var feature = {};
+ this._extractDesc(feature, node, parent);
+ this._extractProperties(feature, node, parent);
+
+ features.push(feature);
+ },
+
+ _extractDesc: function _extractDesc(feature, node, parent) {
+ feature.desc = esutil.getAttachedComment(parent);
+ },
+
+ _extractProperties: function _extractProperties(feature, node, parent) {
+ var featureNode = node.arguments[0];
+ if (featureNode.type !== 'ObjectExpression') {
+ console.warn(
+ 'Expected first argument to Polymer.Base._addFeature to be an object.',
+ 'Got', featureNode.type, 'instead.');
+ return;
+ }
+ if (!featureNode.properties) return;
+
+ feature.properties = featureNode.properties.map(esutil.toPropertyDescriptor);
+ },
+
+ };
+
+ return {visitors: visitors, features: features};
+};
+
+},{"./esutil":7,"estraverse":72}],9:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// jshint node: true
+'use strict';
+var findAlias = function findAlias(names, aliases, name) {
+ if (!names) {
+ return null;
+ }
+ return aliases[names.indexOf(name)];
+};
+
+module.exports = findAlias;
+
+},{}],10:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// jshint node: true
+'use strict';
+var dom5 = require('dom5');
+
+var p = dom5.predicates;
+
+var isHtmlImportNode = p.AND(
+ p.hasTagName('link'),
+ p.hasAttrValue('rel', 'import'),
+ p.NOT(
+ p.hasAttrValue('type', 'css')
+ )
+);
+
+var isStyleNode = p.OR(
+ // inline style
+ p.hasTagName('style'),
+ // external stylesheet
+ p.AND(
+ p.hasTagName('link'),
+ p.hasAttrValue('rel', 'stylesheet')
+ ),
+ // polymer specific external stylesheet
+ p.AND(
+ p.hasTagName('link'),
+ p.hasAttrValue('rel', 'import'),
+ p.hasAttrValue('type', 'css')
+ )
+);
+
+function addNode(node, registry) {
+ if (isHtmlImportNode(node)) {
+ registry.import.push(node);
+ } else if (isStyleNode(node)) {
+ registry.style.push(node);
+ } else if (registry.hasOwnProperty(node.tagName)) {
+ registry[node.tagName].push(node);
+ }
+}
+
+function getLineAndColumn(string, charNumber) {
+ if (charNumber > string.length) {
+ return undefined;
+ }
+ // TODO(ajo): Caching the line lengths of each document could be much faster.
+ var sliced = string.slice(0,charNumber+1);
+ var split = sliced.split('\n');
+ var line = split.length;
+ var column = split[split.length - 1].length;
+ return {line: line, column: column};
+}
+
+/**
+* Parse5's representation of a parsed html document.
+* @typedef {Object} DocumentAST
+*/
+
+/**
+* The ASTs of the HTML elements needed to represent Polymer elements.
+* @typedef {Object} ParsedImport
+* @property {Array<DocumentAST>} template The entry points to the AST at each outermost template tag.
+* @property {Array<DocumentAST>} script The entry points to the AST at each script tag not inside a template.
+* @property {Array<DocumentAST>} style The entry points to the AST at style tag outside a template.
+* @property {Array<DocumentAST>} dom-module The entry points to the AST at each outermost dom-module element.
+* @property {DocumentAST} ast The full parse5 ast for the document.
+*/
+
+/**
+* Parse html into ASTs.
+* @param {string} htmlString A utf8, html5 document containing polymer element or module definitons.
+* @param {string} href The path of the document.
+* @return {ParsedImport}
+*/
+var importParse = function importParse(htmlString, href) {
+ var doc;
+ try {
+ doc = dom5.parse(htmlString, {locationInfo: true});
+ } catch (err) {
+ console.log(err);
+ return null;
+ }
+
+ // Add line/column information
+ dom5.treeMap(doc, function(node) {
+ if (node.__location && node.__location.start >= 0) {
+ node.__locationDetail = getLineAndColumn(htmlString, node.__location.start);
+ if (href) {
+ node.__ownerDocument = href;
+ }
+ }
+ });
+
+ var registry = {
+ base: [],
+ template: [],
+ script: [],
+ style: [],
+ import: [],
+ 'dom-module': []};
+
+ var queue = [].concat(doc.childNodes);
+ var nextNode;
+ while (queue.length > 0) {
+ nextNode = queue.shift();
+ if (nextNode && nextNode.tagName) {
+ queue = queue.concat(nextNode.childNodes);
+ addNode(nextNode, registry);
+ }
+ }
+ registry.ast = doc;
+ return registry;
+};
+
+module.exports = importParse;
+
+},{"dom5":38}],11:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+/**
+* Finds and annotates the Polymer() and modulate() calls in javascript.
+*/
+// jshint node: true
+'use strict';
+var espree = require('espree');
+var estraverse = require('estraverse');
+
+var behaviorFinder = require('./behavior-finder');
+var elementFinder = require('./element-finder');
+var featureFinder = require('./feature-finder');
+
+function traverse(visitorRegistries) {
+ var visitor;
+ function applyVisitors(name, node, parent) {
+ var returnVal;
+ for (var i = 0; i < visitorRegistries.length; i++) {
+ if (name in visitorRegistries[i]) {
+ returnVal = visitorRegistries[i][name](node, parent);
+ if (returnVal) {
+ return returnVal;
+ }
+ }
+ }
+ }
+ return {
+ enter: function(node, parent) {
+ visitor = 'enter' + node.type;
+ return applyVisitors(visitor, node, parent);
+ },
+ leave: function(node, parent) {
+ visitor = 'leave' + node.type;
+ return applyVisitors(visitor, node, parent);
+ }
+ };
+}
+
+var jsParse = function jsParse(jsString) {
+ var script = espree.parse(jsString, {
+ attachComment: true,
+ comment: true,
+ loc: true,
+ ecmaFeatures: {
+ arrowFunctions: true,
+ blockBindings: true,
+ destructuring: true,
+ regexYFlag: true,
+ regexUFlag: true,
+ templateStrings: true,
+ binaryLiterals: true,
+ unicodeCodePointEscapes: true,
+ defaultParams: true,
+ restParams: true,
+ forOf: true,
+ objectLiteralComputedProperties: true,
+ objectLiteralShorthandMethods: true,
+ objectLiteralShorthandProperties: true,
+ objectLiteralDuplicateProperties: true,
+ generators: true,
+ spread: true,
+ classes: true,
+ modules: true,
+ jsx: true,
+ globalReturn: true,
+ }
+ });
+
+ var featureInfo = featureFinder();
+ var behaviorInfo = behaviorFinder();
+ var elementInfo = elementFinder();
+
+ var visitors = [featureInfo, behaviorInfo, elementInfo].map(function(info) {
+ return info.visitors;
+ });
+ estraverse.traverse(script, traverse(visitors));
+
+ return {
+ behaviors: behaviorInfo.behaviors,
+ elements: elementInfo.elements,
+ features: featureInfo.features,
+ };
+};
+
+module.exports = jsParse;
+
+},{"./behavior-finder":4,"./element-finder":6,"./feature-finder":8,"espree":61,"estraverse":72}],12:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// jshint node: true
+'use strict';
+
+var doctrine = require('doctrine');
+
+/**
+ * An annotated JSDoc block tag, all fields are optionally processed except for
+ * the tag:
+ *
+ * @TAG {TYPE} NAME DESC
+ *
+ * `line` and `col` indicate the position of the first character of text that
+ * the tag was extracted from - relative to the first character of the comment
+ * contents (e.g. the value of `desc` on a descriptor node). Lines are
+ * 1-indexed.
+ *
+ * @typedef {{
+ * tag: string,
+ * type: ?string,
+ * name: ?string,
+ * description: ?string,
+ * }}
+ */
+var JsdocTag;
+
+/**
+ * The parsed representation of a JSDoc comment.
+ *
+ * @typedef {{
+ * description: ?string,
+ * tags: Array<JsdocTag>,
+ * }}
+ */
+var JsdocAnnotation;
+
+/**
+ * doctrine configuration,
+ * CURRENTLY UNUSED BECAUSE PRIVATE
+ */
+// function configureDoctrine() {
+
+// // @hero [path/to/image]
+// doctrine.Rules['hero'] = ['parseNamePathOptional', 'ensureEnd'];
+
+// // // @demo [path/to/demo] [Demo title]
+// doctrine.Rules['demo'] = ['parseNamePathOptional', 'parseDescription', 'ensureEnd'];
+
+// // // @polymerBehavior [Polymer.BehaviorName]
+// doctrine.Rules['polymerBehavior'] = ['parseNamePathOptional', 'ensureEnd'];
+// }
+// configureDoctrine();
+
+// @demo [path] [title]
+function parseDemo(tag) {
+ var match = (tag.description || "").match(/^\s*(\S*)\s*(.*)$/);
+ return {
+ tag: 'demo',
+ type: null,
+ name: match ? match[1] : null,
+ description: match ? match[2] : null
+ };
+}
+
+// @hero [path]
+function parseHero(tag) {
+ return {
+ tag: tag.title,
+ type: null,
+ name: tag.description,
+ description: null
+ };
+}
+
+// @polymerBehavior [name]
+function parsePolymerBehavior(tag) {
+ return {
+ tag: tag.title,
+ type: null,
+ name: tag.description,
+ description: null
+ };
+}
+
+// @pseudoElement name
+function parsePseudoElement(tag) {
+ return {
+ tag: tag.title,
+ type: null,
+ name: tag.description,
+ description: null
+ };
+}
+
+var CUSTOM_TAGS = {
+ demo: parseDemo,
+ hero: parseHero,
+ polymerBehavior: parsePolymerBehavior,
+ pseudoElement: parsePseudoElement
+};
+
+/**
+ * Convert doctrine tags to hydrolysis tag format
+ */
+function _tagsToHydroTags(tags) {
+ if (!tags)
+ return null;
+ return tags.map( function(tag) {
+ if (tag.title in CUSTOM_TAGS) {
+ return CUSTOM_TAGS[tag.title](tag);
+ }
+ else {
+ return {
+ tag: tag.title,
+ type: tag.type ? doctrine.type.stringify(tag.type) : null,
+ name: tag.name,
+ description: tag.description,
+ };
+ }
+ });
+}
+
+/**
+ * removes leading *, and any space before it
+ * @param {string} description -- js doc description
+ */
+function _removeLeadingAsterisks(description) {
+ if ((typeof description) !== 'string')
+ return description;
+
+ return description
+ .split('\n')
+ .map( function(line) {
+ // remove leading '\s*' from each line
+ var match = line.match(/^[\s]*\*\s?(.*)$/);
+ return match ? match[1] : line;
+ })
+ .join('\n');
+}
+
+/**
+ * Given a JSDoc string (minus opening/closing comment delimiters), extract its
+ * description and tags.
+ *
+ * @param {string} docs
+ * @return {?JsdocAnnotation}
+ */
+function parseJsdoc(docs) {
+ docs = _removeLeadingAsterisks(docs);
+ var d = doctrine.parse(docs, {
+ unwrap: false,
+ lineNumber: true,
+ preserveWhitespace: true
+ });
+ return {
+ description: d.description,
+ tags: _tagsToHydroTags(d.tags)
+ };
+}
+
+// Utility
+
+/**
+ * @param {JsdocAnnotation} jsdoc
+ * @param {string} tagName
+ * @return {boolean}
+ */
+function hasTag(jsdoc, tagName) {
+ if (!jsdoc || !jsdoc.tags) return false;
+ return jsdoc.tags.some(function(tag) { return tag.tag === tagName; });
+}
+
+/**
+ * Finds the first JSDoc tag matching `name` and returns its value at `key`.
+ *
+ * @param {JsdocAnnotation} jsdoc
+ * @param {string} tagName
+ * @param {string=} key If omitted, the entire tag object is returned.
+ * @return {?string|Object}
+ */
+function getTag(jsdoc, tagName, key) {
+ if (!jsdoc || !jsdoc.tags) return false;
+ for (var i = 0; i < jsdoc.tags.length; i++) {
+ var tag = jsdoc.tags[i];
+ if (tag.tag === tagName) {
+ return key ? tag[key] : tag;
+ }
+ }
+ return null;
+}
+
+/**
+ * @param {?string} text
+ * @return {?string}
+ */
+function unindent(text) {
+ if (!text) return text;
+ var lines = text.replace(/\t/g, ' ').split('\n');
+ var indent = lines.reduce(function(prev, line) {
+ if (/^\s*$/.test(line)) return prev; // Completely ignore blank lines.
+
+ var lineIndent = line.match(/^(\s*)/)[0].length;
+ if (prev === null) return lineIndent;
+ return lineIndent < prev ? lineIndent : prev;
+ }, null);
+
+ return lines.map(function(l) { return l.substr(indent); }).join('\n');
+}
+
+module.exports = {
+ getTag: getTag,
+ hasTag: hasTag,
+ parseJsdoc: parseJsdoc,
+ unindent: unindent
+};
+
+},{"doctrine":29}],13:[function(require,module,exports){
+(function (global){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+// jshint node:true
+'use strict';
+
+// jshint -W079
+// Promise polyfill
+var Promise = global.Promise || require('es6-promise').Promise;
+// jshint +W079
+
+function Deferred() {
+ var self = this;
+ this.promise = new Promise(function(resolve, reject) {
+ self.resolve = resolve;
+ self.reject = reject;
+ });
+}
+
+/**
+ * An object that knows how to resolve resources.
+ * @typedef {Object} Resolver
+ * @memberof hydrolysis
+ * @property {function(string, Deferred): boolean} accept Attempt to resolve
+ * `deferred` with the contents the specified URL. Returns false if the
+ * Resolver is unable to resolve the URL.
+ */
+
+
+/**
+ * A FileLoader lets you resolve URLs with a set of potential resolvers.
+ * @constructor
+ * @memberof hydrolysis
+ */
+function FileLoader() {
+ this.resolvers = [];
+ // map url -> Deferred
+ this.requests = {};
+}
+FileLoader.prototype = {
+
+ /**
+ * Add an instance of a Resolver class to the list of url resolvers
+ *
+ * Ordering of resolvers is most to least recently added
+ * The first resolver to "accept" the url wins.
+ * @param {Resolver} resolver The resolver to add.
+ */
+ addResolver: function(resolver) {
+ this.resolvers.push(resolver);
+ },
+
+ /**
+ * Return a promise for an absolute url
+ *
+ * Url requests are deduplicated by the loader, returning the same Promise for
+ * identical urls
+ *
+ * @param {string} url The absolute url to request.
+ * @return {Promise.<string>} A promise that resolves to the contents of the URL.
+ */
+ request: function(uri) {
+ var promise;
+
+ if (!(uri in this.requests)) {
+ var handled = false;
+ var deferred = new Deferred();
+ this.requests[uri] = deferred;
+
+ // loop backwards through resolvers until one "accepts" the request
+ for (var i = this.resolvers.length - 1, r; i >= 0; i--) {
+ r = this.resolvers[i];
+ if (r.accept(uri, deferred)) {
+ handled = true;
+ break;
+ }
+ }
+
+ if (!handled) {
+ deferred.reject('no resolver found');
+ }
+
+ promise = deferred.promise;
+ } else {
+ promise = this.requests[uri].promise;
+ }
+
+ return promise;
+ }
+};
+
+module.exports = FileLoader;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{"es6-promise":60}],14:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+// jshint node:true
+'use strict';
+
+var fs = require('fs');
+var path = require('path');
+var url = require('url');
+
+function getFile(filepath, deferred) {
+ fs.readFile(filepath, 'utf-8', function(err, content) {
+ if (err) {
+ deferred.reject(err);
+ } else {
+ deferred.resolve(content);
+ }
+ });
+}
+
+/**
+ * Returns true if `patha` is a sibling or aunt of `pathb`.
+ * @return {boolean}
+ */
+function isSiblingOrAunt(patha, pathb) {
+ var parent = path.dirname(patha);
+ if (pathb.indexOf(patha) === -1 && pathb.indexOf(parent) === 0) {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Change `localPath` from a sibling of `basePath` to be a child of
+ * `basePath` joined with `redirect`.
+ * @return {string}
+ */
+function redirectSibling(basePath, localPath, redirect) {
+ var parent = path.dirname(basePath);
+ var redirected = path.join(basePath, redirect, localPath.slice(parent.length));
+ return redirected;
+}
+
+/**
+ * Resolves requests via the file system.
+ * @constructor
+ * @memberof hydrolysis
+ * @param {Object} config configuration options.
+ * @param {string} config.host Hostname to match for absolute urls.
+ * Matches "/" by default
+ * @param {string} config.basePath Prefix directory for components in url.
+ * Defaults to "/".
+ * @param {string} config.root Filesystem root to search. Defaults to the
+ * current working directory.
+ * @param {string} config.redirect Where to redirect lookups to siblings.
+ */
+function FSResolver(config) {
+ this.config = config || {};
+}
+FSResolver.prototype = {
+ accept: function(uri, deferred) {
+ var parsed = url.parse(uri);
+ var host = this.config.host;
+ var base = this.config.basePath && decodeURIComponent(this.config.basePath);
+ var root = this.config.root && path.normalize(this.config.root);
+ var redirect = this.config.redirect;
+
+ var local;
+
+ if (!parsed.hostname || parsed.hostname === host) {
+ local = parsed.pathname;
+ }
+
+ if (local) {
+ // un-escape HTML escapes
+ local = decodeURIComponent(local);
+
+ if (base) {
+ local = path.relative(base, local);
+ }
+ if (root) {
+ local = path.join(root, local);
+ }
+
+ if (redirect && isSiblingOrAunt(root, local)) {
+ local = redirectSibling(root, local, redirect);
+ }
+
+ getFile(local, deferred);
+ return true;
+ }
+
+ return false;
+ }
+};
+
+module.exports = FSResolver;
+
+},{"fs":17,"path":20,"url":26}],15:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+// jshint node:true
+'use strict';
+
+/**
+ * A resolver that resolves to null any uri matching config.
+ * @constructor
+ * @memberof hydrolysis
+ * @param {string} config The url to `accept`.
+ */
+function NoopResolver(config) {
+ this.config = config;
+}
+
+NoopResolver.prototype = {
+
+ /**
+ * @param {string} uri The absolute URI being requested.
+ * @param {!Deferred} deferred The deferred promise that should be resolved if
+ * this resolver handles the URI.
+ * @return {boolean} Whether the URI is handled by this resolver.
+ */
+ accept: function(uri, deferred) {
+ if (!this.config.test) {
+ if (uri.search(this.config) == -1) {
+ return false;
+ }
+ } else if (!this.config.test(uri)) return false;
+
+ deferred.resolve('');
+ return true;
+ }
+};
+
+module.exports = NoopResolver;
+
+},{}],16:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+// jshint node:true
+'use strict';
+
+function getFile(url, deferred, config) {
+ /* global XMLHttpRequest:false */
+ var x = new XMLHttpRequest();
+ x.onload = function() {
+ var status = x.status || 0;
+ if (status >= 200 && status < 300) {
+ deferred.resolve(x.response);
+ } else {
+ deferred.reject('xhr status: ' + status);
+ }
+ };
+ x.onerror = function(e) {
+ deferred.reject(e);
+ };
+ x.open('GET', url, true);
+ if (config && config.responseType) {
+ x.responseType = config.responseType;
+ }
+ x.send();
+}
+
+/**
+ * Construct a resolver that requests resources over XHR.
+ * @constructor
+ * @memberof hydrolysis
+ * @param {Object} config configuration arguments.
+ * @param {string} config.responseType Type of object to be returned by the
+ * XHR. Defaults to 'text', accepts 'document', 'arraybuffer', and 'json'.
+ */
+function XHRResolver(config) {
+ this.config = config;
+}
+XHRResolver.prototype = {
+ accept: function(uri, deferred) {
+ getFile(uri, deferred, this.config);
+ return true;
+ }
+};
+
+module.exports = XHRResolver;
+
+},{}],17:[function(require,module,exports){
+
+},{}],18:[function(require,module,exports){
+// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
+//
+// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
+//
+// Originally from narwhal.js (http://narwhaljs.org)
+// Copyright (c) 2009 Thomas Robinson <280north.com>
+//
+// 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 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.
+
+// when used in node, this will actually load the util module we depend on
+// versus loading the builtin util module as happens otherwise
+// this is a bug in node module loading as far as I am concerned
+var util = require('util/');
+
+var pSlice = Array.prototype.slice;
+var hasOwn = Object.prototype.hasOwnProperty;
+
+// 1. The assert module provides functions that throw
+// AssertionError's when particular conditions are not met. The
+// assert module must conform to the following interface.
+
+var assert = module.exports = ok;
+
+// 2. The AssertionError is defined in assert.
+// new assert.AssertionError({ message: message,
+// actual: actual,
+// expected: expected })
+
+assert.AssertionError = function AssertionError(options) {
+ this.name = 'AssertionError';
+ this.actual = options.actual;
+ this.expected = options.expected;
+ this.operator = options.operator;
+ if (options.message) {
+ this.message = options.message;
+ this.generatedMessage = false;
+ } else {
+ this.message = getMessage(this);
+ this.generatedMessage = true;
+ }
+ var stackStartFunction = options.stackStartFunction || fail;
+
+ if (Error.captureStackTrace) {
+ Error.captureStackTrace(this, stackStartFunction);
+ }
+ else {
+ // non v8 browsers so we can have a stacktrace
+ var err = new Error();
+ if (err.stack) {
+ var out = err.stack;
+
+ // try to strip useless frames
+ var fn_name = stackStartFunction.name;
+ var idx = out.indexOf('\n' + fn_name);
+ if (idx >= 0) {
+ // once we have located the function frame
+ // we need to strip out everything before it (and its line)
+ var next_line = out.indexOf('\n', idx + 1);
+ out = out.substring(next_line + 1);
+ }
+
+ this.stack = out;
+ }
+ }
+};
+
+// assert.AssertionError instanceof Error
+util.inherits(assert.AssertionError, Error);
+
+function replacer(key, value) {
+ if (util.isUndefined(value)) {
+ return '' + value;
+ }
+ if (util.isNumber(value) && !isFinite(value)) {
+ return value.toString();
+ }
+ if (util.isFunction(value) || util.isRegExp(value)) {
+ return value.toString();
+ }
+ return value;
+}
+
+function truncate(s, n) {
+ if (util.isString(s)) {
+ return s.length < n ? s : s.slice(0, n);
+ } else {
+ return s;
+ }
+}
+
+function getMessage(self) {
+ return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' +
+ self.operator + ' ' +
+ truncate(JSON.stringify(self.expected, replacer), 128);
+}
+
+// At present only the three keys mentioned above are used and
+// understood by the spec. Implementations or sub modules can pass
+// other keys to the AssertionError's constructor - they will be
+// ignored.
+
+// 3. All of the following functions must throw an AssertionError
+// when a corresponding condition is not met, with a message that
+// may be undefined if not provided. All assertion methods provide
+// both the actual and expected values to the assertion error for
+// display purposes.
+
+function fail(actual, expected, message, operator, stackStartFunction) {
+ throw new assert.AssertionError({
+ message: message,
+ actual: actual,
+ expected: expected,
+ operator: operator,
+ stackStartFunction: stackStartFunction
+ });
+}
+
+// EXTENSION! allows for well behaved errors defined elsewhere.
+assert.fail = fail;
+
+// 4. Pure assertion tests whether a value is truthy, as determined
+// by !!guard.
+// assert.ok(guard, message_opt);
+// This statement is equivalent to assert.equal(true, !!guard,
+// message_opt);. To test strictly for the value true, use
+// assert.strictEqual(true, guard, message_opt);.
+
+function ok(value, message) {
+ if (!value) fail(value, true, message, '==', assert.ok);
+}
+assert.ok = ok;
+
+// 5. The equality assertion tests shallow, coercive equality with
+// ==.
+// assert.equal(actual, expected, message_opt);
+
+assert.equal = function equal(actual, expected, message) {
+ if (actual != expected) fail(actual, expected, message, '==', assert.equal);
+};
+
+// 6. The non-equality assertion tests for whether two objects are not equal
+// with != assert.notEqual(actual, expected, message_opt);
+
+assert.notEqual = function notEqual(actual, expected, message) {
+ if (actual == expected) {
+ fail(actual, expected, message, '!=', assert.notEqual);
+ }
+};
+
+// 7. The equivalence assertion tests a deep equality relation.
+// assert.deepEqual(actual, expected, message_opt);
+
+assert.deepEqual = function deepEqual(actual, expected, message) {
+ if (!_deepEqual(actual, expected)) {
+ fail(actual, expected, message, 'deepEqual', assert.deepEqual);
+ }
+};
+
+function _deepEqual(actual, expected) {
+ // 7.1. All identical values are equivalent, as determined by ===.
+ if (actual === expected) {
+ return true;
+
+ } else if (util.isBuffer(actual) && util.isBuffer(expected)) {
+ if (actual.length != expected.length) return false;
+
+ for (var i = 0; i < actual.length; i++) {
+ if (actual[i] !== expected[i]) return false;
+ }
+
+ return true;
+
+ // 7.2. If the expected value is a Date object, the actual value is
+ // equivalent if it is also a Date object that refers to the same time.
+ } else if (util.isDate(actual) && util.isDate(expected)) {
+ return actual.getTime() === expected.getTime();
+
+ // 7.3 If the expected value is a RegExp object, the actual value is
+ // equivalent if it is also a RegExp object with the same source and
+ // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
+ } else if (util.isRegExp(actual) && util.isRegExp(expected)) {
+ return actual.source === expected.source &&
+ actual.global === expected.global &&
+ actual.multiline === expected.multiline &&
+ actual.lastIndex === expected.lastIndex &&
+ actual.ignoreCase === expected.ignoreCase;
+
+ // 7.4. Other pairs that do not both pass typeof value == 'object',
+ // equivalence is determined by ==.
+ } else if (!util.isObject(actual) && !util.isObject(expected)) {
+ return actual == expected;
+
+ // 7.5 For all other Object pairs, including Array objects, equivalence is
+ // determined by having the same number of owned properties (as verified
+ // with Object.prototype.hasOwnProperty.call), the same set of keys
+ // (although not necessarily the same order), equivalent values for every
+ // corresponding key, and an identical 'prototype' property. Note: this
+ // accounts for both named and indexed properties on Arrays.
+ } else {
+ return objEquiv(actual, expected);
+ }
+}
+
+function isArguments(object) {
+ return Object.prototype.toString.call(object) == '[object Arguments]';
+}
+
+function objEquiv(a, b) {
+ if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b))
+ return false;
+ // an identical 'prototype' property.
+ if (a.prototype !== b.prototype) return false;
+ // if one is a primitive, the other must be same
+ if (util.isPrimitive(a) || util.isPrimitive(b)) {
+ return a === b;
+ }
+ var aIsArgs = isArguments(a),
+ bIsArgs = isArguments(b);
+ if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
+ return false;
+ if (aIsArgs) {
+ a = pSlice.call(a);
+ b = pSlice.call(b);
+ return _deepEqual(a, b);
+ }
+ var ka = objectKeys(a),
+ kb = objectKeys(b),
+ key, i;
+ // having the same number of owned properties (keys incorporates
+ // hasOwnProperty)
+ if (ka.length != kb.length)
+ return false;
+ //the same set of keys (although not necessarily the same order),
+ ka.sort();
+ kb.sort();
+ //~~~cheap key test
+ for (i = ka.length - 1; i >= 0; i--) {
+ if (ka[i] != kb[i])
+ return false;
+ }
+ //equivalent values for every corresponding key, and
+ //~~~possibly expensive deep test
+ for (i = ka.length - 1; i >= 0; i--) {
+ key = ka[i];
+ if (!_deepEqual(a[key], b[key])) return false;
+ }
+ return true;
+}
+
+// 8. The non-equivalence assertion tests for any deep inequality.
+// assert.notDeepEqual(actual, expected, message_opt);
+
+assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
+ if (_deepEqual(actual, expected)) {
+ fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
+ }
+};
+
+// 9. The strict equality assertion tests strict equality, as determined by ===.
+// assert.strictEqual(actual, expected, message_opt);
+
+assert.strictEqual = function strictEqual(actual, expected, message) {
+ if (actual !== expected) {
+ fail(actual, expected, message, '===', assert.strictEqual);
+ }
+};
+
+// 10. The strict non-equality assertion tests for strict inequality, as
+// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
+
+assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
+ if (actual === expected) {
+ fail(actual, expected, message, '!==', assert.notStrictEqual);
+ }
+};
+
+function expectedException(actual, expected) {
+ if (!actual || !expected) {
+ return false;
+ }
+
+ if (Object.prototype.toString.call(expected) == '[object RegExp]') {
+ return expected.test(actual);
+ } else if (actual instanceof expected) {
+ return true;
+ } else if (expected.call({}, actual) === true) {
+ return true;
+ }
+
+ return false;
+}
+
+function _throws(shouldThrow, block, expected, message) {
+ var actual;
+
+ if (util.isString(expected)) {
+ message = expected;
+ expected = null;
+ }
+
+ try {
+ block();
+ } catch (e) {
+ actual = e;
+ }
+
+ message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
+ (message ? ' ' + message : '.');
+
+ if (shouldThrow && !actual) {
+ fail(actual, expected, 'Missing expected exception' + message);
+ }
+
+ if (!shouldThrow && expectedException(actual, expected)) {
+ fail(actual, expected, 'Got unwanted exception' + message);
+ }
+
+ if ((shouldThrow && actual && expected &&
+ !expectedException(actual, expected)) || (!shouldThrow && actual)) {
+ throw actual;
+ }
+}
+
+// 11. Expected to throw an error:
+// assert.throws(block, Error_opt, message_opt);
+
+assert.throws = function(block, /*optional*/error, /*optional*/message) {
+ _throws.apply(this, [true].concat(pSlice.call(arguments)));
+};
+
+// EXTENSION! This is annoying to write outside this module.
+assert.doesNotThrow = function(block, /*optional*/message) {
+ _throws.apply(this, [false].concat(pSlice.call(arguments)));
+};
+
+assert.ifError = function(err) { if (err) {throw err;}};
+
+var objectKeys = Object.keys || function (obj) {
+ var keys = [];
+ for (var key in obj) {
+ if (hasOwn.call(obj, key)) keys.push(key);
+ }
+ return keys;
+};
+
+},{"util/":28}],19:[function(require,module,exports){
+if (typeof Object.create === 'function') {
+ // implementation from standard node.js 'util' module
+ module.exports = function inherits(ctor, superCtor) {
+ ctor.super_ = superCtor
+ ctor.prototype = Object.create(superCtor.prototype, {
+ constructor: {
+ value: ctor,
+ enumerable: false,
+ writable: true,
+ configurable: true
+ }
+ });
+ };
+} else {
+ // old school shim for old browsers
+ module.exports = function inherits(ctor, superCtor) {
+ ctor.super_ = superCtor
+ var TempCtor = function () {}
+ TempCtor.prototype = superCtor.prototype
+ ctor.prototype = new TempCtor()
+ ctor.prototype.constructor = ctor
+ }
+}
+
+},{}],20:[function(require,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// 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.
+
+// resolves . and .. elements in a path array with directory names there
+// must be no slashes, empty elements, or device names (c:\) in the array
+// (so also no leading and trailing slashes - it does not distinguish
+// relative and absolute paths)
+function normalizeArray(parts, allowAboveRoot) {
+ // if the path tries to go above the root, `up` ends up > 0
+ var up = 0;
+ for (var i = parts.length - 1; i >= 0; i--) {
+ var last = parts[i];
+ if (last === '.') {
+ parts.splice(i, 1);
+ } else if (last === '..') {
+ parts.splice(i, 1);
+ up++;
+ } else if (up) {
+ parts.splice(i, 1);
+ up--;
+ }
+ }
+
+ // if the path is allowed to go above the root, restore leading ..s
+ if (allowAboveRoot) {
+ for (; up--; up) {
+ parts.unshift('..');
+ }
+ }
+
+ return parts;
+}
+
+// Split a filename into [root, dir, basename, ext], unix version
+// 'root' is just a slash, or nothing.
+var splitPathRe =
+ /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+var splitPath = function(filename) {
+ return splitPathRe.exec(filename).slice(1);
+};
+
+// path.resolve([from ...], to)
+// posix version
+exports.resolve = function() {
+ var resolvedPath = '',
+ resolvedAbsolute = false;
+
+ for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+ var path = (i >= 0) ? arguments[i] : process.cwd();
+
+ // Skip empty and invalid entries
+ if (typeof path !== 'string') {
+ throw new TypeError('Arguments to path.resolve must be strings');
+ } else if (!path) {
+ continue;
+ }
+
+ resolvedPath = path + '/' + resolvedPath;
+ resolvedAbsolute = path.charAt(0) === '/';
+ }
+
+ // At this point the path should be resolved to a full absolute path, but
+ // handle relative paths to be safe (might happen when process.cwd() fails)
+
+ // Normalize the path
+ resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
+ return !!p;
+ }), !resolvedAbsolute).join('/');
+
+ return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+};
+
+// path.normalize(path)
+// posix version
+exports.normalize = function(path) {
+ var isAbsolute = exports.isAbsolute(path),
+ trailingSlash = substr(path, -1) === '/';
+
+ // Normalize the path
+ path = normalizeArray(filter(path.split('/'), function(p) {
+ return !!p;
+ }), !isAbsolute).join('/');
+
+ if (!path && !isAbsolute) {
+ path = '.';
+ }
+ if (path && trailingSlash) {
+ path += '/';
+ }
+
+ return (isAbsolute ? '/' : '') + path;
+};
+
+// posix version
+exports.isAbsolute = function(path) {
+ return path.charAt(0) === '/';
+};
+
+// posix version
+exports.join = function() {
+ var paths = Array.prototype.slice.call(arguments, 0);
+ return exports.normalize(filter(paths, function(p, index) {
+ if (typeof p !== 'string') {
+ throw new TypeError('Arguments to path.join must be strings');
+ }
+ return p;
+ }).join('/'));
+};
+
+
+// path.relative(from, to)
+// posix version
+exports.relative = function(from, to) {
+ from = exports.resolve(from).substr(1);
+ to = exports.resolve(to).substr(1);
+
+ function trim(arr) {
+ var start = 0;
+ for (; start < arr.length; start++) {
+ if (arr[start] !== '') break;
+ }
+
+ var end = arr.length - 1;
+ for (; end >= 0; end--) {
+ if (arr[end] !== '') break;
+ }
+
+ if (start > end) return [];
+ return arr.slice(start, end - start + 1);
+ }
+
+ var fromParts = trim(from.split('/'));
+ var toParts = trim(to.split('/'));
+
+ var length = Math.min(fromParts.length, toParts.length);
+ var samePartsLength = length;
+ for (var i = 0; i < length; i++) {
+ if (fromParts[i] !== toParts[i]) {
+ samePartsLength = i;
+ break;
+ }
+ }
+
+ var outputParts = [];
+ for (var i = samePartsLength; i < fromParts.length; i++) {
+ outputParts.push('..');
+ }
+
+ outputParts = outputParts.concat(toParts.slice(samePartsLength));
+
+ return outputParts.join('/');
+};
+
+exports.sep = '/';
+exports.delimiter = ':';
+
+exports.dirname = function(path) {
+ var result = splitPath(path),
+ root = result[0],
+ dir = result[1];
+
+ if (!root && !dir) {
+ // No dirname whatsoever
+ return '.';
+ }
+
+ if (dir) {
+ // It has a dirname, strip trailing slash
+ dir = dir.substr(0, dir.length - 1);
+ }
+
+ return root + dir;
+};
+
+
+exports.basename = function(path, ext) {
+ var f = splitPath(path)[2];
+ // TODO: make this comparison case-insensitive on windows?
+ if (ext && f.substr(-1 * ext.length) === ext) {
+ f = f.substr(0, f.length - ext.length);
+ }
+ return f;
+};
+
+
+exports.extname = function(path) {
+ return splitPath(path)[3];
+};
+
+function filter (xs, f) {
+ if (xs.filter) return xs.filter(f);
+ var res = [];
+ for (var i = 0; i < xs.length; i++) {
+ if (f(xs[i], i, xs)) res.push(xs[i]);
+ }
+ return res;
+}
+
+// String.prototype.substr - negative index don't work in IE8
+var substr = 'ab'.substr(-1) === 'b'
+ ? function (str, start, len) { return str.substr(start, len) }
+ : function (str, start, len) {
+ if (start < 0) start = str.length + start;
+ return str.substr(start, len);
+ }
+;
+
+}).call(this,require('_process'))
+
+},{"_process":21}],21:[function(require,module,exports){
+// shim for using process in browser
+
+var process = module.exports = {};
+var queue = [];
+var draining = false;
+
+function drainQueue() {
+ if (draining) {
+ return;
+ }
+ draining = true;
+ var currentQueue;
+ var len = queue.length;
+ while(len) {
+ currentQueue = queue;
+ queue = [];
+ var i = -1;
+ while (++i < len) {
+ currentQueue[i]();
+ }
+ len = queue.length;
+ }
+ draining = false;
+}
+process.nextTick = function (fun) {
+ queue.push(fun);
+ if (!draining) {
+ setTimeout(drainQueue, 0);
+ }
+};
+
+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');
+};
+
+// TODO(shtylman)
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+ throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],22:[function(require,module,exports){
+(function (global){
+/*! http://mths.be/punycode v1.2.4 by @mathias */
+;(function(root) {
+
+ /** Detect free variables */
+ var freeExports = typeof exports == 'object' && exports;
+ var freeModule = typeof module == 'object' && module &&
+ module.exports == freeExports && module;
+ var freeGlobal = typeof global == 'object' && global;
+ if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
+ root = freeGlobal;
+ }
+
+ /**
+ * The `punycode` object.
+ * @name punycode
+ * @type Object
+ */
+ var punycode,
+
+ /** Highest positive signed 32-bit float value */
+ maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
+
+ /** Bootstring parameters */
+ base = 36,
+ tMin = 1,
+ tMax = 26,
+ skew = 38,
+ damp = 700,
+ initialBias = 72,
+ initialN = 128, // 0x80
+ delimiter = '-', // '\x2D'
+
+ /** Regular expressions */
+ regexPunycode = /^xn--/,
+ regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars
+ regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators
+
+ /** Error messages */
+ errors = {
+ 'overflow': 'Overflow: input needs wider integers to process',
+ 'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
+ 'invalid-input': 'Invalid input'
+ },
+
+ /** Convenience shortcuts */
+ baseMinusTMin = base - tMin,
+ floor = Math.floor,
+ stringFromCharCode = String.fromCharCode,
+
+ /** Temporary variable */
+ key;
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * A generic error utility function.
+ * @private
+ * @param {String} type The error type.
+ * @returns {Error} Throws a `RangeError` with the applicable error message.
+ */
+ function error(type) {
+ throw RangeError(errors[type]);
+ }
+
+ /**
+ * A generic `Array#map` utility function.
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} callback The function that gets called for every array
+ * item.
+ * @returns {Array} A new array of values returned by the callback function.
+ */
+ function map(array, fn) {
+ var length = array.length;
+ while (length--) {
+ array[length] = fn(array[length]);
+ }
+ return array;
+ }
+
+ /**
+ * A simple `Array#map`-like wrapper to work with domain name strings.
+ * @private
+ * @param {String} domain The domain name.
+ * @param {Function} callback The function that gets called for every
+ * character.
+ * @returns {Array} A new string of characters returned by the callback
+ * function.
+ */
+ function mapDomain(string, fn) {
+ return map(string.split(regexSeparators), fn).join('.');
+ }
+
+ /**
+ * Creates an array containing the numeric code points of each Unicode
+ * character in the string. While JavaScript uses UCS-2 internally,
+ * this function will convert a pair of surrogate halves (each of which
+ * UCS-2 exposes as separate characters) into a single code point,
+ * matching UTF-16.
+ * @see `punycode.ucs2.encode`
+ * @see <http://mathiasbynens.be/notes/javascript-encoding>
+ * @memberOf punycode.ucs2
+ * @name decode
+ * @param {String} string The Unicode input string (UCS-2).
+ * @returns {Array} The new array of code points.
+ */
+ function ucs2decode(string) {
+ var output = [],
+ counter = 0,
+ length = string.length,
+ value,
+ extra;
+ while (counter < length) {
+ value = string.charCodeAt(counter++);
+ if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
+ // high surrogate, and there is a next character
+ extra = string.charCodeAt(counter++);
+ if ((extra & 0xFC00) == 0xDC00) { // low surrogate
+ output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
+ } else {
+ // unmatched surrogate; only append this code unit, in case the next
+ // code unit is the high surrogate of a surrogate pair
+ output.push(value);
+ counter--;
+ }
+ } else {
+ output.push(value);
+ }
+ }
+ return output;
+ }
+
+ /**
+ * Creates a string based on an array of numeric code points.
+ * @see `punycode.ucs2.decode`
+ * @memberOf punycode.ucs2
+ * @name encode
+ * @param {Array} codePoints The array of numeric code points.
+ * @returns {String} The new Unicode string (UCS-2).
+ */
+ function ucs2encode(array) {
+ return map(array, function(value) {
+ var output = '';
+ if (value > 0xFFFF) {
+ value -= 0x10000;
+ output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
+ value = 0xDC00 | value & 0x3FF;
+ }
+ output += stringFromCharCode(value);
+ return output;
+ }).join('');
+ }
+
+ /**
+ * Converts a basic code point into a digit/integer.
+ * @see `digitToBasic()`
+ * @private
+ * @param {Number} codePoint The basic numeric code point value.
+ * @returns {Number} The numeric value of a basic code point (for use in
+ * representing integers) in the range `0` to `base - 1`, or `base` if
+ * the code point does not represent a value.
+ */
+ function basicToDigit(codePoint) {
+ if (codePoint - 48 < 10) {
+ return codePoint - 22;
+ }
+ if (codePoint - 65 < 26) {
+ return codePoint - 65;
+ }
+ if (codePoint - 97 < 26) {
+ return codePoint - 97;
+ }
+ return base;
+ }
+
+ /**
+ * Converts a digit/integer into a basic code point.
+ * @see `basicToDigit()`
+ * @private
+ * @param {Number} digit The numeric value of a basic code point.
+ * @returns {Number} The basic code point whose value (when used for
+ * representing integers) is `digit`, which needs to be in the range
+ * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
+ * used; else, the lowercase form is used. The behavior is undefined
+ * if `flag` is non-zero and `digit` has no uppercase form.
+ */
+ function digitToBasic(digit, flag) {
+ // 0..25 map to ASCII a..z or A..Z
+ // 26..35 map to ASCII 0..9
+ return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
+ }
+
+ /**
+ * Bias adaptation function as per section 3.4 of RFC 3492.
+ * http://tools.ietf.org/html/rfc3492#section-3.4
+ * @private
+ */
+ function adapt(delta, numPoints, firstTime) {
+ var k = 0;
+ delta = firstTime ? floor(delta / damp) : delta >> 1;
+ delta += floor(delta / numPoints);
+ for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
+ delta = floor(delta / baseMinusTMin);
+ }
+ return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
+ }
+
+ /**
+ * Converts a Punycode string of ASCII-only symbols to a string of Unicode
+ * symbols.
+ * @memberOf punycode
+ * @param {String} input The Punycode string of ASCII-only symbols.
+ * @returns {String} The resulting string of Unicode symbols.
+ */
+ function decode(input) {
+ // Don't use UCS-2
+ var output = [],
+ inputLength = input.length,
+ out,
+ i = 0,
+ n = initialN,
+ bias = initialBias,
+ basic,
+ j,
+ index,
+ oldi,
+ w,
+ k,
+ digit,
+ t,
+ /** Cached calculation results */
+ baseMinusT;
+
+ // Handle the basic code points: let `basic` be the number of input code
+ // points before the last delimiter, or `0` if there is none, then copy
+ // the first basic code points to the output.
+
+ basic = input.lastIndexOf(delimiter);
+ if (basic < 0) {
+ basic = 0;
+ }
+
+ for (j = 0; j < basic; ++j) {
+ // if it's not a basic code point
+ if (input.charCodeAt(j) >= 0x80) {
+ error('not-basic');
+ }
+ output.push(input.charCodeAt(j));
+ }
+
+ // Main decoding loop: start just after the last delimiter if any basic code
+ // points were copied; start at the beginning otherwise.
+
+ for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
+
+ // `index` is the index of the next character to be consumed.
+ // Decode a generalized variable-length integer into `delta`,
+ // which gets added to `i`. The overflow checking is easier
+ // if we increase `i` as we go, then subtract off its starting
+ // value at the end to obtain `delta`.
+ for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
+
+ if (index >= inputLength) {
+ error('invalid-input');
+ }
+
+ digit = basicToDigit(input.charCodeAt(index++));
+
+ if (digit >= base || digit > floor((maxInt - i) / w)) {
+ error('overflow');
+ }
+
+ i += digit * w;
+ t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
+
+ if (digit < t) {
+ break;
+ }
+
+ baseMinusT = base - t;
+ if (w > floor(maxInt / baseMinusT)) {
+ error('overflow');
+ }
+
+ w *= baseMinusT;
+
+ }
+
+ out = output.length + 1;
+ bias = adapt(i - oldi, out, oldi == 0);
+
+ // `i` was supposed to wrap around from `out` to `0`,
+ // incrementing `n` each time, so we'll fix that now:
+ if (floor(i / out) > maxInt - n) {
+ error('overflow');
+ }
+
+ n += floor(i / out);
+ i %= out;
+
+ // Insert `n` at position `i` of the output
+ output.splice(i++, 0, n);
+
+ }
+
+ return ucs2encode(output);
+ }
+
+ /**
+ * Converts a string of Unicode symbols to a Punycode string of ASCII-only
+ * symbols.
+ * @memberOf punycode
+ * @param {String} input The string of Unicode symbols.
+ * @returns {String} The resulting Punycode string of ASCII-only symbols.
+ */
+ function encode(input) {
+ var n,
+ delta,
+ handledCPCount,
+ basicLength,
+ bias,
+ j,
+ m,
+ q,
+ k,
+ t,
+ currentValue,
+ output = [],
+ /** `inputLength` will hold the number of code points in `input`. */
+ inputLength,
+ /** Cached calculation results */
+ handledCPCountPlusOne,
+ baseMinusT,
+ qMinusT;
+
+ // Convert the input in UCS-2 to Unicode
+ input = ucs2decode(input);
+
+ // Cache the length
+ inputLength = input.length;
+
+ // Initialize the state
+ n = initialN;
+ delta = 0;
+ bias = initialBias;
+
+ // Handle the basic code points
+ for (j = 0; j < inputLength; ++j) {
+ currentValue = input[j];
+ if (currentValue < 0x80) {
+ output.push(stringFromCharCode(currentValue));
+ }
+ }
+
+ handledCPCount = basicLength = output.length;
+
+ // `handledCPCount` is the number of code points that have been handled;
+ // `basicLength` is the number of basic code points.
+
+ // Finish the basic string - if it is not empty - with a delimiter
+ if (basicLength) {
+ output.push(delimiter);
+ }
+
+ // Main encoding loop:
+ while (handledCPCount < inputLength) {
+
+ // All non-basic code points < n have been handled already. Find the next
+ // larger one:
+ for (m = maxInt, j = 0; j < inputLength; ++j) {
+ currentValue = input[j];
+ if (currentValue >= n && currentValue < m) {
+ m = currentValue;
+ }
+ }
+
+ // Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
+ // but guard against overflow
+ handledCPCountPlusOne = handledCPCount + 1;
+ if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
+ error('overflow');
+ }
+
+ delta += (m - n) * handledCPCountPlusOne;
+ n = m;
+
+ for (j = 0; j < inputLength; ++j) {
+ currentValue = input[j];
+
+ if (currentValue < n && ++delta > maxInt) {
+ error('overflow');
+ }
+
+ if (currentValue == n) {
+ // Represent delta as a generalized variable-length integer
+ for (q = delta, k = base; /* no condition */; k += base) {
+ t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
+ if (q < t) {
+ break;
+ }
+ qMinusT = q - t;
+ baseMinusT = base - t;
+ output.push(
+ stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
+ );
+ q = floor(qMinusT / baseMinusT);
+ }
+
+ output.push(stringFromCharCode(digitToBasic(q, 0)));
+ bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
+ delta = 0;
+ ++handledCPCount;
+ }
+ }
+
+ ++delta;
+ ++n;
+
+ }
+ return output.join('');
+ }
+
+ /**
+ * Converts a Punycode string representing a domain name to Unicode. Only the
+ * Punycoded parts of the domain name will be converted, i.e. it doesn't
+ * matter if you call it on a string that has already been converted to
+ * Unicode.
+ * @memberOf punycode
+ * @param {String} domain The Punycode domain name to convert to Unicode.
+ * @returns {String} The Unicode representation of the given Punycode
+ * string.
+ */
+ function toUnicode(domain) {
+ return mapDomain(domain, function(string) {
+ return regexPunycode.test(string)
+ ? decode(string.slice(4).toLowerCase())
+ : string;
+ });
+ }
+
+ /**
+ * Converts a Unicode string representing a domain name to Punycode. Only the
+ * non-ASCII parts of the domain name will be converted, i.e. it doesn't
+ * matter if you call it with a domain that's already in ASCII.
+ * @memberOf punycode
+ * @param {String} domain The domain name to convert, as a Unicode string.
+ * @returns {String} The Punycode representation of the given domain name.
+ */
+ function toASCII(domain) {
+ return mapDomain(domain, function(string) {
+ return regexNonASCII.test(string)
+ ? 'xn--' + encode(string)
+ : string;
+ });
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /** Define the public API */
+ punycode = {
+ /**
+ * A string representing the current Punycode.js version number.
+ * @memberOf punycode
+ * @type String
+ */
+ 'version': '1.2.4',
+ /**
+ * An object of methods to convert from JavaScript's internal character
+ * representation (UCS-2) to Unicode code points, and back.
+ * @see <http://mathiasbynens.be/notes/javascript-encoding>
+ * @memberOf punycode
+ * @type Object
+ */
+ 'ucs2': {
+ 'decode': ucs2decode,
+ 'encode': ucs2encode
+ },
+ 'decode': decode,
+ 'encode': encode,
+ 'toASCII': toASCII,
+ 'toUnicode': toUnicode
+ };
+
+ /** Expose `punycode` */
+ // Some AMD build optimizers, like r.js, check for specific condition patterns
+ // like the following:
+ if (
+ typeof define == 'function' &&
+ typeof define.amd == 'object' &&
+ define.amd
+ ) {
+ define('punycode', function() {
+ return punycode;
+ });
+ } else if (freeExports && !freeExports.nodeType) {
+ if (freeModule) { // in Node.js or RingoJS v0.8.0+
+ freeModule.exports = punycode;
+ } else { // in Narwhal or RingoJS v0.7.0-
+ for (key in punycode) {
+ punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
+ }
+ }
+ } else { // in Rhino or a web browser
+ root.punycode = punycode;
+ }
+
+}(this));
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{}],23:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// 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.
+
+'use strict';
+
+// If obj.hasOwnProperty has been overridden, then calling
+// obj.hasOwnProperty(prop) will break.
+// See: https://github.com/joyent/node/issues/1707
+function hasOwnProperty(obj, prop) {
+ return Object.prototype.hasOwnProperty.call(obj, prop);
+}
+
+module.exports = function(qs, sep, eq, options) {
+ sep = sep || '&';
+ eq = eq || '=';
+ var obj = {};
+
+ if (typeof qs !== 'string' || qs.length === 0) {
+ return obj;
+ }
+
+ var regexp = /\+/g;
+ qs = qs.split(sep);
+
+ var maxKeys = 1000;
+ if (options && typeof options.maxKeys === 'number') {
+ maxKeys = options.maxKeys;
+ }
+
+ var len = qs.length;
+ // maxKeys <= 0 means that we should not limit keys count
+ if (maxKeys > 0 && len > maxKeys) {
+ len = maxKeys;
+ }
+
+ for (var i = 0; i < len; ++i) {
+ var x = qs[i].replace(regexp, '%20'),
+ idx = x.indexOf(eq),
+ kstr, vstr, k, v;
+
+ if (idx >= 0) {
+ kstr = x.substr(0, idx);
+ vstr = x.substr(idx + 1);
+ } else {
+ kstr = x;
+ vstr = '';
+ }
+
+ k = decodeURIComponent(kstr);
+ v = decodeURIComponent(vstr);
+
+ if (!hasOwnProperty(obj, k)) {
+ obj[k] = v;
+ } else if (isArray(obj[k])) {
+ obj[k].push(v);
+ } else {
+ obj[k] = [obj[k], v];
+ }
+ }
+
+ return obj;
+};
+
+var isArray = Array.isArray || function (xs) {
+ return Object.prototype.toString.call(xs) === '[object Array]';
+};
+
+},{}],24:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// 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.
+
+'use strict';
+
+var stringifyPrimitive = function(v) {
+ switch (typeof v) {
+ case 'string':
+ return v;
+
+ case 'boolean':
+ return v ? 'true' : 'false';
+
+ case 'number':
+ return isFinite(v) ? v : '';
+
+ default:
+ return '';
+ }
+};
+
+module.exports = function(obj, sep, eq, name) {
+ sep = sep || '&';
+ eq = eq || '=';
+ if (obj === null) {
+ obj = undefined;
+ }
+
+ if (typeof obj === 'object') {
+ return map(objectKeys(obj), function(k) {
+ var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
+ if (isArray(obj[k])) {
+ return map(obj[k], function(v) {
+ return ks + encodeURIComponent(stringifyPrimitive(v));
+ }).join(sep);
+ } else {
+ return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
+ }
+ }).join(sep);
+
+ }
+
+ if (!name) return '';
+ return encodeURIComponent(stringifyPrimitive(name)) + eq +
+ encodeURIComponent(stringifyPrimitive(obj));
+};
+
+var isArray = Array.isArray || function (xs) {
+ return Object.prototype.toString.call(xs) === '[object Array]';
+};
+
+function map (xs, f) {
+ if (xs.map) return xs.map(f);
+ var res = [];
+ for (var i = 0; i < xs.length; i++) {
+ res.push(f(xs[i], i));
+ }
+ return res;
+}
+
+var objectKeys = Object.keys || function (obj) {
+ var res = [];
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
+ }
+ return res;
+};
+
+},{}],25:[function(require,module,exports){
+'use strict';
+
+exports.decode = exports.parse = require('./decode');
+exports.encode = exports.stringify = require('./encode');
+
+},{"./decode":23,"./encode":24}],26:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// 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 punycode = require('punycode');
+
+exports.parse = urlParse;
+exports.resolve = urlResolve;
+exports.resolveObject = urlResolveObject;
+exports.format = urlFormat;
+
+exports.Url = Url;
+
+function Url() {
+ this.protocol = null;
+ this.slashes = null;
+ this.auth = null;
+ this.host = null;
+ this.port = null;
+ this.hostname = null;
+ this.hash = null;
+ this.search = null;
+ this.query = null;
+ this.pathname = null;
+ this.path = null;
+ this.href = null;
+}
+
+// Reference: RFC 3986, RFC 1808, RFC 2396
+
+// define these here so at least they only have to be
+// compiled once on the first module load.
+var protocolPattern = /^([a-z0-9.+-]+:)/i,
+ portPattern = /:[0-9]*$/,
+
+ // RFC 2396: characters reserved for delimiting URLs.
+ // We actually just auto-escape these.
+ delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
+
+ // RFC 2396: characters not allowed for various reasons.
+ unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
+
+ // Allowed by RFCs, but cause of XSS attacks. Always escape these.
+ autoEscape = ['\''].concat(unwise),
+ // Characters that are never ever allowed in a hostname.
+ // Note that any invalid chars are also handled, but these
+ // are the ones that are *expected* to be seen, so we fast-path
+ // them.
+ nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
+ hostEndingChars = ['/', '?', '#'],
+ hostnameMaxLen = 255,
+ hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/,
+ hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/,
+ // protocols that can allow "unsafe" and "unwise" chars.
+ unsafeProtocol = {
+ 'javascript': true,
+ 'javascript:': true
+ },
+ // protocols that never have a hostname.
+ hostlessProtocol = {
+ 'javascript': true,
+ 'javascript:': true
+ },
+ // protocols that always contain a // bit.
+ slashedProtocol = {
+ 'http': true,
+ 'https': true,
+ 'ftp': true,
+ 'gopher': true,
+ 'file': true,
+ 'http:': true,
+ 'https:': true,
+ 'ftp:': true,
+ 'gopher:': true,
+ 'file:': true
+ },
+ querystring = require('querystring');
+
+function urlParse(url, parseQueryString, slashesDenoteHost) {
+ if (url && isObject(url) && url instanceof Url) return url;
+
+ var u = new Url;
+ u.parse(url, parseQueryString, slashesDenoteHost);
+ return u;
+}
+
+Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
+ if (!isString(url)) {
+ throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
+ }
+
+ var rest = url;
+
+ // trim before proceeding.
+ // This is to support parse stuff like " http://foo.com \n"
+ rest = rest.trim();
+
+ var proto = protocolPattern.exec(rest);
+ if (proto) {
+ proto = proto[0];
+ var lowerProto = proto.toLowerCase();
+ this.protocol = lowerProto;
+ rest = rest.substr(proto.length);
+ }
+
+ // figure out if it's got a host
+ // user@server is *always* interpreted as a hostname, and url
+ // resolution will treat //foo/bar as host=foo,path=bar because that's
+ // how the browser resolves relative URLs.
+ if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
+ var slashes = rest.substr(0, 2) === '//';
+ if (slashes && !(proto && hostlessProtocol[proto])) {
+ rest = rest.substr(2);
+ this.slashes = true;
+ }
+ }
+
+ if (!hostlessProtocol[proto] &&
+ (slashes || (proto && !slashedProtocol[proto]))) {
+
+ // there's a hostname.
+ // the first instance of /, ?, ;, or # ends the host.
+ //
+ // If there is an @ in the hostname, then non-host chars *are* allowed
+ // to the left of the last @ sign, unless some host-ending character
+ // comes *before* the @-sign.
+ // URLs are obnoxious.
+ //
+ // ex:
+ // http://a@b@c/ => user:a@b host:c
+ // http://a@b?@c => user:a host:c path:/?@c
+
+ // v0.12 TODO(isaacs): This is not quite how Chrome does things.
+ // Review our test case against browsers more comprehensively.
+
+ // find the first instance of any hostEndingChars
+ var hostEnd = -1;
+ for (var i = 0; i < hostEndingChars.length; i++) {
+ var hec = rest.indexOf(hostEndingChars[i]);
+ if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
+ hostEnd = hec;
+ }
+
+ // at this point, either we have an explicit point where the
+ // auth portion cannot go past, or the last @ char is the decider.
+ var auth, atSign;
+ if (hostEnd === -1) {
+ // atSign can be anywhere.
+ atSign = rest.lastIndexOf('@');
+ } else {
+ // atSign must be in auth portion.
+ // http://a@b/c@d => host:b auth:a path:/c@d
+ atSign = rest.lastIndexOf('@', hostEnd);
+ }
+
+ // Now we have a portion which is definitely the auth.
+ // Pull that off.
+ if (atSign !== -1) {
+ auth = rest.slice(0, atSign);
+ rest = rest.slice(atSign + 1);
+ this.auth = decodeURIComponent(auth);
+ }
+
+ // the host is the remaining to the left of the first non-host char
+ hostEnd = -1;
+ for (var i = 0; i < nonHostChars.length; i++) {
+ var hec = rest.indexOf(nonHostChars[i]);
+ if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
+ hostEnd = hec;
+ }
+ // if we still have not hit it, then the entire thing is a host.
+ if (hostEnd === -1)
+ hostEnd = rest.length;
+
+ this.host = rest.slice(0, hostEnd);
+ rest = rest.slice(hostEnd);
+
+ // pull out port.
+ this.parseHost();
+
+ // we've indicated that there is a hostname,
+ // so even if it's empty, it has to be present.
+ this.hostname = this.hostname || '';
+
+ // if hostname begins with [ and ends with ]
+ // assume that it's an IPv6 address.
+ var ipv6Hostname = this.hostname[0] === '[' &&
+ this.hostname[this.hostname.length - 1] === ']';
+
+ // validate a little.
+ if (!ipv6Hostname) {
+ var hostparts = this.hostname.split(/\./);
+ for (var i = 0, l = hostparts.length; i < l; i++) {
+ var part = hostparts[i];
+ if (!part) continue;
+ if (!part.match(hostnamePartPattern)) {
+ var newpart = '';
+ for (var j = 0, k = part.length; j < k; j++) {
+ if (part.charCodeAt(j) > 127) {
+ // we replace non-ASCII char with a temporary placeholder
+ // we need this to make sure size of hostname is not
+ // broken by replacing non-ASCII by nothing
+ newpart += 'x';
+ } else {
+ newpart += part[j];
+ }
+ }
+ // we test again with ASCII char only
+ if (!newpart.match(hostnamePartPattern)) {
+ var validParts = hostparts.slice(0, i);
+ var notHost = hostparts.slice(i + 1);
+ var bit = part.match(hostnamePartStart);
+ if (bit) {
+ validParts.push(bit[1]);
+ notHost.unshift(bit[2]);
+ }
+ if (notHost.length) {
+ rest = '/' + notHost.join('.') + rest;
+ }
+ this.hostname = validParts.join('.');
+ break;
+ }
+ }
+ }
+ }
+
+ if (this.hostname.length > hostnameMaxLen) {
+ this.hostname = '';
+ } else {
+ // hostnames are always lower case.
+ this.hostname = this.hostname.toLowerCase();
+ }
+
+ if (!ipv6Hostname) {
+ // IDNA Support: Returns a puny coded representation of "domain".
+ // It only converts the part of the domain name that
+ // has non ASCII characters. I.e. it dosent matter if
+ // you call it with a domain that already is in ASCII.
+ var domainArray = this.hostname.split('.');
+ var newOut = [];
+ for (var i = 0; i < domainArray.length; ++i) {
+ var s = domainArray[i];
+ newOut.push(s.match(/[^A-Za-z0-9_-]/) ?
+ 'xn--' + punycode.encode(s) : s);
+ }
+ this.hostname = newOut.join('.');
+ }
+
+ var p = this.port ? ':' + this.port : '';
+ var h = this.hostname || '';
+ this.host = h + p;
+ this.href += this.host;
+
+ // strip [ and ] from the hostname
+ // the host field still retains them, though
+ if (ipv6Hostname) {
+ this.hostname = this.hostname.substr(1, this.hostname.length - 2);
+ if (rest[0] !== '/') {
+ rest = '/' + rest;
+ }
+ }
+ }
+
+ // now rest is set to the post-host stuff.
+ // chop off any delim chars.
+ if (!unsafeProtocol[lowerProto]) {
+
+ // First, make 100% sure that any "autoEscape" chars get
+ // escaped, even if encodeURIComponent doesn't think they
+ // need to be.
+ for (var i = 0, l = autoEscape.length; i < l; i++) {
+ var ae = autoEscape[i];
+ var esc = encodeURIComponent(ae);
+ if (esc === ae) {
+ esc = escape(ae);
+ }
+ rest = rest.split(ae).join(esc);
+ }
+ }
+
+
+ // chop off from the tail first.
+ var hash = rest.indexOf('#');
+ if (hash !== -1) {
+ // got a fragment string.
+ this.hash = rest.substr(hash);
+ rest = rest.slice(0, hash);
+ }
+ var qm = rest.indexOf('?');
+ if (qm !== -1) {
+ this.search = rest.substr(qm);
+ this.query = rest.substr(qm + 1);
+ if (parseQueryString) {
+ this.query = querystring.parse(this.query);
+ }
+ rest = rest.slice(0, qm);
+ } else if (parseQueryString) {
+ // no query string, but parseQueryString still requested
+ this.search = '';
+ this.query = {};
+ }
+ if (rest) this.pathname = rest;
+ if (slashedProtocol[lowerProto] &&
+ this.hostname && !this.pathname) {
+ this.pathname = '/';
+ }
+
+ //to support http.request
+ if (this.pathname || this.search) {
+ var p = this.pathname || '';
+ var s = this.search || '';
+ this.path = p + s;
+ }
+
+ // finally, reconstruct the href based on what has been validated.
+ this.href = this.format();
+ return this;
+};
+
+// format a parsed object into a url string
+function urlFormat(obj) {
+ // ensure it's an object, and not a string url.
+ // If it's an obj, this is a no-op.
+ // this way, you can call url_format() on strings
+ // to clean up potentially wonky urls.
+ if (isString(obj)) obj = urlParse(obj);
+ if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
+ return obj.format();
+}
+
+Url.prototype.format = function() {
+ var auth = this.auth || '';
+ if (auth) {
+ auth = encodeURIComponent(auth);
+ auth = auth.replace(/%3A/i, ':');
+ auth += '@';
+ }
+
+ var protocol = this.protocol || '',
+ pathname = this.pathname || '',
+ hash = this.hash || '',
+ host = false,
+ query = '';
+
+ if (this.host) {
+ host = auth + this.host;
+ } else if (this.hostname) {
+ host = auth + (this.hostname.indexOf(':') === -1 ?
+ this.hostname :
+ '[' + this.hostname + ']');
+ if (this.port) {
+ host += ':' + this.port;
+ }
+ }
+
+ if (this.query &&
+ isObject(this.query) &&
+ Object.keys(this.query).length) {
+ query = querystring.stringify(this.query);
+ }
+
+ var search = this.search || (query && ('?' + query)) || '';
+
+ if (protocol && protocol.substr(-1) !== ':') protocol += ':';
+
+ // only the slashedProtocols get the //. Not mailto:, xmpp:, etc.
+ // unless they had them to begin with.
+ if (this.slashes ||
+ (!protocol || slashedProtocol[protocol]) && host !== false) {
+ host = '//' + (host || '');
+ if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
+ } else if (!host) {
+ host = '';
+ }
+
+ if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
+ if (search && search.charAt(0) !== '?') search = '?' + search;
+
+ pathname = pathname.replace(/[?#]/g, function(match) {
+ return encodeURIComponent(match);
+ });
+ search = search.replace('#', '%23');
+
+ return protocol + host + pathname + search + hash;
+};
+
+function urlResolve(source, relative) {
+ return urlParse(source, false, true).resolve(relative);
+}
+
+Url.prototype.resolve = function(relative) {
+ return this.resolveObject(urlParse(relative, false, true)).format();
+};
+
+function urlResolveObject(source, relative) {
+ if (!source) return relative;
+ return urlParse(source, false, true).resolveObject(relative);
+}
+
+Url.prototype.resolveObject = function(relative) {
+ if (isString(relative)) {
+ var rel = new Url();
+ rel.parse(relative, false, true);
+ relative = rel;
+ }
+
+ var result = new Url();
+ Object.keys(this).forEach(function(k) {
+ result[k] = this[k];
+ }, this);
+
+ // hash is always overridden, no matter what.
+ // even href="" will remove it.
+ result.hash = relative.hash;
+
+ // if the relative url is empty, then there's nothing left to do here.
+ if (relative.href === '') {
+ result.href = result.format();
+ return result;
+ }
+
+ // hrefs like //foo/bar always cut to the protocol.
+ if (relative.slashes && !relative.protocol) {
+ // take everything except the protocol from relative
+ Object.keys(relative).forEach(function(k) {
+ if (k !== 'protocol')
+ result[k] = relative[k];
+ });
+
+ //urlParse appends trailing / to urls like http://www.example.com
+ if (slashedProtocol[result.protocol] &&
+ result.hostname && !result.pathname) {
+ result.path = result.pathname = '/';
+ }
+
+ result.href = result.format();
+ return result;
+ }
+
+ if (relative.protocol && relative.protocol !== result.protocol) {
+ // if it's a known url protocol, then changing
+ // the protocol does weird things
+ // first, if it's not file:, then we MUST have a host,
+ // and if there was a path
+ // to begin with, then we MUST have a path.
+ // if it is file:, then the host is dropped,
+ // because that's known to be hostless.
+ // anything else is assumed to be absolute.
+ if (!slashedProtocol[relative.protocol]) {
+ Object.keys(relative).forEach(function(k) {
+ result[k] = relative[k];
+ });
+ result.href = result.format();
+ return result;
+ }
+
+ result.protocol = relative.protocol;
+ if (!relative.host && !hostlessProtocol[relative.protocol]) {
+ var relPath = (relative.pathname || '').split('/');
+ while (relPath.length && !(relative.host = relPath.shift()));
+ if (!relative.host) relative.host = '';
+ if (!relative.hostname) relative.hostname = '';
+ if (relPath[0] !== '') relPath.unshift('');
+ if (relPath.length < 2) relPath.unshift('');
+ result.pathname = relPath.join('/');
+ } else {
+ result.pathname = relative.pathname;
+ }
+ result.search = relative.search;
+ result.query = relative.query;
+ result.host = relative.host || '';
+ result.auth = relative.auth;
+ result.hostname = relative.hostname || relative.host;
+ result.port = relative.port;
+ // to support http.request
+ if (result.pathname || result.search) {
+ var p = result.pathname || '';
+ var s = result.search || '';
+ result.path = p + s;
+ }
+ result.slashes = result.slashes || relative.slashes;
+ result.href = result.format();
+ return result;
+ }
+
+ var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
+ isRelAbs = (
+ relative.host ||
+ relative.pathname && relative.pathname.charAt(0) === '/'
+ ),
+ mustEndAbs = (isRelAbs || isSourceAbs ||
+ (result.host && relative.pathname)),
+ removeAllDots = mustEndAbs,
+ srcPath = result.pathname && result.pathname.split('/') || [],
+ relPath = relative.pathname && relative.pathname.split('/') || [],
+ psychotic = result.protocol && !slashedProtocol[result.protocol];
+
+ // if the url is a non-slashed url, then relative
+ // links like ../.. should be able
+ // to crawl up to the hostname, as well. This is strange.
+ // result.protocol has already been set by now.
+ // Later on, put the first path part into the host field.
+ if (psychotic) {
+ result.hostname = '';
+ result.port = null;
+ if (result.host) {
+ if (srcPath[0] === '') srcPath[0] = result.host;
+ else srcPath.unshift(result.host);
+ }
+ result.host = '';
+ if (relative.protocol) {
+ relative.hostname = null;
+ relative.port = null;
+ if (relative.host) {
+ if (relPath[0] === '') relPath[0] = relative.host;
+ else relPath.unshift(relative.host);
+ }
+ relative.host = null;
+ }
+ mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
+ }
+
+ if (isRelAbs) {
+ // it's absolute.
+ result.host = (relative.host || relative.host === '') ?
+ relative.host : result.host;
+ result.hostname = (relative.hostname || relative.hostname === '') ?
+ relative.hostname : result.hostname;
+ result.search = relative.search;
+ result.query = relative.query;
+ srcPath = relPath;
+ // fall through to the dot-handling below.
+ } else if (relPath.length) {
+ // it's relative
+ // throw away the existing file, and take the new path instead.
+ if (!srcPath) srcPath = [];
+ srcPath.pop();
+ srcPath = srcPath.concat(relPath);
+ result.search = relative.search;
+ result.query = relative.query;
+ } else if (!isNullOrUndefined(relative.search)) {
+ // just pull out the search.
+ // like href='?foo'.
+ // Put this after the other two cases because it simplifies the booleans
+ if (psychotic) {
+ result.hostname = result.host = srcPath.shift();
+ //occationaly the auth can get stuck only in host
+ //this especialy happens in cases like
+ //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
+ var authInHost = result.host && result.host.indexOf('@') > 0 ?
+ result.host.split('@') : false;
+ if (authInHost) {
+ result.auth = authInHost.shift();
+ result.host = result.hostname = authInHost.shift();
+ }
+ }
+ result.search = relative.search;
+ result.query = relative.query;
+ //to support http.request
+ if (!isNull(result.pathname) || !isNull(result.search)) {
+ result.path = (result.pathname ? result.pathname : '') +
+ (result.search ? result.search : '');
+ }
+ result.href = result.format();
+ return result;
+ }
+
+ if (!srcPath.length) {
+ // no path at all. easy.
+ // we've already handled the other stuff above.
+ result.pathname = null;
+ //to support http.request
+ if (result.search) {
+ result.path = '/' + result.search;
+ } else {
+ result.path = null;
+ }
+ result.href = result.format();
+ return result;
+ }
+
+ // if a url ENDs in . or .., then it must get a trailing slash.
+ // however, if it ends in anything else non-slashy,
+ // then it must NOT get a trailing slash.
+ var last = srcPath.slice(-1)[0];
+ var hasTrailingSlash = (
+ (result.host || relative.host) && (last === '.' || last === '..') ||
+ last === '');
+
+ // strip single dots, resolve double dots to parent dir
+ // if the path tries to go above the root, `up` ends up > 0
+ var up = 0;
+ for (var i = srcPath.length; i >= 0; i--) {
+ last = srcPath[i];
+ if (last == '.') {
+ srcPath.splice(i, 1);
+ } else if (last === '..') {
+ srcPath.splice(i, 1);
+ up++;
+ } else if (up) {
+ srcPath.splice(i, 1);
+ up--;
+ }
+ }
+
+ // if the path is allowed to go above the root, restore leading ..s
+ if (!mustEndAbs && !removeAllDots) {
+ for (; up--; up) {
+ srcPath.unshift('..');
+ }
+ }
+
+ if (mustEndAbs && srcPath[0] !== '' &&
+ (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
+ srcPath.unshift('');
+ }
+
+ if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
+ srcPath.push('');
+ }
+
+ var isAbsolute = srcPath[0] === '' ||
+ (srcPath[0] && srcPath[0].charAt(0) === '/');
+
+ // put the host back
+ if (psychotic) {
+ result.hostname = result.host = isAbsolute ? '' :
+ srcPath.length ? srcPath.shift() : '';
+ //occationaly the auth can get stuck only in host
+ //this especialy happens in cases like
+ //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
+ var authInHost = result.host && result.host.indexOf('@') > 0 ?
+ result.host.split('@') : false;
+ if (authInHost) {
+ result.auth = authInHost.shift();
+ result.host = result.hostname = authInHost.shift();
+ }
+ }
+
+ mustEndAbs = mustEndAbs || (result.host && srcPath.length);
+
+ if (mustEndAbs && !isAbsolute) {
+ srcPath.unshift('');
+ }
+
+ if (!srcPath.length) {
+ result.pathname = null;
+ result.path = null;
+ } else {
+ result.pathname = srcPath.join('/');
+ }
+
+ //to support request.http
+ if (!isNull(result.pathname) || !isNull(result.search)) {
+ result.path = (result.pathname ? result.pathname : '') +
+ (result.search ? result.search : '');
+ }
+ result.auth = relative.auth || result.auth;
+ result.slashes = result.slashes || relative.slashes;
+ result.href = result.format();
+ return result;
+};
+
+Url.prototype.parseHost = function() {
+ var host = this.host;
+ var port = portPattern.exec(host);
+ if (port) {
+ port = port[0];
+ if (port !== ':') {
+ this.port = port.substr(1);
+ }
+ host = host.substr(0, host.length - port.length);
+ }
+ if (host) this.hostname = host;
+};
+
+function isString(arg) {
+ return typeof arg === "string";
+}
+
+function isObject(arg) {
+ return typeof arg === 'object' && arg !== null;
+}
+
+function isNull(arg) {
+ return arg === null;
+}
+function isNullOrUndefined(arg) {
+ return arg == null;
+}
+
+},{"punycode":22,"querystring":25}],27:[function(require,module,exports){
+module.exports = function isBuffer(arg) {
+ return arg && typeof arg === 'object'
+ && typeof arg.copy === 'function'
+ && typeof arg.fill === 'function'
+ && typeof arg.readUInt8 === 'function';
+}
+},{}],28:[function(require,module,exports){
+(function (process,global){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// 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 formatRegExp = /%[sdj%]/g;
+exports.format = function(f) {
+ if (!isString(f)) {
+ var objects = [];
+ for (var i = 0; i < arguments.length; i++) {
+ objects.push(inspect(arguments[i]));
+ }
+ return objects.join(' ');
+ }
+
+ var i = 1;
+ var args = arguments;
+ var len = args.length;
+ var str = String(f).replace(formatRegExp, function(x) {
+ if (x === '%%') return '%';
+ if (i >= len) return x;
+ switch (x) {
+ case '%s': return String(args[i++]);
+ case '%d': return Number(args[i++]);
+ case '%j':
+ try {
+ return JSON.stringify(args[i++]);
+ } catch (_) {
+ return '[Circular]';
+ }
+ default:
+ return x;
+ }
+ });
+ for (var x = args[i]; i < len; x = args[++i]) {
+ if (isNull(x) || !isObject(x)) {
+ str += ' ' + x;
+ } else {
+ str += ' ' + inspect(x);
+ }
+ }
+ return str;
+};
+
+
+// Mark that a method should not be used.
+// Returns a modified function which warns once by default.
+// If --no-deprecation is set, then it is a no-op.
+exports.deprecate = function(fn, msg) {
+ // Allow for deprecating things in the process of starting up.
+ if (isUndefined(global.process)) {
+ return function() {
+ return exports.deprecate(fn, msg).apply(this, arguments);
+ };
+ }
+
+ if (process.noDeprecation === true) {
+ return fn;
+ }
+
+ var warned = false;
+ function deprecated() {
+ if (!warned) {
+ if (process.throwDeprecation) {
+ throw new Error(msg);
+ } else if (process.traceDeprecation) {
+ console.trace(msg);
+ } else {
+ console.error(msg);
+ }
+ warned = true;
+ }
+ return fn.apply(this, arguments);
+ }
+
+ return deprecated;
+};
+
+
+var debugs = {};
+var debugEnviron;
+exports.debuglog = function(set) {
+ if (isUndefined(debugEnviron))
+ debugEnviron = process.env.NODE_DEBUG || '';
+ set = set.toUpperCase();
+ if (!debugs[set]) {
+ if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
+ var pid = process.pid;
+ debugs[set] = function() {
+ var msg = exports.format.apply(exports, arguments);
+ console.error('%s %d: %s', set, pid, msg);
+ };
+ } else {
+ debugs[set] = function() {};
+ }
+ }
+ return debugs[set];
+};
+
+
+/**
+ * Echos the value of a value. Trys to print the value out
+ * in the best way possible given the different types.
+ *
+ * @param {Object} obj The object to print out.
+ * @param {Object} opts Optional options object that alters the output.
+ */
+/* legacy: obj, showHidden, depth, colors*/
+function inspect(obj, opts) {
+ // default options
+ var ctx = {
+ seen: [],
+ stylize: stylizeNoColor
+ };
+ // legacy...
+ if (arguments.length >= 3) ctx.depth = arguments[2];
+ if (arguments.length >= 4) ctx.colors = arguments[3];
+ if (isBoolean(opts)) {
+ // legacy...
+ ctx.showHidden = opts;
+ } else if (opts) {
+ // got an "options" object
+ exports._extend(ctx, opts);
+ }
+ // set default options
+ if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
+ if (isUndefined(ctx.depth)) ctx.depth = 2;
+ if (isUndefined(ctx.colors)) ctx.colors = false;
+ if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
+ if (ctx.colors) ctx.stylize = stylizeWithColor;
+ return formatValue(ctx, obj, ctx.depth);
+}
+exports.inspect = inspect;
+
+
+// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
+inspect.colors = {
+ 'bold' : [1, 22],
+ 'italic' : [3, 23],
+ 'underline' : [4, 24],
+ 'inverse' : [7, 27],
+ 'white' : [37, 39],
+ 'grey' : [90, 39],
+ 'black' : [30, 39],
+ 'blue' : [34, 39],
+ 'cyan' : [36, 39],
+ 'green' : [32, 39],
+ 'magenta' : [35, 39],
+ 'red' : [31, 39],
+ 'yellow' : [33, 39]
+};
+
+// Don't use 'blue' not visible on cmd.exe
+inspect.styles = {
+ 'special': 'cyan',
+ 'number': 'yellow',
+ 'boolean': 'yellow',
+ 'undefined': 'grey',
+ 'null': 'bold',
+ 'string': 'green',
+ 'date': 'magenta',
+ // "name": intentionally not styling
+ 'regexp': 'red'
+};
+
+
+function stylizeWithColor(str, styleType) {
+ var style = inspect.styles[styleType];
+
+ if (style) {
+ return '\u001b[' + inspect.colors[style][0] + 'm' + str +
+ '\u001b[' + inspect.colors[style][1] + 'm';
+ } else {
+ return str;
+ }
+}
+
+
+function stylizeNoColor(str, styleType) {
+ return str;
+}
+
+
+function arrayToHash(array) {
+ var hash = {};
+
+ array.forEach(function(val, idx) {
+ hash[val] = true;
+ });
+
+ return hash;
+}
+
+
+function formatValue(ctx, value, recurseTimes) {
+ // Provide a hook for user-specified inspect functions.
+ // Check that value is an object with an inspect function on it
+ if (ctx.customInspect &&
+ value &&
+ isFunction(value.inspect) &&
+ // Filter out the util module, it's inspect function is special
+ value.inspect !== exports.inspect &&
+ // Also filter out any prototype objects using the circular check.
+ !(value.constructor && value.constructor.prototype === value)) {
+ var ret = value.inspect(recurseTimes, ctx);
+ if (!isString(ret)) {
+ ret = formatValue(ctx, ret, recurseTimes);
+ }
+ return ret;
+ }
+
+ // Primitive types cannot have properties
+ var primitive = formatPrimitive(ctx, value);
+ if (primitive) {
+ return primitive;
+ }
+
+ // Look up the keys of the object.
+ var keys = Object.keys(value);
+ var visibleKeys = arrayToHash(keys);
+
+ if (ctx.showHidden) {
+ keys = Object.getOwnPropertyNames(value);
+ }
+
+ // IE doesn't make error fields non-enumerable
+ // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
+ if (isError(value)
+ && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
+ return formatError(value);
+ }
+
+ // Some type of object without properties can be shortcutted.
+ if (keys.length === 0) {
+ if (isFunction(value)) {
+ var name = value.name ? ': ' + value.name : '';
+ return ctx.stylize('[Function' + name + ']', 'special');
+ }
+ if (isRegExp(value)) {
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+ }
+ if (isDate(value)) {
+ return ctx.stylize(Date.prototype.toString.call(value), 'date');
+ }
+ if (isError(value)) {
+ return formatError(value);
+ }
+ }
+
+ var base = '', array = false, braces = ['{', '}'];
+
+ // Make Array say that they are Array
+ if (isArray(value)) {
+ array = true;
+ braces = ['[', ']'];
+ }
+
+ // Make functions say that they are functions
+ if (isFunction(value)) {
+ var n = value.name ? ': ' + value.name : '';
+ base = ' [Function' + n + ']';
+ }
+
+ // Make RegExps say that they are RegExps
+ if (isRegExp(value)) {
+ base = ' ' + RegExp.prototype.toString.call(value);
+ }
+
+ // Make dates with properties first say the date
+ if (isDate(value)) {
+ base = ' ' + Date.prototype.toUTCString.call(value);
+ }
+
+ // Make error with message first say the error
+ if (isError(value)) {
+ base = ' ' + formatError(value);
+ }
+
+ if (keys.length === 0 && (!array || value.length == 0)) {
+ return braces[0] + base + braces[1];
+ }
+
+ if (recurseTimes < 0) {
+ if (isRegExp(value)) {
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+ } else {
+ return ctx.stylize('[Object]', 'special');
+ }
+ }
+
+ ctx.seen.push(value);
+
+ var output;
+ if (array) {
+ output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
+ } else {
+ output = keys.map(function(key) {
+ return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
+ });
+ }
+
+ ctx.seen.pop();
+
+ return reduceToSingleString(output, base, braces);
+}
+
+
+function formatPrimitive(ctx, value) {
+ if (isUndefined(value))
+ return ctx.stylize('undefined', 'undefined');
+ if (isString(value)) {
+ var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
+ .replace(/'/g, "\\'")
+ .replace(/\\"/g, '"') + '\'';
+ return ctx.stylize(simple, 'string');
+ }
+ if (isNumber(value))
+ return ctx.stylize('' + value, 'number');
+ if (isBoolean(value))
+ return ctx.stylize('' + value, 'boolean');
+ // For some reason typeof null is "object", so special case here.
+ if (isNull(value))
+ return ctx.stylize('null', 'null');
+}
+
+
+function formatError(value) {
+ return '[' + Error.prototype.toString.call(value) + ']';
+}
+
+
+function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
+ var output = [];
+ for (var i = 0, l = value.length; i < l; ++i) {
+ if (hasOwnProperty(value, String(i))) {
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+ String(i), true));
+ } else {
+ output.push('');
+ }
+ }
+ keys.forEach(function(key) {
+ if (!key.match(/^\d+$/)) {
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+ key, true));
+ }
+ });
+ return output;
+}
+
+
+function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
+ var name, str, desc;
+ desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
+ if (desc.get) {
+ if (desc.set) {
+ str = ctx.stylize('[Getter/Setter]', 'special');
+ } else {
+ str = ctx.stylize('[Getter]', 'special');
+ }
+ } else {
+ if (desc.set) {
+ str = ctx.stylize('[Setter]', 'special');
+ }
+ }
+ if (!hasOwnProperty(visibleKeys, key)) {
+ name = '[' + key + ']';
+ }
+ if (!str) {
+ if (ctx.seen.indexOf(desc.value) < 0) {
+ if (isNull(recurseTimes)) {
+ str = formatValue(ctx, desc.value, null);
+ } else {
+ str = formatValue(ctx, desc.value, recurseTimes - 1);
+ }
+ if (str.indexOf('\n') > -1) {
+ if (array) {
+ str = str.split('\n').map(function(line) {
+ return ' ' + line;
+ }).join('\n').substr(2);
+ } else {
+ str = '\n' + str.split('\n').map(function(line) {
+ return ' ' + line;
+ }).join('\n');
+ }
+ }
+ } else {
+ str = ctx.stylize('[Circular]', 'special');
+ }
+ }
+ if (isUndefined(name)) {
+ if (array && key.match(/^\d+$/)) {
+ return str;
+ }
+ name = JSON.stringify('' + key);
+ if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
+ name = name.substr(1, name.length - 2);
+ name = ctx.stylize(name, 'name');
+ } else {
+ name = name.replace(/'/g, "\\'")
+ .replace(/\\"/g, '"')
+ .replace(/(^"|"$)/g, "'");
+ name = ctx.stylize(name, 'string');
+ }
+ }
+
+ return name + ': ' + str;
+}
+
+
+function reduceToSingleString(output, base, braces) {
+ var numLinesEst = 0;
+ var length = output.reduce(function(prev, cur) {
+ numLinesEst++;
+ if (cur.indexOf('\n') >= 0) numLinesEst++;
+ return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
+ }, 0);
+
+ if (length > 60) {
+ return braces[0] +
+ (base === '' ? '' : base + '\n ') +
+ ' ' +
+ output.join(',\n ') +
+ ' ' +
+ braces[1];
+ }
+
+ return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
+}
+
+
+// NOTE: These type checking functions intentionally don't use `instanceof`
+// because it is fragile and can be easily faked with `Object.create()`.
+function isArray(ar) {
+ return Array.isArray(ar);
+}
+exports.isArray = isArray;
+
+function isBoolean(arg) {
+ return typeof arg === 'boolean';
+}
+exports.isBoolean = isBoolean;
+
+function isNull(arg) {
+ return arg === null;
+}
+exports.isNull = isNull;
+
+function isNullOrUndefined(arg) {
+ return arg == null;
+}
+exports.isNullOrUndefined = isNullOrUndefined;
+
+function isNumber(arg) {
+ return typeof arg === 'number';
+}
+exports.isNumber = isNumber;
+
+function isString(arg) {
+ return typeof arg === 'string';
+}
+exports.isString = isString;
+
+function isSymbol(arg) {
+ return typeof arg === 'symbol';
+}
+exports.isSymbol = isSymbol;
+
+function isUndefined(arg) {
+ return arg === void 0;
+}
+exports.isUndefined = isUndefined;
+
+function isRegExp(re) {
+ return isObject(re) && objectToString(re) === '[object RegExp]';
+}
+exports.isRegExp = isRegExp;
+
+function isObject(arg) {
+ return typeof arg === 'object' && arg !== null;
+}
+exports.isObject = isObject;
+
+function isDate(d) {
+ return isObject(d) && objectToString(d) === '[object Date]';
+}
+exports.isDate = isDate;
+
+function isError(e) {
+ return isObject(e) &&
+ (objectToString(e) === '[object Error]' || e instanceof Error);
+}
+exports.isError = isError;
+
+function isFunction(arg) {
+ return typeof arg === 'function';
+}
+exports.isFunction = isFunction;
+
+function isPrimitive(arg) {
+ return arg === null ||
+ typeof arg === 'boolean' ||
+ typeof arg === 'number' ||
+ typeof arg === 'string' ||
+ typeof arg === 'symbol' || // ES6 symbol
+ typeof arg === 'undefined';
+}
+exports.isPrimitive = isPrimitive;
+
+exports.isBuffer = require('./support/isBuffer');
+
+function objectToString(o) {
+ return Object.prototype.toString.call(o);
+}
+
+
+function pad(n) {
+ return n < 10 ? '0' + n.toString(10) : n.toString(10);
+}
+
+
+var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
+ 'Oct', 'Nov', 'Dec'];
+
+// 26 Feb 16:19:34
+function timestamp() {
+ var d = new Date();
+ var time = [pad(d.getHours()),
+ pad(d.getMinutes()),
+ pad(d.getSeconds())].join(':');
+ return [d.getDate(), months[d.getMonth()], time].join(' ');
+}
+
+
+// log is just a thin wrapper to console.log that prepends a timestamp
+exports.log = function() {
+ console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
+};
+
+
+/**
+ * Inherit the prototype methods from one constructor into another.
+ *
+ * The Function.prototype.inherits from lang.js rewritten as a standalone
+ * function (not on Function.prototype). NOTE: If this file is to be loaded
+ * during bootstrapping this function needs to be rewritten using some native
+ * functions as prototype setup using normal JavaScript does not work as
+ * expected during bootstrapping (see mirror.js in r114903).
+ *
+ * @param {function} ctor Constructor function which needs to inherit the
+ * prototype.
+ * @param {function} superCtor Constructor function to inherit prototype from.
+ */
+exports.inherits = require('inherits');
+
+exports._extend = function(origin, add) {
+ // Don't do anything if add isn't an object
+ if (!add || !isObject(add)) return origin;
+
+ var keys = Object.keys(add);
+ var i = keys.length;
+ while (i--) {
+ origin[keys[i]] = add[keys[i]];
+ }
+ return origin;
+};
+
+function hasOwnProperty(obj, prop) {
+ return Object.prototype.hasOwnProperty.call(obj, prop);
+}
+
+}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{"./support/isBuffer":27,"_process":21,"inherits":19}],29:[function(require,module,exports){
+/*
+ Copyright (C) 2012-2014 Yusuke Suzuki <utatane.tea@gmail.com>
+ Copyright (C) 2014 Dan Tao <daniel.tao@gmail.com>
+ Copyright (C) 2013 Andrew Eisenberg <andrew@eisenberg.as>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+(function () {
+ 'use strict';
+
+ var typed,
+ utility,
+ isArray,
+ jsdoc,
+ esutils,
+ hasOwnProperty;
+
+ esutils = require('esutils');
+ isArray = require('isarray');
+ typed = require('./typed');
+ utility = require('./utility');
+
+ function sliceSource(source, index, last) {
+ return source.slice(index, last);
+ }
+
+ hasOwnProperty = (function () {
+ var func = Object.prototype.hasOwnProperty;
+ return function hasOwnProperty(obj, name) {
+ return func.call(obj, name);
+ };
+ }());
+
+ function shallowCopy(obj) {
+ var ret = {}, key;
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ ret[key] = obj[key];
+ }
+ }
+ return ret;
+ }
+
+ function isASCIIAlphanumeric(ch) {
+ return (ch >= 0x61 /* 'a' */ && ch <= 0x7A /* 'z' */) ||
+ (ch >= 0x41 /* 'A' */ && ch <= 0x5A /* 'Z' */) ||
+ (ch >= 0x30 /* '0' */ && ch <= 0x39 /* '9' */);
+ }
+
+ function isParamTitle(title) {
+ return title === 'param' || title === 'argument' || title === 'arg';
+ }
+
+ function isProperty(title) {
+ return title === 'property' || title === 'prop';
+ }
+
+ function isNameParameterRequired(title) {
+ return isParamTitle(title) || isProperty(title) ||
+ title === 'alias' || title === 'this' || title === 'mixes' || title === 'requires';
+ }
+
+ function isAllowedName(title) {
+ return isNameParameterRequired(title) || title === 'const' || title === 'constant';
+ }
+
+ function isAllowedNested(title) {
+ return isProperty(title) || isParamTitle(title);
+ }
+
+ function isTypeParameterRequired(title) {
+ return isParamTitle(title) || title === 'define' || title === 'enum' ||
+ title === 'implements' || title === 'return' ||
+ title === 'this' || title === 'type' || title === 'typedef' ||
+ title === 'returns' || isProperty(title);
+ }
+
+ // Consider deprecation instead using 'isTypeParameterRequired' and 'Rules' declaration to pick when a type is optional/required
+ // This would require changes to 'parseType'
+ function isAllowedType(title) {
+ return isTypeParameterRequired(title) || title === 'throws' || title === 'const' || title === 'constant' ||
+ title === 'namespace' || title === 'member' || title === 'var' || title === 'module' ||
+ title === 'constructor' || title === 'class' || title === 'extends' || title === 'augments' ||
+ title === 'public' || title === 'private' || title === 'protected';
+ }
+
+ function trim(str) {
+ return str.replace(/^\s+/, '').replace(/\s+$/, '');
+ }
+
+ function unwrapComment(doc) {
+ // JSDoc comment is following form
+ // /**
+ // * .......
+ // */
+ // remove /**, */ and *
+ var BEFORE_STAR = 0,
+ STAR = 1,
+ AFTER_STAR = 2,
+ index,
+ len,
+ mode,
+ result,
+ ch;
+
+ doc = doc.replace(/^\/\*\*?/, '').replace(/\*\/$/, '');
+ index = 0;
+ len = doc.length;
+ mode = BEFORE_STAR;
+ result = '';
+
+ while (index < len) {
+ ch = doc.charCodeAt(index);
+ switch (mode) {
+ case BEFORE_STAR:
+ if (esutils.code.isLineTerminator(ch)) {
+ result += String.fromCharCode(ch);
+ } else if (ch === 0x2A /* '*' */) {
+ mode = STAR;
+ } else if (!esutils.code.isWhiteSpace(ch)) {
+ result += String.fromCharCode(ch);
+ mode = AFTER_STAR;
+ }
+ break;
+
+ case STAR:
+ if (!esutils.code.isWhiteSpace(ch)) {
+ result += String.fromCharCode(ch);
+ }
+ mode = esutils.code.isLineTerminator(ch) ? BEFORE_STAR : AFTER_STAR;
+ break;
+
+ case AFTER_STAR:
+ result += String.fromCharCode(ch);
+ if (esutils.code.isLineTerminator(ch)) {
+ mode = BEFORE_STAR;
+ }
+ break;
+ }
+ index += 1;
+ }
+
+ return result;
+ }
+
+ // JSDoc Tag Parser
+
+ (function (exports) {
+ var Rules,
+ index,
+ lineNumber,
+ length,
+ source,
+ recoverable,
+ sloppy,
+ strict;
+
+ function advance() {
+ var ch = source.charCodeAt(index);
+ index += 1;
+ if (esutils.code.isLineTerminator(ch) && !(ch === 0x0D /* '\r' */ && source.charCodeAt(index) === 0x0A /* '\n' */)) {
+ lineNumber += 1;
+ }
+ return String.fromCharCode(ch);
+ }
+
+ function scanTitle() {
+ var title = '';
+ // waste '@'
+ advance();
+
+ while (index < length && isASCIIAlphanumeric(source.charCodeAt(index))) {
+ title += advance();
+ }
+
+ return title;
+ }
+
+ function seekContent() {
+ var ch, waiting, last = index;
+
+ waiting = false;
+ while (last < length) {
+ ch = source.charCodeAt(last);
+ if (esutils.code.isLineTerminator(ch) && !(ch === 0x0D /* '\r' */ && source.charCodeAt(last + 1) === 0x0A /* '\n' */)) {
+ lineNumber += 1;
+ waiting = true;
+ } else if (waiting) {
+ if (ch === 0x40 /* '@' */) {
+ break;
+ }
+ if (!esutils.code.isWhiteSpace(ch)) {
+ waiting = false;
+ }
+ }
+ last += 1;
+ }
+ return last;
+ }
+
+ // type expression may have nest brace, such as,
+ // { { ok: string } }
+ //
+ // therefore, scanning type expression with balancing braces.
+ function parseType(title, last) {
+ var ch, brace, type, direct = false;
+
+
+ // search '{'
+ while (index < last) {
+ ch = source.charCodeAt(index);
+ if (esutils.code.isWhiteSpace(ch)) {
+ advance();
+ } else if (ch === 0x7B /* '{' */) {
+ advance();
+ break;
+ } else {
+ // this is direct pattern
+ direct = true;
+ break;
+ }
+ }
+
+
+ if (direct) {
+ return null;
+ }
+
+ // type expression { is found
+ brace = 1;
+ type = '';
+ while (index < last) {
+ ch = source.charCodeAt(index);
+ if (esutils.code.isLineTerminator(ch)) {
+ advance();
+ } else {
+ if (ch === 0x7D /* '}' */) {
+ brace -= 1;
+ if (brace === 0) {
+ advance();
+ break;
+ }
+ } else if (ch === 0x7B /* '{' */) {
+ brace += 1;
+ }
+ type += advance();
+ }
+ }
+
+ if (brace !== 0) {
+ // braces is not balanced
+ return utility.throwError('Braces are not balanced');
+ }
+
+ if (isParamTitle(title)) {
+ return typed.parseParamType(type);
+ }
+ return typed.parseType(type);
+ }
+
+ function scanIdentifier(last) {
+ var identifier;
+ if (!esutils.code.isIdentifierStart(source.charCodeAt(index))) {
+ return null;
+ }
+ identifier = advance();
+ while (index < last && esutils.code.isIdentifierPart(source.charCodeAt(index))) {
+ identifier += advance();
+ }
+ return identifier;
+ }
+
+ function skipWhiteSpace(last) {
+ while (index < last && (esutils.code.isWhiteSpace(source.charCodeAt(index)) || esutils.code.isLineTerminator(source.charCodeAt(index)))) {
+ advance();
+ }
+ }
+
+ function parseName(last, allowBrackets, allowNestedParams) {
+ var name = '', useBrackets;
+
+ skipWhiteSpace(last);
+
+ if (index >= last) {
+ return null;
+ }
+
+ if (allowBrackets && source.charCodeAt(index) === 0x5B /* '[' */) {
+ useBrackets = true;
+ name = advance();
+ }
+
+ if (!esutils.code.isIdentifierStart(source.charCodeAt(index))) {
+ return null;
+ }
+
+ name += scanIdentifier(last);
+
+ if (allowNestedParams) {
+ if (source.charCodeAt(index) === 0x3A /* ':' */ && (
+ name === 'module' ||
+ name === 'external' ||
+ name === 'event')) {
+ name += advance();
+ name += scanIdentifier(last);
+
+ }
+ while (source.charCodeAt(index) === 0x2E /* '.' */ ||
+ source.charCodeAt(index) === 0x23 /* '#' */ ||
+ source.charCodeAt(index) === 0x7E /* '~' */) {
+ name += advance();
+ name += scanIdentifier(last);
+ }
+ }
+
+ if (useBrackets) {
+ // do we have a default value for this?
+ if (source.charCodeAt(index) === 0x3D /* '=' */) {
+
+ // consume the '='' symbol
+ name += advance();
+ // scan in the default value
+ while (index < last && source.charCodeAt(index) !== 0x5D /* ']' */) {
+ name += advance();
+ }
+ }
+
+ if (index >= last || source.charCodeAt(index) !== 0x5D /* ']' */) {
+ // we never found a closing ']'
+ return null;
+ }
+
+ // collect the last ']'
+ name += advance();
+ }
+
+ return name;
+ }
+
+ function skipToTag() {
+ while (index < length && source.charCodeAt(index) !== 0x40 /* '@' */) {
+ advance();
+ }
+ if (index >= length) {
+ return false;
+ }
+ utility.assert(source.charCodeAt(index) === 0x40 /* '@' */);
+ return true;
+ }
+
+ function TagParser(options, title) {
+ this._options = options;
+ this._title = title;
+ this._tag = {
+ title: title,
+ description: null
+ };
+ if (this._options.lineNumbers) {
+ this._tag.lineNumber = lineNumber;
+ }
+ this._last = 0;
+ // space to save special information for title parsers.
+ this._extra = { };
+ }
+
+ // addError(err, ...)
+ TagParser.prototype.addError = function addError(errorText) {
+ var args = Array.prototype.slice.call(arguments, 1),
+ msg = errorText.replace(
+ /%(\d)/g,
+ function (whole, index) {
+ utility.assert(index < args.length, 'Message reference must be in range');
+ return args[index];
+ }
+ );
+
+ if (!this._tag.errors) {
+ this._tag.errors = [];
+ }
+ if (strict) {
+ utility.throwError(msg);
+ }
+ this._tag.errors.push(msg);
+ return recoverable;
+ };
+
+ TagParser.prototype.parseType = function () {
+ // type required titles
+ if (isTypeParameterRequired(this._title)) {
+ try {
+ this._tag.type = parseType(this._title, this._last);
+ if (!this._tag.type) {
+ if (!isParamTitle(this._title)) {
+ if (!this.addError('Missing or invalid tag type')) {
+ return false;
+ }
+ }
+ }
+ } catch (error) {
+ this._tag.type = null;
+ if (!this.addError(error.message)) {
+ return false;
+ }
+ }
+ } else if (isAllowedType(this._title)) {
+ // optional types
+ try {
+ this._tag.type = parseType(this._title, this._last);
+ } catch (e) {
+ //For optional types, lets drop the thrown error when we hit the end of the file
+ }
+ }
+ return true;
+ };
+
+ TagParser.prototype._parseNamePath = function (optional) {
+ var name;
+ name = parseName(this._last, sloppy && isParamTitle(this._title), true);
+ if (!name) {
+ if (!optional) {
+ if (!this.addError('Missing or invalid tag name')) {
+ return false;
+ }
+ }
+ }
+ this._tag.name = name;
+ return true;
+ };
+
+ TagParser.prototype.parseNamePath = function () {
+ return this._parseNamePath(false);
+ };
+
+ TagParser.prototype.parseNamePathOptional = function () {
+ return this._parseNamePath(true);
+ };
+
+
+ TagParser.prototype.parseName = function () {
+ var assign, name;
+
+ // param, property requires name
+ if (isAllowedName(this._title)) {
+ this._tag.name = parseName(this._last, sloppy && isParamTitle(this._title), isAllowedNested(this._title));
+ if (!this._tag.name) {
+ if (!isNameParameterRequired(this._title)) {
+ return true;
+ }
+
+ // it's possible the name has already been parsed but interpreted as a type
+ // it's also possible this is a sloppy declaration, in which case it will be
+ // fixed at the end
+ if (isParamTitle(this._title) && this._tag.type && this._tag.type.name) {
+ this._extra.name = this._tag.type;
+ this._tag.name = this._tag.type.name;
+ this._tag.type = null;
+ } else {
+ if (!this.addError('Missing or invalid tag name')) {
+ return false;
+ }
+ }
+ } else {
+ name = this._tag.name;
+ if (name.charAt(0) === '[' && name.charAt(name.length - 1) === ']') {
+ // extract the default value if there is one
+ // example: @param {string} [somebody=John Doe] description
+ assign = name.substring(1, name.length - 1).split('=');
+ if (assign[1]) {
+ this._tag['default'] = assign[1];
+ }
+ this._tag.name = assign[0];
+
+ // convert to an optional type
+ if (this._tag.type && this._tag.type.type !== 'OptionalType') {
+ this._tag.type = {
+ type: 'OptionalType',
+ expression: this._tag.type
+ };
+ }
+ }
+ }
+ }
+
+ return true;
+ };
+
+ TagParser.prototype.parseDescription = function parseDescription() {
+ var description = trim(sliceSource(source, index, this._last));
+ if (description) {
+ if ((/^-\s+/).test(description)) {
+ description = description.substring(2);
+ }
+ this._tag.description = description;
+ }
+ return true;
+ };
+
+ TagParser.prototype.parseKind = function parseKind() {
+ var kind, kinds;
+ kinds = {
+ 'class': true,
+ 'constant': true,
+ 'event': true,
+ 'external': true,
+ 'file': true,
+ 'function': true,
+ 'member': true,
+ 'mixin': true,
+ 'module': true,
+ 'namespace': true,
+ 'typedef': true
+ };
+ kind = trim(sliceSource(source, index, this._last));
+ this._tag.kind = kind;
+ if (!hasOwnProperty(kinds, kind)) {
+ if (!this.addError('Invalid kind name \'%0\'', kind)) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ TagParser.prototype.parseAccess = function parseAccess() {
+ var access;
+ access = trim(sliceSource(source, index, this._last));
+ this._tag.access = access;
+ if (access !== 'private' && access !== 'protected' && access !== 'public') {
+ if (!this.addError('Invalid access name \'%0\'', access)) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ TagParser.prototype.parseVariation = function parseVariation() {
+ var variation, text;
+ text = trim(sliceSource(source, index, this._last));
+ variation = parseFloat(text, 10);
+ this._tag.variation = variation;
+ if (isNaN(variation)) {
+ if (!this.addError('Invalid variation \'%0\'', text)) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ TagParser.prototype.ensureEnd = function () {
+ var shouldBeEmpty = trim(sliceSource(source, index, this._last));
+ if (shouldBeEmpty) {
+ if (!this.addError('Unknown content \'%0\'', shouldBeEmpty)) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ TagParser.prototype.epilogue = function epilogue() {
+ var description;
+
+ description = this._tag.description;
+ // un-fix potentially sloppy declaration
+ if (isParamTitle(this._title) && !this._tag.type && description && description.charAt(0) === '[') {
+ this._tag.type = this._extra.name;
+ this._tag.name = undefined;
+
+ if (!sloppy) {
+ if (!this.addError('Missing or invalid tag name')) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ };
+
+ Rules = {
+ // http://usejsdoc.org/tags-access.html
+ 'access': ['parseAccess'],
+ // http://usejsdoc.org/tags-alias.html
+ 'alias': ['parseNamePath', 'ensureEnd'],
+ // http://usejsdoc.org/tags-augments.html
+ 'augments': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // http://usejsdoc.org/tags-constructor.html
+ 'constructor': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // Synonym: http://usejsdoc.org/tags-constructor.html
+ 'class': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // Synonym: http://usejsdoc.org/tags-extends.html
+ 'extends': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // http://usejsdoc.org/tags-deprecated.html
+ 'deprecated': ['parseDescription'],
+ // http://usejsdoc.org/tags-global.html
+ 'global': ['ensureEnd'],
+ // http://usejsdoc.org/tags-inner.html
+ 'inner': ['ensureEnd'],
+ // http://usejsdoc.org/tags-instance.html
+ 'instance': ['ensureEnd'],
+ // http://usejsdoc.org/tags-kind.html
+ 'kind': ['parseKind'],
+ // http://usejsdoc.org/tags-mixes.html
+ 'mixes': ['parseNamePath', 'ensureEnd'],
+ // http://usejsdoc.org/tags-mixin.html
+ 'mixin': ['parseNamePathOptional', 'ensureEnd'],
+ // http://usejsdoc.org/tags-member.html
+ 'member': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // http://usejsdoc.org/tags-method.html
+ 'method': ['parseNamePathOptional', 'ensureEnd'],
+ // http://usejsdoc.org/tags-module.html
+ 'module': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // Synonym: http://usejsdoc.org/tags-method.html
+ 'func': ['parseNamePathOptional', 'ensureEnd'],
+ // Synonym: http://usejsdoc.org/tags-method.html
+ 'function': ['parseNamePathOptional', 'ensureEnd'],
+ // Synonym: http://usejsdoc.org/tags-member.html
+ 'var': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // http://usejsdoc.org/tags-name.html
+ 'name': ['parseNamePath', 'ensureEnd'],
+ // http://usejsdoc.org/tags-namespace.html
+ 'namespace': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+ // http://usejsdoc.org/tags-private.html
+ 'private': ['parseType', 'parseDescription'],
+ // http://usejsdoc.org/tags-protected.html
+ 'protected': ['parseType', 'parseDescription'],
+ // http://usejsdoc.org/tags-public.html
+ 'public': ['parseType', 'parseDescription'],
+ // http://usejsdoc.org/tags-readonly.html
+ 'readonly': ['ensureEnd'],
+ // http://usejsdoc.org/tags-requires.html
+ 'requires': ['parseNamePath', 'ensureEnd'],
+ // http://usejsdoc.org/tags-since.html
+ 'since': ['parseDescription'],
+ // http://usejsdoc.org/tags-static.html
+ 'static': ['ensureEnd'],
+ // http://usejsdoc.org/tags-summary.html
+ 'summary': ['parseDescription'],
+ // http://usejsdoc.org/tags-this.html
+ 'this': ['parseNamePath', 'ensureEnd'],
+ // http://usejsdoc.org/tags-todo.html
+ 'todo': ['parseDescription'],
+ // http://usejsdoc.org/tags-typedef.html
+ 'typedef': ['parseType', 'parseNamePathOptional'],
+ // http://usejsdoc.org/tags-variation.html
+ 'variation': ['parseVariation'],
+ // http://usejsdoc.org/tags-version.html
+ 'version': ['parseDescription']
+ };
+
+ TagParser.prototype.parse = function parse() {
+ var i, iz, sequences, method;
+
+ // empty title
+ if (!this._title) {
+ if (!this.addError('Missing or invalid title')) {
+ return null;
+ }
+ }
+
+ // Seek to content last index.
+ this._last = seekContent(this._title);
+
+ if (hasOwnProperty(Rules, this._title)) {
+ sequences = Rules[this._title];
+ } else {
+ // default sequences
+ sequences = ['parseType', 'parseName', 'parseDescription', 'epilogue'];
+ }
+
+ for (i = 0, iz = sequences.length; i < iz; ++i) {
+ method = sequences[i];
+ if (!this[method]()) {
+ return null;
+ }
+ }
+
+ // Seek global index to end of this tag.
+ index = this._last;
+ return this._tag;
+ };
+
+ function parseTag(options) {
+ var title, parser;
+
+ // skip to tag
+ if (!skipToTag()) {
+ return null;
+ }
+
+ // scan title
+ title = scanTitle();
+
+ // construct tag parser
+ parser = new TagParser(options, title);
+ return parser.parse();
+ }
+
+ //
+ // Parse JSDoc
+ //
+
+ function scanJSDocDescription(preserveWhitespace) {
+ var description = '', ch, atAllowed;
+
+ atAllowed = true;
+ while (index < length) {
+ ch = source.charCodeAt(index);
+
+ if (atAllowed && ch === 0x40 /* '@' */) {
+ break;
+ }
+
+ if (esutils.code.isLineTerminator(ch)) {
+ atAllowed = true;
+ } else if (atAllowed && !esutils.code.isWhiteSpace(ch)) {
+ atAllowed = false;
+ }
+
+ description += advance();
+ }
+
+ return preserveWhitespace ? description : trim(description);
+ }
+
+ function parse(comment, options) {
+ var tags = [], tag, description, interestingTags, i, iz;
+
+ if (options === undefined) {
+ options = {};
+ }
+
+ if (typeof options.unwrap === 'boolean' && options.unwrap) {
+ source = unwrapComment(comment);
+ } else {
+ source = comment;
+ }
+
+ // array of relevant tags
+ if (options.tags) {
+ if (isArray(options.tags)) {
+ interestingTags = { };
+ for (i = 0, iz = options.tags.length; i < iz; i++) {
+ if (typeof options.tags[i] === 'string') {
+ interestingTags[options.tags[i]] = true;
+ } else {
+ utility.throwError('Invalid "tags" parameter: ' + options.tags);
+ }
+ }
+ } else {
+ utility.throwError('Invalid "tags" parameter: ' + options.tags);
+ }
+ }
+
+ length = source.length;
+ index = 0;
+ lineNumber = 0;
+ recoverable = options.recoverable;
+ sloppy = options.sloppy;
+ strict = options.strict;
+
+ description = scanJSDocDescription(options.preserveWhitespace);
+
+ while (true) {
+ tag = parseTag(options);
+ if (!tag) {
+ break;
+ }
+ if (!interestingTags || interestingTags.hasOwnProperty(tag.title)) {
+ tags.push(tag);
+ }
+ }
+
+ return {
+ description: description,
+ tags: tags
+ };
+ }
+ exports.parse = parse;
+ }(jsdoc = {}));
+
+ exports.version = utility.VERSION;
+ exports.parse = jsdoc.parse;
+ exports.parseType = typed.parseType;
+ exports.parseParamType = typed.parseParamType;
+ exports.unwrapComment = unwrapComment;
+ exports.Syntax = shallowCopy(typed.Syntax);
+ exports.Error = utility.DoctrineError;
+ exports.type = {
+ Syntax: exports.Syntax,
+ parseType: typed.parseType,
+ parseParamType: typed.parseParamType,
+ stringify: typed.stringify
+ };
+}());
+/* vim: set sw=4 ts=4 et tw=80 : */
+
+},{"./typed":30,"./utility":31,"esutils":35,"isarray":36}],30:[function(require,module,exports){
+/*
+ Copyright (C) 2012-2014 Yusuke Suzuki <utatane.tea@gmail.com>
+ Copyright (C) 2014 Dan Tao <daniel.tao@gmail.com>
+ Copyright (C) 2013 Andrew Eisenberg <andrew@eisenberg.as>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// "typed", the Type Expression Parser for doctrine.
+
+(function () {
+ 'use strict';
+
+ var Syntax,
+ Token,
+ source,
+ length,
+ index,
+ previous,
+ token,
+ value,
+ esutils,
+ utility;
+
+ esutils = require('esutils');
+ utility = require('./utility');
+
+ Syntax = {
+ NullableLiteral: 'NullableLiteral',
+ AllLiteral: 'AllLiteral',
+ NullLiteral: 'NullLiteral',
+ UndefinedLiteral: 'UndefinedLiteral',
+ VoidLiteral: 'VoidLiteral',
+ UnionType: 'UnionType',
+ ArrayType: 'ArrayType',
+ RecordType: 'RecordType',
+ FieldType: 'FieldType',
+ FunctionType: 'FunctionType',
+ ParameterType: 'ParameterType',
+ RestType: 'RestType',
+ NonNullableType: 'NonNullableType',
+ OptionalType: 'OptionalType',
+ NullableType: 'NullableType',
+ NameExpression: 'NameExpression',
+ TypeApplication: 'TypeApplication'
+ };
+
+ Token = {
+ ILLEGAL: 0, // ILLEGAL
+ DOT_LT: 1, // .<
+ REST: 2, // ...
+ LT: 3, // <
+ GT: 4, // >
+ LPAREN: 5, // (
+ RPAREN: 6, // )
+ LBRACE: 7, // {
+ RBRACE: 8, // }
+ LBRACK: 9, // [
+ RBRACK: 10, // ]
+ COMMA: 11, // ,
+ COLON: 12, // :
+ STAR: 13, // *
+ PIPE: 14, // |
+ QUESTION: 15, // ?
+ BANG: 16, // !
+ EQUAL: 17, // =
+ NAME: 18, // name token
+ STRING: 19, // string
+ NUMBER: 20, // number
+ EOF: 21
+ };
+
+ function isTypeName(ch) {
+ return '><(){}[],:*|?!='.indexOf(String.fromCharCode(ch)) === -1 && !esutils.code.isWhiteSpace(ch) && !esutils.code.isLineTerminator(ch);
+ }
+
+ function Context(previous, index, token, value) {
+ this._previous = previous;
+ this._index = index;
+ this._token = token;
+ this._value = value;
+ }
+
+ Context.prototype.restore = function () {
+ previous = this._previous;
+ index = this._index;
+ token = this._token;
+ value = this._value;
+ };
+
+ Context.save = function () {
+ return new Context(previous, index, token, value);
+ };
+
+ function advance() {
+ var ch = source.charAt(index);
+ index += 1;
+ return ch;
+ }
+
+ function scanHexEscape(prefix) {
+ var i, len, ch, code = 0;
+
+ len = (prefix === 'u') ? 4 : 2;
+ for (i = 0; i < len; ++i) {
+ if (index < length && esutils.code.isHexDigit(source.charCodeAt(index))) {
+ ch = advance();
+ code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
+ } else {
+ return '';
+ }
+ }
+ return String.fromCharCode(code);
+ }
+
+ function scanString() {
+ var str = '', quote, ch, code, unescaped, restore; //TODO review removal octal = false
+ quote = source.charAt(index);
+ ++index;
+
+ while (index < length) {
+ ch = advance();
+
+ if (ch === quote) {
+ quote = '';
+ break;
+ } else if (ch === '\\') {
+ ch = advance();
+ if (!esutils.code.isLineTerminator(ch.charCodeAt(0))) {
+ switch (ch) {
+ case 'n':
+ str += '\n';
+ break;
+ case 'r':
+ str += '\r';
+ break;
+ case 't':
+ str += '\t';
+ break;
+ case 'u':
+ case 'x':
+ restore = index;
+ unescaped = scanHexEscape(ch);
+ if (unescaped) {
+ str += unescaped;
+ } else {
+ index = restore;
+ str += ch;
+ }
+ break;
+ case 'b':
+ str += '\b';
+ break;
+ case 'f':
+ str += '\f';
+ break;
+ case 'v':
+ str += '\v';
+ break;
+
+ default:
+ if (esutils.code.isOctalDigit(ch.charCodeAt(0))) {
+ code = '01234567'.indexOf(ch);
+
+ // \0 is not octal escape sequence
+ // Deprecating unused code. TODO review removal
+ //if (code !== 0) {
+ // octal = true;
+ //}
+
+ if (index < length && esutils.code.isOctalDigit(source.charCodeAt(index))) {
+ //TODO Review Removal octal = true;
+ code = code * 8 + '01234567'.indexOf(advance());
+
+ // 3 digits are only allowed when string starts
+ // with 0, 1, 2, 3
+ if ('0123'.indexOf(ch) >= 0 &&
+ index < length &&
+ esutils.code.isOctalDigit(source.charCodeAt(index))) {
+ code = code * 8 + '01234567'.indexOf(advance());
+ }
+ }
+ str += String.fromCharCode(code);
+ } else {
+ str += ch;
+ }
+ break;
+ }
+ } else {
+ if (ch === '\r' && source.charCodeAt(index) === 0x0A /* '\n' */) {
+ ++index;
+ }
+ }
+ } else if (esutils.code.isLineTerminator(ch.charCodeAt(0))) {
+ break;
+ } else {
+ str += ch;
+ }
+ }
+
+ if (quote !== '') {
+ utility.throwError('unexpected quote');
+ }
+
+ value = str;
+ return Token.STRING;
+ }
+
+ function scanNumber() {
+ var number, ch;
+
+ number = '';
+ ch = source.charCodeAt(index);
+
+ if (ch !== 0x2E /* '.' */) {
+ number = advance();
+ ch = source.charCodeAt(index);
+
+ if (number === '0') {
+ if (ch === 0x78 /* 'x' */ || ch === 0x58 /* 'X' */) {
+ number += advance();
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (!esutils.code.isHexDigit(ch)) {
+ break;
+ }
+ number += advance();
+ }
+
+ if (number.length <= 2) {
+ // only 0x
+ utility.throwError('unexpected token');
+ }
+
+ if (index < length) {
+ ch = source.charCodeAt(index);
+ if (esutils.code.isIdentifierStart(ch)) {
+ utility.throwError('unexpected token');
+ }
+ }
+ value = parseInt(number, 16);
+ return Token.NUMBER;
+ }
+
+ if (esutils.code.isOctalDigit(ch)) {
+ number += advance();
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (!esutils.code.isOctalDigit(ch)) {
+ break;
+ }
+ number += advance();
+ }
+
+ if (index < length) {
+ ch = source.charCodeAt(index);
+ if (esutils.code.isIdentifierStart(ch) || esutils.code.isDecimalDigit(ch)) {
+ utility.throwError('unexpected token');
+ }
+ }
+ value = parseInt(number, 8);
+ return Token.NUMBER;
+ }
+
+ if (esutils.code.isDecimalDigit(ch)) {
+ utility.throwError('unexpected token');
+ }
+ }
+
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (!esutils.code.isDecimalDigit(ch)) {
+ break;
+ }
+ number += advance();
+ }
+ }
+
+ if (ch === 0x2E /* '.' */) {
+ number += advance();
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (!esutils.code.isDecimalDigit(ch)) {
+ break;
+ }
+ number += advance();
+ }
+ }
+
+ if (ch === 0x65 /* 'e' */ || ch === 0x45 /* 'E' */) {
+ number += advance();
+
+ ch = source.charCodeAt(index);
+ if (ch === 0x2B /* '+' */ || ch === 0x2D /* '-' */) {
+ number += advance();
+ }
+
+ ch = source.charCodeAt(index);
+ if (esutils.code.isDecimalDigit(ch)) {
+ number += advance();
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (!esutils.code.isDecimalDigit(ch)) {
+ break;
+ }
+ number += advance();
+ }
+ } else {
+ utility.throwError('unexpected token');
+ }
+ }
+
+ if (index < length) {
+ ch = source.charCodeAt(index);
+ if (esutils.code.isIdentifierStart(ch)) {
+ utility.throwError('unexpected token');
+ }
+ }
+
+ value = parseFloat(number);
+ return Token.NUMBER;
+ }
+
+
+ function scanTypeName() {
+ var ch, ch2;
+
+ value = advance();
+ while (index < length && isTypeName(source.charCodeAt(index))) {
+ ch = source.charCodeAt(index);
+ if (ch === 0x2E /* '.' */) {
+ if ((index + 1) >= length) {
+ return Token.ILLEGAL;
+ }
+ ch2 = source.charCodeAt(index + 1);
+ if (ch2 === 0x3C /* '<' */) {
+ break;
+ }
+ }
+ value += advance();
+ }
+ return Token.NAME;
+ }
+
+ function next() {
+ var ch;
+
+ previous = index;
+
+ while (index < length && esutils.code.isWhiteSpace(source.charCodeAt(index))) {
+ advance();
+ }
+ if (index >= length) {
+ token = Token.EOF;
+ return token;
+ }
+
+ ch = source.charCodeAt(index);
+ switch (ch) {
+ case 0x27: /* ''' */
+ case 0x22: /* '"' */
+ token = scanString();
+ return token;
+
+ case 0x3A: /* ':' */
+ advance();
+ token = Token.COLON;
+ return token;
+
+ case 0x2C: /* ',' */
+ advance();
+ token = Token.COMMA;
+ return token;
+
+ case 0x28: /* '(' */
+ advance();
+ token = Token.LPAREN;
+ return token;
+
+ case 0x29: /* ')' */
+ advance();
+ token = Token.RPAREN;
+ return token;
+
+ case 0x5B: /* '[' */
+ advance();
+ token = Token.LBRACK;
+ return token;
+
+ case 0x5D: /* ']' */
+ advance();
+ token = Token.RBRACK;
+ return token;
+
+ case 0x7B: /* '{' */
+ advance();
+ token = Token.LBRACE;
+ return token;
+
+ case 0x7D: /* '}' */
+ advance();
+ token = Token.RBRACE;
+ return token;
+
+ case 0x2E: /* '.' */
+ if (index + 1 < length) {
+ ch = source.charCodeAt(index + 1);
+ if (ch === 0x3C /* '<' */) {
+ advance(); // '.'
+ advance(); // '<'
+ token = Token.DOT_LT;
+ return token;
+ }
+
+ if (ch === 0x2E /* '.' */ && index + 2 < length && source.charCodeAt(index + 2) === 0x2E /* '.' */) {
+ advance(); // '.'
+ advance(); // '.'
+ advance(); // '.'
+ token = Token.REST;
+ return token;
+ }
+
+ if (esutils.code.isDecimalDigit(ch)) {
+ token = scanNumber();
+ return token;
+ }
+ }
+ token = Token.ILLEGAL;
+ return token;
+
+ case 0x3C: /* '<' */
+ advance();
+ token = Token.LT;
+ return token;
+
+ case 0x3E: /* '>' */
+ advance();
+ token = Token.GT;
+ return token;
+
+ case 0x2A: /* '*' */
+ advance();
+ token = Token.STAR;
+ return token;
+
+ case 0x7C: /* '|' */
+ advance();
+ token = Token.PIPE;
+ return token;
+
+ case 0x3F: /* '?' */
+ advance();
+ token = Token.QUESTION;
+ return token;
+
+ case 0x21: /* '!' */
+ advance();
+ token = Token.BANG;
+ return token;
+
+ case 0x3D: /* '=' */
+ advance();
+ token = Token.EQUAL;
+ return token;
+
+ default:
+ if (esutils.code.isDecimalDigit(ch)) {
+ token = scanNumber();
+ return token;
+ }
+
+ // type string permits following case,
+ //
+ // namespace.module.MyClass
+ //
+ // this reduced 1 token TK_NAME
+ utility.assert(isTypeName(ch));
+ token = scanTypeName();
+ return token;
+ }
+ }
+
+ function consume(target, text) {
+ utility.assert(token === target, text || 'consumed token not matched');
+ next();
+ }
+
+ function expect(target, message) {
+ if (token !== target) {
+ utility.throwError(message || 'unexpected token');
+ }
+ next();
+ }
+
+ // UnionType := '(' TypeUnionList ')'
+ //
+ // TypeUnionList :=
+ // <<empty>>
+ // | NonemptyTypeUnionList
+ //
+ // NonemptyTypeUnionList :=
+ // TypeExpression
+ // | TypeExpression '|' NonemptyTypeUnionList
+ function parseUnionType() {
+ var elements;
+ consume(Token.LPAREN, 'UnionType should start with (');
+ elements = [];
+ if (token !== Token.RPAREN) {
+ while (true) {
+ elements.push(parseTypeExpression());
+ if (token === Token.RPAREN) {
+ break;
+ }
+ expect(Token.PIPE);
+ }
+ }
+ consume(Token.RPAREN, 'UnionType should end with )');
+ return {
+ type: Syntax.UnionType,
+ elements: elements
+ };
+ }
+
+ // ArrayType := '[' ElementTypeList ']'
+ //
+ // ElementTypeList :=
+ // <<empty>>
+ // | TypeExpression
+ // | '...' TypeExpression
+ // | TypeExpression ',' ElementTypeList
+ function parseArrayType() {
+ var elements;
+ consume(Token.LBRACK, 'ArrayType should start with [');
+ elements = [];
+ while (token !== Token.RBRACK) {
+ if (token === Token.REST) {
+ consume(Token.REST);
+ elements.push({
+ type: Syntax.RestType,
+ expression: parseTypeExpression()
+ });
+ break;
+ } else {
+ elements.push(parseTypeExpression());
+ }
+ if (token !== Token.RBRACK) {
+ expect(Token.COMMA);
+ }
+ }
+ expect(Token.RBRACK);
+ return {
+ type: Syntax.ArrayType,
+ elements: elements
+ };
+ }
+
+ function parseFieldName() {
+ var v = value;
+ if (token === Token.NAME || token === Token.STRING) {
+ next();
+ return v;
+ }
+
+ if (token === Token.NUMBER) {
+ consume(Token.NUMBER);
+ return String(v);
+ }
+
+ utility.throwError('unexpected token');
+ }
+
+ // FieldType :=
+ // FieldName
+ // | FieldName ':' TypeExpression
+ //
+ // FieldName :=
+ // NameExpression
+ // | StringLiteral
+ // | NumberLiteral
+ // | ReservedIdentifier
+ function parseFieldType() {
+ var key;
+
+ key = parseFieldName();
+ if (token === Token.COLON) {
+ consume(Token.COLON);
+ return {
+ type: Syntax.FieldType,
+ key: key,
+ value: parseTypeExpression()
+ };
+ }
+ return {
+ type: Syntax.FieldType,
+ key: key,
+ value: null
+ };
+ }
+
+ // RecordType := '{' FieldTypeList '}'
+ //
+ // FieldTypeList :=
+ // <<empty>>
+ // | FieldType
+ // | FieldType ',' FieldTypeList
+ function parseRecordType() {
+ var fields;
+
+ consume(Token.LBRACE, 'RecordType should start with {');
+ fields = [];
+ if (token === Token.COMMA) {
+ consume(Token.COMMA);
+ } else {
+ while (token !== Token.RBRACE) {
+ fields.push(parseFieldType());
+ if (token !== Token.RBRACE) {
+ expect(Token.COMMA);
+ }
+ }
+ }
+ expect(Token.RBRACE);
+ return {
+ type: Syntax.RecordType,
+ fields: fields
+ };
+ }
+
+ // NameExpression :=
+ // Identifier
+ // | TagIdentifier ':' Identifier
+ //
+ // Tag identifier is one of "module", "external" or "event"
+ // Identifier is the same as Token.NAME, including any dots, something like
+ // namespace.module.MyClass
+ function parseNameExpression() {
+ var name = value;
+ expect(Token.NAME);
+
+ if (token === Token.COLON && (
+ name === 'module' ||
+ name === 'external' ||
+ name === 'event')) {
+ consume(Token.COLON);
+ name += ':' + value;
+ expect(Token.NAME);
+ }
+
+ return {
+ type: Syntax.NameExpression,
+ name: name
+ };
+ }
+
+ // TypeExpressionList :=
+ // TopLevelTypeExpression
+ // | TopLevelTypeExpression ',' TypeExpressionList
+ function parseTypeExpressionList() {
+ var elements = [];
+
+ elements.push(parseTop());
+ while (token === Token.COMMA) {
+ consume(Token.COMMA);
+ elements.push(parseTop());
+ }
+ return elements;
+ }
+
+ // TypeName :=
+ // NameExpression
+ // | NameExpression TypeApplication
+ //
+ // TypeApplication :=
+ // '.<' TypeExpressionList '>'
+ // | '<' TypeExpressionList '>' // this is extension of doctrine
+ function parseTypeName() {
+ var expr, applications;
+
+ expr = parseNameExpression();
+ if (token === Token.DOT_LT || token === Token.LT) {
+ next();
+ applications = parseTypeExpressionList();
+ expect(Token.GT);
+ return {
+ type: Syntax.TypeApplication,
+ expression: expr,
+ applications: applications
+ };
+ }
+ return expr;
+ }
+
+ // ResultType :=
+ // <<empty>>
+ // | ':' void
+ // | ':' TypeExpression
+ //
+ // BNF is above
+ // but, we remove <<empty>> pattern, so token is always TypeToken::COLON
+ function parseResultType() {
+ consume(Token.COLON, 'ResultType should start with :');
+ if (token === Token.NAME && value === 'void') {
+ consume(Token.NAME);
+ return {
+ type: Syntax.VoidLiteral
+ };
+ }
+ return parseTypeExpression();
+ }
+
+ // ParametersType :=
+ // RestParameterType
+ // | NonRestParametersType
+ // | NonRestParametersType ',' RestParameterType
+ //
+ // RestParameterType :=
+ // '...'
+ // '...' Identifier
+ //
+ // NonRestParametersType :=
+ // ParameterType ',' NonRestParametersType
+ // | ParameterType
+ // | OptionalParametersType
+ //
+ // OptionalParametersType :=
+ // OptionalParameterType
+ // | OptionalParameterType, OptionalParametersType
+ //
+ // OptionalParameterType := ParameterType=
+ //
+ // ParameterType := TypeExpression | Identifier ':' TypeExpression
+ //
+ // Identifier is "new" or "this"
+ function parseParametersType() {
+ var params = [], optionalSequence = false, expr, rest = false;
+
+ while (token !== Token.RPAREN) {
+ if (token === Token.REST) {
+ // RestParameterType
+ consume(Token.REST);
+ rest = true;
+ }
+
+ expr = parseTypeExpression();
+ if (expr.type === Syntax.NameExpression && token === Token.COLON) {
+ // Identifier ':' TypeExpression
+ consume(Token.COLON);
+ expr = {
+ type: Syntax.ParameterType,
+ name: expr.name,
+ expression: parseTypeExpression()
+ };
+ }
+ if (token === Token.EQUAL) {
+ consume(Token.EQUAL);
+ expr = {
+ type: Syntax.OptionalType,
+ expression: expr
+ };
+ optionalSequence = true;
+ } else {
+ if (optionalSequence) {
+ utility.throwError('unexpected token');
+ }
+ }
+ if (rest) {
+ expr = {
+ type: Syntax.RestType,
+ expression: expr
+ };
+ }
+ params.push(expr);
+ if (token !== Token.RPAREN) {
+ expect(Token.COMMA);
+ }
+ }
+ return params;
+ }
+
+ // FunctionType := 'function' FunctionSignatureType
+ //
+ // FunctionSignatureType :=
+ // | TypeParameters '(' ')' ResultType
+ // | TypeParameters '(' ParametersType ')' ResultType
+ // | TypeParameters '(' 'this' ':' TypeName ')' ResultType
+ // | TypeParameters '(' 'this' ':' TypeName ',' ParametersType ')' ResultType
+ function parseFunctionType() {
+ var isNew, thisBinding, params, result, fnType;
+ utility.assert(token === Token.NAME && value === 'function', 'FunctionType should start with \'function\'');
+ consume(Token.NAME);
+
+ // Google Closure Compiler is not implementing TypeParameters.
+ // So we do not. if we don't get '(', we see it as error.
+ expect(Token.LPAREN);
+
+ isNew = false;
+ params = [];
+ thisBinding = null;
+ if (token !== Token.RPAREN) {
+ // ParametersType or 'this'
+ if (token === Token.NAME &&
+ (value === 'this' || value === 'new')) {
+ // 'this' or 'new'
+ // 'new' is Closure Compiler extension
+ isNew = value === 'new';
+ consume(Token.NAME);
+ expect(Token.COLON);
+ thisBinding = parseTypeName();
+ if (token === Token.COMMA) {
+ consume(Token.COMMA);
+ params = parseParametersType();
+ }
+ } else {
+ params = parseParametersType();
+ }
+ }
+
+ expect(Token.RPAREN);
+
+ result = null;
+ if (token === Token.COLON) {
+ result = parseResultType();
+ }
+
+ fnType = {
+ type: Syntax.FunctionType,
+ params: params,
+ result: result
+ };
+ if (thisBinding) {
+ // avoid adding null 'new' and 'this' properties
+ fnType['this'] = thisBinding;
+ if (isNew) {
+ fnType['new'] = true;
+ }
+ }
+ return fnType;
+ }
+
+ // BasicTypeExpression :=
+ // '*'
+ // | 'null'
+ // | 'undefined'
+ // | TypeName
+ // | FunctionType
+ // | UnionType
+ // | RecordType
+ // | ArrayType
+ function parseBasicTypeExpression() {
+ var context;
+ switch (token) {
+ case Token.STAR:
+ consume(Token.STAR);
+ return {
+ type: Syntax.AllLiteral
+ };
+
+ case Token.LPAREN:
+ return parseUnionType();
+
+ case Token.LBRACK:
+ return parseArrayType();
+
+ case Token.LBRACE:
+ return parseRecordType();
+
+ case Token.NAME:
+ if (value === 'null') {
+ consume(Token.NAME);
+ return {
+ type: Syntax.NullLiteral
+ };
+ }
+
+ if (value === 'undefined') {
+ consume(Token.NAME);
+ return {
+ type: Syntax.UndefinedLiteral
+ };
+ }
+
+ context = Context.save();
+ if (value === 'function') {
+ try {
+ return parseFunctionType();
+ } catch (e) {
+ context.restore();
+ }
+ }
+
+ return parseTypeName();
+
+ default:
+ utility.throwError('unexpected token');
+ }
+ }
+
+ // TypeExpression :=
+ // BasicTypeExpression
+ // | '?' BasicTypeExpression
+ // | '!' BasicTypeExpression
+ // | BasicTypeExpression '?'
+ // | BasicTypeExpression '!'
+ // | '?'
+ // | BasicTypeExpression '[]'
+ function parseTypeExpression() {
+ var expr;
+
+ if (token === Token.QUESTION) {
+ consume(Token.QUESTION);
+ if (token === Token.COMMA || token === Token.EQUAL || token === Token.RBRACE ||
+ token === Token.RPAREN || token === Token.PIPE || token === Token.EOF ||
+ token === Token.RBRACK || token === Token.GT) {
+ return {
+ type: Syntax.NullableLiteral
+ };
+ }
+ return {
+ type: Syntax.NullableType,
+ expression: parseBasicTypeExpression(),
+ prefix: true
+ };
+ }
+
+ if (token === Token.BANG) {
+ consume(Token.BANG);
+ return {
+ type: Syntax.NonNullableType,
+ expression: parseBasicTypeExpression(),
+ prefix: true
+ };
+ }
+
+ expr = parseBasicTypeExpression();
+ if (token === Token.BANG) {
+ consume(Token.BANG);
+ return {
+ type: Syntax.NonNullableType,
+ expression: expr,
+ prefix: false
+ };
+ }
+
+ if (token === Token.QUESTION) {
+ consume(Token.QUESTION);
+ return {
+ type: Syntax.NullableType,
+ expression: expr,
+ prefix: false
+ };
+ }
+
+ if (token === Token.LBRACK) {
+ consume(Token.LBRACK);
+ expect(Token.RBRACK, 'expected an array-style type declaration (' + value + '[])');
+ return {
+ type: Syntax.TypeApplication,
+ expression: {
+ type: Syntax.NameExpression,
+ name: 'Array'
+ },
+ applications: [expr]
+ };
+ }
+
+ return expr;
+ }
+
+ // TopLevelTypeExpression :=
+ // TypeExpression
+ // | TypeUnionList
+ //
+ // This rule is Google Closure Compiler extension, not ES4
+ // like,
+ // { number | string }
+ // If strict to ES4, we should write it as
+ // { (number|string) }
+ function parseTop() {
+ var expr, elements;
+
+ expr = parseTypeExpression();
+ if (token !== Token.PIPE) {
+ return expr;
+ }
+
+ elements = [ expr ];
+ consume(Token.PIPE);
+ while (true) {
+ elements.push(parseTypeExpression());
+ if (token !== Token.PIPE) {
+ break;
+ }
+ consume(Token.PIPE);
+ }
+
+ return {
+ type: Syntax.UnionType,
+ elements: elements
+ };
+ }
+
+ function parseTopParamType() {
+ var expr;
+
+ if (token === Token.REST) {
+ consume(Token.REST);
+ return {
+ type: Syntax.RestType,
+ expression: parseTop()
+ };
+ }
+
+ expr = parseTop();
+ if (token === Token.EQUAL) {
+ consume(Token.EQUAL);
+ return {
+ type: Syntax.OptionalType,
+ expression: expr
+ };
+ }
+
+ return expr;
+ }
+
+ function parseType(src, opt) {
+ var expr;
+
+ source = src;
+ length = source.length;
+ index = 0;
+ previous = 0;
+
+ next();
+ expr = parseTop();
+
+ if (opt && opt.midstream) {
+ return {
+ expression: expr,
+ index: previous
+ };
+ }
+
+ if (token !== Token.EOF) {
+ utility.throwError('not reach to EOF');
+ }
+
+ return expr;
+ }
+
+ function parseParamType(src, opt) {
+ var expr;
+
+ source = src;
+ length = source.length;
+ index = 0;
+ previous = 0;
+
+ next();
+ expr = parseTopParamType();
+
+ if (opt && opt.midstream) {
+ return {
+ expression: expr,
+ index: previous
+ };
+ }
+
+ if (token !== Token.EOF) {
+ utility.throwError('not reach to EOF');
+ }
+
+ return expr;
+ }
+
+ function stringifyImpl(node, compact, topLevel) {
+ var result, i, iz;
+
+ switch (node.type) {
+ case Syntax.NullableLiteral:
+ result = '?';
+ break;
+
+ case Syntax.AllLiteral:
+ result = '*';
+ break;
+
+ case Syntax.NullLiteral:
+ result = 'null';
+ break;
+
+ case Syntax.UndefinedLiteral:
+ result = 'undefined';
+ break;
+
+ case Syntax.VoidLiteral:
+ result = 'void';
+ break;
+
+ case Syntax.UnionType:
+ if (!topLevel) {
+ result = '(';
+ } else {
+ result = '';
+ }
+
+ for (i = 0, iz = node.elements.length; i < iz; ++i) {
+ result += stringifyImpl(node.elements[i], compact);
+ if ((i + 1) !== iz) {
+ result += '|';
+ }
+ }
+
+ if (!topLevel) {
+ result += ')';
+ }
+ break;
+
+ case Syntax.ArrayType:
+ result = '[';
+ for (i = 0, iz = node.elements.length; i < iz; ++i) {
+ result += stringifyImpl(node.elements[i], compact);
+ if ((i + 1) !== iz) {
+ result += compact ? ',' : ', ';
+ }
+ }
+ result += ']';
+ break;
+
+ case Syntax.RecordType:
+ result = '{';
+ for (i = 0, iz = node.fields.length; i < iz; ++i) {
+ result += stringifyImpl(node.fields[i], compact);
+ if ((i + 1) !== iz) {
+ result += compact ? ',' : ', ';
+ }
+ }
+ result += '}';
+ break;
+
+ case Syntax.FieldType:
+ if (node.value) {
+ result = node.key + (compact ? ':' : ': ') + stringifyImpl(node.value, compact);
+ } else {
+ result = node.key;
+ }
+ break;
+
+ case Syntax.FunctionType:
+ result = compact ? 'function(' : 'function (';
+
+ if (node['this']) {
+ if (node['new']) {
+ result += (compact ? 'new:' : 'new: ');
+ } else {
+ result += (compact ? 'this:' : 'this: ');
+ }
+
+ result += stringifyImpl(node['this'], compact);
+
+ if (node.params.length !== 0) {
+ result += compact ? ',' : ', ';
+ }
+ }
+
+ for (i = 0, iz = node.params.length; i < iz; ++i) {
+ result += stringifyImpl(node.params[i], compact);
+ if ((i + 1) !== iz) {
+ result += compact ? ',' : ', ';
+ }
+ }
+
+ result += ')';
+
+ if (node.result) {
+ result += (compact ? ':' : ': ') + stringifyImpl(node.result, compact);
+ }
+ break;
+
+ case Syntax.ParameterType:
+ result = node.name + (compact ? ':' : ': ') + stringifyImpl(node.expression, compact);
+ break;
+
+ case Syntax.RestType:
+ result = '...';
+ if (node.expression) {
+ result += stringifyImpl(node.expression, compact);
+ }
+ break;
+
+ case Syntax.NonNullableType:
+ if (node.prefix) {
+ result = '!' + stringifyImpl(node.expression, compact);
+ } else {
+ result = stringifyImpl(node.expression, compact) + '!';
+ }
+ break;
+
+ case Syntax.OptionalType:
+ result = stringifyImpl(node.expression, compact) + '=';
+ break;
+
+ case Syntax.NullableType:
+ if (node.prefix) {
+ result = '?' + stringifyImpl(node.expression, compact);
+ } else {
+ result = stringifyImpl(node.expression, compact) + '?';
+ }
+ break;
+
+ case Syntax.NameExpression:
+ result = node.name;
+ break;
+
+ case Syntax.TypeApplication:
+ result = stringifyImpl(node.expression, compact) + '.<';
+ for (i = 0, iz = node.applications.length; i < iz; ++i) {
+ result += stringifyImpl(node.applications[i], compact);
+ if ((i + 1) !== iz) {
+ result += compact ? ',' : ', ';
+ }
+ }
+ result += '>';
+ break;
+
+ default:
+ utility.throwError('Unknown type ' + node.type);
+ }
+
+ return result;
+ }
+
+ function stringify(node, options) {
+ if (options == null) {
+ options = {};
+ }
+ return stringifyImpl(node, options.compact, options.topLevel);
+ }
+
+ exports.parseType = parseType;
+ exports.parseParamType = parseParamType;
+ exports.stringify = stringify;
+ exports.Syntax = Syntax;
+}());
+/* vim: set sw=4 ts=4 et tw=80 : */
+
+},{"./utility":31,"esutils":35}],31:[function(require,module,exports){
+/*
+ Copyright (C) 2014 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+(function () {
+ 'use strict';
+
+ var VERSION;
+
+ VERSION = require('../package.json').version;
+ exports.VERSION = VERSION;
+
+ function DoctrineError(message) {
+ this.name = 'DoctrineError';
+ this.message = message;
+ }
+ DoctrineError.prototype = (function () {
+ var Middle = function () { };
+ Middle.prototype = Error.prototype;
+ return new Middle();
+ }());
+ DoctrineError.prototype.constructor = DoctrineError;
+ exports.DoctrineError = DoctrineError;
+
+ function throwError(message) {
+ throw new DoctrineError(message);
+ }
+ exports.throwError = throwError;
+
+ exports.assert = require('assert');
+}());
+
+/* vim: set sw=4 ts=4 et tw=80 : */
+
+},{"../package.json":37,"assert":18}],32:[function(require,module,exports){
+/*
+ Copyright (C) 2013 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+(function () {
+ 'use strict';
+
+ function isExpression(node) {
+ if (node == null) { return false; }
+ switch (node.type) {
+ case 'ArrayExpression':
+ case 'AssignmentExpression':
+ case 'BinaryExpression':
+ case 'CallExpression':
+ case 'ConditionalExpression':
+ case 'FunctionExpression':
+ case 'Identifier':
+ case 'Literal':
+ case 'LogicalExpression':
+ case 'MemberExpression':
+ case 'NewExpression':
+ case 'ObjectExpression':
+ case 'SequenceExpression':
+ case 'ThisExpression':
+ case 'UnaryExpression':
+ case 'UpdateExpression':
+ return true;
+ }
+ return false;
+ }
+
+ function isIterationStatement(node) {
+ if (node == null) { return false; }
+ switch (node.type) {
+ case 'DoWhileStatement':
+ case 'ForInStatement':
+ case 'ForStatement':
+ case 'WhileStatement':
+ return true;
+ }
+ return false;
+ }
+
+ function isStatement(node) {
+ if (node == null) { return false; }
+ switch (node.type) {
+ case 'BlockStatement':
+ case 'BreakStatement':
+ case 'ContinueStatement':
+ case 'DebuggerStatement':
+ case 'DoWhileStatement':
+ case 'EmptyStatement':
+ case 'ExpressionStatement':
+ case 'ForInStatement':
+ case 'ForStatement':
+ case 'IfStatement':
+ case 'LabeledStatement':
+ case 'ReturnStatement':
+ case 'SwitchStatement':
+ case 'ThrowStatement':
+ case 'TryStatement':
+ case 'VariableDeclaration':
+ case 'WhileStatement':
+ case 'WithStatement':
+ return true;
+ }
+ return false;
+ }
+
+ function isSourceElement(node) {
+ return isStatement(node) || node != null && node.type === 'FunctionDeclaration';
+ }
+
+ function trailingStatement(node) {
+ switch (node.type) {
+ case 'IfStatement':
+ if (node.alternate != null) {
+ return node.alternate;
+ }
+ return node.consequent;
+
+ case 'LabeledStatement':
+ case 'ForStatement':
+ case 'ForInStatement':
+ case 'WhileStatement':
+ case 'WithStatement':
+ return node.body;
+ }
+ return null;
+ }
+
+ function isProblematicIfStatement(node) {
+ var current;
+
+ if (node.type !== 'IfStatement') {
+ return false;
+ }
+ if (node.alternate == null) {
+ return false;
+ }
+ current = node.consequent;
+ do {
+ if (current.type === 'IfStatement') {
+ if (current.alternate == null) {
+ return true;
+ }
+ }
+ current = trailingStatement(current);
+ } while (current);
+
+ return false;
+ }
+
+ module.exports = {
+ isExpression: isExpression,
+ isStatement: isStatement,
+ isIterationStatement: isIterationStatement,
+ isSourceElement: isSourceElement,
+ isProblematicIfStatement: isProblematicIfStatement,
+
+ trailingStatement: trailingStatement
+ };
+}());
+/* vim: set sw=4 ts=4 et tw=80 : */
+
+},{}],33:[function(require,module,exports){
+/*
+ Copyright (C) 2013-2014 Yusuke Suzuki <utatane.tea@gmail.com>
+ Copyright (C) 2014 Ivan Nikulin <ifaaan@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+(function () {
+ 'use strict';
+
+ var Regex, NON_ASCII_WHITESPACES;
+
+ // See `tools/generate-identifier-regex.js`.
+ Regex = {
+ NonAsciiIdentifierStart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'),
+ NonAsciiIdentifierPart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0\u08A2-\u08AC\u08E4-\u08FE\u0900-\u0963\u0966-\u096F\u0971-\u0977\u0979-\u097F\u0981-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C82\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D02\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191C\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1D00-\u1DE6\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA697\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7B\uAA80-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE26\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]')
+ };
+
+ function isDecimalDigit(ch) {
+ return (ch >= 48 && ch <= 57); // 0..9
+ }
+
+ function isHexDigit(ch) {
+ return isDecimalDigit(ch) || // 0..9
+ (97 <= ch && ch <= 102) || // a..f
+ (65 <= ch && ch <= 70); // A..F
+ }
+
+ function isOctalDigit(ch) {
+ return (ch >= 48 && ch <= 55); // 0..7
+ }
+
+ // 7.2 White Space
+
+ NON_ASCII_WHITESPACES = [
+ 0x1680, 0x180E,
+ 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A,
+ 0x202F, 0x205F,
+ 0x3000,
+ 0xFEFF
+ ];
+
+ function isWhiteSpace(ch) {
+ return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
+ (ch >= 0x1680 && NON_ASCII_WHITESPACES.indexOf(ch) >= 0);
+ }
+
+ // 7.3 Line Terminators
+
+ function isLineTerminator(ch) {
+ return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029);
+ }
+
+ // 7.6 Identifier Names and Identifiers
+
+ function isIdentifierStart(ch) {
+ return (ch >= 97 && ch <= 122) || // a..z
+ (ch >= 65 && ch <= 90) || // A..Z
+ (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore)
+ (ch === 92) || // \ (backslash)
+ ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
+ }
+
+ function isIdentifierPart(ch) {
+ return (ch >= 97 && ch <= 122) || // a..z
+ (ch >= 65 && ch <= 90) || // A..Z
+ (ch >= 48 && ch <= 57) || // 0..9
+ (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore)
+ (ch === 92) || // \ (backslash)
+ ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
+ }
+
+ module.exports = {
+ isDecimalDigit: isDecimalDigit,
+ isHexDigit: isHexDigit,
+ isOctalDigit: isOctalDigit,
+ isWhiteSpace: isWhiteSpace,
+ isLineTerminator: isLineTerminator,
+ isIdentifierStart: isIdentifierStart,
+ isIdentifierPart: isIdentifierPart
+ };
+}());
+/* vim: set sw=4 ts=4 et tw=80 : */
+
+},{}],34:[function(require,module,exports){
+/*
+ Copyright (C) 2013 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+(function () {
+ 'use strict';
+
+ var code = require('./code');
+
+ function isStrictModeReservedWordES6(id) {
+ switch (id) {
+ case 'implements':
+ case 'interface':
+ case 'package':
+ case 'private':
+ case 'protected':
+ case 'public':
+ case 'static':
+ case 'let':
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ function isKeywordES5(id, strict) {
+ // yield should not be treated as keyword under non-strict mode.
+ if (!strict && id === 'yield') {
+ return false;
+ }
+ return isKeywordES6(id, strict);
+ }
+
+ function isKeywordES6(id, strict) {
+ if (strict && isStrictModeReservedWordES6(id)) {
+ return true;
+ }
+
+ switch (id.length) {
+ case 2:
+ return (id === 'if') || (id === 'in') || (id === 'do');
+ case 3:
+ return (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try');
+ case 4:
+ return (id === 'this') || (id === 'else') || (id === 'case') ||
+ (id === 'void') || (id === 'with') || (id === 'enum');
+ case 5:
+ return (id === 'while') || (id === 'break') || (id === 'catch') ||
+ (id === 'throw') || (id === 'const') || (id === 'yield') ||
+ (id === 'class') || (id === 'super');
+ case 6:
+ return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
+ (id === 'switch') || (id === 'export') || (id === 'import');
+ case 7:
+ return (id === 'default') || (id === 'finally') || (id === 'extends');
+ case 8:
+ return (id === 'function') || (id === 'continue') || (id === 'debugger');
+ case 10:
+ return (id === 'instanceof');
+ default:
+ return false;
+ }
+ }
+
+ function isReservedWordES5(id, strict) {
+ return id === 'null' || id === 'true' || id === 'false' || isKeywordES5(id, strict);
+ }
+
+ function isReservedWordES6(id, strict) {
+ return id === 'null' || id === 'true' || id === 'false' || isKeywordES6(id, strict);
+ }
+
+ function isRestrictedWord(id) {
+ return id === 'eval' || id === 'arguments';
+ }
+
+ function isIdentifierName(id) {
+ var i, iz, ch;
+
+ if (id.length === 0) {
+ return false;
+ }
+
+ ch = id.charCodeAt(0);
+ if (!code.isIdentifierStart(ch) || ch === 92) { // \ (backslash)
+ return false;
+ }
+
+ for (i = 1, iz = id.length; i < iz; ++i) {
+ ch = id.charCodeAt(i);
+ if (!code.isIdentifierPart(ch) || ch === 92) { // \ (backslash)
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function isIdentifierES5(id, strict) {
+ return isIdentifierName(id) && !isReservedWordES5(id, strict);
+ }
+
+ function isIdentifierES6(id, strict) {
+ return isIdentifierName(id) && !isReservedWordES6(id, strict);
+ }
+
+ module.exports = {
+ isKeywordES5: isKeywordES5,
+ isKeywordES6: isKeywordES6,
+ isReservedWordES5: isReservedWordES5,
+ isReservedWordES6: isReservedWordES6,
+ isRestrictedWord: isRestrictedWord,
+ isIdentifierName: isIdentifierName,
+ isIdentifierES5: isIdentifierES5,
+ isIdentifierES6: isIdentifierES6
+ };
+}());
+/* vim: set sw=4 ts=4 et tw=80 : */
+
+},{"./code":33}],35:[function(require,module,exports){
+/*
+ Copyright (C) 2013 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+(function () {
+ 'use strict';
+
+ exports.ast = require('./ast');
+ exports.code = require('./code');
+ exports.keyword = require('./keyword');
+}());
+/* vim: set sw=4 ts=4 et tw=80 : */
+
+},{"./ast":32,"./code":33,"./keyword":34}],36:[function(require,module,exports){
+module.exports = Array.isArray || function (arr) {
+ return Object.prototype.toString.call(arr) == '[object Array]';
+};
+
+},{}],37:[function(require,module,exports){
+module.exports={
+ "name": "doctrine",
+ "description": "JSDoc parser",
+ "homepage": "http://github.com/Constellation/doctrine.html",
+ "main": "lib/doctrine.js",
+ "version": "0.6.4",
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "directories": {
+ "lib": "./lib"
+ },
+ "files": [
+ "lib",
+ "LICENSE.BSD",
+ "LICENSE.closure-compiler",
+ "LICENSE.esprima",
+ "README.md"
+ ],
+ "maintainers": [
+ {
+ "name": "Yusuke Suzuki",
+ "email": "utatane.tea@gmail.com",
+ "url": "http://github.com/Constellation"
+ }
+ ],
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/Constellation/doctrine.git"
+ },
+ "devDependencies": {
+ "coveralls": "^2.11.2",
+ "gulp": "^3.8.10",
+ "gulp-bump": "^0.1.13",
+ "gulp-eslint": "^0.5.0",
+ "gulp-filter": "^2.0.2",
+ "gulp-git": "^1.0.0",
+ "gulp-istanbul": "^0.6.0",
+ "gulp-jshint": "^1.9.0",
+ "gulp-mocha": "^2.0.0",
+ "gulp-tag-version": "^1.2.1",
+ "jshint-stylish": "^1.0.0",
+ "should": "^5.0.1"
+ },
+ "licenses": [
+ {
+ "type": "BSD",
+ "url": "http://github.com/Constellation/doctrine/raw/master/LICENSE.BSD"
+ }
+ ],
+ "scripts": {
+ "test": "gulp",
+ "unit-test": "gulp test",
+ "lint": "gulp lint",
+ "coveralls": "cat ./coverage/lcov.info | coveralls && rm -rf ./coverage"
+ },
+ "dependencies": {
+ "esutils": "^1.1.6",
+ "isarray": "0.0.1"
+ },
+ "gitHead": "4f74c86ea5cd03fbd947c4df91a2192d13779fb5",
+ "readme": "doctrine ([doctrine](http://github.com/Constellation/doctrine)) is JSDoc parser.\n\n[](https://travis-ci.org/Constellation/doctrine)\n[](https://coveralls.io/r/Constellation/doctrine?branch=master)\n[](https://david-dm.org/Constellation/doctrine)\n[](https://david-dm.org/Constellation/doctrine#info=devDependencies)\n[](https://gitter.im/Constellation/doctrine)\n\nIt is now used by content assist system of [Eclipse Orion](http://www.eclipse.org/orion/) ([detail](http://planetorion.org/news/2012/10/orion-1-0-release/)). And used as JSDoc validator in [ESLint](http://eslint.org/).\n\nDoctrine can be used in a web browser with using browserify.\nor in a Node.js application via the package manager:\n\n npm install doctrine\n\nsimple example:\n\n doctrine.parse(\n [\n \"/**\",\n \" * This function comment is parsed by doctrine\",\n \" * @param {{ok:String}} userName\",\n \"*/\"\n ].join('\\n'), { unwrap: true });\n\nand gets following information\n\n {\n \"description\": \"This function comment is parsed by doctrine\",\n \"tags\": [\n {\n \"title\": \"param\",\n \"description\": null,\n \"type\": {\n \"type\": \"RecordType\",\n \"fields\": [\n {\n \"type\": \"FieldType\",\n \"key\": \"ok\",\n \"value\": {\n \"type\": \"NameExpression\",\n \"name\": \"String\"\n }\n }\n ]\n },\n \"name\": \"userName\"\n }\n ]\n }\n\nsee [demo page](http://constellation.github.com/doctrine/demo/index.html) more detail.\n\n### Options\n\n#### doctrine.parse\nWe can pass options to `doctrine.parse(comment, options)`.\n```js\n{\n unwrap: boolean, // default: false\n tags: [ string ] | null, // default: null\n recoverable: boolean, // default: false\n sloppy: boolean, // default: false\n lineNumbers: boolean // default: false\n}\n```\n\n##### unwrap\n\nWhen `unwrap` is `true`, doctrine attempt to unwrap comment specific string from a provided comment text. (removes `/**`, `*/` and `*`)\nFor example, `unwrap` transforms\n```\n/**\n * @param use\n */\n```\nto\n```\n@param use\n```\nIf a provided comment has these comment specific strings, you need to specify this `unwrap` option to `true`.\n\n##### tags\n\nWhen `tags` array is specified, doctrine only produce tags that is specified in this array.\nFor example, if you specify `[ 'param' ]`, doctrine only produces `param` tags.\nIf null is specified, doctrine produces all tags that doctrine can recognize.\n\n##### recoverable\n\nWhen `recoverable` is `true`, doctrine becomes `recoverable` - When failing to parse jsdoc comment, doctrine recovers its state and attempt to continue parsing.\n\n##### sloppy\n\nWhen `sloppy` is `true`,\n```\n@param String [foo]\n```\n's `[foo]` is interpreted as a optional parameter, not interpreted as a name of this `@param`.\n\n##### lineNumbers\n\nWhen `lineNumbers` is `true`, parsed tags will include a `lineNumber` property indicating the line (relative to the start of the comment block) where each tag is located in the source. So, given the following comment:\n```\n/**\n * @param {String} foo\n * @return {number}\n */\n```\nThe `@param` tag will have `lineNumber: 1`, and the `@return` tag will have `lineNumber: 2`.\n\n\n### License\n\n#### doctrine\n\nCopyright (C) 2012 [Yusuke Suzuki](http://github.com/Constellation)\n (twitter: [@Constellation](http://twitter.com/Constellation)) and other contributors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n\n * Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in the\n documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\nTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#### esprima\n\nsome of functions is derived from esprima\n\nCopyright (C) 2012, 2011 [Ariya Hidayat](http://ariya.ofilabs.com/about)\n (twitter: [@ariyahidayat](http://twitter.com/ariyahidayat)) and other contributors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n\n * Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in the\n documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\nTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\n#### closure-compiler\n\nsome of extensions is derived from closure-compiler\n\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n",
+ "readmeFilename": "README.md",
+ "bugs": {
+ "url": "https://github.com/Constellation/doctrine/issues"
+ },
+ "_id": "doctrine@0.6.4",
+ "_shasum": "5b8d534412b49b8177b52082cd95df380de390aa",
+ "_from": "git://github.com/PolymerLabs/doctrine.git#master",
+ "_resolved": "git://github.com/PolymerLabs/doctrine.git#4f74c86ea5cd03fbd947c4df91a2192d13779fb5",
+ "_fromGithub": true
+}
+
+},{}],38:[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+// jshint node: true
+'use strict';
+
+function getAttributeIndex(element, name) {
+ if (!element.attrs) {
+ return -1;
+ }
+ var n = name.toLowerCase();
+ for (var i = 0; i < element.attrs.length; i++) {
+ if (element.attrs[i].name.toLowerCase() === n) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+/**
+ * @returns {boolean} `true` iff [element] has the attribute [name], `false`
+ * otherwise.
+ */
+function hasAttribute(element, name) {
+ return getAttributeIndex(element, name) !== -1;
+}
+
+/**
+ * @returns {string|null} The string value of attribute `name`, or `null`.
+ */
+function getAttribute(element, name) {
+ var i = getAttributeIndex(element, name);
+ if (i > -1) {
+ return element.attrs[i].value;
+ }
+ return null;
+}
+
+function setAttribute(element, name, value) {
+ var i = getAttributeIndex(element, name);
+ if (i > -1) {
+ element.attrs[i].value = value;
+ } else {
+ element.attrs.push({name: name, value: value});
+ }
+}
+
+function removeAttribute(element, name) {
+ var i = getAttributeIndex(element, name);
+ if (i > -1) {
+ element.attrs.splice(i, 1);
+ }
+}
+
+function hasTagName(name) {
+ var n = name.toLowerCase();
+ return function(node) {
+ if (!node.tagName) {
+ return false;
+ }
+ return node.tagName.toLowerCase() === n;
+ };
+}
+
+/**
+ * Returns true if `regex.match(tagName)` finds a match.
+ *
+ * This will use the lowercased tagName for comparison.
+ *
+ * @param {RegExp} regex
+ * @return {Boolean}
+ */
+function hasMatchingTagName(regex) {
+ return function(node) {
+ if (!node.tagName) {
+ return false;
+ }
+ return regex.test(node.tagName.toLowerCase());
+ };
+}
+
+function hasClass(name) {
+ return function(node) {
+ var attr = getAttribute(node, 'class');
+ if (!attr) {
+ return false;
+ }
+ return attr.split(' ').indexOf(name) > -1;
+ };
+}
+
+function collapseTextRange(parent, start, end) {
+ var text = '';
+ for (var i = start; i <= end; i++) {
+ text += getTextContent(parent.childNodes[i]);
+ }
+ parent.childNodes.splice(start, (end - start) + 1);
+ if (text) {
+ var tn = newTextNode(text);
+ tn.parentNode = parent;
+ parent.childNodes.splice(start, 0, tn);
+ }
+}
+
+/**
+ * Normalize the text inside an element
+ *
+ * Equivalent to `element.normalize()` in the browser
+ * See https://developer.mozilla.org/en-US/docs/Web/API/Node/normalize
+ */
+function normalize(node) {
+ if (!(isElement(node) || isDocument(node) || isDocumentFragment(node))) {
+ return;
+ }
+ var textRangeStart = -1;
+ for (var i = node.childNodes.length - 1, n; i >= 0; i--) {
+ n = node.childNodes[i];
+ if (isTextNode(n)) {
+ if (textRangeStart == -1) {
+ textRangeStart = i;
+ }
+ if (i === 0) {
+ // collapse leading text nodes
+ collapseTextRange(node, 0, textRangeStart);
+ }
+ } else {
+ // recurse
+ normalize(n);
+ // collapse the range after this node
+ if (textRangeStart > -1) {
+ collapseTextRange(node, i + 1, textRangeStart);
+ textRangeStart = -1;
+ }
+ }
+ }
+}
+
+/**
+ * Return the text value of a node or element
+ *
+ * Equivalent to `node.textContent` in the browser
+ */
+function getTextContent(node) {
+ if (isCommentNode(node)) {
+ return node.data;
+ }
+ if (isTextNode(node)) {
+ return node.value;
+ }
+ var subtree = nodeWalkAll(node, isTextNode);
+ return subtree.map(getTextContent).join('');
+}
+
+/**
+ * Set the text value of a node or element
+ *
+ * Equivalent to `node.textContent = value` in the browser
+ */
+function setTextContent(node, value) {
+ if (isCommentNode(node)) {
+ node.data = value;
+ } else if (isTextNode(node)) {
+ node.value = value;
+ } else {
+ var tn = newTextNode(value);
+ tn.parentNode = node;
+ node.childNodes = [tn];
+ }
+}
+
+/**
+ * Match the text inside an element, textnode, or comment
+ *
+ * Note: nodeWalkAll with hasTextValue may return an textnode and its parent if
+ * the textnode is the only child in that parent.
+ */
+function hasTextValue(value) {
+ return function(node) {
+ return getTextContent(node) === value;
+ };
+}
+
+/**
+ * OR an array of predicates
+ */
+function OR(/* ...rules */) {
+ var rules = new Array(arguments.length);
+ for (var i = 0; i < arguments.length; i++) {
+ rules[i] = arguments[i];
+ }
+ return function(node) {
+ for (var i = 0; i < rules.length; i++) {
+ if (rules[i](node)) {
+ return true;
+ }
+ }
+ return false;
+ };
+}
+
+/**
+ * AND an array of predicates
+ */
+function AND(/* ...rules */) {
+ var rules = new Array(arguments.length);
+ for (var i = 0; i < arguments.length; i++) {
+ rules[i] = arguments[i];
+ }
+ return function(node) {
+ for (var i = 0; i < rules.length; i++) {
+ if (!rules[i](node)) {
+ return false;
+ }
+ }
+ return true;
+ };
+}
+
+/**
+ * negate an individual predicate, or a group with AND or OR
+ */
+function NOT(predicateFn) {
+ return function(node) {
+ return !predicateFn(node);
+ };
+}
+
+/**
+ * Returns a predicate that matches any node with a parent matching `predicateFn`.
+ */
+function parentMatches(predicateFn) {
+ return function(node) {
+ var parent = node.parentNode;
+ while(parent !== undefined) {
+ if (predicateFn(parent)) {
+ return true;
+ }
+ parent = parent.parentNode;
+ }
+ return false;
+ };
+}
+
+function hasAttr(attr) {
+ return function(node) {
+ return getAttributeIndex(node, attr) > -1;
+ };
+}
+
+function hasAttrValue(attr, value) {
+ return function(node) {
+ return getAttribute(node, attr) === value;
+ };
+}
+
+function isDocument(node) {
+ return node.nodeName === '#document';
+}
+
+function isDocumentFragment(node) {
+ return node.nodeName === '#document-fragment';
+}
+
+function isElement(node) {
+ return node.nodeName === node.tagName;
+}
+
+function isTextNode(node) {
+ return node.nodeName === '#text';
+}
+
+function isCommentNode(node) {
+ return node.nodeName === '#comment';
+}
+
+/**
+ * Applies `mapfn` to `node` and the tree below `node`, returning a flattened
+ * list of results.
+ * @return {Array}
+ */
+function treeMap(node, mapfn) {
+ var results = [];
+ nodeWalk(node, function(node){
+ results = results.concat(mapfn(node));
+ return false;
+ });
+ return results;
+}
+
+/**
+ * Walk the tree down from `node`, applying the `predicate` function.
+ * Return the first node that matches the given predicate.
+ *
+ * @returns {Node} `null` if no node matches, parse5 node object if a node
+ * matches
+ */
+function nodeWalk(node, predicate) {
+ if (predicate(node)) {
+ return node;
+ }
+ var match = null;
+ if (node.childNodes) {
+ for (var i = 0; i < node.childNodes.length; i++) {
+ match = nodeWalk(node.childNodes[i], predicate);
+ if (match) {
+ break;
+ }
+ }
+ }
+ return match;
+}
+
+/**
+ * Walk the tree down from `node`, applying the `predicate` function.
+ * All nodes matching the predicate function from `node` to leaves will be
+ * returned.
+ *
+ * @returns {Array[Node]}
+ */
+function nodeWalkAll(node, predicate, matches) {
+ if (!matches) {
+ matches = [];
+ }
+ if (predicate(node)) {
+ matches.push(node);
+ }
+ if (node.childNodes) {
+ for (var i = 0; i < node.childNodes.length; i++) {
+ nodeWalkAll(node.childNodes[i], predicate, matches);
+ }
+ }
+ return matches;
+}
+
+function _reverseNodeWalkAll(node, predicate, matches) {
+ if (!matches) {
+ matches = [];
+ }
+ if (node.childNodes) {
+ for (var i = node.childNodes.length - 1; i >= 0; i--) {
+ nodeWalkAll(node.childNodes[i], predicate, matches);
+ }
+ }
+ if (predicate(node)) {
+ matches.push(node);
+ }
+ return matches;
+}
+
+/**
+ * Equivalent to `nodeWalkAll`, but only returns nodes that are either
+ * ancestors or earlier cousins/siblings in the document.
+ *
+ * Nodes are returned in reverse document order, starting from `node`.
+ */
+function nodeWalkAllPrior(node, predicate, matches) {
+ if (!matches) {
+ matches = [];
+ }
+ if (predicate(node)) {
+ matches.push(node);
+ }
+ // Search our earlier siblings and their descendents.
+ var parent = node.parentNode;
+ if (parent) {
+ var idx = parent.childNodes.indexOf(node);
+ var siblings = parent.childNodes.slice(0, idx);
+ for (var i = siblings.length-1; i >= 0; i--) {
+ _reverseNodeWalkAll(siblings[i], predicate, matches);
+ }
+ nodeWalkAllPrior(parent, predicate, matches);
+ }
+ return matches;
+}
+
+/**
+ * Equivalent to `nodeWalk`, but only matches elements
+ *
+ * @returns {Element}
+ */
+function query(node, predicate) {
+ var elementPredicate = AND(isElement, predicate);
+ return nodeWalk(node, elementPredicate);
+}
+
+/**
+ * Equivalent to `nodeWalkAll`, but only matches elements
+ *
+ * @return {Array[Element]}
+ */
+function queryAll(node, predicate, matches) {
+ var elementPredicate = AND(isElement, predicate);
+ return nodeWalkAll(node, elementPredicate, matches);
+}
+
+function newTextNode(value) {
+ return {
+ nodeName: '#text',
+ value: value,
+ parentNode: null
+ };
+}
+
+function newCommentNode(comment) {
+ return {
+ nodeName: '#comment',
+ data: comment,
+ parentNode: null
+ };
+}
+
+function newElement(tagName, namespace) {
+ return {
+ nodeName: tagName,
+ tagName: tagName,
+ childNodes: [],
+ namespaceURI: namespace || 'http://www.w3.org/1999/xhtml',
+ attrs: [],
+ parentNode: null,
+ };
+}
+
+function replace(oldNode, newNode) {
+ insertBefore(oldNode.parentNode, oldNode, newNode);
+ remove(oldNode);
+}
+
+function remove(node) {
+ var parent = node.parentNode;
+ if (parent) {
+ var idx = parent.childNodes.indexOf(node);
+ parent.childNodes.splice(idx, 1);
+ }
+ node.parentNode = null;
+}
+
+function insertBefore(parent, oldNode, newNode) {
+ remove(newNode);
+ var idx = parent.childNodes.indexOf(oldNode);
+ parent.childNodes.splice(idx, 0, newNode);
+ newNode.parentNode = parent;
+}
+
+function append(parent, node) {
+ remove(node);
+ parent.childNodes.push(node);
+ node.parentNode = parent;
+}
+
+var parse5 = require('parse5');
+function parse(text, options) {
+ var parser = new parse5.Parser(parse5.TreeAdapters.default, options);
+ return parser.parse(text);
+}
+
+function parseFragment(text) {
+ var parser = new parse5.Parser();
+ return parser.parseFragment(text);
+}
+
+function serialize(ast) {
+ var serializer = new parse5.Serializer();
+ return serializer.serialize(ast);
+}
+
+module.exports = {
+ getAttribute: getAttribute,
+ hasAttribute: hasAttribute,
+ setAttribute: setAttribute,
+ removeAttribute: removeAttribute,
+ getTextContent: getTextContent,
+ setTextContent: setTextContent,
+ remove: remove,
+ replace: replace,
+ append: append,
+ insertBefore: insertBefore,
+ normalize: normalize,
+ isDocument: isDocument,
+ isDocumentFragment: isDocumentFragment,
+ isElement: isElement,
+ isTextNode: isTextNode,
+ isCommentNode: isCommentNode,
+ query: query,
+ queryAll: queryAll,
+ nodeWalk: nodeWalk,
+ nodeWalkAll: nodeWalkAll,
+ nodeWalkAllPrior: nodeWalkAllPrior,
+ treeMap: treeMap,
+ predicates: {
+ hasClass: hasClass,
+ hasAttr: hasAttr,
+ hasAttrValue: hasAttrValue,
+ hasMatchingTagName: hasMatchingTagName,
+ hasTagName: hasTagName,
+ hasTextValue: hasTextValue,
+ AND: AND,
+ OR: OR,
+ NOT: NOT,
+ parentMatches: parentMatches
+ },
+ constructors: {
+ text: newTextNode,
+ comment: newCommentNode,
+ element: newElement
+ },
+ parse: parse,
+ parseFragment: parseFragment,
+ serialize: serialize
+};
+
+},{"parse5":39}],39:[function(require,module,exports){
+'use strict';
+
+exports.Parser = require('./lib/tree_construction/parser');
+exports.SimpleApiParser = require('./lib/simple_api/simple_api_parser');
+exports.TreeSerializer =
+exports.Serializer = require('./lib/serialization/serializer');
+exports.JsDomParser = require('./lib/jsdom/jsdom_parser');
+
+exports.TreeAdapters = {
+ default: require('./lib/tree_adapters/default'),
+ htmlparser2: require('./lib/tree_adapters/htmlparser2')
+};
+
+},{"./lib/jsdom/jsdom_parser":45,"./lib/serialization/serializer":47,"./lib/simple_api/simple_api_parser":48,"./lib/tree_adapters/default":54,"./lib/tree_adapters/htmlparser2":55,"./lib/tree_construction/parser":59}],40:[function(require,module,exports){
+'use strict';
+
+//Const
+var VALID_DOCTYPE_NAME = 'html',
+ QUIRKS_MODE_SYSTEM_ID = 'http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd',
+ QUIRKS_MODE_PUBLIC_ID_PREFIXES = [
+ "+//silmaril//dtd html pro v0r11 19970101//en",
+ "-//advasoft ltd//dtd html 3.0 aswedit + extensions//en",
+ "-//as//dtd html 3.0 aswedit + extensions//en",
+ "-//ietf//dtd html 2.0 level 1//en",
+ "-//ietf//dtd html 2.0 level 2//en",
+ "-//ietf//dtd html 2.0 strict level 1//en",
+ "-//ietf//dtd html 2.0 strict level 2//en",
+ "-//ietf//dtd html 2.0 strict//en",
+ "-//ietf//dtd html 2.0//en",
+ "-//ietf//dtd html 2.1e//en",
+ "-//ietf//dtd html 3.0//en",
+ "-//ietf//dtd html 3.0//en//",
+ "-//ietf//dtd html 3.2 final//en",
+ "-//ietf//dtd html 3.2//en",
+ "-//ietf//dtd html 3//en",
+ "-//ietf//dtd html level 0//en",
+ "-//ietf//dtd html level 0//en//2.0",
+ "-//ietf//dtd html level 1//en",
+ "-//ietf//dtd html level 1//en//2.0",
+ "-//ietf//dtd html level 2//en",
+ "-//ietf//dtd html level 2//en//2.0",
+ "-//ietf//dtd html level 3//en",
+ "-//ietf//dtd html level 3//en//3.0",
+ "-//ietf//dtd html strict level 0//en",
+ "-//ietf//dtd html strict level 0//en//2.0",
+ "-//ietf//dtd html strict level 1//en",
+ "-//ietf//dtd html strict level 1//en//2.0",
+ "-//ietf//dtd html strict level 2//en",
+ "-//ietf//dtd html strict level 2//en//2.0",
+ "-//ietf//dtd html strict level 3//en",
+ "-//ietf//dtd html strict level 3//en//3.0",
+ "-//ietf//dtd html strict//en",
+ "-//ietf//dtd html strict//en//2.0",
+ "-//ietf//dtd html strict//en//3.0",
+ "-//ietf//dtd html//en",
+ "-//ietf//dtd html//en//2.0",
+ "-//ietf//dtd html//en//3.0",
+ "-//metrius//dtd metrius presentational//en",
+ "-//microsoft//dtd internet explorer 2.0 html strict//en",
+ "-//microsoft//dtd internet explorer 2.0 html//en",
+ "-//microsoft//dtd internet explorer 2.0 tables//en",
+ "-//microsoft//dtd internet explorer 3.0 html strict//en",
+ "-//microsoft//dtd internet explorer 3.0 html//en",
+ "-//microsoft//dtd internet explorer 3.0 tables//en",
+ "-//netscape comm. corp.//dtd html//en",
+ "-//netscape comm. corp.//dtd strict html//en",
+ "-//o'reilly and associates//dtd html 2.0//en",
+ "-//o'reilly and associates//dtd html extended 1.0//en",
+ "-//spyglass//dtd html 2.0 extended//en",
+ "-//sq//dtd html 2.0 hotmetal + extensions//en",
+ "-//sun microsystems corp.//dtd hotjava html//en",
+ "-//sun microsystems corp.//dtd hotjava strict html//en",
+ "-//w3c//dtd html 3 1995-03-24//en",
+ "-//w3c//dtd html 3.2 draft//en",
+ "-//w3c//dtd html 3.2 final//en",
+ "-//w3c//dtd html 3.2//en",
+ "-//w3c//dtd html 3.2s draft//en",
+ "-//w3c//dtd html 4.0 frameset//en",
+ "-//w3c//dtd html 4.0 transitional//en",
+ "-//w3c//dtd html experimental 19960712//en",
+ "-//w3c//dtd html experimental 970421//en",
+ "-//w3c//dtd w3 html//en",
+ "-//w3o//dtd w3 html 3.0//en",
+ "-//w3o//dtd w3 html 3.0//en//",
+ "-//webtechs//dtd mozilla html 2.0//en",
+ "-//webtechs//dtd mozilla html//en"
+ ],
+ QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES = [
+ '-//w3c//dtd html 4.01 frameset//',
+ '-//w3c//dtd html 4.01 transitional//'
+ ],
+ QUIRKS_MODE_PUBLIC_IDS = [
+ '-//w3o//dtd w3 html strict 3.0//en//',
+ '-/w3c/dtd html 4.0 transitional/en',
+ 'html'
+ ];
+
+
+//Utils
+function enquoteDoctypeId(id) {
+ var quote = id.indexOf('"') !== -1 ? '\'' : '"';
+
+ return quote + id + quote;
+}
+
+
+//API
+exports.isQuirks = function (name, publicId, systemId) {
+ if (name !== VALID_DOCTYPE_NAME)
+ return true;
+
+ if (systemId && systemId.toLowerCase() === QUIRKS_MODE_SYSTEM_ID)
+ return true;
+
+ if (publicId !== null) {
+ publicId = publicId.toLowerCase();
+
+ if (QUIRKS_MODE_PUBLIC_IDS.indexOf(publicId) > -1)
+ return true;
+
+ var prefixes = QUIRKS_MODE_PUBLIC_ID_PREFIXES;
+
+ if (systemId === null)
+ prefixes = prefixes.concat(QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES);
+
+ for (var i = 0; i < prefixes.length; i++) {
+ if (publicId.indexOf(prefixes[i]) === 0)
+ return true;
+ }
+ }
+
+ return false;
+};
+
+exports.serializeContent = function (name, publicId, systemId) {
+ var str = '!DOCTYPE ' + name;
+
+ if (publicId !== null)
+ str += ' PUBLIC ' + enquoteDoctypeId(publicId);
+
+ else if (systemId !== null)
+ str += ' SYSTEM';
+
+ if (systemId !== null)
+ str += ' ' + enquoteDoctypeId(systemId);
+
+ return str;
+};
+
+},{}],41:[function(require,module,exports){
+'use strict';
+
+var Tokenizer = require('../tokenization/tokenizer'),
+ HTML = require('./html');
+
+//Aliases
+var $ = HTML.TAG_NAMES,
+ NS = HTML.NAMESPACES,
+ ATTRS = HTML.ATTRS;
+
+
+//MIME types
+var MIME_TYPES = {
+ TEXT_HTML: 'text/html',
+ APPLICATION_XML: 'application/xhtml+xml'
+};
+
+//Attributes
+var DEFINITION_URL_ATTR = 'definitionurl',
+ ADJUSTED_DEFINITION_URL_ATTR = 'definitionURL',
+ SVG_ATTRS_ADJUSTMENT_MAP = {
+ 'attributename': 'attributeName',
+ 'attributetype': 'attributeType',
+ 'basefrequency': 'baseFrequency',
+ 'baseprofile': 'baseProfile',
+ 'calcmode': 'calcMode',
+ 'clippathunits': 'clipPathUnits',
+ 'contentscripttype': 'contentScriptType',
+ 'contentstyletype': 'contentStyleType',
+ 'diffuseconstant': 'diffuseConstant',
+ 'edgemode': 'edgeMode',
+ 'externalresourcesrequired': 'externalResourcesRequired',
+ 'filterres': 'filterRes',
+ 'filterunits': 'filterUnits',
+ 'glyphref': 'glyphRef',
+ 'gradienttransform': 'gradientTransform',
+ 'gradientunits': 'gradientUnits',
+ 'kernelmatrix': 'kernelMatrix',
+ 'kernelunitlength': 'kernelUnitLength',
+ 'keypoints': 'keyPoints',
+ 'keysplines': 'keySplines',
+ 'keytimes': 'keyTimes',
+ 'lengthadjust': 'lengthAdjust',
+ 'limitingconeangle': 'limitingConeAngle',
+ 'markerheight': 'markerHeight',
+ 'markerunits': 'markerUnits',
+ 'markerwidth': 'markerWidth',
+ 'maskcontentunits': 'maskContentUnits',
+ 'maskunits': 'maskUnits',
+ 'numoctaves': 'numOctaves',
+ 'pathlength': 'pathLength',
+ 'patterncontentunits': 'patternContentUnits',
+ 'patterntransform': 'patternTransform',
+ 'patternunits': 'patternUnits',
+ 'pointsatx': 'pointsAtX',
+ 'pointsaty': 'pointsAtY',
+ 'pointsatz': 'pointsAtZ',
+ 'preservealpha': 'preserveAlpha',
+ 'preserveaspectratio': 'preserveAspectRatio',
+ 'primitiveunits': 'primitiveUnits',
+ 'refx': 'refX',
+ 'refy': 'refY',
+ 'repeatcount': 'repeatCount',
+ 'repeatdur': 'repeatDur',
+ 'requiredextensions': 'requiredExtensions',
+ 'requiredfeatures': 'requiredFeatures',
+ 'specularconstant': 'specularConstant',
+ 'specularexponent': 'specularExponent',
+ 'spreadmethod': 'spreadMethod',
+ 'startoffset': 'startOffset',
+ 'stddeviation': 'stdDeviation',
+ 'stitchtiles': 'stitchTiles',
+ 'surfacescale': 'surfaceScale',
+ 'systemlanguage': 'systemLanguage',
+ 'tablevalues': 'tableValues',
+ 'targetx': 'targetX',
+ 'targety': 'targetY',
+ 'textlength': 'textLength',
+ 'viewbox': 'viewBox',
+ 'viewtarget': 'viewTarget',
+ 'xchannelselector': 'xChannelSelector',
+ 'ychannelselector': 'yChannelSelector',
+ 'zoomandpan': 'zoomAndPan'
+ },
+ XML_ATTRS_ADJUSTMENT_MAP = {
+ 'xlink:actuate': {prefix: 'xlink', name: 'actuate', namespace: NS.XLINK},
+ 'xlink:arcrole': {prefix: 'xlink', name: 'arcrole', namespace: NS.XLINK},
+ 'xlink:href': {prefix: 'xlink', name: 'href', namespace: NS.XLINK},
+ 'xlink:role': {prefix: 'xlink', name: 'role', namespace: NS.XLINK},
+ 'xlink:show': {prefix: 'xlink', name: 'show', namespace: NS.XLINK},
+ 'xlink:title': {prefix: 'xlink', name: 'title', namespace: NS.XLINK},
+ 'xlink:type': {prefix: 'xlink', name: 'type', namespace: NS.XLINK},
+ 'xml:base': {prefix: 'xml', name: 'base', namespace: NS.XML},
+ 'xml:lang': {prefix: 'xml', name: 'lang', namespace: NS.XML},
+ 'xml:space': {prefix: 'xml', name: 'space', namespace: NS.XML},
+ 'xmlns': {prefix: '', name: 'xmlns', namespace: NS.XMLNS},
+ 'xmlns:xlink': {prefix: 'xmlns', name: 'xlink', namespace: NS.XMLNS}
+
+ };
+
+//SVG tag names adjustment map
+var SVG_TAG_NAMES_ADJUSTMENT_MAP = {
+ 'altglyph': 'altGlyph',
+ 'altglyphdef': 'altGlyphDef',
+ 'altglyphitem': 'altGlyphItem',
+ 'animatecolor': 'animateColor',
+ 'animatemotion': 'animateMotion',
+ 'animatetransform': 'animateTransform',
+ 'clippath': 'clipPath',
+ 'feblend': 'feBlend',
+ 'fecolormatrix': 'feColorMatrix',
+ 'fecomponenttransfer': 'feComponentTransfer',
+ 'fecomposite': 'feComposite',
+ 'feconvolvematrix': 'feConvolveMatrix',
+ 'fediffuselighting': 'feDiffuseLighting',
+ 'fedisplacementmap': 'feDisplacementMap',
+ 'fedistantlight': 'feDistantLight',
+ 'feflood': 'feFlood',
+ 'fefunca': 'feFuncA',
+ 'fefuncb': 'feFuncB',
+ 'fefuncg': 'feFuncG',
+ 'fefuncr': 'feFuncR',
+ 'fegaussianblur': 'feGaussianBlur',
+ 'feimage': 'feImage',
+ 'femerge': 'feMerge',
+ 'femergenode': 'feMergeNode',
+ 'femorphology': 'feMorphology',
+ 'feoffset': 'feOffset',
+ 'fepointlight': 'fePointLight',
+ 'fespecularlighting': 'feSpecularLighting',
+ 'fespotlight': 'feSpotLight',
+ 'fetile': 'feTile',
+ 'feturbulence': 'feTurbulence',
+ 'foreignobject': 'foreignObject',
+ 'glyphref': 'glyphRef',
+ 'lineargradient': 'linearGradient',
+ 'radialgradient': 'radialGradient',
+ 'textpath': 'textPath'
+};
+
+//Tags that causes exit from foreign content
+var EXITS_FOREIGN_CONTENT = {};
+
+EXITS_FOREIGN_CONTENT[$.B] = true;
+EXITS_FOREIGN_CONTENT[$.BIG] = true;
+EXITS_FOREIGN_CONTENT[$.BLOCKQUOTE] = true;
+EXITS_FOREIGN_CONTENT[$.BODY] = true;
+EXITS_FOREIGN_CONTENT[$.BR] = true;
+EXITS_FOREIGN_CONTENT[$.CENTER] = true;
+EXITS_FOREIGN_CONTENT[$.CODE] = true;
+EXITS_FOREIGN_CONTENT[$.DD] = true;
+EXITS_FOREIGN_CONTENT[$.DIV] = true;
+EXITS_FOREIGN_CONTENT[$.DL] = true;
+EXITS_FOREIGN_CONTENT[$.DT] = true;
+EXITS_FOREIGN_CONTENT[$.EM] = true;
+EXITS_FOREIGN_CONTENT[$.EMBED] = true;
+EXITS_FOREIGN_CONTENT[$.H1] = true;
+EXITS_FOREIGN_CONTENT[$.H2] = true;
+EXITS_FOREIGN_CONTENT[$.H3] = true;
+EXITS_FOREIGN_CONTENT[$.H4] = true;
+EXITS_FOREIGN_CONTENT[$.H5] = true;
+EXITS_FOREIGN_CONTENT[$.H6] = true;
+EXITS_FOREIGN_CONTENT[$.HEAD] = true;
+EXITS_FOREIGN_CONTENT[$.HR] = true;
+EXITS_FOREIGN_CONTENT[$.I] = true;
+EXITS_FOREIGN_CONTENT[$.IMG] = true;
+EXITS_FOREIGN_CONTENT[$.LI] = true;
+EXITS_FOREIGN_CONTENT[$.LISTING] = true;
+EXITS_FOREIGN_CONTENT[$.MENU] = true;
+EXITS_FOREIGN_CONTENT[$.META] = true;
+EXITS_FOREIGN_CONTENT[$.NOBR] = true;
+EXITS_FOREIGN_CONTENT[$.OL] = true;
+EXITS_FOREIGN_CONTENT[$.P] = true;
+EXITS_FOREIGN_CONTENT[$.PRE] = true;
+EXITS_FOREIGN_CONTENT[$.RUBY] = true;
+EXITS_FOREIGN_CONTENT[$.S] = true;
+EXITS_FOREIGN_CONTENT[$.SMALL] = true;
+EXITS_FOREIGN_CONTENT[$.SPAN] = true;
+EXITS_FOREIGN_CONTENT[$.STRONG] = true;
+EXITS_FOREIGN_CONTENT[$.STRIKE] = true;
+EXITS_FOREIGN_CONTENT[$.SUB] = true;
+EXITS_FOREIGN_CONTENT[$.SUP] = true;
+EXITS_FOREIGN_CONTENT[$.TABLE] = true;
+EXITS_FOREIGN_CONTENT[$.TT] = true;
+EXITS_FOREIGN_CONTENT[$.U] = true;
+EXITS_FOREIGN_CONTENT[$.UL] = true;
+EXITS_FOREIGN_CONTENT[$.VAR] = true;
+
+//Check exit from foreign content
+exports.causesExit = function (startTagToken) {
+ var tn = startTagToken.tagName;
+
+ if (tn === $.FONT && (Tokenizer.getTokenAttr(startTagToken, ATTRS.COLOR) !== null ||
+ Tokenizer.getTokenAttr(startTagToken, ATTRS.SIZE) !== null ||
+ Tokenizer.getTokenAttr(startTagToken, ATTRS.FACE) !== null)) {
+ return true;
+ }
+
+ return EXITS_FOREIGN_CONTENT[tn];
+};
+
+//Token adjustments
+exports.adjustTokenMathMLAttrs = function (token) {
+ for (var i = 0; i < token.attrs.length; i++) {
+ if (token.attrs[i].name === DEFINITION_URL_ATTR) {
+ token.attrs[i].name = ADJUSTED_DEFINITION_URL_ATTR;
+ break;
+ }
+ }
+};
+
+exports.adjustTokenSVGAttrs = function (token) {
+ for (var i = 0; i < token.attrs.length; i++) {
+ var adjustedAttrName = SVG_ATTRS_ADJUSTMENT_MAP[token.attrs[i].name];
+
+ if (adjustedAttrName)
+ token.attrs[i].name = adjustedAttrName;
+ }
+};
+
+exports.adjustTokenXMLAttrs = function (token) {
+ for (var i = 0; i < token.attrs.length; i++) {
+ var adjustedAttrEntry = XML_ATTRS_ADJUSTMENT_MAP[token.attrs[i].name];
+
+ if (adjustedAttrEntry) {
+ token.attrs[i].prefix = adjustedAttrEntry.prefix;
+ token.attrs[i].name = adjustedAttrEntry.name;
+ token.attrs[i].namespace = adjustedAttrEntry.namespace;
+ }
+ }
+};
+
+exports.adjustTokenSVGTagName = function (token) {
+ var adjustedTagName = SVG_TAG_NAMES_ADJUSTMENT_MAP[token.tagName];
+
+ if (adjustedTagName)
+ token.tagName = adjustedTagName;
+};
+
+//Integration points
+exports.isMathMLTextIntegrationPoint = function (tn, ns) {
+ return ns === NS.MATHML && (tn === $.MI || tn === $.MO || tn === $.MN || tn === $.MS || tn === $.MTEXT);
+};
+
+exports.isHtmlIntegrationPoint = function (tn, ns, attrs) {
+ if (ns === NS.MATHML && tn === $.ANNOTATION_XML) {
+ for (var i = 0; i < attrs.length; i++) {
+ if (attrs[i].name === ATTRS.ENCODING) {
+ var value = attrs[i].value.toLowerCase();
+
+ return value === MIME_TYPES.TEXT_HTML || value === MIME_TYPES.APPLICATION_XML;
+ }
+ }
+ }
+
+ return ns === NS.SVG && (tn === $.FOREIGN_OBJECT || tn === $.DESC || tn === $.TITLE);
+};
+
+},{"../tokenization/tokenizer":53,"./html":42}],42:[function(require,module,exports){
+'use strict';
+
+var NS = exports.NAMESPACES = {
+ HTML: 'http://www.w3.org/1999/xhtml',
+ MATHML: 'http://www.w3.org/1998/Math/MathML',
+ SVG: 'http://www.w3.org/2000/svg',
+ XLINK: 'http://www.w3.org/1999/xlink',
+ XML: 'http://www.w3.org/XML/1998/namespace',
+ XMLNS: 'http://www.w3.org/2000/xmlns/'
+};
+
+exports.ATTRS = {
+ TYPE: 'type',
+ ACTION: 'action',
+ ENCODING: 'encoding',
+ PROMPT: 'prompt',
+ NAME: 'name',
+ COLOR: 'color',
+ FACE: 'face',
+ SIZE: 'size'
+};
+
+var $ = exports.TAG_NAMES = {
+ A: 'a',
+ ADDRESS: 'address',
+ ANNOTATION_XML: 'annotation-xml',
+ APPLET: 'applet',
+ AREA: 'area',
+ ARTICLE: 'article',
+ ASIDE: 'aside',
+
+ B: 'b',
+ BASE: 'base',
+ BASEFONT: 'basefont',
+ BGSOUND: 'bgsound',
+ BIG: 'big',
+ BLOCKQUOTE: 'blockquote',
+ BODY: 'body',
+ BR: 'br',
+ BUTTON: 'button',
+
+ CAPTION: 'caption',
+ CENTER: 'center',
+ CODE: 'code',
+ COL: 'col',
+ COLGROUP: 'colgroup',
+ COMMAND: 'command',
+
+ DD: 'dd',
+ DESC: 'desc',
+ DETAILS: 'details',
+ DIALOG: 'dialog',
+ DIR: 'dir',
+ DIV: 'div',
+ DL: 'dl',
+ DT: 'dt',
+
+ EM: 'em',
+ EMBED: 'embed',
+
+ FIELDSET: 'fieldset',
+ FIGCAPTION: 'figcaption',
+ FIGURE: 'figure',
+ FONT: 'font',
+ FOOTER: 'footer',
+ FOREIGN_OBJECT: 'foreignObject',
+ FORM: 'form',
+ FRAME: 'frame',
+ FRAMESET: 'frameset',
+
+ H1: 'h1',
+ H2: 'h2',
+ H3: 'h3',
+ H4: 'h4',
+ H5: 'h5',
+ H6: 'h6',
+ HEAD: 'head',
+ HEADER: 'header',
+ HGROUP: 'hgroup',
+ HR: 'hr',
+ HTML: 'html',
+
+ I: 'i',
+ IMG: 'img',
+ IMAGE: 'image',
+ INPUT: 'input',
+ IFRAME: 'iframe',
+ ISINDEX: 'isindex',
+
+ KEYGEN: 'keygen',
+
+ LABEL: 'label',
+ LI: 'li',
+ LINK: 'link',
+ LISTING: 'listing',
+
+ MAIN: 'main',
+ MALIGNMARK: 'malignmark',
+ MARQUEE: 'marquee',
+ MATH: 'math',
+ MENU: 'menu',
+ MENUITEM: 'menuitem',
+ META: 'meta',
+ MGLYPH: 'mglyph',
+ MI: 'mi',
+ MO: 'mo',
+ MN: 'mn',
+ MS: 'ms',
+ MTEXT: 'mtext',
+
+ NAV: 'nav',
+ NOBR: 'nobr',
+ NOFRAMES: 'noframes',
+ NOEMBED: 'noembed',
+ NOSCRIPT: 'noscript',
+
+ OBJECT: 'object',
+ OL: 'ol',
+ OPTGROUP: 'optgroup',
+ OPTION: 'option',
+
+ P: 'p',
+ PARAM: 'param',
+ PLAINTEXT: 'plaintext',
+ PRE: 'pre',
+
+ RP: 'rp',
+ RT: 'rt',
+ RUBY: 'ruby',
+
+ S: 's',
+ SCRIPT: 'script',
+ SECTION: 'section',
+ SELECT: 'select',
+ SOURCE: 'source',
+ SMALL: 'small',
+ SPAN: 'span',
+ STRIKE: 'strike',
+ STRONG: 'strong',
+ STYLE: 'style',
+ SUB: 'sub',
+ SUMMARY: 'summary',
+ SUP: 'sup',
+
+ TABLE: 'table',
+ TBODY: 'tbody',
+ TEMPLATE: 'template',
+ TEXTAREA: 'textarea',
+ TFOOT: 'tfoot',
+ TD: 'td',
+ TH: 'th',
+ THEAD: 'thead',
+ TITLE: 'title',
+ TR: 'tr',
+ TRACK: 'track',
+ TT: 'tt',
+
+ U: 'u',
+ UL: 'ul',
+
+ SVG: 'svg',
+
+ VAR: 'var',
+
+ WBR: 'wbr',
+
+ XMP: 'xmp'
+};
+
+var SPECIAL_ELEMENTS = exports.SPECIAL_ELEMENTS = {};
+
+SPECIAL_ELEMENTS[NS.HTML] = {};
+SPECIAL_ELEMENTS[NS.HTML][$.ADDRESS] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.APPLET] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.AREA] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.ARTICLE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.ASIDE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.BASE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.BASEFONT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.BGSOUND] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.BLOCKQUOTE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.BODY] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.BR] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.BUTTON] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.CAPTION] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.CENTER] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.COL] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.COLGROUP] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.DD] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.DETAILS] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.DIR] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.DIV] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.DL] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.DT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.EMBED] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.FIELDSET] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.FIGCAPTION] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.FIGURE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.FOOTER] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.FORM] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.FRAME] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.FRAMESET] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.H1] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.H2] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.H3] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.H4] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.H5] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.H6] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.HEAD] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.HEADER] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.HGROUP] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.HR] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.HTML] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.IFRAME] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.IMG] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.INPUT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.ISINDEX] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.LI] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.LINK] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.LISTING] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.MAIN] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.MARQUEE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.MENU] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.MENUITEM] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.META] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.NAV] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.NOEMBED] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.NOFRAMES] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.NOSCRIPT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.OBJECT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.OL] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.P] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.PARAM] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.PLAINTEXT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.PRE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.SCRIPT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.SECTION] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.SELECT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.SOURCE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.STYLE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.SUMMARY] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TABLE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TBODY] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TD] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TEMPLATE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TEXTAREA] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TFOOT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TH] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.THEAD] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TITLE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TR] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TRACK] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.UL] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.WBR] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.XMP] = true;
+
+SPECIAL_ELEMENTS[NS.MATHML] = {};
+SPECIAL_ELEMENTS[NS.MATHML][$.MI] = true;
+SPECIAL_ELEMENTS[NS.MATHML][$.MO] = true;
+SPECIAL_ELEMENTS[NS.MATHML][$.MN] = true;
+SPECIAL_ELEMENTS[NS.MATHML][$.MS] = true;
+SPECIAL_ELEMENTS[NS.MATHML][$.MTEXT] = true;
+SPECIAL_ELEMENTS[NS.MATHML][$.ANNOTATION_XML] = true;
+
+SPECIAL_ELEMENTS[NS.SVG] = {};
+SPECIAL_ELEMENTS[NS.SVG][$.TITLE] = true;
+SPECIAL_ELEMENTS[NS.SVG][$.FOREIGN_OBJECT] = true;
+SPECIAL_ELEMENTS[NS.SVG][$.DESC] = true;
+
+},{}],43:[function(require,module,exports){
+'use strict';
+
+exports.REPLACEMENT_CHARACTER = '\uFFFD';
+
+exports.CODE_POINTS = {
+ EOF: -1,
+ NULL: 0x00,
+ TABULATION: 0x09,
+ CARRIAGE_RETURN: 0x0D,
+ LINE_FEED: 0x0A,
+ FORM_FEED: 0x0C,
+ SPACE: 0x20,
+ EXCLAMATION_MARK: 0x21,
+ QUOTATION_MARK: 0x22,
+ NUMBER_SIGN: 0x23,
+ AMPERSAND: 0x26,
+ APOSTROPHE: 0x27,
+ HYPHEN_MINUS: 0x2D,
+ SOLIDUS: 0x2F,
+ DIGIT_0: 0x30,
+ DIGIT_9: 0x39,
+ SEMICOLON: 0x3B,
+ LESS_THAN_SIGN: 0x3C,
+ EQUALS_SIGN: 0x3D,
+ GREATER_THAN_SIGN: 0x3E,
+ QUESTION_MARK: 0x3F,
+ LATIN_CAPITAL_A: 0x41,
+ LATIN_CAPITAL_F: 0x46,
+ LATIN_CAPITAL_X: 0x58,
+ LATIN_CAPITAL_Z: 0x5A,
+ GRAVE_ACCENT: 0x60,
+ LATIN_SMALL_A: 0x61,
+ LATIN_SMALL_F: 0x66,
+ LATIN_SMALL_X: 0x78,
+ LATIN_SMALL_Z: 0x7A,
+ BOM: 0xFEFF,
+ REPLACEMENT_CHARACTER: 0xFFFD
+};
+
+exports.CODE_POINT_SEQUENCES = {
+ DASH_DASH_STRING: [0x2D, 0x2D], //--
+ DOCTYPE_STRING: [0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45], //DOCTYPE
+ CDATA_START_STRING: [0x5B, 0x43, 0x44, 0x41, 0x54, 0x41, 0x5B], //[CDATA[
+ CDATA_END_STRING: [0x5D, 0x5D, 0x3E], //]]>
+ SCRIPT_STRING: [0x73, 0x63, 0x72, 0x69, 0x70, 0x74], //script
+ PUBLIC_STRING: [0x50, 0x55, 0x42, 0x4C, 0x49, 0x43], //PUBLIC
+ SYSTEM_STRING: [0x53, 0x59, 0x53, 0x54, 0x45, 0x4D] //SYSTEM
+};
+
+},{}],44:[function(require,module,exports){
+'use strict';
+
+exports.mergeOptions = function (defaults, options) {
+ options = options || {};
+
+ return [defaults, options].reduce(function (merged, optObj) {
+ Object.keys(optObj).forEach(function (key) {
+ merged[key] = optObj[key];
+ });
+
+ return merged;
+ }, {});
+};
+
+},{}],45:[function(require,module,exports){
+(function (process){
+'use strict';
+
+var Parser = require('../tree_construction/parser'),
+ ParsingUnit = require('./parsing_unit');
+
+//API
+exports.parseDocument = function (html, treeAdapter) {
+ //NOTE: this should be reentrant, so we create new parser here
+ var parser = new Parser(treeAdapter),
+ parsingUnit = new ParsingUnit(parser);
+
+ //NOTE: override parser loop method
+ parser._runParsingLoop = function () {
+ parsingUnit.parsingLoopLock = true;
+
+ while (!parsingUnit.suspended && !this.stopped)
+ this._iterateParsingLoop();
+
+ parsingUnit.parsingLoopLock = false;
+
+ if (this.stopped)
+ parsingUnit.callback(this.document);
+ };
+
+ //NOTE: wait while parserController will be adopted by calling code, then
+ //start parsing
+ process.nextTick(function () {
+ parser.parse(html);
+ });
+
+ return parsingUnit;
+};
+
+exports.parseInnerHtml = function (innerHtml, contextElement, treeAdapter) {
+ //NOTE: this should be reentrant, so we create new parser here
+ var parser = new Parser(treeAdapter);
+
+ return parser.parseFragment(innerHtml, contextElement);
+};
+}).call(this,require('_process'))
+
+},{"../tree_construction/parser":59,"./parsing_unit":46,"_process":21}],46:[function(require,module,exports){
+'use strict';
+
+var ParsingUnit = module.exports = function (parser) {
+ this.parser = parser;
+ this.suspended = false;
+ this.parsingLoopLock = false;
+ this.callback = null;
+};
+
+ParsingUnit.prototype._stateGuard = function (suspend) {
+ if (this.suspended && suspend)
+ throw new Error('parse5: Parser was already suspended. Please, check your control flow logic.');
+
+ else if (!this.suspended && !suspend)
+ throw new Error('parse5: Parser was already resumed. Please, check your control flow logic.');
+
+ return suspend;
+};
+
+ParsingUnit.prototype.suspend = function () {
+ this.suspended = this._stateGuard(true);
+
+ return this;
+};
+
+ParsingUnit.prototype.resume = function () {
+ this.suspended = this._stateGuard(false);
+
+ //NOTE: don't enter parsing loop if it is locked. Without this lock _runParsingLoop() may be called
+ //while parsing loop is still running. E.g. when suspend() and resume() called synchronously.
+ if (!this.parsingLoopLock)
+ this.parser._runParsingLoop();
+
+ return this;
+};
+
+ParsingUnit.prototype.documentWrite = function (html) {
+ this.parser.tokenizer.preprocessor.write(html);
+
+ return this;
+};
+
+ParsingUnit.prototype.handleScripts = function (scriptHandler) {
+ this.parser.scriptHandler = scriptHandler;
+
+ return this;
+};
+
+ParsingUnit.prototype.done = function (callback) {
+ this.callback = callback;
+
+ return this;
+};
+
+},{}],47:[function(require,module,exports){
+'use strict';
+
+var DefaultTreeAdapter = require('../tree_adapters/default'),
+ Doctype = require('../common/doctype'),
+ Utils = require('../common/utils'),
+ HTML = require('../common/html');
+
+//Aliases
+var $ = HTML.TAG_NAMES,
+ NS = HTML.NAMESPACES;
+
+//Default serializer options
+var DEFAULT_OPTIONS = {
+ encodeHtmlEntities: true
+};
+
+//Escaping regexes
+var AMP_REGEX = /&/g,
+ NBSP_REGEX = /\u00a0/g,
+ DOUBLE_QUOTE_REGEX = /"/g,
+ LT_REGEX = /</g,
+ GT_REGEX = />/g;
+
+//Escape string
+function escapeString(str, attrMode) {
+ str = str
+ .replace(AMP_REGEX, '&')
+ .replace(NBSP_REGEX, ' ');
+
+ if (attrMode)
+ str = str.replace(DOUBLE_QUOTE_REGEX, '"');
+
+ else {
+ str = str
+ .replace(LT_REGEX, '<')
+ .replace(GT_REGEX, '>');
+ }
+
+ return str;
+}
+
+
+//Enquote doctype ID
+
+
+
+//Serializer
+var Serializer = module.exports = function (treeAdapter, options) {
+ this.treeAdapter = treeAdapter || DefaultTreeAdapter;
+ this.options = Utils.mergeOptions(DEFAULT_OPTIONS, options);
+};
+
+
+//API
+Serializer.prototype.serialize = function (node) {
+ this.html = '';
+ this._serializeChildNodes(node);
+
+ return this.html;
+};
+
+
+//Internals
+Serializer.prototype._serializeChildNodes = function (parentNode) {
+ var childNodes = this.treeAdapter.getChildNodes(parentNode);
+
+ if (childNodes) {
+ for (var i = 0, cnLength = childNodes.length; i < cnLength; i++) {
+ var currentNode = childNodes[i];
+
+ if (this.treeAdapter.isElementNode(currentNode))
+ this._serializeElement(currentNode);
+
+ else if (this.treeAdapter.isTextNode(currentNode))
+ this._serializeTextNode(currentNode);
+
+ else if (this.treeAdapter.isCommentNode(currentNode))
+ this._serializeCommentNode(currentNode);
+
+ else if (this.treeAdapter.isDocumentTypeNode(currentNode))
+ this._serializeDocumentTypeNode(currentNode);
+ }
+ }
+};
+
+Serializer.prototype._serializeElement = function (node) {
+ var tn = this.treeAdapter.getTagName(node),
+ ns = this.treeAdapter.getNamespaceURI(node),
+ qualifiedTn = (ns === NS.HTML || ns === NS.SVG || ns === NS.MATHML) ? tn : (ns + ':' + tn);
+
+ this.html += '<' + qualifiedTn;
+ this._serializeAttributes(node);
+ this.html += '>';
+
+ if (tn !== $.AREA && tn !== $.BASE && tn !== $.BASEFONT && tn !== $.BGSOUND && tn !== $.BR && tn !== $.BR &&
+ tn !== $.COL && tn !== $.EMBED && tn !== $.FRAME && tn !== $.HR && tn !== $.IMG && tn !== $.INPUT &&
+ tn !== $.KEYGEN && tn !== $.LINK && tn !== $.MENUITEM && tn !== $.META && tn !== $.PARAM && tn !== $.SOURCE &&
+ tn !== $.TRACK && tn !== $.WBR) {
+
+ if (tn === $.PRE || tn === $.TEXTAREA || tn === $.LISTING) {
+ var firstChild = this.treeAdapter.getFirstChild(node);
+
+ if (firstChild && this.treeAdapter.isTextNode(firstChild)) {
+ var content = this.treeAdapter.getTextNodeContent(firstChild);
+
+ if (content[0] === '\n')
+ this.html += '\n';
+ }
+ }
+
+ var childNodesHolder = tn === $.TEMPLATE && ns === NS.HTML ?
+ this.treeAdapter.getChildNodes(node)[0] :
+ node;
+
+ this._serializeChildNodes(childNodesHolder);
+ this.html += '</' + qualifiedTn + '>';
+ }
+};
+
+Serializer.prototype._serializeAttributes = function (node) {
+ var attrs = this.treeAdapter.getAttrList(node);
+
+ for (var i = 0, attrsLength = attrs.length; i < attrsLength; i++) {
+ var attr = attrs[i],
+ value = this.options.encodeHtmlEntities ? escapeString(attr.value, true) : attr.value;
+
+ this.html += ' ';
+
+ if (!attr.namespace)
+ this.html += attr.name;
+
+ else if (attr.namespace === NS.XML)
+ this.html += 'xml:' + attr.name;
+
+ else if (attr.namespace === NS.XMLNS) {
+ if (attr.name !== 'xmlns')
+ this.html += 'xmlns:';
+
+ this.html += attr.name;
+ }
+
+ else if (attr.namespace === NS.XLINK)
+ this.html += 'xlink:' + attr.name;
+
+ else
+ this.html += attr.namespace + ':' + attr.name;
+
+ this.html += '="' + value + '"';
+ }
+};
+
+Serializer.prototype._serializeTextNode = function (node) {
+ var content = this.treeAdapter.getTextNodeContent(node),
+ parent = this.treeAdapter.getParentNode(node),
+ parentTn = void 0;
+
+ if (parent && this.treeAdapter.isElementNode(parent))
+ parentTn = this.treeAdapter.getTagName(parent);
+
+ if (parentTn === $.STYLE || parentTn === $.SCRIPT || parentTn === $.XMP || parentTn === $.IFRAME ||
+ parentTn === $.NOEMBED || parentTn === $.NOFRAMES || parentTn === $.PLAINTEXT || parentTn === $.NOSCRIPT) {
+ this.html += content;
+ }
+
+ else
+ this.html += this.options.encodeHtmlEntities ? escapeString(content, false) : content;
+};
+
+Serializer.prototype._serializeCommentNode = function (node) {
+ this.html += '<!--' + this.treeAdapter.getCommentNodeContent(node) + '-->';
+};
+
+Serializer.prototype._serializeDocumentTypeNode = function (node) {
+ var name = this.treeAdapter.getDocumentTypeNodeName(node),
+ publicId = this.treeAdapter.getDocumentTypeNodePublicId(node),
+ systemId = this.treeAdapter.getDocumentTypeNodeSystemId(node);
+
+ this.html += '<' + Doctype.serializeContent(name, publicId, systemId) + '>';
+};
+
+},{"../common/doctype":40,"../common/html":42,"../common/utils":44,"../tree_adapters/default":54}],48:[function(require,module,exports){
+'use strict';
+
+var Tokenizer = require('../tokenization/tokenizer'),
+ TokenizerProxy = require('./tokenizer_proxy'),
+ Utils = require('../common/utils');
+
+//Default options
+var DEFAULT_OPTIONS = {
+ decodeHtmlEntities: true,
+ locationInfo: false
+};
+
+//Skipping handler
+function skip() {
+ //NOTE: do nothing =)
+}
+
+//SimpleApiParser
+var SimpleApiParser = module.exports = function (handlers, options) {
+ this.options = Utils.mergeOptions(DEFAULT_OPTIONS, options);
+ this.handlers = {
+ doctype: this._wrapHandler(handlers.doctype),
+ startTag: this._wrapHandler(handlers.startTag),
+ endTag: this._wrapHandler(handlers.endTag),
+ text: this._wrapHandler(handlers.text),
+ comment: this._wrapHandler(handlers.comment)
+ };
+};
+
+SimpleApiParser.prototype._wrapHandler = function (handler) {
+ var parser = this;
+
+ handler = handler || skip;
+
+ if (this.options.locationInfo) {
+ return function () {
+ var args = Array.prototype.slice.call(arguments);
+ args.push(parser.currentTokenLocation);
+ handler.apply(handler, args);
+ };
+ }
+
+ return handler;
+};
+
+//API
+SimpleApiParser.prototype.parse = function (html) {
+ var token = null;
+
+ this._reset(html);
+
+ do {
+ token = this.tokenizerProxy.getNextToken();
+
+ if (token.type === Tokenizer.CHARACTER_TOKEN ||
+ token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN ||
+ token.type === Tokenizer.NULL_CHARACTER_TOKEN) {
+
+ if (this.options.locationInfo) {
+ if (this.pendingText === null)
+ this.currentTokenLocation = token.location;
+
+ else
+ this.currentTokenLocation.end = token.location.end;
+ }
+
+ this.pendingText = (this.pendingText || '') + token.chars;
+ }
+
+ else {
+ this._emitPendingText();
+ this._handleToken(token);
+ }
+ } while (token.type !== Tokenizer.EOF_TOKEN);
+};
+
+//Internals
+SimpleApiParser.prototype._handleToken = function (token) {
+ if (this.options.locationInfo)
+ this.currentTokenLocation = token.location;
+
+ if (token.type === Tokenizer.START_TAG_TOKEN)
+ this.handlers.startTag(token.tagName, token.attrs, token.selfClosing);
+
+ else if (token.type === Tokenizer.END_TAG_TOKEN)
+ this.handlers.endTag(token.tagName);
+
+ else if (token.type === Tokenizer.COMMENT_TOKEN)
+ this.handlers.comment(token.data);
+
+ else if (token.type === Tokenizer.DOCTYPE_TOKEN)
+ this.handlers.doctype(token.name, token.publicId, token.systemId);
+
+};
+
+SimpleApiParser.prototype._reset = function (html) {
+ this.tokenizerProxy = new TokenizerProxy(html, this.options);
+ this.pendingText = null;
+ this.currentTokenLocation = null;
+};
+
+SimpleApiParser.prototype._emitPendingText = function () {
+ if (this.pendingText !== null) {
+ this.handlers.text(this.pendingText);
+ this.pendingText = null;
+ }
+};
+
+},{"../common/utils":44,"../tokenization/tokenizer":53,"./tokenizer_proxy":49}],49:[function(require,module,exports){
+'use strict';
+
+var Tokenizer = require('../tokenization/tokenizer'),
+ ForeignContent = require('../common/foreign_content'),
+ UNICODE = require('../common/unicode'),
+ HTML = require('../common/html');
+
+//Aliases
+var $ = HTML.TAG_NAMES,
+ NS = HTML.NAMESPACES;
+
+
+//Tokenizer proxy
+//NOTE: this proxy simulates adjustment of the Tokenizer which performed by standard parser during tree construction.
+var TokenizerProxy = module.exports = function (html, options) {
+ this.tokenizer = new Tokenizer(html, options);
+
+ this.namespaceStack = [];
+ this.namespaceStackTop = -1;
+ this.currentNamespace = null;
+ this.inForeignContent = false;
+};
+
+//API
+TokenizerProxy.prototype.getNextToken = function () {
+ var token = this.tokenizer.getNextToken();
+
+ if (token.type === Tokenizer.START_TAG_TOKEN)
+ this._handleStartTagToken(token);
+
+ else if (token.type === Tokenizer.END_TAG_TOKEN)
+ this._handleEndTagToken(token);
+
+ else if (token.type === Tokenizer.NULL_CHARACTER_TOKEN && this.inForeignContent) {
+ token.type = Tokenizer.CHARACTER_TOKEN;
+ token.chars = UNICODE.REPLACEMENT_CHARACTER;
+ }
+
+ return token;
+};
+
+//Namespace stack mutations
+TokenizerProxy.prototype._enterNamespace = function (namespace) {
+ this.namespaceStackTop++;
+ this.namespaceStack.push(namespace);
+
+ this.inForeignContent = namespace !== NS.HTML;
+ this.currentNamespace = namespace;
+ this.tokenizer.allowCDATA = this.inForeignContent;
+};
+
+TokenizerProxy.prototype._leaveCurrentNamespace = function () {
+ this.namespaceStackTop--;
+ this.namespaceStack.pop();
+
+ this.currentNamespace = this.namespaceStack[this.namespaceStackTop];
+ this.inForeignContent = this.currentNamespace !== NS.HTML;
+ this.tokenizer.allowCDATA = this.inForeignContent;
+};
+
+//Token handlers
+TokenizerProxy.prototype._ensureTokenizerMode = function (tn) {
+ if (tn === $.TEXTAREA || tn === $.TITLE)
+ this.tokenizer.state = Tokenizer.MODE.RCDATA;
+
+ else if (tn === $.PLAINTEXT)
+ this.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
+
+ else if (tn === $.SCRIPT)
+ this.tokenizer.state = Tokenizer.MODE.SCRIPT_DATA;
+
+ else if (tn === $.STYLE || tn === $.IFRAME || tn === $.XMP ||
+ tn === $.NOEMBED || tn === $.NOFRAMES || tn === $.NOSCRIPT) {
+ this.tokenizer.state = Tokenizer.MODE.RAWTEXT;
+ }
+};
+
+TokenizerProxy.prototype._handleStartTagToken = function (token) {
+ var tn = token.tagName;
+
+ if (tn === $.SVG)
+ this._enterNamespace(NS.SVG);
+
+ else if (tn === $.MATH)
+ this._enterNamespace(NS.MATHML);
+
+ else {
+ if (this.inForeignContent) {
+ if (ForeignContent.causesExit(token))
+ this._leaveCurrentNamespace();
+
+ else if (ForeignContent.isMathMLTextIntegrationPoint(tn, this.currentNamespace) ||
+ ForeignContent.isHtmlIntegrationPoint(tn, this.currentNamespace, token.attrs)) {
+ this._enterNamespace(NS.HTML);
+ }
+ }
+
+ else
+ this._ensureTokenizerMode(tn);
+ }
+};
+
+TokenizerProxy.prototype._handleEndTagToken = function (token) {
+ var tn = token.tagName;
+
+ if (!this.inForeignContent) {
+ var previousNs = this.namespaceStack[this.namespaceStackTop - 1];
+
+ //NOTE: check for exit from integration point
+ if (ForeignContent.isMathMLTextIntegrationPoint(tn, previousNs) ||
+ ForeignContent.isHtmlIntegrationPoint(tn, previousNs, token.attrs)) {
+ this._leaveCurrentNamespace();
+ }
+
+ else if (tn === $.SCRIPT)
+ this.tokenizer.state = Tokenizer.MODE.DATA;
+ }
+
+ else if ((tn === $.SVG && this.currentNamespace === NS.SVG) ||
+ (tn === $.MATH && this.currentNamespace === NS.MATHML))
+ this._leaveCurrentNamespace();
+};
+
+},{"../common/foreign_content":41,"../common/html":42,"../common/unicode":43,"../tokenization/tokenizer":53}],50:[function(require,module,exports){
+'use strict';
+
+exports.assign = function (tokenizer) {
+ //NOTE: obtain Tokenizer proto this way to avoid module circular references
+ var tokenizerProto = Object.getPrototypeOf(tokenizer);
+
+ tokenizer.tokenStartLoc = -1;
+
+ //NOTE: add location info builder method
+ tokenizer._attachLocationInfo = function (token) {
+ token.location = {
+ start: this.tokenStartLoc,
+ end: -1
+ };
+ };
+
+ //NOTE: patch token creation methods and attach location objects
+ tokenizer._createStartTagToken = function (tagNameFirstCh) {
+ tokenizerProto._createStartTagToken.call(this, tagNameFirstCh);
+ this._attachLocationInfo(this.currentToken);
+ };
+
+ tokenizer._createEndTagToken = function (tagNameFirstCh) {
+ tokenizerProto._createEndTagToken.call(this, tagNameFirstCh);
+ this._attachLocationInfo(this.currentToken);
+ };
+
+ tokenizer._createCommentToken = function () {
+ tokenizerProto._createCommentToken.call(this);
+ this._attachLocationInfo(this.currentToken);
+ };
+
+ tokenizer._createDoctypeToken = function (doctypeNameFirstCh) {
+ tokenizerProto._createDoctypeToken.call(this, doctypeNameFirstCh);
+ this._attachLocationInfo(this.currentToken);
+ };
+
+ tokenizer._createCharacterToken = function (type, ch) {
+ tokenizerProto._createCharacterToken.call(this, type, ch);
+ this._attachLocationInfo(this.currentCharacterToken);
+ };
+
+ //NOTE: patch token emission methods to determine end location
+ tokenizer._emitCurrentToken = function () {
+ //NOTE: if we have pending character token make it's end location equal to the
+ //current token's start location.
+ if (this.currentCharacterToken)
+ this.currentCharacterToken.location.end = this.currentToken.location.start;
+
+ this.currentToken.location.end = this.preprocessor.pos + 1;
+ tokenizerProto._emitCurrentToken.call(this);
+ };
+
+ tokenizer._emitCurrentCharacterToken = function () {
+ //NOTE: if we have character token and it's location wasn't set in the _emitCurrentToken(),
+ //then set it's location at the current preprocessor position
+ if (this.currentCharacterToken && this.currentCharacterToken.location.end === -1) {
+ //NOTE: we don't need to increment preprocessor position, since character token
+ //emission is always forced by the start of the next character token here.
+ //So, we already have advanced position.
+ this.currentCharacterToken.location.end = this.preprocessor.pos;
+ }
+
+ tokenizerProto._emitCurrentCharacterToken.call(this);
+ };
+
+ //NOTE: patch initial states for each mode to obtain token start position
+ Object.keys(tokenizerProto.MODE)
+
+ .map(function (modeName) {
+ return tokenizerProto.MODE[modeName];
+ })
+
+ .forEach(function (state) {
+ tokenizer[state] = function (cp) {
+ this.tokenStartLoc = this.preprocessor.pos;
+ tokenizerProto[state].call(this, cp);
+ };
+ });
+};
+
+},{}],51:[function(require,module,exports){
+'use strict';
+
+//NOTE: this file contains auto generated trie structure that is used for named entity references consumption
+//(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#tokenizing-character-references and
+//http://www.whatwg.org/specs/web-apps/current-work/multipage/named-character-references.html#named-character-references)
+module.exports = {
+ 0x41: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [193]}}, c: [193]}}}}}}}}}, 0x62: {l: {0x72: {l: {0x65: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [258]}}}}}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [194]}}, c: [194]}}}}}, 0x79: {l: {0x3B: {c: [1040]}}}}}, 0x45: {l: {0x6C: {l: {0x69: {l: {0x67: {l: {0x3B: {c: [198]}}, c: [198]}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120068]}}}}}, 0x67: {l: {0x72: {l: {0x61: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [192]}}, c: [192]}}}}}}}}}, 0x6C: {l: {0x70: {l: {0x68: {l: {0x61: {l: {0x3B: {c: [913]}}}}}}}}}, 0x6D: {l: {0x61: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [256]}}}}}}}}}, 0x4D: {l: {0x50: {l: {0x3B: {c: [38]}}, c: [38]}}}, 0x6E: {l: {0x64: {l: {0x3B: {c: [10835]}}}}}, 0x6F: {l: {0x67: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [260]}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120120]}}}}}}}, 0x70: {l: {0x70: {l: {0x6C: {l: {0x79: {l: {0x46: {l: {0x75: {l: {0x6E: {l: {0x63: {l: {0x74: {l: {0x69: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [8289]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x6E: {l: {0x67: {l: {0x3B: {c: [197]}}, c: [197]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119964]}}}}}, 0x73: {l: {0x69: {l: {0x67: {l: {0x6E: {l: {0x3B: {c: [8788]}}}}}}}}}}}, 0x74: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [195]}}, c: [195]}}}}}}}}}, 0x75: {l: {0x6D: {l: {0x6C: {l: {0x3B: {c: [196]}}, c: [196]}}}}}}},
+ 0x61: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [225]}}, c: [225]}}}}}}}}}, 0x62: {l: {0x72: {l: {0x65: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [259]}}}}}}}}}}}, 0x63: {l: {0x3B: {c: [8766]}, 0x64: {l: {0x3B: {c: [8767]}}}, 0x45: {l: {0x3B: {c: [8766, 819]}}}, 0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [226]}}, c: [226]}}}}}, 0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [180]}}, c: [180]}}}}}, 0x79: {l: {0x3B: {c: [1072]}}}}}, 0x65: {l: {0x6C: {l: {0x69: {l: {0x67: {l: {0x3B: {c: [230]}}, c: [230]}}}}}}}, 0x66: {l: {0x3B: {c: [8289]}, 0x72: {l: {0x3B: {c: [120094]}}}}}, 0x67: {l: {0x72: {l: {0x61: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [224]}}, c: [224]}}}}}}}}}, 0x6C: {l: {0x65: {l: {0x66: {l: {0x73: {l: {0x79: {l: {0x6D: {l: {0x3B: {c: [8501]}}}}}}}}}, 0x70: {l: {0x68: {l: {0x3B: {c: [8501]}}}}}}}, 0x70: {l: {0x68: {l: {0x61: {l: {0x3B: {c: [945]}}}}}}}}}, 0x6D: {l: {0x61: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [257]}}}}}, 0x6C: {l: {0x67: {l: {0x3B: {c: [10815]}}}}}}}, 0x70: {l: {0x3B: {c: [38]}}, c: [38]}}}, 0x6E: {l: {0x64: {l: {0x61: {l: {0x6E: {l: {0x64: {l: {0x3B: {c: [10837]}}}}}}}, 0x3B: {c: [8743]}, 0x64: {l: {0x3B: {c: [10844]}}}, 0x73: {l: {0x6C: {l: {0x6F: {l: {0x70: {l: {0x65: {l: {0x3B: {c: [10840]}}}}}}}}}}}, 0x76: {l: {0x3B: {c: [10842]}}}}}, 0x67: {l: {0x3B: {c: [8736]}, 0x65: {l: {0x3B: {c: [10660]}}}, 0x6C: {l: {0x65: {l: {0x3B: {c: [8736]}}}}}, 0x6D: {l: {0x73: {l: {0x64: {l: {0x61: {l: {0x61: {l: {0x3B: {c: [10664]}}}, 0x62: {l: {0x3B: {c: [10665]}}}, 0x63: {l: {0x3B: {c: [10666]}}}, 0x64: {l: {0x3B: {c: [10667]}}}, 0x65: {l: {0x3B: {c: [10668]}}}, 0x66: {l: {0x3B: {c: [10669]}}}, 0x67: {l: {0x3B: {c: [10670]}}}, 0x68: {l: {0x3B: {c: [10671]}}}}}, 0x3B: {c: [8737]}}}}}}}, 0x72: {l: {0x74: {l: {0x3B: {c: [8735]}, 0x76: {l: {0x62: {l: {0x3B: {c: [8894]}, 0x64: {l: {0x3B: {c: [10653]}}}}}}}}}}}, 0x73: {l: {0x70: {l: {0x68: {l: {0x3B: {c: [8738]}}}}}, 0x74: {l: {0x3B: {c: [197]}}}}}, 0x7A: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [9084]}}}}}}}}}}}}}, 0x6F: {l: {0x67: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [261]}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120146]}}}}}}}, 0x70: {l: {0x61: {l: {0x63: {l: {0x69: {l: {0x72: {l: {0x3B: {c: [10863]}}}}}}}}}, 0x3B: {c: [8776]}, 0x45: {l: {0x3B: {c: [10864]}}}, 0x65: {l: {0x3B: {c: [8778]}}}, 0x69: {l: {0x64: {l: {0x3B: {c: [8779]}}}}}, 0x6F: {l: {0x73: {l: {0x3B: {c: [39]}}}}}, 0x70: {l: {0x72: {l: {0x6F: {l: {0x78: {l: {0x3B: {c: [8776]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8778]}}}}}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x6E: {l: {0x67: {l: {0x3B: {c: [229]}}, c: [229]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119990]}}}}}, 0x74: {l: {0x3B: {c: [42]}}}, 0x79: {l: {0x6D: {l: {0x70: {l: {0x3B: {c: [8776]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8781]}}}}}}}}}}}}}, 0x74: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [227]}}, c: [227]}}}}}}}}}, 0x75: {l: {0x6D: {l: {0x6C: {l: {0x3B: {c: [228]}}, c: [228]}}}}}, 0x77: {l: {0x63: {l: {0x6F: {l: {0x6E: {l: {0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [8755]}}}}}}}}}}}}}, 0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [10769]}}}}}}}}}}},
+ 0x62: {l: {0x61: {l: {0x63: {l: {0x6B: {l: {0x63: {l: {0x6F: {l: {0x6E: {l: {0x67: {l: {0x3B: {c: [8780]}}}}}}}}}, 0x65: {l: {0x70: {l: {0x73: {l: {0x69: {l: {0x6C: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [1014]}}}}}}}}}}}}}}}, 0x70: {l: {0x72: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x3B: {c: [8245]}}}}}}}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8765]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8909]}}}}}}}}}}}}}}}, 0x72: {l: {0x76: {l: {0x65: {l: {0x65: {l: {0x3B: {c: [8893]}}}}}}}, 0x77: {l: {0x65: {l: {0x64: {l: {0x3B: {c: [8965]}, 0x67: {l: {0x65: {l: {0x3B: {c: [8965]}}}}}}}}}}}}}}}, 0x62: {l: {0x72: {l: {0x6B: {l: {0x3B: {c: [9141]}, 0x74: {l: {0x62: {l: {0x72: {l: {0x6B: {l: {0x3B: {c: [9142]}}}}}}}}}}}}}}}, 0x63: {l: {0x6F: {l: {0x6E: {l: {0x67: {l: {0x3B: {c: [8780]}}}}}}}, 0x79: {l: {0x3B: {c: [1073]}}}}}, 0x64: {l: {0x71: {l: {0x75: {l: {0x6F: {l: {0x3B: {c: [8222]}}}}}}}}}, 0x65: {l: {0x63: {l: {0x61: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8757]}, 0x65: {l: {0x3B: {c: [8757]}}}}}}}}}}}, 0x6D: {l: {0x70: {l: {0x74: {l: {0x79: {l: {0x76: {l: {0x3B: {c: [10672]}}}}}}}}}}}, 0x70: {l: {0x73: {l: {0x69: {l: {0x3B: {c: [1014]}}}}}}}, 0x72: {l: {0x6E: {l: {0x6F: {l: {0x75: {l: {0x3B: {c: [8492]}}}}}}}}}, 0x74: {l: {0x61: {l: {0x3B: {c: [946]}}}, 0x68: {l: {0x3B: {c: [8502]}}}, 0x77: {l: {0x65: {l: {0x65: {l: {0x6E: {l: {0x3B: {c: [8812]}}}}}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120095]}}}}}, 0x69: {l: {0x67: {l: {0x63: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [8898]}}}}}, 0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [9711]}}}}}}}, 0x75: {l: {0x70: {l: {0x3B: {c: [8899]}}}}}}}, 0x6F: {l: {0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10752]}}}}}}}, 0x70: {l: {0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [10753]}}}}}}}}}, 0x74: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [10754]}}}}}}}}}}}}}, 0x73: {l: {0x71: {l: {0x63: {l: {0x75: {l: {0x70: {l: {0x3B: {c: [10758]}}}}}}}}}, 0x74: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [9733]}}}}}}}}}, 0x74: {l: {0x72: {l: {0x69: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x64: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x3B: {c: [9661]}}}}}}}}}, 0x75: {l: {0x70: {l: {0x3B: {c: [9651]}}}}}}}}}}}}}}}}}}}}}, 0x75: {l: {0x70: {l: {0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [10756]}}}}}}}}}}}, 0x76: {l: {0x65: {l: {0x65: {l: {0x3B: {c: [8897]}}}}}}}, 0x77: {l: {0x65: {l: {0x64: {l: {0x67: {l: {0x65: {l: {0x3B: {c: [8896]}}}}}}}}}}}}}}}, 0x6B: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10509]}}}}}}}}}}}, 0x6C: {l: {0x61: {l: {0x63: {l: {0x6B: {l: {0x6C: {l: {0x6F: {l: {0x7A: {l: {0x65: {l: {0x6E: {l: {0x67: {l: {0x65: {l: {0x3B: {c: [10731]}}}}}}}}}}}}}}}, 0x73: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x72: {l: {0x65: {l: {0x3B: {c: [9642]}}}}}}}}}}}}}, 0x74: {l: {0x72: {l: {0x69: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x3B: {c: [9652]}, 0x64: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x3B: {c: [9662]}}}}}}}}}, 0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x3B: {c: [9666]}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x3B: {c: [9656]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x6E: {l: {0x6B: {l: {0x3B: {c: [9251]}}}}}}}, 0x6B: {l: {0x31: {l: {0x32: {l: {0x3B: {c: [9618]}}}, 0x34: {l: {0x3B: {c: [9617]}}}}}, 0x33: {l: {0x34: {l: {0x3B: {c: [9619]}}}}}}}, 0x6F: {l: {0x63: {l: {0x6B: {l: {0x3B: {c: [9608]}}}}}}}}}, 0x6E: {l: {0x65: {l: {0x3B: {c: [61, 8421]}, 0x71: {l: {0x75: {l: {0x69: {l: {0x76: {l: {0x3B: {c: [8801, 8421]}}}}}}}}}}}, 0x6F: {l: {0x74: {l: {0x3B: {c: [8976]}}}}}}}, 0x4E: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10989]}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120147]}}}}}, 0x74: {l: {0x3B: {c: [8869]}, 0x74: {l: {0x6F: {l: {0x6D: {l: {0x3B: {c: [8869]}}}}}}}}}, 0x77: {l: {0x74: {l: {0x69: {l: {0x65: {l: {0x3B: {c: [8904]}}}}}}}}}, 0x78: {l: {0x62: {l: {0x6F: {l: {0x78: {l: {0x3B: {c: [10697]}}}}}}}, 0x64: {l: {0x6C: {l: {0x3B: {c: [9488]}}}, 0x4C: {l: {0x3B: {c: [9557]}}}, 0x72: {l: {0x3B: {c: [9484]}}}, 0x52: {l: {0x3B: {c: [9554]}}}}}, 0x44: {l: {0x6C: {l: {0x3B: {c: [9558]}}}, 0x4C: {l: {0x3B: {c: [9559]}}}, 0x72: {l: {0x3B: {c: [9555]}}}, 0x52: {l: {0x3B: {c: [9556]}}}}}, 0x68: {l: {0x3B: {c: [9472]}, 0x64: {l: {0x3B: {c: [9516]}}}, 0x44: {l: {0x3B: {c: [9573]}}}, 0x75: {l: {0x3B: {c: [9524]}}}, 0x55: {l: {0x3B: {c: [9576]}}}}}, 0x48: {l: {0x3B: {c: [9552]}, 0x64: {l: {0x3B: {c: [9572]}}}, 0x44: {l: {0x3B: {c: [9574]}}}, 0x75: {l: {0x3B: {c: [9575]}}}, 0x55: {l: {0x3B: {c: [9577]}}}}}, 0x6D: {l: {0x69: {l: {0x6E: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8863]}}}}}}}}}}}, 0x70: {l: {0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8862]}}}}}}}}}, 0x74: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [8864]}}}}}}}}}}}, 0x75: {l: {0x6C: {l: {0x3B: {c: [9496]}}}, 0x4C: {l: {0x3B: {c: [9563]}}}, 0x72: {l: {0x3B: {c: [9492]}}}, 0x52: {l: {0x3B: {c: [9560]}}}}}, 0x55: {l: {0x6C: {l: {0x3B: {c: [9564]}}}, 0x4C: {l: {0x3B: {c: [9565]}}}, 0x72: {l: {0x3B: {c: [9561]}}}, 0x52: {l: {0x3B: {c: [9562]}}}}}, 0x76: {l: {0x3B: {c: [9474]}, 0x68: {l: {0x3B: {c: [9532]}}}, 0x48: {l: {0x3B: {c: [9578]}}}, 0x6C: {l: {0x3B: {c: [9508]}}}, 0x4C: {l: {0x3B: {c: [9569]}}}, 0x72: {l: {0x3B: {c: [9500]}}}, 0x52: {l: {0x3B: {c: [9566]}}}}}, 0x56: {l: {0x3B: {c: [9553]}, 0x68: {l: {0x3B: {c: [9579]}}}, 0x48: {l: {0x3B: {c: [9580]}}}, 0x6C: {l: {0x3B: {c: [9570]}}}, 0x4C: {l: {0x3B: {c: [9571]}}}, 0x72: {l: {0x3B: {c: [9567]}}}, 0x52: {l: {0x3B: {c: [9568]}}}}}}}}}, 0x70: {l: {0x72: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x3B: {c: [8245]}}}}}}}}}}}, 0x72: {l: {0x65: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [728]}}}}}}}, 0x76: {l: {0x62: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [166]}}, c: [166]}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119991]}}}}}, 0x65: {l: {0x6D: {l: {0x69: {l: {0x3B: {c: [8271]}}}}}}}, 0x69: {l: {0x6D: {l: {0x3B: {c: [8765]}, 0x65: {l: {0x3B: {c: [8909]}}}}}}}, 0x6F: {l: {0x6C: {l: {0x62: {l: {0x3B: {c: [10693]}}}, 0x3B: {c: [92]}, 0x68: {l: {0x73: {l: {0x75: {l: {0x62: {l: {0x3B: {c: [10184]}}}}}}}}}}}}}}}, 0x75: {l: {0x6C: {l: {0x6C: {l: {0x3B: {c: [8226]}, 0x65: {l: {0x74: {l: {0x3B: {c: [8226]}}}}}}}}}, 0x6D: {l: {0x70: {l: {0x3B: {c: [8782]}, 0x45: {l: {0x3B: {c: [10926]}}}, 0x65: {l: {0x3B: {c: [8783]}, 0x71: {l: {0x3B: {c: [8783]}}}}}}}}}}}}},
+ 0x42: {l: {0x61: {l: {0x63: {l: {0x6B: {l: {0x73: {l: {0x6C: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8726]}}}}}}}}}}}}}}}, 0x72: {l: {0x76: {l: {0x3B: {c: [10983]}}}, 0x77: {l: {0x65: {l: {0x64: {l: {0x3B: {c: [8966]}}}}}}}}}}}, 0x63: {l: {0x79: {l: {0x3B: {c: [1041]}}}}}, 0x65: {l: {0x63: {l: {0x61: {l: {0x75: {l: {0x73: {l: {0x65: {l: {0x3B: {c: [8757]}}}}}}}}}}}, 0x72: {l: {0x6E: {l: {0x6F: {l: {0x75: {l: {0x6C: {l: {0x6C: {l: {0x69: {l: {0x73: {l: {0x3B: {c: [8492]}}}}}}}}}}}}}}}}}, 0x74: {l: {0x61: {l: {0x3B: {c: [914]}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120069]}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120121]}}}}}}}, 0x72: {l: {0x65: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [728]}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [8492]}}}}}}}, 0x75: {l: {0x6D: {l: {0x70: {l: {0x65: {l: {0x71: {l: {0x3B: {c: [8782]}}}}}}}}}}}}},
+ 0x43: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [262]}}}}}}}}}, 0x70: {l: {0x3B: {c: [8914]}, 0x69: {l: {0x74: {l: {0x61: {l: {0x6C: {l: {0x44: {l: {0x69: {l: {0x66: {l: {0x66: {l: {0x65: {l: {0x72: {l: {0x65: {l: {0x6E: {l: {0x74: {l: {0x69: {l: {0x61: {l: {0x6C: {l: {0x44: {l: {0x3B: {c: [8517]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x79: {l: {0x6C: {l: {0x65: {l: {0x79: {l: {0x73: {l: {0x3B: {c: [8493]}}}}}}}}}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [268]}}}}}}}}}, 0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [199]}}, c: [199]}}}}}}}, 0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [264]}}}}}}}, 0x6F: {l: {0x6E: {l: {0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [8752]}}}}}}}}}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [266]}}}}}}}, 0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x6C: {l: {0x61: {l: {0x3B: {c: [184]}}}}}}}}}}}, 0x6E: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x44: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [183]}}}}}}}}}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [8493]}}}}}, 0x48: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1063]}}}}}}}, 0x68: {l: {0x69: {l: {0x3B: {c: [935]}}}}}, 0x69: {l: {0x72: {l: {0x63: {l: {0x6C: {l: {0x65: {l: {0x44: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8857]}}}}}}}, 0x4D: {l: {0x69: {l: {0x6E: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8854]}}}}}}}}}}}, 0x50: {l: {0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8853]}}}}}}}}}, 0x54: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [8855]}}}}}}}}}}}}}}}}}}}}}, 0x6C: {l: {0x6F: {l: {0x63: {l: {0x6B: {l: {0x77: {l: {0x69: {l: {0x73: {l: {0x65: {l: {0x43: {l: {0x6F: {l: {0x6E: {l: {0x74: {l: {0x6F: {l: {0x75: {l: {0x72: {l: {0x49: {l: {0x6E: {l: {0x74: {l: {0x65: {l: {0x67: {l: {0x72: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8754]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x65: {l: {0x43: {l: {0x75: {l: {0x72: {l: {0x6C: {l: {0x79: {l: {0x44: {l: {0x6F: {l: {0x75: {l: {0x62: {l: {0x6C: {l: {0x65: {l: {0x51: {l: {0x75: {l: {0x6F: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [8221]}}}}}}}}}}}}}}}}}}}}}}}, 0x51: {l: {0x75: {l: {0x6F: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [8217]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x6F: {l: {0x6C: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [8759]}, 0x65: {l: {0x3B: {c: [10868]}}}}}}}}}, 0x6E: {l: {0x67: {l: {0x72: {l: {0x75: {l: {0x65: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [8801]}}}}}}}}}}}}}, 0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [8751]}}}}}}}, 0x74: {l: {0x6F: {l: {0x75: {l: {0x72: {l: {0x49: {l: {0x6E: {l: {0x74: {l: {0x65: {l: {0x67: {l: {0x72: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8750]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [8450]}}}, 0x72: {l: {0x6F: {l: {0x64: {l: {0x75: {l: {0x63: {l: {0x74: {l: {0x3B: {c: [8720]}}}}}}}}}}}}}}}, 0x75: {l: {0x6E: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x43: {l: {0x6C: {l: {0x6F: {l: {0x63: {l: {0x6B: {l: {0x77: {l: {0x69: {l: {0x73: {l: {0x65: {l: {0x43: {l: {0x6F: {l: {0x6E: {l: {0x74: {l: {0x6F: {l: {0x75: {l: {0x72: {l: {0x49: {l: {0x6E: {l: {0x74: {l: {0x65: {l: {0x67: {l: {0x72: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8755]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x4F: {l: {0x50: {l: {0x59: {l: {0x3B: {c: [169]}}, c: [169]}}}}}, 0x72: {l: {0x6F: {l: {0x73: {l: {0x73: {l: {0x3B: {c: [10799]}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119966]}}}}}}}, 0x75: {l: {0x70: {l: {0x43: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [8781]}}}}}}}, 0x3B: {c: [8915]}}}}}}},
+ 0x63: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [263]}}}}}}}}}, 0x70: {l: {0x61: {l: {0x6E: {l: {0x64: {l: {0x3B: {c: [10820]}}}}}}}, 0x62: {l: {0x72: {l: {0x63: {l: {0x75: {l: {0x70: {l: {0x3B: {c: [10825]}}}}}}}}}}}, 0x63: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [10827]}}}}}, 0x75: {l: {0x70: {l: {0x3B: {c: [10823]}}}}}}}, 0x3B: {c: [8745]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10816]}}}}}}}, 0x73: {l: {0x3B: {c: [8745, 65024]}}}}}, 0x72: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8257]}}}}}, 0x6F: {l: {0x6E: {l: {0x3B: {c: [711]}}}}}}}}}, 0x63: {l: {0x61: {l: {0x70: {l: {0x73: {l: {0x3B: {c: [10829]}}}}}, 0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [269]}}}}}}}}}, 0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [231]}}, c: [231]}}}}}}}, 0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [265]}}}}}}}, 0x75: {l: {0x70: {l: {0x73: {l: {0x3B: {c: [10828]}, 0x73: {l: {0x6D: {l: {0x3B: {c: [10832]}}}}}}}}}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [267]}}}}}}}, 0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [184]}}, c: [184]}}}}}, 0x6D: {l: {0x70: {l: {0x74: {l: {0x79: {l: {0x76: {l: {0x3B: {c: [10674]}}}}}}}}}}}, 0x6E: {l: {0x74: {l: {0x3B: {c: [162]}, 0x65: {l: {0x72: {l: {0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [183]}}}}}}}}}}}}, c: [162]}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120096]}}}}}, 0x68: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1095]}}}}}, 0x65: {l: {0x63: {l: {0x6B: {l: {0x3B: {c: [10003]}, 0x6D: {l: {0x61: {l: {0x72: {l: {0x6B: {l: {0x3B: {c: [10003]}}}}}}}}}}}}}}}, 0x69: {l: {0x3B: {c: [967]}}}}}, 0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [710]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8791]}}}}}, 0x6C: {l: {0x65: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x3B: {c: [8634]}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x3B: {c: [8635]}}}}}}}}}}}}}}}}}}}}}, 0x64: {l: {0x61: {l: {0x73: {l: {0x74: {l: {0x3B: {c: [8859]}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [8858]}}}}}}}}}, 0x64: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8861]}}}}}}}}}, 0x52: {l: {0x3B: {c: [174]}}}, 0x53: {l: {0x3B: {c: [9416]}}}}}}}}}}}, 0x3B: {c: [9675]}, 0x45: {l: {0x3B: {c: [10691]}}}, 0x65: {l: {0x3B: {c: [8791]}}}, 0x66: {l: {0x6E: {l: {0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [10768]}}}}}}}}}}}, 0x6D: {l: {0x69: {l: {0x64: {l: {0x3B: {c: [10991]}}}}}}}, 0x73: {l: {0x63: {l: {0x69: {l: {0x72: {l: {0x3B: {c: [10690]}}}}}}}}}}}}}, 0x6C: {l: {0x75: {l: {0x62: {l: {0x73: {l: {0x3B: {c: [9827]}, 0x75: {l: {0x69: {l: {0x74: {l: {0x3B: {c: [9827]}}}}}}}}}}}}}}}, 0x6F: {l: {0x6C: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [58]}, 0x65: {l: {0x3B: {c: [8788]}, 0x71: {l: {0x3B: {c: [8788]}}}}}}}}}}}, 0x6D: {l: {0x6D: {l: {0x61: {l: {0x3B: {c: [44]}, 0x74: {l: {0x3B: {c: [64]}}}}}}}, 0x70: {l: {0x3B: {c: [8705]}, 0x66: {l: {0x6E: {l: {0x3B: {c: [8728]}}}}}, 0x6C: {l: {0x65: {l: {0x6D: {l: {0x65: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [8705]}}}}}}}}}, 0x78: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [8450]}}}}}}}}}}}}}}}, 0x6E: {l: {0x67: {l: {0x3B: {c: [8773]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10861]}}}}}}}}}, 0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [8750]}}}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120148]}}}, 0x72: {l: {0x6F: {l: {0x64: {l: {0x3B: {c: [8720]}}}}}}}, 0x79: {l: {0x3B: {c: [169]}, 0x73: {l: {0x72: {l: {0x3B: {c: [8471]}}}}}}, c: [169]}}}}}, 0x72: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8629]}}}}}}}, 0x6F: {l: {0x73: {l: {0x73: {l: {0x3B: {c: [10007]}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119992]}}}}}, 0x75: {l: {0x62: {l: {0x3B: {c: [10959]}, 0x65: {l: {0x3B: {c: [10961]}}}}}, 0x70: {l: {0x3B: {c: [10960]}, 0x65: {l: {0x3B: {c: [10962]}}}}}}}}}, 0x74: {l: {0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8943]}}}}}}}}}, 0x75: {l: {0x64: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6C: {l: {0x3B: {c: [10552]}}}, 0x72: {l: {0x3B: {c: [10549]}}}}}}}}}}}, 0x65: {l: {0x70: {l: {0x72: {l: {0x3B: {c: [8926]}}}}}, 0x73: {l: {0x63: {l: {0x3B: {c: [8927]}}}}}}}, 0x6C: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8630]}, 0x70: {l: {0x3B: {c: [10557]}}}}}}}}}}}, 0x70: {l: {0x62: {l: {0x72: {l: {0x63: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [10824]}}}}}}}}}}}, 0x63: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [10822]}}}}}, 0x75: {l: {0x70: {l: {0x3B: {c: [10826]}}}}}}}, 0x3B: {c: [8746]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8845]}}}}}}}, 0x6F: {l: {0x72: {l: {0x3B: {c: [10821]}}}}}, 0x73: {l: {0x3B: {c: [8746, 65024]}}}}}, 0x72: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8631]}, 0x6D: {l: {0x3B: {c: [10556]}}}}}}}}}, 0x6C: {l: {0x79: {l: {0x65: {l: {0x71: {l: {0x70: {l: {0x72: {l: {0x65: {l: {0x63: {l: {0x3B: {c: [8926]}}}}}}}}}, 0x73: {l: {0x75: {l: {0x63: {l: {0x63: {l: {0x3B: {c: [8927]}}}}}}}}}}}}}, 0x76: {l: {0x65: {l: {0x65: {l: {0x3B: {c: [8910]}}}}}}}, 0x77: {l: {0x65: {l: {0x64: {l: {0x67: {l: {0x65: {l: {0x3B: {c: [8911]}}}}}}}}}}}}}}}, 0x72: {l: {0x65: {l: {0x6E: {l: {0x3B: {c: [164]}}, c: [164]}}}}}, 0x76: {l: {0x65: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x3B: {c: [8630]}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x3B: {c: [8631]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x76: {l: {0x65: {l: {0x65: {l: {0x3B: {c: [8910]}}}}}}}, 0x77: {l: {0x65: {l: {0x64: {l: {0x3B: {c: [8911]}}}}}}}}}, 0x77: {l: {0x63: {l: {0x6F: {l: {0x6E: {l: {0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [8754]}}}}}}}}}}}}}, 0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [8753]}}}}}}}}}, 0x79: {l: {0x6C: {l: {0x63: {l: {0x74: {l: {0x79: {l: {0x3B: {c: [9005]}}}}}}}}}}}}},
+ 0x64: {l: {0x61: {l: {0x67: {l: {0x67: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [8224]}}}}}}}}}, 0x6C: {l: {0x65: {l: {0x74: {l: {0x68: {l: {0x3B: {c: [8504]}}}}}}}}}, 0x72: {l: {0x72: {l: {0x3B: {c: [8595]}}}}}, 0x73: {l: {0x68: {l: {0x3B: {c: [8208]}, 0x76: {l: {0x3B: {c: [8867]}}}}}}}}}, 0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8659]}}}}}}}, 0x62: {l: {0x6B: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10511]}}}}}}}}}}}, 0x6C: {l: {0x61: {l: {0x63: {l: {0x3B: {c: [733]}}}}}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [271]}}}}}}}}}, 0x79: {l: {0x3B: {c: [1076]}}}}}, 0x64: {l: {0x61: {l: {0x67: {l: {0x67: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [8225]}}}}}}}}}, 0x72: {l: {0x72: {l: {0x3B: {c: [8650]}}}}}}}, 0x3B: {c: [8518]}, 0x6F: {l: {0x74: {l: {0x73: {l: {0x65: {l: {0x71: {l: {0x3B: {c: [10871]}}}}}}}}}}}}}, 0x65: {l: {0x67: {l: {0x3B: {c: [176]}}, c: [176]}, 0x6C: {l: {0x74: {l: {0x61: {l: {0x3B: {c: [948]}}}}}}}, 0x6D: {l: {0x70: {l: {0x74: {l: {0x79: {l: {0x76: {l: {0x3B: {c: [10673]}}}}}}}}}}}}}, 0x66: {l: {0x69: {l: {0x73: {l: {0x68: {l: {0x74: {l: {0x3B: {c: [10623]}}}}}}}}}, 0x72: {l: {0x3B: {c: [120097]}}}}}, 0x48: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10597]}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x6C: {l: {0x3B: {c: [8643]}}}, 0x72: {l: {0x3B: {c: [8642]}}}}}}}}}, 0x69: {l: {0x61: {l: {0x6D: {l: {0x3B: {c: [8900]}, 0x6F: {l: {0x6E: {l: {0x64: {l: {0x3B: {c: [8900]}, 0x73: {l: {0x75: {l: {0x69: {l: {0x74: {l: {0x3B: {c: [9830]}}}}}}}}}}}}}}}, 0x73: {l: {0x3B: {c: [9830]}}}}}}}, 0x65: {l: {0x3B: {c: [168]}}}, 0x67: {l: {0x61: {l: {0x6D: {l: {0x6D: {l: {0x61: {l: {0x3B: {c: [989]}}}}}}}}}}}, 0x73: {l: {0x69: {l: {0x6E: {l: {0x3B: {c: [8946]}}}}}}}, 0x76: {l: {0x3B: {c: [247]}, 0x69: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [247]}, 0x6F: {l: {0x6E: {l: {0x74: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [8903]}}}}}}}}}}}}}}}}, c: [247]}}}}}, 0x6F: {l: {0x6E: {l: {0x78: {l: {0x3B: {c: [8903]}}}}}}}}}}}, 0x6A: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1106]}}}}}}}, 0x6C: {l: {0x63: {l: {0x6F: {l: {0x72: {l: {0x6E: {l: {0x3B: {c: [8990]}}}}}}}, 0x72: {l: {0x6F: {l: {0x70: {l: {0x3B: {c: [8973]}}}}}}}}}}}, 0x6F: {l: {0x6C: {l: {0x6C: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [36]}}}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120149]}}}}}, 0x74: {l: {0x3B: {c: [729]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8784]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8785]}}}}}}}}}}}, 0x6D: {l: {0x69: {l: {0x6E: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8760]}}}}}}}}}}}, 0x70: {l: {0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8724]}}}}}}}}}, 0x73: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x72: {l: {0x65: {l: {0x3B: {c: [8865]}}}}}}}}}}}}}}}, 0x75: {l: {0x62: {l: {0x6C: {l: {0x65: {l: {0x62: {l: {0x61: {l: {0x72: {l: {0x77: {l: {0x65: {l: {0x64: {l: {0x67: {l: {0x65: {l: {0x3B: {c: [8966]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x77: {l: {0x6E: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8595]}}}}}}}}}}}, 0x64: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x73: {l: {0x3B: {c: [8650]}}}}}}}}}}}}}}}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x70: {l: {0x6F: {l: {0x6F: {l: {0x6E: {l: {0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x3B: {c: [8643]}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x3B: {c: [8642]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x72: {l: {0x62: {l: {0x6B: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10512]}}}}}}}}}}}}}, 0x63: {l: {0x6F: {l: {0x72: {l: {0x6E: {l: {0x3B: {c: [8991]}}}}}}}, 0x72: {l: {0x6F: {l: {0x70: {l: {0x3B: {c: [8972]}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119993]}}}, 0x79: {l: {0x3B: {c: [1109]}}}}}, 0x6F: {l: {0x6C: {l: {0x3B: {c: [10742]}}}}}, 0x74: {l: {0x72: {l: {0x6F: {l: {0x6B: {l: {0x3B: {c: [273]}}}}}}}}}}}, 0x74: {l: {0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8945]}}}}}}}, 0x72: {l: {0x69: {l: {0x3B: {c: [9663]}, 0x66: {l: {0x3B: {c: [9662]}}}}}}}}}, 0x75: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8693]}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10607]}}}}}}}}}, 0x77: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x3B: {c: [10662]}}}}}}}}}}}}}, 0x7A: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1119]}}}}}, 0x69: {l: {0x67: {l: {0x72: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10239]}}}}}}}}}}}}}}}}},
+ 0x44: {l: {0x61: {l: {0x67: {l: {0x67: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [8225]}}}}}}}}}, 0x72: {l: {0x72: {l: {0x3B: {c: [8609]}}}}}, 0x73: {l: {0x68: {l: {0x76: {l: {0x3B: {c: [10980]}}}}}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [270]}}}}}}}}}, 0x79: {l: {0x3B: {c: [1044]}}}}}, 0x44: {l: {0x3B: {c: [8517]}, 0x6F: {l: {0x74: {l: {0x72: {l: {0x61: {l: {0x68: {l: {0x64: {l: {0x3B: {c: [10513]}}}}}}}}}}}}}}}, 0x65: {l: {0x6C: {l: {0x3B: {c: [8711]}, 0x74: {l: {0x61: {l: {0x3B: {c: [916]}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120071]}}}}}, 0x69: {l: {0x61: {l: {0x63: {l: {0x72: {l: {0x69: {l: {0x74: {l: {0x69: {l: {0x63: {l: {0x61: {l: {0x6C: {l: {0x41: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [180]}}}}}}}}}}}, 0x44: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [729]}}}, 0x75: {l: {0x62: {l: {0x6C: {l: {0x65: {l: {0x41: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [733]}}}}}}}}}}}}}}}}}}}}}}}, 0x47: {l: {0x72: {l: {0x61: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [96]}}}}}}}}}}}, 0x54: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [732]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x6D: {l: {0x6F: {l: {0x6E: {l: {0x64: {l: {0x3B: {c: [8900]}}}}}}}}}}}, 0x66: {l: {0x66: {l: {0x65: {l: {0x72: {l: {0x65: {l: {0x6E: {l: {0x74: {l: {0x69: {l: {0x61: {l: {0x6C: {l: {0x44: {l: {0x3B: {c: [8518]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x4A: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1026]}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120123]}}}}}, 0x74: {l: {0x3B: {c: [168]}, 0x44: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8412]}}}}}}}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8784]}}}}}}}}}}}}}, 0x75: {l: {0x62: {l: {0x6C: {l: {0x65: {l: {0x43: {l: {0x6F: {l: {0x6E: {l: {0x74: {l: {0x6F: {l: {0x75: {l: {0x72: {l: {0x49: {l: {0x6E: {l: {0x74: {l: {0x65: {l: {0x67: {l: {0x72: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8751]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x44: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [168]}}}, 0x77: {l: {0x6E: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8659]}}}}}}}}}}}}}}}}}}}, 0x4C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8656]}}}}}}}}}}}, 0x52: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8660]}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x65: {l: {0x65: {l: {0x3B: {c: [10980]}}}}}}}}}}}}}, 0x6F: {l: {0x6E: {l: {0x67: {l: {0x4C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10232]}}}}}}}}}}}, 0x52: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10234]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x52: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10233]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x52: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8658]}}}}}}}}}}}, 0x54: {l: {0x65: {l: {0x65: {l: {0x3B: {c: [8872]}}}}}}}}}}}}}}}}}, 0x55: {l: {0x70: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8657]}}}}}}}}}}}, 0x44: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8661]}}}}}}}}}}}}}}}}}}}}}}}, 0x56: {l: {0x65: {l: {0x72: {l: {0x74: {l: {0x69: {l: {0x63: {l: {0x61: {l: {0x6C: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8741]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x77: {l: {0x6E: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10515]}}}}}}}, 0x3B: {c: [8595]}, 0x55: {l: {0x70: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8693]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8659]}}}}}}}}}}}, 0x42: {l: {0x72: {l: {0x65: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [785]}}}}}}}}}}}, 0x4C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x52: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [10576]}}}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x65: {l: {0x65: {l: {0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [10590]}}}}}}}}}}}}}}}}}}}, 0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10582]}}}}}}}, 0x3B: {c: [8637]}}}}}}}}}}}}}}}}}}}}}, 0x52: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x54: {l: {0x65: {l: {0x65: {l: {0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [10591]}}}}}}}}}}}}}}}}}}}, 0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10583]}}}}}}}, 0x3B: {c: [8641]}}}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x65: {l: {0x65: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8615]}}}}}}}}}}}, 0x3B: {c: [8868]}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119967]}}}}}, 0x74: {l: {0x72: {l: {0x6F: {l: {0x6B: {l: {0x3B: {c: [272]}}}}}}}}}}}, 0x53: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1029]}}}}}}}, 0x5A: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1039]}}}}}}}}},
+ 0x45: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [201]}}, c: [201]}}}}}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [282]}}}}}}}}}, 0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [202]}}, c: [202]}}}}}, 0x79: {l: {0x3B: {c: [1069]}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [278]}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120072]}}}}}, 0x67: {l: {0x72: {l: {0x61: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [200]}}, c: [200]}}}}}}}}}, 0x6C: {l: {0x65: {l: {0x6D: {l: {0x65: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [8712]}}}}}}}}}}}}}, 0x6D: {l: {0x61: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [274]}}}}}}}, 0x70: {l: {0x74: {l: {0x79: {l: {0x53: {l: {0x6D: {l: {0x61: {l: {0x6C: {l: {0x6C: {l: {0x53: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x72: {l: {0x65: {l: {0x3B: {c: [9723]}}}}}}}}}}}}}}}}}}}}}}}, 0x56: {l: {0x65: {l: {0x72: {l: {0x79: {l: {0x53: {l: {0x6D: {l: {0x61: {l: {0x6C: {l: {0x6C: {l: {0x53: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x72: {l: {0x65: {l: {0x3B: {c: [9643]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x4E: {l: {0x47: {l: {0x3B: {c: [330]}}}}}, 0x6F: {l: {0x67: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [280]}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120124]}}}}}}}, 0x70: {l: {0x73: {l: {0x69: {l: {0x6C: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [917]}}}}}}}}}}}}}, 0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [10869]}, 0x54: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8770]}}}}}}}}}}}}}}}, 0x69: {l: {0x6C: {l: {0x69: {l: {0x62: {l: {0x72: {l: {0x69: {l: {0x75: {l: {0x6D: {l: {0x3B: {c: [8652]}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [8496]}}}}}, 0x69: {l: {0x6D: {l: {0x3B: {c: [10867]}}}}}}}, 0x74: {l: {0x61: {l: {0x3B: {c: [919]}}}}}, 0x54: {l: {0x48: {l: {0x3B: {c: [208]}}, c: [208]}}}, 0x75: {l: {0x6D: {l: {0x6C: {l: {0x3B: {c: [203]}}, c: [203]}}}}}, 0x78: {l: {0x69: {l: {0x73: {l: {0x74: {l: {0x73: {l: {0x3B: {c: [8707]}}}}}}}}}, 0x70: {l: {0x6F: {l: {0x6E: {l: {0x65: {l: {0x6E: {l: {0x74: {l: {0x69: {l: {0x61: {l: {0x6C: {l: {0x45: {l: {0x3B: {c: [8519]}}}}}}}}}}}}}}}}}}}}}}}}},
+ 0x65: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [233]}}, c: [233]}}}}}}}, 0x73: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [10862]}}}}}}}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [283]}}}}}}}}}, 0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [234]}}, c: [234]}, 0x3B: {c: [8790]}}}}}, 0x6F: {l: {0x6C: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [8789]}}}}}}}}}, 0x79: {l: {0x3B: {c: [1101]}}}}}, 0x44: {l: {0x44: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10871]}}}}}}}, 0x6F: {l: {0x74: {l: {0x3B: {c: [8785]}}}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [279]}}}}}}}, 0x65: {l: {0x3B: {c: [8519]}}}, 0x66: {l: {0x44: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8786]}}}}}}}, 0x72: {l: {0x3B: {c: [120098]}}}}}, 0x67: {l: {0x3B: {c: [10906]}, 0x72: {l: {0x61: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [232]}}, c: [232]}}}}}}}, 0x73: {l: {0x3B: {c: [10902]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10904]}}}}}}}}}}}, 0x6C: {l: {0x3B: {c: [10905]}, 0x69: {l: {0x6E: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x73: {l: {0x3B: {c: [9191]}}}}}}}}}}}}}, 0x6C: {l: {0x3B: {c: [8467]}}}, 0x73: {l: {0x3B: {c: [10901]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10903]}}}}}}}}}}}, 0x6D: {l: {0x61: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [275]}}}}}}}, 0x70: {l: {0x74: {l: {0x79: {l: {0x3B: {c: [8709]}, 0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8709]}}}}}}}, 0x76: {l: {0x3B: {c: [8709]}}}}}}}}}, 0x73: {l: {0x70: {l: {0x31: {l: {0x33: {l: {0x3B: {c: [8196]}}}, 0x34: {l: {0x3B: {c: [8197]}}}}}, 0x3B: {c: [8195]}}}}}}}, 0x6E: {l: {0x67: {l: {0x3B: {c: [331]}}}, 0x73: {l: {0x70: {l: {0x3B: {c: [8194]}}}}}}}, 0x6F: {l: {0x67: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [281]}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120150]}}}}}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8917]}, 0x73: {l: {0x6C: {l: {0x3B: {c: [10723]}}}}}}}}}, 0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [10865]}}}}}}}, 0x73: {l: {0x69: {l: {0x3B: {c: [949]}, 0x6C: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [949]}}}}}}}, 0x76: {l: {0x3B: {c: [1013]}}}}}}}}}, 0x71: {l: {0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [8790]}}}}}}}, 0x6F: {l: {0x6C: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [8789]}}}}}}}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8770]}}}}}, 0x6C: {l: {0x61: {l: {0x6E: {l: {0x74: {l: {0x67: {l: {0x74: {l: {0x72: {l: {0x3B: {c: [10902]}}}}}}}, 0x6C: {l: {0x65: {l: {0x73: {l: {0x73: {l: {0x3B: {c: [10901]}}}}}}}}}}}}}}}}}}}, 0x75: {l: {0x61: {l: {0x6C: {l: {0x73: {l: {0x3B: {c: [61]}}}}}}}, 0x65: {l: {0x73: {l: {0x74: {l: {0x3B: {c: [8799]}}}}}}}, 0x69: {l: {0x76: {l: {0x3B: {c: [8801]}, 0x44: {l: {0x44: {l: {0x3B: {c: [10872]}}}}}}}}}}}, 0x76: {l: {0x70: {l: {0x61: {l: {0x72: {l: {0x73: {l: {0x6C: {l: {0x3B: {c: [10725]}}}}}}}}}}}}}}}, 0x72: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10609]}}}}}}}, 0x44: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8787]}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [8495]}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8784]}}}}}}}, 0x69: {l: {0x6D: {l: {0x3B: {c: [8770]}}}}}}}, 0x74: {l: {0x61: {l: {0x3B: {c: [951]}}}, 0x68: {l: {0x3B: {c: [240]}}, c: [240]}}}, 0x75: {l: {0x6D: {l: {0x6C: {l: {0x3B: {c: [235]}}, c: [235]}}}, 0x72: {l: {0x6F: {l: {0x3B: {c: [8364]}}}}}}}, 0x78: {l: {0x63: {l: {0x6C: {l: {0x3B: {c: [33]}}}}}, 0x69: {l: {0x73: {l: {0x74: {l: {0x3B: {c: [8707]}}}}}}}, 0x70: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x61: {l: {0x74: {l: {0x69: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [8496]}}}}}}}}}}}}}}}}}, 0x6F: {l: {0x6E: {l: {0x65: {l: {0x6E: {l: {0x74: {l: {0x69: {l: {0x61: {l: {0x6C: {l: {0x65: {l: {0x3B: {c: [8519]}}}}}}}}}}}}}}}}}}}}}}}}},
+ 0x66: {l: {0x61: {l: {0x6C: {l: {0x6C: {l: {0x69: {l: {0x6E: {l: {0x67: {l: {0x64: {l: {0x6F: {l: {0x74: {l: {0x73: {l: {0x65: {l: {0x71: {l: {0x3B: {c: [8786]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x63: {l: {0x79: {l: {0x3B: {c: [1092]}}}}}, 0x65: {l: {0x6D: {l: {0x61: {l: {0x6C: {l: {0x65: {l: {0x3B: {c: [9792]}}}}}}}}}}}, 0x66: {l: {0x69: {l: {0x6C: {l: {0x69: {l: {0x67: {l: {0x3B: {c: [64259]}}}}}}}}}, 0x6C: {l: {0x69: {l: {0x67: {l: {0x3B: {c: [64256]}}}}}, 0x6C: {l: {0x69: {l: {0x67: {l: {0x3B: {c: [64260]}}}}}}}}}, 0x72: {l: {0x3B: {c: [120099]}}}}}, 0x69: {l: {0x6C: {l: {0x69: {l: {0x67: {l: {0x3B: {c: [64257]}}}}}}}}}, 0x6A: {l: {0x6C: {l: {0x69: {l: {0x67: {l: {0x3B: {c: [102, 106]}}}}}}}}}, 0x6C: {l: {0x61: {l: {0x74: {l: {0x3B: {c: [9837]}}}}}, 0x6C: {l: {0x69: {l: {0x67: {l: {0x3B: {c: [64258]}}}}}}}, 0x74: {l: {0x6E: {l: {0x73: {l: {0x3B: {c: [9649]}}}}}}}}}, 0x6E: {l: {0x6F: {l: {0x66: {l: {0x3B: {c: [402]}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120151]}}}}}, 0x72: {l: {0x61: {l: {0x6C: {l: {0x6C: {l: {0x3B: {c: [8704]}}}}}}}, 0x6B: {l: {0x3B: {c: [8916]}, 0x76: {l: {0x3B: {c: [10969]}}}}}}}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x74: {l: {0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [10765]}}}}}}}}}}}}}}}, 0x72: {l: {0x61: {l: {0x63: {l: {0x31: {l: {0x32: {l: {0x3B: {c: [189]}}, c: [189]}, 0x33: {l: {0x3B: {c: [8531]}}}, 0x34: {l: {0x3B: {c: [188]}}, c: [188]}, 0x35: {l: {0x3B: {c: [8533]}}}, 0x36: {l: {0x3B: {c: [8537]}}}, 0x38: {l: {0x3B: {c: [8539]}}}}}, 0x32: {l: {0x33: {l: {0x3B: {c: [8532]}}}, 0x35: {l: {0x3B: {c: [8534]}}}}}, 0x33: {l: {0x34: {l: {0x3B: {c: [190]}}, c: [190]}, 0x35: {l: {0x3B: {c: [8535]}}}, 0x38: {l: {0x3B: {c: [8540]}}}}}, 0x34: {l: {0x35: {l: {0x3B: {c: [8536]}}}}}, 0x35: {l: {0x36: {l: {0x3B: {c: [8538]}}}, 0x38: {l: {0x3B: {c: [8541]}}}}}, 0x37: {l: {0x38: {l: {0x3B: {c: [8542]}}}}}}}, 0x73: {l: {0x6C: {l: {0x3B: {c: [8260]}}}}}}}, 0x6F: {l: {0x77: {l: {0x6E: {l: {0x3B: {c: [8994]}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119995]}}}}}}}}},
+ 0x46: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1060]}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120073]}}}}}, 0x69: {l: {0x6C: {l: {0x6C: {l: {0x65: {l: {0x64: {l: {0x53: {l: {0x6D: {l: {0x61: {l: {0x6C: {l: {0x6C: {l: {0x53: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x72: {l: {0x65: {l: {0x3B: {c: [9724]}}}}}}}}}}}}}}}}}}}}}}}, 0x56: {l: {0x65: {l: {0x72: {l: {0x79: {l: {0x53: {l: {0x6D: {l: {0x61: {l: {0x6C: {l: {0x6C: {l: {0x53: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x72: {l: {0x65: {l: {0x3B: {c: [9642]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120125]}}}}}, 0x72: {l: {0x41: {l: {0x6C: {l: {0x6C: {l: {0x3B: {c: [8704]}}}}}}}}}, 0x75: {l: {0x72: {l: {0x69: {l: {0x65: {l: {0x72: {l: {0x74: {l: {0x72: {l: {0x66: {l: {0x3B: {c: [8497]}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [8497]}}}}}}}}},
+ 0x67: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [501]}}}}}}}}}, 0x6D: {l: {0x6D: {l: {0x61: {l: {0x3B: {c: [947]}, 0x64: {l: {0x3B: {c: [989]}}}}}}}}}, 0x70: {l: {0x3B: {c: [10886]}}}}}, 0x62: {l: {0x72: {l: {0x65: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [287]}}}}}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [285]}}}}}}}, 0x79: {l: {0x3B: {c: [1075]}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [289]}}}}}}}, 0x65: {l: {0x3B: {c: [8805]}, 0x6C: {l: {0x3B: {c: [8923]}}}, 0x71: {l: {0x3B: {c: [8805]}, 0x71: {l: {0x3B: {c: [8807]}}}, 0x73: {l: {0x6C: {l: {0x61: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [10878]}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x63: {l: {0x3B: {c: [10921]}}}}}, 0x3B: {c: [10878]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10880]}, 0x6F: {l: {0x3B: {c: [10882]}, 0x6C: {l: {0x3B: {c: [10884]}}}}}}}}}}}, 0x6C: {l: {0x3B: {c: [8923, 65024]}, 0x65: {l: {0x73: {l: {0x3B: {c: [10900]}}}}}}}}}}}, 0x45: {l: {0x3B: {c: [8807]}, 0x6C: {l: {0x3B: {c: [10892]}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120100]}}}}}, 0x67: {l: {0x3B: {c: [8811]}, 0x67: {l: {0x3B: {c: [8921]}}}}}, 0x69: {l: {0x6D: {l: {0x65: {l: {0x6C: {l: {0x3B: {c: [8503]}}}}}}}}}, 0x6A: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1107]}}}}}}}, 0x6C: {l: {0x61: {l: {0x3B: {c: [10917]}}}, 0x3B: {c: [8823]}, 0x45: {l: {0x3B: {c: [10898]}}}, 0x6A: {l: {0x3B: {c: [10916]}}}}}, 0x6E: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [10890]}, 0x70: {l: {0x72: {l: {0x6F: {l: {0x78: {l: {0x3B: {c: [10890]}}}}}}}}}}}}}, 0x65: {l: {0x3B: {c: [10888]}, 0x71: {l: {0x3B: {c: [10888]}, 0x71: {l: {0x3B: {c: [8809]}}}}}}}, 0x45: {l: {0x3B: {c: [8809]}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8935]}}}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120152]}}}}}}}, 0x72: {l: {0x61: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [96]}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [8458]}}}}}, 0x69: {l: {0x6D: {l: {0x3B: {c: [8819]}, 0x65: {l: {0x3B: {c: [10894]}}}, 0x6C: {l: {0x3B: {c: [10896]}}}}}}}}}, 0x74: {l: {0x63: {l: {0x63: {l: {0x3B: {c: [10919]}}}, 0x69: {l: {0x72: {l: {0x3B: {c: [10874]}}}}}}}, 0x3B: {c: [62]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8919]}}}}}}}, 0x6C: {l: {0x50: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10645]}}}}}}}}}, 0x71: {l: {0x75: {l: {0x65: {l: {0x73: {l: {0x74: {l: {0x3B: {c: [10876]}}}}}}}}}}}, 0x72: {l: {0x61: {l: {0x70: {l: {0x70: {l: {0x72: {l: {0x6F: {l: {0x78: {l: {0x3B: {c: [10886]}}}}}}}}}}}, 0x72: {l: {0x72: {l: {0x3B: {c: [10616]}}}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8919]}}}}}}}, 0x65: {l: {0x71: {l: {0x6C: {l: {0x65: {l: {0x73: {l: {0x73: {l: {0x3B: {c: [8923]}}}}}}}}}, 0x71: {l: {0x6C: {l: {0x65: {l: {0x73: {l: {0x73: {l: {0x3B: {c: [10892]}}}}}}}}}}}}}}}, 0x6C: {l: {0x65: {l: {0x73: {l: {0x73: {l: {0x3B: {c: [8823]}}}}}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8819]}}}}}}}}}}, c: [62]}, 0x76: {l: {0x65: {l: {0x72: {l: {0x74: {l: {0x6E: {l: {0x65: {l: {0x71: {l: {0x71: {l: {0x3B: {c: [8809, 65024]}}}}}}}}}}}}}}}, 0x6E: {l: {0x45: {l: {0x3B: {c: [8809, 65024]}}}}}}}}},
+ 0x47: {l: {0x61: {l: {0x6D: {l: {0x6D: {l: {0x61: {l: {0x3B: {c: [915]}, 0x64: {l: {0x3B: {c: [988]}}}}}}}}}}}, 0x62: {l: {0x72: {l: {0x65: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [286]}}}}}}}}}}}, 0x63: {l: {0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [290]}}}}}}}}}, 0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [284]}}}}}}}, 0x79: {l: {0x3B: {c: [1043]}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [288]}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120074]}}}}}, 0x67: {l: {0x3B: {c: [8921]}}}, 0x4A: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1027]}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120126]}}}}}}}, 0x72: {l: {0x65: {l: {0x61: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8805]}, 0x4C: {l: {0x65: {l: {0x73: {l: {0x73: {l: {0x3B: {c: [8923]}}}}}}}}}}}}}}}}}}}, 0x46: {l: {0x75: {l: {0x6C: {l: {0x6C: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8807]}}}}}}}}}}}}}}}}}}}, 0x47: {l: {0x72: {l: {0x65: {l: {0x61: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [10914]}}}}}}}}}}}}}}}, 0x4C: {l: {0x65: {l: {0x73: {l: {0x73: {l: {0x3B: {c: [8823]}}}}}}}}}, 0x53: {l: {0x6C: {l: {0x61: {l: {0x6E: {l: {0x74: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [10878]}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8819]}}}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119970]}}}}}}}, 0x54: {l: {0x3B: {c: [62]}}, c: [62]}, 0x74: {l: {0x3B: {c: [8811]}}}}},
+ 0x48: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x6B: {l: {0x3B: {c: [711]}}}}}}}, 0x74: {l: {0x3B: {c: [94]}}}}}, 0x41: {l: {0x52: {l: {0x44: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1066]}}}}}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [292]}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [8460]}}}}}, 0x69: {l: {0x6C: {l: {0x62: {l: {0x65: {l: {0x72: {l: {0x74: {l: {0x53: {l: {0x70: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [8459]}}}}}}}}}}}}}}}}}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [8461]}}}}}, 0x72: {l: {0x69: {l: {0x7A: {l: {0x6F: {l: {0x6E: {l: {0x74: {l: {0x61: {l: {0x6C: {l: {0x4C: {l: {0x69: {l: {0x6E: {l: {0x65: {l: {0x3B: {c: [9472]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [8459]}}}}}, 0x74: {l: {0x72: {l: {0x6F: {l: {0x6B: {l: {0x3B: {c: [294]}}}}}}}}}}}, 0x75: {l: {0x6D: {l: {0x70: {l: {0x44: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x48: {l: {0x75: {l: {0x6D: {l: {0x70: {l: {0x3B: {c: [8782]}}}}}}}}}}}}}}}}}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8783]}}}}}}}}}}}}}}}}}}},
+ 0x68: {l: {0x61: {l: {0x69: {l: {0x72: {l: {0x73: {l: {0x70: {l: {0x3B: {c: [8202]}}}}}}}}}, 0x6C: {l: {0x66: {l: {0x3B: {c: [189]}}}}}, 0x6D: {l: {0x69: {l: {0x6C: {l: {0x74: {l: {0x3B: {c: [8459]}}}}}}}}}, 0x72: {l: {0x64: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1098]}}}}}}}, 0x72: {l: {0x63: {l: {0x69: {l: {0x72: {l: {0x3B: {c: [10568]}}}}}}}, 0x3B: {c: [8596]}, 0x77: {l: {0x3B: {c: [8621]}}}}}}}}}, 0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8660]}}}}}}}, 0x62: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8463]}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [293]}}}}}}}}}, 0x65: {l: {0x61: {l: {0x72: {l: {0x74: {l: {0x73: {l: {0x3B: {c: [9829]}, 0x75: {l: {0x69: {l: {0x74: {l: {0x3B: {c: [9829]}}}}}}}}}}}}}}}, 0x6C: {l: {0x6C: {l: {0x69: {l: {0x70: {l: {0x3B: {c: [8230]}}}}}}}}}, 0x72: {l: {0x63: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [8889]}}}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120101]}}}}}, 0x6B: {l: {0x73: {l: {0x65: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10533]}}}}}}}}}}}, 0x77: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10534]}}}}}}}}}}}}}}}, 0x6F: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8703]}}}}}}}, 0x6D: {l: {0x74: {l: {0x68: {l: {0x74: {l: {0x3B: {c: [8763]}}}}}}}}}, 0x6F: {l: {0x6B: {l: {0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8617]}}}}}}}}}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8618]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120153]}}}}}, 0x72: {l: {0x62: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8213]}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119997]}}}}}, 0x6C: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8463]}}}}}}}}}, 0x74: {l: {0x72: {l: {0x6F: {l: {0x6B: {l: {0x3B: {c: [295]}}}}}}}}}}}, 0x79: {l: {0x62: {l: {0x75: {l: {0x6C: {l: {0x6C: {l: {0x3B: {c: [8259]}}}}}}}}}, 0x70: {l: {0x68: {l: {0x65: {l: {0x6E: {l: {0x3B: {c: [8208]}}}}}}}}}}}}},
+ 0x49: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [205]}}, c: [205]}}}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [206]}}, c: [206]}}}}}, 0x79: {l: {0x3B: {c: [1048]}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [304]}}}}}}}, 0x45: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1045]}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [8465]}}}}}, 0x67: {l: {0x72: {l: {0x61: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [204]}}, c: [204]}}}}}}}}}, 0x4A: {l: {0x6C: {l: {0x69: {l: {0x67: {l: {0x3B: {c: [306]}}}}}}}}}, 0x6D: {l: {0x61: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [298]}}}}}, 0x67: {l: {0x69: {l: {0x6E: {l: {0x61: {l: {0x72: {l: {0x79: {l: {0x49: {l: {0x3B: {c: [8520]}}}}}}}}}}}}}}}}}, 0x3B: {c: [8465]}, 0x70: {l: {0x6C: {l: {0x69: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [8658]}}}}}}}}}}}}}, 0x6E: {l: {0x74: {l: {0x3B: {c: [8748]}, 0x65: {l: {0x67: {l: {0x72: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8747]}}}}}}}}}, 0x72: {l: {0x73: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x69: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [8898]}}}}}}}}}}}}}}}}}}}}}, 0x76: {l: {0x69: {l: {0x73: {l: {0x69: {l: {0x62: {l: {0x6C: {l: {0x65: {l: {0x43: {l: {0x6F: {l: {0x6D: {l: {0x6D: {l: {0x61: {l: {0x3B: {c: [8291]}}}}}}}}}}}, 0x54: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [8290]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x4F: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1025]}}}}}}}, 0x6F: {l: {0x67: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [302]}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120128]}}}}}, 0x74: {l: {0x61: {l: {0x3B: {c: [921]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [8464]}}}}}}}, 0x74: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [296]}}}}}}}}}}}, 0x75: {l: {0x6B: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1030]}}}}}}}, 0x6D: {l: {0x6C: {l: {0x3B: {c: [207]}}, c: [207]}}}}}}},
+ 0x69: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [237]}}, c: [237]}}}}}}}}}, 0x63: {l: {0x3B: {c: [8291]}, 0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [238]}}, c: [238]}}}}}, 0x79: {l: {0x3B: {c: [1080]}}}}}, 0x65: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1077]}}}}}, 0x78: {l: {0x63: {l: {0x6C: {l: {0x3B: {c: [161]}}, c: [161]}}}}}}}, 0x66: {l: {0x66: {l: {0x3B: {c: [8660]}}}, 0x72: {l: {0x3B: {c: [120102]}}}}}, 0x67: {l: {0x72: {l: {0x61: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [236]}}, c: [236]}}}}}}}}}, 0x69: {l: {0x3B: {c: [8520]}, 0x69: {l: {0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [10764]}}}}}}}, 0x6E: {l: {0x74: {l: {0x3B: {c: [8749]}}}}}}}, 0x6E: {l: {0x66: {l: {0x69: {l: {0x6E: {l: {0x3B: {c: [10716]}}}}}}}}}, 0x6F: {l: {0x74: {l: {0x61: {l: {0x3B: {c: [8489]}}}}}}}}}, 0x6A: {l: {0x6C: {l: {0x69: {l: {0x67: {l: {0x3B: {c: [307]}}}}}}}}}, 0x6D: {l: {0x61: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [299]}}}}}, 0x67: {l: {0x65: {l: {0x3B: {c: [8465]}}}, 0x6C: {l: {0x69: {l: {0x6E: {l: {0x65: {l: {0x3B: {c: [8464]}}}}}}}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x74: {l: {0x3B: {c: [8465]}}}}}}}}}}}, 0x74: {l: {0x68: {l: {0x3B: {c: [305]}}}}}}}, 0x6F: {l: {0x66: {l: {0x3B: {c: [8887]}}}}}, 0x70: {l: {0x65: {l: {0x64: {l: {0x3B: {c: [437]}}}}}}}}}, 0x6E: {l: {0x63: {l: {0x61: {l: {0x72: {l: {0x65: {l: {0x3B: {c: [8453]}}}}}}}}}, 0x3B: {c: [8712]}, 0x66: {l: {0x69: {l: {0x6E: {l: {0x3B: {c: [8734]}, 0x74: {l: {0x69: {l: {0x65: {l: {0x3B: {c: [10717]}}}}}}}}}}}}}, 0x6F: {l: {0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [305]}}}}}}}}}, 0x74: {l: {0x63: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8890]}}}}}}}, 0x3B: {c: [8747]}, 0x65: {l: {0x67: {l: {0x65: {l: {0x72: {l: {0x73: {l: {0x3B: {c: [8484]}}}}}}}}}, 0x72: {l: {0x63: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8890]}}}}}}}}}}}, 0x6C: {l: {0x61: {l: {0x72: {l: {0x68: {l: {0x6B: {l: {0x3B: {c: [10775]}}}}}}}}}}}, 0x70: {l: {0x72: {l: {0x6F: {l: {0x64: {l: {0x3B: {c: [10812]}}}}}}}}}}}}}, 0x6F: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1105]}}}}}, 0x67: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [303]}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120154]}}}}}, 0x74: {l: {0x61: {l: {0x3B: {c: [953]}}}}}}}, 0x70: {l: {0x72: {l: {0x6F: {l: {0x64: {l: {0x3B: {c: [10812]}}}}}}}}}, 0x71: {l: {0x75: {l: {0x65: {l: {0x73: {l: {0x74: {l: {0x3B: {c: [191]}}, c: [191]}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119998]}}}}}, 0x69: {l: {0x6E: {l: {0x3B: {c: [8712]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8949]}}}}}}}, 0x45: {l: {0x3B: {c: [8953]}}}, 0x73: {l: {0x3B: {c: [8948]}, 0x76: {l: {0x3B: {c: [8947]}}}}}, 0x76: {l: {0x3B: {c: [8712]}}}}}}}}}, 0x74: {l: {0x3B: {c: [8290]}, 0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [297]}}}}}}}}}}}, 0x75: {l: {0x6B: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1110]}}}}}}}, 0x6D: {l: {0x6C: {l: {0x3B: {c: [239]}}, c: [239]}}}}}}},
+ 0x4A: {l: {0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [308]}}}}}}}, 0x79: {l: {0x3B: {c: [1049]}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120077]}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120129]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119973]}}}}}, 0x65: {l: {0x72: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1032]}}}}}}}}}}}, 0x75: {l: {0x6B: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1028]}}}}}}}}}}},
+ 0x6A: {l: {0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [309]}}}}}}}, 0x79: {l: {0x3B: {c: [1081]}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120103]}}}}}, 0x6D: {l: {0x61: {l: {0x74: {l: {0x68: {l: {0x3B: {c: [567]}}}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120155]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119999]}}}}}, 0x65: {l: {0x72: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1112]}}}}}}}}}}}, 0x75: {l: {0x6B: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1108]}}}}}}}}}}},
+ 0x4B: {l: {0x61: {l: {0x70: {l: {0x70: {l: {0x61: {l: {0x3B: {c: [922]}}}}}}}}}, 0x63: {l: {0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [310]}}}}}}}}}, 0x79: {l: {0x3B: {c: [1050]}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120078]}}}}}, 0x48: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1061]}}}}}}}, 0x4A: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1036]}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120130]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119974]}}}}}}}}},
+ 0x6B: {l: {0x61: {l: {0x70: {l: {0x70: {l: {0x61: {l: {0x3B: {c: [954]}, 0x76: {l: {0x3B: {c: [1008]}}}}}}}}}}}, 0x63: {l: {0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [311]}}}}}}}}}, 0x79: {l: {0x3B: {c: [1082]}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120104]}}}}}, 0x67: {l: {0x72: {l: {0x65: {l: {0x65: {l: {0x6E: {l: {0x3B: {c: [312]}}}}}}}}}}}, 0x68: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1093]}}}}}}}, 0x6A: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1116]}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120156]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [120000]}}}}}}}}},
+ 0x6C: {l: {0x41: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8666]}}}}}}}, 0x72: {l: {0x72: {l: {0x3B: {c: [8656]}}}}}, 0x74: {l: {0x61: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [10523]}}}}}}}}}}}, 0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [314]}}}}}}}}}, 0x65: {l: {0x6D: {l: {0x70: {l: {0x74: {l: {0x79: {l: {0x76: {l: {0x3B: {c: [10676]}}}}}}}}}}}}}, 0x67: {l: {0x72: {l: {0x61: {l: {0x6E: {l: {0x3B: {c: [8466]}}}}}}}}}, 0x6D: {l: {0x62: {l: {0x64: {l: {0x61: {l: {0x3B: {c: [955]}}}}}}}}}, 0x6E: {l: {0x67: {l: {0x3B: {c: [10216]}, 0x64: {l: {0x3B: {c: [10641]}}}, 0x6C: {l: {0x65: {l: {0x3B: {c: [10216]}}}}}}}}}, 0x70: {l: {0x3B: {c: [10885]}}}, 0x71: {l: {0x75: {l: {0x6F: {l: {0x3B: {c: [171]}}, c: [171]}}}}}, 0x72: {l: {0x72: {l: {0x62: {l: {0x3B: {c: [8676]}, 0x66: {l: {0x73: {l: {0x3B: {c: [10527]}}}}}}}, 0x3B: {c: [8592]}, 0x66: {l: {0x73: {l: {0x3B: {c: [10525]}}}}}, 0x68: {l: {0x6B: {l: {0x3B: {c: [8617]}}}}}, 0x6C: {l: {0x70: {l: {0x3B: {c: [8619]}}}}}, 0x70: {l: {0x6C: {l: {0x3B: {c: [10553]}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [10611]}}}}}}}, 0x74: {l: {0x6C: {l: {0x3B: {c: [8610]}}}}}}}}}, 0x74: {l: {0x61: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [10521]}}}}}}}, 0x3B: {c: [10923]}, 0x65: {l: {0x3B: {c: [10925]}, 0x73: {l: {0x3B: {c: [10925, 65024]}}}}}}}}}, 0x62: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10508]}}}}}}}, 0x62: {l: {0x72: {l: {0x6B: {l: {0x3B: {c: [10098]}}}}}}}, 0x72: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [123]}}}, 0x6B: {l: {0x3B: {c: [91]}}}}}}}, 0x6B: {l: {0x65: {l: {0x3B: {c: [10635]}}}, 0x73: {l: {0x6C: {l: {0x64: {l: {0x3B: {c: [10639]}}}, 0x75: {l: {0x3B: {c: [10637]}}}}}}}}}}}}}, 0x42: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10510]}}}}}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [318]}}}}}}}}}, 0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [316]}}}}}}}, 0x69: {l: {0x6C: {l: {0x3B: {c: [8968]}}}}}}}, 0x75: {l: {0x62: {l: {0x3B: {c: [123]}}}}}, 0x79: {l: {0x3B: {c: [1083]}}}}}, 0x64: {l: {0x63: {l: {0x61: {l: {0x3B: {c: [10550]}}}}}, 0x71: {l: {0x75: {l: {0x6F: {l: {0x3B: {c: [8220]}, 0x72: {l: {0x3B: {c: [8222]}}}}}}}}}, 0x72: {l: {0x64: {l: {0x68: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10599]}}}}}}}}}, 0x75: {l: {0x73: {l: {0x68: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10571]}}}}}}}}}}}}}, 0x73: {l: {0x68: {l: {0x3B: {c: [8626]}}}}}}}, 0x65: {l: {0x3B: {c: [8804]}, 0x66: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8592]}, 0x74: {l: {0x61: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [8610]}}}}}}}}}}}}}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x70: {l: {0x6F: {l: {0x6F: {l: {0x6E: {l: {0x64: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x3B: {c: [8637]}}}}}}}}}, 0x75: {l: {0x70: {l: {0x3B: {c: [8636]}}}}}}}}}}}}}}}}}}}, 0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x73: {l: {0x3B: {c: [8647]}}}}}}}}}}}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8596]}, 0x73: {l: {0x3B: {c: [8646]}}}}}}}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x70: {l: {0x6F: {l: {0x6F: {l: {0x6E: {l: {0x73: {l: {0x3B: {c: [8651]}}}}}}}}}}}}}}}}}, 0x73: {l: {0x71: {l: {0x75: {l: {0x69: {l: {0x67: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8621]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x74: {l: {0x68: {l: {0x72: {l: {0x65: {l: {0x65: {l: {0x74: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [8907]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x67: {l: {0x3B: {c: [8922]}}}, 0x71: {l: {0x3B: {c: [8804]}, 0x71: {l: {0x3B: {c: [8806]}}}, 0x73: {l: {0x6C: {l: {0x61: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [10877]}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x63: {l: {0x3B: {c: [10920]}}}}}, 0x3B: {c: [10877]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10879]}, 0x6F: {l: {0x3B: {c: [10881]}, 0x72: {l: {0x3B: {c: [10883]}}}}}}}}}}}, 0x67: {l: {0x3B: {c: [8922, 65024]}, 0x65: {l: {0x73: {l: {0x3B: {c: [10899]}}}}}}}, 0x73: {l: {0x61: {l: {0x70: {l: {0x70: {l: {0x72: {l: {0x6F: {l: {0x78: {l: {0x3B: {c: [10885]}}}}}}}}}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8918]}}}}}}}, 0x65: {l: {0x71: {l: {0x67: {l: {0x74: {l: {0x72: {l: {0x3B: {c: [8922]}}}}}}}, 0x71: {l: {0x67: {l: {0x74: {l: {0x72: {l: {0x3B: {c: [10891]}}}}}}}}}}}}}, 0x67: {l: {0x74: {l: {0x72: {l: {0x3B: {c: [8822]}}}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8818]}}}}}}}}}}}}}, 0x45: {l: {0x3B: {c: [8806]}, 0x67: {l: {0x3B: {c: [10891]}}}}}, 0x66: {l: {0x69: {l: {0x73: {l: {0x68: {l: {0x74: {l: {0x3B: {c: [10620]}}}}}}}}}, 0x6C: {l: {0x6F: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [8970]}}}}}}}}}, 0x72: {l: {0x3B: {c: [120105]}}}}}, 0x67: {l: {0x3B: {c: [8822]}, 0x45: {l: {0x3B: {c: [10897]}}}}}, 0x48: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10594]}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x64: {l: {0x3B: {c: [8637]}}}, 0x75: {l: {0x3B: {c: [8636]}, 0x6C: {l: {0x3B: {c: [10602]}}}}}}}}}, 0x62: {l: {0x6C: {l: {0x6B: {l: {0x3B: {c: [9604]}}}}}}}}}, 0x6A: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1113]}}}}}}}, 0x6C: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8647]}}}}}}}, 0x3B: {c: [8810]}, 0x63: {l: {0x6F: {l: {0x72: {l: {0x6E: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [8990]}}}}}}}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x64: {l: {0x3B: {c: [10603]}}}}}}}}}, 0x74: {l: {0x72: {l: {0x69: {l: {0x3B: {c: [9722]}}}}}}}}}, 0x6D: {l: {0x69: {l: {0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [320]}}}}}}}}}, 0x6F: {l: {0x75: {l: {0x73: {l: {0x74: {l: {0x61: {l: {0x63: {l: {0x68: {l: {0x65: {l: {0x3B: {c: [9136]}}}}}}}}}, 0x3B: {c: [9136]}}}}}}}}}}}, 0x6E: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [10889]}, 0x70: {l: {0x72: {l: {0x6F: {l: {0x78: {l: {0x3B: {c: [10889]}}}}}}}}}}}}}, 0x65: {l: {0x3B: {c: [10887]}, 0x71: {l: {0x3B: {c: [10887]}, 0x71: {l: {0x3B: {c: [8808]}}}}}}}, 0x45: {l: {0x3B: {c: [8808]}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8934]}}}}}}}}}, 0x6F: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x3B: {c: [10220]}}}}}, 0x72: {l: {0x72: {l: {0x3B: {c: [8701]}}}}}}}, 0x62: {l: {0x72: {l: {0x6B: {l: {0x3B: {c: [10214]}}}}}}}, 0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10229]}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10231]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x6D: {l: {0x61: {l: {0x70: {l: {0x73: {l: {0x74: {l: {0x6F: {l: {0x3B: {c: [10236]}}}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10230]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x6F: {l: {0x70: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x3B: {c: [8619]}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x3B: {c: [8620]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10629]}}}}}, 0x66: {l: {0x3B: {c: [120157]}}}, 0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [10797]}}}}}}}}}, 0x74: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [10804]}}}}}}}}}}}, 0x77: {l: {0x61: {l: {0x73: {l: {0x74: {l: {0x3B: {c: [8727]}}}}}}}, 0x62: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [95]}}}}}}}}}, 0x7A: {l: {0x3B: {c: [9674]}, 0x65: {l: {0x6E: {l: {0x67: {l: {0x65: {l: {0x3B: {c: [9674]}}}}}}}}}, 0x66: {l: {0x3B: {c: [10731]}}}}}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [40]}, 0x6C: {l: {0x74: {l: {0x3B: {c: [10643]}}}}}}}}}}}, 0x72: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8646]}}}}}}}, 0x63: {l: {0x6F: {l: {0x72: {l: {0x6E: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [8991]}}}}}}}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8651]}, 0x64: {l: {0x3B: {c: [10605]}}}}}}}}}, 0x6D: {l: {0x3B: {c: [8206]}}}, 0x74: {l: {0x72: {l: {0x69: {l: {0x3B: {c: [8895]}}}}}}}}}, 0x73: {l: {0x61: {l: {0x71: {l: {0x75: {l: {0x6F: {l: {0x3B: {c: [8249]}}}}}}}}}, 0x63: {l: {0x72: {l: {0x3B: {c: [120001]}}}}}, 0x68: {l: {0x3B: {c: [8624]}}}, 0x69: {l: {0x6D: {l: {0x3B: {c: [8818]}, 0x65: {l: {0x3B: {c: [10893]}}}, 0x67: {l: {0x3B: {c: [10895]}}}}}}}, 0x71: {l: {0x62: {l: {0x3B: {c: [91]}}}, 0x75: {l: {0x6F: {l: {0x3B: {c: [8216]}, 0x72: {l: {0x3B: {c: [8218]}}}}}}}}}, 0x74: {l: {0x72: {l: {0x6F: {l: {0x6B: {l: {0x3B: {c: [322]}}}}}}}}}}}, 0x74: {l: {0x63: {l: {0x63: {l: {0x3B: {c: [10918]}}}, 0x69: {l: {0x72: {l: {0x3B: {c: [10873]}}}}}}}, 0x3B: {c: [60]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8918]}}}}}}}, 0x68: {l: {0x72: {l: {0x65: {l: {0x65: {l: {0x3B: {c: [8907]}}}}}}}}}, 0x69: {l: {0x6D: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [8905]}}}}}}}}}, 0x6C: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10614]}}}}}}}}}, 0x71: {l: {0x75: {l: {0x65: {l: {0x73: {l: {0x74: {l: {0x3B: {c: [10875]}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x3B: {c: [9667]}, 0x65: {l: {0x3B: {c: [8884]}}}, 0x66: {l: {0x3B: {c: [9666]}}}}}, 0x50: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10646]}}}}}}}}}}, c: [60]}, 0x75: {l: {0x72: {l: {0x64: {l: {0x73: {l: {0x68: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10570]}}}}}}}}}}}, 0x75: {l: {0x68: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10598]}}}}}}}}}}}}}, 0x76: {l: {0x65: {l: {0x72: {l: {0x74: {l: {0x6E: {l: {0x65: {l: {0x71: {l: {0x71: {l: {0x3B: {c: [8808, 65024]}}}}}}}}}}}}}}}, 0x6E: {l: {0x45: {l: {0x3B: {c: [8808, 65024]}}}}}}}}},
+ 0x4C: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [313]}}}}}}}}}, 0x6D: {l: {0x62: {l: {0x64: {l: {0x61: {l: {0x3B: {c: [923]}}}}}}}}}, 0x6E: {l: {0x67: {l: {0x3B: {c: [10218]}}}}}, 0x70: {l: {0x6C: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x74: {l: {0x72: {l: {0x66: {l: {0x3B: {c: [8466]}}}}}}}}}}}}}}}}}, 0x72: {l: {0x72: {l: {0x3B: {c: [8606]}}}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [317]}}}}}}}}}, 0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [315]}}}}}}}}}, 0x79: {l: {0x3B: {c: [1051]}}}}}, 0x65: {l: {0x66: {l: {0x74: {l: {0x41: {l: {0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x42: {l: {0x72: {l: {0x61: {l: {0x63: {l: {0x6B: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [10216]}}}}}}}}}}}}}}}}}}}}}}}, 0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8676]}}}}}}}, 0x3B: {c: [8592]}, 0x52: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8646]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8656]}}}}}}}}}}}, 0x43: {l: {0x65: {l: {0x69: {l: {0x6C: {l: {0x69: {l: {0x6E: {l: {0x67: {l: {0x3B: {c: [8968]}}}}}}}}}}}}}}}, 0x44: {l: {0x6F: {l: {0x75: {l: {0x62: {l: {0x6C: {l: {0x65: {l: {0x42: {l: {0x72: {l: {0x61: {l: {0x63: {l: {0x6B: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [10214]}}}}}}}}}}}}}}}}}}}}}}}, 0x77: {l: {0x6E: {l: {0x54: {l: {0x65: {l: {0x65: {l: {0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [10593]}}}}}}}}}}}}}}}}}}}, 0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10585]}}}}}}}, 0x3B: {c: [8643]}}}}}}}}}}}}}}}}}}}}}, 0x46: {l: {0x6C: {l: {0x6F: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [8970]}}}}}}}}}}}, 0x52: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8596]}}}}}}}}}}}, 0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [10574]}}}}}}}}}}}}}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8660]}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x65: {l: {0x65: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8612]}}}}}}}}}}}, 0x3B: {c: [8867]}, 0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [10586]}}}}}}}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10703]}}}}}}}, 0x3B: {c: [8882]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8884]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x55: {l: {0x70: {l: {0x44: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [10577]}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x65: {l: {0x65: {l: {0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [10592]}}}}}}}}}}}}}}}}}}}, 0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10584]}}}}}}}, 0x3B: {c: [8639]}}}}}}}}}}}}}}}}}, 0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10578]}}}}}}}, 0x3B: {c: [8636]}}}}}}}}}}}}}}}}}, 0x73: {l: {0x73: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x47: {l: {0x72: {l: {0x65: {l: {0x61: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [8922]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x46: {l: {0x75: {l: {0x6C: {l: {0x6C: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8806]}}}}}}}}}}}}}}}}}}}, 0x47: {l: {0x72: {l: {0x65: {l: {0x61: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [8822]}}}}}}}}}}}}}}}, 0x4C: {l: {0x65: {l: {0x73: {l: {0x73: {l: {0x3B: {c: [10913]}}}}}}}}}, 0x53: {l: {0x6C: {l: {0x61: {l: {0x6E: {l: {0x74: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [10877]}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8818]}}}}}}}}}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120079]}}}}}, 0x4A: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1033]}}}}}}}, 0x6C: {l: {0x3B: {c: [8920]}, 0x65: {l: {0x66: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8666]}}}}}}}}}}}}}}}}}}}, 0x6D: {l: {0x69: {l: {0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [319]}}}}}}}}}}}, 0x6F: {l: {0x6E: {l: {0x67: {l: {0x4C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10229]}}}}}}}}}}}, 0x52: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10231]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10232]}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10234]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x52: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10230]}}}}}}}}}}}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [10233]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120131]}}}}}, 0x77: {l: {0x65: {l: {0x72: {l: {0x4C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8601]}}}}}}}}}}}}}}}}}}}, 0x52: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8600]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [8466]}}}}}, 0x68: {l: {0x3B: {c: [8624]}}}, 0x74: {l: {0x72: {l: {0x6F: {l: {0x6B: {l: {0x3B: {c: [321]}}}}}}}}}}}, 0x54: {l: {0x3B: {c: [60]}}, c: [60]}, 0x74: {l: {0x3B: {c: [8810]}}}}},
+ 0x6D: {l: {0x61: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [175]}}, c: [175]}}}, 0x6C: {l: {0x65: {l: {0x3B: {c: [9794]}}}, 0x74: {l: {0x3B: {c: [10016]}, 0x65: {l: {0x73: {l: {0x65: {l: {0x3B: {c: [10016]}}}}}}}}}}}, 0x70: {l: {0x3B: {c: [8614]}, 0x73: {l: {0x74: {l: {0x6F: {l: {0x3B: {c: [8614]}, 0x64: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x3B: {c: [8615]}}}}}}}}}, 0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x3B: {c: [8612]}}}}}}}}}, 0x75: {l: {0x70: {l: {0x3B: {c: [8613]}}}}}}}}}}}}}, 0x72: {l: {0x6B: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [9646]}}}}}}}}}}}, 0x63: {l: {0x6F: {l: {0x6D: {l: {0x6D: {l: {0x61: {l: {0x3B: {c: [10793]}}}}}}}}}, 0x79: {l: {0x3B: {c: [1084]}}}}}, 0x64: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8212]}}}}}}}}}, 0x44: {l: {0x44: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8762]}}}}}}}}}, 0x65: {l: {0x61: {l: {0x73: {l: {0x75: {l: {0x72: {l: {0x65: {l: {0x64: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x3B: {c: [8737]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120106]}}}}}, 0x68: {l: {0x6F: {l: {0x3B: {c: [8487]}}}}}, 0x69: {l: {0x63: {l: {0x72: {l: {0x6F: {l: {0x3B: {c: [181]}}, c: [181]}}}}}, 0x64: {l: {0x61: {l: {0x73: {l: {0x74: {l: {0x3B: {c: [42]}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x3B: {c: [10992]}}}}}}}, 0x3B: {c: [8739]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [183]}}, c: [183]}}}}}}}, 0x6E: {l: {0x75: {l: {0x73: {l: {0x62: {l: {0x3B: {c: [8863]}}}, 0x3B: {c: [8722]}, 0x64: {l: {0x3B: {c: [8760]}, 0x75: {l: {0x3B: {c: [10794]}}}}}}}}}}}}}, 0x6C: {l: {0x63: {l: {0x70: {l: {0x3B: {c: [10971]}}}}}, 0x64: {l: {0x72: {l: {0x3B: {c: [8230]}}}}}}}, 0x6E: {l: {0x70: {l: {0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8723]}}}}}}}}}}}, 0x6F: {l: {0x64: {l: {0x65: {l: {0x6C: {l: {0x73: {l: {0x3B: {c: [8871]}}}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120158]}}}}}}}, 0x70: {l: {0x3B: {c: [8723]}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [120002]}}}}}, 0x74: {l: {0x70: {l: {0x6F: {l: {0x73: {l: {0x3B: {c: [8766]}}}}}}}}}}}, 0x75: {l: {0x3B: {c: [956]}, 0x6C: {l: {0x74: {l: {0x69: {l: {0x6D: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [8888]}}}}}}}}}}}}}, 0x6D: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [8888]}}}}}}}}}}},
+ 0x4D: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [10501]}}}}}, 0x63: {l: {0x79: {l: {0x3B: {c: [1052]}}}}}, 0x65: {l: {0x64: {l: {0x69: {l: {0x75: {l: {0x6D: {l: {0x53: {l: {0x70: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [8287]}}}}}}}}}}}}}}}}}}}, 0x6C: {l: {0x6C: {l: {0x69: {l: {0x6E: {l: {0x74: {l: {0x72: {l: {0x66: {l: {0x3B: {c: [8499]}}}}}}}}}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120080]}}}}}, 0x69: {l: {0x6E: {l: {0x75: {l: {0x73: {l: {0x50: {l: {0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8723]}}}}}}}}}}}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120132]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [8499]}}}}}}}, 0x75: {l: {0x3B: {c: [924]}}}}},
+ 0x6E: {l: {0x61: {l: {0x62: {l: {0x6C: {l: {0x61: {l: {0x3B: {c: [8711]}}}}}}}, 0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [324]}}}}}}}}}, 0x6E: {l: {0x67: {l: {0x3B: {c: [8736, 8402]}}}}}, 0x70: {l: {0x3B: {c: [8777]}, 0x45: {l: {0x3B: {c: [10864, 824]}}}, 0x69: {l: {0x64: {l: {0x3B: {c: [8779, 824]}}}}}, 0x6F: {l: {0x73: {l: {0x3B: {c: [329]}}}}}, 0x70: {l: {0x72: {l: {0x6F: {l: {0x78: {l: {0x3B: {c: [8777]}}}}}}}}}}}, 0x74: {l: {0x75: {l: {0x72: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [9838]}, 0x73: {l: {0x3B: {c: [8469]}}}}}}}, 0x3B: {c: [9838]}}}}}}}}}, 0x62: {l: {0x73: {l: {0x70: {l: {0x3B: {c: [160]}}, c: [160]}}}, 0x75: {l: {0x6D: {l: {0x70: {l: {0x3B: {c: [8782, 824]}, 0x65: {l: {0x3B: {c: [8783, 824]}}}}}}}}}}}, 0x63: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [10819]}}}, 0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [328]}}}}}}}}}, 0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [326]}}}}}}}}}, 0x6F: {l: {0x6E: {l: {0x67: {l: {0x3B: {c: [8775]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10861, 824]}}}}}}}}}}}}}, 0x75: {l: {0x70: {l: {0x3B: {c: [10818]}}}}}, 0x79: {l: {0x3B: {c: [1085]}}}}}, 0x64: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8211]}}}}}}}}}, 0x65: {l: {0x61: {l: {0x72: {l: {0x68: {l: {0x6B: {l: {0x3B: {c: [10532]}}}}}, 0x72: {l: {0x3B: {c: [8599]}, 0x6F: {l: {0x77: {l: {0x3B: {c: [8599]}}}}}}}}}}}, 0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8663]}}}}}}}, 0x3B: {c: [8800]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8784, 824]}}}}}}}, 0x71: {l: {0x75: {l: {0x69: {l: {0x76: {l: {0x3B: {c: [8802]}}}}}}}}}, 0x73: {l: {0x65: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10536]}}}}}}}, 0x69: {l: {0x6D: {l: {0x3B: {c: [8770, 824]}}}}}}}, 0x78: {l: {0x69: {l: {0x73: {l: {0x74: {l: {0x3B: {c: [8708]}, 0x73: {l: {0x3B: {c: [8708]}}}}}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120107]}}}}}, 0x67: {l: {0x45: {l: {0x3B: {c: [8807, 824]}}}, 0x65: {l: {0x3B: {c: [8817]}, 0x71: {l: {0x3B: {c: [8817]}, 0x71: {l: {0x3B: {c: [8807, 824]}}}, 0x73: {l: {0x6C: {l: {0x61: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [10878, 824]}}}}}}}}}}}}}, 0x73: {l: {0x3B: {c: [10878, 824]}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8821]}}}}}}}, 0x74: {l: {0x3B: {c: [8815]}, 0x72: {l: {0x3B: {c: [8815]}}}}}}}, 0x47: {l: {0x67: {l: {0x3B: {c: [8921, 824]}}}, 0x74: {l: {0x3B: {c: [8811, 8402]}, 0x76: {l: {0x3B: {c: [8811, 824]}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8622]}}}}}}}, 0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8654]}}}}}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10994]}}}}}}}}}, 0x69: {l: {0x3B: {c: [8715]}, 0x73: {l: {0x3B: {c: [8956]}, 0x64: {l: {0x3B: {c: [8954]}}}}}, 0x76: {l: {0x3B: {c: [8715]}}}}}, 0x6A: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1114]}}}}}}}, 0x6C: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8602]}}}}}}}, 0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8653]}}}}}}}, 0x64: {l: {0x72: {l: {0x3B: {c: [8229]}}}}}, 0x45: {l: {0x3B: {c: [8806, 824]}}}, 0x65: {l: {0x3B: {c: [8816]}, 0x66: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8602]}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8622]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x71: {l: {0x3B: {c: [8816]}, 0x71: {l: {0x3B: {c: [8806, 824]}}}, 0x73: {l: {0x6C: {l: {0x61: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [10877, 824]}}}}}}}}}}}}}, 0x73: {l: {0x3B: {c: [10877, 824]}, 0x73: {l: {0x3B: {c: [8814]}}}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8820]}}}}}}}, 0x74: {l: {0x3B: {c: [8814]}, 0x72: {l: {0x69: {l: {0x3B: {c: [8938]}, 0x65: {l: {0x3B: {c: [8940]}}}}}}}}}}}, 0x4C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8653]}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8654]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x6C: {l: {0x3B: {c: [8920, 824]}}}, 0x74: {l: {0x3B: {c: [8810, 8402]}, 0x76: {l: {0x3B: {c: [8810, 824]}}}}}}}, 0x6D: {l: {0x69: {l: {0x64: {l: {0x3B: {c: [8740]}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120159]}}}}}, 0x74: {l: {0x3B: {c: [172]}, 0x69: {l: {0x6E: {l: {0x3B: {c: [8713]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8949, 824]}}}}}}}, 0x45: {l: {0x3B: {c: [8953, 824]}}}, 0x76: {l: {0x61: {l: {0x3B: {c: [8713]}}}, 0x62: {l: {0x3B: {c: [8951]}}}, 0x63: {l: {0x3B: {c: [8950]}}}}}}}}}, 0x6E: {l: {0x69: {l: {0x3B: {c: [8716]}, 0x76: {l: {0x61: {l: {0x3B: {c: [8716]}}}, 0x62: {l: {0x3B: {c: [8958]}}}, 0x63: {l: {0x3B: {c: [8957]}}}}}}}}}}, c: [172]}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x61: {l: {0x6C: {l: {0x6C: {l: {0x65: {l: {0x6C: {l: {0x3B: {c: [8742]}}}}}}}}}}}, 0x3B: {c: [8742]}, 0x73: {l: {0x6C: {l: {0x3B: {c: [11005, 8421]}}}}}, 0x74: {l: {0x3B: {c: [8706, 824]}}}}}}}, 0x6F: {l: {0x6C: {l: {0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [10772]}}}}}}}}}}}, 0x72: {l: {0x3B: {c: [8832]}, 0x63: {l: {0x75: {l: {0x65: {l: {0x3B: {c: [8928]}}}}}}}, 0x65: {l: {0x63: {l: {0x3B: {c: [8832]}, 0x65: {l: {0x71: {l: {0x3B: {c: [10927, 824]}}}}}}}, 0x3B: {c: [10927, 824]}}}}}}}, 0x72: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [10547, 824]}}}, 0x3B: {c: [8603]}, 0x77: {l: {0x3B: {c: [8605, 824]}}}}}}}}}, 0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8655]}}}}}}}, 0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8603]}}}}}}}}}}}}}}}}}}}, 0x74: {l: {0x72: {l: {0x69: {l: {0x3B: {c: [8939]}, 0x65: {l: {0x3B: {c: [8941]}}}}}}}}}}}, 0x52: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8655]}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x3B: {c: [8833]}, 0x63: {l: {0x75: {l: {0x65: {l: {0x3B: {c: [8929]}}}}}}}, 0x65: {l: {0x3B: {c: [10928, 824]}}}, 0x72: {l: {0x3B: {c: [120003]}}}}}, 0x68: {l: {0x6F: {l: {0x72: {l: {0x74: {l: {0x6D: {l: {0x69: {l: {0x64: {l: {0x3B: {c: [8740]}}}}}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x61: {l: {0x6C: {l: {0x6C: {l: {0x65: {l: {0x6C: {l: {0x3B: {c: [8742]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x69: {l: {0x6D: {l: {0x3B: {c: [8769]}, 0x65: {l: {0x3B: {c: [8772]}, 0x71: {l: {0x3B: {c: [8772]}}}}}}}}}, 0x6D: {l: {0x69: {l: {0x64: {l: {0x3B: {c: [8740]}}}}}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8742]}}}}}}}, 0x71: {l: {0x73: {l: {0x75: {l: {0x62: {l: {0x65: {l: {0x3B: {c: [8930]}}}}}, 0x70: {l: {0x65: {l: {0x3B: {c: [8931]}}}}}}}}}}}, 0x75: {l: {0x62: {l: {0x3B: {c: [8836]}, 0x45: {l: {0x3B: {c: [10949, 824]}}}, 0x65: {l: {0x3B: {c: [8840]}}}, 0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8834, 8402]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8840]}, 0x71: {l: {0x3B: {c: [10949, 824]}}}}}}}}}}}}}}}, 0x63: {l: {0x63: {l: {0x3B: {c: [8833]}, 0x65: {l: {0x71: {l: {0x3B: {c: [10928, 824]}}}}}}}}}, 0x70: {l: {0x3B: {c: [8837]}, 0x45: {l: {0x3B: {c: [10950, 824]}}}, 0x65: {l: {0x3B: {c: [8841]}}}, 0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8835, 8402]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8841]}, 0x71: {l: {0x3B: {c: [10950, 824]}}}}}}}}}}}}}}}}}}}, 0x74: {l: {0x67: {l: {0x6C: {l: {0x3B: {c: [8825]}}}}}, 0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [241]}}, c: [241]}}}}}}}, 0x6C: {l: {0x67: {l: {0x3B: {c: [8824]}}}}}, 0x72: {l: {0x69: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x3B: {c: [8938]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8940]}}}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x3B: {c: [8939]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8941]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x75: {l: {0x3B: {c: [957]}, 0x6D: {l: {0x3B: {c: [35]}, 0x65: {l: {0x72: {l: {0x6F: {l: {0x3B: {c: [8470]}}}}}}}, 0x73: {l: {0x70: {l: {0x3B: {c: [8199]}}}}}}}}}, 0x76: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [8781, 8402]}}}}}, 0x64: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8876]}}}}}}}}}, 0x44: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8877]}}}}}}}}}, 0x67: {l: {0x65: {l: {0x3B: {c: [8805, 8402]}}}, 0x74: {l: {0x3B: {c: [62, 8402]}}}}}, 0x48: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10500]}}}}}}}}}, 0x69: {l: {0x6E: {l: {0x66: {l: {0x69: {l: {0x6E: {l: {0x3B: {c: [10718]}}}}}}}}}}}, 0x6C: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10498]}}}}}}}, 0x65: {l: {0x3B: {c: [8804, 8402]}}}, 0x74: {l: {0x3B: {c: [60, 8402]}, 0x72: {l: {0x69: {l: {0x65: {l: {0x3B: {c: [8884, 8402]}}}}}}}}}}}, 0x72: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10499]}}}}}}}, 0x74: {l: {0x72: {l: {0x69: {l: {0x65: {l: {0x3B: {c: [8885, 8402]}}}}}}}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8764, 8402]}}}}}}}}}, 0x56: {l: {0x64: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8878]}}}}}}}}}, 0x44: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8879]}}}}}}}}}}}, 0x77: {l: {0x61: {l: {0x72: {l: {0x68: {l: {0x6B: {l: {0x3B: {c: [10531]}}}}}, 0x72: {l: {0x3B: {c: [8598]}, 0x6F: {l: {0x77: {l: {0x3B: {c: [8598]}}}}}}}}}}}, 0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8662]}}}}}}}, 0x6E: {l: {0x65: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10535]}}}}}}}}}}}}},
+ 0x4E: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [323]}}}}}}}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [327]}}}}}}}}}, 0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [325]}}}}}}}}}, 0x79: {l: {0x3B: {c: [1053]}}}}}, 0x65: {l: {0x67: {l: {0x61: {l: {0x74: {l: {0x69: {l: {0x76: {l: {0x65: {l: {0x4D: {l: {0x65: {l: {0x64: {l: {0x69: {l: {0x75: {l: {0x6D: {l: {0x53: {l: {0x70: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [8203]}}}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x68: {l: {0x69: {l: {0x63: {l: {0x6B: {l: {0x53: {l: {0x70: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [8203]}}}}}}}}}}}}}}}, 0x6E: {l: {0x53: {l: {0x70: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [8203]}}}}}}}}}}}}}}}}}}}, 0x56: {l: {0x65: {l: {0x72: {l: {0x79: {l: {0x54: {l: {0x68: {l: {0x69: {l: {0x6E: {l: {0x53: {l: {0x70: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [8203]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x74: {l: {0x65: {l: {0x64: {l: {0x47: {l: {0x72: {l: {0x65: {l: {0x61: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x47: {l: {0x72: {l: {0x65: {l: {0x61: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [8811]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x4C: {l: {0x65: {l: {0x73: {l: {0x73: {l: {0x4C: {l: {0x65: {l: {0x73: {l: {0x73: {l: {0x3B: {c: [8810]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x77: {l: {0x4C: {l: {0x69: {l: {0x6E: {l: {0x65: {l: {0x3B: {c: [10]}}}}}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120081]}}}}}, 0x4A: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1034]}}}}}}}, 0x6F: {l: {0x42: {l: {0x72: {l: {0x65: {l: {0x61: {l: {0x6B: {l: {0x3B: {c: [8288]}}}}}}}}}}}, 0x6E: {l: {0x42: {l: {0x72: {l: {0x65: {l: {0x61: {l: {0x6B: {l: {0x69: {l: {0x6E: {l: {0x67: {l: {0x53: {l: {0x70: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [160]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [8469]}}}}}, 0x74: {l: {0x3B: {c: [10988]}, 0x43: {l: {0x6F: {l: {0x6E: {l: {0x67: {l: {0x72: {l: {0x75: {l: {0x65: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [8802]}}}}}}}}}}}}}}}}}, 0x75: {l: {0x70: {l: {0x43: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [8813]}}}}}}}}}}}}}, 0x44: {l: {0x6F: {l: {0x75: {l: {0x62: {l: {0x6C: {l: {0x65: {l: {0x56: {l: {0x65: {l: {0x72: {l: {0x74: {l: {0x69: {l: {0x63: {l: {0x61: {l: {0x6C: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8742]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x45: {l: {0x6C: {l: {0x65: {l: {0x6D: {l: {0x65: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [8713]}}}}}}}}}}}}}, 0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8800]}, 0x54: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8770, 824]}}}}}}}}}}}}}}}}}}}, 0x78: {l: {0x69: {l: {0x73: {l: {0x74: {l: {0x73: {l: {0x3B: {c: [8708]}}}}}}}}}}}}}, 0x47: {l: {0x72: {l: {0x65: {l: {0x61: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [8815]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8817]}}}}}}}}}}}, 0x46: {l: {0x75: {l: {0x6C: {l: {0x6C: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8807, 824]}}}}}}}}}}}}}}}}}}}, 0x47: {l: {0x72: {l: {0x65: {l: {0x61: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [8811, 824]}}}}}}}}}}}}}}}, 0x4C: {l: {0x65: {l: {0x73: {l: {0x73: {l: {0x3B: {c: [8825]}}}}}}}}}, 0x53: {l: {0x6C: {l: {0x61: {l: {0x6E: {l: {0x74: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [10878, 824]}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8821]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x48: {l: {0x75: {l: {0x6D: {l: {0x70: {l: {0x44: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x48: {l: {0x75: {l: {0x6D: {l: {0x70: {l: {0x3B: {c: [8782, 824]}}}}}}}}}}}}}}}}}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8783, 824]}}}}}}}}}}}}}}}}}}}, 0x4C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x54: {l: {0x72: {l: {0x69: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10703, 824]}}}}}}}, 0x3B: {c: [8938]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8940]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x73: {l: {0x3B: {c: [8814]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8816]}}}}}}}}}}}, 0x47: {l: {0x72: {l: {0x65: {l: {0x61: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [8824]}}}}}}}}}}}}}}}, 0x4C: {l: {0x65: {l: {0x73: {l: {0x73: {l: {0x3B: {c: [8810, 824]}}}}}}}}}, 0x53: {l: {0x6C: {l: {0x61: {l: {0x6E: {l: {0x74: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [10877, 824]}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8820]}}}}}}}}}}}}}}}}}}}, 0x4E: {l: {0x65: {l: {0x73: {l: {0x74: {l: {0x65: {l: {0x64: {l: {0x47: {l: {0x72: {l: {0x65: {l: {0x61: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x47: {l: {0x72: {l: {0x65: {l: {0x61: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x3B: {c: [10914, 824]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x4C: {l: {0x65: {l: {0x73: {l: {0x73: {l: {0x4C: {l: {0x65: {l: {0x73: {l: {0x73: {l: {0x3B: {c: [10913, 824]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x50: {l: {0x72: {l: {0x65: {l: {0x63: {l: {0x65: {l: {0x64: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [8832]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [10927, 824]}}}}}}}}}}}, 0x53: {l: {0x6C: {l: {0x61: {l: {0x6E: {l: {0x74: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8928]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x52: {l: {0x65: {l: {0x76: {l: {0x65: {l: {0x72: {l: {0x73: {l: {0x65: {l: {0x45: {l: {0x6C: {l: {0x65: {l: {0x6D: {l: {0x65: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [8716]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x54: {l: {0x72: {l: {0x69: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10704, 824]}}}}}}}, 0x3B: {c: [8939]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8941]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x53: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x72: {l: {0x65: {l: {0x53: {l: {0x75: {l: {0x62: {l: {0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8847, 824]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8930]}}}}}}}}}}}}}}}}}}}, 0x70: {l: {0x65: {l: {0x72: {l: {0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8848, 824]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8931]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x75: {l: {0x62: {l: {0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8834, 8402]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8840]}}}}}}}}}}}}}}}}}}}, 0x63: {l: {0x63: {l: {0x65: {l: {0x65: {l: {0x64: {l: {0x73: {l: {0x3B: {c: [8833]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [10928, 824]}}}}}}}}}}}, 0x53: {l: {0x6C: {l: {0x61: {l: {0x6E: {l: {0x74: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8929]}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8831, 824]}}}}}}}}}}}}}}}}}}}}}}}, 0x70: {l: {0x65: {l: {0x72: {l: {0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8835, 8402]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8841]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8769]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8772]}}}}}}}}}}}, 0x46: {l: {0x75: {l: {0x6C: {l: {0x6C: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8775]}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8777]}}}}}}}}}}}}}}}}}}}}}, 0x56: {l: {0x65: {l: {0x72: {l: {0x74: {l: {0x69: {l: {0x63: {l: {0x61: {l: {0x6C: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8740]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119977]}}}}}}}, 0x74: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [209]}}, c: [209]}}}}}}}}}, 0x75: {l: {0x3B: {c: [925]}}}}},
+ 0x4F: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [211]}}, c: [211]}}}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [212]}}, c: [212]}}}}}, 0x79: {l: {0x3B: {c: [1054]}}}}}, 0x64: {l: {0x62: {l: {0x6C: {l: {0x61: {l: {0x63: {l: {0x3B: {c: [336]}}}}}}}}}}}, 0x45: {l: {0x6C: {l: {0x69: {l: {0x67: {l: {0x3B: {c: [338]}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120082]}}}}}, 0x67: {l: {0x72: {l: {0x61: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [210]}}, c: [210]}}}}}}}}}, 0x6D: {l: {0x61: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [332]}}}}}}}, 0x65: {l: {0x67: {l: {0x61: {l: {0x3B: {c: [937]}}}}}}}, 0x69: {l: {0x63: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [927]}}}}}}}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120134]}}}}}}}, 0x70: {l: {0x65: {l: {0x6E: {l: {0x43: {l: {0x75: {l: {0x72: {l: {0x6C: {l: {0x79: {l: {0x44: {l: {0x6F: {l: {0x75: {l: {0x62: {l: {0x6C: {l: {0x65: {l: {0x51: {l: {0x75: {l: {0x6F: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [8220]}}}}}}}}}}}}}}}}}}}}}}}, 0x51: {l: {0x75: {l: {0x6F: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [8216]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x72: {l: {0x3B: {c: [10836]}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119978]}}}}}, 0x6C: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [216]}}, c: [216]}}}}}}}}}, 0x74: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [213]}}, c: [213]}}}}}, 0x6D: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [10807]}}}}}}}}}}}, 0x75: {l: {0x6D: {l: {0x6C: {l: {0x3B: {c: [214]}}, c: [214]}}}}}, 0x76: {l: {0x65: {l: {0x72: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8254]}}}}}, 0x72: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [9182]}}}, 0x6B: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [9140]}}}}}}}}}}}}}}}, 0x50: {l: {0x61: {l: {0x72: {l: {0x65: {l: {0x6E: {l: {0x74: {l: {0x68: {l: {0x65: {l: {0x73: {l: {0x69: {l: {0x73: {l: {0x3B: {c: [9180]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},
+ 0x6F: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [243]}}, c: [243]}}}}}}}, 0x73: {l: {0x74: {l: {0x3B: {c: [8859]}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [244]}}, c: [244]}, 0x3B: {c: [8858]}}}}}, 0x79: {l: {0x3B: {c: [1086]}}}}}, 0x64: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8861]}}}}}}}, 0x62: {l: {0x6C: {l: {0x61: {l: {0x63: {l: {0x3B: {c: [337]}}}}}}}}}, 0x69: {l: {0x76: {l: {0x3B: {c: [10808]}}}}}, 0x6F: {l: {0x74: {l: {0x3B: {c: [8857]}}}}}, 0x73: {l: {0x6F: {l: {0x6C: {l: {0x64: {l: {0x3B: {c: [10684]}}}}}}}}}}}, 0x65: {l: {0x6C: {l: {0x69: {l: {0x67: {l: {0x3B: {c: [339]}}}}}}}}}, 0x66: {l: {0x63: {l: {0x69: {l: {0x72: {l: {0x3B: {c: [10687]}}}}}}}, 0x72: {l: {0x3B: {c: [120108]}}}}}, 0x67: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [731]}}}}}, 0x72: {l: {0x61: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [242]}}, c: [242]}}}}}}}, 0x74: {l: {0x3B: {c: [10689]}}}}}, 0x68: {l: {0x62: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10677]}}}}}}}, 0x6D: {l: {0x3B: {c: [937]}}}}}, 0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [8750]}}}}}}}, 0x6C: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8634]}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x3B: {c: [10686]}}}}}, 0x72: {l: {0x6F: {l: {0x73: {l: {0x73: {l: {0x3B: {c: [10683]}}}}}}}}}}}, 0x69: {l: {0x6E: {l: {0x65: {l: {0x3B: {c: [8254]}}}}}}}, 0x74: {l: {0x3B: {c: [10688]}}}}}, 0x6D: {l: {0x61: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [333]}}}}}}}, 0x65: {l: {0x67: {l: {0x61: {l: {0x3B: {c: [969]}}}}}}}, 0x69: {l: {0x63: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [959]}}}}}}}}}, 0x64: {l: {0x3B: {c: [10678]}}}, 0x6E: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8854]}}}}}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120160]}}}}}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10679]}}}}}, 0x65: {l: {0x72: {l: {0x70: {l: {0x3B: {c: [10681]}}}}}}}, 0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8853]}}}}}}}}}, 0x72: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8635]}}}}}}}, 0x3B: {c: [8744]}, 0x64: {l: {0x3B: {c: [10845]}, 0x65: {l: {0x72: {l: {0x3B: {c: [8500]}, 0x6F: {l: {0x66: {l: {0x3B: {c: [8500]}}}}}}}}}, 0x66: {l: {0x3B: {c: [170]}}, c: [170]}, 0x6D: {l: {0x3B: {c: [186]}}, c: [186]}}}, 0x69: {l: {0x67: {l: {0x6F: {l: {0x66: {l: {0x3B: {c: [8886]}}}}}}}}}, 0x6F: {l: {0x72: {l: {0x3B: {c: [10838]}}}}}, 0x73: {l: {0x6C: {l: {0x6F: {l: {0x70: {l: {0x65: {l: {0x3B: {c: [10839]}}}}}}}}}}}, 0x76: {l: {0x3B: {c: [10843]}}}}}, 0x53: {l: {0x3B: {c: [9416]}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [8500]}}}}}, 0x6C: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [248]}}, c: [248]}}}}}}}, 0x6F: {l: {0x6C: {l: {0x3B: {c: [8856]}}}}}}}, 0x74: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [245]}}, c: [245]}}}}}, 0x6D: {l: {0x65: {l: {0x73: {l: {0x61: {l: {0x73: {l: {0x3B: {c: [10806]}}}}}, 0x3B: {c: [8855]}}}}}}}}}}}, 0x75: {l: {0x6D: {l: {0x6C: {l: {0x3B: {c: [246]}}, c: [246]}}}}}, 0x76: {l: {0x62: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [9021]}}}}}}}}}}},
+ 0x70: {l: {0x61: {l: {0x72: {l: {0x61: {l: {0x3B: {c: [182]}, 0x6C: {l: {0x6C: {l: {0x65: {l: {0x6C: {l: {0x3B: {c: [8741]}}}}}}}}}}, c: [182]}, 0x3B: {c: [8741]}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [10995]}}}}}, 0x6C: {l: {0x3B: {c: [11005]}}}}}, 0x74: {l: {0x3B: {c: [8706]}}}}}}}, 0x63: {l: {0x79: {l: {0x3B: {c: [1087]}}}}}, 0x65: {l: {0x72: {l: {0x63: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [37]}}}}}}}, 0x69: {l: {0x6F: {l: {0x64: {l: {0x3B: {c: [46]}}}}}}}, 0x6D: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [8240]}}}}}}}, 0x70: {l: {0x3B: {c: [8869]}}}, 0x74: {l: {0x65: {l: {0x6E: {l: {0x6B: {l: {0x3B: {c: [8241]}}}}}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120109]}}}}}, 0x68: {l: {0x69: {l: {0x3B: {c: [966]}, 0x76: {l: {0x3B: {c: [981]}}}}}, 0x6D: {l: {0x6D: {l: {0x61: {l: {0x74: {l: {0x3B: {c: [8499]}}}}}}}}}, 0x6F: {l: {0x6E: {l: {0x65: {l: {0x3B: {c: [9742]}}}}}}}}}, 0x69: {l: {0x3B: {c: [960]}, 0x74: {l: {0x63: {l: {0x68: {l: {0x66: {l: {0x6F: {l: {0x72: {l: {0x6B: {l: {0x3B: {c: [8916]}}}}}}}}}}}}}}}, 0x76: {l: {0x3B: {c: [982]}}}}}, 0x6C: {l: {0x61: {l: {0x6E: {l: {0x63: {l: {0x6B: {l: {0x3B: {c: [8463]}, 0x68: {l: {0x3B: {c: [8462]}}}}}}}, 0x6B: {l: {0x76: {l: {0x3B: {c: [8463]}}}}}}}}}, 0x75: {l: {0x73: {l: {0x61: {l: {0x63: {l: {0x69: {l: {0x72: {l: {0x3B: {c: [10787]}}}}}}}}}, 0x62: {l: {0x3B: {c: [8862]}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x3B: {c: [10786]}}}}}}}, 0x3B: {c: [43]}, 0x64: {l: {0x6F: {l: {0x3B: {c: [8724]}}}, 0x75: {l: {0x3B: {c: [10789]}}}}}, 0x65: {l: {0x3B: {c: [10866]}}}, 0x6D: {l: {0x6E: {l: {0x3B: {c: [177]}}, c: [177]}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [10790]}}}}}}}, 0x74: {l: {0x77: {l: {0x6F: {l: {0x3B: {c: [10791]}}}}}}}}}}}}}, 0x6D: {l: {0x3B: {c: [177]}}}, 0x6F: {l: {0x69: {l: {0x6E: {l: {0x74: {l: {0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [10773]}}}}}}}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120161]}}}}}, 0x75: {l: {0x6E: {l: {0x64: {l: {0x3B: {c: [163]}}, c: [163]}}}}}}}, 0x72: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [10935]}}}}}, 0x3B: {c: [8826]}, 0x63: {l: {0x75: {l: {0x65: {l: {0x3B: {c: [8828]}}}}}}}, 0x65: {l: {0x63: {l: {0x61: {l: {0x70: {l: {0x70: {l: {0x72: {l: {0x6F: {l: {0x78: {l: {0x3B: {c: [10935]}}}}}}}}}}}}}, 0x3B: {c: [8826]}, 0x63: {l: {0x75: {l: {0x72: {l: {0x6C: {l: {0x79: {l: {0x65: {l: {0x71: {l: {0x3B: {c: [8828]}}}}}}}}}}}}}}}, 0x65: {l: {0x71: {l: {0x3B: {c: [10927]}}}}}, 0x6E: {l: {0x61: {l: {0x70: {l: {0x70: {l: {0x72: {l: {0x6F: {l: {0x78: {l: {0x3B: {c: [10937]}}}}}}}}}}}}}, 0x65: {l: {0x71: {l: {0x71: {l: {0x3B: {c: [10933]}}}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8936]}}}}}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8830]}}}}}}}}}, 0x3B: {c: [10927]}}}, 0x45: {l: {0x3B: {c: [10931]}}}, 0x69: {l: {0x6D: {l: {0x65: {l: {0x3B: {c: [8242]}, 0x73: {l: {0x3B: {c: [8473]}}}}}}}}}, 0x6E: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [10937]}}}}}, 0x45: {l: {0x3B: {c: [10933]}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8936]}}}}}}}}}, 0x6F: {l: {0x64: {l: {0x3B: {c: [8719]}}}, 0x66: {l: {0x61: {l: {0x6C: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [9006]}}}}}}}}}, 0x6C: {l: {0x69: {l: {0x6E: {l: {0x65: {l: {0x3B: {c: [8978]}}}}}}}}}, 0x73: {l: {0x75: {l: {0x72: {l: {0x66: {l: {0x3B: {c: [8979]}}}}}}}}}}}, 0x70: {l: {0x3B: {c: [8733]}, 0x74: {l: {0x6F: {l: {0x3B: {c: [8733]}}}}}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8830]}}}}}}}, 0x75: {l: {0x72: {l: {0x65: {l: {0x6C: {l: {0x3B: {c: [8880]}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [120005]}}}}}, 0x69: {l: {0x3B: {c: [968]}}}}}, 0x75: {l: {0x6E: {l: {0x63: {l: {0x73: {l: {0x70: {l: {0x3B: {c: [8200]}}}}}}}}}}}}},
+ 0x50: {l: {0x61: {l: {0x72: {l: {0x74: {l: {0x69: {l: {0x61: {l: {0x6C: {l: {0x44: {l: {0x3B: {c: [8706]}}}}}}}}}}}}}}}, 0x63: {l: {0x79: {l: {0x3B: {c: [1055]}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120083]}}}}}, 0x68: {l: {0x69: {l: {0x3B: {c: [934]}}}}}, 0x69: {l: {0x3B: {c: [928]}}}, 0x6C: {l: {0x75: {l: {0x73: {l: {0x4D: {l: {0x69: {l: {0x6E: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [177]}}}}}}}}}}}}}}}}}, 0x6F: {l: {0x69: {l: {0x6E: {l: {0x63: {l: {0x61: {l: {0x72: {l: {0x65: {l: {0x70: {l: {0x6C: {l: {0x61: {l: {0x6E: {l: {0x65: {l: {0x3B: {c: [8460]}}}}}}}}}}}}}}}}}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [8473]}}}}}}}, 0x72: {l: {0x3B: {c: [10939]}, 0x65: {l: {0x63: {l: {0x65: {l: {0x64: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [8826]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [10927]}}}}}}}}}}}, 0x53: {l: {0x6C: {l: {0x61: {l: {0x6E: {l: {0x74: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8828]}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8830]}}}}}}}}}}}}}}}}}}}}}}}, 0x69: {l: {0x6D: {l: {0x65: {l: {0x3B: {c: [8243]}}}}}}}, 0x6F: {l: {0x64: {l: {0x75: {l: {0x63: {l: {0x74: {l: {0x3B: {c: [8719]}}}}}}}}}, 0x70: {l: {0x6F: {l: {0x72: {l: {0x74: {l: {0x69: {l: {0x6F: {l: {0x6E: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8733]}}}}}, 0x3B: {c: [8759]}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119979]}}}}}, 0x69: {l: {0x3B: {c: [936]}}}}}}},
+ 0x51: {l: {0x66: {l: {0x72: {l: {0x3B: {c: [120084]}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [8474]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119980]}}}}}}}, 0x55: {l: {0x4F: {l: {0x54: {l: {0x3B: {c: [34]}}, c: [34]}}}}}}},
+ 0x71: {l: {0x66: {l: {0x72: {l: {0x3B: {c: [120110]}}}}}, 0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [10764]}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120162]}}}}}}}, 0x70: {l: {0x72: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x3B: {c: [8279]}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [120006]}}}}}}}, 0x75: {l: {0x61: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x6E: {l: {0x69: {l: {0x6F: {l: {0x6E: {l: {0x73: {l: {0x3B: {c: [8461]}}}}}}}}}}}}}}}, 0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [10774]}}}}}}}}}}}, 0x65: {l: {0x73: {l: {0x74: {l: {0x3B: {c: [63]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8799]}}}}}}}}}}}, 0x6F: {l: {0x74: {l: {0x3B: {c: [34]}}, c: [34]}}}}}}},
+ 0x72: {l: {0x41: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8667]}}}}}}}, 0x72: {l: {0x72: {l: {0x3B: {c: [8658]}}}}}, 0x74: {l: {0x61: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [10524]}}}}}}}}}}}, 0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [8765, 817]}}}, 0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [341]}}}}}}}}}, 0x64: {l: {0x69: {l: {0x63: {l: {0x3B: {c: [8730]}}}}}}}, 0x65: {l: {0x6D: {l: {0x70: {l: {0x74: {l: {0x79: {l: {0x76: {l: {0x3B: {c: [10675]}}}}}}}}}}}}}, 0x6E: {l: {0x67: {l: {0x3B: {c: [10217]}, 0x64: {l: {0x3B: {c: [10642]}}}, 0x65: {l: {0x3B: {c: [10661]}}}, 0x6C: {l: {0x65: {l: {0x3B: {c: [10217]}}}}}}}}}, 0x71: {l: {0x75: {l: {0x6F: {l: {0x3B: {c: [187]}}, c: [187]}}}}}, 0x72: {l: {0x72: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [10613]}}}}}, 0x62: {l: {0x3B: {c: [8677]}, 0x66: {l: {0x73: {l: {0x3B: {c: [10528]}}}}}}}, 0x63: {l: {0x3B: {c: [10547]}}}, 0x3B: {c: [8594]}, 0x66: {l: {0x73: {l: {0x3B: {c: [10526]}}}}}, 0x68: {l: {0x6B: {l: {0x3B: {c: [8618]}}}}}, 0x6C: {l: {0x70: {l: {0x3B: {c: [8620]}}}}}, 0x70: {l: {0x6C: {l: {0x3B: {c: [10565]}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [10612]}}}}}}}, 0x74: {l: {0x6C: {l: {0x3B: {c: [8611]}}}}}, 0x77: {l: {0x3B: {c: [8605]}}}}}}}, 0x74: {l: {0x61: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [10522]}}}}}}}, 0x69: {l: {0x6F: {l: {0x3B: {c: [8758]}, 0x6E: {l: {0x61: {l: {0x6C: {l: {0x73: {l: {0x3B: {c: [8474]}}}}}}}}}}}}}}}}}, 0x62: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10509]}}}}}}}, 0x62: {l: {0x72: {l: {0x6B: {l: {0x3B: {c: [10099]}}}}}}}, 0x72: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [125]}}}, 0x6B: {l: {0x3B: {c: [93]}}}}}}}, 0x6B: {l: {0x65: {l: {0x3B: {c: [10636]}}}, 0x73: {l: {0x6C: {l: {0x64: {l: {0x3B: {c: [10638]}}}, 0x75: {l: {0x3B: {c: [10640]}}}}}}}}}}}}}, 0x42: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10511]}}}}}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [345]}}}}}}}}}, 0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [343]}}}}}}}, 0x69: {l: {0x6C: {l: {0x3B: {c: [8969]}}}}}}}, 0x75: {l: {0x62: {l: {0x3B: {c: [125]}}}}}, 0x79: {l: {0x3B: {c: [1088]}}}}}, 0x64: {l: {0x63: {l: {0x61: {l: {0x3B: {c: [10551]}}}}}, 0x6C: {l: {0x64: {l: {0x68: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10601]}}}}}}}}}}}, 0x71: {l: {0x75: {l: {0x6F: {l: {0x3B: {c: [8221]}, 0x72: {l: {0x3B: {c: [8221]}}}}}}}}}, 0x73: {l: {0x68: {l: {0x3B: {c: [8627]}}}}}}}, 0x65: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8476]}, 0x69: {l: {0x6E: {l: {0x65: {l: {0x3B: {c: [8475]}}}}}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x74: {l: {0x3B: {c: [8476]}}}}}}}}}, 0x73: {l: {0x3B: {c: [8477]}}}}}}}, 0x63: {l: {0x74: {l: {0x3B: {c: [9645]}}}}}, 0x67: {l: {0x3B: {c: [174]}}, c: [174]}}}, 0x66: {l: {0x69: {l: {0x73: {l: {0x68: {l: {0x74: {l: {0x3B: {c: [10621]}}}}}}}}}, 0x6C: {l: {0x6F: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [8971]}}}}}}}}}, 0x72: {l: {0x3B: {c: [120111]}}}}}, 0x48: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10596]}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x64: {l: {0x3B: {c: [8641]}}}, 0x75: {l: {0x3B: {c: [8640]}, 0x6C: {l: {0x3B: {c: [10604]}}}}}}}}}, 0x6F: {l: {0x3B: {c: [961]}, 0x76: {l: {0x3B: {c: [1009]}}}}}}}, 0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8594]}, 0x74: {l: {0x61: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [8611]}}}}}}}}}}}}}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x70: {l: {0x6F: {l: {0x6F: {l: {0x6E: {l: {0x64: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x3B: {c: [8641]}}}}}}}}}, 0x75: {l: {0x70: {l: {0x3B: {c: [8640]}}}}}}}}}}}}}}}}}}}, 0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x73: {l: {0x3B: {c: [8644]}}}}}}}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x70: {l: {0x6F: {l: {0x6F: {l: {0x6E: {l: {0x73: {l: {0x3B: {c: [8652]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x73: {l: {0x3B: {c: [8649]}}}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x71: {l: {0x75: {l: {0x69: {l: {0x67: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8605]}}}}}}}}}}}}}}}}}}}}}, 0x74: {l: {0x68: {l: {0x72: {l: {0x65: {l: {0x65: {l: {0x74: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [8908]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x6E: {l: {0x67: {l: {0x3B: {c: [730]}}}}}, 0x73: {l: {0x69: {l: {0x6E: {l: {0x67: {l: {0x64: {l: {0x6F: {l: {0x74: {l: {0x73: {l: {0x65: {l: {0x71: {l: {0x3B: {c: [8787]}}}}}}}}}}}}}}}}}}}}}}}, 0x6C: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8644]}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8652]}}}}}}}, 0x6D: {l: {0x3B: {c: [8207]}}}}}, 0x6D: {l: {0x6F: {l: {0x75: {l: {0x73: {l: {0x74: {l: {0x61: {l: {0x63: {l: {0x68: {l: {0x65: {l: {0x3B: {c: [9137]}}}}}}}}}, 0x3B: {c: [9137]}}}}}}}}}}}, 0x6E: {l: {0x6D: {l: {0x69: {l: {0x64: {l: {0x3B: {c: [10990]}}}}}}}}}, 0x6F: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x3B: {c: [10221]}}}}}, 0x72: {l: {0x72: {l: {0x3B: {c: [8702]}}}}}}}, 0x62: {l: {0x72: {l: {0x6B: {l: {0x3B: {c: [10215]}}}}}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10630]}}}}}, 0x66: {l: {0x3B: {c: [120163]}}}, 0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [10798]}}}}}}}}}, 0x74: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [10805]}}}}}}}}}}}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [41]}, 0x67: {l: {0x74: {l: {0x3B: {c: [10644]}}}}}}}}}, 0x70: {l: {0x6F: {l: {0x6C: {l: {0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [10770]}}}}}}}}}}}}}}}, 0x72: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8649]}}}}}}}}}, 0x73: {l: {0x61: {l: {0x71: {l: {0x75: {l: {0x6F: {l: {0x3B: {c: [8250]}}}}}}}}}, 0x63: {l: {0x72: {l: {0x3B: {c: [120007]}}}}}, 0x68: {l: {0x3B: {c: [8625]}}}, 0x71: {l: {0x62: {l: {0x3B: {c: [93]}}}, 0x75: {l: {0x6F: {l: {0x3B: {c: [8217]}, 0x72: {l: {0x3B: {c: [8217]}}}}}}}}}}}, 0x74: {l: {0x68: {l: {0x72: {l: {0x65: {l: {0x65: {l: {0x3B: {c: [8908]}}}}}}}}}, 0x69: {l: {0x6D: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [8906]}}}}}}}}}, 0x72: {l: {0x69: {l: {0x3B: {c: [9657]}, 0x65: {l: {0x3B: {c: [8885]}}}, 0x66: {l: {0x3B: {c: [9656]}}}, 0x6C: {l: {0x74: {l: {0x72: {l: {0x69: {l: {0x3B: {c: [10702]}}}}}}}}}}}}}}}, 0x75: {l: {0x6C: {l: {0x75: {l: {0x68: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10600]}}}}}}}}}}}}}, 0x78: {l: {0x3B: {c: [8478]}}}}},
+ 0x52: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [340]}}}}}}}}}, 0x6E: {l: {0x67: {l: {0x3B: {c: [10219]}}}}}, 0x72: {l: {0x72: {l: {0x3B: {c: [8608]}, 0x74: {l: {0x6C: {l: {0x3B: {c: [10518]}}}}}}}}}}}, 0x42: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10512]}}}}}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [344]}}}}}}}}}, 0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [342]}}}}}}}}}, 0x79: {l: {0x3B: {c: [1056]}}}}}, 0x65: {l: {0x3B: {c: [8476]}, 0x76: {l: {0x65: {l: {0x72: {l: {0x73: {l: {0x65: {l: {0x45: {l: {0x6C: {l: {0x65: {l: {0x6D: {l: {0x65: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [8715]}}}}}}}}}}}}}, 0x71: {l: {0x75: {l: {0x69: {l: {0x6C: {l: {0x69: {l: {0x62: {l: {0x72: {l: {0x69: {l: {0x75: {l: {0x6D: {l: {0x3B: {c: [8651]}}}}}}}}}}}}}}}}}}}}}}}, 0x55: {l: {0x70: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x69: {l: {0x6C: {l: {0x69: {l: {0x62: {l: {0x72: {l: {0x69: {l: {0x75: {l: {0x6D: {l: {0x3B: {c: [10607]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x45: {l: {0x47: {l: {0x3B: {c: [174]}}, c: [174]}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [8476]}}}}}, 0x68: {l: {0x6F: {l: {0x3B: {c: [929]}}}}}, 0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x41: {l: {0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x42: {l: {0x72: {l: {0x61: {l: {0x63: {l: {0x6B: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [10217]}}}}}}}}}}}}}}}}}}}}}}}, 0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8677]}}}}}}}, 0x3B: {c: [8594]}, 0x4C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8644]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8658]}}}}}}}}}}}, 0x43: {l: {0x65: {l: {0x69: {l: {0x6C: {l: {0x69: {l: {0x6E: {l: {0x67: {l: {0x3B: {c: [8969]}}}}}}}}}}}}}}}, 0x44: {l: {0x6F: {l: {0x75: {l: {0x62: {l: {0x6C: {l: {0x65: {l: {0x42: {l: {0x72: {l: {0x61: {l: {0x63: {l: {0x6B: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [10215]}}}}}}}}}}}}}}}}}}}}}}}, 0x77: {l: {0x6E: {l: {0x54: {l: {0x65: {l: {0x65: {l: {0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [10589]}}}}}}}}}}}}}}}}}}}, 0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10581]}}}}}}}, 0x3B: {c: [8642]}}}}}}}}}}}}}}}}}}}}}, 0x46: {l: {0x6C: {l: {0x6F: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [8971]}}}}}}}}}}}, 0x54: {l: {0x65: {l: {0x65: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8614]}}}}}}}}}}}, 0x3B: {c: [8866]}, 0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [10587]}}}}}}}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10704]}}}}}}}, 0x3B: {c: [8883]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8885]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x55: {l: {0x70: {l: {0x44: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [10575]}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x65: {l: {0x65: {l: {0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [10588]}}}}}}}}}}}}}}}}}}}, 0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10580]}}}}}}}, 0x3B: {c: [8638]}}}}}}}}}}}}}}}}}, 0x56: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10579]}}}}}}}, 0x3B: {c: [8640]}}}}}}}}}}}}}}}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [8477]}}}}}, 0x75: {l: {0x6E: {l: {0x64: {l: {0x49: {l: {0x6D: {l: {0x70: {l: {0x6C: {l: {0x69: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [10608]}}}}}}}}}}}}}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8667]}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [8475]}}}}}, 0x68: {l: {0x3B: {c: [8625]}}}}}, 0x75: {l: {0x6C: {l: {0x65: {l: {0x44: {l: {0x65: {l: {0x6C: {l: {0x61: {l: {0x79: {l: {0x65: {l: {0x64: {l: {0x3B: {c: [10740]}}}}}}}}}}}}}}}}}}}}}}},
+ 0x53: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [346]}}}}}}}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [352]}}}}}}}}}, 0x3B: {c: [10940]}, 0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [350]}}}}}}}}}, 0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [348]}}}}}}}, 0x79: {l: {0x3B: {c: [1057]}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120086]}}}}}, 0x48: {l: {0x43: {l: {0x48: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1065]}}}}}}}}}, 0x63: {l: {0x79: {l: {0x3B: {c: [1064]}}}}}}}, 0x68: {l: {0x6F: {l: {0x72: {l: {0x74: {l: {0x44: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8595]}}}}}}}}}}}}}}}}}}}, 0x4C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8592]}}}}}}}}}}}}}}}}}}}, 0x52: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8594]}}}}}}}}}}}}}}}}}}}}}, 0x55: {l: {0x70: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8593]}}}}}}}}}}}}}}}}}}}}}}}, 0x69: {l: {0x67: {l: {0x6D: {l: {0x61: {l: {0x3B: {c: [931]}}}}}}}}}, 0x6D: {l: {0x61: {l: {0x6C: {l: {0x6C: {l: {0x43: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x6C: {l: {0x65: {l: {0x3B: {c: [8728]}}}}}}}}}}}}}}}}}}}}}, 0x4F: {l: {0x46: {l: {0x54: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1068]}}}}}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120138]}}}}}}}, 0x71: {l: {0x72: {l: {0x74: {l: {0x3B: {c: [8730]}}}}}, 0x75: {l: {0x61: {l: {0x72: {l: {0x65: {l: {0x3B: {c: [9633]}, 0x49: {l: {0x6E: {l: {0x74: {l: {0x65: {l: {0x72: {l: {0x73: {l: {0x65: {l: {0x63: {l: {0x74: {l: {0x69: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [8851]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x53: {l: {0x75: {l: {0x62: {l: {0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8847]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8849]}}}}}}}}}}}}}}}}}}}, 0x70: {l: {0x65: {l: {0x72: {l: {0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8848]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8850]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x55: {l: {0x6E: {l: {0x69: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [8852]}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119982]}}}}}}}, 0x74: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8902]}}}}}}}, 0x75: {l: {0x62: {l: {0x3B: {c: [8912]}, 0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8912]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8838]}}}}}}}}}}}}}}}}}}}, 0x63: {l: {0x63: {l: {0x65: {l: {0x65: {l: {0x64: {l: {0x73: {l: {0x3B: {c: [8827]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [10928]}}}}}}}}}}}, 0x53: {l: {0x6C: {l: {0x61: {l: {0x6E: {l: {0x74: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8829]}}}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8831]}}}}}}}}}}}}}}}}}}}}}, 0x68: {l: {0x54: {l: {0x68: {l: {0x61: {l: {0x74: {l: {0x3B: {c: [8715]}}}}}}}}}}}}}, 0x6D: {l: {0x3B: {c: [8721]}}}, 0x70: {l: {0x3B: {c: [8913]}, 0x65: {l: {0x72: {l: {0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8835]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8839]}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8913]}}}}}}}}}}}}},
+ 0x73: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [347]}}}}}}}}}}}, 0x62: {l: {0x71: {l: {0x75: {l: {0x6F: {l: {0x3B: {c: [8218]}}}}}}}}}, 0x63: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [10936]}}}, 0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [353]}}}}}}}}}, 0x3B: {c: [8827]}, 0x63: {l: {0x75: {l: {0x65: {l: {0x3B: {c: [8829]}}}}}}}, 0x65: {l: {0x3B: {c: [10928]}, 0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [351]}}}}}}}}}, 0x45: {l: {0x3B: {c: [10932]}}}, 0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [349]}}}}}}}, 0x6E: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [10938]}}}}}, 0x45: {l: {0x3B: {c: [10934]}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8937]}}}}}}}}}, 0x70: {l: {0x6F: {l: {0x6C: {l: {0x69: {l: {0x6E: {l: {0x74: {l: {0x3B: {c: [10771]}}}}}}}}}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8831]}}}}}}}, 0x79: {l: {0x3B: {c: [1089]}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x62: {l: {0x3B: {c: [8865]}}}, 0x3B: {c: [8901]}, 0x65: {l: {0x3B: {c: [10854]}}}}}}}}}, 0x65: {l: {0x61: {l: {0x72: {l: {0x68: {l: {0x6B: {l: {0x3B: {c: [10533]}}}}}, 0x72: {l: {0x3B: {c: [8600]}, 0x6F: {l: {0x77: {l: {0x3B: {c: [8600]}}}}}}}}}}}, 0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8664]}}}}}}}, 0x63: {l: {0x74: {l: {0x3B: {c: [167]}}, c: [167]}}}, 0x6D: {l: {0x69: {l: {0x3B: {c: [59]}}}}}, 0x73: {l: {0x77: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10537]}}}}}}}}}, 0x74: {l: {0x6D: {l: {0x69: {l: {0x6E: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8726]}}}}}}}}}, 0x6E: {l: {0x3B: {c: [8726]}}}}}}}, 0x78: {l: {0x74: {l: {0x3B: {c: [10038]}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120112]}, 0x6F: {l: {0x77: {l: {0x6E: {l: {0x3B: {c: [8994]}}}}}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x70: {l: {0x3B: {c: [9839]}}}}}}}, 0x63: {l: {0x68: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1097]}}}}}}}, 0x79: {l: {0x3B: {c: [1096]}}}}}, 0x6F: {l: {0x72: {l: {0x74: {l: {0x6D: {l: {0x69: {l: {0x64: {l: {0x3B: {c: [8739]}}}}}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x61: {l: {0x6C: {l: {0x6C: {l: {0x65: {l: {0x6C: {l: {0x3B: {c: [8741]}}}}}}}}}}}}}}}}}}}}}}}, 0x79: {l: {0x3B: {c: [173]}}, c: [173]}}}, 0x69: {l: {0x67: {l: {0x6D: {l: {0x61: {l: {0x3B: {c: [963]}, 0x66: {l: {0x3B: {c: [962]}}}, 0x76: {l: {0x3B: {c: [962]}}}}}}}}}, 0x6D: {l: {0x3B: {c: [8764]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10858]}}}}}}}, 0x65: {l: {0x3B: {c: [8771]}, 0x71: {l: {0x3B: {c: [8771]}}}}}, 0x67: {l: {0x3B: {c: [10910]}, 0x45: {l: {0x3B: {c: [10912]}}}}}, 0x6C: {l: {0x3B: {c: [10909]}, 0x45: {l: {0x3B: {c: [10911]}}}}}, 0x6E: {l: {0x65: {l: {0x3B: {c: [8774]}}}}}, 0x70: {l: {0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [10788]}}}}}}}}}, 0x72: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10610]}}}}}}}}}}}}}, 0x6C: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8592]}}}}}}}}}, 0x6D: {l: {0x61: {l: {0x6C: {l: {0x6C: {l: {0x73: {l: {0x65: {l: {0x74: {l: {0x6D: {l: {0x69: {l: {0x6E: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8726]}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x68: {l: {0x70: {l: {0x3B: {c: [10803]}}}}}}}}}, 0x65: {l: {0x70: {l: {0x61: {l: {0x72: {l: {0x73: {l: {0x6C: {l: {0x3B: {c: [10724]}}}}}}}}}}}}}, 0x69: {l: {0x64: {l: {0x3B: {c: [8739]}}}, 0x6C: {l: {0x65: {l: {0x3B: {c: [8995]}}}}}}}, 0x74: {l: {0x3B: {c: [10922]}, 0x65: {l: {0x3B: {c: [10924]}, 0x73: {l: {0x3B: {c: [10924, 65024]}}}}}}}}}, 0x6F: {l: {0x66: {l: {0x74: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1100]}}}}}}}}}, 0x6C: {l: {0x62: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [9023]}}}}}, 0x3B: {c: [10692]}}}, 0x3B: {c: [47]}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120164]}}}}}}}, 0x70: {l: {0x61: {l: {0x64: {l: {0x65: {l: {0x73: {l: {0x3B: {c: [9824]}, 0x75: {l: {0x69: {l: {0x74: {l: {0x3B: {c: [9824]}}}}}}}}}}}}}, 0x72: {l: {0x3B: {c: [8741]}}}}}}}, 0x71: {l: {0x63: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [8851]}, 0x73: {l: {0x3B: {c: [8851, 65024]}}}}}}}, 0x75: {l: {0x70: {l: {0x3B: {c: [8852]}, 0x73: {l: {0x3B: {c: [8852, 65024]}}}}}}}}}, 0x73: {l: {0x75: {l: {0x62: {l: {0x3B: {c: [8847]}, 0x65: {l: {0x3B: {c: [8849]}}}, 0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8847]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8849]}}}}}}}}}}}}}, 0x70: {l: {0x3B: {c: [8848]}, 0x65: {l: {0x3B: {c: [8850]}}}, 0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8848]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8850]}}}}}}}}}}}}}}}}}, 0x75: {l: {0x61: {l: {0x72: {l: {0x65: {l: {0x3B: {c: [9633]}}}, 0x66: {l: {0x3B: {c: [9642]}}}}}}}, 0x3B: {c: [9633]}, 0x66: {l: {0x3B: {c: [9642]}}}}}}}, 0x72: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8594]}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [120008]}}}}}, 0x65: {l: {0x74: {l: {0x6D: {l: {0x6E: {l: {0x3B: {c: [8726]}}}}}}}}}, 0x6D: {l: {0x69: {l: {0x6C: {l: {0x65: {l: {0x3B: {c: [8995]}}}}}}}}}, 0x74: {l: {0x61: {l: {0x72: {l: {0x66: {l: {0x3B: {c: [8902]}}}}}}}}}}}, 0x74: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [9734]}, 0x66: {l: {0x3B: {c: [9733]}}}}}}}, 0x72: {l: {0x61: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x65: {l: {0x70: {l: {0x73: {l: {0x69: {l: {0x6C: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [1013]}}}}}}}}}}}}}}}, 0x70: {l: {0x68: {l: {0x69: {l: {0x3B: {c: [981]}}}}}}}}}}}}}}}}}, 0x6E: {l: {0x73: {l: {0x3B: {c: [175]}}}}}}}}}, 0x75: {l: {0x62: {l: {0x3B: {c: [8834]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10941]}}}}}}}, 0x45: {l: {0x3B: {c: [10949]}}}, 0x65: {l: {0x3B: {c: [8838]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10947]}}}}}}}}}, 0x6D: {l: {0x75: {l: {0x6C: {l: {0x74: {l: {0x3B: {c: [10945]}}}}}}}}}, 0x6E: {l: {0x45: {l: {0x3B: {c: [10955]}}}, 0x65: {l: {0x3B: {c: [8842]}}}}}, 0x70: {l: {0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [10943]}}}}}}}}}, 0x72: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10617]}}}}}}}}}, 0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8834]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8838]}, 0x71: {l: {0x3B: {c: [10949]}}}}}}}, 0x6E: {l: {0x65: {l: {0x71: {l: {0x3B: {c: [8842]}, 0x71: {l: {0x3B: {c: [10955]}}}}}}}}}}}}}, 0x69: {l: {0x6D: {l: {0x3B: {c: [10951]}}}}}, 0x75: {l: {0x62: {l: {0x3B: {c: [10965]}}}, 0x70: {l: {0x3B: {c: [10963]}}}}}}}}}, 0x63: {l: {0x63: {l: {0x61: {l: {0x70: {l: {0x70: {l: {0x72: {l: {0x6F: {l: {0x78: {l: {0x3B: {c: [10936]}}}}}}}}}}}}}, 0x3B: {c: [8827]}, 0x63: {l: {0x75: {l: {0x72: {l: {0x6C: {l: {0x79: {l: {0x65: {l: {0x71: {l: {0x3B: {c: [8829]}}}}}}}}}}}}}}}, 0x65: {l: {0x71: {l: {0x3B: {c: [10928]}}}}}, 0x6E: {l: {0x61: {l: {0x70: {l: {0x70: {l: {0x72: {l: {0x6F: {l: {0x78: {l: {0x3B: {c: [10938]}}}}}}}}}}}}}, 0x65: {l: {0x71: {l: {0x71: {l: {0x3B: {c: [10934]}}}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8937]}}}}}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8831]}}}}}}}}}}}, 0x6D: {l: {0x3B: {c: [8721]}}}, 0x6E: {l: {0x67: {l: {0x3B: {c: [9834]}}}}}, 0x70: {l: {0x31: {l: {0x3B: {c: [185]}}, c: [185]}, 0x32: {l: {0x3B: {c: [178]}}, c: [178]}, 0x33: {l: {0x3B: {c: [179]}}, c: [179]}, 0x3B: {c: [8835]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10942]}}}}}, 0x73: {l: {0x75: {l: {0x62: {l: {0x3B: {c: [10968]}}}}}}}}}, 0x45: {l: {0x3B: {c: [10950]}}}, 0x65: {l: {0x3B: {c: [8839]}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10948]}}}}}}}}}, 0x68: {l: {0x73: {l: {0x6F: {l: {0x6C: {l: {0x3B: {c: [10185]}}}}}, 0x75: {l: {0x62: {l: {0x3B: {c: [10967]}}}}}}}}}, 0x6C: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10619]}}}}}}}}}, 0x6D: {l: {0x75: {l: {0x6C: {l: {0x74: {l: {0x3B: {c: [10946]}}}}}}}}}, 0x6E: {l: {0x45: {l: {0x3B: {c: [10956]}}}, 0x65: {l: {0x3B: {c: [8843]}}}}}, 0x70: {l: {0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [10944]}}}}}}}}}, 0x73: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8835]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8839]}, 0x71: {l: {0x3B: {c: [10950]}}}}}}}, 0x6E: {l: {0x65: {l: {0x71: {l: {0x3B: {c: [8843]}, 0x71: {l: {0x3B: {c: [10956]}}}}}}}}}}}}}, 0x69: {l: {0x6D: {l: {0x3B: {c: [10952]}}}}}, 0x75: {l: {0x62: {l: {0x3B: {c: [10964]}}}, 0x70: {l: {0x3B: {c: [10966]}}}}}}}}}}}, 0x77: {l: {0x61: {l: {0x72: {l: {0x68: {l: {0x6B: {l: {0x3B: {c: [10534]}}}}}, 0x72: {l: {0x3B: {c: [8601]}, 0x6F: {l: {0x77: {l: {0x3B: {c: [8601]}}}}}}}}}}}, 0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8665]}}}}}}}, 0x6E: {l: {0x77: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10538]}}}}}}}}}}}, 0x7A: {l: {0x6C: {l: {0x69: {l: {0x67: {l: {0x3B: {c: [223]}}, c: [223]}}}}}}}}},
+ 0x54: {l: {0x61: {l: {0x62: {l: {0x3B: {c: [9]}}}, 0x75: {l: {0x3B: {c: [932]}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [356]}}}}}}}}}, 0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [354]}}}}}}}}}, 0x79: {l: {0x3B: {c: [1058]}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120087]}}}}}, 0x68: {l: {0x65: {l: {0x72: {l: {0x65: {l: {0x66: {l: {0x6F: {l: {0x72: {l: {0x65: {l: {0x3B: {c: [8756]}}}}}}}}}}}}}, 0x74: {l: {0x61: {l: {0x3B: {c: [920]}}}}}}}, 0x69: {l: {0x63: {l: {0x6B: {l: {0x53: {l: {0x70: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [8287, 8202]}}}}}}}}}}}}}}}, 0x6E: {l: {0x53: {l: {0x70: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [8201]}}}}}}}}}}}}}}}}}, 0x48: {l: {0x4F: {l: {0x52: {l: {0x4E: {l: {0x3B: {c: [222]}}, c: [222]}}}}}}}, 0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8764]}, 0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8771]}}}}}}}}}}}, 0x46: {l: {0x75: {l: {0x6C: {l: {0x6C: {l: {0x45: {l: {0x71: {l: {0x75: {l: {0x61: {l: {0x6C: {l: {0x3B: {c: [8773]}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8776]}}}}}}}}}}}}}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120139]}}}}}}}, 0x52: {l: {0x41: {l: {0x44: {l: {0x45: {l: {0x3B: {c: [8482]}}}}}}}}}, 0x72: {l: {0x69: {l: {0x70: {l: {0x6C: {l: {0x65: {l: {0x44: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8411]}}}}}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119983]}}}}}, 0x74: {l: {0x72: {l: {0x6F: {l: {0x6B: {l: {0x3B: {c: [358]}}}}}}}}}}}, 0x53: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1062]}}}}}, 0x48: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1035]}}}}}}}}}}},
+ 0x74: {l: {0x61: {l: {0x72: {l: {0x67: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [8982]}}}}}}}}}, 0x75: {l: {0x3B: {c: [964]}}}}}, 0x62: {l: {0x72: {l: {0x6B: {l: {0x3B: {c: [9140]}}}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [357]}}}}}}}}}, 0x65: {l: {0x64: {l: {0x69: {l: {0x6C: {l: {0x3B: {c: [355]}}}}}}}}}, 0x79: {l: {0x3B: {c: [1090]}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8411]}}}}}}}, 0x65: {l: {0x6C: {l: {0x72: {l: {0x65: {l: {0x63: {l: {0x3B: {c: [8981]}}}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120113]}}}}}, 0x68: {l: {0x65: {l: {0x72: {l: {0x65: {l: {0x34: {l: {0x3B: {c: [8756]}}}, 0x66: {l: {0x6F: {l: {0x72: {l: {0x65: {l: {0x3B: {c: [8756]}}}}}}}}}}}}}, 0x74: {l: {0x61: {l: {0x3B: {c: [952]}, 0x73: {l: {0x79: {l: {0x6D: {l: {0x3B: {c: [977]}}}}}}}, 0x76: {l: {0x3B: {c: [977]}}}}}}}}}, 0x69: {l: {0x63: {l: {0x6B: {l: {0x61: {l: {0x70: {l: {0x70: {l: {0x72: {l: {0x6F: {l: {0x78: {l: {0x3B: {c: [8776]}}}}}}}}}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8764]}}}}}}}}}}}, 0x6E: {l: {0x73: {l: {0x70: {l: {0x3B: {c: [8201]}}}}}}}}}, 0x6B: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [8776]}}}}}, 0x73: {l: {0x69: {l: {0x6D: {l: {0x3B: {c: [8764]}}}}}}}}}, 0x6F: {l: {0x72: {l: {0x6E: {l: {0x3B: {c: [254]}}, c: [254]}}}}}}}, 0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [732]}}}}}}}, 0x6D: {l: {0x65: {l: {0x73: {l: {0x62: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10801]}}}}}, 0x3B: {c: [8864]}}}, 0x3B: {c: [215]}, 0x64: {l: {0x3B: {c: [10800]}}}}, c: [215]}}}}}, 0x6E: {l: {0x74: {l: {0x3B: {c: [8749]}}}}}}}, 0x6F: {l: {0x65: {l: {0x61: {l: {0x3B: {c: [10536]}}}}}, 0x70: {l: {0x62: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [9014]}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x3B: {c: [10993]}}}}}}}, 0x3B: {c: [8868]}, 0x66: {l: {0x3B: {c: [120165]}, 0x6F: {l: {0x72: {l: {0x6B: {l: {0x3B: {c: [10970]}}}}}}}}}}}, 0x73: {l: {0x61: {l: {0x3B: {c: [10537]}}}}}}}, 0x70: {l: {0x72: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x3B: {c: [8244]}}}}}}}}}}}, 0x72: {l: {0x61: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8482]}}}}}}}, 0x69: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x3B: {c: [9653]}, 0x64: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x3B: {c: [9663]}}}}}}}}}, 0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x3B: {c: [9667]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8884]}}}}}}}}}}}}}, 0x71: {l: {0x3B: {c: [8796]}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x3B: {c: [9657]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8885]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [9708]}}}}}}}, 0x65: {l: {0x3B: {c: [8796]}}}, 0x6D: {l: {0x69: {l: {0x6E: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [10810]}}}}}}}}}}}, 0x70: {l: {0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [10809]}}}}}}}}}, 0x73: {l: {0x62: {l: {0x3B: {c: [10701]}}}}}, 0x74: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x3B: {c: [10811]}}}}}}}}}}}, 0x70: {l: {0x65: {l: {0x7A: {l: {0x69: {l: {0x75: {l: {0x6D: {l: {0x3B: {c: [9186]}}}}}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [120009]}}}, 0x79: {l: {0x3B: {c: [1094]}}}}}, 0x68: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1115]}}}}}}}, 0x74: {l: {0x72: {l: {0x6F: {l: {0x6B: {l: {0x3B: {c: [359]}}}}}}}}}}}, 0x77: {l: {0x69: {l: {0x78: {l: {0x74: {l: {0x3B: {c: [8812]}}}}}}}, 0x6F: {l: {0x68: {l: {0x65: {l: {0x61: {l: {0x64: {l: {0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8606]}}}}}}}}}}}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8608]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},
+ 0x55: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [218]}}, c: [218]}}}}}}}, 0x72: {l: {0x72: {l: {0x3B: {c: [8607]}, 0x6F: {l: {0x63: {l: {0x69: {l: {0x72: {l: {0x3B: {c: [10569]}}}}}}}}}}}}}}}, 0x62: {l: {0x72: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1038]}}}}}, 0x65: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [364]}}}}}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [219]}}, c: [219]}}}}}, 0x79: {l: {0x3B: {c: [1059]}}}}}, 0x64: {l: {0x62: {l: {0x6C: {l: {0x61: {l: {0x63: {l: {0x3B: {c: [368]}}}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120088]}}}}}, 0x67: {l: {0x72: {l: {0x61: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [217]}}, c: [217]}}}}}}}}}, 0x6D: {l: {0x61: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [362]}}}}}}}}}, 0x6E: {l: {0x64: {l: {0x65: {l: {0x72: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [95]}}}}}, 0x72: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [9183]}}}, 0x6B: {l: {0x65: {l: {0x74: {l: {0x3B: {c: [9141]}}}}}}}}}}}}}}}, 0x50: {l: {0x61: {l: {0x72: {l: {0x65: {l: {0x6E: {l: {0x74: {l: {0x68: {l: {0x65: {l: {0x73: {l: {0x69: {l: {0x73: {l: {0x3B: {c: [9181]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x69: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [8899]}, 0x50: {l: {0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8846]}}}}}}}}}}}}}}}}}, 0x6F: {l: {0x67: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [370]}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120140]}}}}}}}, 0x70: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10514]}}}}}}}, 0x3B: {c: [8593]}, 0x44: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8645]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8657]}}}}}}}}}}}, 0x44: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8597]}}}}}}}}}}}}}}}}}}}, 0x64: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8661]}}}}}}}}}}}}}}}}}}}, 0x45: {l: {0x71: {l: {0x75: {l: {0x69: {l: {0x6C: {l: {0x69: {l: {0x62: {l: {0x72: {l: {0x69: {l: {0x75: {l: {0x6D: {l: {0x3B: {c: [10606]}}}}}}}}}}}}}}}}}}}}}}}, 0x70: {l: {0x65: {l: {0x72: {l: {0x4C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8598]}}}}}}}}}}}}}}}}}}}, 0x52: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8599]}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x73: {l: {0x69: {l: {0x3B: {c: [978]}, 0x6C: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [933]}}}}}}}}}}}, 0x54: {l: {0x65: {l: {0x65: {l: {0x41: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8613]}}}}}}}}}}}, 0x3B: {c: [8869]}}}}}}}}}, 0x72: {l: {0x69: {l: {0x6E: {l: {0x67: {l: {0x3B: {c: [366]}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119984]}}}}}}}, 0x74: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [360]}}}}}}}}}}}, 0x75: {l: {0x6D: {l: {0x6C: {l: {0x3B: {c: [220]}}, c: [220]}}}}}}},
+ 0x75: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [250]}}, c: [250]}}}}}}}, 0x72: {l: {0x72: {l: {0x3B: {c: [8593]}}}}}}}, 0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8657]}}}}}}}, 0x62: {l: {0x72: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1118]}}}}}, 0x65: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [365]}}}}}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [251]}}, c: [251]}}}}}, 0x79: {l: {0x3B: {c: [1091]}}}}}, 0x64: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8645]}}}}}}}, 0x62: {l: {0x6C: {l: {0x61: {l: {0x63: {l: {0x3B: {c: [369]}}}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10606]}}}}}}}}}, 0x66: {l: {0x69: {l: {0x73: {l: {0x68: {l: {0x74: {l: {0x3B: {c: [10622]}}}}}}}}}, 0x72: {l: {0x3B: {c: [120114]}}}}}, 0x67: {l: {0x72: {l: {0x61: {l: {0x76: {l: {0x65: {l: {0x3B: {c: [249]}}, c: [249]}}}}}}}}}, 0x48: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10595]}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x6C: {l: {0x3B: {c: [8639]}}}, 0x72: {l: {0x3B: {c: [8638]}}}}}}}, 0x62: {l: {0x6C: {l: {0x6B: {l: {0x3B: {c: [9600]}}}}}}}}}, 0x6C: {l: {0x63: {l: {0x6F: {l: {0x72: {l: {0x6E: {l: {0x3B: {c: [8988]}, 0x65: {l: {0x72: {l: {0x3B: {c: [8988]}}}}}}}}}}}, 0x72: {l: {0x6F: {l: {0x70: {l: {0x3B: {c: [8975]}}}}}}}}}, 0x74: {l: {0x72: {l: {0x69: {l: {0x3B: {c: [9720]}}}}}}}}}, 0x6D: {l: {0x61: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [363]}}}}}}}, 0x6C: {l: {0x3B: {c: [168]}}, c: [168]}}}, 0x6F: {l: {0x67: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [371]}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120166]}}}}}}}, 0x70: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8593]}}}}}}}}}}}, 0x64: {l: {0x6F: {l: {0x77: {l: {0x6E: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x3B: {c: [8597]}}}}}}}}}}}}}}}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x70: {l: {0x6F: {l: {0x6F: {l: {0x6E: {l: {0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x3B: {c: [8639]}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x3B: {c: [8638]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [8846]}}}}}}}, 0x73: {l: {0x69: {l: {0x3B: {c: [965]}, 0x68: {l: {0x3B: {c: [978]}}}, 0x6C: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [965]}}}}}}}}}}}, 0x75: {l: {0x70: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x6F: {l: {0x77: {l: {0x73: {l: {0x3B: {c: [8648]}}}}}}}}}}}}}}}}}}}, 0x72: {l: {0x63: {l: {0x6F: {l: {0x72: {l: {0x6E: {l: {0x3B: {c: [8989]}, 0x65: {l: {0x72: {l: {0x3B: {c: [8989]}}}}}}}}}}}, 0x72: {l: {0x6F: {l: {0x70: {l: {0x3B: {c: [8974]}}}}}}}}}, 0x69: {l: {0x6E: {l: {0x67: {l: {0x3B: {c: [367]}}}}}}}, 0x74: {l: {0x72: {l: {0x69: {l: {0x3B: {c: [9721]}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [120010]}}}}}}}, 0x74: {l: {0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [8944]}}}}}}}, 0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [361]}}}}}}}}}, 0x72: {l: {0x69: {l: {0x3B: {c: [9653]}, 0x66: {l: {0x3B: {c: [9652]}}}}}}}}}, 0x75: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8648]}}}}}}}, 0x6D: {l: {0x6C: {l: {0x3B: {c: [252]}}, c: [252]}}}}}, 0x77: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x3B: {c: [10663]}}}}}}}}}}}}}}},
+ 0x76: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x72: {l: {0x74: {l: {0x3B: {c: [10652]}}}}}}}}}, 0x72: {l: {0x65: {l: {0x70: {l: {0x73: {l: {0x69: {l: {0x6C: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [1013]}}}}}}}}}}}}}}}, 0x6B: {l: {0x61: {l: {0x70: {l: {0x70: {l: {0x61: {l: {0x3B: {c: [1008]}}}}}}}}}}}, 0x6E: {l: {0x6F: {l: {0x74: {l: {0x68: {l: {0x69: {l: {0x6E: {l: {0x67: {l: {0x3B: {c: [8709]}}}}}}}}}}}}}}}, 0x70: {l: {0x68: {l: {0x69: {l: {0x3B: {c: [981]}}}}}, 0x69: {l: {0x3B: {c: [982]}}}, 0x72: {l: {0x6F: {l: {0x70: {l: {0x74: {l: {0x6F: {l: {0x3B: {c: [8733]}}}}}}}}}}}}}, 0x72: {l: {0x3B: {c: [8597]}, 0x68: {l: {0x6F: {l: {0x3B: {c: [1009]}}}}}}}, 0x73: {l: {0x69: {l: {0x67: {l: {0x6D: {l: {0x61: {l: {0x3B: {c: [962]}}}}}}}}}, 0x75: {l: {0x62: {l: {0x73: {l: {0x65: {l: {0x74: {l: {0x6E: {l: {0x65: {l: {0x71: {l: {0x3B: {c: [8842, 65024]}, 0x71: {l: {0x3B: {c: [10955, 65024]}}}}}}}}}}}}}}}}}, 0x70: {l: {0x73: {l: {0x65: {l: {0x74: {l: {0x6E: {l: {0x65: {l: {0x71: {l: {0x3B: {c: [8843, 65024]}, 0x71: {l: {0x3B: {c: [10956, 65024]}}}}}}}}}}}}}}}}}}}}}, 0x74: {l: {0x68: {l: {0x65: {l: {0x74: {l: {0x61: {l: {0x3B: {c: [977]}}}}}}}}}, 0x72: {l: {0x69: {l: {0x61: {l: {0x6E: {l: {0x67: {l: {0x6C: {l: {0x65: {l: {0x6C: {l: {0x65: {l: {0x66: {l: {0x74: {l: {0x3B: {c: [8882]}}}}}}}}}, 0x72: {l: {0x69: {l: {0x67: {l: {0x68: {l: {0x74: {l: {0x3B: {c: [8883]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8661]}}}}}}}, 0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10984]}, 0x76: {l: {0x3B: {c: [10985]}}}}}}}}}, 0x63: {l: {0x79: {l: {0x3B: {c: [1074]}}}}}, 0x64: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8866]}}}}}}}}}, 0x44: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8872]}}}}}}}}}, 0x65: {l: {0x65: {l: {0x62: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8891]}}}}}}}, 0x3B: {c: [8744]}, 0x65: {l: {0x71: {l: {0x3B: {c: [8794]}}}}}}}, 0x6C: {l: {0x6C: {l: {0x69: {l: {0x70: {l: {0x3B: {c: [8942]}}}}}}}}}, 0x72: {l: {0x62: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [124]}}}}}}}, 0x74: {l: {0x3B: {c: [124]}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120115]}}}}}, 0x6C: {l: {0x74: {l: {0x72: {l: {0x69: {l: {0x3B: {c: [8882]}}}}}}}}}, 0x6E: {l: {0x73: {l: {0x75: {l: {0x62: {l: {0x3B: {c: [8834, 8402]}}}, 0x70: {l: {0x3B: {c: [8835, 8402]}}}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120167]}}}}}}}, 0x70: {l: {0x72: {l: {0x6F: {l: {0x70: {l: {0x3B: {c: [8733]}}}}}}}}}, 0x72: {l: {0x74: {l: {0x72: {l: {0x69: {l: {0x3B: {c: [8883]}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [120011]}}}}}, 0x75: {l: {0x62: {l: {0x6E: {l: {0x45: {l: {0x3B: {c: [10955, 65024]}}}, 0x65: {l: {0x3B: {c: [8842, 65024]}}}}}}}, 0x70: {l: {0x6E: {l: {0x45: {l: {0x3B: {c: [10956, 65024]}}}, 0x65: {l: {0x3B: {c: [8843, 65024]}}}}}}}}}}}, 0x7A: {l: {0x69: {l: {0x67: {l: {0x7A: {l: {0x61: {l: {0x67: {l: {0x3B: {c: [10650]}}}}}}}}}}}}}}},
+ 0x56: {l: {0x62: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10987]}}}}}}}, 0x63: {l: {0x79: {l: {0x3B: {c: [1042]}}}}}, 0x64: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8873]}, 0x6C: {l: {0x3B: {c: [10982]}}}}}}}}}}}, 0x44: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8875]}}}}}}}}}, 0x65: {l: {0x65: {l: {0x3B: {c: [8897]}}}, 0x72: {l: {0x62: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8214]}}}}}}}, 0x74: {l: {0x3B: {c: [8214]}, 0x69: {l: {0x63: {l: {0x61: {l: {0x6C: {l: {0x42: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [8739]}}}}}}}, 0x4C: {l: {0x69: {l: {0x6E: {l: {0x65: {l: {0x3B: {c: [124]}}}}}}}}}, 0x53: {l: {0x65: {l: {0x70: {l: {0x61: {l: {0x72: {l: {0x61: {l: {0x74: {l: {0x6F: {l: {0x72: {l: {0x3B: {c: [10072]}}}}}}}}}}}}}}}}}}}, 0x54: {l: {0x69: {l: {0x6C: {l: {0x64: {l: {0x65: {l: {0x3B: {c: [8768]}}}}}}}}}}}}}}}}}}}}}, 0x79: {l: {0x54: {l: {0x68: {l: {0x69: {l: {0x6E: {l: {0x53: {l: {0x70: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [8202]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120089]}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120141]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119985]}}}}}}}, 0x76: {l: {0x64: {l: {0x61: {l: {0x73: {l: {0x68: {l: {0x3B: {c: [8874]}}}}}}}}}}}}},
+ 0x57: {l: {0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [372]}}}}}}}}}, 0x65: {l: {0x64: {l: {0x67: {l: {0x65: {l: {0x3B: {c: [8896]}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120090]}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120142]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119986]}}}}}}}}},
+ 0x77: {l: {0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [373]}}}}}}}}}, 0x65: {l: {0x64: {l: {0x62: {l: {0x61: {l: {0x72: {l: {0x3B: {c: [10847]}}}}}}}, 0x67: {l: {0x65: {l: {0x3B: {c: [8743]}, 0x71: {l: {0x3B: {c: [8793]}}}}}}}}}, 0x69: {l: {0x65: {l: {0x72: {l: {0x70: {l: {0x3B: {c: [8472]}}}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120116]}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120168]}}}}}}}, 0x70: {l: {0x3B: {c: [8472]}}}, 0x72: {l: {0x3B: {c: [8768]}, 0x65: {l: {0x61: {l: {0x74: {l: {0x68: {l: {0x3B: {c: [8768]}}}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [120012]}}}}}}}}},
+ 0x78: {l: {0x63: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [8898]}}}}}, 0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [9711]}}}}}}}, 0x75: {l: {0x70: {l: {0x3B: {c: [8899]}}}}}}}, 0x64: {l: {0x74: {l: {0x72: {l: {0x69: {l: {0x3B: {c: [9661]}}}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120117]}}}}}, 0x68: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10231]}}}}}}}, 0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10234]}}}}}}}}}, 0x69: {l: {0x3B: {c: [958]}}}, 0x6C: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10229]}}}}}}}, 0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10232]}}}}}}}}}, 0x6D: {l: {0x61: {l: {0x70: {l: {0x3B: {c: [10236]}}}}}}}, 0x6E: {l: {0x69: {l: {0x73: {l: {0x3B: {c: [8955]}}}}}}}, 0x6F: {l: {0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [10752]}}}}}}}, 0x70: {l: {0x66: {l: {0x3B: {c: [120169]}}}, 0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [10753]}}}}}}}}}, 0x74: {l: {0x69: {l: {0x6D: {l: {0x65: {l: {0x3B: {c: [10754]}}}}}}}}}}}, 0x72: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10230]}}}}}}}, 0x41: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [10233]}}}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [120013]}}}}}, 0x71: {l: {0x63: {l: {0x75: {l: {0x70: {l: {0x3B: {c: [10758]}}}}}}}}}}}, 0x75: {l: {0x70: {l: {0x6C: {l: {0x75: {l: {0x73: {l: {0x3B: {c: [10756]}}}}}}}}}, 0x74: {l: {0x72: {l: {0x69: {l: {0x3B: {c: [9651]}}}}}}}}}, 0x76: {l: {0x65: {l: {0x65: {l: {0x3B: {c: [8897]}}}}}}}, 0x77: {l: {0x65: {l: {0x64: {l: {0x67: {l: {0x65: {l: {0x3B: {c: [8896]}}}}}}}}}}}}},
+ 0x58: {l: {0x66: {l: {0x72: {l: {0x3B: {c: [120091]}}}}}, 0x69: {l: {0x3B: {c: [926]}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120143]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119987]}}}}}}}}},
+ 0x59: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [221]}}, c: [221]}}}}}}}}}, 0x41: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1071]}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [374]}}}}}}}, 0x79: {l: {0x3B: {c: [1067]}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120092]}}}}}, 0x49: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1031]}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120144]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119988]}}}}}}}, 0x55: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1070]}}}}}}}, 0x75: {l: {0x6D: {l: {0x6C: {l: {0x3B: {c: [376]}}}}}}}}},
+ 0x79: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [253]}}, c: [253]}}}}}, 0x79: {l: {0x3B: {c: [1103]}}}}}}}, 0x63: {l: {0x69: {l: {0x72: {l: {0x63: {l: {0x3B: {c: [375]}}}}}}}, 0x79: {l: {0x3B: {c: [1099]}}}}}, 0x65: {l: {0x6E: {l: {0x3B: {c: [165]}}, c: [165]}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120118]}}}}}, 0x69: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1111]}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120170]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [120014]}}}}}}}, 0x75: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1102]}}}}}, 0x6D: {l: {0x6C: {l: {0x3B: {c: [255]}}, c: [255]}}}}}}},
+ 0x5A: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [377]}}}}}}}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [381]}}}}}}}}}, 0x79: {l: {0x3B: {c: [1047]}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [379]}}}}}}}, 0x65: {l: {0x72: {l: {0x6F: {l: {0x57: {l: {0x69: {l: {0x64: {l: {0x74: {l: {0x68: {l: {0x53: {l: {0x70: {l: {0x61: {l: {0x63: {l: {0x65: {l: {0x3B: {c: [8203]}}}}}}}}}}}}}}}}}}}}}}}}}, 0x74: {l: {0x61: {l: {0x3B: {c: [918]}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [8488]}}}}}, 0x48: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1046]}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [8484]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [119989]}}}}}}}}},
+ 0x7A: {l: {0x61: {l: {0x63: {l: {0x75: {l: {0x74: {l: {0x65: {l: {0x3B: {c: [378]}}}}}}}}}}}, 0x63: {l: {0x61: {l: {0x72: {l: {0x6F: {l: {0x6E: {l: {0x3B: {c: [382]}}}}}}}}}, 0x79: {l: {0x3B: {c: [1079]}}}}}, 0x64: {l: {0x6F: {l: {0x74: {l: {0x3B: {c: [380]}}}}}}}, 0x65: {l: {0x65: {l: {0x74: {l: {0x72: {l: {0x66: {l: {0x3B: {c: [8488]}}}}}}}}}, 0x74: {l: {0x61: {l: {0x3B: {c: [950]}}}}}}}, 0x66: {l: {0x72: {l: {0x3B: {c: [120119]}}}}}, 0x68: {l: {0x63: {l: {0x79: {l: {0x3B: {c: [1078]}}}}}}}, 0x69: {l: {0x67: {l: {0x72: {l: {0x61: {l: {0x72: {l: {0x72: {l: {0x3B: {c: [8669]}}}}}}}}}}}}}, 0x6F: {l: {0x70: {l: {0x66: {l: {0x3B: {c: [120171]}}}}}}}, 0x73: {l: {0x63: {l: {0x72: {l: {0x3B: {c: [120015]}}}}}}}, 0x77: {l: {0x6A: {l: {0x3B: {c: [8205]}}}, 0x6E: {l: {0x6A: {l: {0x3B: {c: [8204]}}}}}}}}}
+};
+},{}],52:[function(require,module,exports){
+'use strict';
+
+var UNICODE = require('../common/unicode');
+
+//Aliases
+var $ = UNICODE.CODE_POINTS;
+
+//Utils
+
+//OPTIMIZATION: these utility functions should not be moved out of this module. V8 Crankshaft will not inline
+//this functions if they will be situated in another module due to context switch.
+//Always perform inlining check before modifying this functions ('node --trace-inlining').
+function isReservedCodePoint(cp) {
+ return cp >= 0xD800 && cp <= 0xDFFF || cp > 0x10FFFF;
+}
+
+function isSurrogatePair(cp1, cp2) {
+ return cp1 >= 0xD800 && cp1 <= 0xDBFF && cp2 >= 0xDC00 && cp2 <= 0xDFFF;
+}
+
+function getSurrogatePairCodePoint(cp1, cp2) {
+ return (cp1 - 0xD800) * 0x400 + 0x2400 + cp2;
+}
+
+//Preprocessor
+//NOTE: HTML input preprocessing
+//(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#preprocessing-the-input-stream)
+var Preprocessor = module.exports = function (html) {
+ this.write(html);
+
+ //NOTE: one leading U+FEFF BYTE ORDER MARK character must be ignored if any are present in the input stream.
+ this.pos = this.html.charCodeAt(0) === $.BOM ? 0 : -1;
+
+ this.gapStack = [];
+ this.lastGapPos = -1;
+ this.skipNextNewLine = false;
+};
+
+Preprocessor.prototype.write = function (html) {
+ if (this.html) {
+ this.html = this.html.substring(0, this.pos + 1) +
+ html +
+ this.html.substring(this.pos + 1, this.html.length);
+
+ }
+ else
+ this.html = html;
+
+
+ this.lastCharPos = this.html.length - 1;
+};
+
+Preprocessor.prototype.advanceAndPeekCodePoint = function () {
+ this.pos++;
+
+ if (this.pos > this.lastCharPos)
+ return $.EOF;
+
+ var cp = this.html.charCodeAt(this.pos);
+
+ //NOTE: any U+000A LINE FEED (LF) characters that immediately follow a U+000D CARRIAGE RETURN (CR) character
+ //must be ignored.
+ if (this.skipNextNewLine && cp === $.LINE_FEED) {
+ this.skipNextNewLine = false;
+ this._addGap();
+ return this.advanceAndPeekCodePoint();
+ }
+
+ //NOTE: all U+000D CARRIAGE RETURN (CR) characters must be converted to U+000A LINE FEED (LF) characters
+ if (cp === $.CARRIAGE_RETURN) {
+ this.skipNextNewLine = true;
+ return $.LINE_FEED;
+ }
+
+ this.skipNextNewLine = false;
+
+ //OPTIMIZATION: first perform check if the code point in the allowed range that covers most common
+ //HTML input (e.g. ASCII codes) to avoid performance-cost operations for high-range code points.
+ return cp >= 0xD800 ? this._processHighRangeCodePoint(cp) : cp;
+};
+
+Preprocessor.prototype._processHighRangeCodePoint = function (cp) {
+ //NOTE: try to peek a surrogate pair
+ if (this.pos !== this.lastCharPos) {
+ var nextCp = this.html.charCodeAt(this.pos + 1);
+
+ if (isSurrogatePair(cp, nextCp)) {
+ //NOTE: we have a surrogate pair. Peek pair character and recalculate code point.
+ this.pos++;
+ cp = getSurrogatePairCodePoint(cp, nextCp);
+
+ //NOTE: add gap that should be avoided during retreat
+ this._addGap();
+ }
+ }
+
+ if (isReservedCodePoint(cp))
+ cp = $.REPLACEMENT_CHARACTER;
+
+ return cp;
+};
+
+Preprocessor.prototype._addGap = function () {
+ this.gapStack.push(this.lastGapPos);
+ this.lastGapPos = this.pos;
+};
+
+Preprocessor.prototype.retreat = function () {
+ if (this.pos === this.lastGapPos) {
+ this.lastGapPos = this.gapStack.pop();
+ this.pos--;
+ }
+
+ this.pos--;
+};
+
+},{"../common/unicode":43}],53:[function(require,module,exports){
+'use strict';
+
+var Preprocessor = require('./preprocessor'),
+ LocationInfoMixin = require('./location_info_mixin'),
+ UNICODE = require('../common/unicode'),
+ NAMED_ENTITY_TRIE = require('./named_entity_trie');
+
+//Aliases
+var $ = UNICODE.CODE_POINTS,
+ $$ = UNICODE.CODE_POINT_SEQUENCES;
+
+//Replacement code points for numeric entities
+var NUMERIC_ENTITY_REPLACEMENTS = {
+ 0x00: 0xFFFD, 0x0D: 0x000D, 0x80: 0x20AC, 0x81: 0x0081, 0x82: 0x201A, 0x83: 0x0192, 0x84: 0x201E,
+ 0x85: 0x2026, 0x86: 0x2020, 0x87: 0x2021, 0x88: 0x02C6, 0x89: 0x2030, 0x8A: 0x0160, 0x8B: 0x2039,
+ 0x8C: 0x0152, 0x8D: 0x008D, 0x8E: 0x017D, 0x8F: 0x008F, 0x90: 0x0090, 0x91: 0x2018, 0x92: 0x2019,
+ 0x93: 0x201C, 0x94: 0x201D, 0x95: 0x2022, 0x96: 0x2013, 0x97: 0x2014, 0x98: 0x02DC, 0x99: 0x2122,
+ 0x9A: 0x0161, 0x9B: 0x203A, 0x9C: 0x0153, 0x9D: 0x009D, 0x9E: 0x017E, 0x9F: 0x0178
+};
+
+//States
+var DATA_STATE = 'DATA_STATE',
+ CHARACTER_REFERENCE_IN_DATA_STATE = 'CHARACTER_REFERENCE_IN_DATA_STATE',
+ RCDATA_STATE = 'RCDATA_STATE',
+ CHARACTER_REFERENCE_IN_RCDATA_STATE = 'CHARACTER_REFERENCE_IN_RCDATA_STATE',
+ RAWTEXT_STATE = 'RAWTEXT_STATE',
+ SCRIPT_DATA_STATE = 'SCRIPT_DATA_STATE',
+ PLAINTEXT_STATE = 'PLAINTEXT_STATE',
+ TAG_OPEN_STATE = 'TAG_OPEN_STATE',
+ END_TAG_OPEN_STATE = 'END_TAG_OPEN_STATE',
+ TAG_NAME_STATE = 'TAG_NAME_STATE',
+ RCDATA_LESS_THAN_SIGN_STATE = 'RCDATA_LESS_THAN_SIGN_STATE',
+ RCDATA_END_TAG_OPEN_STATE = 'RCDATA_END_TAG_OPEN_STATE',
+ RCDATA_END_TAG_NAME_STATE = 'RCDATA_END_TAG_NAME_STATE',
+ RAWTEXT_LESS_THAN_SIGN_STATE = 'RAWTEXT_LESS_THAN_SIGN_STATE',
+ RAWTEXT_END_TAG_OPEN_STATE = 'RAWTEXT_END_TAG_OPEN_STATE',
+ RAWTEXT_END_TAG_NAME_STATE = 'RAWTEXT_END_TAG_NAME_STATE',
+ SCRIPT_DATA_LESS_THAN_SIGN_STATE = 'SCRIPT_DATA_LESS_THAN_SIGN_STATE',
+ SCRIPT_DATA_END_TAG_OPEN_STATE = 'SCRIPT_DATA_END_TAG_OPEN_STATE',
+ SCRIPT_DATA_END_TAG_NAME_STATE = 'SCRIPT_DATA_END_TAG_NAME_STATE',
+ SCRIPT_DATA_ESCAPE_START_STATE = 'SCRIPT_DATA_ESCAPE_START_STATE',
+ SCRIPT_DATA_ESCAPE_START_DASH_STATE = 'SCRIPT_DATA_ESCAPE_START_DASH_STATE',
+ SCRIPT_DATA_ESCAPED_STATE = 'SCRIPT_DATA_ESCAPED_STATE',
+ SCRIPT_DATA_ESCAPED_DASH_STATE = 'SCRIPT_DATA_ESCAPED_DASH_STATE',
+ SCRIPT_DATA_ESCAPED_DASH_DASH_STATE = 'SCRIPT_DATA_ESCAPED_DASH_DASH_STATE',
+ SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE = 'SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE',
+ SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE = 'SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE',
+ SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE = 'SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE',
+ SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE',
+ SCRIPT_DATA_DOUBLE_ESCAPED_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_STATE',
+ SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE',
+ SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE',
+ SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE',
+ SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE = 'SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE',
+ BEFORE_ATTRIBUTE_NAME_STATE = 'BEFORE_ATTRIBUTE_NAME_STATE',
+ ATTRIBUTE_NAME_STATE = 'ATTRIBUTE_NAME_STATE',
+ AFTER_ATTRIBUTE_NAME_STATE = 'AFTER_ATTRIBUTE_NAME_STATE',
+ BEFORE_ATTRIBUTE_VALUE_STATE = 'BEFORE_ATTRIBUTE_VALUE_STATE',
+ ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE = 'ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE',
+ ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE = 'ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE',
+ ATTRIBUTE_VALUE_UNQUOTED_STATE = 'ATTRIBUTE_VALUE_UNQUOTED_STATE',
+ CHARACTER_REFERENCE_IN_ATTRIBUTE_VALUE_STATE = 'CHARACTER_REFERENCE_IN_ATTRIBUTE_VALUE_STATE',
+ AFTER_ATTRIBUTE_VALUE_QUOTED_STATE = 'AFTER_ATTRIBUTE_VALUE_QUOTED_STATE',
+ SELF_CLOSING_START_TAG_STATE = 'SELF_CLOSING_START_TAG_STATE',
+ BOGUS_COMMENT_STATE = 'BOGUS_COMMENT_STATE',
+ MARKUP_DECLARATION_OPEN_STATE = 'MARKUP_DECLARATION_OPEN_STATE',
+ COMMENT_START_STATE = 'COMMENT_START_STATE',
+ COMMENT_START_DASH_STATE = 'COMMENT_START_DASH_STATE',
+ COMMENT_STATE = 'COMMENT_STATE',
+ COMMENT_END_DASH_STATE = 'COMMENT_END_DASH_STATE',
+ COMMENT_END_STATE = 'COMMENT_END_STATE',
+ COMMENT_END_BANG_STATE = 'COMMENT_END_BANG_STATE',
+ DOCTYPE_STATE = 'DOCTYPE_STATE',
+ BEFORE_DOCTYPE_NAME_STATE = 'BEFORE_DOCTYPE_NAME_STATE',
+ DOCTYPE_NAME_STATE = 'DOCTYPE_NAME_STATE',
+ AFTER_DOCTYPE_NAME_STATE = 'AFTER_DOCTYPE_NAME_STATE',
+ AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE = 'AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE',
+ BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE = 'BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE',
+ DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE = 'DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE',
+ DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE = 'DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE',
+ AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE = 'AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE',
+ BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE = 'BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE',
+ AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE = 'AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE',
+ BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE = 'BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE',
+ DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE = 'DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE',
+ DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE = 'DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE',
+ AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE = 'AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE',
+ BOGUS_DOCTYPE_STATE = 'BOGUS_DOCTYPE_STATE',
+ CDATA_SECTION_STATE = 'CDATA_SECTION_STATE';
+
+//Utils
+
+//OPTIMIZATION: these utility functions should not be moved out of this module. V8 Crankshaft will not inline
+//this functions if they will be situated in another module due to context switch.
+//Always perform inlining check before modifying this functions ('node --trace-inlining').
+function isWhitespace(cp) {
+ return cp === $.SPACE || cp === $.LINE_FEED || cp === $.TABULATION || cp === $.FORM_FEED;
+}
+
+function isAsciiDigit(cp) {
+ return cp >= $.DIGIT_0 && cp <= $.DIGIT_9;
+}
+
+function isAsciiUpper(cp) {
+ return cp >= $.LATIN_CAPITAL_A && cp <= $.LATIN_CAPITAL_Z;
+}
+
+function isAsciiLower(cp) {
+ return cp >= $.LATIN_SMALL_A && cp <= $.LATIN_SMALL_Z;
+}
+
+function isAsciiAlphaNumeric(cp) {
+ return isAsciiDigit(cp) || isAsciiUpper(cp) || isAsciiLower(cp);
+}
+
+function isDigit(cp, isHex) {
+ return isAsciiDigit(cp) || (isHex && ((cp >= $.LATIN_CAPITAL_A && cp <= $.LATIN_CAPITAL_F) ||
+ (cp >= $.LATIN_SMALL_A && cp <= $.LATIN_SMALL_F)));
+}
+
+function isReservedCodePoint(cp) {
+ return cp >= 0xD800 && cp <= 0xDFFF || cp > 0x10FFFF;
+}
+
+function toAsciiLowerCodePoint(cp) {
+ return cp + 0x0020;
+}
+
+//NOTE: String.fromCharCode() function can handle only characters from BMP subset.
+//So, we need to workaround this manually.
+//(see: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/fromCharCode#Getting_it_to_work_with_higher_values)
+function toChar(cp) {
+ if (cp <= 0xFFFF)
+ return String.fromCharCode(cp);
+
+ cp -= 0x10000;
+ return String.fromCharCode(cp >>> 10 & 0x3FF | 0xD800) + String.fromCharCode(0xDC00 | cp & 0x3FF);
+}
+
+function toAsciiLowerChar(cp) {
+ return String.fromCharCode(toAsciiLowerCodePoint(cp));
+}
+
+//Tokenizer
+var Tokenizer = module.exports = function (html, options) {
+ this.disableEntitiesDecoding = false;
+
+ this.preprocessor = new Preprocessor(html);
+
+ this.tokenQueue = [];
+
+ this.allowCDATA = false;
+
+ this.state = DATA_STATE;
+ this.returnState = '';
+
+ this.consumptionPos = 0;
+
+ this.tempBuff = [];
+ this.additionalAllowedCp = void 0;
+ this.lastStartTagName = '';
+
+ this.currentCharacterToken = null;
+ this.currentToken = null;
+ this.currentAttr = null;
+
+ if (options) {
+ this.disableEntitiesDecoding = !options.decodeHtmlEntities;
+
+ if (options.locationInfo)
+ LocationInfoMixin.assign(this);
+ }
+};
+
+//Token types
+Tokenizer.CHARACTER_TOKEN = 'CHARACTER_TOKEN';
+Tokenizer.NULL_CHARACTER_TOKEN = 'NULL_CHARACTER_TOKEN';
+Tokenizer.WHITESPACE_CHARACTER_TOKEN = 'WHITESPACE_CHARACTER_TOKEN';
+Tokenizer.START_TAG_TOKEN = 'START_TAG_TOKEN';
+Tokenizer.END_TAG_TOKEN = 'END_TAG_TOKEN';
+Tokenizer.COMMENT_TOKEN = 'COMMENT_TOKEN';
+Tokenizer.DOCTYPE_TOKEN = 'DOCTYPE_TOKEN';
+Tokenizer.EOF_TOKEN = 'EOF_TOKEN';
+
+//Tokenizer initial states for different modes
+Tokenizer.MODE = Tokenizer.prototype.MODE = {
+ DATA: DATA_STATE,
+ RCDATA: RCDATA_STATE,
+ RAWTEXT: RAWTEXT_STATE,
+ SCRIPT_DATA: SCRIPT_DATA_STATE,
+ PLAINTEXT: PLAINTEXT_STATE
+};
+
+//Static
+Tokenizer.getTokenAttr = function (token, attrName) {
+ for (var i = token.attrs.length - 1; i >= 0; i--) {
+ if (token.attrs[i].name === attrName)
+ return token.attrs[i].value;
+ }
+
+ return null;
+};
+
+//Get token
+Tokenizer.prototype.getNextToken = function () {
+ while (!this.tokenQueue.length)
+ this[this.state](this._consume());
+
+ return this.tokenQueue.shift();
+};
+
+//Consumption
+Tokenizer.prototype._consume = function () {
+ this.consumptionPos++;
+ return this.preprocessor.advanceAndPeekCodePoint();
+};
+
+Tokenizer.prototype._unconsume = function () {
+ this.consumptionPos--;
+ this.preprocessor.retreat();
+};
+
+Tokenizer.prototype._unconsumeSeveral = function (count) {
+ while (count--)
+ this._unconsume();
+};
+
+Tokenizer.prototype._reconsumeInState = function (state) {
+ this.state = state;
+ this._unconsume();
+};
+
+Tokenizer.prototype._consumeSubsequentIfMatch = function (pattern, startCp, caseSensitive) {
+ var rollbackPos = this.consumptionPos,
+ isMatch = true,
+ patternLength = pattern.length,
+ patternPos = 0,
+ cp = startCp,
+ patternCp = void 0;
+
+ for (; patternPos < patternLength; patternPos++) {
+ if (patternPos > 0)
+ cp = this._consume();
+
+ if (cp === $.EOF) {
+ isMatch = false;
+ break;
+ }
+
+ patternCp = pattern[patternPos];
+
+ if (cp !== patternCp && (caseSensitive || cp !== toAsciiLowerCodePoint(patternCp))) {
+ isMatch = false;
+ break;
+ }
+ }
+
+ if (!isMatch)
+ this._unconsumeSeveral(this.consumptionPos - rollbackPos);
+
+ return isMatch;
+};
+
+//Lookahead
+Tokenizer.prototype._lookahead = function () {
+ var cp = this.preprocessor.advanceAndPeekCodePoint();
+ this.preprocessor.retreat();
+
+ return cp;
+};
+
+//Temp buffer
+Tokenizer.prototype.isTempBufferEqualToScriptString = function () {
+ if (this.tempBuff.length !== $$.SCRIPT_STRING.length)
+ return false;
+
+ for (var i = 0; i < this.tempBuff.length; i++) {
+ if (this.tempBuff[i] !== $$.SCRIPT_STRING[i])
+ return false;
+ }
+
+ return true;
+};
+
+//Token creation
+Tokenizer.prototype.buildStartTagToken = function (tagName) {
+ return {
+ type: Tokenizer.START_TAG_TOKEN,
+ tagName: tagName,
+ selfClosing: false,
+ attrs: []
+ };
+};
+
+Tokenizer.prototype.buildEndTagToken = function (tagName) {
+ return {
+ type: Tokenizer.END_TAG_TOKEN,
+ tagName: tagName,
+ ignored: false,
+ attrs: []
+ };
+};
+
+Tokenizer.prototype._createStartTagToken = function (tagNameFirstCh) {
+ this.currentToken = this.buildStartTagToken(tagNameFirstCh);
+};
+
+Tokenizer.prototype._createEndTagToken = function (tagNameFirstCh) {
+ this.currentToken = this.buildEndTagToken(tagNameFirstCh);
+};
+
+Tokenizer.prototype._createCommentToken = function () {
+ this.currentToken = {
+ type: Tokenizer.COMMENT_TOKEN,
+ data: ''
+ };
+};
+
+Tokenizer.prototype._createDoctypeToken = function (doctypeNameFirstCh) {
+ this.currentToken = {
+ type: Tokenizer.DOCTYPE_TOKEN,
+ name: doctypeNameFirstCh || '',
+ forceQuirks: false,
+ publicId: null,
+ systemId: null
+ };
+};
+
+Tokenizer.prototype._createCharacterToken = function (type, ch) {
+ this.currentCharacterToken = {
+ type: type,
+ chars: ch
+ };
+};
+
+//Tag attributes
+Tokenizer.prototype._createAttr = function (attrNameFirstCh) {
+ this.currentAttr = {
+ name: attrNameFirstCh,
+ value: ''
+ };
+};
+
+Tokenizer.prototype._isDuplicateAttr = function () {
+ return Tokenizer.getTokenAttr(this.currentToken, this.currentAttr.name) !== null;
+};
+
+Tokenizer.prototype._leaveAttrName = function (toState) {
+ this.state = toState;
+
+ if (!this._isDuplicateAttr())
+ this.currentToken.attrs.push(this.currentAttr);
+};
+
+//Appropriate end tag token
+//(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#appropriate-end-tag-token)
+Tokenizer.prototype._isAppropriateEndTagToken = function () {
+ return this.lastStartTagName === this.currentToken.tagName;
+};
+
+//Token emission
+Tokenizer.prototype._emitCurrentToken = function () {
+ this._emitCurrentCharacterToken();
+
+ //NOTE: store emited start tag's tagName to determine is the following end tag token is appropriate.
+ if (this.currentToken.type === Tokenizer.START_TAG_TOKEN)
+ this.lastStartTagName = this.currentToken.tagName;
+
+ this.tokenQueue.push(this.currentToken);
+ this.currentToken = null;
+};
+
+Tokenizer.prototype._emitCurrentCharacterToken = function () {
+ if (this.currentCharacterToken) {
+ this.tokenQueue.push(this.currentCharacterToken);
+ this.currentCharacterToken = null;
+ }
+};
+
+Tokenizer.prototype._emitEOFToken = function () {
+ this._emitCurrentCharacterToken();
+ this.tokenQueue.push({type: Tokenizer.EOF_TOKEN});
+};
+
+//Characters emission
+
+//OPTIMIZATION: specification uses only one type of character tokens (one token per character).
+//This causes a huge memory overhead and a lot of unnecessary parser loops. parse5 uses 3 groups of characters.
+//If we have a sequence of characters that belong to the same group, parser can process it
+//as a single solid character token.
+//So, there are 3 types of character tokens in parse5:
+//1)NULL_CHARACTER_TOKEN - \u0000-character sequences (e.g. '\u0000\u0000\u0000')
+//2)WHITESPACE_CHARACTER_TOKEN - any whitespace/new-line character sequences (e.g. '\n \r\t \f')
+//3)CHARACTER_TOKEN - any character sequence which don't belong to groups 1 and 2 (e.g. 'abcdef1234@@#$%^')
+Tokenizer.prototype._appendCharToCurrentCharacterToken = function (type, ch) {
+ if (this.currentCharacterToken && this.currentCharacterToken.type !== type)
+ this._emitCurrentCharacterToken();
+
+ if (this.currentCharacterToken)
+ this.currentCharacterToken.chars += ch;
+
+ else
+ this._createCharacterToken(type, ch);
+};
+
+Tokenizer.prototype._emitCodePoint = function (cp) {
+ var type = Tokenizer.CHARACTER_TOKEN;
+
+ if (isWhitespace(cp))
+ type = Tokenizer.WHITESPACE_CHARACTER_TOKEN;
+
+ else if (cp === $.NULL)
+ type = Tokenizer.NULL_CHARACTER_TOKEN;
+
+ this._appendCharToCurrentCharacterToken(type, toChar(cp));
+};
+
+Tokenizer.prototype._emitSeveralCodePoints = function (codePoints) {
+ for (var i = 0; i < codePoints.length; i++)
+ this._emitCodePoint(codePoints[i]);
+};
+
+//NOTE: used then we emit character explicitly. This is always a non-whitespace and a non-null character.
+//So we can avoid additional checks here.
+Tokenizer.prototype._emitChar = function (ch) {
+ this._appendCharToCurrentCharacterToken(Tokenizer.CHARACTER_TOKEN, ch);
+};
+
+//Character reference tokenization
+Tokenizer.prototype._consumeNumericEntity = function (isHex) {
+ var digits = '',
+ nextCp = void 0;
+
+ do {
+ digits += toChar(this._consume());
+ nextCp = this._lookahead();
+ } while (nextCp !== $.EOF && isDigit(nextCp, isHex));
+
+ if (this._lookahead() === $.SEMICOLON)
+ this._consume();
+
+ var referencedCp = parseInt(digits, isHex ? 16 : 10),
+ replacement = NUMERIC_ENTITY_REPLACEMENTS[referencedCp];
+
+ if (replacement)
+ return replacement;
+
+ if (isReservedCodePoint(referencedCp))
+ return $.REPLACEMENT_CHARACTER;
+
+ return referencedCp;
+};
+
+Tokenizer.prototype._consumeNamedEntity = function (startCp, inAttr) {
+ var referencedCodePoints = null,
+ entityCodePointsCount = 0,
+ cp = startCp,
+ leaf = NAMED_ENTITY_TRIE[cp],
+ consumedCount = 1,
+ semicolonTerminated = false;
+
+ for (; leaf && cp !== $.EOF; cp = this._consume(), consumedCount++, leaf = leaf.l && leaf.l[cp]) {
+ if (leaf.c) {
+ //NOTE: we have at least one named reference match. But we don't stop lookup at this point,
+ //because longer matches still can be found (e.g. '¬' and '∉') except the case
+ //then found match is terminated by semicolon.
+ referencedCodePoints = leaf.c;
+ entityCodePointsCount = consumedCount;
+
+ if (cp === $.SEMICOLON) {
+ semicolonTerminated = true;
+ break;
+ }
+ }
+ }
+
+ if (referencedCodePoints) {
+ if (!semicolonTerminated) {
+ //NOTE: unconsume excess (e.g. 'it' in '¬it')
+ this._unconsumeSeveral(consumedCount - entityCodePointsCount);
+
+ //NOTE: If the character reference is being consumed as part of an attribute and the next character
+ //is either a U+003D EQUALS SIGN character (=) or an alphanumeric ASCII character, then, for historical
+ //reasons, all the characters that were matched after the U+0026 AMPERSAND character (&) must be
+ //unconsumed, and nothing is returned.
+ //However, if this next character is in fact a U+003D EQUALS SIGN character (=), then this is a
+ //parse error, because some legacy user agents will misinterpret the markup in those cases.
+ //(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#tokenizing-character-references)
+ if (inAttr) {
+ var nextCp = this._lookahead();
+
+ if (nextCp === $.EQUALS_SIGN || isAsciiAlphaNumeric(nextCp)) {
+ this._unconsumeSeveral(entityCodePointsCount);
+ return null;
+ }
+ }
+ }
+
+ return referencedCodePoints;
+ }
+
+ this._unconsumeSeveral(consumedCount);
+
+ return null;
+};
+
+Tokenizer.prototype._consumeCharacterReference = function (startCp, inAttr) {
+ if (this.disableEntitiesDecoding || isWhitespace(startCp) || startCp === $.GREATER_THAN_SIGN ||
+ startCp === $.AMPERSAND || startCp === this.additionalAllowedCp || startCp === $.EOF) {
+ //NOTE: not a character reference. No characters are consumed, and nothing is returned.
+ this._unconsume();
+ return null;
+ }
+
+ else if (startCp === $.NUMBER_SIGN) {
+ //NOTE: we have a numeric entity candidate, now we should determine if it's hex or decimal
+ var isHex = false,
+ nextCp = this._lookahead();
+
+ if (nextCp === $.LATIN_SMALL_X || nextCp === $.LATIN_CAPITAL_X) {
+ this._consume();
+ isHex = true;
+ }
+
+ nextCp = this._lookahead();
+
+ //NOTE: if we have at least one digit this is a numeric entity for sure, so we consume it
+ if (nextCp !== $.EOF && isDigit(nextCp, isHex))
+ return [this._consumeNumericEntity(isHex)];
+
+ else {
+ //NOTE: otherwise this is a bogus number entity and a parse error. Unconsume the number sign
+ //and the 'x'-character if appropriate.
+ this._unconsumeSeveral(isHex ? 2 : 1);
+ return null;
+ }
+ }
+
+ else
+ return this._consumeNamedEntity(startCp, inAttr);
+};
+
+//State machine
+var _ = Tokenizer.prototype;
+
+//12.2.4.1 Data state
+//------------------------------------------------------------------
+_[DATA_STATE] = function dataState(cp) {
+ if (cp === $.AMPERSAND)
+ this.state = CHARACTER_REFERENCE_IN_DATA_STATE;
+
+ else if (cp === $.LESS_THAN_SIGN)
+ this.state = TAG_OPEN_STATE;
+
+ else if (cp === $.NULL)
+ this._emitCodePoint(cp);
+
+ else if (cp === $.EOF)
+ this._emitEOFToken();
+
+ else
+ this._emitCodePoint(cp);
+};
+
+
+//12.2.4.2 Character reference in data state
+//------------------------------------------------------------------
+_[CHARACTER_REFERENCE_IN_DATA_STATE] = function characterReferenceInDataState(cp) {
+ this.state = DATA_STATE;
+ this.additionalAllowedCp = void 0;
+
+ var referencedCodePoints = this._consumeCharacterReference(cp, false);
+
+ if (referencedCodePoints)
+ this._emitSeveralCodePoints(referencedCodePoints);
+ else
+ this._emitChar('&');
+};
+
+
+//12.2.4.3 RCDATA state
+//------------------------------------------------------------------
+_[RCDATA_STATE] = function rcdataState(cp) {
+ if (cp === $.AMPERSAND)
+ this.state = CHARACTER_REFERENCE_IN_RCDATA_STATE;
+
+ else if (cp === $.LESS_THAN_SIGN)
+ this.state = RCDATA_LESS_THAN_SIGN_STATE;
+
+ else if (cp === $.NULL)
+ this._emitChar(UNICODE.REPLACEMENT_CHARACTER);
+
+ else if (cp === $.EOF)
+ this._emitEOFToken();
+
+ else
+ this._emitCodePoint(cp);
+};
+
+
+//12.2.4.4 Character reference in RCDATA state
+//------------------------------------------------------------------
+_[CHARACTER_REFERENCE_IN_RCDATA_STATE] = function characterReferenceInRcdataState(cp) {
+ this.state = RCDATA_STATE;
+ this.additionalAllowedCp = void 0;
+
+ var referencedCodePoints = this._consumeCharacterReference(cp, false);
+
+ if (referencedCodePoints)
+ this._emitSeveralCodePoints(referencedCodePoints);
+ else
+ this._emitChar('&');
+};
+
+
+//12.2.4.5 RAWTEXT state
+//------------------------------------------------------------------
+_[RAWTEXT_STATE] = function rawtextState(cp) {
+ if (cp === $.LESS_THAN_SIGN)
+ this.state = RAWTEXT_LESS_THAN_SIGN_STATE;
+
+ else if (cp === $.NULL)
+ this._emitChar(UNICODE.REPLACEMENT_CHARACTER);
+
+ else if (cp === $.EOF)
+ this._emitEOFToken();
+
+ else
+ this._emitCodePoint(cp);
+};
+
+
+//12.2.4.6 Script data state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_STATE] = function scriptDataState(cp) {
+ if (cp === $.LESS_THAN_SIGN)
+ this.state = SCRIPT_DATA_LESS_THAN_SIGN_STATE;
+
+ else if (cp === $.NULL)
+ this._emitChar(UNICODE.REPLACEMENT_CHARACTER);
+
+ else if (cp === $.EOF)
+ this._emitEOFToken();
+
+ else
+ this._emitCodePoint(cp);
+};
+
+
+//12.2.4.7 PLAINTEXT state
+//------------------------------------------------------------------
+_[PLAINTEXT_STATE] = function plaintextState(cp) {
+ if (cp === $.NULL)
+ this._emitChar(UNICODE.REPLACEMENT_CHARACTER);
+
+ else if (cp === $.EOF)
+ this._emitEOFToken();
+
+ else
+ this._emitCodePoint(cp);
+};
+
+
+//12.2.4.8 Tag open state
+//------------------------------------------------------------------
+_[TAG_OPEN_STATE] = function tagOpenState(cp) {
+ if (cp === $.EXCLAMATION_MARK)
+ this.state = MARKUP_DECLARATION_OPEN_STATE;
+
+ else if (cp === $.SOLIDUS)
+ this.state = END_TAG_OPEN_STATE;
+
+ else if (isAsciiUpper(cp)) {
+ this._createStartTagToken(toAsciiLowerChar(cp));
+ this.state = TAG_NAME_STATE;
+ }
+
+ else if (isAsciiLower(cp)) {
+ this._createStartTagToken(toChar(cp));
+ this.state = TAG_NAME_STATE;
+ }
+
+ else if (cp === $.QUESTION_MARK) {
+ //NOTE: call bogus comment state directly with current consumed character to avoid unnecessary reconsumption.
+ this[BOGUS_COMMENT_STATE](cp);
+ }
+
+ else {
+ this._emitChar('<');
+ this._reconsumeInState(DATA_STATE);
+ }
+};
+
+
+//12.2.4.9 End tag open state
+//------------------------------------------------------------------
+_[END_TAG_OPEN_STATE] = function endTagOpenState(cp) {
+ if (isAsciiUpper(cp)) {
+ this._createEndTagToken(toAsciiLowerChar(cp));
+ this.state = TAG_NAME_STATE;
+ }
+
+ else if (isAsciiLower(cp)) {
+ this._createEndTagToken(toChar(cp));
+ this.state = TAG_NAME_STATE;
+ }
+
+ else if (cp === $.GREATER_THAN_SIGN)
+ this.state = DATA_STATE;
+
+ else if (cp === $.EOF) {
+ this._reconsumeInState(DATA_STATE);
+ this._emitChar('<');
+ this._emitChar('/');
+ }
+
+ else {
+ //NOTE: call bogus comment state directly with current consumed character to avoid unnecessary reconsumption.
+ this[BOGUS_COMMENT_STATE](cp);
+ }
+};
+
+
+//12.2.4.10 Tag name state
+//------------------------------------------------------------------
+_[TAG_NAME_STATE] = function tagNameState(cp) {
+ if (isWhitespace(cp))
+ this.state = BEFORE_ATTRIBUTE_NAME_STATE;
+
+ else if (cp === $.SOLIDUS)
+ this.state = SELF_CLOSING_START_TAG_STATE;
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.state = DATA_STATE;
+ this._emitCurrentToken();
+ }
+
+ else if (isAsciiUpper(cp))
+ this.currentToken.tagName += toAsciiLowerChar(cp);
+
+ else if (cp === $.NULL)
+ this.currentToken.tagName += UNICODE.REPLACEMENT_CHARACTER;
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else
+ this.currentToken.tagName += toChar(cp);
+};
+
+
+//12.2.4.11 RCDATA less-than sign state
+//------------------------------------------------------------------
+_[RCDATA_LESS_THAN_SIGN_STATE] = function rcdataLessThanSignState(cp) {
+ if (cp === $.SOLIDUS) {
+ this.tempBuff = [];
+ this.state = RCDATA_END_TAG_OPEN_STATE;
+ }
+
+ else {
+ this._emitChar('<');
+ this._reconsumeInState(RCDATA_STATE);
+ }
+};
+
+
+//12.2.4.12 RCDATA end tag open state
+//------------------------------------------------------------------
+_[RCDATA_END_TAG_OPEN_STATE] = function rcdataEndTagOpenState(cp) {
+ if (isAsciiUpper(cp)) {
+ this._createEndTagToken(toAsciiLowerChar(cp));
+ this.tempBuff.push(cp);
+ this.state = RCDATA_END_TAG_NAME_STATE;
+ }
+
+ else if (isAsciiLower(cp)) {
+ this._createEndTagToken(toChar(cp));
+ this.tempBuff.push(cp);
+ this.state = RCDATA_END_TAG_NAME_STATE;
+ }
+
+ else {
+ this._emitChar('<');
+ this._emitChar('/');
+ this._reconsumeInState(RCDATA_STATE);
+ }
+};
+
+
+//12.2.4.13 RCDATA end tag name state
+//------------------------------------------------------------------
+_[RCDATA_END_TAG_NAME_STATE] = function rcdataEndTagNameState(cp) {
+ if (isAsciiUpper(cp)) {
+ this.currentToken.tagName += toAsciiLowerChar(cp);
+ this.tempBuff.push(cp);
+ }
+
+ else if (isAsciiLower(cp)) {
+ this.currentToken.tagName += toChar(cp);
+ this.tempBuff.push(cp);
+ }
+
+ else {
+ if (this._isAppropriateEndTagToken()) {
+ if (isWhitespace(cp)) {
+ this.state = BEFORE_ATTRIBUTE_NAME_STATE;
+ return;
+ }
+
+ if (cp === $.SOLIDUS) {
+ this.state = SELF_CLOSING_START_TAG_STATE;
+ return;
+ }
+
+ if (cp === $.GREATER_THAN_SIGN) {
+ this.state = DATA_STATE;
+ this._emitCurrentToken();
+ return;
+ }
+ }
+
+ this._emitChar('<');
+ this._emitChar('/');
+ this._emitSeveralCodePoints(this.tempBuff);
+ this._reconsumeInState(RCDATA_STATE);
+ }
+};
+
+
+//12.2.4.14 RAWTEXT less-than sign state
+//------------------------------------------------------------------
+_[RAWTEXT_LESS_THAN_SIGN_STATE] = function rawtextLessThanSignState(cp) {
+ if (cp === $.SOLIDUS) {
+ this.tempBuff = [];
+ this.state = RAWTEXT_END_TAG_OPEN_STATE;
+ }
+
+ else {
+ this._emitChar('<');
+ this._reconsumeInState(RAWTEXT_STATE);
+ }
+};
+
+
+//12.2.4.15 RAWTEXT end tag open state
+//------------------------------------------------------------------
+_[RAWTEXT_END_TAG_OPEN_STATE] = function rawtextEndTagOpenState(cp) {
+ if (isAsciiUpper(cp)) {
+ this._createEndTagToken(toAsciiLowerChar(cp));
+ this.tempBuff.push(cp);
+ this.state = RAWTEXT_END_TAG_NAME_STATE;
+ }
+
+ else if (isAsciiLower(cp)) {
+ this._createEndTagToken(toChar(cp));
+ this.tempBuff.push(cp);
+ this.state = RAWTEXT_END_TAG_NAME_STATE;
+ }
+
+ else {
+ this._emitChar('<');
+ this._emitChar('/');
+ this._reconsumeInState(RAWTEXT_STATE);
+ }
+};
+
+
+//12.2.4.16 RAWTEXT end tag name state
+//------------------------------------------------------------------
+_[RAWTEXT_END_TAG_NAME_STATE] = function rawtextEndTagNameState(cp) {
+ if (isAsciiUpper(cp)) {
+ this.currentToken.tagName += toAsciiLowerChar(cp);
+ this.tempBuff.push(cp);
+ }
+
+ else if (isAsciiLower(cp)) {
+ this.currentToken.tagName += toChar(cp);
+ this.tempBuff.push(cp);
+ }
+
+ else {
+ if (this._isAppropriateEndTagToken()) {
+ if (isWhitespace(cp)) {
+ this.state = BEFORE_ATTRIBUTE_NAME_STATE;
+ return;
+ }
+
+ if (cp === $.SOLIDUS) {
+ this.state = SELF_CLOSING_START_TAG_STATE;
+ return;
+ }
+
+ if (cp === $.GREATER_THAN_SIGN) {
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ return;
+ }
+ }
+
+ this._emitChar('<');
+ this._emitChar('/');
+ this._emitSeveralCodePoints(this.tempBuff);
+ this._reconsumeInState(RAWTEXT_STATE);
+ }
+};
+
+
+//12.2.4.17 Script data less-than sign state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_LESS_THAN_SIGN_STATE] = function scriptDataLessThanSignState(cp) {
+ if (cp === $.SOLIDUS) {
+ this.tempBuff = [];
+ this.state = SCRIPT_DATA_END_TAG_OPEN_STATE;
+ }
+
+ else if (cp === $.EXCLAMATION_MARK) {
+ this.state = SCRIPT_DATA_ESCAPE_START_STATE;
+ this._emitChar('<');
+ this._emitChar('!');
+ }
+
+ else {
+ this._emitChar('<');
+ this._reconsumeInState(SCRIPT_DATA_STATE);
+ }
+};
+
+
+//12.2.4.18 Script data end tag open state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_END_TAG_OPEN_STATE] = function scriptDataEndTagOpenState(cp) {
+ if (isAsciiUpper(cp)) {
+ this._createEndTagToken(toAsciiLowerChar(cp));
+ this.tempBuff.push(cp);
+ this.state = SCRIPT_DATA_END_TAG_NAME_STATE;
+ }
+
+ else if (isAsciiLower(cp)) {
+ this._createEndTagToken(toChar(cp));
+ this.tempBuff.push(cp);
+ this.state = SCRIPT_DATA_END_TAG_NAME_STATE;
+ }
+
+ else {
+ this._emitChar('<');
+ this._emitChar('/');
+ this._reconsumeInState(SCRIPT_DATA_STATE);
+ }
+};
+
+
+//12.2.4.19 Script data end tag name state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_END_TAG_NAME_STATE] = function scriptDataEndTagNameState(cp) {
+ if (isAsciiUpper(cp)) {
+ this.currentToken.tagName += toAsciiLowerChar(cp);
+ this.tempBuff.push(cp);
+ }
+
+ else if (isAsciiLower(cp)) {
+ this.currentToken.tagName += toChar(cp);
+ this.tempBuff.push(cp);
+ }
+
+ else {
+ if (this._isAppropriateEndTagToken()) {
+ if (isWhitespace(cp)) {
+ this.state = BEFORE_ATTRIBUTE_NAME_STATE;
+ return;
+ }
+
+ else if (cp === $.SOLIDUS) {
+ this.state = SELF_CLOSING_START_TAG_STATE;
+ return;
+ }
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ return;
+ }
+ }
+
+ this._emitChar('<');
+ this._emitChar('/');
+ this._emitSeveralCodePoints(this.tempBuff);
+ this._reconsumeInState(SCRIPT_DATA_STATE);
+ }
+};
+
+
+//12.2.4.20 Script data escape start state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_ESCAPE_START_STATE] = function scriptDataEscapeStartState(cp) {
+ if (cp === $.HYPHEN_MINUS) {
+ this.state = SCRIPT_DATA_ESCAPE_START_DASH_STATE;
+ this._emitChar('-');
+ }
+
+ else
+ this._reconsumeInState(SCRIPT_DATA_STATE);
+};
+
+
+//12.2.4.21 Script data escape start dash state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_ESCAPE_START_DASH_STATE] = function scriptDataEscapeStartDashState(cp) {
+ if (cp === $.HYPHEN_MINUS) {
+ this.state = SCRIPT_DATA_ESCAPED_DASH_DASH_STATE;
+ this._emitChar('-');
+ }
+
+ else
+ this._reconsumeInState(SCRIPT_DATA_STATE);
+};
+
+
+//12.2.4.22 Script data escaped state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_ESCAPED_STATE] = function scriptDataEscapedState(cp) {
+ if (cp === $.HYPHEN_MINUS) {
+ this.state = SCRIPT_DATA_ESCAPED_DASH_STATE;
+ this._emitChar('-');
+ }
+
+ else if (cp === $.LESS_THAN_SIGN)
+ this.state = SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE;
+
+ else if (cp === $.NULL)
+ this._emitChar(UNICODE.REPLACEMENT_CHARACTER);
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else
+ this._emitCodePoint(cp);
+};
+
+
+//12.2.4.23 Script data escaped dash state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_ESCAPED_DASH_STATE] = function scriptDataEscapedDashState(cp) {
+ if (cp === $.HYPHEN_MINUS) {
+ this.state = SCRIPT_DATA_ESCAPED_DASH_DASH_STATE;
+ this._emitChar('-');
+ }
+
+ else if (cp === $.LESS_THAN_SIGN)
+ this.state = SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE;
+
+ else if (cp === $.NULL) {
+ this.state = SCRIPT_DATA_ESCAPED_STATE;
+ this._emitChar(UNICODE.REPLACEMENT_CHARACTER);
+ }
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else {
+ this.state = SCRIPT_DATA_ESCAPED_STATE;
+ this._emitCodePoint(cp);
+ }
+};
+
+
+//12.2.4.24 Script data escaped dash dash state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_ESCAPED_DASH_DASH_STATE] = function scriptDataEscapedDashDashState(cp) {
+ if (cp === $.HYPHEN_MINUS)
+ this._emitChar('-');
+
+ else if (cp === $.LESS_THAN_SIGN)
+ this.state = SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE;
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.state = SCRIPT_DATA_STATE;
+ this._emitChar('>');
+ }
+
+ else if (cp === $.NULL) {
+ this.state = SCRIPT_DATA_ESCAPED_STATE;
+ this._emitChar(UNICODE.REPLACEMENT_CHARACTER);
+ }
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else {
+ this.state = SCRIPT_DATA_ESCAPED_STATE;
+ this._emitCodePoint(cp);
+ }
+};
+
+
+//12.2.4.25 Script data escaped less-than sign state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN_STATE] = function scriptDataEscapedLessThanSignState(cp) {
+ if (cp === $.SOLIDUS) {
+ this.tempBuff = [];
+ this.state = SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE;
+ }
+
+ else if (isAsciiUpper(cp)) {
+ this.tempBuff = [];
+ this.tempBuff.push(toAsciiLowerCodePoint(cp));
+ this.state = SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE;
+ this._emitChar('<');
+ this._emitCodePoint(cp);
+ }
+
+ else if (isAsciiLower(cp)) {
+ this.tempBuff = [];
+ this.tempBuff.push(cp);
+ this.state = SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE;
+ this._emitChar('<');
+ this._emitCodePoint(cp);
+ }
+
+ else {
+ this._emitChar('<');
+ this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
+ }
+};
+
+
+//12.2.4.26 Script data escaped end tag open state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_ESCAPED_END_TAG_OPEN_STATE] = function scriptDataEscapedEndTagOpenState(cp) {
+ if (isAsciiUpper(cp)) {
+ this._createEndTagToken(toAsciiLowerChar(cp));
+ this.tempBuff.push(cp);
+ this.state = SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE;
+ }
+
+ else if (isAsciiLower(cp)) {
+ this._createEndTagToken(toChar(cp));
+ this.tempBuff.push(cp);
+ this.state = SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE;
+ }
+
+ else {
+ this._emitChar('<');
+ this._emitChar('/');
+ this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
+ }
+};
+
+
+//12.2.4.27 Script data escaped end tag name state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_ESCAPED_END_TAG_NAME_STATE] = function scriptDataEscapedEndTagNameState(cp) {
+ if (isAsciiUpper(cp)) {
+ this.currentToken.tagName += toAsciiLowerChar(cp);
+ this.tempBuff.push(cp);
+ }
+
+ else if (isAsciiLower(cp)) {
+ this.currentToken.tagName += toChar(cp);
+ this.tempBuff.push(cp);
+ }
+
+ else {
+ if (this._isAppropriateEndTagToken()) {
+ if (isWhitespace(cp)) {
+ this.state = BEFORE_ATTRIBUTE_NAME_STATE;
+ return;
+ }
+
+ if (cp === $.SOLIDUS) {
+ this.state = SELF_CLOSING_START_TAG_STATE;
+ return;
+ }
+
+ if (cp === $.GREATER_THAN_SIGN) {
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ return;
+ }
+ }
+
+ this._emitChar('<');
+ this._emitChar('/');
+ this._emitSeveralCodePoints(this.tempBuff);
+ this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
+ }
+};
+
+
+//12.2.4.28 Script data double escape start state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_DOUBLE_ESCAPE_START_STATE] = function scriptDataDoubleEscapeStartState(cp) {
+ if (isWhitespace(cp) || cp === $.SOLIDUS || cp === $.GREATER_THAN_SIGN) {
+ this.state = this.isTempBufferEqualToScriptString() ? SCRIPT_DATA_DOUBLE_ESCAPED_STATE : SCRIPT_DATA_ESCAPED_STATE;
+ this._emitCodePoint(cp);
+ }
+
+ else if (isAsciiUpper(cp)) {
+ this.tempBuff.push(toAsciiLowerCodePoint(cp));
+ this._emitCodePoint(cp);
+ }
+
+ else if (isAsciiLower(cp)) {
+ this.tempBuff.push(cp);
+ this._emitCodePoint(cp);
+ }
+
+ else
+ this._reconsumeInState(SCRIPT_DATA_ESCAPED_STATE);
+};
+
+
+//12.2.4.29 Script data double escaped state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_DOUBLE_ESCAPED_STATE] = function scriptDataDoubleEscapedState(cp) {
+ if (cp === $.HYPHEN_MINUS) {
+ this.state = SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE;
+ this._emitChar('-');
+ }
+
+ else if (cp === $.LESS_THAN_SIGN) {
+ this.state = SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE;
+ this._emitChar('<');
+ }
+
+ else if (cp === $.NULL)
+ this._emitChar(UNICODE.REPLACEMENT_CHARACTER);
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else
+ this._emitCodePoint(cp);
+};
+
+
+//12.2.4.30 Script data double escaped dash state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_DOUBLE_ESCAPED_DASH_STATE] = function scriptDataDoubleEscapedDashState(cp) {
+ if (cp === $.HYPHEN_MINUS) {
+ this.state = SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE;
+ this._emitChar('-');
+ }
+
+ else if (cp === $.LESS_THAN_SIGN) {
+ this.state = SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE;
+ this._emitChar('<');
+ }
+
+ else if (cp === $.NULL) {
+ this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
+ this._emitChar(UNICODE.REPLACEMENT_CHARACTER);
+ }
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else {
+ this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
+ this._emitCodePoint(cp);
+ }
+};
+
+
+//12.2.4.31 Script data double escaped dash dash state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH_STATE] = function scriptDataDoubleEscapedDashDashState(cp) {
+ if (cp === $.HYPHEN_MINUS)
+ this._emitChar('-');
+
+ else if (cp === $.LESS_THAN_SIGN) {
+ this.state = SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE;
+ this._emitChar('<');
+ }
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.state = SCRIPT_DATA_STATE;
+ this._emitChar('>');
+ }
+
+ else if (cp === $.NULL) {
+ this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
+ this._emitChar(UNICODE.REPLACEMENT_CHARACTER);
+ }
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else {
+ this.state = SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
+ this._emitCodePoint(cp);
+ }
+};
+
+
+//12.2.4.32 Script data double escaped less-than sign state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN_STATE] = function scriptDataDoubleEscapedLessThanSignState(cp) {
+ if (cp === $.SOLIDUS) {
+ this.tempBuff = [];
+ this.state = SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE;
+ this._emitChar('/');
+ }
+
+ else
+ this._reconsumeInState(SCRIPT_DATA_DOUBLE_ESCAPED_STATE);
+};
+
+
+//12.2.4.33 Script data double escape end state
+//------------------------------------------------------------------
+_[SCRIPT_DATA_DOUBLE_ESCAPE_END_STATE] = function scriptDataDoubleEscapeEndState(cp) {
+ if (isWhitespace(cp) || cp === $.SOLIDUS || cp === $.GREATER_THAN_SIGN) {
+ this.state = this.isTempBufferEqualToScriptString() ? SCRIPT_DATA_ESCAPED_STATE : SCRIPT_DATA_DOUBLE_ESCAPED_STATE;
+
+ this._emitCodePoint(cp);
+ }
+
+ else if (isAsciiUpper(cp)) {
+ this.tempBuff.push(toAsciiLowerCodePoint(cp));
+ this._emitCodePoint(cp);
+ }
+
+ else if (isAsciiLower(cp)) {
+ this.tempBuff.push(cp);
+ this._emitCodePoint(cp);
+ }
+
+ else
+ this._reconsumeInState(SCRIPT_DATA_DOUBLE_ESCAPED_STATE);
+};
+
+
+//12.2.4.34 Before attribute name state
+//------------------------------------------------------------------
+_[BEFORE_ATTRIBUTE_NAME_STATE] = function beforeAttributeNameState(cp) {
+ if (isWhitespace(cp))
+ return;
+
+ if (cp === $.SOLIDUS)
+ this.state = SELF_CLOSING_START_TAG_STATE;
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.state = DATA_STATE;
+ this._emitCurrentToken();
+ }
+
+ else if (isAsciiUpper(cp)) {
+ this._createAttr(toAsciiLowerChar(cp));
+ this.state = ATTRIBUTE_NAME_STATE;
+ }
+
+ else if (cp === $.NULL) {
+ this._createAttr(UNICODE.REPLACEMENT_CHARACTER);
+ this.state = ATTRIBUTE_NAME_STATE;
+ }
+
+ else if (cp === $.QUOTATION_MARK || cp === $.APOSTROPHE || cp === $.LESS_THAN_SIGN || cp === $.EQUALS_SIGN) {
+ this._createAttr(toChar(cp));
+ this.state = ATTRIBUTE_NAME_STATE;
+ }
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else {
+ this._createAttr(toChar(cp));
+ this.state = ATTRIBUTE_NAME_STATE;
+ }
+};
+
+
+//12.2.4.35 Attribute name state
+//------------------------------------------------------------------
+_[ATTRIBUTE_NAME_STATE] = function attributeNameState(cp) {
+ if (isWhitespace(cp))
+ this._leaveAttrName(AFTER_ATTRIBUTE_NAME_STATE);
+
+ else if (cp === $.SOLIDUS)
+ this._leaveAttrName(SELF_CLOSING_START_TAG_STATE);
+
+ else if (cp === $.EQUALS_SIGN)
+ this._leaveAttrName(BEFORE_ATTRIBUTE_VALUE_STATE);
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this._leaveAttrName(DATA_STATE);
+ this._emitCurrentToken();
+ }
+
+ else if (isAsciiUpper(cp))
+ this.currentAttr.name += toAsciiLowerChar(cp);
+
+ else if (cp === $.QUOTATION_MARK || cp === $.APOSTROPHE || cp === $.LESS_THAN_SIGN)
+ this.currentAttr.name += toChar(cp);
+
+ else if (cp === $.NULL)
+ this.currentAttr.name += UNICODE.REPLACEMENT_CHARACTER;
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else
+ this.currentAttr.name += toChar(cp);
+};
+
+
+//12.2.4.36 After attribute name state
+//------------------------------------------------------------------
+_[AFTER_ATTRIBUTE_NAME_STATE] = function afterAttributeNameState(cp) {
+ if (isWhitespace(cp))
+ return;
+
+ if (cp === $.SOLIDUS)
+ this.state = SELF_CLOSING_START_TAG_STATE;
+
+ else if (cp === $.EQUALS_SIGN)
+ this.state = BEFORE_ATTRIBUTE_VALUE_STATE;
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.state = DATA_STATE;
+ this._emitCurrentToken();
+ }
+
+ else if (isAsciiUpper(cp)) {
+ this._createAttr(toAsciiLowerChar(cp));
+ this.state = ATTRIBUTE_NAME_STATE;
+ }
+
+ else if (cp === $.NULL) {
+ this._createAttr(UNICODE.REPLACEMENT_CHARACTER);
+ this.state = ATTRIBUTE_NAME_STATE;
+ }
+
+ else if (cp === $.QUOTATION_MARK || cp === $.APOSTROPHE || cp === $.LESS_THAN_SIGN) {
+ this._createAttr(toChar(cp));
+ this.state = ATTRIBUTE_NAME_STATE;
+ }
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else {
+ this._createAttr(toChar(cp));
+ this.state = ATTRIBUTE_NAME_STATE;
+ }
+};
+
+
+//12.2.4.37 Before attribute value state
+//------------------------------------------------------------------
+_[BEFORE_ATTRIBUTE_VALUE_STATE] = function beforeAttributeValueState(cp) {
+ if (isWhitespace(cp))
+ return;
+
+ if (cp === $.QUOTATION_MARK)
+ this.state = ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE;
+
+ else if (cp === $.AMPERSAND)
+ this._reconsumeInState(ATTRIBUTE_VALUE_UNQUOTED_STATE);
+
+ else if (cp === $.APOSTROPHE)
+ this.state = ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE;
+
+ else if (cp === $.NULL) {
+ this.currentAttr.value += UNICODE.REPLACEMENT_CHARACTER;
+ this.state = ATTRIBUTE_VALUE_UNQUOTED_STATE;
+ }
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.state = DATA_STATE;
+ this._emitCurrentToken();
+ }
+
+ else if (cp === $.LESS_THAN_SIGN || cp === $.EQUALS_SIGN || cp === $.GRAVE_ACCENT) {
+ this.currentAttr.value += toChar(cp);
+ this.state = ATTRIBUTE_VALUE_UNQUOTED_STATE;
+ }
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else {
+ this.currentAttr.value += toChar(cp);
+ this.state = ATTRIBUTE_VALUE_UNQUOTED_STATE;
+ }
+};
+
+
+//12.2.4.38 Attribute value (double-quoted) state
+//------------------------------------------------------------------
+_[ATTRIBUTE_VALUE_DOUBLE_QUOTED_STATE] = function attributeValueDoubleQuotedState(cp) {
+ if (cp === $.QUOTATION_MARK)
+ this.state = AFTER_ATTRIBUTE_VALUE_QUOTED_STATE;
+
+ else if (cp === $.AMPERSAND) {
+ this.additionalAllowedCp = $.QUOTATION_MARK;
+ this.returnState = this.state;
+ this.state = CHARACTER_REFERENCE_IN_ATTRIBUTE_VALUE_STATE;
+ }
+
+ else if (cp === $.NULL)
+ this.currentAttr.value += UNICODE.REPLACEMENT_CHARACTER;
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else
+ this.currentAttr.value += toChar(cp);
+};
+
+
+//12.2.4.39 Attribute value (single-quoted) state
+//------------------------------------------------------------------
+_[ATTRIBUTE_VALUE_SINGLE_QUOTED_STATE] = function attributeValueSingleQuotedState(cp) {
+ if (cp === $.APOSTROPHE)
+ this.state = AFTER_ATTRIBUTE_VALUE_QUOTED_STATE;
+
+ else if (cp === $.AMPERSAND) {
+ this.additionalAllowedCp = $.APOSTROPHE;
+ this.returnState = this.state;
+ this.state = CHARACTER_REFERENCE_IN_ATTRIBUTE_VALUE_STATE;
+ }
+
+ else if (cp === $.NULL)
+ this.currentAttr.value += UNICODE.REPLACEMENT_CHARACTER;
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else
+ this.currentAttr.value += toChar(cp);
+};
+
+
+//12.2.4.40 Attribute value (unquoted) state
+//------------------------------------------------------------------
+_[ATTRIBUTE_VALUE_UNQUOTED_STATE] = function attributeValueUnquotedState(cp) {
+ if (isWhitespace(cp))
+ this.state = BEFORE_ATTRIBUTE_NAME_STATE;
+
+ else if (cp === $.AMPERSAND) {
+ this.additionalAllowedCp = $.GREATER_THAN_SIGN;
+ this.returnState = this.state;
+ this.state = CHARACTER_REFERENCE_IN_ATTRIBUTE_VALUE_STATE;
+ }
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.state = DATA_STATE;
+ this._emitCurrentToken();
+ }
+
+ else if (cp === $.NULL)
+ this.currentAttr.value += UNICODE.REPLACEMENT_CHARACTER;
+
+ else if (cp === $.QUOTATION_MARK || cp === $.APOSTROPHE || cp === $.LESS_THAN_SIGN ||
+ cp === $.EQUALS_SIGN || cp === $.GRAVE_ACCENT) {
+ this.currentAttr.value += toChar(cp);
+ }
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else
+ this.currentAttr.value += toChar(cp);
+};
+
+
+//12.2.4.41 Character reference in attribute value state
+//------------------------------------------------------------------
+_[CHARACTER_REFERENCE_IN_ATTRIBUTE_VALUE_STATE] = function characterReferenceInAttributeValueState(cp) {
+ var referencedCodePoints = this._consumeCharacterReference(cp, true);
+
+ if (referencedCodePoints) {
+ for (var i = 0; i < referencedCodePoints.length; i++)
+ this.currentAttr.value += toChar(referencedCodePoints[i]);
+ } else
+ this.currentAttr.value += '&';
+
+ this.state = this.returnState;
+};
+
+
+//12.2.4.42 After attribute value (quoted) state
+//------------------------------------------------------------------
+_[AFTER_ATTRIBUTE_VALUE_QUOTED_STATE] = function afterAttributeValueQuotedState(cp) {
+ if (isWhitespace(cp))
+ this.state = BEFORE_ATTRIBUTE_NAME_STATE;
+
+ else if (cp === $.SOLIDUS)
+ this.state = SELF_CLOSING_START_TAG_STATE;
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.state = DATA_STATE;
+ this._emitCurrentToken();
+ }
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else
+ this._reconsumeInState(BEFORE_ATTRIBUTE_NAME_STATE);
+};
+
+
+//12.2.4.43 Self-closing start tag state
+//------------------------------------------------------------------
+_[SELF_CLOSING_START_TAG_STATE] = function selfClosingStartTagState(cp) {
+ if (cp === $.GREATER_THAN_SIGN) {
+ this.currentToken.selfClosing = true;
+ this.state = DATA_STATE;
+ this._emitCurrentToken();
+ }
+
+ else if (cp === $.EOF)
+ this._reconsumeInState(DATA_STATE);
+
+ else
+ this._reconsumeInState(BEFORE_ATTRIBUTE_NAME_STATE);
+};
+
+
+//12.2.4.44 Bogus comment state
+//------------------------------------------------------------------
+_[BOGUS_COMMENT_STATE] = function bogusCommentState(cp) {
+ this._createCommentToken();
+
+ while (true) {
+ if (cp === $.GREATER_THAN_SIGN) {
+ this.state = DATA_STATE;
+ break;
+ }
+
+ else if (cp === $.EOF) {
+ this._reconsumeInState(DATA_STATE);
+ break;
+ }
+
+ else {
+ this.currentToken.data += cp === $.NULL ? UNICODE.REPLACEMENT_CHARACTER : toChar(cp);
+ cp = this._consume();
+ }
+ }
+
+ this._emitCurrentToken();
+};
+
+
+//12.2.4.45 Markup declaration open state
+//------------------------------------------------------------------
+_[MARKUP_DECLARATION_OPEN_STATE] = function markupDeclarationOpenState(cp) {
+ if (this._consumeSubsequentIfMatch($$.DASH_DASH_STRING, cp, true)) {
+ this._createCommentToken();
+ this.state = COMMENT_START_STATE;
+ }
+
+ else if (this._consumeSubsequentIfMatch($$.DOCTYPE_STRING, cp, false))
+ this.state = DOCTYPE_STATE;
+
+ else if (this.allowCDATA && this._consumeSubsequentIfMatch($$.CDATA_START_STRING, cp, true))
+ this.state = CDATA_SECTION_STATE;
+
+ else {
+ //NOTE: call bogus comment state directly with current consumed character to avoid unnecessary reconsumption.
+ this[BOGUS_COMMENT_STATE](cp);
+ }
+};
+
+
+//12.2.4.46 Comment start state
+//------------------------------------------------------------------
+_[COMMENT_START_STATE] = function commentStartState(cp) {
+ if (cp === $.HYPHEN_MINUS)
+ this.state = COMMENT_START_DASH_STATE;
+
+ else if (cp === $.NULL) {
+ this.currentToken.data += UNICODE.REPLACEMENT_CHARACTER;
+ this.state = COMMENT_STATE;
+ }
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.state = DATA_STATE;
+ this._emitCurrentToken();
+ }
+
+ else if (cp === $.EOF) {
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else {
+ this.currentToken.data += toChar(cp);
+ this.state = COMMENT_STATE;
+ }
+};
+
+
+//12.2.4.47 Comment start dash state
+//------------------------------------------------------------------
+_[COMMENT_START_DASH_STATE] = function commentStartDashState(cp) {
+ if (cp === $.HYPHEN_MINUS)
+ this.state = COMMENT_END_STATE;
+
+ else if (cp === $.NULL) {
+ this.currentToken.data += '-';
+ this.currentToken.data += UNICODE.REPLACEMENT_CHARACTER;
+ this.state = COMMENT_STATE;
+ }
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.state = DATA_STATE;
+ this._emitCurrentToken();
+ }
+
+ else if (cp === $.EOF) {
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else {
+ this.currentToken.data += '-';
+ this.currentToken.data += toChar(cp);
+ this.state = COMMENT_STATE;
+ }
+};
+
+
+//12.2.4.48 Comment state
+//------------------------------------------------------------------
+_[COMMENT_STATE] = function commentState(cp) {
+ if (cp === $.HYPHEN_MINUS)
+ this.state = COMMENT_END_DASH_STATE;
+
+ else if (cp === $.NULL)
+ this.currentToken.data += UNICODE.REPLACEMENT_CHARACTER;
+
+ else if (cp === $.EOF) {
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else
+ this.currentToken.data += toChar(cp);
+};
+
+
+//12.2.4.49 Comment end dash state
+//------------------------------------------------------------------
+_[COMMENT_END_DASH_STATE] = function commentEndDashState(cp) {
+ if (cp === $.HYPHEN_MINUS)
+ this.state = COMMENT_END_STATE;
+
+ else if (cp === $.NULL) {
+ this.currentToken.data += '-';
+ this.currentToken.data += UNICODE.REPLACEMENT_CHARACTER;
+ this.state = COMMENT_STATE;
+ }
+
+ else if (cp === $.EOF) {
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else {
+ this.currentToken.data += '-';
+ this.currentToken.data += toChar(cp);
+ this.state = COMMENT_STATE;
+ }
+};
+
+
+//12.2.4.50 Comment end state
+//------------------------------------------------------------------
+_[COMMENT_END_STATE] = function commentEndState(cp) {
+ if (cp === $.GREATER_THAN_SIGN) {
+ this.state = DATA_STATE;
+ this._emitCurrentToken();
+ }
+
+ else if (cp === $.EXCLAMATION_MARK)
+ this.state = COMMENT_END_BANG_STATE;
+
+ else if (cp === $.HYPHEN_MINUS)
+ this.currentToken.data += '-';
+
+ else if (cp === $.NULL) {
+ this.currentToken.data += '--';
+ this.currentToken.data += UNICODE.REPLACEMENT_CHARACTER;
+ this.state = COMMENT_STATE;
+ }
+
+ else if (cp === $.EOF) {
+ this._reconsumeInState(DATA_STATE);
+ this._emitCurrentToken();
+ }
+
+ else {
+ this.currentToken.data += '--';
+ this.currentToken.data += toChar(cp);
+ this.state = COMMENT_STATE;
+ }
+};
+
+
+//12.2.4.51 Comment end bang state
+//------------------------------------------------------------------
+_[COMMENT_END_BANG_STATE] = function commentEndBangState(cp) {
+ if (cp === $.HYPHEN_MINUS) {
+ this.currentToken.data += '--!';
+ this.state = COMMENT_END_DASH_STATE;
+ }
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.state = DATA_STATE;
+ this._emitCurrentToken();
+ }
+
+ else if (cp === $.NULL) {
+ this.currentToken.data += '--!';
+ this.currentToken.data += UNICODE.REPLACEMENT_CHARACTER;
+ this.state = COMMENT_STATE;
+ }
+
+ else if (cp === $.EOF) {
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else {
+ this.currentToken.data += '--!';
+ this.currentToken.data += toChar(cp);
+ this.state = COMMENT_STATE;
+ }
+};
+
+
+//12.2.4.52 DOCTYPE state
+//------------------------------------------------------------------
+_[DOCTYPE_STATE] = function doctypeState(cp) {
+ if (isWhitespace(cp))
+ this.state = BEFORE_DOCTYPE_NAME_STATE;
+
+ else if (cp === $.EOF) {
+ this._createDoctypeToken();
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else
+ this._reconsumeInState(BEFORE_DOCTYPE_NAME_STATE);
+};
+
+
+//12.2.4.53 Before DOCTYPE name state
+//------------------------------------------------------------------
+_[BEFORE_DOCTYPE_NAME_STATE] = function beforeDoctypeNameState(cp) {
+ if (isWhitespace(cp))
+ return;
+
+ if (isAsciiUpper(cp)) {
+ this._createDoctypeToken(toAsciiLowerChar(cp));
+ this.state = DOCTYPE_NAME_STATE;
+ }
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this._createDoctypeToken();
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ }
+
+ else if (cp === $.EOF) {
+ this._createDoctypeToken();
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else if (cp === $.NULL) {
+ this._createDoctypeToken(UNICODE.REPLACEMENT_CHARACTER);
+ this.state = DOCTYPE_NAME_STATE;
+ }
+
+ else {
+ this._createDoctypeToken(toChar(cp));
+ this.state = DOCTYPE_NAME_STATE;
+ }
+};
+
+
+//12.2.4.54 DOCTYPE name state
+//------------------------------------------------------------------
+_[DOCTYPE_NAME_STATE] = function doctypeNameState(cp) {
+ if (isWhitespace(cp))
+ this.state = AFTER_DOCTYPE_NAME_STATE;
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ }
+
+ else if (isAsciiUpper(cp))
+ this.currentToken.name += toAsciiLowerChar(cp);
+
+ else if (cp === $.NULL)
+ this.currentToken.name += UNICODE.REPLACEMENT_CHARACTER;
+
+ else if (cp === $.EOF) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else
+ this.currentToken.name += toChar(cp);
+};
+
+
+//12.2.4.55 After DOCTYPE name state
+//------------------------------------------------------------------
+_[AFTER_DOCTYPE_NAME_STATE] = function afterDoctypeNameState(cp) {
+ if (isWhitespace(cp))
+ return;
+
+ if (cp === $.GREATER_THAN_SIGN) {
+ this.state = DATA_STATE;
+ this._emitCurrentToken();
+ }
+
+ else if (cp === $.EOF) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else if (this._consumeSubsequentIfMatch($$.PUBLIC_STRING, cp, false))
+ this.state = AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE;
+
+ else if (this._consumeSubsequentIfMatch($$.SYSTEM_STRING, cp, false))
+ this.state = AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE;
+
+ else {
+ this.currentToken.forceQuirks = true;
+ this.state = BOGUS_DOCTYPE_STATE;
+ }
+};
+
+
+//12.2.4.56 After DOCTYPE public keyword state
+//------------------------------------------------------------------
+_[AFTER_DOCTYPE_PUBLIC_KEYWORD_STATE] = function afterDoctypePublicKeywordState(cp) {
+ if (isWhitespace(cp))
+ this.state = BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE;
+
+ else if (cp === $.QUOTATION_MARK) {
+ this.currentToken.publicId = '';
+ this.state = DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE;
+ }
+
+ else if (cp === $.APOSTROPHE) {
+ this.currentToken.publicId = '';
+ this.state = DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE;
+ }
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ }
+
+ else if (cp === $.EOF) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else {
+ this.currentToken.forceQuirks = true;
+ this.state = BOGUS_DOCTYPE_STATE;
+ }
+};
+
+
+//12.2.4.57 Before DOCTYPE public identifier state
+//------------------------------------------------------------------
+_[BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE] = function beforeDoctypePublicIdentifierState(cp) {
+ if (isWhitespace(cp))
+ return;
+
+ if (cp === $.QUOTATION_MARK) {
+ this.currentToken.publicId = '';
+ this.state = DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE;
+ }
+
+ else if (cp === $.APOSTROPHE) {
+ this.currentToken.publicId = '';
+ this.state = DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE;
+ }
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ }
+
+ else if (cp === $.EOF) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else {
+ this.currentToken.forceQuirks = true;
+ this.state = BOGUS_DOCTYPE_STATE;
+ }
+};
+
+
+//12.2.4.58 DOCTYPE public identifier (double-quoted) state
+//------------------------------------------------------------------
+_[DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED_STATE] = function doctypePublicIdentifierDoubleQuotedState(cp) {
+ if (cp === $.QUOTATION_MARK)
+ this.state = AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE;
+
+ else if (cp === $.NULL)
+ this.currentToken.publicId += UNICODE.REPLACEMENT_CHARACTER;
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ }
+
+ else if (cp === $.EOF) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else
+ this.currentToken.publicId += toChar(cp);
+};
+
+
+//12.2.4.59 DOCTYPE public identifier (single-quoted) state
+//------------------------------------------------------------------
+_[DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED_STATE] = function doctypePublicIdentifierSingleQuotedState(cp) {
+ if (cp === $.APOSTROPHE)
+ this.state = AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE;
+
+ else if (cp === $.NULL)
+ this.currentToken.publicId += UNICODE.REPLACEMENT_CHARACTER;
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ }
+
+ else if (cp === $.EOF) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else
+ this.currentToken.publicId += toChar(cp);
+};
+
+
+//12.2.4.60 After DOCTYPE public identifier state
+//------------------------------------------------------------------
+_[AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE] = function afterDoctypePublicIdentifierState(cp) {
+ if (isWhitespace(cp))
+ this.state = BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE;
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ }
+
+ else if (cp === $.QUOTATION_MARK) {
+ this.currentToken.systemId = '';
+ this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
+ }
+
+ else if (cp === $.APOSTROPHE) {
+ this.currentToken.systemId = '';
+ this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
+ }
+
+ else if (cp === $.EOF) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else {
+ this.currentToken.forceQuirks = true;
+ this.state = BOGUS_DOCTYPE_STATE;
+ }
+};
+
+
+//12.2.4.61 Between DOCTYPE public and system identifiers state
+//------------------------------------------------------------------
+_[BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS_STATE] = function betweenDoctypePublicAndSystemIdentifiersState(cp) {
+ if (isWhitespace(cp))
+ return;
+
+ if (cp === $.GREATER_THAN_SIGN) {
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ }
+
+ else if (cp === $.QUOTATION_MARK) {
+ this.currentToken.systemId = '';
+ this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
+ }
+
+
+ else if (cp === $.APOSTROPHE) {
+ this.currentToken.systemId = '';
+ this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
+ }
+
+ else if (cp === $.EOF) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else {
+ this.currentToken.forceQuirks = true;
+ this.state = BOGUS_DOCTYPE_STATE;
+ }
+};
+
+
+//12.2.4.62 After DOCTYPE system keyword state
+//------------------------------------------------------------------
+_[AFTER_DOCTYPE_SYSTEM_KEYWORD_STATE] = function afterDoctypeSystemKeywordState(cp) {
+ if (isWhitespace(cp))
+ this.state = BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
+
+ else if (cp === $.QUOTATION_MARK) {
+ this.currentToken.systemId = '';
+ this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
+ }
+
+ else if (cp === $.APOSTROPHE) {
+ this.currentToken.systemId = '';
+ this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
+ }
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ }
+
+ else if (cp === $.EOF) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else {
+ this.currentToken.forceQuirks = true;
+ this.state = BOGUS_DOCTYPE_STATE;
+ }
+};
+
+
+//12.2.4.63 Before DOCTYPE system identifier state
+//------------------------------------------------------------------
+_[BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE] = function beforeDoctypeSystemIdentifierState(cp) {
+ if (isWhitespace(cp))
+ return;
+
+ if (cp === $.QUOTATION_MARK) {
+ this.currentToken.systemId = '';
+ this.state = DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE;
+ }
+
+ else if (cp === $.APOSTROPHE) {
+ this.currentToken.systemId = '';
+ this.state = DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE;
+ }
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ }
+
+ else if (cp === $.EOF) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else {
+ this.currentToken.forceQuirks = true;
+ this.state = BOGUS_DOCTYPE_STATE;
+ }
+};
+
+
+//12.2.4.64 DOCTYPE system identifier (double-quoted) state
+//------------------------------------------------------------------
+_[DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED_STATE] = function doctypeSystemIdentifierDoubleQuotedState(cp) {
+ if (cp === $.QUOTATION_MARK)
+ this.state = AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ }
+
+ else if (cp === $.NULL)
+ this.currentToken.systemId += UNICODE.REPLACEMENT_CHARACTER;
+
+ else if (cp === $.EOF) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else
+ this.currentToken.systemId += toChar(cp);
+};
+
+
+//12.2.4.65 DOCTYPE system identifier (single-quoted) state
+//------------------------------------------------------------------
+_[DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED_STATE] = function doctypeSystemIdentifierSingleQuotedState(cp) {
+ if (cp === $.APOSTROPHE)
+ this.state = AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
+
+ else if (cp === $.GREATER_THAN_SIGN) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ }
+
+ else if (cp === $.NULL)
+ this.currentToken.systemId += UNICODE.REPLACEMENT_CHARACTER;
+
+ else if (cp === $.EOF) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else
+ this.currentToken.systemId += toChar(cp);
+};
+
+
+//12.2.4.66 After DOCTYPE system identifier state
+//------------------------------------------------------------------
+_[AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE] = function afterDoctypeSystemIdentifierState(cp) {
+ if (isWhitespace(cp))
+ return;
+
+ if (cp === $.GREATER_THAN_SIGN) {
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ }
+
+ else if (cp === $.EOF) {
+ this.currentToken.forceQuirks = true;
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+
+ else
+ this.state = BOGUS_DOCTYPE_STATE;
+};
+
+
+//12.2.4.67 Bogus DOCTYPE state
+//------------------------------------------------------------------
+_[BOGUS_DOCTYPE_STATE] = function bogusDoctypeState(cp) {
+ if (cp === $.GREATER_THAN_SIGN) {
+ this._emitCurrentToken();
+ this.state = DATA_STATE;
+ }
+
+ else if (cp === $.EOF) {
+ this._emitCurrentToken();
+ this._reconsumeInState(DATA_STATE);
+ }
+};
+
+
+//12.2.4.68 CDATA section state
+//------------------------------------------------------------------
+_[CDATA_SECTION_STATE] = function cdataSectionState(cp) {
+ while (true) {
+ if (cp === $.EOF) {
+ this._reconsumeInState(DATA_STATE);
+ break;
+ }
+
+ else if (this._consumeSubsequentIfMatch($$.CDATA_END_STRING, cp, true)) {
+ this.state = DATA_STATE;
+ break;
+ }
+
+ else {
+ this._emitCodePoint(cp);
+ cp = this._consume();
+ }
+ }
+};
+
+},{"../common/unicode":43,"./location_info_mixin":50,"./named_entity_trie":51,"./preprocessor":52}],54:[function(require,module,exports){
+'use strict';
+
+//Node construction
+exports.createDocument = function () {
+ return {
+ nodeName: '#document',
+ quirksMode: false,
+ childNodes: []
+ };
+};
+
+exports.createDocumentFragment = function () {
+ return {
+ nodeName: '#document-fragment',
+ quirksMode: false,
+ childNodes: []
+ };
+};
+
+exports.createElement = function (tagName, namespaceURI, attrs) {
+ return {
+ nodeName: tagName,
+ tagName: tagName,
+ attrs: attrs,
+ namespaceURI: namespaceURI,
+ childNodes: [],
+ parentNode: null
+ };
+};
+
+exports.createCommentNode = function (data) {
+ return {
+ nodeName: '#comment',
+ data: data,
+ parentNode: null
+ };
+};
+
+var createTextNode = function (value) {
+ return {
+ nodeName: '#text',
+ value: value,
+ parentNode: null
+ }
+};
+
+
+//Tree mutation
+exports.setDocumentType = function (document, name, publicId, systemId) {
+ var doctypeNode = null;
+
+ for (var i = 0; i < document.childNodes.length; i++) {
+ if (document.childNodes[i].nodeName === '#documentType') {
+ doctypeNode = document.childNodes[i];
+ break;
+ }
+ }
+
+ if (doctypeNode) {
+ doctypeNode.name = name;
+ doctypeNode.publicId = publicId;
+ doctypeNode.systemId = systemId;
+ }
+
+ else {
+ appendChild(document, {
+ nodeName: '#documentType',
+ name: name,
+ publicId: publicId,
+ systemId: systemId
+ });
+ }
+};
+
+exports.setQuirksMode = function (document) {
+ document.quirksMode = true;
+};
+
+exports.isQuirksMode = function (document) {
+ return document.quirksMode;
+};
+
+var appendChild = exports.appendChild = function (parentNode, newNode) {
+ parentNode.childNodes.push(newNode);
+ newNode.parentNode = parentNode;
+};
+
+var insertBefore = exports.insertBefore = function (parentNode, newNode, referenceNode) {
+ var insertionIdx = parentNode.childNodes.indexOf(referenceNode);
+
+ parentNode.childNodes.splice(insertionIdx, 0, newNode);
+ newNode.parentNode = parentNode;
+};
+
+exports.detachNode = function (node) {
+ if (node.parentNode) {
+ var idx = node.parentNode.childNodes.indexOf(node);
+
+ node.parentNode.childNodes.splice(idx, 1);
+ node.parentNode = null;
+ }
+};
+
+exports.insertText = function (parentNode, text) {
+ if (parentNode.childNodes.length) {
+ var prevNode = parentNode.childNodes[parentNode.childNodes.length - 1];
+
+ if (prevNode.nodeName === '#text') {
+ prevNode.value += text;
+ return;
+ }
+ }
+
+ appendChild(parentNode, createTextNode(text));
+};
+
+exports.insertTextBefore = function (parentNode, text, referenceNode) {
+ var prevNode = parentNode.childNodes[parentNode.childNodes.indexOf(referenceNode) - 1];
+
+ if (prevNode && prevNode.nodeName === '#text')
+ prevNode.value += text;
+ else
+ insertBefore(parentNode, createTextNode(text), referenceNode);
+};
+
+exports.adoptAttributes = function (recipientNode, attrs) {
+ var recipientAttrsMap = [];
+
+ for (var i = 0; i < recipientNode.attrs.length; i++)
+ recipientAttrsMap.push(recipientNode.attrs[i].name);
+
+ for (var j = 0; j < attrs.length; j++) {
+ if (recipientAttrsMap.indexOf(attrs[j].name) === -1)
+ recipientNode.attrs.push(attrs[j]);
+ }
+};
+
+
+//Tree traversing
+exports.getFirstChild = function (node) {
+ return node.childNodes[0];
+};
+
+exports.getChildNodes = function (node) {
+ return node.childNodes;
+};
+
+exports.getParentNode = function (node) {
+ return node.parentNode;
+};
+
+exports.getAttrList = function (node) {
+ return node.attrs;
+};
+
+//Node data
+exports.getTagName = function (element) {
+ return element.tagName;
+};
+
+exports.getNamespaceURI = function (element) {
+ return element.namespaceURI;
+};
+
+exports.getTextNodeContent = function (textNode) {
+ return textNode.value;
+};
+
+exports.getCommentNodeContent = function (commentNode) {
+ return commentNode.data;
+};
+
+exports.getDocumentTypeNodeName = function (doctypeNode) {
+ return doctypeNode.name;
+};
+
+exports.getDocumentTypeNodePublicId = function (doctypeNode) {
+ return doctypeNode.publicId;
+};
+
+exports.getDocumentTypeNodeSystemId = function (doctypeNode) {
+ return doctypeNode.systemId;
+};
+
+//Node types
+exports.isTextNode = function (node) {
+ return node.nodeName === '#text';
+};
+
+exports.isCommentNode = function (node) {
+ return node.nodeName === '#comment';
+};
+
+exports.isDocumentTypeNode = function (node) {
+ return node.nodeName === '#documentType';
+};
+
+exports.isElementNode = function (node) {
+ return !!node.tagName;
+};
+
+},{}],55:[function(require,module,exports){
+'use strict';
+
+var Doctype = require('../common/doctype');
+
+//Conversion tables for DOM Level1 structure emulation
+var nodeTypes = {
+ element: 1,
+ text: 3,
+ cdata: 4,
+ comment: 8
+};
+
+var nodePropertyShorthands = {
+ tagName: 'name',
+ childNodes: 'children',
+ parentNode: 'parent',
+ previousSibling: 'prev',
+ nextSibling: 'next',
+ nodeValue: 'data'
+};
+
+//Node
+var Node = function (props) {
+ for (var key in props) {
+ if (props.hasOwnProperty(key))
+ this[key] = props[key];
+ }
+};
+
+Node.prototype = {
+ get firstChild() {
+ var children = this.children;
+ return children && children[0] || null;
+ },
+
+ get lastChild() {
+ var children = this.children;
+ return children && children[children.length - 1] || null;
+ },
+
+ get nodeType() {
+ return nodeTypes[this.type] || nodeTypes.element;
+ }
+};
+
+Object.keys(nodePropertyShorthands).forEach(function (key) {
+ var shorthand = nodePropertyShorthands[key];
+
+ Object.defineProperty(Node.prototype, key, {
+ get: function () {
+ return this[shorthand] || null;
+ },
+ set: function (val) {
+ this[shorthand] = val;
+ return val;
+ }
+ });
+});
+
+
+//Node construction
+exports.createDocument =
+exports.createDocumentFragment = function () {
+ return new Node({
+ type: 'root',
+ name: 'root',
+ parent: null,
+ prev: null,
+ next: null,
+ children: []
+ });
+};
+
+exports.createElement = function (tagName, namespaceURI, attrs) {
+ var attribs = {},
+ attribsNamespace = {},
+ attribsPrefix = {};
+
+ for (var i = 0; i < attrs.length; i++) {
+ var attrName = attrs[i].name;
+
+ attribs[attrName] = attrs[i].value;
+ attribsNamespace[attrName] = attrs[i].namespace;
+ attribsPrefix[attrName] = attrs[i].prefix;
+ }
+
+ return new Node({
+ type: tagName === 'script' || tagName === 'style' ? tagName : 'tag',
+ name: tagName,
+ namespace: namespaceURI,
+ attribs: attribs,
+ 'x-attribsNamespace': attribsNamespace,
+ 'x-attribsPrefix': attribsPrefix,
+ children: [],
+ parent: null,
+ prev: null,
+ next: null
+ });
+};
+
+exports.createCommentNode = function (data) {
+ return new Node({
+ type: 'comment',
+ data: data,
+ parent: null,
+ prev: null,
+ next: null
+ });
+};
+
+var createTextNode = function (value) {
+ return new Node({
+ type: 'text',
+ data: value,
+ parent: null,
+ prev: null,
+ next: null
+ });
+};
+
+
+//Tree mutation
+exports.setDocumentType = function (document, name, publicId, systemId) {
+ var data = Doctype.serializeContent(name, publicId, systemId),
+ doctypeNode = null;
+
+ for (var i = 0; i < document.children.length; i++) {
+ if (document.children[i].type === 'directive' && document.children[i].name === '!doctype') {
+ doctypeNode = document.children[i];
+ break;
+ }
+ }
+
+ if (doctypeNode) {
+ doctypeNode.data = data;
+ doctypeNode['x-name'] = name;
+ doctypeNode['x-publicId'] = publicId;
+ doctypeNode['x-systemId'] = systemId;
+ }
+
+ else {
+ appendChild(document, new Node({
+ type: 'directive',
+ name: '!doctype',
+ data: data,
+ 'x-name': name,
+ 'x-publicId': publicId,
+ 'x-systemId': systemId
+ }));
+ }
+
+};
+
+exports.setQuirksMode = function (document) {
+ document.quirksMode = true;
+};
+
+exports.isQuirksMode = function (document) {
+ return document.quirksMode;
+};
+
+var appendChild = exports.appendChild = function (parentNode, newNode) {
+ var prev = parentNode.children[parentNode.children.length - 1];
+
+ if (prev) {
+ prev.next = newNode;
+ newNode.prev = prev;
+ }
+
+ parentNode.children.push(newNode);
+ newNode.parent = parentNode;
+};
+
+var insertBefore = exports.insertBefore = function (parentNode, newNode, referenceNode) {
+ var insertionIdx = parentNode.children.indexOf(referenceNode),
+ prev = referenceNode.prev;
+
+ if (prev) {
+ prev.next = newNode;
+ newNode.prev = prev;
+ }
+
+ referenceNode.prev = newNode;
+ newNode.next = referenceNode;
+
+ parentNode.children.splice(insertionIdx, 0, newNode);
+ newNode.parent = parentNode;
+};
+
+exports.detachNode = function (node) {
+ if (node.parent) {
+ var idx = node.parent.children.indexOf(node),
+ prev = node.prev,
+ next = node.next;
+
+ node.prev = null;
+ node.next = null;
+
+ if (prev)
+ prev.next = next;
+
+ if (next)
+ next.prev = prev;
+
+ node.parent.children.splice(idx, 1);
+ node.parent = null;
+ }
+};
+
+exports.insertText = function (parentNode, text) {
+ var lastChild = parentNode.children[parentNode.children.length - 1];
+
+ if (lastChild && lastChild.type === 'text')
+ lastChild.data += text;
+ else
+ appendChild(parentNode, createTextNode(text));
+};
+
+exports.insertTextBefore = function (parentNode, text, referenceNode) {
+ var prevNode = parentNode.children[parentNode.children.indexOf(referenceNode) - 1];
+
+ if (prevNode && prevNode.type === 'text')
+ prevNode.data += text;
+ else
+ insertBefore(parentNode, createTextNode(text), referenceNode);
+};
+
+exports.adoptAttributes = function (recipientNode, attrs) {
+ for (var i = 0; i < attrs.length; i++) {
+ var attrName = attrs[i].name;
+
+ if (typeof recipientNode.attribs[attrName] === 'undefined') {
+ recipientNode.attribs[attrName] = attrs[i].value;
+ recipientNode['x-attribsNamespace'][attrName] = attrs[i].namespace;
+ recipientNode['x-attribsPrefix'][attrName] = attrs[i].prefix;
+ }
+ }
+};
+
+
+//Tree traversing
+exports.getFirstChild = function (node) {
+ return node.children[0];
+};
+
+exports.getChildNodes = function (node) {
+ return node.children;
+};
+
+exports.getParentNode = function (node) {
+ return node.parent;
+};
+
+exports.getAttrList = function (node) {
+ var attrList = [];
+
+ for (var name in node.attribs) {
+ if (node.attribs.hasOwnProperty(name)) {
+ attrList.push({
+ name: name,
+ value: node.attribs[name],
+ namespace: node['x-attribsNamespace'][name],
+ prefix: node['x-attribsPrefix'][name]
+ });
+ }
+ }
+
+ return attrList;
+};
+
+
+//Node data
+exports.getTagName = function (element) {
+ return element.name;
+};
+
+exports.getNamespaceURI = function (element) {
+ return element.namespace;
+};
+
+exports.getTextNodeContent = function (textNode) {
+ return textNode.data;
+};
+
+exports.getCommentNodeContent = function (commentNode) {
+ return commentNode.data;
+};
+
+exports.getDocumentTypeNodeName = function (doctypeNode) {
+ return doctypeNode['x-name'];
+};
+
+exports.getDocumentTypeNodePublicId = function (doctypeNode) {
+ return doctypeNode['x-publicId'];
+};
+
+exports.getDocumentTypeNodeSystemId = function (doctypeNode) {
+ return doctypeNode['x-systemId'];
+};
+
+
+//Node types
+exports.isTextNode = function (node) {
+ return node.type === 'text';
+};
+
+exports.isCommentNode = function (node) {
+ return node.type === 'comment';
+};
+
+exports.isDocumentTypeNode = function (node) {
+ return node.type === 'directive' && node.name === '!doctype';
+};
+
+exports.isElementNode = function (node) {
+ return !!node.attribs;
+};
+
+},{"../common/doctype":40}],56:[function(require,module,exports){
+'use strict';
+
+//Const
+var NOAH_ARK_CAPACITY = 3;
+
+//List of formatting elements
+var FormattingElementList = module.exports = function (treeAdapter) {
+ this.length = 0;
+ this.entries = [];
+ this.treeAdapter = treeAdapter;
+ this.bookmark = null;
+};
+
+//Entry types
+FormattingElementList.MARKER_ENTRY = 'MARKER_ENTRY';
+FormattingElementList.ELEMENT_ENTRY = 'ELEMENT_ENTRY';
+
+//Noah Ark's condition
+//OPTIMIZATION: at first we try to find possible candidates for exclusion using
+//lightweight heuristics without thorough attributes check.
+FormattingElementList.prototype._getNoahArkConditionCandidates = function (newElement) {
+ var candidates = [];
+
+ if (this.length >= NOAH_ARK_CAPACITY) {
+ var neAttrsLength = this.treeAdapter.getAttrList(newElement).length,
+ neTagName = this.treeAdapter.getTagName(newElement),
+ neNamespaceURI = this.treeAdapter.getNamespaceURI(newElement);
+
+ for (var i = this.length - 1; i >= 0; i--) {
+ var entry = this.entries[i];
+
+ if (entry.type === FormattingElementList.MARKER_ENTRY)
+ break;
+
+ var element = entry.element,
+ elementAttrs = this.treeAdapter.getAttrList(element);
+
+ if (this.treeAdapter.getTagName(element) === neTagName &&
+ this.treeAdapter.getNamespaceURI(element) === neNamespaceURI &&
+ elementAttrs.length === neAttrsLength) {
+ candidates.push({idx: i, attrs: elementAttrs});
+ }
+ }
+ }
+
+ return candidates.length < NOAH_ARK_CAPACITY ? [] : candidates;
+};
+
+FormattingElementList.prototype._ensureNoahArkCondition = function (newElement) {
+ var candidates = this._getNoahArkConditionCandidates(newElement),
+ cLength = candidates.length;
+
+ if (cLength) {
+ var neAttrs = this.treeAdapter.getAttrList(newElement),
+ neAttrsLength = neAttrs.length,
+ neAttrsMap = {};
+
+ //NOTE: build attrs map for the new element so we can perform fast lookups
+ for (var i = 0; i < neAttrsLength; i++) {
+ var neAttr = neAttrs[i];
+
+ neAttrsMap[neAttr.name] = neAttr.value;
+ }
+
+ for (var i = 0; i < neAttrsLength; i++) {
+ for (var j = 0; j < cLength; j++) {
+ var cAttr = candidates[j].attrs[i];
+
+ if (neAttrsMap[cAttr.name] !== cAttr.value) {
+ candidates.splice(j, 1);
+ cLength--;
+ }
+
+ if (candidates.length < NOAH_ARK_CAPACITY)
+ return;
+ }
+ }
+
+ //NOTE: remove bottommost candidates until Noah's Ark condition will not be met
+ for (var i = cLength - 1; i >= NOAH_ARK_CAPACITY - 1; i--) {
+ this.entries.splice(candidates[i].idx, 1);
+ this.length--;
+ }
+ }
+};
+
+//Mutations
+FormattingElementList.prototype.insertMarker = function () {
+ this.entries.push({type: FormattingElementList.MARKER_ENTRY});
+ this.length++;
+};
+
+FormattingElementList.prototype.pushElement = function (element, token) {
+ this._ensureNoahArkCondition(element);
+
+ this.entries.push({
+ type: FormattingElementList.ELEMENT_ENTRY,
+ element: element,
+ token: token
+ });
+
+ this.length++;
+};
+
+FormattingElementList.prototype.insertElementAfterBookmark = function (element, token) {
+ var bookmarkIdx = this.length - 1;
+
+ for (; bookmarkIdx >= 0; bookmarkIdx--) {
+ if (this.entries[bookmarkIdx] === this.bookmark)
+ break;
+ }
+
+ this.entries.splice(bookmarkIdx + 1, 0, {
+ type: FormattingElementList.ELEMENT_ENTRY,
+ element: element,
+ token: token
+ });
+
+ this.length++;
+};
+
+FormattingElementList.prototype.removeEntry = function (entry) {
+ for (var i = this.length - 1; i >= 0; i--) {
+ if (this.entries[i] === entry) {
+ this.entries.splice(i, 1);
+ this.length--;
+ break;
+ }
+ }
+};
+
+FormattingElementList.prototype.clearToLastMarker = function () {
+ while (this.length) {
+ var entry = this.entries.pop();
+
+ this.length--;
+
+ if (entry.type === FormattingElementList.MARKER_ENTRY)
+ break;
+ }
+};
+
+//Search
+FormattingElementList.prototype.getElementEntryInScopeWithTagName = function (tagName) {
+ for (var i = this.length - 1; i >= 0; i--) {
+ var entry = this.entries[i];
+
+ if (entry.type === FormattingElementList.MARKER_ENTRY)
+ return null;
+
+ if (this.treeAdapter.getTagName(entry.element) === tagName)
+ return entry;
+ }
+
+ return null;
+};
+
+FormattingElementList.prototype.getElementEntry = function (element) {
+ for (var i = this.length - 1; i >= 0; i--) {
+ var entry = this.entries[i];
+
+ if (entry.type === FormattingElementList.ELEMENT_ENTRY && entry.element == element)
+ return entry;
+ }
+
+ return null;
+};
+
+},{}],57:[function(require,module,exports){
+'use strict';
+
+var OpenElementStack = require('./open_element_stack'),
+ Tokenizer = require('../tokenization/tokenizer'),
+ HTML = require('../common/html');
+
+
+//Aliases
+var $ = HTML.TAG_NAMES;
+
+
+function setEndLocation(element, endTagToken) {
+ if (element.__location)
+ element.__location.end = endTagToken.location.end;
+}
+
+//NOTE: patch open elements stack, so we can assign end location for the elements
+function patchOpenElementsStack(stack, parser) {
+ stack.pop = function () {
+ setEndLocation(this.current, parser.currentToken);
+ OpenElementStack.prototype.pop.call(this);
+ };
+
+ stack.popAllUpToHtmlElement = function () {
+ for (var i = this.stackTop; i > 0; i--)
+ setEndLocation(this.items[i], parser.currentToken);
+
+ OpenElementStack.prototype.popAllUpToHtmlElement.call(this);
+ };
+
+ stack.remove = function (element) {
+ setEndLocation(element, parser.currentToken);
+ OpenElementStack.prototype.remove.call(this, element);
+ };
+}
+
+exports.assign = function (parser) {
+ //NOTE: obtain Parser proto this way to avoid module circular references
+ var parserProto = Object.getPrototypeOf(parser);
+
+ //NOTE: patch _reset method
+ parser._reset = function (html, document, fragmentContext) {
+ parserProto._reset.call(this, html, document, fragmentContext);
+
+ this.attachableElementLocation = null;
+ this.lastFosterParentingLocation = null;
+ this.currentToken = null;
+
+ patchOpenElementsStack(this.openElements, parser);
+ };
+
+ parser._processTokenInForeignContent = function (token) {
+ this.currentToken = token;
+ parserProto._processTokenInForeignContent.call(this, token);
+ };
+
+ parser._processToken = function (token) {
+ this.currentToken = token;
+ parserProto._processToken.call(this, token);
+
+ //NOTE: <body> and <html> are never popped from the stack, so we need to updated
+ //their end location explicitly.
+ if (token.type === Tokenizer.END_TAG_TOKEN &&
+ (token.tagName === $.HTML ||
+ (token.tagName === $.BODY && this.openElements.hasInScope($.BODY)))) {
+ for (var i = this.openElements.stackTop; i >= 0; i--) {
+ var element = this.openElements.items[i];
+
+ if (this.treeAdapter.getTagName(element) === token.tagName) {
+ setEndLocation(element, token);
+ break;
+ }
+ }
+ }
+ };
+
+ //Doctype
+ parser._setDocumentType = function (token) {
+ parserProto._setDocumentType.call(this, token);
+
+ var documentChildren = this.treeAdapter.getChildNodes(this.document),
+ cnLength = documentChildren.length;
+
+ for (var i = 0; i < cnLength; i++) {
+ var node = documentChildren[i];
+
+ if (this.treeAdapter.isDocumentTypeNode(node)) {
+ node.__location = token.location;
+ break;
+ }
+ }
+ };
+
+ //Elements
+ parser._attachElementToTree = function (element) {
+ //NOTE: _attachElementToTree is called from _appendElement, _insertElement and _insertTemplate methods.
+ //So we will use token location stored in this methods for the element.
+ element.__location = this.attachableElementLocation || null;
+ this.attachableElementLocation = null;
+ parserProto._attachElementToTree.call(this, element);
+ };
+
+ parser._appendElement = function (token, namespaceURI) {
+ this.attachableElementLocation = token.location;
+ parserProto._appendElement.call(this, token, namespaceURI);
+ };
+
+ parser._insertElement = function (token, namespaceURI) {
+ this.attachableElementLocation = token.location;
+ parserProto._insertElement.call(this, token, namespaceURI);
+ };
+
+ parser._insertTemplate = function (token) {
+ this.attachableElementLocation = token.location;
+ parserProto._insertTemplate.call(this, token);
+
+ var tmplContent = this.treeAdapter.getChildNodes(this.openElements.current)[0];
+
+ tmplContent.__location = null;
+ };
+
+ parser._insertFakeRootElement = function () {
+ parserProto._insertFakeRootElement.call(this);
+ this.openElements.current.__location = null;
+ };
+
+ //Comments
+ parser._appendCommentNode = function (token, parent) {
+ parserProto._appendCommentNode.call(this, token, parent);
+
+ var children = this.treeAdapter.getChildNodes(parent),
+ commentNode = children[children.length - 1];
+
+ commentNode.__location = token.location;
+ };
+
+ //Text
+ parser._findFosterParentingLocation = function () {
+ //NOTE: store last foster parenting location, so we will be able to find inserted text
+ //in case of foster parenting
+ this.lastFosterParentingLocation = parserProto._findFosterParentingLocation.call(this);
+ return this.lastFosterParentingLocation;
+ };
+
+ parser._insertCharacters = function (token) {
+ parserProto._insertCharacters.call(this, token);
+
+ var hasFosterParent = this._shouldFosterParentOnInsertion(),
+ parentingLocation = this.lastFosterParentingLocation,
+ parent = (hasFosterParent && parentingLocation.parent) ||
+ this.openElements.currentTmplContent ||
+ this.openElements.current,
+ siblings = this.treeAdapter.getChildNodes(parent),
+ textNodeIdx = hasFosterParent && parentingLocation.beforeElement ?
+ siblings.indexOf(parentingLocation.beforeElement) - 1 :
+ siblings.length - 1,
+ textNode = siblings[textNodeIdx];
+
+ //NOTE: if we have location assigned by another token, then just update end position
+ if (textNode.__location)
+ textNode.__location.end = token.location.end;
+
+ else
+ textNode.__location = token.location;
+ };
+};
+
+
+},{"../common/html":42,"../tokenization/tokenizer":53,"./open_element_stack":58}],58:[function(require,module,exports){
+'use strict';
+
+var HTML = require('../common/html');
+
+//Aliases
+var $ = HTML.TAG_NAMES,
+ NS = HTML.NAMESPACES;
+
+//Element utils
+
+//OPTIMIZATION: Integer comparisons are low-cost, so we can use very fast tag name length filters here.
+//It's faster than using dictionary.
+function isImpliedEndTagRequired(tn) {
+ switch (tn.length) {
+ case 1:
+ return tn === $.P;
+
+ case 2:
+ return tn === $.RP || tn === $.RT || tn === $.DD || tn === $.DT || tn === $.LI;
+
+ case 6:
+ return tn === $.OPTION;
+
+ case 8:
+ return tn === $.OPTGROUP;
+ }
+
+ return false;
+}
+
+function isScopingElement(tn, ns) {
+ switch (tn.length) {
+ case 2:
+ if (tn === $.TD || tn === $.TH)
+ return ns === NS.HTML;
+
+ else if (tn === $.MI || tn === $.MO || tn == $.MN || tn === $.MS)
+ return ns === NS.MATHML;
+
+ break;
+
+ case 4:
+ if (tn === $.HTML)
+ return ns === NS.HTML;
+
+ else if (tn === $.DESC)
+ return ns === NS.SVG;
+
+ break;
+
+ case 5:
+ if (tn === $.TABLE)
+ return ns === NS.HTML;
+
+ else if (tn === $.MTEXT)
+ return ns === NS.MATHML;
+
+ else if (tn === $.TITLE)
+ return ns === NS.SVG;
+
+ break;
+
+ case 6:
+ return (tn === $.APPLET || tn === $.OBJECT) && ns === NS.HTML;
+
+ case 7:
+ return (tn === $.CAPTION || tn === $.MARQUEE) && ns === NS.HTML;
+
+ case 8:
+ return tn === $.TEMPLATE && ns === NS.HTML;
+
+ case 13:
+ return tn === $.FOREIGN_OBJECT && ns === NS.SVG;
+
+ case 14:
+ return tn === $.ANNOTATION_XML && ns === NS.MATHML;
+ }
+
+ return false;
+}
+
+//Stack of open elements
+var OpenElementStack = module.exports = function (document, treeAdapter) {
+ this.stackTop = -1;
+ this.items = [];
+ this.current = document;
+ this.currentTagName = null;
+ this.currentTmplContent = null;
+ this.tmplCount = 0;
+ this.treeAdapter = treeAdapter;
+};
+
+//Index of element
+OpenElementStack.prototype._indexOf = function (element) {
+ var idx = -1;
+
+ for (var i = this.stackTop; i >= 0; i--) {
+ if (this.items[i] === element) {
+ idx = i;
+ break;
+ }
+ }
+ return idx;
+};
+
+//Update current element
+OpenElementStack.prototype._isInTemplate = function () {
+ if (this.currentTagName !== $.TEMPLATE)
+ return false;
+
+ return this.treeAdapter.getNamespaceURI(this.current) === NS.HTML;
+};
+
+OpenElementStack.prototype._updateCurrentElement = function () {
+ this.current = this.items[this.stackTop];
+ this.currentTagName = this.current && this.treeAdapter.getTagName(this.current);
+
+ this.currentTmplContent = this._isInTemplate() ? this.treeAdapter.getChildNodes(this.current)[0] : null;
+};
+
+//Mutations
+OpenElementStack.prototype.push = function (element) {
+ this.items[++this.stackTop] = element;
+ this._updateCurrentElement();
+
+ if (this._isInTemplate())
+ this.tmplCount++;
+
+};
+
+OpenElementStack.prototype.pop = function () {
+ this.stackTop--;
+
+ if (this.tmplCount > 0 && this._isInTemplate())
+ this.tmplCount--;
+
+ this._updateCurrentElement();
+};
+
+OpenElementStack.prototype.replace = function (oldElement, newElement) {
+ var idx = this._indexOf(oldElement);
+ this.items[idx] = newElement;
+
+ if (idx === this.stackTop)
+ this._updateCurrentElement();
+};
+
+OpenElementStack.prototype.insertAfter = function (referenceElement, newElement) {
+ var insertionIdx = this._indexOf(referenceElement) + 1;
+
+ this.items.splice(insertionIdx, 0, newElement);
+
+ if (insertionIdx == ++this.stackTop)
+ this._updateCurrentElement();
+};
+
+OpenElementStack.prototype.popUntilTagNamePopped = function (tagName) {
+ while (this.stackTop > -1) {
+ var tn = this.currentTagName;
+
+ this.pop();
+
+ if (tn === tagName)
+ break;
+ }
+};
+
+OpenElementStack.prototype.popUntilTemplatePopped = function () {
+ while (this.stackTop > -1) {
+ var tn = this.currentTagName,
+ ns = this.treeAdapter.getNamespaceURI(this.current);
+
+ this.pop();
+
+ if (tn === $.TEMPLATE && ns === NS.HTML)
+ break;
+ }
+};
+
+OpenElementStack.prototype.popUntilElementPopped = function (element) {
+ while (this.stackTop > -1) {
+ var poppedElement = this.current;
+
+ this.pop();
+
+ if (poppedElement === element)
+ break;
+ }
+};
+
+OpenElementStack.prototype.popUntilNumberedHeaderPopped = function () {
+ while (this.stackTop > -1) {
+ var tn = this.currentTagName;
+
+ this.pop();
+
+ if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6)
+ break;
+ }
+};
+
+OpenElementStack.prototype.popAllUpToHtmlElement = function () {
+ //NOTE: here we assume that root <html> element is always first in the open element stack, so
+ //we perform this fast stack clean up.
+ this.stackTop = 0;
+ this._updateCurrentElement();
+};
+
+OpenElementStack.prototype.clearBackToTableContext = function () {
+ while (this.currentTagName !== $.TABLE && this.currentTagName !== $.TEMPLATE && this.currentTagName !== $.HTML)
+ this.pop();
+};
+
+OpenElementStack.prototype.clearBackToTableBodyContext = function () {
+ while (this.currentTagName !== $.TBODY && this.currentTagName !== $.TFOOT &&
+ this.currentTagName !== $.THEAD && this.currentTagName !== $.TEMPLATE &&
+ this.currentTagName !== $.HTML) {
+ this.pop();
+ }
+};
+
+OpenElementStack.prototype.clearBackToTableRowContext = function () {
+ while (this.currentTagName !== $.TR && this.currentTagName !== $.TEMPLATE && this.currentTagName !== $.HTML)
+ this.pop();
+};
+
+OpenElementStack.prototype.remove = function (element) {
+ for (var i = this.stackTop; i >= 0; i--) {
+ if (this.items[i] === element) {
+ this.items.splice(i, 1);
+ this.stackTop--;
+ this._updateCurrentElement();
+ break;
+ }
+ }
+};
+
+//Search
+OpenElementStack.prototype.tryPeekProperlyNestedBodyElement = function () {
+ //Properly nested <body> element (should be second element in stack).
+ var element = this.items[1];
+ return element && this.treeAdapter.getTagName(element) === $.BODY ? element : null;
+};
+
+OpenElementStack.prototype.contains = function (element) {
+ return this._indexOf(element) > -1;
+};
+
+OpenElementStack.prototype.getCommonAncestor = function (element) {
+ var elementIdx = this._indexOf(element);
+
+ return --elementIdx >= 0 ? this.items[elementIdx] : null;
+};
+
+OpenElementStack.prototype.isRootHtmlElementCurrent = function () {
+ return this.stackTop === 0 && this.currentTagName === $.HTML;
+};
+
+//Element in scope
+OpenElementStack.prototype.hasInScope = function (tagName) {
+ for (var i = this.stackTop; i >= 0; i--) {
+ var tn = this.treeAdapter.getTagName(this.items[i]);
+
+ if (tn === tagName)
+ return true;
+
+ var ns = this.treeAdapter.getNamespaceURI(this.items[i]);
+
+ if (isScopingElement(tn, ns))
+ return false;
+ }
+
+ return true;
+};
+
+OpenElementStack.prototype.hasNumberedHeaderInScope = function () {
+ for (var i = this.stackTop; i >= 0; i--) {
+ var tn = this.treeAdapter.getTagName(this.items[i]);
+
+ if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6)
+ return true;
+
+ if (isScopingElement(tn, this.treeAdapter.getNamespaceURI(this.items[i])))
+ return false;
+ }
+
+ return true;
+};
+
+OpenElementStack.prototype.hasInListItemScope = function (tagName) {
+ for (var i = this.stackTop; i >= 0; i--) {
+ var tn = this.treeAdapter.getTagName(this.items[i]);
+
+ if (tn === tagName)
+ return true;
+
+ var ns = this.treeAdapter.getNamespaceURI(this.items[i]);
+
+ if (((tn === $.UL || tn === $.OL) && ns === NS.HTML) || isScopingElement(tn, ns))
+ return false;
+ }
+
+ return true;
+};
+
+OpenElementStack.prototype.hasInButtonScope = function (tagName) {
+ for (var i = this.stackTop; i >= 0; i--) {
+ var tn = this.treeAdapter.getTagName(this.items[i]);
+
+ if (tn === tagName)
+ return true;
+
+ var ns = this.treeAdapter.getNamespaceURI(this.items[i]);
+
+ if ((tn === $.BUTTON && ns === NS.HTML) || isScopingElement(tn, ns))
+ return false;
+ }
+
+ return true;
+};
+
+OpenElementStack.prototype.hasInTableScope = function (tagName) {
+ for (var i = this.stackTop; i >= 0; i--) {
+ var tn = this.treeAdapter.getTagName(this.items[i]);
+
+ if (tn === tagName)
+ return true;
+
+ var ns = this.treeAdapter.getNamespaceURI(this.items[i]);
+
+ if ((tn === $.TABLE || tn === $.TEMPLATE || tn === $.HTML) && ns === NS.HTML)
+ return false;
+ }
+
+ return true;
+};
+
+OpenElementStack.prototype.hasTableBodyContextInTableScope = function () {
+ for (var i = this.stackTop; i >= 0; i--) {
+ var tn = this.treeAdapter.getTagName(this.items[i]);
+
+ if (tn === $.TBODY || tn === $.THEAD || tn === $.TFOOT)
+ return true;
+
+ var ns = this.treeAdapter.getNamespaceURI(this.items[i]);
+
+ if ((tn === $.TABLE || tn === $.HTML) && ns === NS.HTML)
+ return false;
+ }
+
+ return true;
+};
+
+OpenElementStack.prototype.hasInSelectScope = function (tagName) {
+ for (var i = this.stackTop; i >= 0; i--) {
+ var tn = this.treeAdapter.getTagName(this.items[i]);
+
+ if (tn === tagName)
+ return true;
+
+ var ns = this.treeAdapter.getNamespaceURI(this.items[i]);
+
+ if (tn !== $.OPTION && tn !== $.OPTGROUP && ns === NS.HTML)
+ return false;
+ }
+
+ return true;
+};
+
+//Implied end tags
+OpenElementStack.prototype.generateImpliedEndTags = function () {
+ while (isImpliedEndTagRequired(this.currentTagName))
+ this.pop();
+};
+
+OpenElementStack.prototype.generateImpliedEndTagsWithExclusion = function (exclusionTagName) {
+ while (isImpliedEndTagRequired(this.currentTagName) && this.currentTagName !== exclusionTagName)
+ this.pop();
+};
+
+},{"../common/html":42}],59:[function(require,module,exports){
+'use strict';
+
+var Tokenizer = require('../tokenization/tokenizer'),
+ OpenElementStack = require('./open_element_stack'),
+ FormattingElementList = require('./formatting_element_list'),
+ LocationInfoMixin = require('./location_info_mixin'),
+ DefaultTreeAdapter = require('../tree_adapters/default'),
+ Doctype = require('../common/doctype'),
+ ForeignContent = require('../common/foreign_content'),
+ Utils = require('../common/utils'),
+ UNICODE = require('../common/unicode'),
+ HTML = require('../common/html');
+
+//Aliases
+var $ = HTML.TAG_NAMES,
+ NS = HTML.NAMESPACES,
+ ATTRS = HTML.ATTRS;
+
+//Default options
+var DEFAULT_OPTIONS = {
+ decodeHtmlEntities: true,
+ locationInfo: false
+};
+
+//Misc constants
+var SEARCHABLE_INDEX_DEFAULT_PROMPT = 'This is a searchable index. Enter search keywords: ',
+ SEARCHABLE_INDEX_INPUT_NAME = 'isindex',
+ HIDDEN_INPUT_TYPE = 'hidden';
+
+//Adoption agency loops iteration count
+var AA_OUTER_LOOP_ITER = 8,
+ AA_INNER_LOOP_ITER = 3;
+
+//Insertion modes
+var INITIAL_MODE = 'INITIAL_MODE',
+ BEFORE_HTML_MODE = 'BEFORE_HTML_MODE',
+ BEFORE_HEAD_MODE = 'BEFORE_HEAD_MODE',
+ IN_HEAD_MODE = 'IN_HEAD_MODE',
+ AFTER_HEAD_MODE = 'AFTER_HEAD_MODE',
+ IN_BODY_MODE = 'IN_BODY_MODE',
+ TEXT_MODE = 'TEXT_MODE',
+ IN_TABLE_MODE = 'IN_TABLE_MODE',
+ IN_TABLE_TEXT_MODE = 'IN_TABLE_TEXT_MODE',
+ IN_CAPTION_MODE = 'IN_CAPTION_MODE',
+ IN_COLUMN_GROUP_MODE = 'IN_COLUMN_GROUP_MODE',
+ IN_TABLE_BODY_MODE = 'IN_TABLE_BODY_MODE',
+ IN_ROW_MODE = 'IN_ROW_MODE',
+ IN_CELL_MODE = 'IN_CELL_MODE',
+ IN_SELECT_MODE = 'IN_SELECT_MODE',
+ IN_SELECT_IN_TABLE_MODE = 'IN_SELECT_IN_TABLE_MODE',
+ IN_TEMPLATE_MODE = 'IN_TEMPLATE_MODE',
+ AFTER_BODY_MODE = 'AFTER_BODY_MODE',
+ IN_FRAMESET_MODE = 'IN_FRAMESET_MODE',
+ AFTER_FRAMESET_MODE = 'AFTER_FRAMESET_MODE',
+ AFTER_AFTER_BODY_MODE = 'AFTER_AFTER_BODY_MODE',
+ AFTER_AFTER_FRAMESET_MODE = 'AFTER_AFTER_FRAMESET_MODE';
+
+//Insertion mode reset map
+var INSERTION_MODE_RESET_MAP = {};
+
+INSERTION_MODE_RESET_MAP[$.TR] = IN_ROW_MODE;
+INSERTION_MODE_RESET_MAP[$.TBODY] =
+INSERTION_MODE_RESET_MAP[$.THEAD] =
+INSERTION_MODE_RESET_MAP[$.TFOOT] = IN_TABLE_BODY_MODE;
+INSERTION_MODE_RESET_MAP[$.CAPTION] = IN_CAPTION_MODE;
+INSERTION_MODE_RESET_MAP[$.COLGROUP] = IN_COLUMN_GROUP_MODE;
+INSERTION_MODE_RESET_MAP[$.TABLE] = IN_TABLE_MODE;
+INSERTION_MODE_RESET_MAP[$.BODY] = IN_BODY_MODE;
+INSERTION_MODE_RESET_MAP[$.FRAMESET] = IN_FRAMESET_MODE;
+
+//Template insertion mode switch map
+var TEMPLATE_INSERTION_MODE_SWITCH_MAP = {};
+
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.CAPTION] =
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.COLGROUP] =
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TBODY] =
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TFOOT] =
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.THEAD] = IN_TABLE_MODE;
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.COL] = IN_COLUMN_GROUP_MODE;
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TR] = IN_TABLE_BODY_MODE;
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TD] =
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TH] = IN_ROW_MODE;
+
+//Token handlers map for insertion modes
+var _ = {};
+
+_[INITIAL_MODE] = {};
+_[INITIAL_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[INITIAL_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenInInitialMode;
+_[INITIAL_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = ignoreToken;
+_[INITIAL_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[INITIAL_MODE][Tokenizer.DOCTYPE_TOKEN] = doctypeInInitialMode;
+_[INITIAL_MODE][Tokenizer.START_TAG_TOKEN] =
+_[INITIAL_MODE][Tokenizer.END_TAG_TOKEN] =
+_[INITIAL_MODE][Tokenizer.EOF_TOKEN] = tokenInInitialMode;
+
+_[BEFORE_HTML_MODE] = {};
+_[BEFORE_HTML_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[BEFORE_HTML_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenBeforeHtml;
+_[BEFORE_HTML_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = ignoreToken;
+_[BEFORE_HTML_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[BEFORE_HTML_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[BEFORE_HTML_MODE][Tokenizer.START_TAG_TOKEN] = startTagBeforeHtml;
+_[BEFORE_HTML_MODE][Tokenizer.END_TAG_TOKEN] = endTagBeforeHtml;
+_[BEFORE_HTML_MODE][Tokenizer.EOF_TOKEN] = tokenBeforeHtml;
+
+_[BEFORE_HEAD_MODE] = {};
+_[BEFORE_HEAD_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[BEFORE_HEAD_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenBeforeHead;
+_[BEFORE_HEAD_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = ignoreToken;
+_[BEFORE_HEAD_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[BEFORE_HEAD_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[BEFORE_HEAD_MODE][Tokenizer.START_TAG_TOKEN] = startTagBeforeHead;
+_[BEFORE_HEAD_MODE][Tokenizer.END_TAG_TOKEN] = endTagBeforeHead;
+_[BEFORE_HEAD_MODE][Tokenizer.EOF_TOKEN] = tokenBeforeHead;
+
+_[IN_HEAD_MODE] = {};
+_[IN_HEAD_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[IN_HEAD_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenInHead;
+_[IN_HEAD_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[IN_HEAD_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_HEAD_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_HEAD_MODE][Tokenizer.START_TAG_TOKEN] = startTagInHead;
+_[IN_HEAD_MODE][Tokenizer.END_TAG_TOKEN] = endTagInHead;
+_[IN_HEAD_MODE][Tokenizer.EOF_TOKEN] = tokenInHead;
+
+_[AFTER_HEAD_MODE] = {};
+_[AFTER_HEAD_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[AFTER_HEAD_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenAfterHead;
+_[AFTER_HEAD_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[AFTER_HEAD_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[AFTER_HEAD_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[AFTER_HEAD_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterHead;
+_[AFTER_HEAD_MODE][Tokenizer.END_TAG_TOKEN] = endTagAfterHead;
+_[AFTER_HEAD_MODE][Tokenizer.EOF_TOKEN] = tokenAfterHead;
+
+_[IN_BODY_MODE] = {};
+_[IN_BODY_MODE][Tokenizer.CHARACTER_TOKEN] = characterInBody;
+_[IN_BODY_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_BODY_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody;
+_[IN_BODY_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_BODY_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_BODY_MODE][Tokenizer.START_TAG_TOKEN] = startTagInBody;
+_[IN_BODY_MODE][Tokenizer.END_TAG_TOKEN] = endTagInBody;
+_[IN_BODY_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[TEXT_MODE] = {};
+_[TEXT_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[TEXT_MODE][Tokenizer.NULL_CHARACTER_TOKEN] =
+_[TEXT_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[TEXT_MODE][Tokenizer.COMMENT_TOKEN] =
+_[TEXT_MODE][Tokenizer.DOCTYPE_TOKEN] =
+_[TEXT_MODE][Tokenizer.START_TAG_TOKEN] = ignoreToken;
+_[TEXT_MODE][Tokenizer.END_TAG_TOKEN] = endTagInText;
+_[TEXT_MODE][Tokenizer.EOF_TOKEN] = eofInText;
+
+_[IN_TABLE_MODE] = {};
+_[IN_TABLE_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[IN_TABLE_MODE][Tokenizer.NULL_CHARACTER_TOKEN] =
+_[IN_TABLE_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = characterInTable;
+_[IN_TABLE_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_TABLE_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_TABLE_MODE][Tokenizer.START_TAG_TOKEN] = startTagInTable;
+_[IN_TABLE_MODE][Tokenizer.END_TAG_TOKEN] = endTagInTable;
+_[IN_TABLE_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_TABLE_TEXT_MODE] = {};
+_[IN_TABLE_TEXT_MODE][Tokenizer.CHARACTER_TOKEN] = characterInTableText;
+_[IN_TABLE_TEXT_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_TABLE_TEXT_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInTableText;
+_[IN_TABLE_TEXT_MODE][Tokenizer.COMMENT_TOKEN] =
+_[IN_TABLE_TEXT_MODE][Tokenizer.DOCTYPE_TOKEN] =
+_[IN_TABLE_TEXT_MODE][Tokenizer.START_TAG_TOKEN] =
+_[IN_TABLE_TEXT_MODE][Tokenizer.END_TAG_TOKEN] =
+_[IN_TABLE_TEXT_MODE][Tokenizer.EOF_TOKEN] = tokenInTableText;
+
+_[IN_CAPTION_MODE] = {};
+_[IN_CAPTION_MODE][Tokenizer.CHARACTER_TOKEN] = characterInBody;
+_[IN_CAPTION_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_CAPTION_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody;
+_[IN_CAPTION_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_CAPTION_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_CAPTION_MODE][Tokenizer.START_TAG_TOKEN] = startTagInCaption;
+_[IN_CAPTION_MODE][Tokenizer.END_TAG_TOKEN] = endTagInCaption;
+_[IN_CAPTION_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_COLUMN_GROUP_MODE] = {};
+_[IN_COLUMN_GROUP_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[IN_COLUMN_GROUP_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenInColumnGroup;
+_[IN_COLUMN_GROUP_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[IN_COLUMN_GROUP_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_COLUMN_GROUP_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_COLUMN_GROUP_MODE][Tokenizer.START_TAG_TOKEN] = startTagInColumnGroup;
+_[IN_COLUMN_GROUP_MODE][Tokenizer.END_TAG_TOKEN] = endTagInColumnGroup;
+_[IN_COLUMN_GROUP_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_TABLE_BODY_MODE] = {};
+_[IN_TABLE_BODY_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[IN_TABLE_BODY_MODE][Tokenizer.NULL_CHARACTER_TOKEN] =
+_[IN_TABLE_BODY_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = characterInTable;
+_[IN_TABLE_BODY_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_TABLE_BODY_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_TABLE_BODY_MODE][Tokenizer.START_TAG_TOKEN] = startTagInTableBody;
+_[IN_TABLE_BODY_MODE][Tokenizer.END_TAG_TOKEN] = endTagInTableBody;
+_[IN_TABLE_BODY_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_ROW_MODE] = {};
+_[IN_ROW_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[IN_ROW_MODE][Tokenizer.NULL_CHARACTER_TOKEN] =
+_[IN_ROW_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = characterInTable;
+_[IN_ROW_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_ROW_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_ROW_MODE][Tokenizer.START_TAG_TOKEN] = startTagInRow;
+_[IN_ROW_MODE][Tokenizer.END_TAG_TOKEN] = endTagInRow;
+_[IN_ROW_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_CELL_MODE] = {};
+_[IN_CELL_MODE][Tokenizer.CHARACTER_TOKEN] = characterInBody;
+_[IN_CELL_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_CELL_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody;
+_[IN_CELL_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_CELL_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_CELL_MODE][Tokenizer.START_TAG_TOKEN] = startTagInCell;
+_[IN_CELL_MODE][Tokenizer.END_TAG_TOKEN] = endTagInCell;
+_[IN_CELL_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_SELECT_MODE] = {};
+_[IN_SELECT_MODE][Tokenizer.CHARACTER_TOKEN] = insertCharacters;
+_[IN_SELECT_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_SELECT_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[IN_SELECT_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_SELECT_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_SELECT_MODE][Tokenizer.START_TAG_TOKEN] = startTagInSelect;
+_[IN_SELECT_MODE][Tokenizer.END_TAG_TOKEN] = endTagInSelect;
+_[IN_SELECT_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_SELECT_IN_TABLE_MODE] = {};
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.CHARACTER_TOKEN] = insertCharacters;
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.START_TAG_TOKEN] = startTagInSelectInTable;
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.END_TAG_TOKEN] = endTagInSelectInTable;
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_TEMPLATE_MODE] = {};
+_[IN_TEMPLATE_MODE][Tokenizer.CHARACTER_TOKEN] = characterInBody;
+_[IN_TEMPLATE_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_TEMPLATE_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody;
+_[IN_TEMPLATE_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_TEMPLATE_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_TEMPLATE_MODE][Tokenizer.START_TAG_TOKEN] = startTagInTemplate;
+_[IN_TEMPLATE_MODE][Tokenizer.END_TAG_TOKEN] = endTagInTemplate;
+_[IN_TEMPLATE_MODE][Tokenizer.EOF_TOKEN] = eofInTemplate;
+
+_[AFTER_BODY_MODE] = {};
+_[AFTER_BODY_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[AFTER_BODY_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenAfterBody;
+_[AFTER_BODY_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody;
+_[AFTER_BODY_MODE][Tokenizer.COMMENT_TOKEN] = appendCommentToRootHtmlElement;
+_[AFTER_BODY_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[AFTER_BODY_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterBody;
+_[AFTER_BODY_MODE][Tokenizer.END_TAG_TOKEN] = endTagAfterBody;
+_[AFTER_BODY_MODE][Tokenizer.EOF_TOKEN] = stopParsing;
+
+_[IN_FRAMESET_MODE] = {};
+_[IN_FRAMESET_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[IN_FRAMESET_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_FRAMESET_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[IN_FRAMESET_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_FRAMESET_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_FRAMESET_MODE][Tokenizer.START_TAG_TOKEN] = startTagInFrameset;
+_[IN_FRAMESET_MODE][Tokenizer.END_TAG_TOKEN] = endTagInFrameset;
+_[IN_FRAMESET_MODE][Tokenizer.EOF_TOKEN] = stopParsing;
+
+_[AFTER_FRAMESET_MODE] = {};
+_[AFTER_FRAMESET_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[AFTER_FRAMESET_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[AFTER_FRAMESET_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[AFTER_FRAMESET_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[AFTER_FRAMESET_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[AFTER_FRAMESET_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterFrameset;
+_[AFTER_FRAMESET_MODE][Tokenizer.END_TAG_TOKEN] = endTagAfterFrameset;
+_[AFTER_FRAMESET_MODE][Tokenizer.EOF_TOKEN] = stopParsing;
+
+_[AFTER_AFTER_BODY_MODE] = {};
+_[AFTER_AFTER_BODY_MODE][Tokenizer.CHARACTER_TOKEN] = tokenAfterAfterBody;
+_[AFTER_AFTER_BODY_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenAfterAfterBody;
+_[AFTER_AFTER_BODY_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody;
+_[AFTER_AFTER_BODY_MODE][Tokenizer.COMMENT_TOKEN] = appendCommentToDocument;
+_[AFTER_AFTER_BODY_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[AFTER_AFTER_BODY_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterAfterBody;
+_[AFTER_AFTER_BODY_MODE][Tokenizer.END_TAG_TOKEN] = tokenAfterAfterBody;
+_[AFTER_AFTER_BODY_MODE][Tokenizer.EOF_TOKEN] = stopParsing;
+
+_[AFTER_AFTER_FRAMESET_MODE] = {};
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody;
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.COMMENT_TOKEN] = appendCommentToDocument;
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterAfterFrameset;
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.END_TAG_TOKEN] = ignoreToken;
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.EOF_TOKEN] = stopParsing;
+
+//Searchable index building utils (<isindex> tag)
+function getSearchableIndexFormAttrs(isindexStartTagToken) {
+ var indexAction = Tokenizer.getTokenAttr(isindexStartTagToken, ATTRS.ACTION),
+ attrs = [];
+
+ if (indexAction !== null) {
+ attrs.push({
+ name: ATTRS.ACTION,
+ value: indexAction
+ });
+ }
+
+ return attrs;
+}
+
+function getSearchableIndexLabelText(isindexStartTagToken) {
+ var indexPrompt = Tokenizer.getTokenAttr(isindexStartTagToken, ATTRS.PROMPT);
+
+ return indexPrompt === null ? SEARCHABLE_INDEX_DEFAULT_PROMPT : indexPrompt;
+}
+
+function getSearchableIndexInputAttrs(isindexStartTagToken) {
+ var isindexAttrs = isindexStartTagToken.attrs,
+ inputAttrs = [];
+
+ for (var i = 0; i < isindexAttrs.length; i++) {
+ var name = isindexAttrs[i].name;
+
+ if (name !== ATTRS.NAME && name !== ATTRS.ACTION && name !== ATTRS.PROMPT)
+ inputAttrs.push(isindexAttrs[i]);
+ }
+
+ inputAttrs.push({
+ name: ATTRS.NAME,
+ value: SEARCHABLE_INDEX_INPUT_NAME
+ });
+
+ return inputAttrs;
+}
+
+//Parser
+var Parser = module.exports = function (treeAdapter, options) {
+ this.treeAdapter = treeAdapter || DefaultTreeAdapter;
+ this.options = Utils.mergeOptions(DEFAULT_OPTIONS, options);
+ this.scriptHandler = null;
+
+ if (this.options.locationInfo)
+ LocationInfoMixin.assign(this);
+};
+
+//API
+Parser.prototype.parse = function (html) {
+ var document = this.treeAdapter.createDocument();
+
+ this._reset(html, document, null);
+ this._runParsingLoop();
+
+ return document;
+};
+
+Parser.prototype.parseFragment = function (html, fragmentContext) {
+ //NOTE: use <template> element as a fragment context if context element was not provided,
+ //so we will parse in "forgiving" manner
+ if (!fragmentContext)
+ fragmentContext = this.treeAdapter.createElement($.TEMPLATE, NS.HTML, []);
+
+ //NOTE: create fake element which will be used as 'document' for fragment parsing.
+ //This is important for jsdom there 'document' can't be recreated, therefore
+ //fragment parsing causes messing of the main `document`.
+ var documentMock = this.treeAdapter.createElement('documentmock', NS.HTML, []);
+
+ this._reset(html, documentMock, fragmentContext);
+
+ if (this.treeAdapter.getTagName(fragmentContext) === $.TEMPLATE)
+ this._pushTmplInsertionMode(IN_TEMPLATE_MODE);
+
+ this._initTokenizerForFragmentParsing();
+ this._insertFakeRootElement();
+ this._resetInsertionMode();
+ this._findFormInFragmentContext();
+ this._runParsingLoop();
+
+ var rootElement = this.treeAdapter.getFirstChild(documentMock),
+ fragment = this.treeAdapter.createDocumentFragment();
+
+ this._adoptNodes(rootElement, fragment);
+
+ return fragment;
+};
+
+//Reset state
+Parser.prototype._reset = function (html, document, fragmentContext) {
+ this.tokenizer = new Tokenizer(html, this.options);
+
+ this.stopped = false;
+
+ this.insertionMode = INITIAL_MODE;
+ this.originalInsertionMode = '';
+
+ this.document = document;
+ this.fragmentContext = fragmentContext;
+
+ this.headElement = null;
+ this.formElement = null;
+
+ this.openElements = new OpenElementStack(this.document, this.treeAdapter);
+ this.activeFormattingElements = new FormattingElementList(this.treeAdapter);
+
+ this.tmplInsertionModeStack = [];
+ this.tmplInsertionModeStackTop = -1;
+ this.currentTmplInsertionMode = null;
+
+ this.pendingCharacterTokens = [];
+ this.hasNonWhitespacePendingCharacterToken = false;
+
+ this.framesetOk = true;
+ this.skipNextNewLine = false;
+ this.fosterParentingEnabled = false;
+};
+
+//Parsing loop
+Parser.prototype._iterateParsingLoop = function () {
+ this._setupTokenizerCDATAMode();
+
+ var token = this.tokenizer.getNextToken();
+
+ if (this.skipNextNewLine) {
+ this.skipNextNewLine = false;
+
+ if (token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN && token.chars[0] === '\n') {
+ if (token.chars.length === 1)
+ return;
+
+ token.chars = token.chars.substr(1);
+ }
+ }
+
+ if (this._shouldProcessTokenInForeignContent(token))
+ this._processTokenInForeignContent(token);
+
+ else
+ this._processToken(token);
+};
+
+Parser.prototype._runParsingLoop = function () {
+ while (!this.stopped)
+ this._iterateParsingLoop();
+};
+
+//Text parsing
+Parser.prototype._setupTokenizerCDATAMode = function () {
+ var current = this._getAdjustedCurrentElement();
+
+ this.tokenizer.allowCDATA = current && current !== this.document &&
+ this.treeAdapter.getNamespaceURI(current) !== NS.HTML &&
+ (!this._isHtmlIntegrationPoint(current)) &&
+ (!this._isMathMLTextIntegrationPoint(current));
+};
+
+Parser.prototype._switchToTextParsing = function (currentToken, nextTokenizerState) {
+ this._insertElement(currentToken, NS.HTML);
+ this.tokenizer.state = nextTokenizerState;
+ this.originalInsertionMode = this.insertionMode;
+ this.insertionMode = TEXT_MODE;
+};
+
+//Fragment parsing
+Parser.prototype._getAdjustedCurrentElement = function () {
+ return this.openElements.stackTop === 0 && this.fragmentContext ?
+ this.fragmentContext :
+ this.openElements.current;
+};
+
+Parser.prototype._findFormInFragmentContext = function () {
+ var node = this.fragmentContext;
+
+ do {
+ if (this.treeAdapter.getTagName(node) === $.FORM) {
+ this.formElement = node;
+ break;
+ }
+
+ node = this.treeAdapter.getParentNode(node);
+ } while (node);
+};
+
+Parser.prototype._initTokenizerForFragmentParsing = function () {
+ var tn = this.treeAdapter.getTagName(this.fragmentContext);
+
+ if (tn === $.TITLE || tn === $.TEXTAREA)
+ this.tokenizer.state = Tokenizer.MODE.RCDATA;
+
+ else if (tn === $.STYLE || tn === $.XMP || tn === $.IFRAME ||
+ tn === $.NOEMBED || tn === $.NOFRAMES || tn === $.NOSCRIPT) {
+ this.tokenizer.state = Tokenizer.MODE.RAWTEXT;
+ }
+
+ else if (tn === $.SCRIPT)
+ this.tokenizer.state = Tokenizer.MODE.SCRIPT_DATA;
+
+ else if (tn === $.PLAINTEXT)
+ this.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
+};
+
+//Tree mutation
+Parser.prototype._setDocumentType = function (token) {
+ this.treeAdapter.setDocumentType(this.document, token.name, token.publicId, token.systemId);
+};
+
+Parser.prototype._attachElementToTree = function (element) {
+ if (this._shouldFosterParentOnInsertion())
+ this._fosterParentElement(element);
+
+ else {
+ var parent = this.openElements.currentTmplContent || this.openElements.current;
+
+ this.treeAdapter.appendChild(parent, element);
+ }
+};
+
+Parser.prototype._appendElement = function (token, namespaceURI) {
+ var element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
+
+ this._attachElementToTree(element);
+};
+
+Parser.prototype._insertElement = function (token, namespaceURI) {
+ var element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
+
+ this._attachElementToTree(element);
+ this.openElements.push(element);
+};
+
+Parser.prototype._insertTemplate = function (token) {
+ var tmpl = this.treeAdapter.createElement(token.tagName, NS.HTML, token.attrs),
+ content = this.treeAdapter.createDocumentFragment();
+
+ this.treeAdapter.appendChild(tmpl, content);
+ this._attachElementToTree(tmpl);
+ this.openElements.push(tmpl);
+};
+
+Parser.prototype._insertFakeRootElement = function () {
+ var element = this.treeAdapter.createElement($.HTML, NS.HTML, []);
+
+ this.treeAdapter.appendChild(this.openElements.current, element);
+ this.openElements.push(element);
+};
+
+Parser.prototype._appendCommentNode = function (token, parent) {
+ var commentNode = this.treeAdapter.createCommentNode(token.data);
+
+ this.treeAdapter.appendChild(parent, commentNode);
+};
+
+Parser.prototype._insertCharacters = function (token) {
+ if (this._shouldFosterParentOnInsertion())
+ this._fosterParentText(token.chars);
+
+ else {
+ var parent = this.openElements.currentTmplContent || this.openElements.current;
+
+ this.treeAdapter.insertText(parent, token.chars);
+ }
+};
+
+Parser.prototype._adoptNodes = function (donor, recipient) {
+ while (true) {
+ var child = this.treeAdapter.getFirstChild(donor);
+
+ if (!child)
+ break;
+
+ this.treeAdapter.detachNode(child);
+ this.treeAdapter.appendChild(recipient, child);
+ }
+};
+
+//Token processing
+Parser.prototype._shouldProcessTokenInForeignContent = function (token) {
+ var current = this._getAdjustedCurrentElement();
+
+ if (!current || current === this.document)
+ return false;
+
+ var ns = this.treeAdapter.getNamespaceURI(current);
+
+ if (ns === NS.HTML)
+ return false;
+
+ if (this.treeAdapter.getTagName(current) === $.ANNOTATION_XML && ns === NS.MATHML &&
+ token.type === Tokenizer.START_TAG_TOKEN && token.tagName === $.SVG) {
+ return false;
+ }
+
+ var isCharacterToken = token.type === Tokenizer.CHARACTER_TOKEN ||
+ token.type === Tokenizer.NULL_CHARACTER_TOKEN ||
+ token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN,
+ isMathMLTextStartTag = token.type === Tokenizer.START_TAG_TOKEN &&
+ token.tagName !== $.MGLYPH &&
+ token.tagName !== $.MALIGNMARK;
+
+ if ((isMathMLTextStartTag || isCharacterToken) && this._isMathMLTextIntegrationPoint(current))
+ return false;
+
+ if ((token.type === Tokenizer.START_TAG_TOKEN || isCharacterToken) && this._isHtmlIntegrationPoint(current))
+ return false;
+
+ return token.type !== Tokenizer.EOF_TOKEN;
+};
+
+Parser.prototype._processToken = function (token) {
+ _[this.insertionMode][token.type](this, token);
+};
+
+Parser.prototype._processTokenInBodyMode = function (token) {
+ _[IN_BODY_MODE][token.type](this, token);
+};
+
+Parser.prototype._processTokenInForeignContent = function (token) {
+ if (token.type === Tokenizer.CHARACTER_TOKEN)
+ characterInForeignContent(this, token);
+
+ else if (token.type === Tokenizer.NULL_CHARACTER_TOKEN)
+ nullCharacterInForeignContent(this, token);
+
+ else if (token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN)
+ insertCharacters(this, token);
+
+ else if (token.type === Tokenizer.COMMENT_TOKEN)
+ appendComment(this, token);
+
+ else if (token.type === Tokenizer.START_TAG_TOKEN)
+ startTagInForeignContent(this, token);
+
+ else if (token.type === Tokenizer.END_TAG_TOKEN)
+ endTagInForeignContent(this, token);
+};
+
+Parser.prototype._processFakeStartTagWithAttrs = function (tagName, attrs) {
+ var fakeToken = this.tokenizer.buildStartTagToken(tagName);
+
+ fakeToken.attrs = attrs;
+ this._processToken(fakeToken);
+};
+
+Parser.prototype._processFakeStartTag = function (tagName) {
+ var fakeToken = this.tokenizer.buildStartTagToken(tagName);
+
+ this._processToken(fakeToken);
+ return fakeToken;
+};
+
+Parser.prototype._processFakeEndTag = function (tagName) {
+ var fakeToken = this.tokenizer.buildEndTagToken(tagName);
+
+ this._processToken(fakeToken);
+ return fakeToken;
+};
+
+//Integration points
+Parser.prototype._isMathMLTextIntegrationPoint = function (element) {
+ var tn = this.treeAdapter.getTagName(element),
+ ns = this.treeAdapter.getNamespaceURI(element);
+
+ return ForeignContent.isMathMLTextIntegrationPoint(tn, ns);
+};
+
+Parser.prototype._isHtmlIntegrationPoint = function (element) {
+ var tn = this.treeAdapter.getTagName(element),
+ ns = this.treeAdapter.getNamespaceURI(element),
+ attrs = this.treeAdapter.getAttrList(element);
+
+ return ForeignContent.isHtmlIntegrationPoint(tn, ns, attrs);
+};
+
+//Active formatting elements reconstruction
+Parser.prototype._reconstructActiveFormattingElements = function () {
+ var listLength = this.activeFormattingElements.length;
+
+ if (listLength) {
+ var unopenIdx = listLength,
+ entry = null;
+
+ do {
+ unopenIdx--;
+ entry = this.activeFormattingElements.entries[unopenIdx];
+
+ if (entry.type === FormattingElementList.MARKER_ENTRY || this.openElements.contains(entry.element)) {
+ unopenIdx++;
+ break;
+ }
+ } while (unopenIdx > 0);
+
+ for (var i = unopenIdx; i < listLength; i++) {
+ entry = this.activeFormattingElements.entries[i];
+ this._insertElement(entry.token, this.treeAdapter.getNamespaceURI(entry.element));
+ entry.element = this.openElements.current;
+ }
+ }
+};
+
+//Close elements
+Parser.prototype._closeTableCell = function () {
+ if (this.openElements.hasInTableScope($.TD))
+ this._processFakeEndTag($.TD);
+
+ else
+ this._processFakeEndTag($.TH);
+};
+
+Parser.prototype._closePElement = function () {
+ this.openElements.generateImpliedEndTagsWithExclusion($.P);
+ this.openElements.popUntilTagNamePopped($.P);
+};
+
+//Insertion modes
+Parser.prototype._resetInsertionMode = function () {
+ for (var i = this.openElements.stackTop, last = false; i >= 0; i--) {
+ var element = this.openElements.items[i];
+
+ if (i === 0) {
+ last = true;
+
+ if (this.fragmentContext)
+ element = this.fragmentContext;
+ }
+
+ var tn = this.treeAdapter.getTagName(element),
+ newInsertionMode = INSERTION_MODE_RESET_MAP[tn];
+
+ if (newInsertionMode) {
+ this.insertionMode = newInsertionMode;
+ break;
+ }
+
+ else if (!last && (tn === $.TD || tn === $.TH)) {
+ this.insertionMode = IN_CELL_MODE;
+ break;
+ }
+
+ else if (!last && tn === $.HEAD) {
+ this.insertionMode = IN_HEAD_MODE;
+ break;
+ }
+
+ else if (tn === $.SELECT) {
+ this._resetInsertionModeForSelect(i);
+ break;
+ }
+
+ else if (tn === $.TEMPLATE) {
+ this.insertionMode = this.currentTmplInsertionMode;
+ break;
+ }
+
+ else if (tn === $.HTML) {
+ this.insertionMode = this.headElement ? AFTER_HEAD_MODE : BEFORE_HEAD_MODE;
+ break;
+ }
+
+ else if (last) {
+ this.insertionMode = IN_BODY_MODE;
+ break;
+ }
+ }
+};
+
+Parser.prototype._resetInsertionModeForSelect = function (selectIdx) {
+ if (selectIdx > 0) {
+ for (var i = selectIdx - 1; i > 0; i--) {
+ var ancestor = this.openElements.items[i],
+ tn = this.treeAdapter.getTagName(ancestor);
+
+ if (tn === $.TEMPLATE)
+ break;
+
+ else if (tn === $.TABLE) {
+ this.insertionMode = IN_SELECT_IN_TABLE_MODE;
+ return;
+ }
+ }
+ }
+
+ this.insertionMode = IN_SELECT_MODE;
+};
+
+Parser.prototype._pushTmplInsertionMode = function (mode) {
+ this.tmplInsertionModeStack.push(mode);
+ this.tmplInsertionModeStackTop++;
+ this.currentTmplInsertionMode = mode;
+};
+
+Parser.prototype._popTmplInsertionMode = function () {
+ this.tmplInsertionModeStack.pop();
+ this.tmplInsertionModeStackTop--;
+ this.currentTmplInsertionMode = this.tmplInsertionModeStack[this.tmplInsertionModeStackTop];
+};
+
+//Foster parenting
+Parser.prototype._isElementCausesFosterParenting = function (element) {
+ var tn = this.treeAdapter.getTagName(element);
+
+ return tn === $.TABLE || tn === $.TBODY || tn === $.TFOOT || tn == $.THEAD || tn === $.TR;
+};
+
+Parser.prototype._shouldFosterParentOnInsertion = function () {
+ return this.fosterParentingEnabled && this._isElementCausesFosterParenting(this.openElements.current);
+};
+
+Parser.prototype._findFosterParentingLocation = function () {
+ var location = {
+ parent: null,
+ beforeElement: null
+ };
+
+ for (var i = this.openElements.stackTop; i >= 0; i--) {
+ var openElement = this.openElements.items[i],
+ tn = this.treeAdapter.getTagName(openElement),
+ ns = this.treeAdapter.getNamespaceURI(openElement);
+
+ if (tn === $.TEMPLATE && ns === NS.HTML) {
+ location.parent = this.treeAdapter.getChildNodes(openElement)[0];
+ break;
+ }
+
+ else if (tn === $.TABLE) {
+ location.parent = this.treeAdapter.getParentNode(openElement);
+
+ if (location.parent)
+ location.beforeElement = openElement;
+ else
+ location.parent = this.openElements.items[i - 1];
+
+ break;
+ }
+ }
+
+ if (!location.parent)
+ location.parent = this.openElements.items[0];
+
+ return location;
+};
+
+Parser.prototype._fosterParentElement = function (element) {
+ var location = this._findFosterParentingLocation();
+
+ if (location.beforeElement)
+ this.treeAdapter.insertBefore(location.parent, element, location.beforeElement);
+ else
+ this.treeAdapter.appendChild(location.parent, element);
+};
+
+Parser.prototype._fosterParentText = function (chars) {
+ var location = this._findFosterParentingLocation();
+
+ if (location.beforeElement)
+ this.treeAdapter.insertTextBefore(location.parent, chars, location.beforeElement);
+ else
+ this.treeAdapter.insertText(location.parent, chars);
+};
+
+//Special elements
+Parser.prototype._isSpecialElement = function (element) {
+ var tn = this.treeAdapter.getTagName(element),
+ ns = this.treeAdapter.getNamespaceURI(element);
+
+ return HTML.SPECIAL_ELEMENTS[ns][tn];
+};
+
+//Adoption agency algorithm
+//(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#adoptionAgency)
+//------------------------------------------------------------------
+
+//Steps 5-8 of the algorithm
+function aaObtainFormattingElementEntry(p, token) {
+ var formattingElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName(token.tagName);
+
+ if (formattingElementEntry) {
+ if (!p.openElements.contains(formattingElementEntry.element)) {
+ p.activeFormattingElements.removeEntry(formattingElementEntry);
+ formattingElementEntry = null;
+ }
+
+ else if (!p.openElements.hasInScope(token.tagName))
+ formattingElementEntry = null;
+ }
+
+ else
+ genericEndTagInBody(p, token);
+
+ return formattingElementEntry;
+}
+
+//Steps 9 and 10 of the algorithm
+function aaObtainFurthestBlock(p, formattingElementEntry) {
+ var furthestBlock = null;
+
+ for (var i = p.openElements.stackTop; i >= 0; i--) {
+ var element = p.openElements.items[i];
+
+ if (element === formattingElementEntry.element)
+ break;
+
+ if (p._isSpecialElement(element))
+ furthestBlock = element;
+ }
+
+ if (!furthestBlock) {
+ p.openElements.popUntilElementPopped(formattingElementEntry.element);
+ p.activeFormattingElements.removeEntry(formattingElementEntry);
+ }
+
+ return furthestBlock;
+}
+
+//Step 13 of the algorithm
+function aaInnerLoop(p, furthestBlock, formattingElement) {
+ var element = null,
+ lastElement = furthestBlock,
+ nextElement = p.openElements.getCommonAncestor(furthestBlock);
+
+ for (var i = 0; i < AA_INNER_LOOP_ITER; i++) {
+ element = nextElement;
+
+ //NOTE: store next element for the next loop iteration (it may be deleted from the stack by step 9.5)
+ nextElement = p.openElements.getCommonAncestor(element);
+
+ var elementEntry = p.activeFormattingElements.getElementEntry(element);
+
+ if (!elementEntry) {
+ p.openElements.remove(element);
+ continue;
+ }
+
+ if (element === formattingElement)
+ break;
+
+ element = aaRecreateElementFromEntry(p, elementEntry);
+
+ if (lastElement === furthestBlock)
+ p.activeFormattingElements.bookmark = elementEntry;
+
+ p.treeAdapter.detachNode(lastElement);
+ p.treeAdapter.appendChild(element, lastElement);
+ lastElement = element;
+ }
+
+ return lastElement;
+}
+
+//Step 13.7 of the algorithm
+function aaRecreateElementFromEntry(p, elementEntry) {
+ var ns = p.treeAdapter.getNamespaceURI(elementEntry.element),
+ newElement = p.treeAdapter.createElement(elementEntry.token.tagName, ns, elementEntry.token.attrs);
+
+ p.openElements.replace(elementEntry.element, newElement);
+ elementEntry.element = newElement;
+
+ return newElement;
+}
+
+//Step 14 of the algorithm
+function aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement) {
+ if (p._isElementCausesFosterParenting(commonAncestor))
+ p._fosterParentElement(lastElement);
+
+ else {
+ var tn = p.treeAdapter.getTagName(commonAncestor),
+ ns = p.treeAdapter.getNamespaceURI(commonAncestor);
+
+ if (tn === $.TEMPLATE && ns === NS.HTML)
+ commonAncestor = p.treeAdapter.getChildNodes(commonAncestor)[0];
+
+ p.treeAdapter.appendChild(commonAncestor, lastElement);
+ }
+}
+
+//Steps 15-19 of the algorithm
+function aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry) {
+ var ns = p.treeAdapter.getNamespaceURI(formattingElementEntry.element),
+ token = formattingElementEntry.token,
+ newElement = p.treeAdapter.createElement(token.tagName, ns, token.attrs);
+
+ p._adoptNodes(furthestBlock, newElement);
+ p.treeAdapter.appendChild(furthestBlock, newElement);
+
+ p.activeFormattingElements.insertElementAfterBookmark(newElement, formattingElementEntry.token);
+ p.activeFormattingElements.removeEntry(formattingElementEntry);
+
+ p.openElements.remove(formattingElementEntry.element);
+ p.openElements.insertAfter(furthestBlock, newElement);
+}
+
+//Algorithm entry point
+function callAdoptionAgency(p, token) {
+ for (var i = 0; i < AA_OUTER_LOOP_ITER; i++) {
+ var formattingElementEntry = aaObtainFormattingElementEntry(p, token, formattingElementEntry);
+
+ if (!formattingElementEntry)
+ break;
+
+ var furthestBlock = aaObtainFurthestBlock(p, formattingElementEntry);
+
+ if (!furthestBlock)
+ break;
+
+ p.activeFormattingElements.bookmark = formattingElementEntry;
+
+ var lastElement = aaInnerLoop(p, furthestBlock, formattingElementEntry.element),
+ commonAncestor = p.openElements.getCommonAncestor(formattingElementEntry.element);
+
+ p.treeAdapter.detachNode(lastElement);
+ aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement);
+ aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry);
+ }
+}
+
+
+//Generic token handlers
+//------------------------------------------------------------------
+function ignoreToken(p, token) {
+ //NOTE: do nothing =)
+}
+
+function appendComment(p, token) {
+ p._appendCommentNode(token, p.openElements.currentTmplContent || p.openElements.current)
+}
+
+function appendCommentToRootHtmlElement(p, token) {
+ p._appendCommentNode(token, p.openElements.items[0]);
+}
+
+function appendCommentToDocument(p, token) {
+ p._appendCommentNode(token, p.document);
+}
+
+function insertCharacters(p, token) {
+ p._insertCharacters(token);
+}
+
+function stopParsing(p, token) {
+ p.stopped = true;
+}
+
+//12.2.5.4.1 The "initial" insertion mode
+//------------------------------------------------------------------
+function doctypeInInitialMode(p, token) {
+ p._setDocumentType(token);
+
+ if (token.forceQuirks || Doctype.isQuirks(token.name, token.publicId, token.systemId))
+ p.treeAdapter.setQuirksMode(p.document);
+
+ p.insertionMode = BEFORE_HTML_MODE;
+}
+
+function tokenInInitialMode(p, token) {
+ p.treeAdapter.setQuirksMode(p.document);
+ p.insertionMode = BEFORE_HTML_MODE;
+ p._processToken(token);
+}
+
+
+//12.2.5.4.2 The "before html" insertion mode
+//------------------------------------------------------------------
+function startTagBeforeHtml(p, token) {
+ if (token.tagName === $.HTML) {
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = BEFORE_HEAD_MODE;
+ }
+
+ else
+ tokenBeforeHtml(p, token);
+}
+
+function endTagBeforeHtml(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HTML || tn === $.HEAD || tn === $.BODY || tn === $.BR)
+ tokenBeforeHtml(p, token);
+}
+
+function tokenBeforeHtml(p, token) {
+ p._insertFakeRootElement();
+ p.insertionMode = BEFORE_HEAD_MODE;
+ p._processToken(token);
+}
+
+
+//12.2.5.4.3 The "before head" insertion mode
+//------------------------------------------------------------------
+function startTagBeforeHead(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HTML)
+ startTagInBody(p, token);
+
+ else if (tn === $.HEAD) {
+ p._insertElement(token, NS.HTML);
+ p.headElement = p.openElements.current;
+ p.insertionMode = IN_HEAD_MODE;
+ }
+
+ else
+ tokenBeforeHead(p, token);
+}
+
+function endTagBeforeHead(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HEAD || tn === $.BODY || tn === $.HTML || tn === $.BR)
+ tokenBeforeHead(p, token);
+}
+
+function tokenBeforeHead(p, token) {
+ p._processFakeStartTag($.HEAD);
+ p._processToken(token);
+}
+
+
+//12.2.5.4.4 The "in head" insertion mode
+//------------------------------------------------------------------
+function startTagInHead(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HTML)
+ startTagInBody(p, token);
+
+ else if (tn === $.BASE || tn === $.BASEFONT || tn === $.BGSOUND ||
+ tn === $.COMMAND || tn === $.LINK || tn === $.META) {
+ p._appendElement(token, NS.HTML);
+ }
+
+ else if (tn === $.TITLE)
+ p._switchToTextParsing(token, Tokenizer.MODE.RCDATA);
+
+ //NOTE: here we assume that we always act as an interactive user agent with enabled scripting, so we parse
+ //<noscript> as a rawtext.
+ else if (tn === $.NOSCRIPT || tn === $.NOFRAMES || tn === $.STYLE)
+ p._switchToTextParsing(token, Tokenizer.MODE.RAWTEXT);
+
+ else if (tn === $.SCRIPT)
+ p._switchToTextParsing(token, Tokenizer.MODE.SCRIPT_DATA);
+
+ else if (tn === $.TEMPLATE) {
+ p._insertTemplate(token, NS.HTML);
+ p.activeFormattingElements.insertMarker();
+ p.framesetOk = false;
+ p.insertionMode = IN_TEMPLATE_MODE;
+ p._pushTmplInsertionMode(IN_TEMPLATE_MODE);
+ }
+
+ else if (tn !== $.HEAD)
+ tokenInHead(p, token);
+}
+
+function endTagInHead(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HEAD) {
+ p.openElements.pop();
+ p.insertionMode = AFTER_HEAD_MODE;
+ }
+
+ else if (tn === $.BODY || tn === $.BR || tn === $.HTML)
+ tokenInHead(p, token);
+
+ else if (tn === $.TEMPLATE && p.openElements.tmplCount > 0) {
+ p.openElements.generateImpliedEndTags();
+ p.openElements.popUntilTemplatePopped();
+ p.activeFormattingElements.clearToLastMarker();
+ p._popTmplInsertionMode();
+ p._resetInsertionMode();
+ }
+}
+
+function tokenInHead(p, token) {
+ p._processFakeEndTag($.HEAD);
+ p._processToken(token);
+}
+
+
+//12.2.5.4.6 The "after head" insertion mode
+//------------------------------------------------------------------
+function startTagAfterHead(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HTML)
+ startTagInBody(p, token);
+
+ else if (tn === $.BODY) {
+ p._insertElement(token, NS.HTML);
+ p.framesetOk = false;
+ p.insertionMode = IN_BODY_MODE;
+ }
+
+ else if (tn === $.FRAMESET) {
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = IN_FRAMESET_MODE;
+ }
+
+ else if (tn === $.BASE || tn === $.BASEFONT || tn === $.BGSOUND || tn === $.LINK || tn === $.META ||
+ tn === $.NOFRAMES || tn === $.SCRIPT || tn === $.STYLE || tn === $.TEMPLATE || tn === $.TITLE) {
+ p.openElements.push(p.headElement);
+ startTagInHead(p, token);
+ p.openElements.remove(p.headElement);
+ }
+
+ else if (tn !== $.HEAD)
+ tokenAfterHead(p, token);
+}
+
+function endTagAfterHead(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.BODY || tn === $.HTML || tn === $.BR)
+ tokenAfterHead(p, token);
+
+ else if (tn === $.TEMPLATE)
+ endTagInHead(p, token);
+}
+
+function tokenAfterHead(p, token) {
+ p._processFakeStartTag($.BODY);
+ p.framesetOk = true;
+ p._processToken(token);
+}
+
+
+//12.2.5.4.7 The "in body" insertion mode
+//------------------------------------------------------------------
+function whitespaceCharacterInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._insertCharacters(token);
+}
+
+function characterInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._insertCharacters(token);
+ p.framesetOk = false;
+}
+
+function htmlStartTagInBody(p, token) {
+ if (p.openElements.tmplCount === 0)
+ p.treeAdapter.adoptAttributes(p.openElements.items[0], token.attrs);
+}
+
+function bodyStartTagInBody(p, token) {
+ var bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
+
+ if (bodyElement && p.openElements.tmplCount === 0) {
+ p.framesetOk = false;
+ p.treeAdapter.adoptAttributes(bodyElement, token.attrs);
+ }
+}
+
+function framesetStartTagInBody(p, token) {
+ var bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
+
+ if (p.framesetOk && bodyElement) {
+ p.treeAdapter.detachNode(bodyElement);
+ p.openElements.popAllUpToHtmlElement();
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = IN_FRAMESET_MODE;
+ }
+}
+
+function addressStartTagInBody(p, token) {
+ if (p.openElements.hasInButtonScope($.P))
+ p._closePElement();
+
+ p._insertElement(token, NS.HTML);
+}
+
+function numberedHeaderStartTagInBody(p, token) {
+ if (p.openElements.hasInButtonScope($.P))
+ p._closePElement();
+
+ var tn = p.openElements.currentTagName;
+
+ if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6)
+ p.openElements.pop();
+
+ p._insertElement(token, NS.HTML);
+}
+
+function preStartTagInBody(p, token) {
+ if (p.openElements.hasInButtonScope($.P))
+ p._closePElement();
+
+ p._insertElement(token, NS.HTML);
+ //NOTE: If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move
+ //on to the next one. (Newlines at the start of pre blocks are ignored as an authoring convenience.)
+ p.skipNextNewLine = true;
+ p.framesetOk = false;
+}
+
+function formStartTagInBody(p, token) {
+ var inTemplate = p.openElements.tmplCount > 0;
+
+ if (!p.formElement || inTemplate) {
+ if (p.openElements.hasInButtonScope($.P))
+ p._closePElement();
+
+ p._insertElement(token, NS.HTML);
+
+ if (!inTemplate)
+ p.formElement = p.openElements.current;
+ }
+}
+
+function listItemStartTagInBody(p, token) {
+ p.framesetOk = false;
+
+ for (var i = p.openElements.stackTop; i >= 0; i--) {
+ var element = p.openElements.items[i],
+ tn = p.treeAdapter.getTagName(element);
+
+ if ((token.tagName === $.LI && tn === $.LI) ||
+ ((token.tagName === $.DD || token.tagName === $.DT) && (tn === $.DD || tn == $.DT))) {
+ p._processFakeEndTag(tn);
+ break;
+ }
+
+ if (tn !== $.ADDRESS && tn !== $.DIV && tn !== $.P && p._isSpecialElement(element))
+ break;
+ }
+
+ if (p.openElements.hasInButtonScope($.P))
+ p._closePElement();
+
+ p._insertElement(token, NS.HTML);
+}
+
+function plaintextStartTagInBody(p, token) {
+ if (p.openElements.hasInButtonScope($.P))
+ p._closePElement();
+
+ p._insertElement(token, NS.HTML);
+ p.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
+}
+
+function buttonStartTagInBody(p, token) {
+ if (p.openElements.hasInScope($.BUTTON)) {
+ p._processFakeEndTag($.BUTTON);
+ buttonStartTagInBody(p, token);
+ }
+
+ else {
+ p._reconstructActiveFormattingElements();
+ p._insertElement(token, NS.HTML);
+ p.framesetOk = false;
+ }
+}
+
+function aStartTagInBody(p, token) {
+ var activeElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName($.A);
+
+ if (activeElementEntry) {
+ p._processFakeEndTag($.A);
+ p.openElements.remove(activeElementEntry.element);
+ p.activeFormattingElements.removeEntry(activeElementEntry);
+ }
+
+ p._reconstructActiveFormattingElements();
+ p._insertElement(token, NS.HTML);
+ p.activeFormattingElements.pushElement(p.openElements.current, token);
+}
+
+function bStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._insertElement(token, NS.HTML);
+ p.activeFormattingElements.pushElement(p.openElements.current, token);
+}
+
+function nobrStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+
+ if (p.openElements.hasInScope($.NOBR)) {
+ p._processFakeEndTag($.NOBR);
+ p._reconstructActiveFormattingElements();
+ }
+
+ p._insertElement(token, NS.HTML);
+ p.activeFormattingElements.pushElement(p.openElements.current, token);
+}
+
+function appletStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._insertElement(token, NS.HTML);
+ p.activeFormattingElements.insertMarker();
+ p.framesetOk = false;
+}
+
+function tableStartTagInBody(p, token) {
+ if (!p.treeAdapter.isQuirksMode(p.document) && p.openElements.hasInButtonScope($.P))
+ p._closePElement();
+
+ p._insertElement(token, NS.HTML);
+ p.framesetOk = false;
+ p.insertionMode = IN_TABLE_MODE;
+}
+
+function areaStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._appendElement(token, NS.HTML);
+ p.framesetOk = false;
+}
+
+function inputStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._appendElement(token, NS.HTML);
+
+ var inputType = Tokenizer.getTokenAttr(token, ATTRS.TYPE);
+
+ if (!inputType || inputType.toLowerCase() !== HIDDEN_INPUT_TYPE)
+ p.framesetOk = false;
+
+}
+
+function paramStartTagInBody(p, token) {
+ p._appendElement(token, NS.HTML);
+}
+
+function hrStartTagInBody(p, token) {
+ if (p.openElements.hasInButtonScope($.P))
+ p._closePElement();
+
+ p._appendElement(token, NS.HTML);
+ p.framesetOk = false;
+}
+
+function imageStartTagInBody(p, token) {
+ token.tagName = $.IMG;
+ areaStartTagInBody(p, token);
+}
+
+function isindexStartTagInBody(p, token) {
+ if (!p.formElement || p.openElements.tmplCount > 0) {
+ p._processFakeStartTagWithAttrs($.FORM, getSearchableIndexFormAttrs(token));
+ p._processFakeStartTag($.HR);
+ p._processFakeStartTag($.LABEL);
+ p.treeAdapter.insertText(p.openElements.current, getSearchableIndexLabelText(token));
+ p._processFakeStartTagWithAttrs($.INPUT, getSearchableIndexInputAttrs(token));
+ p._processFakeEndTag($.LABEL);
+ p._processFakeStartTag($.HR);
+ p._processFakeEndTag($.FORM);
+ }
+}
+
+function textareaStartTagInBody(p, token) {
+ p._insertElement(token, NS.HTML);
+ //NOTE: If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move
+ //on to the next one. (Newlines at the start of textarea elements are ignored as an authoring convenience.)
+ p.skipNextNewLine = true;
+ p.tokenizer.state = Tokenizer.MODE.RCDATA;
+ p.originalInsertionMode = p.insertionMode;
+ p.framesetOk = false;
+ p.insertionMode = TEXT_MODE;
+}
+
+function xmpStartTagInBody(p, token) {
+ if (p.openElements.hasInButtonScope($.P))
+ p._closePElement();
+
+ p._reconstructActiveFormattingElements();
+ p.framesetOk = false;
+ p._switchToTextParsing(token, Tokenizer.MODE.RAWTEXT);
+}
+
+function iframeStartTagInBody(p, token) {
+ p.framesetOk = false;
+ p._switchToTextParsing(token, Tokenizer.MODE.RAWTEXT);
+}
+
+//NOTE: here we assume that we always act as an user agent with enabled plugins, so we parse
+//<noembed> as a rawtext.
+function noembedStartTagInBody(p, token) {
+ p._switchToTextParsing(token, Tokenizer.MODE.RAWTEXT);
+}
+
+function selectStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._insertElement(token, NS.HTML);
+ p.framesetOk = false;
+
+ if (p.insertionMode === IN_TABLE_MODE || p.insertionMode === IN_CAPTION_MODE ||
+ p.insertionMode === IN_TABLE_BODY_MODE || p.insertionMode === IN_ROW_MODE ||
+ p.insertionMode === IN_CELL_MODE) {
+ p.insertionMode = IN_SELECT_IN_TABLE_MODE;
+ }
+
+ else
+ p.insertionMode = IN_SELECT_MODE;
+}
+
+function optgroupStartTagInBody(p, token) {
+ if (p.openElements.currentTagName === $.OPTION)
+ p._processFakeEndTag($.OPTION);
+
+ p._reconstructActiveFormattingElements();
+ p._insertElement(token, NS.HTML);
+}
+
+function rpStartTagInBody(p, token) {
+ if (p.openElements.hasInScope($.RUBY))
+ p.openElements.generateImpliedEndTags();
+
+ p._insertElement(token, NS.HTML);
+}
+
+function menuitemStartTagInBody(p, token) {
+ p._appendElement(token, NS.HTML);
+}
+
+function mathStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+
+ ForeignContent.adjustTokenMathMLAttrs(token);
+ ForeignContent.adjustTokenXMLAttrs(token);
+
+ if (token.selfClosing)
+ p._appendElement(token, NS.MATHML);
+ else
+ p._insertElement(token, NS.MATHML);
+}
+
+function svgStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+
+ ForeignContent.adjustTokenSVGAttrs(token);
+ ForeignContent.adjustTokenXMLAttrs(token);
+
+ if (token.selfClosing)
+ p._appendElement(token, NS.SVG);
+ else
+ p._insertElement(token, NS.SVG);
+}
+
+function genericStartTagInBody(p, token) {
+ p._reconstructActiveFormattingElements();
+ p._insertElement(token, NS.HTML);
+}
+
+//OPTIMIZATION: Integer comparisons are low-cost, so we can use very fast tag name length filters here.
+//It's faster than using dictionary.
+function startTagInBody(p, token) {
+ var tn = token.tagName;
+
+ switch (tn.length) {
+ case 1:
+ if (tn === $.I || tn === $.S || tn === $.B || tn === $.U)
+ bStartTagInBody(p, token);
+
+ else if (tn === $.P)
+ addressStartTagInBody(p, token);
+
+ else if (tn === $.A)
+ aStartTagInBody(p, token);
+
+ else
+ genericStartTagInBody(p, token);
+
+ break;
+
+ case 2:
+ if (tn === $.DL || tn === $.OL || tn === $.UL)
+ addressStartTagInBody(p, token);
+
+ else if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6)
+ numberedHeaderStartTagInBody(p, token);
+
+ else if (tn === $.LI || tn === $.DD || tn === $.DT)
+ listItemStartTagInBody(p, token);
+
+ else if (tn === $.EM || tn === $.TT)
+ bStartTagInBody(p, token);
+
+ else if (tn === $.BR)
+ areaStartTagInBody(p, token);
+
+ else if (tn === $.HR)
+ hrStartTagInBody(p, token);
+
+ else if (tn === $.RP || tn === $.RT)
+ rpStartTagInBody(p, token);
+
+ else if (tn !== $.TH && tn !== $.TD && tn !== $.TR)
+ genericStartTagInBody(p, token);
+
+ break;
+
+ case 3:
+ if (tn === $.DIV || tn === $.DIR || tn === $.NAV)
+ addressStartTagInBody(p, token);
+
+ else if (tn === $.PRE)
+ preStartTagInBody(p, token);
+
+ else if (tn === $.BIG)
+ bStartTagInBody(p, token);
+
+ else if (tn === $.IMG || tn === $.WBR)
+ areaStartTagInBody(p, token);
+
+ else if (tn === $.XMP)
+ xmpStartTagInBody(p, token);
+
+ else if (tn === $.SVG)
+ svgStartTagInBody(p, token);
+
+ else if (tn !== $.COL)
+ genericStartTagInBody(p, token);
+
+ break;
+
+ case 4:
+ if (tn === $.HTML)
+ htmlStartTagInBody(p, token);
+
+ else if (tn === $.BASE || tn === $.LINK || tn === $.META)
+ startTagInHead(p, token);
+
+ else if (tn === $.BODY)
+ bodyStartTagInBody(p, token);
+
+ else if (tn === $.MAIN || tn === $.MENU)
+ addressStartTagInBody(p, token);
+
+ else if (tn === $.FORM)
+ formStartTagInBody(p, token);
+
+ else if (tn === $.CODE || tn === $.FONT)
+ bStartTagInBody(p, token);
+
+ else if (tn === $.NOBR)
+ nobrStartTagInBody(p, token);
+
+ else if (tn === $.AREA)
+ areaStartTagInBody(p, token);
+
+ else if (tn === $.MATH)
+ mathStartTagInBody(p, token);
+
+ else if (tn !== $.HEAD)
+ genericStartTagInBody(p, token);
+
+ break;
+
+ case 5:
+ if (tn === $.STYLE || tn === $.TITLE)
+ startTagInHead(p, token);
+
+ else if (tn === $.ASIDE)
+ addressStartTagInBody(p, token);
+
+ else if (tn === $.SMALL)
+ bStartTagInBody(p, token);
+
+ else if (tn === $.TABLE)
+ tableStartTagInBody(p, token);
+
+ else if (tn === $.EMBED)
+ areaStartTagInBody(p, token);
+
+ else if (tn === $.INPUT)
+ inputStartTagInBody(p, token);
+
+ else if (tn === $.PARAM || tn === $.TRACK)
+ paramStartTagInBody(p, token);
+
+ else if (tn === $.IMAGE)
+ imageStartTagInBody(p, token);
+
+ else if (tn !== $.FRAME && tn !== $.TBODY && tn !== $.TFOOT && tn !== $.THEAD)
+ genericStartTagInBody(p, token);
+
+ break;
+
+ case 6:
+ if (tn === $.SCRIPT)
+ startTagInHead(p, token);
+
+ else if (tn === $.CENTER || tn === $.FIGURE || tn === $.FOOTER || tn === $.HEADER || tn === $.HGROUP)
+ addressStartTagInBody(p, token);
+
+ else if (tn === $.BUTTON)
+ buttonStartTagInBody(p, token);
+
+ else if (tn === $.STRIKE || tn === $.STRONG)
+ bStartTagInBody(p, token);
+
+ else if (tn === $.APPLET || tn === $.OBJECT)
+ appletStartTagInBody(p, token);
+
+ else if (tn === $.KEYGEN)
+ areaStartTagInBody(p, token);
+
+ else if (tn === $.SOURCE)
+ paramStartTagInBody(p, token);
+
+ else if (tn === $.IFRAME)
+ iframeStartTagInBody(p, token);
+
+ else if (tn === $.SELECT)
+ selectStartTagInBody(p, token);
+
+ else if (tn === $.OPTION)
+ optgroupStartTagInBody(p, token);
+
+ else
+ genericStartTagInBody(p, token);
+
+ break;
+
+ case 7:
+ if (tn === $.BGSOUND || tn === $.COMMAND)
+ startTagInHead(p, token);
+
+ else if (tn === $.DETAILS || tn === $.ADDRESS || tn === $.ARTICLE || tn === $.SECTION || tn === $.SUMMARY)
+ addressStartTagInBody(p, token);
+
+ else if (tn === $.LISTING)
+ preStartTagInBody(p, token);
+
+ else if (tn === $.MARQUEE)
+ appletStartTagInBody(p, token);
+
+ else if (tn === $.ISINDEX)
+ isindexStartTagInBody(p, token);
+
+ else if (tn === $.NOEMBED)
+ noembedStartTagInBody(p, token);
+
+ else if (tn !== $.CAPTION)
+ genericStartTagInBody(p, token);
+
+ break;
+
+ case 8:
+ if (tn === $.BASEFONT || tn === $.MENUITEM)
+ menuitemStartTagInBody(p, token);
+
+ else if (tn === $.FRAMESET)
+ framesetStartTagInBody(p, token);
+
+ else if (tn === $.FIELDSET)
+ addressStartTagInBody(p, token);
+
+ else if (tn === $.TEXTAREA)
+ textareaStartTagInBody(p, token);
+
+ else if (tn === $.TEMPLATE)
+ startTagInHead(p, token);
+
+ else if (tn === $.NOSCRIPT)
+ noembedStartTagInBody(p, token);
+
+ else if (tn === $.OPTGROUP)
+ optgroupStartTagInBody(p, token);
+
+ else if (tn !== $.COLGROUP)
+ genericStartTagInBody(p, token);
+
+ break;
+
+ case 9:
+ if (tn === $.PLAINTEXT)
+ plaintextStartTagInBody(p, token);
+
+ else
+ genericStartTagInBody(p, token);
+
+ break;
+
+ case 10:
+ if (tn === $.BLOCKQUOTE || tn === $.FIGCAPTION)
+ addressStartTagInBody(p, token);
+
+ else
+ genericStartTagInBody(p, token);
+
+ break;
+
+ default:
+ genericStartTagInBody(p, token);
+ }
+}
+
+function bodyEndTagInBody(p, token) {
+ if (p.openElements.hasInScope($.BODY))
+ p.insertionMode = AFTER_BODY_MODE;
+
+ else
+ token.ignored = true;
+}
+
+function htmlEndTagInBody(p, token) {
+ var fakeToken = p._processFakeEndTag($.BODY);
+
+ if (!fakeToken.ignored)
+ p._processToken(token);
+}
+
+function addressEndTagInBody(p, token) {
+ var tn = token.tagName;
+
+ if (p.openElements.hasInScope(tn)) {
+ p.openElements.generateImpliedEndTags();
+ p.openElements.popUntilTagNamePopped(tn);
+ }
+}
+
+function formEndTagInBody(p, token) {
+ var inTemplate = p.openElements.tmplCount > 0,
+ formElement = p.formElement;
+
+ if (!inTemplate)
+ p.formElement = null;
+
+ if ((formElement || inTemplate) && p.openElements.hasInScope($.FORM)) {
+ p.openElements.generateImpliedEndTags();
+
+ if (inTemplate)
+ p.openElements.popUntilTagNamePopped($.FORM);
+
+ else
+ p.openElements.remove(formElement);
+ }
+}
+
+function pEndTagInBody(p, token) {
+ if (p.openElements.hasInButtonScope($.P)) {
+ p.openElements.generateImpliedEndTagsWithExclusion($.P);
+ p.openElements.popUntilTagNamePopped($.P);
+ }
+
+ else {
+ p._processFakeStartTag($.P);
+ p._processToken(token);
+ }
+}
+
+function liEndTagInBody(p, token) {
+ if (p.openElements.hasInListItemScope($.LI)) {
+ p.openElements.generateImpliedEndTagsWithExclusion($.LI);
+ p.openElements.popUntilTagNamePopped($.LI);
+ }
+}
+
+function ddEndTagInBody(p, token) {
+ var tn = token.tagName;
+
+ if (p.openElements.hasInScope(tn)) {
+ p.openElements.generateImpliedEndTagsWithExclusion(tn);
+ p.openElements.popUntilTagNamePopped(tn);
+ }
+}
+
+function numberedHeaderEndTagInBody(p, token) {
+ if (p.openElements.hasNumberedHeaderInScope()) {
+ p.openElements.generateImpliedEndTags();
+ p.openElements.popUntilNumberedHeaderPopped();
+ }
+}
+
+function appletEndTagInBody(p, token) {
+ var tn = token.tagName;
+
+ if (p.openElements.hasInScope(tn)) {
+ p.openElements.generateImpliedEndTags();
+ p.openElements.popUntilTagNamePopped(tn);
+ p.activeFormattingElements.clearToLastMarker();
+ }
+}
+
+function brEndTagInBody(p, token) {
+ p._processFakeStartTag($.BR);
+}
+
+function genericEndTagInBody(p, token) {
+ var tn = token.tagName;
+
+ for (var i = p.openElements.stackTop; i > 0; i--) {
+ var element = p.openElements.items[i];
+
+ if (p.treeAdapter.getTagName(element) === tn) {
+ p.openElements.generateImpliedEndTagsWithExclusion(tn);
+ p.openElements.popUntilElementPopped(element);
+ break;
+ }
+
+ if (p._isSpecialElement(element))
+ break;
+ }
+}
+
+//OPTIMIZATION: Integer comparisons are low-cost, so we can use very fast tag name length filters here.
+//It's faster than using dictionary.
+function endTagInBody(p, token) {
+ var tn = token.tagName;
+
+ switch (tn.length) {
+ case 1:
+ if (tn === $.A || tn === $.B || tn === $.I || tn === $.S || tn == $.U)
+ callAdoptionAgency(p, token);
+
+ else if (tn === $.P)
+ pEndTagInBody(p, token);
+
+ else
+ genericEndTagInBody(p, token);
+
+ break;
+
+ case 2:
+ if (tn == $.DL || tn === $.UL || tn === $.OL)
+ addressEndTagInBody(p, token);
+
+ else if (tn === $.LI)
+ liEndTagInBody(p, token);
+
+ else if (tn === $.DD || tn === $.DT)
+ ddEndTagInBody(p, token);
+
+ else if (tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6)
+ numberedHeaderEndTagInBody(p, token);
+
+ else if (tn === $.BR)
+ brEndTagInBody(p, token);
+
+ else if (tn === $.EM || tn === $.TT)
+ callAdoptionAgency(p, token);
+
+ else
+ genericEndTagInBody(p, token);
+
+ break;
+
+ case 3:
+ if (tn === $.BIG)
+ callAdoptionAgency(p, token);
+
+ else if (tn === $.DIR || tn === $.DIV || tn === $.NAV)
+ addressEndTagInBody(p, token);
+
+ else
+ genericEndTagInBody(p, token);
+
+ break;
+
+ case 4:
+ if (tn === $.BODY)
+ bodyEndTagInBody(p, token);
+
+ else if (tn === $.HTML)
+ htmlEndTagInBody(p, token);
+
+ else if (tn === $.FORM)
+ formEndTagInBody(p, token);
+
+ else if (tn === $.CODE || tn === $.FONT || tn === $.NOBR)
+ callAdoptionAgency(p, token);
+
+ else if (tn === $.MAIN || tn === $.MENU)
+ addressEndTagInBody(p, token);
+
+ else
+ genericEndTagInBody(p, token);
+
+ break;
+
+ case 5:
+ if (tn === $.ASIDE)
+ addressEndTagInBody(p, token);
+
+ else if (tn === $.SMALL)
+ callAdoptionAgency(p, token);
+
+ else
+ genericEndTagInBody(p, token);
+
+ break;
+
+ case 6:
+ if (tn === $.CENTER || tn === $.FIGURE || tn === $.FOOTER || tn === $.HEADER || tn === $.HGROUP)
+ addressEndTagInBody(p, token);
+
+ else if (tn === $.APPLET || tn === $.OBJECT)
+ appletEndTagInBody(p, token);
+
+ else if (tn == $.STRIKE || tn === $.STRONG)
+ callAdoptionAgency(p, token);
+
+ else
+ genericEndTagInBody(p, token);
+
+ break;
+
+ case 7:
+ if (tn === $.ADDRESS || tn === $.ARTICLE || tn === $.DETAILS || tn === $.SECTION || tn === $.SUMMARY)
+ addressEndTagInBody(p, token);
+
+ else if (tn === $.MARQUEE)
+ appletEndTagInBody(p, token);
+
+ else
+ genericEndTagInBody(p, token);
+
+ break;
+
+ case 8:
+ if (tn === $.FIELDSET)
+ addressEndTagInBody(p, token);
+
+ else if (tn === $.TEMPLATE)
+ endTagInHead(p, token);
+
+ else
+ genericEndTagInBody(p, token);
+
+ break;
+
+ case 10:
+ if (tn === $.BLOCKQUOTE || tn === $.FIGCAPTION)
+ addressEndTagInBody(p, token);
+
+ else
+ genericEndTagInBody(p, token);
+
+ break;
+
+ default :
+ genericEndTagInBody(p, token);
+ }
+}
+
+function eofInBody(p, token) {
+ if (p.tmplInsertionModeStackTop > -1)
+ eofInTemplate(p, token);
+
+ else
+ p.stopped = true;
+}
+
+//12.2.5.4.8 The "text" insertion mode
+//------------------------------------------------------------------
+function endTagInText(p, token) {
+ if (!p.fragmentContext && p.scriptHandler && token.tagName === $.SCRIPT)
+ p.scriptHandler(p.document, p.openElements.current);
+
+ p.openElements.pop();
+ p.insertionMode = p.originalInsertionMode;
+}
+
+
+function eofInText(p, token) {
+ p.openElements.pop();
+ p.insertionMode = p.originalInsertionMode;
+ p._processToken(token);
+}
+
+
+//12.2.5.4.9 The "in table" insertion mode
+//------------------------------------------------------------------
+function characterInTable(p, token) {
+ var curTn = p.openElements.currentTagName;
+
+ if (curTn === $.TABLE || curTn === $.TBODY || curTn === $.TFOOT || curTn === $.THEAD || curTn === $.TR) {
+ p.pendingCharacterTokens = [];
+ p.hasNonWhitespacePendingCharacterToken = false;
+ p.originalInsertionMode = p.insertionMode;
+ p.insertionMode = IN_TABLE_TEXT_MODE;
+ p._processToken(token);
+ }
+
+ else
+ tokenInTable(p, token);
+}
+
+function captionStartTagInTable(p, token) {
+ p.openElements.clearBackToTableContext();
+ p.activeFormattingElements.insertMarker();
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = IN_CAPTION_MODE;
+}
+
+function colgroupStartTagInTable(p, token) {
+ p.openElements.clearBackToTableContext();
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = IN_COLUMN_GROUP_MODE;
+}
+
+function colStartTagInTable(p, token) {
+ p._processFakeStartTag($.COLGROUP);
+ p._processToken(token);
+}
+
+function tbodyStartTagInTable(p, token) {
+ p.openElements.clearBackToTableContext();
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = IN_TABLE_BODY_MODE;
+}
+
+function tdStartTagInTable(p, token) {
+ p._processFakeStartTag($.TBODY);
+ p._processToken(token);
+}
+
+function tableStartTagInTable(p, token) {
+ var fakeToken = p._processFakeEndTag($.TABLE);
+
+ //NOTE: The fake end tag token here can only be ignored in the fragment case.
+ if (!fakeToken.ignored)
+ p._processToken(token);
+}
+
+function inputStartTagInTable(p, token) {
+ var inputType = Tokenizer.getTokenAttr(token, ATTRS.TYPE);
+
+ if (inputType && inputType.toLowerCase() === HIDDEN_INPUT_TYPE)
+ p._appendElement(token, NS.HTML);
+
+ else
+ tokenInTable(p, token);
+}
+
+function formStartTagInTable(p, token) {
+ if (!p.formElement && p.openElements.tmplCount === 0) {
+ p._insertElement(token, NS.HTML);
+ p.formElement = p.openElements.current;
+ p.openElements.pop();
+ }
+}
+
+function startTagInTable(p, token) {
+ var tn = token.tagName;
+
+ switch (tn.length) {
+ case 2:
+ if (tn === $.TD || tn === $.TH || tn === $.TR)
+ tdStartTagInTable(p, token);
+
+ else
+ tokenInTable(p, token);
+
+ break;
+
+ case 3:
+ if (tn === $.COL)
+ colStartTagInTable(p, token);
+
+ else
+ tokenInTable(p, token);
+
+ break;
+
+ case 4:
+ if (tn === $.FORM)
+ formStartTagInTable(p, token);
+
+ else
+ tokenInTable(p, token);
+
+ break;
+
+ case 5:
+ if (tn === $.TABLE)
+ tableStartTagInTable(p, token);
+
+ else if (tn === $.STYLE)
+ startTagInHead(p, token);
+
+ else if (tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD)
+ tbodyStartTagInTable(p, token);
+
+ else if (tn === $.INPUT)
+ inputStartTagInTable(p, token);
+
+ else
+ tokenInTable(p, token);
+
+ break;
+
+ case 6:
+ if (tn === $.SCRIPT)
+ startTagInHead(p, token);
+
+ else
+ tokenInTable(p, token);
+
+ break;
+
+ case 7:
+ if (tn === $.CAPTION)
+ captionStartTagInTable(p, token);
+
+ else
+ tokenInTable(p, token);
+
+ break;
+
+ case 8:
+ if (tn === $.COLGROUP)
+ colgroupStartTagInTable(p, token);
+
+ else if (tn === $.TEMPLATE)
+ startTagInHead(p, token);
+
+ else
+ tokenInTable(p, token);
+
+ break;
+
+ default:
+ tokenInTable(p, token);
+ }
+
+}
+
+function endTagInTable(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.TABLE) {
+ if (p.openElements.hasInTableScope($.TABLE)) {
+ p.openElements.popUntilTagNamePopped($.TABLE);
+ p._resetInsertionMode();
+ }
+
+ else
+ token.ignored = true;
+ }
+
+ else if (tn === $.TEMPLATE)
+ endTagInHead(p, token);
+
+ else if (tn !== $.BODY && tn !== $.CAPTION && tn !== $.COL && tn !== $.COLGROUP && tn !== $.HTML &&
+ tn !== $.TBODY && tn !== $.TD && tn !== $.TFOOT && tn !== $.TH && tn !== $.THEAD && tn !== $.TR) {
+ tokenInTable(p, token);
+ }
+}
+
+function tokenInTable(p, token) {
+ var savedFosterParentingState = p.fosterParentingEnabled;
+
+ p.fosterParentingEnabled = true;
+ p._processTokenInBodyMode(token);
+ p.fosterParentingEnabled = savedFosterParentingState;
+}
+
+
+//12.2.5.4.10 The "in table text" insertion mode
+//------------------------------------------------------------------
+function whitespaceCharacterInTableText(p, token) {
+ p.pendingCharacterTokens.push(token);
+}
+
+function characterInTableText(p, token) {
+ p.pendingCharacterTokens.push(token);
+ p.hasNonWhitespacePendingCharacterToken = true;
+}
+
+function tokenInTableText(p, token) {
+ if (p.hasNonWhitespacePendingCharacterToken) {
+ for (var i = 0; i < p.pendingCharacterTokens.length; i++)
+ tokenInTable(p, p.pendingCharacterTokens[i]);
+ }
+
+ else {
+ for (var i = 0; i < p.pendingCharacterTokens.length; i++)
+ p._insertCharacters(p.pendingCharacterTokens[i]);
+ }
+
+ p.insertionMode = p.originalInsertionMode;
+ p._processToken(token);
+}
+
+
+//12.2.5.4.11 The "in caption" insertion mode
+//------------------------------------------------------------------
+function startTagInCaption(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.CAPTION || tn === $.COL || tn === $.COLGROUP || tn === $.TBODY ||
+ tn === $.TD || tn === $.TFOOT || tn === $.TH || tn === $.THEAD || tn === $.TR) {
+ var fakeToken = p._processFakeEndTag($.CAPTION);
+
+ //NOTE: The fake end tag token here can only be ignored in the fragment case.
+ if (!fakeToken.ignored)
+ p._processToken(token);
+ }
+
+ else
+ startTagInBody(p, token);
+}
+
+function endTagInCaption(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.CAPTION) {
+ if (p.openElements.hasInTableScope($.CAPTION)) {
+ p.openElements.generateImpliedEndTags();
+ p.openElements.popUntilTagNamePopped($.CAPTION);
+ p.activeFormattingElements.clearToLastMarker();
+ p.insertionMode = IN_TABLE_MODE;
+ }
+
+ else
+ token.ignored = true;
+ }
+
+ else if (tn === $.TABLE) {
+ var fakeToken = p._processFakeEndTag($.CAPTION);
+
+ //NOTE: The fake end tag token here can only be ignored in the fragment case.
+ if (!fakeToken.ignored)
+ p._processToken(token);
+ }
+
+ else if (tn !== $.BODY && tn !== $.COL && tn !== $.COLGROUP && tn !== $.HTML && tn !== $.TBODY &&
+ tn !== $.TD && tn !== $.TFOOT && tn !== $.TH && tn !== $.THEAD && tn !== $.TR) {
+ endTagInBody(p, token);
+ }
+}
+
+
+//12.2.5.4.12 The "in column group" insertion mode
+//------------------------------------------------------------------
+function startTagInColumnGroup(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HTML)
+ startTagInBody(p, token);
+
+ else if (tn === $.COL)
+ p._appendElement(token, NS.HTML);
+
+ else if (tn === $.TEMPLATE)
+ startTagInHead(p, token);
+
+ else
+ tokenInColumnGroup(p, token);
+}
+
+function endTagInColumnGroup(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.COLGROUP) {
+ if (p.openElements.currentTagName !== $.COLGROUP)
+ token.ignored = true;
+
+ else {
+ p.openElements.pop();
+ p.insertionMode = IN_TABLE_MODE;
+ }
+ }
+
+ else if (tn === $.TEMPLATE)
+ endTagInHead(p, token);
+
+ else if (tn !== $.COL)
+ tokenInColumnGroup(p, token);
+}
+
+function tokenInColumnGroup(p, token) {
+ var fakeToken = p._processFakeEndTag($.COLGROUP);
+
+ //NOTE: The fake end tag token here can only be ignored in the fragment case.
+ if (!fakeToken.ignored)
+ p._processToken(token);
+}
+
+//12.2.5.4.13 The "in table body" insertion mode
+//------------------------------------------------------------------
+function startTagInTableBody(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.TR) {
+ p.openElements.clearBackToTableBodyContext();
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = IN_ROW_MODE;
+ }
+
+ else if (tn === $.TH || tn === $.TD) {
+ p._processFakeStartTag($.TR);
+ p._processToken(token);
+ }
+
+ else if (tn === $.CAPTION || tn === $.COL || tn === $.COLGROUP ||
+ tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD) {
+
+ if (p.openElements.hasTableBodyContextInTableScope()) {
+ p.openElements.clearBackToTableBodyContext();
+ p._processFakeEndTag(p.openElements.currentTagName);
+ p._processToken(token);
+ }
+ }
+
+ else
+ startTagInTable(p, token);
+}
+
+function endTagInTableBody(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD) {
+ if (p.openElements.hasInTableScope(tn)) {
+ p.openElements.clearBackToTableBodyContext();
+ p.openElements.pop();
+ p.insertionMode = IN_TABLE_MODE;
+ }
+ }
+
+ else if (tn === $.TABLE) {
+ if (p.openElements.hasTableBodyContextInTableScope()) {
+ p.openElements.clearBackToTableBodyContext();
+ p._processFakeEndTag(p.openElements.currentTagName);
+ p._processToken(token);
+ }
+ }
+
+ else if (tn !== $.BODY && tn !== $.CAPTION && tn !== $.COL && tn !== $.COLGROUP ||
+ tn !== $.HTML && tn !== $.TD && tn !== $.TH && tn !== $.TR) {
+ endTagInTable(p, token);
+ }
+}
+
+//12.2.5.4.14 The "in row" insertion mode
+//------------------------------------------------------------------
+function startTagInRow(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.TH || tn === $.TD) {
+ p.openElements.clearBackToTableRowContext();
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = IN_CELL_MODE;
+ p.activeFormattingElements.insertMarker();
+ }
+
+ else if (tn === $.CAPTION || tn === $.COL || tn === $.COLGROUP || tn === $.TBODY ||
+ tn === $.TFOOT || tn === $.THEAD || tn === $.TR) {
+ var fakeToken = p._processFakeEndTag($.TR);
+
+ //NOTE: The fake end tag token here can only be ignored in the fragment case.
+ if (!fakeToken.ignored)
+ p._processToken(token);
+ }
+
+ else
+ startTagInTable(p, token);
+}
+
+function endTagInRow(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.TR) {
+ if (p.openElements.hasInTableScope($.TR)) {
+ p.openElements.clearBackToTableRowContext();
+ p.openElements.pop();
+ p.insertionMode = IN_TABLE_BODY_MODE;
+ }
+
+ else
+ token.ignored = true;
+ }
+
+ else if (tn === $.TABLE) {
+ var fakeToken = p._processFakeEndTag($.TR);
+
+ //NOTE: The fake end tag token here can only be ignored in the fragment case.
+ if (!fakeToken.ignored)
+ p._processToken(token);
+ }
+
+ else if (tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD) {
+ if (p.openElements.hasInTableScope(tn)) {
+ p._processFakeEndTag($.TR);
+ p._processToken(token);
+ }
+ }
+
+ else if (tn !== $.BODY && tn !== $.CAPTION && tn !== $.COL && tn !== $.COLGROUP ||
+ tn !== $.HTML && tn !== $.TD && tn !== $.TH) {
+ endTagInTable(p, token);
+ }
+}
+
+
+//12.2.5.4.15 The "in cell" insertion mode
+//------------------------------------------------------------------
+function startTagInCell(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.CAPTION || tn === $.COL || tn === $.COLGROUP || tn === $.TBODY ||
+ tn === $.TD || tn === $.TFOOT || tn === $.TH || tn === $.THEAD || tn === $.TR) {
+
+ if (p.openElements.hasInTableScope($.TD) || p.openElements.hasInTableScope($.TH)) {
+ p._closeTableCell();
+ p._processToken(token);
+ }
+ }
+
+ else
+ startTagInBody(p, token);
+}
+
+function endTagInCell(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.TD || tn === $.TH) {
+ if (p.openElements.hasInTableScope(tn)) {
+ p.openElements.generateImpliedEndTags();
+ p.openElements.popUntilTagNamePopped(tn);
+ p.activeFormattingElements.clearToLastMarker();
+ p.insertionMode = IN_ROW_MODE;
+ }
+ }
+
+ else if (tn === $.TABLE || tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD || tn === $.TR) {
+ if (p.openElements.hasInTableScope(tn)) {
+ p._closeTableCell();
+ p._processToken(token);
+ }
+ }
+
+ else if (tn !== $.BODY && tn !== $.CAPTION && tn !== $.COL && tn !== $.COLGROUP && tn !== $.HTML)
+ endTagInBody(p, token);
+}
+
+//12.2.5.4.16 The "in select" insertion mode
+//------------------------------------------------------------------
+function startTagInSelect(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HTML)
+ startTagInBody(p, token);
+
+ else if (tn === $.OPTION) {
+ if (p.openElements.currentTagName === $.OPTION)
+ p._processFakeEndTag($.OPTION);
+
+ p._insertElement(token, NS.HTML);
+ }
+
+ else if (tn === $.OPTGROUP) {
+ if (p.openElements.currentTagName === $.OPTION)
+ p._processFakeEndTag($.OPTION);
+
+ if (p.openElements.currentTagName === $.OPTGROUP)
+ p._processFakeEndTag($.OPTGROUP);
+
+ p._insertElement(token, NS.HTML);
+ }
+
+ else if (tn === $.SELECT)
+ p._processFakeEndTag($.SELECT);
+
+ else if (tn === $.INPUT || tn === $.KEYGEN || tn === $.TEXTAREA) {
+ if (p.openElements.hasInSelectScope($.SELECT)) {
+ p._processFakeEndTag($.SELECT);
+ p._processToken(token);
+ }
+ }
+
+ else if (tn === $.SCRIPT || tn === $.TEMPLATE)
+ startTagInHead(p, token);
+}
+
+function endTagInSelect(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.OPTGROUP) {
+ var prevOpenElement = p.openElements.items[p.openElements.stackTop - 1],
+ prevOpenElementTn = prevOpenElement && p.treeAdapter.getTagName(prevOpenElement);
+
+ if (p.openElements.currentTagName === $.OPTION && prevOpenElementTn === $.OPTGROUP)
+ p._processFakeEndTag($.OPTION);
+
+ if (p.openElements.currentTagName === $.OPTGROUP)
+ p.openElements.pop();
+ }
+
+ else if (tn === $.OPTION) {
+ if (p.openElements.currentTagName === $.OPTION)
+ p.openElements.pop();
+ }
+
+ else if (tn === $.SELECT && p.openElements.hasInSelectScope($.SELECT)) {
+ p.openElements.popUntilTagNamePopped($.SELECT);
+ p._resetInsertionMode();
+ }
+
+ else if (tn === $.TEMPLATE)
+ endTagInHead(p, token);
+}
+
+//12.2.5.4.17 The "in select in table" insertion mode
+//------------------------------------------------------------------
+function startTagInSelectInTable(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.CAPTION || tn === $.TABLE || tn === $.TBODY || tn === $.TFOOT ||
+ tn === $.THEAD || tn === $.TR || tn === $.TD || tn === $.TH) {
+ p._processFakeEndTag($.SELECT);
+ p._processToken(token);
+ }
+
+ else
+ startTagInSelect(p, token);
+}
+
+function endTagInSelectInTable(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.CAPTION || tn === $.TABLE || tn === $.TBODY || tn === $.TFOOT ||
+ tn === $.THEAD || tn === $.TR || tn === $.TD || tn === $.TH) {
+ if (p.openElements.hasInTableScope(tn)) {
+ p._processFakeEndTag($.SELECT);
+ p._processToken(token);
+ }
+ }
+
+ else
+ endTagInSelect(p, token);
+}
+
+//12.2.5.4.18 The "in template" insertion mode
+//------------------------------------------------------------------
+function startTagInTemplate(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.BASE || tn === $.BASEFONT || tn === $.BGSOUND || tn === $.LINK || tn === $.META ||
+ tn === $.NOFRAMES || tn === $.SCRIPT || tn === $.STYLE || tn === $.TEMPLATE || tn === $.TITLE) {
+ startTagInHead(p, token);
+ }
+
+ else {
+ var newInsertionMode = TEMPLATE_INSERTION_MODE_SWITCH_MAP[tn] || IN_BODY_MODE;
+
+ p._popTmplInsertionMode();
+ p._pushTmplInsertionMode(newInsertionMode);
+ p.insertionMode = newInsertionMode;
+ p._processToken(token);
+ }
+}
+
+function endTagInTemplate(p, token) {
+ if (token.tagName === $.TEMPLATE)
+ endTagInHead(p, token);
+}
+
+function eofInTemplate(p, token) {
+ if (p.openElements.tmplCount > 0) {
+ p.openElements.popUntilTemplatePopped();
+ p.activeFormattingElements.clearToLastMarker();
+ p._popTmplInsertionMode();
+ p._resetInsertionMode();
+ p._processToken(token);
+ }
+
+ else
+ p.stopped = true;
+}
+
+
+//12.2.5.4.19 The "after body" insertion mode
+//------------------------------------------------------------------
+function startTagAfterBody(p, token) {
+ if (token.tagName === $.HTML)
+ startTagInBody(p, token);
+
+ else
+ tokenAfterBody(p, token);
+}
+
+function endTagAfterBody(p, token) {
+ if (token.tagName === $.HTML) {
+ if (!p.fragmentContext)
+ p.insertionMode = AFTER_AFTER_BODY_MODE;
+ }
+
+ else
+ tokenAfterBody(p, token);
+}
+
+function tokenAfterBody(p, token) {
+ p.insertionMode = IN_BODY_MODE;
+ p._processToken(token);
+}
+
+//12.2.5.4.20 The "in frameset" insertion mode
+//------------------------------------------------------------------
+function startTagInFrameset(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HTML)
+ startTagInBody(p, token);
+
+ else if (tn === $.FRAMESET)
+ p._insertElement(token, NS.HTML);
+
+ else if (tn === $.FRAME)
+ p._appendElement(token, NS.HTML);
+
+ else if (tn === $.NOFRAMES)
+ startTagInHead(p, token);
+}
+
+function endTagInFrameset(p, token) {
+ if (token.tagName === $.FRAMESET && !p.openElements.isRootHtmlElementCurrent()) {
+ p.openElements.pop();
+
+ if (!p.fragmentContext && p.openElements.currentTagName !== $.FRAMESET)
+ p.insertionMode = AFTER_FRAMESET_MODE;
+ }
+}
+
+//12.2.5.4.21 The "after frameset" insertion mode
+//------------------------------------------------------------------
+function startTagAfterFrameset(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HTML)
+ startTagInBody(p, token);
+
+ else if (tn === $.NOFRAMES)
+ startTagInHead(p, token);
+}
+
+function endTagAfterFrameset(p, token) {
+ if (token.tagName === $.HTML)
+ p.insertionMode = AFTER_AFTER_FRAMESET_MODE;
+}
+
+//12.2.5.4.22 The "after after body" insertion mode
+//------------------------------------------------------------------
+function startTagAfterAfterBody(p, token) {
+ if (token.tagName === $.HTML)
+ startTagInBody(p, token);
+
+ else
+ tokenAfterAfterBody(p, token);
+}
+
+function tokenAfterAfterBody(p, token) {
+ p.insertionMode = IN_BODY_MODE;
+ p._processToken(token);
+}
+
+//12.2.5.4.23 The "after after frameset" insertion mode
+//------------------------------------------------------------------
+function startTagAfterAfterFrameset(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HTML)
+ startTagInBody(p, token);
+
+ else if (tn === $.NOFRAMES)
+ startTagInHead(p, token);
+}
+
+
+//12.2.5.5 The rules for parsing tokens in foreign content
+//------------------------------------------------------------------
+function nullCharacterInForeignContent(p, token) {
+ token.chars = UNICODE.REPLACEMENT_CHARACTER;
+ p._insertCharacters(token);
+}
+
+function characterInForeignContent(p, token) {
+ p._insertCharacters(token);
+ p.framesetOk = false;
+}
+
+function startTagInForeignContent(p, token) {
+ if (ForeignContent.causesExit(token) && !p.fragmentContext) {
+ while (p.treeAdapter.getNamespaceURI(p.openElements.current) !== NS.HTML &&
+ (!p._isMathMLTextIntegrationPoint(p.openElements.current)) &&
+ (!p._isHtmlIntegrationPoint(p.openElements.current))) {
+ p.openElements.pop();
+ }
+
+ p._processToken(token);
+ }
+
+ else {
+ var current = p._getAdjustedCurrentElement(),
+ currentNs = p.treeAdapter.getNamespaceURI(current);
+
+ if (currentNs === NS.MATHML)
+ ForeignContent.adjustTokenMathMLAttrs(token);
+
+ else if (currentNs === NS.SVG) {
+ ForeignContent.adjustTokenSVGTagName(token);
+ ForeignContent.adjustTokenSVGAttrs(token);
+ }
+
+ ForeignContent.adjustTokenXMLAttrs(token);
+
+ if (token.selfClosing)
+ p._appendElement(token, currentNs);
+ else
+ p._insertElement(token, currentNs);
+ }
+}
+
+function endTagInForeignContent(p, token) {
+ for (var i = p.openElements.stackTop; i > 0; i--) {
+ var element = p.openElements.items[i];
+
+ if (p.treeAdapter.getNamespaceURI(element) === NS.HTML) {
+ p._processToken(token);
+ break;
+ }
+
+ if (p.treeAdapter.getTagName(element).toLowerCase() === token.tagName) {
+ p.openElements.popUntilElementPopped(element);
+ break;
+ }
+ }
+}
+
+},{"../common/doctype":40,"../common/foreign_content":41,"../common/html":42,"../common/unicode":43,"../common/utils":44,"../tokenization/tokenizer":53,"../tree_adapters/default":54,"./formatting_element_list":56,"./location_info_mixin":57,"./open_element_stack":58}],60:[function(require,module,exports){
+(function (process,global){
+/*!
+ * @overview es6-promise - a tiny implementation of Promises/A+.
+ * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
+ * @license Licensed under MIT license
+ * See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE
+ * @version 2.3.0
+ */
+
+(function() {
+ "use strict";
+ function lib$es6$promise$utils$$objectOrFunction(x) {
+ return typeof x === 'function' || (typeof x === 'object' && x !== null);
+ }
+
+ function lib$es6$promise$utils$$isFunction(x) {
+ return typeof x === 'function';
+ }
+
+ function lib$es6$promise$utils$$isMaybeThenable(x) {
+ return typeof x === 'object' && x !== null;
+ }
+
+ var lib$es6$promise$utils$$_isArray;
+ if (!Array.isArray) {
+ lib$es6$promise$utils$$_isArray = function (x) {
+ return Object.prototype.toString.call(x) === '[object Array]';
+ };
+ } else {
+ lib$es6$promise$utils$$_isArray = Array.isArray;
+ }
+
+ var lib$es6$promise$utils$$isArray = lib$es6$promise$utils$$_isArray;
+ var lib$es6$promise$asap$$len = 0;
+ var lib$es6$promise$asap$$toString = {}.toString;
+ var lib$es6$promise$asap$$vertxNext;
+ var lib$es6$promise$asap$$customSchedulerFn;
+
+ var lib$es6$promise$asap$$asap = function asap(callback, arg) {
+ lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len] = callback;
+ lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len + 1] = arg;
+ lib$es6$promise$asap$$len += 2;
+ if (lib$es6$promise$asap$$len === 2) {
+ // If len is 2, that means that we need to schedule an async flush.
+ // If additional callbacks are queued before the queue is flushed, they
+ // will be processed by this flush that we are scheduling.
+ if (lib$es6$promise$asap$$customSchedulerFn) {
+ lib$es6$promise$asap$$customSchedulerFn(lib$es6$promise$asap$$flush);
+ } else {
+ lib$es6$promise$asap$$scheduleFlush();
+ }
+ }
+ }
+
+ function lib$es6$promise$asap$$setScheduler(scheduleFn) {
+ lib$es6$promise$asap$$customSchedulerFn = scheduleFn;
+ }
+
+ function lib$es6$promise$asap$$setAsap(asapFn) {
+ lib$es6$promise$asap$$asap = asapFn;
+ }
+
+ var lib$es6$promise$asap$$browserWindow = (typeof window !== 'undefined') ? window : undefined;
+ var lib$es6$promise$asap$$browserGlobal = lib$es6$promise$asap$$browserWindow || {};
+ var lib$es6$promise$asap$$BrowserMutationObserver = lib$es6$promise$asap$$browserGlobal.MutationObserver || lib$es6$promise$asap$$browserGlobal.WebKitMutationObserver;
+ var lib$es6$promise$asap$$isNode = typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
+
+ // test for web worker but not in IE10
+ var lib$es6$promise$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' &&
+ typeof importScripts !== 'undefined' &&
+ typeof MessageChannel !== 'undefined';
+
+ // node
+ function lib$es6$promise$asap$$useNextTick() {
+ var nextTick = process.nextTick;
+ // node version 0.10.x displays a deprecation warning when nextTick is used recursively
+ // setImmediate should be used instead instead
+ var version = process.versions.node.match(/^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$/);
+ if (Array.isArray(version) && version[1] === '0' && version[2] === '10') {
+ nextTick = setImmediate;
+ }
+ return function() {
+ nextTick(lib$es6$promise$asap$$flush);
+ };
+ }
+
+ // vertx
+ function lib$es6$promise$asap$$useVertxTimer() {
+ return function() {
+ lib$es6$promise$asap$$vertxNext(lib$es6$promise$asap$$flush);
+ };
+ }
+
+ function lib$es6$promise$asap$$useMutationObserver() {
+ var iterations = 0;
+ var observer = new lib$es6$promise$asap$$BrowserMutationObserver(lib$es6$promise$asap$$flush);
+ var node = document.createTextNode('');
+ observer.observe(node, { characterData: true });
+
+ return function() {
+ node.data = (iterations = ++iterations % 2);
+ };
+ }
+
+ // web worker
+ function lib$es6$promise$asap$$useMessageChannel() {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = lib$es6$promise$asap$$flush;
+ return function () {
+ channel.port2.postMessage(0);
+ };
+ }
+
+ function lib$es6$promise$asap$$useSetTimeout() {
+ return function() {
+ setTimeout(lib$es6$promise$asap$$flush, 1);
+ };
+ }
+
+ var lib$es6$promise$asap$$queue = new Array(1000);
+ function lib$es6$promise$asap$$flush() {
+ for (var i = 0; i < lib$es6$promise$asap$$len; i+=2) {
+ var callback = lib$es6$promise$asap$$queue[i];
+ var arg = lib$es6$promise$asap$$queue[i+1];
+
+ callback(arg);
+
+ lib$es6$promise$asap$$queue[i] = undefined;
+ lib$es6$promise$asap$$queue[i+1] = undefined;
+ }
+
+ lib$es6$promise$asap$$len = 0;
+ }
+
+ function lib$es6$promise$asap$$attemptVertex() {
+ try {
+ var r = require;
+ var vertx = r('vertx');
+ lib$es6$promise$asap$$vertxNext = vertx.runOnLoop || vertx.runOnContext;
+ return lib$es6$promise$asap$$useVertxTimer();
+ } catch(e) {
+ return lib$es6$promise$asap$$useSetTimeout();
+ }
+ }
+
+ var lib$es6$promise$asap$$scheduleFlush;
+ // Decide what async method to use to triggering processing of queued callbacks:
+ if (lib$es6$promise$asap$$isNode) {
+ lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useNextTick();
+ } else if (lib$es6$promise$asap$$BrowserMutationObserver) {
+ lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMutationObserver();
+ } else if (lib$es6$promise$asap$$isWorker) {
+ lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMessageChannel();
+ } else if (lib$es6$promise$asap$$browserWindow === undefined && typeof require === 'function') {
+ lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$attemptVertex();
+ } else {
+ lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useSetTimeout();
+ }
+
+ function lib$es6$promise$$internal$$noop() {}
+
+ var lib$es6$promise$$internal$$PENDING = void 0;
+ var lib$es6$promise$$internal$$FULFILLED = 1;
+ var lib$es6$promise$$internal$$REJECTED = 2;
+
+ var lib$es6$promise$$internal$$GET_THEN_ERROR = new lib$es6$promise$$internal$$ErrorObject();
+
+ function lib$es6$promise$$internal$$selfFullfillment() {
+ return new TypeError("You cannot resolve a promise with itself");
+ }
+
+ function lib$es6$promise$$internal$$cannotReturnOwn() {
+ return new TypeError('A promises callback cannot return that same promise.');
+ }
+
+ function lib$es6$promise$$internal$$getThen(promise) {
+ try {
+ return promise.then;
+ } catch(error) {
+ lib$es6$promise$$internal$$GET_THEN_ERROR.error = error;
+ return lib$es6$promise$$internal$$GET_THEN_ERROR;
+ }
+ }
+
+ function lib$es6$promise$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) {
+ try {
+ then.call(value, fulfillmentHandler, rejectionHandler);
+ } catch(e) {
+ return e;
+ }
+ }
+
+ function lib$es6$promise$$internal$$handleForeignThenable(promise, thenable, then) {
+ lib$es6$promise$asap$$asap(function(promise) {
+ var sealed = false;
+ var error = lib$es6$promise$$internal$$tryThen(then, thenable, function(value) {
+ if (sealed) { return; }
+ sealed = true;
+ if (thenable !== value) {
+ lib$es6$promise$$internal$$resolve(promise, value);
+ } else {
+ lib$es6$promise$$internal$$fulfill(promise, value);
+ }
+ }, function(reason) {
+ if (sealed) { return; }
+ sealed = true;
+
+ lib$es6$promise$$internal$$reject(promise, reason);
+ }, 'Settle: ' + (promise._label || ' unknown promise'));
+
+ if (!sealed && error) {
+ sealed = true;
+ lib$es6$promise$$internal$$reject(promise, error);
+ }
+ }, promise);
+ }
+
+ function lib$es6$promise$$internal$$handleOwnThenable(promise, thenable) {
+ if (thenable._state === lib$es6$promise$$internal$$FULFILLED) {
+ lib$es6$promise$$internal$$fulfill(promise, thenable._result);
+ } else if (thenable._state === lib$es6$promise$$internal$$REJECTED) {
+ lib$es6$promise$$internal$$reject(promise, thenable._result);
+ } else {
+ lib$es6$promise$$internal$$subscribe(thenable, undefined, function(value) {
+ lib$es6$promise$$internal$$resolve(promise, value);
+ }, function(reason) {
+ lib$es6$promise$$internal$$reject(promise, reason);
+ });
+ }
+ }
+
+ function lib$es6$promise$$internal$$handleMaybeThenable(promise, maybeThenable) {
+ if (maybeThenable.constructor === promise.constructor) {
+ lib$es6$promise$$internal$$handleOwnThenable(promise, maybeThenable);
+ } else {
+ var then = lib$es6$promise$$internal$$getThen(maybeThenable);
+
+ if (then === lib$es6$promise$$internal$$GET_THEN_ERROR) {
+ lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$GET_THEN_ERROR.error);
+ } else if (then === undefined) {
+ lib$es6$promise$$internal$$fulfill(promise, maybeThenable);
+ } else if (lib$es6$promise$utils$$isFunction(then)) {
+ lib$es6$promise$$internal$$handleForeignThenable(promise, maybeThenable, then);
+ } else {
+ lib$es6$promise$$internal$$fulfill(promise, maybeThenable);
+ }
+ }
+ }
+
+ function lib$es6$promise$$internal$$resolve(promise, value) {
+ if (promise === value) {
+ lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$selfFullfillment());
+ } else if (lib$es6$promise$utils$$objectOrFunction(value)) {
+ lib$es6$promise$$internal$$handleMaybeThenable(promise, value);
+ } else {
+ lib$es6$promise$$internal$$fulfill(promise, value);
+ }
+ }
+
+ function lib$es6$promise$$internal$$publishRejection(promise) {
+ if (promise._onerror) {
+ promise._onerror(promise._result);
+ }
+
+ lib$es6$promise$$internal$$publish(promise);
+ }
+
+ function lib$es6$promise$$internal$$fulfill(promise, value) {
+ if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }
+
+ promise._result = value;
+ promise._state = lib$es6$promise$$internal$$FULFILLED;
+
+ if (promise._subscribers.length !== 0) {
+ lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, promise);
+ }
+ }
+
+ function lib$es6$promise$$internal$$reject(promise, reason) {
+ if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }
+ promise._state = lib$es6$promise$$internal$$REJECTED;
+ promise._result = reason;
+
+ lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publishRejection, promise);
+ }
+
+ function lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection) {
+ var subscribers = parent._subscribers;
+ var length = subscribers.length;
+
+ parent._onerror = null;
+
+ subscribers[length] = child;
+ subscribers[length + lib$es6$promise$$internal$$FULFILLED] = onFulfillment;
+ subscribers[length + lib$es6$promise$$internal$$REJECTED] = onRejection;
+
+ if (length === 0 && parent._state) {
+ lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, parent);
+ }
+ }
+
+ function lib$es6$promise$$internal$$publish(promise) {
+ var subscribers = promise._subscribers;
+ var settled = promise._state;
+
+ if (subscribers.length === 0) { return; }
+
+ var child, callback, detail = promise._result;
+
+ for (var i = 0; i < subscribers.length; i += 3) {
+ child = subscribers[i];
+ callback = subscribers[i + settled];
+
+ if (child) {
+ lib$es6$promise$$internal$$invokeCallback(settled, child, callback, detail);
+ } else {
+ callback(detail);
+ }
+ }
+
+ promise._subscribers.length = 0;
+ }
+
+ function lib$es6$promise$$internal$$ErrorObject() {
+ this.error = null;
+ }
+
+ var lib$es6$promise$$internal$$TRY_CATCH_ERROR = new lib$es6$promise$$internal$$ErrorObject();
+
+ function lib$es6$promise$$internal$$tryCatch(callback, detail) {
+ try {
+ return callback(detail);
+ } catch(e) {
+ lib$es6$promise$$internal$$TRY_CATCH_ERROR.error = e;
+ return lib$es6$promise$$internal$$TRY_CATCH_ERROR;
+ }
+ }
+
+ function lib$es6$promise$$internal$$invokeCallback(settled, promise, callback, detail) {
+ var hasCallback = lib$es6$promise$utils$$isFunction(callback),
+ value, error, succeeded, failed;
+
+ if (hasCallback) {
+ value = lib$es6$promise$$internal$$tryCatch(callback, detail);
+
+ if (value === lib$es6$promise$$internal$$TRY_CATCH_ERROR) {
+ failed = true;
+ error = value.error;
+ value = null;
+ } else {
+ succeeded = true;
+ }
+
+ if (promise === value) {
+ lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$cannotReturnOwn());
+ return;
+ }
+
+ } else {
+ value = detail;
+ succeeded = true;
+ }
+
+ if (promise._state !== lib$es6$promise$$internal$$PENDING) {
+ // noop
+ } else if (hasCallback && succeeded) {
+ lib$es6$promise$$internal$$resolve(promise, value);
+ } else if (failed) {
+ lib$es6$promise$$internal$$reject(promise, error);
+ } else if (settled === lib$es6$promise$$internal$$FULFILLED) {
+ lib$es6$promise$$internal$$fulfill(promise, value);
+ } else if (settled === lib$es6$promise$$internal$$REJECTED) {
+ lib$es6$promise$$internal$$reject(promise, value);
+ }
+ }
+
+ function lib$es6$promise$$internal$$initializePromise(promise, resolver) {
+ try {
+ resolver(function resolvePromise(value){
+ lib$es6$promise$$internal$$resolve(promise, value);
+ }, function rejectPromise(reason) {
+ lib$es6$promise$$internal$$reject(promise, reason);
+ });
+ } catch(e) {
+ lib$es6$promise$$internal$$reject(promise, e);
+ }
+ }
+
+ function lib$es6$promise$enumerator$$Enumerator(Constructor, input) {
+ var enumerator = this;
+
+ enumerator._instanceConstructor = Constructor;
+ enumerator.promise = new Constructor(lib$es6$promise$$internal$$noop);
+
+ if (enumerator._validateInput(input)) {
+ enumerator._input = input;
+ enumerator.length = input.length;
+ enumerator._remaining = input.length;
+
+ enumerator._init();
+
+ if (enumerator.length === 0) {
+ lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);
+ } else {
+ enumerator.length = enumerator.length || 0;
+ enumerator._enumerate();
+ if (enumerator._remaining === 0) {
+ lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);
+ }
+ }
+ } else {
+ lib$es6$promise$$internal$$reject(enumerator.promise, enumerator._validationError());
+ }
+ }
+
+ lib$es6$promise$enumerator$$Enumerator.prototype._validateInput = function(input) {
+ return lib$es6$promise$utils$$isArray(input);
+ };
+
+ lib$es6$promise$enumerator$$Enumerator.prototype._validationError = function() {
+ return new Error('Array Methods must be provided an Array');
+ };
+
+ lib$es6$promise$enumerator$$Enumerator.prototype._init = function() {
+ this._result = new Array(this.length);
+ };
+
+ var lib$es6$promise$enumerator$$default = lib$es6$promise$enumerator$$Enumerator;
+
+ lib$es6$promise$enumerator$$Enumerator.prototype._enumerate = function() {
+ var enumerator = this;
+
+ var length = enumerator.length;
+ var promise = enumerator.promise;
+ var input = enumerator._input;
+
+ for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {
+ enumerator._eachEntry(input[i], i);
+ }
+ };
+
+ lib$es6$promise$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) {
+ var enumerator = this;
+ var c = enumerator._instanceConstructor;
+
+ if (lib$es6$promise$utils$$isMaybeThenable(entry)) {
+ if (entry.constructor === c && entry._state !== lib$es6$promise$$internal$$PENDING) {
+ entry._onerror = null;
+ enumerator._settledAt(entry._state, i, entry._result);
+ } else {
+ enumerator._willSettleAt(c.resolve(entry), i);
+ }
+ } else {
+ enumerator._remaining--;
+ enumerator._result[i] = entry;
+ }
+ };
+
+ lib$es6$promise$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) {
+ var enumerator = this;
+ var promise = enumerator.promise;
+
+ if (promise._state === lib$es6$promise$$internal$$PENDING) {
+ enumerator._remaining--;
+
+ if (state === lib$es6$promise$$internal$$REJECTED) {
+ lib$es6$promise$$internal$$reject(promise, value);
+ } else {
+ enumerator._result[i] = value;
+ }
+ }
+
+ if (enumerator._remaining === 0) {
+ lib$es6$promise$$internal$$fulfill(promise, enumerator._result);
+ }
+ };
+
+ lib$es6$promise$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) {
+ var enumerator = this;
+
+ lib$es6$promise$$internal$$subscribe(promise, undefined, function(value) {
+ enumerator._settledAt(lib$es6$promise$$internal$$FULFILLED, i, value);
+ }, function(reason) {
+ enumerator._settledAt(lib$es6$promise$$internal$$REJECTED, i, reason);
+ });
+ };
+ function lib$es6$promise$promise$all$$all(entries) {
+ return new lib$es6$promise$enumerator$$default(this, entries).promise;
+ }
+ var lib$es6$promise$promise$all$$default = lib$es6$promise$promise$all$$all;
+ function lib$es6$promise$promise$race$$race(entries) {
+ /*jshint validthis:true */
+ var Constructor = this;
+
+ var promise = new Constructor(lib$es6$promise$$internal$$noop);
+
+ if (!lib$es6$promise$utils$$isArray(entries)) {
+ lib$es6$promise$$internal$$reject(promise, new TypeError('You must pass an array to race.'));
+ return promise;
+ }
+
+ var length = entries.length;
+
+ function onFulfillment(value) {
+ lib$es6$promise$$internal$$resolve(promise, value);
+ }
+
+ function onRejection(reason) {
+ lib$es6$promise$$internal$$reject(promise, reason);
+ }
+
+ for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {
+ lib$es6$promise$$internal$$subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);
+ }
+
+ return promise;
+ }
+ var lib$es6$promise$promise$race$$default = lib$es6$promise$promise$race$$race;
+ function lib$es6$promise$promise$resolve$$resolve(object) {
+ /*jshint validthis:true */
+ var Constructor = this;
+
+ if (object && typeof object === 'object' && object.constructor === Constructor) {
+ return object;
+ }
+
+ var promise = new Constructor(lib$es6$promise$$internal$$noop);
+ lib$es6$promise$$internal$$resolve(promise, object);
+ return promise;
+ }
+ var lib$es6$promise$promise$resolve$$default = lib$es6$promise$promise$resolve$$resolve;
+ function lib$es6$promise$promise$reject$$reject(reason) {
+ /*jshint validthis:true */
+ var Constructor = this;
+ var promise = new Constructor(lib$es6$promise$$internal$$noop);
+ lib$es6$promise$$internal$$reject(promise, reason);
+ return promise;
+ }
+ var lib$es6$promise$promise$reject$$default = lib$es6$promise$promise$reject$$reject;
+
+ var lib$es6$promise$promise$$counter = 0;
+
+ function lib$es6$promise$promise$$needsResolver() {
+ throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
+ }
+
+ function lib$es6$promise$promise$$needsNew() {
+ throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
+ }
+
+ var lib$es6$promise$promise$$default = lib$es6$promise$promise$$Promise;
+ /**
+ Promise objects represent the eventual result of an asynchronous operation. The
+ primary way of interacting with a promise is through its `then` method, which
+ registers callbacks to receive either a promise's eventual value or the reason
+ why the promise cannot be fulfilled.
+
+ Terminology
+ -----------
+
+ - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
+ - `thenable` is an object or function that defines a `then` method.
+ - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
+ - `exception` is a value that is thrown using the throw statement.
+ - `reason` is a value that indicates why a promise was rejected.
+ - `settled` the final resting state of a promise, fulfilled or rejected.
+
+ A promise can be in one of three states: pending, fulfilled, or rejected.
+
+ Promises that are fulfilled have a fulfillment value and are in the fulfilled
+ state. Promises that are rejected have a rejection reason and are in the
+ rejected state. A fulfillment value is never a thenable.
+
+ Promises can also be said to *resolve* a value. If this value is also a
+ promise, then the original promise's settled state will match the value's
+ settled state. So a promise that *resolves* a promise that rejects will
+ itself reject, and a promise that *resolves* a promise that fulfills will
+ itself fulfill.
+
+
+ Basic Usage:
+ ------------
+
+ ```js
+ var promise = new Promise(function(resolve, reject) {
+ // on success
+ resolve(value);
+
+ // on failure
+ reject(reason);
+ });
+
+ promise.then(function(value) {
+ // on fulfillment
+ }, function(reason) {
+ // on rejection
+ });
+ ```
+
+ Advanced Usage:
+ ---------------
+
+ Promises shine when abstracting away asynchronous interactions such as
+ `XMLHttpRequest`s.
+
+ ```js
+ function getJSON(url) {
+ return new Promise(function(resolve, reject){
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', url);
+ xhr.onreadystatechange = handler;
+ xhr.responseType = 'json';
+ xhr.setRequestHeader('Accept', 'application/json');
+ xhr.send();
+
+ function handler() {
+ if (this.readyState === this.DONE) {
+ if (this.status === 200) {
+ resolve(this.response);
+ } else {
+ reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
+ }
+ }
+ };
+ });
+ }
+
+ getJSON('/posts.json').then(function(json) {
+ // on fulfillment
+ }, function(reason) {
+ // on rejection
+ });
+ ```
+
+ Unlike callbacks, promises are great composable primitives.
+
+ ```js
+ Promise.all([
+ getJSON('/posts'),
+ getJSON('/comments')
+ ]).then(function(values){
+ values[0] // => postsJSON
+ values[1] // => commentsJSON
+
+ return values;
+ });
+ ```
+
+ @class Promise
+ @param {function} resolver
+ Useful for tooling.
+ @constructor
+ */
+ function lib$es6$promise$promise$$Promise(resolver) {
+ this._id = lib$es6$promise$promise$$counter++;
+ this._state = undefined;
+ this._result = undefined;
+ this._subscribers = [];
+
+ if (lib$es6$promise$$internal$$noop !== resolver) {
+ if (!lib$es6$promise$utils$$isFunction(resolver)) {
+ lib$es6$promise$promise$$needsResolver();
+ }
+
+ if (!(this instanceof lib$es6$promise$promise$$Promise)) {
+ lib$es6$promise$promise$$needsNew();
+ }
+
+ lib$es6$promise$$internal$$initializePromise(this, resolver);
+ }
+ }
+
+ lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default;
+ lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default;
+ lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default;
+ lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default;
+ lib$es6$promise$promise$$Promise._setScheduler = lib$es6$promise$asap$$setScheduler;
+ lib$es6$promise$promise$$Promise._setAsap = lib$es6$promise$asap$$setAsap;
+ lib$es6$promise$promise$$Promise._asap = lib$es6$promise$asap$$asap;
+
+ lib$es6$promise$promise$$Promise.prototype = {
+ constructor: lib$es6$promise$promise$$Promise,
+
+ /**
+ The primary way of interacting with a promise is through its `then` method,
+ which registers callbacks to receive either a promise's eventual value or the
+ reason why the promise cannot be fulfilled.
+
+ ```js
+ findUser().then(function(user){
+ // user is available
+ }, function(reason){
+ // user is unavailable, and you are given the reason why
+ });
+ ```
+
+ Chaining
+ --------
+
+ The return value of `then` is itself a promise. This second, 'downstream'
+ promise is resolved with the return value of the first promise's fulfillment
+ or rejection handler, or rejected if the handler throws an exception.
+
+ ```js
+ findUser().then(function (user) {
+ return user.name;
+ }, function (reason) {
+ return 'default name';
+ }).then(function (userName) {
+ // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
+ // will be `'default name'`
+ });
+
+ findUser().then(function (user) {
+ throw new Error('Found user, but still unhappy');
+ }, function (reason) {
+ throw new Error('`findUser` rejected and we're unhappy');
+ }).then(function (value) {
+ // never reached
+ }, function (reason) {
+ // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
+ // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
+ });
+ ```
+ If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
+
+ ```js
+ findUser().then(function (user) {
+ throw new PedagogicalException('Upstream error');
+ }).then(function (value) {
+ // never reached
+ }).then(function (value) {
+ // never reached
+ }, function (reason) {
+ // The `PedgagocialException` is propagated all the way down to here
+ });
+ ```
+
+ Assimilation
+ ------------
+
+ Sometimes the value you want to propagate to a downstream promise can only be
+ retrieved asynchronously. This can be achieved by returning a promise in the
+ fulfillment or rejection handler. The downstream promise will then be pending
+ until the returned promise is settled. This is called *assimilation*.
+
+ ```js
+ findUser().then(function (user) {
+ return findCommentsByAuthor(user);
+ }).then(function (comments) {
+ // The user's comments are now available
+ });
+ ```
+
+ If the assimliated promise rejects, then the downstream promise will also reject.
+
+ ```js
+ findUser().then(function (user) {
+ return findCommentsByAuthor(user);
+ }).then(function (comments) {
+ // If `findCommentsByAuthor` fulfills, we'll have the value here
+ }, function (reason) {
+ // If `findCommentsByAuthor` rejects, we'll have the reason here
+ });
+ ```
+
+ Simple Example
+ --------------
+
+ Synchronous Example
+
+ ```javascript
+ var result;
+
+ try {
+ result = findResult();
+ // success
+ } catch(reason) {
+ // failure
+ }
+ ```
+
+ Errback Example
+
+ ```js
+ findResult(function(result, err){
+ if (err) {
+ // failure
+ } else {
+ // success
+ }
+ });
+ ```
+
+ Promise Example;
+
+ ```javascript
+ findResult().then(function(result){
+ // success
+ }, function(reason){
+ // failure
+ });
+ ```
+
+ Advanced Example
+ --------------
+
+ Synchronous Example
+
+ ```javascript
+ var author, books;
+
+ try {
+ author = findAuthor();
+ books = findBooksByAuthor(author);
+ // success
+ } catch(reason) {
+ // failure
+ }
+ ```
+
+ Errback Example
+
+ ```js
+
+ function foundBooks(books) {
+
+ }
+
+ function failure(reason) {
+
+ }
+
+ findAuthor(function(author, err){
+ if (err) {
+ failure(err);
+ // failure
+ } else {
+ try {
+ findBoooksByAuthor(author, function(books, err) {
+ if (err) {
+ failure(err);
+ } else {
+ try {
+ foundBooks(books);
+ } catch(reason) {
+ failure(reason);
+ }
+ }
+ });
+ } catch(error) {
+ failure(err);
+ }
+ // success
+ }
+ });
+ ```
+
+ Promise Example;
+
+ ```javascript
+ findAuthor().
+ then(findBooksByAuthor).
+ then(function(books){
+ // found books
+ }).catch(function(reason){
+ // something went wrong
+ });
+ ```
+
+ @method then
+ @param {Function} onFulfilled
+ @param {Function} onRejected
+ Useful for tooling.
+ @return {Promise}
+ */
+ then: function(onFulfillment, onRejection) {
+ var parent = this;
+ var state = parent._state;
+
+ if (state === lib$es6$promise$$internal$$FULFILLED && !onFulfillment || state === lib$es6$promise$$internal$$REJECTED && !onRejection) {
+ return this;
+ }
+
+ var child = new this.constructor(lib$es6$promise$$internal$$noop);
+ var result = parent._result;
+
+ if (state) {
+ var callback = arguments[state - 1];
+ lib$es6$promise$asap$$asap(function(){
+ lib$es6$promise$$internal$$invokeCallback(state, child, callback, result);
+ });
+ } else {
+ lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection);
+ }
+
+ return child;
+ },
+
+ /**
+ `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
+ as the catch block of a try/catch statement.
+
+ ```js
+ function findAuthor(){
+ throw new Error('couldn't find that author');
+ }
+
+ // synchronous
+ try {
+ findAuthor();
+ } catch(reason) {
+ // something went wrong
+ }
+
+ // async with promises
+ findAuthor().catch(function(reason){
+ // something went wrong
+ });
+ ```
+
+ @method catch
+ @param {Function} onRejection
+ Useful for tooling.
+ @return {Promise}
+ */
+ 'catch': function(onRejection) {
+ return this.then(null, onRejection);
+ }
+ };
+ function lib$es6$promise$polyfill$$polyfill() {
+ var local;
+
+ if (typeof global !== 'undefined') {
+ local = global;
+ } else if (typeof self !== 'undefined') {
+ local = self;
+ } else {
+ try {
+ local = Function('return this')();
+ } catch (e) {
+ throw new Error('polyfill failed because global object is unavailable in this environment');
+ }
+ }
+
+ var P = local.Promise;
+
+ if (P && Object.prototype.toString.call(P.resolve()) === '[object Promise]' && !P.cast) {
+ return;
+ }
+
+ local.Promise = lib$es6$promise$promise$$default;
+ }
+ var lib$es6$promise$polyfill$$default = lib$es6$promise$polyfill$$polyfill;
+
+ var lib$es6$promise$umd$$ES6Promise = {
+ 'Promise': lib$es6$promise$promise$$default,
+ 'polyfill': lib$es6$promise$polyfill$$default
+ };
+
+ /* global define:true module:true window: true */
+ if (typeof define === 'function' && define['amd']) {
+ define(function() { return lib$es6$promise$umd$$ES6Promise; });
+ } else if (typeof module !== 'undefined' && module['exports']) {
+ module['exports'] = lib$es6$promise$umd$$ES6Promise;
+ } else if (typeof this !== 'undefined') {
+ this['ES6Promise'] = lib$es6$promise$umd$$ES6Promise;
+ }
+
+ lib$es6$promise$polyfill$$default();
+}).call(this);
+
+
+}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{"_process":21}],61:[function(require,module,exports){
+/*
+Copyright (C) 2015 Fred K. Schott <fkschott@gmail.com>
+Copyright (C) 2013 Ariya Hidayat <ariya.hidayat@gmail.com>
+Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com>
+Copyright (C) 2013 Mathias Bynens <mathias@qiwi.be>
+Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
+Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>
+Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
+Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>
+Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
+Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>
+Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*eslint no-undefined:0, no-use-before-define: 0*/
+
+"use strict";
+
+var syntax = require("./lib/syntax"),
+ tokenInfo = require("./lib/token-info"),
+ astNodeTypes = require("./lib/ast-node-types"),
+ astNodeFactory = require("./lib/ast-node-factory"),
+ defaultFeatures = require("./lib/features"),
+ Messages = require("./lib/messages"),
+ XHTMLEntities = require("./lib/xhtml-entities"),
+ StringMap = require("./lib/string-map"),
+ commentAttachment = require("./lib/comment-attachment");
+
+var Token = tokenInfo.Token,
+ TokenName = tokenInfo.TokenName,
+ FnExprTokens = tokenInfo.FnExprTokens,
+ Regex = syntax.Regex,
+ PropertyKind,
+ source,
+ strict,
+ index,
+ lineNumber,
+ lineStart,
+ length,
+ lookahead,
+ state,
+ extra;
+
+PropertyKind = {
+ Data: 1,
+ Get: 2,
+ Set: 4
+};
+
+
+// Ensure the condition is true, otherwise throw an error.
+// This is only to have a better contract semantic, i.e. another safety net
+// to catch a logic error. The condition shall be fulfilled in normal case.
+// Do NOT use this to enforce a certain condition on any user input.
+
+function assert(condition, message) {
+ /* istanbul ignore if */
+ if (!condition) {
+ throw new Error("ASSERT: " + message);
+ }
+}
+
+// 7.4 Comments
+
+function addComment(type, value, start, end, loc) {
+ var comment;
+
+ assert(typeof start === "number", "Comment must have valid position");
+
+ // Because the way the actual token is scanned, often the comments
+ // (if any) are skipped twice during the lexical analysis.
+ // Thus, we need to skip adding a comment if the comment array already
+ // handled it.
+ if (state.lastCommentStart >= start) {
+ return;
+ }
+ state.lastCommentStart = start;
+
+ comment = {
+ type: type,
+ value: value
+ };
+ if (extra.range) {
+ comment.range = [start, end];
+ }
+ if (extra.loc) {
+ comment.loc = loc;
+ }
+ extra.comments.push(comment);
+
+ if (extra.attachComment) {
+ commentAttachment.addComment(comment);
+ }
+}
+
+function skipSingleLineComment(offset) {
+ var start, loc, ch, comment;
+
+ start = index - offset;
+ loc = {
+ start: {
+ line: lineNumber,
+ column: index - lineStart - offset
+ }
+ };
+
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ ++index;
+ if (syntax.isLineTerminator(ch)) {
+ if (extra.comments) {
+ comment = source.slice(start + offset, index - 1);
+ loc.end = {
+ line: lineNumber,
+ column: index - lineStart - 1
+ };
+ addComment("Line", comment, start, index - 1, loc);
+ }
+ if (ch === 13 && source.charCodeAt(index) === 10) {
+ ++index;
+ }
+ ++lineNumber;
+ lineStart = index;
+ return;
+ }
+ }
+
+ if (extra.comments) {
+ comment = source.slice(start + offset, index);
+ loc.end = {
+ line: lineNumber,
+ column: index - lineStart
+ };
+ addComment("Line", comment, start, index, loc);
+ }
+}
+
+function skipMultiLineComment() {
+ var start, loc, ch, comment;
+
+ if (extra.comments) {
+ start = index - 2;
+ loc = {
+ start: {
+ line: lineNumber,
+ column: index - lineStart - 2
+ }
+ };
+ }
+
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (syntax.isLineTerminator(ch)) {
+ if (ch === 0x0D && source.charCodeAt(index + 1) === 0x0A) {
+ ++index;
+ }
+ ++lineNumber;
+ ++index;
+ lineStart = index;
+ if (index >= length) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+ } else if (ch === 0x2A) {
+ // Block comment ends with "*/".
+ if (source.charCodeAt(index + 1) === 0x2F) {
+ ++index;
+ ++index;
+ if (extra.comments) {
+ comment = source.slice(start + 2, index - 2);
+ loc.end = {
+ line: lineNumber,
+ column: index - lineStart
+ };
+ addComment("Block", comment, start, index, loc);
+ }
+ return;
+ }
+ ++index;
+ } else {
+ ++index;
+ }
+ }
+
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+}
+
+function skipComment() {
+ var ch, start;
+
+ start = (index === 0);
+ while (index < length) {
+ ch = source.charCodeAt(index);
+
+ if (syntax.isWhiteSpace(ch)) {
+ ++index;
+ } else if (syntax.isLineTerminator(ch)) {
+ ++index;
+ if (ch === 0x0D && source.charCodeAt(index) === 0x0A) {
+ ++index;
+ }
+ ++lineNumber;
+ lineStart = index;
+ start = true;
+ } else if (ch === 0x2F) { // U+002F is "/"
+ ch = source.charCodeAt(index + 1);
+ if (ch === 0x2F) {
+ ++index;
+ ++index;
+ skipSingleLineComment(2);
+ start = true;
+ } else if (ch === 0x2A) { // U+002A is "*"
+ ++index;
+ ++index;
+ skipMultiLineComment();
+ } else {
+ break;
+ }
+ } else if (start && ch === 0x2D) { // U+002D is "-"
+ // U+003E is ">"
+ if ((source.charCodeAt(index + 1) === 0x2D) && (source.charCodeAt(index + 2) === 0x3E)) {
+ // "-->" is a single-line comment
+ index += 3;
+ skipSingleLineComment(3);
+ } else {
+ break;
+ }
+ } else if (ch === 0x3C) { // U+003C is "<"
+ if (source.slice(index + 1, index + 4) === "!--") {
+ ++index; // `<`
+ ++index; // `!`
+ ++index; // `-`
+ ++index; // `-`
+ skipSingleLineComment(4);
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+}
+
+function scanHexEscape(prefix) {
+ var i, len, ch, code = 0;
+
+ len = (prefix === "u") ? 4 : 2;
+ for (i = 0; i < len; ++i) {
+ if (index < length && syntax.isHexDigit(source[index])) {
+ ch = source[index++];
+ code = code * 16 + "0123456789abcdef".indexOf(ch.toLowerCase());
+ } else {
+ return "";
+ }
+ }
+ return String.fromCharCode(code);
+}
+
+/**
+ * Scans an extended unicode code point escape sequence from source. Throws an
+ * error if the sequence is empty or if the code point value is too large.
+ * @returns {string} The string created by the Unicode escape sequence.
+ * @private
+ */
+function scanUnicodeCodePointEscape() {
+ var ch, code, cu1, cu2;
+
+ ch = source[index];
+ code = 0;
+
+ // At least one hex digit is required.
+ if (ch === "}") {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+
+ while (index < length) {
+ ch = source[index++];
+ if (!syntax.isHexDigit(ch)) {
+ break;
+ }
+ code = code * 16 + "0123456789abcdef".indexOf(ch.toLowerCase());
+ }
+
+ if (code > 0x10FFFF || ch !== "}") {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+
+ // UTF-16 Encoding
+ if (code <= 0xFFFF) {
+ return String.fromCharCode(code);
+ }
+ cu1 = ((code - 0x10000) >> 10) + 0xD800;
+ cu2 = ((code - 0x10000) & 1023) + 0xDC00;
+ return String.fromCharCode(cu1, cu2);
+}
+
+function getEscapedIdentifier() {
+ var ch, id;
+
+ ch = source.charCodeAt(index++);
+ id = String.fromCharCode(ch);
+
+ // "\u" (U+005C, U+0075) denotes an escaped character.
+ if (ch === 0x5C) {
+ if (source.charCodeAt(index) !== 0x75) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+ ++index;
+ ch = scanHexEscape("u");
+ if (!ch || ch === "\\" || !syntax.isIdentifierStart(ch.charCodeAt(0))) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+ id = ch;
+ }
+
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (!syntax.isIdentifierPart(ch)) {
+ break;
+ }
+ ++index;
+ id += String.fromCharCode(ch);
+
+ // "\u" (U+005C, U+0075) denotes an escaped character.
+ if (ch === 0x5C) {
+ id = id.substr(0, id.length - 1);
+ if (source.charCodeAt(index) !== 0x75) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+ ++index;
+ ch = scanHexEscape("u");
+ if (!ch || ch === "\\" || !syntax.isIdentifierPart(ch.charCodeAt(0))) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+ id += ch;
+ }
+ }
+
+ return id;
+}
+
+function getIdentifier() {
+ var start, ch;
+
+ start = index++;
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (ch === 0x5C) {
+ // Blackslash (U+005C) marks Unicode escape sequence.
+ index = start;
+ return getEscapedIdentifier();
+ }
+ if (syntax.isIdentifierPart(ch)) {
+ ++index;
+ } else {
+ break;
+ }
+ }
+
+ return source.slice(start, index);
+}
+
+function scanIdentifier() {
+ var start, id, type;
+
+ start = index;
+
+ // Backslash (U+005C) starts an escaped character.
+ id = (source.charCodeAt(index) === 0x5C) ? getEscapedIdentifier() : getIdentifier();
+
+ // There is no keyword or literal with only one character.
+ // Thus, it must be an identifier.
+ if (id.length === 1) {
+ type = Token.Identifier;
+ } else if (syntax.isKeyword(id, strict, extra.ecmaFeatures)) {
+ type = Token.Keyword;
+ } else if (id === "null") {
+ type = Token.NullLiteral;
+ } else if (id === "true" || id === "false") {
+ type = Token.BooleanLiteral;
+ } else {
+ type = Token.Identifier;
+ }
+
+ return {
+ type: type,
+ value: id,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+}
+
+
+// 7.7 Punctuators
+
+function scanPunctuator() {
+ var start = index,
+ code = source.charCodeAt(index),
+ code2,
+ ch1 = source[index],
+ ch2,
+ ch3,
+ ch4;
+
+ switch (code) {
+ // Check for most common single-character punctuators.
+ case 40: // ( open bracket
+ case 41: // ) close bracket
+ case 59: // ; semicolon
+ case 44: // , comma
+ case 91: // [
+ case 93: // ]
+ case 58: // :
+ case 63: // ?
+ case 126: // ~
+ ++index;
+
+ if (extra.tokenize && code === 40) {
+ extra.openParenToken = extra.tokens.length;
+ }
+
+ return {
+ type: Token.Punctuator,
+ value: String.fromCharCode(code),
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+
+ case 123: // { open curly brace
+ case 125: // } close curly brace
+ ++index;
+
+ if (extra.tokenize && code === 123) {
+ extra.openCurlyToken = extra.tokens.length;
+ }
+
+ // lookahead2 function can cause tokens to be scanned twice and in doing so
+ // would wreck the curly stack by pushing the same token onto the stack twice.
+ // curlyLastIndex ensures each token is pushed or popped exactly once
+ if (index > state.curlyLastIndex) {
+ state.curlyLastIndex = index;
+ if (code === 123) {
+ state.curlyStack.push("{");
+ } else {
+ state.curlyStack.pop();
+ }
+ }
+
+ return {
+ type: Token.Punctuator,
+ value: String.fromCharCode(code),
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+
+ default:
+ code2 = source.charCodeAt(index + 1);
+
+ // "=" (char #61) marks an assignment or comparison operator.
+ if (code2 === 61) {
+ switch (code) {
+ case 37: // %
+ case 38: // &
+ case 42: // *:
+ case 43: // +
+ case 45: // -
+ case 47: // /
+ case 60: // <
+ case 62: // >
+ case 94: // ^
+ case 124: // |
+ index += 2;
+ return {
+ type: Token.Punctuator,
+ value: String.fromCharCode(code) + String.fromCharCode(code2),
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+
+ case 33: // !
+ case 61: // =
+ index += 2;
+
+ // !== and ===
+ if (source.charCodeAt(index) === 61) {
+ ++index;
+ }
+ return {
+ type: Token.Punctuator,
+ value: source.slice(start, index),
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ default:
+ break;
+ }
+ }
+ break;
+ }
+
+ // Peek more characters.
+
+ ch2 = source[index + 1];
+ ch3 = source[index + 2];
+ ch4 = source[index + 3];
+
+ // 4-character punctuator: >>>=
+
+ if (ch1 === ">" && ch2 === ">" && ch3 === ">") {
+ if (ch4 === "=") {
+ index += 4;
+ return {
+ type: Token.Punctuator,
+ value: ">>>=",
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+ }
+
+ // 3-character punctuators: === !== >>> <<= >>=
+
+ if (ch1 === ">" && ch2 === ">" && ch3 === ">") {
+ index += 3;
+ return {
+ type: Token.Punctuator,
+ value: ">>>",
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ if (ch1 === "<" && ch2 === "<" && ch3 === "=") {
+ index += 3;
+ return {
+ type: Token.Punctuator,
+ value: "<<=",
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ if (ch1 === ">" && ch2 === ">" && ch3 === "=") {
+ index += 3;
+ return {
+ type: Token.Punctuator,
+ value: ">>=",
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ // The ... operator (spread, restParams, JSX, etc.)
+ if (extra.ecmaFeatures.spread ||
+ extra.ecmaFeatures.restParams ||
+ (extra.ecmaFeatures.jsx && state.inJSXSpreadAttribute)
+ ) {
+ if (ch1 === "." && ch2 === "." && ch3 === ".") {
+ index += 3;
+ return {
+ type: Token.Punctuator,
+ value: "...",
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+ }
+
+ // Other 2-character punctuators: ++ -- << >> && ||
+ if (ch1 === ch2 && ("+-<>&|".indexOf(ch1) >= 0)) {
+ index += 2;
+ return {
+ type: Token.Punctuator,
+ value: ch1 + ch2,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ // the => for arrow functions
+ if (extra.ecmaFeatures.arrowFunctions) {
+ if (ch1 === "=" && ch2 === ">") {
+ index += 2;
+ return {
+ type: Token.Punctuator,
+ value: "=>",
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+ }
+
+ if ("<>=!+-*%&|^/".indexOf(ch1) >= 0) {
+ ++index;
+ return {
+ type: Token.Punctuator,
+ value: ch1,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ if (ch1 === ".") {
+ ++index;
+ return {
+ type: Token.Punctuator,
+ value: ch1,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+}
+
+// 7.8.3 Numeric Literals
+
+function scanHexLiteral(start) {
+ var number = "";
+
+ while (index < length) {
+ if (!syntax.isHexDigit(source[index])) {
+ break;
+ }
+ number += source[index++];
+ }
+
+ if (number.length === 0) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+
+ if (syntax.isIdentifierStart(source.charCodeAt(index))) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+
+ return {
+ type: Token.NumericLiteral,
+ value: parseInt("0x" + number, 16),
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+}
+
+function scanBinaryLiteral(start) {
+ var ch, number = "";
+
+ while (index < length) {
+ ch = source[index];
+ if (ch !== "0" && ch !== "1") {
+ break;
+ }
+ number += source[index++];
+ }
+
+ if (number.length === 0) {
+ // only 0b or 0B
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+
+
+ if (index < length) {
+ ch = source.charCodeAt(index);
+ /* istanbul ignore else */
+ if (syntax.isIdentifierStart(ch) || syntax.isDecimalDigit(ch)) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+ }
+
+ return {
+ type: Token.NumericLiteral,
+ value: parseInt(number, 2),
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+}
+
+function scanOctalLiteral(prefix, start) {
+ var number, octal;
+
+ if (syntax.isOctalDigit(prefix)) {
+ octal = true;
+ number = "0" + source[index++];
+ } else {
+ octal = false;
+ ++index;
+ number = "";
+ }
+
+ while (index < length) {
+ if (!syntax.isOctalDigit(source[index])) {
+ break;
+ }
+ number += source[index++];
+ }
+
+ if (!octal && number.length === 0) {
+ // only 0o or 0O
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+
+ if (syntax.isIdentifierStart(source.charCodeAt(index)) || syntax.isDecimalDigit(source.charCodeAt(index))) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+
+ return {
+ type: Token.NumericLiteral,
+ value: parseInt(number, 8),
+ octal: octal,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+}
+
+function scanNumericLiteral() {
+ var number, start, ch;
+
+ ch = source[index];
+ assert(syntax.isDecimalDigit(ch.charCodeAt(0)) || (ch === "."),
+ "Numeric literal must start with a decimal digit or a decimal point");
+
+ start = index;
+ number = "";
+ if (ch !== ".") {
+ number = source[index++];
+ ch = source[index];
+
+ // Hex number starts with "0x".
+ // Octal number starts with "0".
+ if (number === "0") {
+ if (ch === "x" || ch === "X") {
+ ++index;
+ return scanHexLiteral(start);
+ }
+
+ // Binary number in ES6 starts with '0b'
+ if (extra.ecmaFeatures.binaryLiterals) {
+ if (ch === "b" || ch === "B") {
+ ++index;
+ return scanBinaryLiteral(start);
+ }
+ }
+
+ if ((extra.ecmaFeatures.octalLiterals && (ch === "o" || ch === "O")) || syntax.isOctalDigit(ch)) {
+ return scanOctalLiteral(ch, start);
+ }
+
+ // decimal number starts with "0" such as "09" is illegal.
+ if (ch && syntax.isDecimalDigit(ch.charCodeAt(0))) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+ }
+
+ while (syntax.isDecimalDigit(source.charCodeAt(index))) {
+ number += source[index++];
+ }
+ ch = source[index];
+ }
+
+ if (ch === ".") {
+ number += source[index++];
+ while (syntax.isDecimalDigit(source.charCodeAt(index))) {
+ number += source[index++];
+ }
+ ch = source[index];
+ }
+
+ if (ch === "e" || ch === "E") {
+ number += source[index++];
+
+ ch = source[index];
+ if (ch === "+" || ch === "-") {
+ number += source[index++];
+ }
+ if (syntax.isDecimalDigit(source.charCodeAt(index))) {
+ while (syntax.isDecimalDigit(source.charCodeAt(index))) {
+ number += source[index++];
+ }
+ } else {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+ }
+
+ if (syntax.isIdentifierStart(source.charCodeAt(index))) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+
+ return {
+ type: Token.NumericLiteral,
+ value: parseFloat(number),
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+}
+
+/**
+ * Scan a string escape sequence and return its special character.
+ * @param {string} ch The starting character of the given sequence.
+ * @returns {Object} An object containing the character and a flag
+ * if the escape sequence was an octal.
+ * @private
+ */
+function scanEscapeSequence(ch) {
+ var code,
+ unescaped,
+ restore,
+ escapedCh,
+ octal = false;
+
+ // An escape sequence cannot be empty
+ if (!ch) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+
+ if (syntax.isLineTerminator(ch.charCodeAt(0))) {
+ ++lineNumber;
+ if (ch === "\r" && source[index] === "\n") {
+ ++index;
+ }
+ lineStart = index;
+ escapedCh = "";
+ } else if (ch === "u" && source[index] === "{") {
+ // Handle ES6 extended unicode code point escape sequences.
+ if (extra.ecmaFeatures.unicodeCodePointEscapes) {
+ ++index;
+ escapedCh = scanUnicodeCodePointEscape();
+ } else {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+ } else if (ch === "u" || ch === "x") {
+ // Handle other unicode and hex codes normally
+ restore = index;
+ unescaped = scanHexEscape(ch);
+ if (unescaped) {
+ escapedCh = unescaped;
+ } else {
+ index = restore;
+ escapedCh = ch;
+ }
+ } else if (ch === "n") {
+ escapedCh = "\n";
+ } else if (ch === "r") {
+ escapedCh = "\r";
+ } else if (ch === "t") {
+ escapedCh = "\t";
+ } else if (ch === "b") {
+ escapedCh = "\b";
+ } else if (ch === "f") {
+ escapedCh = "\f";
+ } else if (ch === "v") {
+ escapedCh = "\v";
+ } else if (syntax.isOctalDigit(ch)) {
+ code = "01234567".indexOf(ch);
+
+ // \0 is not octal escape sequence
+ if (code !== 0) {
+ octal = true;
+ }
+
+ if (index < length && syntax.isOctalDigit(source[index])) {
+ octal = true;
+ code = code * 8 + "01234567".indexOf(source[index++]);
+
+ // 3 digits are only allowed when string starts with 0, 1, 2, 3
+ if ("0123".indexOf(ch) >= 0 &&
+ index < length &&
+ syntax.isOctalDigit(source[index])) {
+ code = code * 8 + "01234567".indexOf(source[index++]);
+ }
+ }
+ escapedCh = String.fromCharCode(code);
+ } else {
+ escapedCh = ch;
+ }
+
+ return {
+ ch: escapedCh,
+ octal: octal
+ };
+}
+
+function scanStringLiteral() {
+ var str = "",
+ ch,
+ escapedSequence,
+ octal = false,
+ start = index,
+ startLineNumber = lineNumber,
+ startLineStart = lineStart,
+ quote = source[index];
+
+ assert((quote === "'" || quote === "\""),
+ "String literal must starts with a quote");
+
+ ++index;
+
+ while (index < length) {
+ ch = source[index++];
+
+ if (syntax.isLineTerminator(ch.charCodeAt(0))) {
+ break;
+ } else if (ch === quote) {
+ quote = "";
+ break;
+ } else if (ch === "\\") {
+ ch = source[index++];
+ escapedSequence = scanEscapeSequence(ch);
+ str += escapedSequence.ch;
+ octal = escapedSequence.octal || octal;
+ } else {
+ str += ch;
+ }
+ }
+
+ if (quote !== "") {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+
+ return {
+ type: Token.StringLiteral,
+ value: str,
+ octal: octal,
+ startLineNumber: startLineNumber,
+ startLineStart: startLineStart,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+}
+
+/**
+ * Scan a template string and return a token. This scans both the first and
+ * subsequent pieces of a template string and assumes that the first backtick
+ * or the closing } have already been scanned.
+ * @returns {Token} The template string token.
+ * @private
+ */
+function scanTemplate() {
+ var cooked = "",
+ ch,
+ escapedSequence,
+ start = index,
+ terminated = false,
+ tail = false,
+ head = (source[index] === "`");
+
+ ++index;
+
+ while (index < length) {
+ ch = source[index++];
+
+ if (ch === "`") {
+ tail = true;
+ terminated = true;
+ break;
+ } else if (ch === "$") {
+ if (source[index] === "{") {
+ ++index;
+ terminated = true;
+ break;
+ }
+ cooked += ch;
+ } else if (ch === "\\") {
+ ch = source[index++];
+ escapedSequence = scanEscapeSequence(ch);
+
+ if (escapedSequence.octal) {
+ throwError({}, Messages.TemplateOctalLiteral);
+ }
+
+ cooked += escapedSequence.ch;
+
+ } else if (syntax.isLineTerminator(ch.charCodeAt(0))) {
+ ++lineNumber;
+ if (ch === "\r" && source[index] === "\n") {
+ ++index;
+ }
+ lineStart = index;
+ cooked += "\n";
+ } else {
+ cooked += ch;
+ }
+ }
+
+ if (!terminated) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+
+ if (index > state.curlyLastIndex) {
+ state.curlyLastIndex = index;
+
+ if (!tail) {
+ state.curlyStack.push("template");
+ }
+
+ if (!head) {
+ state.curlyStack.pop();
+ }
+ }
+
+ return {
+ type: Token.Template,
+ value: {
+ cooked: cooked,
+ raw: source.slice(start + 1, index - ((tail) ? 1 : 2))
+ },
+ head: head,
+ tail: tail,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+}
+
+function testRegExp(pattern, flags) {
+ var tmp = pattern,
+ validFlags = "gmsi";
+
+ if (extra.ecmaFeatures.regexYFlag) {
+ validFlags += "y";
+ }
+
+ if (extra.ecmaFeatures.regexUFlag) {
+ validFlags += "u";
+ }
+
+ if (!RegExp("^[" + validFlags + "]*$").test(flags)) {
+ throwError({}, Messages.InvalidRegExpFlag);
+ }
+
+
+ if (flags.indexOf("u") >= 0) {
+ // Replace each astral symbol and every Unicode code point
+ // escape sequence with a single ASCII symbol to avoid throwing on
+ // regular expressions that are only valid in combination with the
+ // `/u` flag.
+ // Note: replacing with the ASCII symbol `x` might cause false
+ // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
+ // perfectly valid pattern that is equivalent to `[a-b]`, but it
+ // would be replaced by `[x-b]` which throws an error.
+ tmp = tmp
+ .replace(/\\u\{([0-9a-fA-F]+)\}/g, function ($0, $1) {
+ if (parseInt($1, 16) <= 0x10FFFF) {
+ return "x";
+ }
+ throwError({}, Messages.InvalidRegExp);
+ })
+ .replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x");
+ }
+
+ // First, detect invalid regular expressions.
+ try {
+ RegExp(tmp);
+ } catch (e) {
+ throwError({}, Messages.InvalidRegExp);
+ }
+
+ // Return a regular expression object for this pattern-flag pair, or
+ // `null` in case the current environment doesn't support the flags it
+ // uses.
+ try {
+ return new RegExp(pattern, flags);
+ } catch (exception) {
+ return null;
+ }
+}
+
+function scanRegExpBody() {
+ var ch, str, classMarker, terminated, body;
+
+ ch = source[index];
+ assert(ch === "/", "Regular expression literal must start with a slash");
+ str = source[index++];
+
+ classMarker = false;
+ terminated = false;
+ while (index < length) {
+ ch = source[index++];
+ str += ch;
+ if (ch === "\\") {
+ ch = source[index++];
+ // ECMA-262 7.8.5
+ if (syntax.isLineTerminator(ch.charCodeAt(0))) {
+ throwError({}, Messages.UnterminatedRegExp);
+ }
+ str += ch;
+ } else if (syntax.isLineTerminator(ch.charCodeAt(0))) {
+ throwError({}, Messages.UnterminatedRegExp);
+ } else if (classMarker) {
+ if (ch === "]") {
+ classMarker = false;
+ }
+ } else {
+ if (ch === "/") {
+ terminated = true;
+ break;
+ } else if (ch === "[") {
+ classMarker = true;
+ }
+ }
+ }
+
+ if (!terminated) {
+ throwError({}, Messages.UnterminatedRegExp);
+ }
+
+ // Exclude leading and trailing slash.
+ body = str.substr(1, str.length - 2);
+ return {
+ value: body,
+ literal: str
+ };
+}
+
+function scanRegExpFlags() {
+ var ch, str, flags, restore;
+
+ str = "";
+ flags = "";
+ while (index < length) {
+ ch = source[index];
+ if (!syntax.isIdentifierPart(ch.charCodeAt(0))) {
+ break;
+ }
+
+ ++index;
+ if (ch === "\\" && index < length) {
+ ch = source[index];
+ if (ch === "u") {
+ ++index;
+ restore = index;
+ ch = scanHexEscape("u");
+ if (ch) {
+ flags += ch;
+ for (str += "\\u"; restore < index; ++restore) {
+ str += source[restore];
+ }
+ } else {
+ index = restore;
+ flags += "u";
+ str += "\\u";
+ }
+ throwErrorTolerant({}, Messages.UnexpectedToken, "ILLEGAL");
+ } else {
+ str += "\\";
+ throwErrorTolerant({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+ } else {
+ flags += ch;
+ str += ch;
+ }
+ }
+
+ return {
+ value: flags,
+ literal: str
+ };
+}
+
+function scanRegExp() {
+ var start, body, flags, value;
+
+ lookahead = null;
+ skipComment();
+ start = index;
+
+ body = scanRegExpBody();
+ flags = scanRegExpFlags();
+ value = testRegExp(body.value, flags.value);
+
+ if (extra.tokenize) {
+ return {
+ type: Token.RegularExpression,
+ value: value,
+ regex: {
+ pattern: body.value,
+ flags: flags.value
+ },
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+ }
+
+ return {
+ literal: body.literal + flags.literal,
+ value: value,
+ regex: {
+ pattern: body.value,
+ flags: flags.value
+ },
+ range: [start, index]
+ };
+}
+
+function collectRegex() {
+ var pos, loc, regex, token;
+
+ skipComment();
+
+ pos = index;
+ loc = {
+ start: {
+ line: lineNumber,
+ column: index - lineStart
+ }
+ };
+
+ regex = scanRegExp();
+ loc.end = {
+ line: lineNumber,
+ column: index - lineStart
+ };
+
+ /* istanbul ignore next */
+ if (!extra.tokenize) {
+ // Pop the previous token, which is likely "/" or "/="
+ if (extra.tokens.length > 0) {
+ token = extra.tokens[extra.tokens.length - 1];
+ if (token.range[0] === pos && token.type === "Punctuator") {
+ if (token.value === "/" || token.value === "/=") {
+ extra.tokens.pop();
+ }
+ }
+ }
+
+ extra.tokens.push({
+ type: "RegularExpression",
+ value: regex.literal,
+ regex: regex.regex,
+ range: [pos, index],
+ loc: loc
+ });
+ }
+
+ return regex;
+}
+
+function isIdentifierName(token) {
+ return token.type === Token.Identifier ||
+ token.type === Token.Keyword ||
+ token.type === Token.BooleanLiteral ||
+ token.type === Token.NullLiteral;
+}
+
+function advanceSlash() {
+ var prevToken,
+ checkToken;
+ // Using the following algorithm:
+ // https://github.com/mozilla/sweet.js/wiki/design
+ prevToken = extra.tokens[extra.tokens.length - 1];
+ if (!prevToken) {
+ // Nothing before that: it cannot be a division.
+ return collectRegex();
+ }
+ if (prevToken.type === "Punctuator") {
+ if (prevToken.value === "]") {
+ return scanPunctuator();
+ }
+ if (prevToken.value === ")") {
+ checkToken = extra.tokens[extra.openParenToken - 1];
+ if (checkToken &&
+ checkToken.type === "Keyword" &&
+ (checkToken.value === "if" ||
+ checkToken.value === "while" ||
+ checkToken.value === "for" ||
+ checkToken.value === "with")) {
+ return collectRegex();
+ }
+ return scanPunctuator();
+ }
+ if (prevToken.value === "}") {
+ // Dividing a function by anything makes little sense,
+ // but we have to check for that.
+ if (extra.tokens[extra.openCurlyToken - 3] &&
+ extra.tokens[extra.openCurlyToken - 3].type === "Keyword") {
+ // Anonymous function.
+ checkToken = extra.tokens[extra.openCurlyToken - 4];
+ if (!checkToken) {
+ return scanPunctuator();
+ }
+ } else if (extra.tokens[extra.openCurlyToken - 4] &&
+ extra.tokens[extra.openCurlyToken - 4].type === "Keyword") {
+ // Named function.
+ checkToken = extra.tokens[extra.openCurlyToken - 5];
+ if (!checkToken) {
+ return collectRegex();
+ }
+ } else {
+ return scanPunctuator();
+ }
+ // checkToken determines whether the function is
+ // a declaration or an expression.
+ if (FnExprTokens.indexOf(checkToken.value) >= 0) {
+ // It is an expression.
+ return scanPunctuator();
+ }
+ // It is a declaration.
+ return collectRegex();
+ }
+ return collectRegex();
+ }
+ if (prevToken.type === "Keyword") {
+ return collectRegex();
+ }
+ return scanPunctuator();
+}
+
+function advance() {
+ var ch,
+ allowJSX = extra.ecmaFeatures.jsx,
+ allowTemplateStrings = extra.ecmaFeatures.templateStrings;
+
+ /*
+ * If JSX isn't allowed or JSX is allowed and we're not inside an JSX child,
+ * then skip any comments.
+ */
+ if (!allowJSX || !state.inJSXChild) {
+ skipComment();
+ }
+
+ if (index >= length) {
+ return {
+ type: Token.EOF,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [index, index]
+ };
+ }
+
+ // if inside an JSX child, then abort regular tokenization
+ if (allowJSX && state.inJSXChild) {
+ return advanceJSXChild();
+ }
+
+ ch = source.charCodeAt(index);
+
+ // Very common: ( and ) and ;
+ if (ch === 0x28 || ch === 0x29 || ch === 0x3B) {
+ return scanPunctuator();
+ }
+
+ // String literal starts with single quote (U+0027) or double quote (U+0022).
+ if (ch === 0x27 || ch === 0x22) {
+ if (allowJSX && state.inJSXTag) {
+ return scanJSXStringLiteral();
+ }
+
+ return scanStringLiteral();
+ }
+
+ if (allowJSX && state.inJSXTag && syntax.isJSXIdentifierStart(ch)) {
+ return scanJSXIdentifier();
+ }
+
+ // Template strings start with backtick (U+0096) or closing curly brace (125) and backtick.
+ if (allowTemplateStrings) {
+
+ // template strings start with backtick (96) or open curly (125) but only if the open
+ // curly closes a previously opened curly from a template.
+ if (ch === 96 || (ch === 125 && state.curlyStack[state.curlyStack.length - 1] === "template")) {
+ return scanTemplate();
+ }
+ }
+
+ if (syntax.isIdentifierStart(ch)) {
+ return scanIdentifier();
+ }
+
+ // Dot (.) U+002E can also start a floating-point number, hence the need
+ // to check the next character.
+ if (ch === 0x2E) {
+ if (syntax.isDecimalDigit(source.charCodeAt(index + 1))) {
+ return scanNumericLiteral();
+ }
+ return scanPunctuator();
+ }
+
+ if (syntax.isDecimalDigit(ch)) {
+ return scanNumericLiteral();
+ }
+
+ // Slash (/) U+002F can also start a regex.
+ if (extra.tokenize && ch === 0x2F) {
+ return advanceSlash();
+ }
+
+ return scanPunctuator();
+}
+
+function collectToken() {
+ var loc, token, range, value, entry,
+ allowJSX = extra.ecmaFeatures.jsx;
+
+ /* istanbul ignore else */
+ if (!allowJSX || !state.inJSXChild) {
+ skipComment();
+ }
+
+ loc = {
+ start: {
+ line: lineNumber,
+ column: index - lineStart
+ }
+ };
+
+ token = advance();
+ loc.end = {
+ line: lineNumber,
+ column: index - lineStart
+ };
+
+ if (token.type !== Token.EOF) {
+ range = [token.range[0], token.range[1]];
+ value = source.slice(token.range[0], token.range[1]);
+ entry = {
+ type: TokenName[token.type],
+ value: value,
+ range: range,
+ loc: loc
+ };
+ if (token.regex) {
+ entry.regex = {
+ pattern: token.regex.pattern,
+ flags: token.regex.flags
+ };
+ }
+ extra.tokens.push(entry);
+ }
+
+ return token;
+}
+
+function lex() {
+ var token;
+
+ token = lookahead;
+ index = token.range[1];
+ lineNumber = token.lineNumber;
+ lineStart = token.lineStart;
+
+ lookahead = (typeof extra.tokens !== "undefined") ? collectToken() : advance();
+
+ index = token.range[1];
+ lineNumber = token.lineNumber;
+ lineStart = token.lineStart;
+
+ return token;
+}
+
+function peek() {
+ var pos,
+ line,
+ start;
+
+ pos = index;
+ line = lineNumber;
+ start = lineStart;
+
+ lookahead = (typeof extra.tokens !== "undefined") ? collectToken() : advance();
+
+ index = pos;
+ lineNumber = line;
+ lineStart = start;
+}
+
+function lookahead2() {
+ var adv, pos, line, start, result;
+
+ // If we are collecting the tokens, don't grab the next one yet.
+ /* istanbul ignore next */
+ adv = (typeof extra.advance === "function") ? extra.advance : advance;
+
+ pos = index;
+ line = lineNumber;
+ start = lineStart;
+
+ // Scan for the next immediate token.
+ /* istanbul ignore if */
+ if (lookahead === null) {
+ lookahead = adv();
+ }
+ index = lookahead.range[1];
+ lineNumber = lookahead.lineNumber;
+ lineStart = lookahead.lineStart;
+
+ // Grab the token right after.
+ result = adv();
+ index = pos;
+ lineNumber = line;
+ lineStart = start;
+
+ return result;
+}
+
+
+//------------------------------------------------------------------------------
+// JSX
+//------------------------------------------------------------------------------
+
+function getQualifiedJSXName(object) {
+ if (object.type === astNodeTypes.JSXIdentifier) {
+ return object.name;
+ }
+ if (object.type === astNodeTypes.JSXNamespacedName) {
+ return object.namespace.name + ":" + object.name.name;
+ }
+ /* istanbul ignore else */
+ if (object.type === astNodeTypes.JSXMemberExpression) {
+ return (
+ getQualifiedJSXName(object.object) + "." +
+ getQualifiedJSXName(object.property)
+ );
+ }
+ /* istanbul ignore next */
+ throwUnexpected(object);
+}
+
+function scanJSXIdentifier() {
+ var ch, start, value = "";
+
+ start = index;
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (!syntax.isJSXIdentifierPart(ch)) {
+ break;
+ }
+ value += source[index++];
+ }
+
+ return {
+ type: Token.JSXIdentifier,
+ value: value,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+}
+
+function scanJSXEntity() {
+ var ch, str = "", start = index, count = 0, code;
+ ch = source[index];
+ assert(ch === "&", "Entity must start with an ampersand");
+ index++;
+ while (index < length && count++ < 10) {
+ ch = source[index++];
+ if (ch === ";") {
+ break;
+ }
+ str += ch;
+ }
+
+ // Well-formed entity (ending was found).
+ if (ch === ";") {
+ // Numeric entity.
+ if (str[0] === "#") {
+ if (str[1] === "x") {
+ code = +("0" + str.substr(1));
+ } else {
+ // Removing leading zeros in order to avoid treating as octal in old browsers.
+ code = +str.substr(1).replace(Regex.LeadingZeros, "");
+ }
+
+ if (!isNaN(code)) {
+ return String.fromCharCode(code);
+ }
+ /* istanbul ignore else */
+ } else if (XHTMLEntities[str]) {
+ return XHTMLEntities[str];
+ }
+ }
+
+ // Treat non-entity sequences as regular text.
+ index = start + 1;
+ return "&";
+}
+
+function scanJSXText(stopChars) {
+ var ch, str = "", start;
+ start = index;
+ while (index < length) {
+ ch = source[index];
+ if (stopChars.indexOf(ch) !== -1) {
+ break;
+ }
+ if (ch === "&") {
+ str += scanJSXEntity();
+ } else {
+ index++;
+ if (ch === "\r" && source[index] === "\n") {
+ str += ch;
+ ch = source[index];
+ index++;
+ }
+ if (syntax.isLineTerminator(ch.charCodeAt(0))) {
+ ++lineNumber;
+ lineStart = index;
+ }
+ str += ch;
+ }
+ }
+ return {
+ type: Token.JSXText,
+ value: str,
+ lineNumber: lineNumber,
+ lineStart: lineStart,
+ range: [start, index]
+ };
+}
+
+function scanJSXStringLiteral() {
+ var innerToken, quote, start;
+
+ quote = source[index];
+ assert((quote === "\"" || quote === "'"),
+ "String literal must starts with a quote");
+
+ start = index;
+ ++index;
+
+ innerToken = scanJSXText([quote]);
+
+ if (quote !== source[index]) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+
+ ++index;
+
+ innerToken.range = [start, index];
+
+ return innerToken;
+}
+
+/*
+ * Between JSX opening and closing tags (e.g. <foo>HERE</foo>), anything that
+ * is not another JSX tag and is not an expression wrapped by {} is text.
+ */
+function advanceJSXChild() {
+ var ch = source.charCodeAt(index);
+
+ // { (123) and < (60)
+ if (ch !== 123 && ch !== 60) {
+ return scanJSXText(["<", "{"]);
+ }
+
+ return scanPunctuator();
+}
+
+function parseJSXIdentifier() {
+ var token, marker = markerCreate();
+
+ if (lookahead.type !== Token.JSXIdentifier) {
+ throwUnexpected(lookahead);
+ }
+
+ token = lex();
+ return markerApply(marker, astNodeFactory.createJSXIdentifier(token.value));
+}
+
+function parseJSXNamespacedName() {
+ var namespace, name, marker = markerCreate();
+
+ namespace = parseJSXIdentifier();
+ expect(":");
+ name = parseJSXIdentifier();
+
+ return markerApply(marker, astNodeFactory.createJSXNamespacedName(namespace, name));
+}
+
+function parseJSXMemberExpression() {
+ var marker = markerCreate(),
+ expr = parseJSXIdentifier();
+
+ while (match(".")) {
+ lex();
+ expr = markerApply(marker, astNodeFactory.createJSXMemberExpression(expr, parseJSXIdentifier()));
+ }
+
+ return expr;
+}
+
+function parseJSXElementName() {
+ if (lookahead2().value === ":") {
+ return parseJSXNamespacedName();
+ }
+ if (lookahead2().value === ".") {
+ return parseJSXMemberExpression();
+ }
+
+ return parseJSXIdentifier();
+}
+
+function parseJSXAttributeName() {
+ if (lookahead2().value === ":") {
+ return parseJSXNamespacedName();
+ }
+
+ return parseJSXIdentifier();
+}
+
+function parseJSXAttributeValue() {
+ var value, marker;
+ if (match("{")) {
+ value = parseJSXExpressionContainer();
+ if (value.expression.type === astNodeTypes.JSXEmptyExpression) {
+ throwError(
+ value,
+ "JSX attributes must only be assigned a non-empty " +
+ "expression"
+ );
+ }
+ } else if (match("<")) {
+ value = parseJSXElement();
+ } else if (lookahead.type === Token.JSXText) {
+ marker = markerCreate();
+ value = markerApply(marker, astNodeFactory.createLiteralFromSource(lex(), source));
+ } else {
+ throwError({}, Messages.InvalidJSXAttributeValue);
+ }
+ return value;
+}
+
+function parseJSXEmptyExpression() {
+ var marker = markerCreatePreserveWhitespace();
+ while (source.charAt(index) !== "}") {
+ index++;
+ }
+ return markerApply(marker, astNodeFactory.createJSXEmptyExpression());
+}
+
+function parseJSXExpressionContainer() {
+ var expression, origInJSXChild, origInJSXTag, marker = markerCreate();
+
+ origInJSXChild = state.inJSXChild;
+ origInJSXTag = state.inJSXTag;
+ state.inJSXChild = false;
+ state.inJSXTag = false;
+
+ expect("{");
+
+ if (match("}")) {
+ expression = parseJSXEmptyExpression();
+ } else {
+ expression = parseExpression();
+ }
+
+ state.inJSXChild = origInJSXChild;
+ state.inJSXTag = origInJSXTag;
+
+ expect("}");
+
+ return markerApply(marker, astNodeFactory.createJSXExpressionContainer(expression));
+}
+
+function parseJSXSpreadAttribute() {
+ var expression, origInJSXChild, origInJSXTag, marker = markerCreate();
+
+ origInJSXChild = state.inJSXChild;
+ origInJSXTag = state.inJSXTag;
+ state.inJSXChild = false;
+ state.inJSXTag = false;
+ state.inJSXSpreadAttribute = true;
+
+ expect("{");
+ expect("...");
+
+ state.inJSXSpreadAttribute = false;
+
+ expression = parseAssignmentExpression();
+
+ state.inJSXChild = origInJSXChild;
+ state.inJSXTag = origInJSXTag;
+
+ expect("}");
+
+ return markerApply(marker, astNodeFactory.createJSXSpreadAttribute(expression));
+}
+
+function parseJSXAttribute() {
+ var name, marker;
+
+ if (match("{")) {
+ return parseJSXSpreadAttribute();
+ }
+
+ marker = markerCreate();
+
+ name = parseJSXAttributeName();
+
+ // HTML empty attribute
+ if (match("=")) {
+ lex();
+ return markerApply(marker, astNodeFactory.createJSXAttribute(name, parseJSXAttributeValue()));
+ }
+
+ return markerApply(marker, astNodeFactory.createJSXAttribute(name));
+}
+
+function parseJSXChild() {
+ var token, marker;
+ if (match("{")) {
+ token = parseJSXExpressionContainer();
+ } else if (lookahead.type === Token.JSXText) {
+ marker = markerCreatePreserveWhitespace();
+ token = markerApply(marker, astNodeFactory.createLiteralFromSource(lex(), source));
+ } else {
+ token = parseJSXElement();
+ }
+ return token;
+}
+
+function parseJSXClosingElement() {
+ var name, origInJSXChild, origInJSXTag, marker = markerCreate();
+ origInJSXChild = state.inJSXChild;
+ origInJSXTag = state.inJSXTag;
+ state.inJSXChild = false;
+ state.inJSXTag = true;
+ expect("<");
+ expect("/");
+ name = parseJSXElementName();
+ // Because advance() (called by lex() called by expect()) expects there
+ // to be a valid token after >, it needs to know whether to look for a
+ // standard JS token or an JSX text node
+ state.inJSXChild = origInJSXChild;
+ state.inJSXTag = origInJSXTag;
+ expect(">");
+ return markerApply(marker, astNodeFactory.createJSXClosingElement(name));
+}
+
+function parseJSXOpeningElement() {
+ var name, attributes = [], selfClosing = false, origInJSXChild,
+ origInJSXTag, marker = markerCreate();
+
+ origInJSXChild = state.inJSXChild;
+ origInJSXTag = state.inJSXTag;
+ state.inJSXChild = false;
+ state.inJSXTag = true;
+
+ expect("<");
+
+ name = parseJSXElementName();
+
+ while (index < length &&
+ lookahead.value !== "/" &&
+ lookahead.value !== ">") {
+ attributes.push(parseJSXAttribute());
+ }
+
+ state.inJSXTag = origInJSXTag;
+
+ if (lookahead.value === "/") {
+ expect("/");
+ // Because advance() (called by lex() called by expect()) expects
+ // there to be a valid token after >, it needs to know whether to
+ // look for a standard JS token or an JSX text node
+ state.inJSXChild = origInJSXChild;
+ expect(">");
+ selfClosing = true;
+ } else {
+ state.inJSXChild = true;
+ expect(">");
+ }
+ return markerApply(marker, astNodeFactory.createJSXOpeningElement(name, attributes, selfClosing));
+}
+
+function parseJSXElement() {
+ var openingElement, closingElement = null, children = [], origInJSXChild, origInJSXTag, marker = markerCreate();
+
+ origInJSXChild = state.inJSXChild;
+ origInJSXTag = state.inJSXTag;
+ openingElement = parseJSXOpeningElement();
+
+ if (!openingElement.selfClosing) {
+ while (index < length) {
+ state.inJSXChild = false; // Call lookahead2() with inJSXChild = false because </ should not be considered in the child
+ if (lookahead.value === "<" && lookahead2().value === "/") {
+ break;
+ }
+ state.inJSXChild = true;
+ children.push(parseJSXChild());
+ }
+ state.inJSXChild = origInJSXChild;
+ state.inJSXTag = origInJSXTag;
+ closingElement = parseJSXClosingElement();
+ if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) {
+ throwError({}, Messages.ExpectedJSXClosingTag, getQualifiedJSXName(openingElement.name));
+ }
+ }
+
+ /*
+ * When (erroneously) writing two adjacent tags like
+ *
+ * var x = <div>one</div><div>two</div>;
+ *
+ * the default error message is a bit incomprehensible. Since it"s
+ * rarely (never?) useful to write a less-than sign after an JSX
+ * element, we disallow it here in the parser in order to provide a
+ * better error message. (In the rare case that the less-than operator
+ * was intended, the left tag can be wrapped in parentheses.)
+ */
+ if (!origInJSXChild && match("<")) {
+ throwError(lookahead, Messages.AdjacentJSXElements);
+ }
+
+ return markerApply(marker, astNodeFactory.createJSXElement(openingElement, closingElement, children));
+}
+
+//------------------------------------------------------------------------------
+// Location markers
+//------------------------------------------------------------------------------
+
+/**
+ * Applies location information to the given node by using the given marker.
+ * The marker indicates the point at which the node is said to have to begun
+ * in the source code.
+ * @param {Object} marker The marker to use for the node.
+ * @param {ASTNode} node The AST node to apply location information to.
+ * @returns {ASTNode} The node that was passed in.
+ * @private
+ */
+function markerApply(marker, node) {
+
+ // add range information to the node if present
+ if (extra.range) {
+ node.range = [marker.offset, index];
+ }
+
+ // add location information the node if present
+ if (extra.loc) {
+ node.loc = {
+ start: {
+ line: marker.line,
+ column: marker.col
+ },
+ end: {
+ line: lineNumber,
+ column: index - lineStart
+ }
+ };
+ // Attach extra.source information to the location, if present
+ if (extra.source) {
+ node.loc.source = extra.source;
+ }
+ }
+
+ // attach leading and trailing comments if requested
+ if (extra.attachComment) {
+ commentAttachment.processComment(node);
+ }
+
+ return node;
+}
+
+/**
+ * Creates a location marker in the source code. Location markers are used for
+ * tracking where tokens and nodes appear in the source code.
+ * @returns {Object} A marker object or undefined if the parser doesn't have
+ * any location information.
+ * @private
+ */
+function markerCreate() {
+
+ if (!extra.loc && !extra.range) {
+ return undefined;
+ }
+
+ skipComment();
+
+ return {
+ offset: index,
+ line: lineNumber,
+ col: index - lineStart
+ };
+}
+
+/**
+ * Creates a location marker in the source code. Location markers are used for
+ * tracking where tokens and nodes appear in the source code. This method
+ * doesn't skip comments or extra whitespace which is important for JSX.
+ * @returns {Object} A marker object or undefined if the parser doesn't have
+ * any location information.
+ * @private
+ */
+function markerCreatePreserveWhitespace() {
+
+ if (!extra.loc && !extra.range) {
+ return undefined;
+ }
+
+ return {
+ offset: index,
+ line: lineNumber,
+ col: index - lineStart
+ };
+}
+
+
+//------------------------------------------------------------------------------
+// Syntax Tree Delegate
+//------------------------------------------------------------------------------
+
+// Return true if there is a line terminator before the next token.
+
+function peekLineTerminator() {
+ var pos, line, start, found;
+
+ pos = index;
+ line = lineNumber;
+ start = lineStart;
+ skipComment();
+ found = lineNumber !== line;
+ index = pos;
+ lineNumber = line;
+ lineStart = start;
+
+ return found;
+}
+
+// Throw an exception
+
+function throwError(token, messageFormat) {
+
+ var error,
+ args = Array.prototype.slice.call(arguments, 2),
+ msg = messageFormat.replace(
+ /%(\d)/g,
+ function (whole, index) {
+ assert(index < args.length, "Message reference must be in range");
+ return args[index];
+ }
+ );
+
+ if (typeof token.lineNumber === "number") {
+ error = new Error("Line " + token.lineNumber + ": " + msg);
+ error.index = token.range[0];
+ error.lineNumber = token.lineNumber;
+ error.column = token.range[0] - lineStart + 1;
+ } else {
+ error = new Error("Line " + lineNumber + ": " + msg);
+ error.index = index;
+ error.lineNumber = lineNumber;
+ error.column = index - lineStart + 1;
+ }
+
+ error.description = msg;
+ throw error;
+}
+
+function throwErrorTolerant() {
+ try {
+ throwError.apply(null, arguments);
+ } catch (e) {
+ if (extra.errors) {
+ extra.errors.push(e);
+ } else {
+ throw e;
+ }
+ }
+}
+
+
+// Throw an exception because of the token.
+
+function throwUnexpected(token) {
+
+ if (token.type === Token.EOF) {
+ throwError(token, Messages.UnexpectedEOS);
+ }
+
+ if (token.type === Token.NumericLiteral) {
+ throwError(token, Messages.UnexpectedNumber);
+ }
+
+ if (token.type === Token.StringLiteral || token.type === Token.JSXText) {
+ throwError(token, Messages.UnexpectedString);
+ }
+
+ if (token.type === Token.Identifier) {
+ throwError(token, Messages.UnexpectedIdentifier);
+ }
+
+ if (token.type === Token.Keyword) {
+ if (syntax.isFutureReservedWord(token.value)) {
+ throwError(token, Messages.UnexpectedReserved);
+ } else if (strict && syntax.isStrictModeReservedWord(token.value)) {
+ throwErrorTolerant(token, Messages.StrictReservedWord);
+ return;
+ }
+ throwError(token, Messages.UnexpectedToken, token.value);
+ }
+
+ if (token.type === Token.Template) {
+ throwError(token, Messages.UnexpectedTemplate, token.value.raw);
+ }
+
+ // BooleanLiteral, NullLiteral, or Punctuator.
+ throwError(token, Messages.UnexpectedToken, token.value);
+}
+
+// Expect the next token to match the specified punctuator.
+// If not, an exception will be thrown.
+
+function expect(value) {
+ var token = lex();
+ if (token.type !== Token.Punctuator || token.value !== value) {
+ throwUnexpected(token);
+ }
+}
+
+// Expect the next token to match the specified keyword.
+// If not, an exception will be thrown.
+
+function expectKeyword(keyword) {
+ var token = lex();
+ if (token.type !== Token.Keyword || token.value !== keyword) {
+ throwUnexpected(token);
+ }
+}
+
+// Return true if the next token matches the specified punctuator.
+
+function match(value) {
+ return lookahead.type === Token.Punctuator && lookahead.value === value;
+}
+
+// Return true if the next token matches the specified keyword
+
+function matchKeyword(keyword) {
+ return lookahead.type === Token.Keyword && lookahead.value === keyword;
+}
+
+// Return true if the next token matches the specified contextual keyword
+// (where an identifier is sometimes a keyword depending on the context)
+
+function matchContextualKeyword(keyword) {
+ return lookahead.type === Token.Identifier && lookahead.value === keyword;
+}
+
+// Return true if the next token is an assignment operator
+
+function matchAssign() {
+ var op;
+
+ if (lookahead.type !== Token.Punctuator) {
+ return false;
+ }
+ op = lookahead.value;
+ return op === "=" ||
+ op === "*=" ||
+ op === "/=" ||
+ op === "%=" ||
+ op === "+=" ||
+ op === "-=" ||
+ op === "<<=" ||
+ op === ">>=" ||
+ op === ">>>=" ||
+ op === "&=" ||
+ op === "^=" ||
+ op === "|=";
+}
+
+function consumeSemicolon() {
+ var line;
+
+ // Catch the very common case first: immediately a semicolon (U+003B).
+ if (source.charCodeAt(index) === 0x3B || match(";")) {
+ lex();
+ return;
+ }
+
+ line = lineNumber;
+ skipComment();
+ if (lineNumber !== line) {
+ return;
+ }
+
+ if (lookahead.type !== Token.EOF && !match("}")) {
+ throwUnexpected(lookahead);
+ }
+}
+
+// Return true if provided expression is LeftHandSideExpression
+
+function isLeftHandSide(expr) {
+ return expr.type === astNodeTypes.Identifier || expr.type === astNodeTypes.MemberExpression;
+}
+
+// 11.1.4 Array Initialiser
+
+function parseArrayInitialiser() {
+ var elements = [],
+ marker = markerCreate(),
+ tmp;
+
+ expect("[");
+
+ while (!match("]")) {
+ if (match(",")) {
+ lex(); // only get here when you have [a,,] or similar
+ elements.push(null);
+ } else {
+ tmp = parseSpreadOrAssignmentExpression();
+ elements.push(tmp);
+ if (!(match("]"))) {
+ expect(","); // handles the common case of comma-separated values
+ }
+ }
+ }
+
+ expect("]");
+
+ return markerApply(marker, astNodeFactory.createArrayExpression(elements));
+}
+
+// 11.1.5 Object Initialiser
+
+function parsePropertyFunction(paramInfo, options) {
+ var previousStrict = strict,
+ previousYieldAllowed = state.yieldAllowed,
+ generator = options ? options.generator : false,
+ body;
+
+ state.yieldAllowed = generator;
+
+ /*
+ * Esprima uses parseConciseBody() here, which is incorrect. Object literal
+ * methods must have braces.
+ */
+ body = parseFunctionSourceElements();
+
+ if (strict && paramInfo.firstRestricted) {
+ throwErrorTolerant(paramInfo.firstRestricted, Messages.StrictParamName);
+ }
+
+ if (strict && paramInfo.stricted) {
+ throwErrorTolerant(paramInfo.stricted, paramInfo.message);
+ }
+
+ strict = previousStrict;
+ state.yieldAllowed = previousYieldAllowed;
+
+ return markerApply(options.marker, astNodeFactory.createFunctionExpression(
+ null,
+ paramInfo.params,
+ body,
+ generator,
+ body.type !== astNodeTypes.BlockStatement
+ ));
+}
+
+function parsePropertyMethodFunction(options) {
+ var previousStrict = strict,
+ marker = markerCreate(),
+ params,
+ method;
+
+ strict = true;
+
+ params = parseParams();
+
+ if (params.stricted) {
+ throwErrorTolerant(params.stricted, params.message);
+ }
+
+ method = parsePropertyFunction(params, {
+ generator: options ? options.generator : false,
+ marker: marker
+ });
+
+ strict = previousStrict;
+
+ return method;
+}
+
+function parseObjectPropertyKey() {
+ var marker = markerCreate(),
+ token = lex(),
+ allowObjectLiteralComputed = extra.ecmaFeatures.objectLiteralComputedProperties,
+ expr,
+ result;
+
+ // Note: This function is called only from parseObjectProperty(), where
+ // EOF and Punctuator tokens are already filtered out.
+
+ switch (token.type) {
+ case Token.StringLiteral:
+ case Token.NumericLiteral:
+ if (strict && token.octal) {
+ throwErrorTolerant(token, Messages.StrictOctalLiteral);
+ }
+ return markerApply(marker, astNodeFactory.createLiteralFromSource(token, source));
+
+ case Token.Identifier:
+ case Token.BooleanLiteral:
+ case Token.NullLiteral:
+ case Token.Keyword:
+ return markerApply(marker, astNodeFactory.createIdentifier(token.value));
+
+ case Token.Punctuator:
+ if ((!state.inObjectLiteral || allowObjectLiteralComputed) &&
+ token.value === "[") {
+ // For computed properties we should skip the [ and ], and
+ // capture in marker only the assignment expression itself.
+ marker = markerCreate();
+ expr = parseAssignmentExpression();
+ result = markerApply(marker, expr);
+ expect("]");
+ return result;
+ }
+
+ // no default
+ }
+
+ throwUnexpected(token);
+}
+
+function lookaheadPropertyName() {
+ switch (lookahead.type) {
+ case Token.Identifier:
+ case Token.StringLiteral:
+ case Token.BooleanLiteral:
+ case Token.NullLiteral:
+ case Token.NumericLiteral:
+ case Token.Keyword:
+ return true;
+ case Token.Punctuator:
+ return lookahead.value === "[";
+ // no default
+ }
+ return false;
+}
+
+// This function is to try to parse a MethodDefinition as defined in 14.3. But in the case of object literals,
+// it might be called at a position where there is in fact a short hand identifier pattern or a data property.
+// This can only be determined after we consumed up to the left parentheses.
+// In order to avoid back tracking, it returns `null` if the position is not a MethodDefinition and the caller
+// is responsible to visit other options.
+function tryParseMethodDefinition(token, key, computed, marker) {
+ var value, options, methodMarker;
+
+ if (token.type === Token.Identifier) {
+ // check for `get` and `set`;
+
+ if (token.value === "get" && lookaheadPropertyName()) {
+
+ computed = match("[");
+ key = parseObjectPropertyKey();
+ methodMarker = markerCreate();
+ expect("(");
+ expect(")");
+
+ value = parsePropertyFunction({
+ params: [],
+ stricted: null,
+ firstRestricted: null,
+ message: null
+ }, {
+ marker: methodMarker
+ });
+
+ return markerApply(marker, astNodeFactory.createProperty("get", key, value, false, false, computed));
+
+ } else if (token.value === "set" && lookaheadPropertyName()) {
+ computed = match("[");
+ key = parseObjectPropertyKey();
+ methodMarker = markerCreate();
+ expect("(");
+
+ options = {
+ params: [],
+ defaultCount: 0,
+ stricted: null,
+ firstRestricted: null,
+ paramSet: new StringMap()
+ };
+ if (match(")")) {
+ throwErrorTolerant(lookahead, Messages.UnexpectedToken, lookahead.value);
+ } else {
+ parseParam(options);
+ }
+ expect(")");
+
+ value = parsePropertyFunction(options, { marker: methodMarker });
+ return markerApply(marker, astNodeFactory.createProperty("set", key, value, false, false, computed));
+ }
+ }
+
+ if (match("(")) {
+ value = parsePropertyMethodFunction();
+ return markerApply(marker, astNodeFactory.createProperty("init", key, value, true, false, computed));
+ }
+
+ // Not a MethodDefinition.
+ return null;
+}
+
+/**
+ * Parses Generator Properties
+ * @param {ASTNode} key The property key (usually an identifier).
+ * @param {Object} marker The marker to use for the node.
+ * @returns {ASTNode} The generator property node.
+ */
+function parseGeneratorProperty(key, marker) {
+
+ var computed = (lookahead.type === Token.Punctuator && lookahead.value === "[");
+
+ if (!match("(")) {
+ throwUnexpected(lex());
+ }
+
+ return markerApply(
+ marker,
+ astNodeFactory.createProperty(
+ "init",
+ key,
+ parsePropertyMethodFunction({ generator: true }),
+ true,
+ false,
+ computed
+ )
+ );
+}
+
+// TODO(nzakas): Update to match Esprima
+function parseObjectProperty() {
+ var token, key, id, computed, methodMarker, options;
+ var allowComputed = extra.ecmaFeatures.objectLiteralComputedProperties,
+ allowMethod = extra.ecmaFeatures.objectLiteralShorthandMethods,
+ allowShorthand = extra.ecmaFeatures.objectLiteralShorthandProperties,
+ allowGenerators = extra.ecmaFeatures.generators,
+ allowDestructuring = extra.ecmaFeatures.destructuring,
+ marker = markerCreate();
+
+ token = lookahead;
+ computed = (token.value === "[" && token.type === Token.Punctuator);
+
+ if (token.type === Token.Identifier || (allowComputed && computed)) {
+
+ id = parseObjectPropertyKey();
+
+ /*
+ * Check for getters and setters. Be careful! "get" and "set" are legal
+ * method names. It's only a getter or setter if followed by a space.
+ */
+ if (token.value === "get" &&
+ !(match(":") || match("(") || match(",") || match("}"))) {
+ computed = (lookahead.value === "[");
+ key = parseObjectPropertyKey();
+ methodMarker = markerCreate();
+ expect("(");
+ expect(")");
+
+ return markerApply(
+ marker,
+ astNodeFactory.createProperty(
+ "get",
+ key,
+ parsePropertyFunction({
+ generator: false
+ }, {
+ marker: methodMarker
+ }),
+ false,
+ false,
+ computed
+ )
+ );
+ }
+
+ if (token.value === "set" &&
+ !(match(":") || match("(") || match(",") || match("}"))) {
+ computed = (lookahead.value === "[");
+ key = parseObjectPropertyKey();
+ methodMarker = markerCreate();
+ expect("(");
+
+ options = {
+ params: [],
+ defaultCount: 0,
+ stricted: null,
+ firstRestricted: null,
+ paramSet: new StringMap()
+ };
+
+ if (match(")")) {
+ throwErrorTolerant(lookahead, Messages.UnexpectedToken, lookahead.value);
+ } else {
+ parseParam(options);
+ }
+
+ expect(")");
+
+ return markerApply(
+ marker,
+ astNodeFactory.createProperty(
+ "set",
+ key,
+ parsePropertyFunction(options, {
+ marker: methodMarker
+ }),
+ false,
+ false,
+ computed
+ )
+ );
+ }
+
+ // normal property (key:value)
+ if (match(":")) {
+ lex();
+ return markerApply(
+ marker,
+ astNodeFactory.createProperty(
+ "init",
+ id,
+ parseAssignmentExpression(),
+ false,
+ false,
+ computed
+ )
+ );
+ }
+
+ // method shorthand (key(){...})
+ if (allowMethod && match("(")) {
+ return markerApply(
+ marker,
+ astNodeFactory.createProperty(
+ "init",
+ id,
+ parsePropertyMethodFunction({ generator: false }),
+ true,
+ false,
+ computed
+ )
+ );
+ }
+
+ // destructuring defaults (shorthand syntax)
+ if (allowDestructuring && match("=")) {
+ lex();
+ var value = parseAssignmentExpression();
+ var prop = markerApply(marker, astNodeFactory.createAssignmentExpression("=", id, value));
+ prop.type = astNodeTypes.AssignmentPattern;
+ var fullProperty = astNodeFactory.createProperty(
+ "init",
+ id,
+ prop,
+ false,
+ true, // shorthand
+ computed
+ );
+ return markerApply(marker, fullProperty);
+ }
+
+ /*
+ * Only other possibility is that this is a shorthand property. Computed
+ * properties cannot use shorthand notation, so that's a syntax error.
+ * If shorthand properties aren't allow, then this is an automatic
+ * syntax error. Destructuring is another case with a similar shorthand syntax.
+ */
+ if (computed || (!allowShorthand && !allowDestructuring)) {
+ throwUnexpected(lookahead);
+ }
+
+ // shorthand property
+ return markerApply(
+ marker,
+ astNodeFactory.createProperty(
+ "init",
+ id,
+ id,
+ false,
+ true,
+ false
+ )
+ );
+ }
+
+ // only possibility in this branch is a shorthand generator
+ if (token.type === Token.EOF || token.type === Token.Punctuator) {
+ if (!allowGenerators || !match("*") || !allowMethod) {
+ throwUnexpected(token);
+ }
+
+ lex();
+
+ id = parseObjectPropertyKey();
+
+ return parseGeneratorProperty(id, marker);
+
+ }
+
+ /*
+ * If we've made it here, then that means the property name is represented
+ * by a string (i.e, { "foo": 2}). The only options here are normal
+ * property with a colon or a method.
+ */
+ key = parseObjectPropertyKey();
+
+ // check for property value
+ if (match(":")) {
+ lex();
+ return markerApply(
+ marker,
+ astNodeFactory.createProperty(
+ "init",
+ key,
+ parseAssignmentExpression(),
+ false,
+ false,
+ false
+ )
+ );
+ }
+
+ // check for method
+ if (allowMethod && match("(")) {
+ return markerApply(
+ marker,
+ astNodeFactory.createProperty(
+ "init",
+ key,
+ parsePropertyMethodFunction(),
+ true,
+ false,
+ false
+ )
+ );
+ }
+
+ // no other options, this is bad
+ throwUnexpected(lex());
+}
+
+function getFieldName(key) {
+ var toString = String;
+ if (key.type === astNodeTypes.Identifier) {
+ return key.name;
+ }
+ return toString(key.value);
+}
+
+function parseObjectInitialiser() {
+ var marker = markerCreate(),
+ allowDuplicates = extra.ecmaFeatures.objectLiteralDuplicateProperties,
+ properties = [],
+ property,
+ name,
+ propertyFn,
+ kind,
+ storedKind,
+ previousInObjectLiteral = state.inObjectLiteral,
+ kindMap = new StringMap();
+
+ state.inObjectLiteral = true;
+
+ expect("{");
+
+ while (!match("}")) {
+
+ property = parseObjectProperty();
+
+ if (!property.computed) {
+
+ name = getFieldName(property.key);
+ propertyFn = (property.kind === "get") ? PropertyKind.Get : PropertyKind.Set;
+ kind = (property.kind === "init") ? PropertyKind.Data : propertyFn;
+
+ if (kindMap.has(name)) {
+ storedKind = kindMap.get(name);
+ if (storedKind === PropertyKind.Data) {
+ if (kind === PropertyKind.Data && name === "__proto__" && allowDuplicates) {
+ // Duplicate '__proto__' literal properties are forbidden in ES 6
+ throwErrorTolerant({}, Messages.DuplicatePrototypeProperty);
+ } else if (strict && kind === PropertyKind.Data && !allowDuplicates) {
+ // Duplicate literal properties are only forbidden in ES 5 strict mode
+ throwErrorTolerant({}, Messages.StrictDuplicateProperty);
+ } else if (kind !== PropertyKind.Data) {
+ throwErrorTolerant({}, Messages.AccessorDataProperty);
+ }
+ } else {
+ if (kind === PropertyKind.Data) {
+ throwErrorTolerant({}, Messages.AccessorDataProperty);
+ } else if (storedKind & kind) {
+ throwErrorTolerant({}, Messages.AccessorGetSet);
+ }
+ }
+ kindMap.set(name, storedKind | kind);
+ } else {
+ kindMap.set(name, kind);
+ }
+ }
+
+ properties.push(property);
+
+ if (!match("}")) {
+ expect(",");
+ }
+ }
+
+ expect("}");
+
+ state.inObjectLiteral = previousInObjectLiteral;
+
+ return markerApply(marker, astNodeFactory.createObjectExpression(properties));
+}
+
+/**
+ * Parse a template string element and return its ASTNode representation
+ * @param {Object} option Parsing & scanning options
+ * @param {Object} option.head True if this element is the first in the
+ * template string, false otherwise.
+ * @returns {ASTNode} The template element node with marker info applied
+ * @private
+ */
+function parseTemplateElement(option) {
+ var marker, token;
+
+ if (lookahead.type !== Token.Template || (option.head && !lookahead.head)) {
+ throwError({}, Messages.UnexpectedToken, "ILLEGAL");
+ }
+
+ marker = markerCreate();
+ token = lex();
+
+ return markerApply(
+ marker,
+ astNodeFactory.createTemplateElement(
+ {
+ raw: token.value.raw,
+ cooked: token.value.cooked
+ },
+ token.tail
+ )
+ );
+}
+
+/**
+ * Parse a template string literal and return its ASTNode representation
+ * @returns {ASTNode} The template literal node with marker info applied
+ * @private
+ */
+function parseTemplateLiteral() {
+ var quasi, quasis, expressions, marker = markerCreate();
+
+ quasi = parseTemplateElement({ head: true });
+ quasis = [ quasi ];
+ expressions = [];
+
+ while (!quasi.tail) {
+ expressions.push(parseExpression());
+ quasi = parseTemplateElement({ head: false });
+ quasis.push(quasi);
+ }
+
+ return markerApply(marker, astNodeFactory.createTemplateLiteral(quasis, expressions));
+}
+
+// 11.1.6 The Grouping Operator
+
+function parseGroupExpression() {
+ var expr;
+
+ expect("(");
+
+ ++state.parenthesisCount;
+
+ expr = parseExpression();
+
+ expect(")");
+
+ return expr;
+}
+
+
+// 11.1 Primary Expressions
+
+function parsePrimaryExpression() {
+ var type, token, expr,
+ marker,
+ allowJSX = extra.ecmaFeatures.jsx,
+ allowClasses = extra.ecmaFeatures.classes,
+ allowSuper = allowClasses || extra.ecmaFeatures.superInFunctions;
+
+ if (match("(")) {
+ return parseGroupExpression();
+ }
+
+ if (match("[")) {
+ return parseArrayInitialiser();
+ }
+
+ if (match("{")) {
+ return parseObjectInitialiser();
+ }
+
+ if (allowJSX && match("<")) {
+ return parseJSXElement();
+ }
+
+ type = lookahead.type;
+ marker = markerCreate();
+
+ if (type === Token.Identifier) {
+ expr = astNodeFactory.createIdentifier(lex().value);
+ } else if (type === Token.StringLiteral || type === Token.NumericLiteral) {
+ if (strict && lookahead.octal) {
+ throwErrorTolerant(lookahead, Messages.StrictOctalLiteral);
+ }
+ expr = astNodeFactory.createLiteralFromSource(lex(), source);
+ } else if (type === Token.Keyword) {
+ if (matchKeyword("function")) {
+ return parseFunctionExpression();
+ }
+
+ if (allowSuper && matchKeyword("super") && state.inFunctionBody) {
+ marker = markerCreate();
+ lex();
+ return markerApply(marker, astNodeFactory.createSuper());
+ }
+
+ if (matchKeyword("this")) {
+ marker = markerCreate();
+ lex();
+ return markerApply(marker, astNodeFactory.createThisExpression());
+ }
+
+ if (allowClasses && matchKeyword("class")) {
+ return parseClassExpression();
+ }
+
+ throwUnexpected(lex());
+ } else if (type === Token.BooleanLiteral) {
+ token = lex();
+ token.value = (token.value === "true");
+ expr = astNodeFactory.createLiteralFromSource(token, source);
+ } else if (type === Token.NullLiteral) {
+ token = lex();
+ token.value = null;
+ expr = astNodeFactory.createLiteralFromSource(token, source);
+ } else if (match("/") || match("/=")) {
+ if (typeof extra.tokens !== "undefined") {
+ expr = astNodeFactory.createLiteralFromSource(collectRegex(), source);
+ } else {
+ expr = astNodeFactory.createLiteralFromSource(scanRegExp(), source);
+ }
+ peek();
+ } else if (type === Token.Template) {
+ return parseTemplateLiteral();
+ } else {
+ throwUnexpected(lex());
+ }
+
+ return markerApply(marker, expr);
+}
+
+// 11.2 Left-Hand-Side Expressions
+
+function parseArguments() {
+ var args = [], arg;
+
+ expect("(");
+ if (!match(")")) {
+ while (index < length) {
+ arg = parseSpreadOrAssignmentExpression();
+ args.push(arg);
+
+ if (match(")")) {
+ break;
+ }
+
+ expect(",");
+ }
+ }
+
+ expect(")");
+
+ return args;
+}
+
+function parseSpreadOrAssignmentExpression() {
+ if (match("...")) {
+ var marker = markerCreate();
+ lex();
+ return markerApply(marker, astNodeFactory.createSpreadElement(parseAssignmentExpression()));
+ }
+ return parseAssignmentExpression();
+}
+
+function parseNonComputedProperty() {
+ var token,
+ marker = markerCreate();
+
+ token = lex();
+
+ if (!isIdentifierName(token)) {
+ throwUnexpected(token);
+ }
+
+ return markerApply(marker, astNodeFactory.createIdentifier(token.value));
+}
+
+function parseNonComputedMember() {
+ expect(".");
+
+ return parseNonComputedProperty();
+}
+
+function parseComputedMember() {
+ var expr;
+
+ expect("[");
+
+ expr = parseExpression();
+
+ expect("]");
+
+ return expr;
+}
+
+function parseNewExpression() {
+ var callee, args,
+ marker = markerCreate();
+
+ expectKeyword("new");
+ callee = parseLeftHandSideExpression();
+ args = match("(") ? parseArguments() : [];
+
+ return markerApply(marker, astNodeFactory.createNewExpression(callee, args));
+}
+
+function parseLeftHandSideExpressionAllowCall() {
+ var expr, args,
+ previousAllowIn = state.allowIn,
+ marker = markerCreate();
+
+ state.allowIn = true;
+ expr = matchKeyword("new") ? parseNewExpression() : parsePrimaryExpression();
+ state.allowIn = previousAllowIn;
+
+ // only start parsing template literal if the lookahead is a head (beginning with `)
+ while (match(".") || match("[") || match("(") || (lookahead.type === Token.Template && lookahead.head)) {
+ if (match("(")) {
+ args = parseArguments();
+ expr = markerApply(marker, astNodeFactory.createCallExpression(expr, args));
+ } else if (match("[")) {
+ expr = markerApply(marker, astNodeFactory.createMemberExpression("[", expr, parseComputedMember()));
+ } else if (match(".")) {
+ expr = markerApply(marker, astNodeFactory.createMemberExpression(".", expr, parseNonComputedMember()));
+ } else {
+ expr = markerApply(marker, astNodeFactory.createTaggedTemplateExpression(expr, parseTemplateLiteral()));
+ }
+ }
+
+ return expr;
+}
+
+function parseLeftHandSideExpression() {
+ var expr,
+ previousAllowIn = state.allowIn,
+ marker = markerCreate();
+
+ expr = matchKeyword("new") ? parseNewExpression() : parsePrimaryExpression();
+ state.allowIn = previousAllowIn;
+
+ // only start parsing template literal if the lookahead is a head (beginning with `)
+ while (match(".") || match("[") || (lookahead.type === Token.Template && lookahead.head)) {
+ if (match("[")) {
+ expr = markerApply(marker, astNodeFactory.createMemberExpression("[", expr, parseComputedMember()));
+ } else if (match(".")) {
+ expr = markerApply(marker, astNodeFactory.createMemberExpression(".", expr, parseNonComputedMember()));
+ } else {
+ expr = markerApply(marker, astNodeFactory.createTaggedTemplateExpression(expr, parseTemplateLiteral()));
+ }
+ }
+
+ return expr;
+}
+
+
+// 11.3 Postfix Expressions
+
+function parsePostfixExpression() {
+ var expr, token,
+ marker = markerCreate();
+
+ expr = parseLeftHandSideExpressionAllowCall();
+
+ if (lookahead.type === Token.Punctuator) {
+ if ((match("++") || match("--")) && !peekLineTerminator()) {
+ // 11.3.1, 11.3.2
+ if (strict && expr.type === astNodeTypes.Identifier && syntax.isRestrictedWord(expr.name)) {
+ throwErrorTolerant({}, Messages.StrictLHSPostfix);
+ }
+
+ if (!isLeftHandSide(expr)) {
+ throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
+ }
+
+ token = lex();
+ expr = markerApply(marker, astNodeFactory.createPostfixExpression(token.value, expr));
+ }
+ }
+
+ return expr;
+}
+
+// 11.4 Unary Operators
+
+function parseUnaryExpression() {
+ var token, expr,
+ marker;
+
+ if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {
+ expr = parsePostfixExpression();
+ } else if (match("++") || match("--")) {
+ marker = markerCreate();
+ token = lex();
+ expr = parseUnaryExpression();
+ // 11.4.4, 11.4.5
+ if (strict && expr.type === astNodeTypes.Identifier && syntax.isRestrictedWord(expr.name)) {
+ throwErrorTolerant({}, Messages.StrictLHSPrefix);
+ }
+
+ if (!isLeftHandSide(expr)) {
+ throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
+ }
+
+ expr = astNodeFactory.createUnaryExpression(token.value, expr);
+ expr = markerApply(marker, expr);
+ } else if (match("+") || match("-") || match("~") || match("!")) {
+ marker = markerCreate();
+ token = lex();
+ expr = parseUnaryExpression();
+ expr = astNodeFactory.createUnaryExpression(token.value, expr);
+ expr = markerApply(marker, expr);
+ } else if (matchKeyword("delete") || matchKeyword("void") || matchKeyword("typeof")) {
+ marker = markerCreate();
+ token = lex();
+ expr = parseUnaryExpression();
+ expr = astNodeFactory.createUnaryExpression(token.value, expr);
+ expr = markerApply(marker, expr);
+ if (strict && expr.operator === "delete" && expr.argument.type === astNodeTypes.Identifier) {
+ throwErrorTolerant({}, Messages.StrictDelete);
+ }
+ } else {
+ expr = parsePostfixExpression();
+ }
+
+ return expr;
+}
+
+function binaryPrecedence(token, allowIn) {
+ var prec = 0;
+
+ if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {
+ return 0;
+ }
+
+ switch (token.value) {
+ case "||":
+ prec = 1;
+ break;
+
+ case "&&":
+ prec = 2;
+ break;
+
+ case "|":
+ prec = 3;
+ break;
+
+ case "^":
+ prec = 4;
+ break;
+
+ case "&":
+ prec = 5;
+ break;
+
+ case "==":
+ case "!=":
+ case "===":
+ case "!==":
+ prec = 6;
+ break;
+
+ case "<":
+ case ">":
+ case "<=":
+ case ">=":
+ case "instanceof":
+ prec = 7;
+ break;
+
+ case "in":
+ prec = allowIn ? 7 : 0;
+ break;
+
+ case "<<":
+ case ">>":
+ case ">>>":
+ prec = 8;
+ break;
+
+ case "+":
+ case "-":
+ prec = 9;
+ break;
+
+ case "*":
+ case "/":
+ case "%":
+ prec = 11;
+ break;
+
+ default:
+ break;
+ }
+
+ return prec;
+}
+
+// 11.5 Multiplicative Operators
+// 11.6 Additive Operators
+// 11.7 Bitwise Shift Operators
+// 11.8 Relational Operators
+// 11.9 Equality Operators
+// 11.10 Binary Bitwise Operators
+// 11.11 Binary Logical Operators
+function parseBinaryExpression() {
+ var expr, token, prec, previousAllowIn, stack, right, operator, left, i,
+ marker, markers;
+
+ previousAllowIn = state.allowIn;
+ state.allowIn = true;
+
+ marker = markerCreate();
+ left = parseUnaryExpression();
+
+ token = lookahead;
+ prec = binaryPrecedence(token, previousAllowIn);
+ if (prec === 0) {
+ return left;
+ }
+ token.prec = prec;
+ lex();
+
+ markers = [marker, markerCreate()];
+ right = parseUnaryExpression();
+
+ stack = [left, token, right];
+
+ while ((prec = binaryPrecedence(lookahead, previousAllowIn)) > 0) {
+
+ // Reduce: make a binary expression from the three topmost entries.
+ while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {
+ right = stack.pop();
+ operator = stack.pop().value;
+ left = stack.pop();
+ expr = astNodeFactory.createBinaryExpression(operator, left, right);
+ markers.pop();
+ marker = markers.pop();
+ markerApply(marker, expr);
+ stack.push(expr);
+ markers.push(marker);
+ }
+
+ // Shift.
+ token = lex();
+ token.prec = prec;
+ stack.push(token);
+ markers.push(markerCreate());
+ expr = parseUnaryExpression();
+ stack.push(expr);
+ }
+
+ state.allowIn = previousAllowIn;
+
+ // Final reduce to clean-up the stack.
+ i = stack.length - 1;
+ expr = stack[i];
+ markers.pop();
+ while (i > 1) {
+ expr = astNodeFactory.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr);
+ i -= 2;
+ marker = markers.pop();
+ markerApply(marker, expr);
+ }
+
+ return expr;
+}
+
+// 11.12 Conditional Operator
+
+function parseConditionalExpression() {
+ var expr, previousAllowIn, consequent, alternate,
+ marker = markerCreate();
+
+ expr = parseBinaryExpression();
+
+ if (match("?")) {
+ lex();
+ previousAllowIn = state.allowIn;
+ state.allowIn = true;
+ consequent = parseAssignmentExpression();
+ state.allowIn = previousAllowIn;
+ expect(":");
+ alternate = parseAssignmentExpression();
+
+ expr = astNodeFactory.createConditionalExpression(expr, consequent, alternate);
+ markerApply(marker, expr);
+ }
+
+ return expr;
+}
+
+// [ES6] 14.2 Arrow Function
+
+function parseConciseBody() {
+ if (match("{")) {
+ return parseFunctionSourceElements();
+ }
+ return parseAssignmentExpression();
+}
+
+function reinterpretAsCoverFormalsList(expressions) {
+ var i, len, param, params, options,
+ allowRestParams = extra.ecmaFeatures.restParams;
+
+ params = [];
+ options = {
+ paramSet: new StringMap()
+ };
+
+ for (i = 0, len = expressions.length; i < len; i += 1) {
+ param = expressions[i];
+ if (param.type === astNodeTypes.Identifier) {
+ params.push(param);
+ validateParam(options, param, param.name);
+ } else if (param.type === astNodeTypes.ObjectExpression || param.type === astNodeTypes.ArrayExpression) {
+ reinterpretAsDestructuredParameter(options, param);
+ params.push(param);
+ } else if (param.type === astNodeTypes.SpreadElement) {
+ assert(i === len - 1, "It is guaranteed that SpreadElement is last element by parseExpression");
+ if (param.argument.type !== astNodeTypes.Identifier) {
+ throwError({}, Messages.UnexpectedToken, "[");
+ }
+
+ if (!allowRestParams) {
+ // can't get correct line/column here :(
+ throwError({}, Messages.UnexpectedToken, ".");
+ }
+
+ reinterpretAsDestructuredParameter(options, param.argument);
+ param.type = astNodeTypes.RestElement;
+ params.push(param);
+ } else if (param.type === astNodeTypes.RestElement) {
+ params.push(param);
+ validateParam(options, param.argument, param.argument.name);
+ } else if (param.type === astNodeTypes.AssignmentExpression) {
+
+ // TODO: Find a less hacky way of doing this
+ param.type = astNodeTypes.AssignmentPattern;
+ delete param.operator;
+
+ params.push(param);
+ validateParam(options, param.left, param.left.name);
+ } else {
+ return null;
+ }
+ }
+
+ if (options.message === Messages.StrictParamDupe) {
+ throwError(
+ strict ? options.stricted : options.firstRestricted,
+ options.message
+ );
+ }
+
+ return {
+ params: params,
+ stricted: options.stricted,
+ firstRestricted: options.firstRestricted,
+ message: options.message
+ };
+}
+
+function parseArrowFunctionExpression(options, marker) {
+ var previousStrict, body;
+
+ expect("=>");
+ previousStrict = strict;
+
+ body = parseConciseBody();
+
+ if (strict && options.firstRestricted) {
+ throwError(options.firstRestricted, options.message);
+ }
+ if (strict && options.stricted) {
+ throwErrorTolerant(options.stricted, options.message);
+ }
+
+ strict = previousStrict;
+ return markerApply(marker, astNodeFactory.createArrowFunctionExpression(
+ options.params,
+ body,
+ body.type !== astNodeTypes.BlockStatement
+ ));
+}
+
+// 11.13 Assignment Operators
+
+// 12.14.5 AssignmentPattern
+
+function reinterpretAsAssignmentBindingPattern(expr) {
+ var i, len, property, element,
+ allowDestructuring = extra.ecmaFeatures.destructuring;
+
+ if (!allowDestructuring) {
+ throwUnexpected(lex());
+ }
+
+ if (expr.type === astNodeTypes.ObjectExpression) {
+ expr.type = astNodeTypes.ObjectPattern;
+ for (i = 0, len = expr.properties.length; i < len; i += 1) {
+ property = expr.properties[i];
+ if (property.kind !== "init") {
+ throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
+ }
+ reinterpretAsAssignmentBindingPattern(property.value);
+ }
+ } else if (expr.type === astNodeTypes.ArrayExpression) {
+ expr.type = astNodeTypes.ArrayPattern;
+ for (i = 0, len = expr.elements.length; i < len; i += 1) {
+ element = expr.elements[i];
+ /* istanbul ignore else */
+ if (element) {
+ reinterpretAsAssignmentBindingPattern(element);
+ }
+ }
+ } else if (expr.type === astNodeTypes.Identifier) {
+ if (syntax.isRestrictedWord(expr.name)) {
+ throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
+ }
+ } else if (expr.type === astNodeTypes.SpreadElement) {
+ reinterpretAsAssignmentBindingPattern(expr.argument);
+ if (expr.argument.type === astNodeTypes.ObjectPattern) {
+ throwErrorTolerant({}, Messages.ObjectPatternAsSpread);
+ }
+ } else if (expr.type === "AssignmentExpression" && expr.operator === "=") {
+ expr.type = astNodeTypes.AssignmentPattern;
+ } else {
+ /* istanbul ignore else */
+ if (expr.type !== astNodeTypes.MemberExpression &&
+ expr.type !== astNodeTypes.CallExpression &&
+ expr.type !== astNodeTypes.NewExpression &&
+ expr.type !== astNodeTypes.AssignmentPattern
+ ) {
+ throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
+ }
+ }
+}
+
+// 13.2.3 BindingPattern
+
+function reinterpretAsDestructuredParameter(options, expr) {
+ var i, len, property, element,
+ allowDestructuring = extra.ecmaFeatures.destructuring;
+
+ if (!allowDestructuring) {
+ throwUnexpected(lex());
+ }
+
+ if (expr.type === astNodeTypes.ObjectExpression) {
+ expr.type = astNodeTypes.ObjectPattern;
+ for (i = 0, len = expr.properties.length; i < len; i += 1) {
+ property = expr.properties[i];
+ if (property.kind !== "init") {
+ throwErrorTolerant({}, Messages.InvalidLHSInFormalsList);
+ }
+ reinterpretAsDestructuredParameter(options, property.value);
+ }
+ } else if (expr.type === astNodeTypes.ArrayExpression) {
+ expr.type = astNodeTypes.ArrayPattern;
+ for (i = 0, len = expr.elements.length; i < len; i += 1) {
+ element = expr.elements[i];
+ if (element) {
+ reinterpretAsDestructuredParameter(options, element);
+ }
+ }
+ } else if (expr.type === astNodeTypes.Identifier) {
+ validateParam(options, expr, expr.name);
+ } else if (expr.type === astNodeTypes.SpreadElement) {
+ // BindingRestElement only allows BindingIdentifier
+ if (expr.argument.type !== astNodeTypes.Identifier) {
+ throwErrorTolerant({}, Messages.InvalidLHSInFormalsList);
+ }
+ validateParam(options, expr.argument, expr.argument.name);
+ } else if (expr.type === astNodeTypes.AssignmentExpression && expr.operator === "=") {
+ expr.type = astNodeTypes.AssignmentPattern;
+ } else if (expr.type !== astNodeTypes.AssignmentPattern) {
+ throwError({}, Messages.InvalidLHSInFormalsList);
+ }
+}
+
+function parseAssignmentExpression() {
+ var token, left, right, node, params,
+ marker,
+ startsWithParen = false,
+ oldParenthesisCount = state.parenthesisCount,
+ allowGenerators = extra.ecmaFeatures.generators;
+
+ // Note that 'yield' is treated as a keyword in strict mode, but a
+ // contextual keyword (identifier) in non-strict mode, so we need
+ // to use matchKeyword and matchContextualKeyword appropriately.
+ if (allowGenerators && ((state.yieldAllowed && matchContextualKeyword("yield")) || (strict && matchKeyword("yield")))) {
+ return parseYieldExpression();
+ }
+
+ marker = markerCreate();
+
+ if (match("(")) {
+ token = lookahead2();
+ if ((token.value === ")" && token.type === Token.Punctuator) || token.value === "...") {
+ params = parseParams();
+ if (!match("=>")) {
+ throwUnexpected(lex());
+ }
+ return parseArrowFunctionExpression(params, marker);
+ }
+ startsWithParen = true;
+ }
+
+ // revert to the previous lookahead style object
+ token = lookahead;
+ node = left = parseConditionalExpression();
+
+ if (match("=>") &&
+ (state.parenthesisCount === oldParenthesisCount ||
+ state.parenthesisCount === (oldParenthesisCount + 1))) {
+
+ if (node.type === astNodeTypes.Identifier) {
+ params = reinterpretAsCoverFormalsList([ node ]);
+ } else if (node.type === astNodeTypes.AssignmentExpression ||
+ node.type === astNodeTypes.ArrayExpression ||
+ node.type === astNodeTypes.ObjectExpression) {
+ if (!startsWithParen) {
+ throwUnexpected(lex());
+ }
+ params = reinterpretAsCoverFormalsList([ node ]);
+ } else if (node.type === astNodeTypes.SequenceExpression) {
+ params = reinterpretAsCoverFormalsList(node.expressions);
+ }
+
+ if (params) {
+ return parseArrowFunctionExpression(params, marker);
+ }
+ }
+
+ if (matchAssign()) {
+
+ // 11.13.1
+ if (strict && left.type === astNodeTypes.Identifier && syntax.isRestrictedWord(left.name)) {
+ throwErrorTolerant(token, Messages.StrictLHSAssignment);
+ }
+
+ // ES.next draf 11.13 Runtime Semantics step 1
+ if (match("=") && (node.type === astNodeTypes.ObjectExpression || node.type === astNodeTypes.ArrayExpression)) {
+ reinterpretAsAssignmentBindingPattern(node);
+ } else if (!isLeftHandSide(node)) {
+ throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
+ }
+
+ token = lex();
+ right = parseAssignmentExpression();
+ node = markerApply(marker, astNodeFactory.createAssignmentExpression(token.value, left, right));
+ }
+
+ return node;
+}
+
+// 11.14 Comma Operator
+
+function parseExpression() {
+ var marker = markerCreate(),
+ expr = parseAssignmentExpression(),
+ expressions = [ expr ],
+ sequence, spreadFound;
+
+ if (match(",")) {
+ while (index < length) {
+ if (!match(",")) {
+ break;
+ }
+ lex();
+ expr = parseSpreadOrAssignmentExpression();
+ expressions.push(expr);
+
+ if (expr.type === astNodeTypes.SpreadElement) {
+ spreadFound = true;
+ if (!match(")")) {
+ throwError({}, Messages.ElementAfterSpreadElement);
+ }
+ break;
+ }
+ }
+
+ sequence = markerApply(marker, astNodeFactory.createSequenceExpression(expressions));
+ }
+
+ if (spreadFound && lookahead2().value !== "=>") {
+ throwError({}, Messages.IllegalSpread);
+ }
+
+ return sequence || expr;
+}
+
+// 12.1 Block
+
+function parseStatementList() {
+ var list = [],
+ statement;
+
+ while (index < length) {
+ if (match("}")) {
+ break;
+ }
+ statement = parseSourceElement();
+ if (typeof statement === "undefined") {
+ break;
+ }
+ list.push(statement);
+ }
+
+ return list;
+}
+
+function parseBlock() {
+ var block,
+ marker = markerCreate();
+
+ expect("{");
+
+ block = parseStatementList();
+
+ expect("}");
+
+ return markerApply(marker, astNodeFactory.createBlockStatement(block));
+}
+
+// 12.2 Variable Statement
+
+function parseVariableIdentifier() {
+ var token,
+ marker = markerCreate();
+
+ token = lex();
+
+ if (token.type !== Token.Identifier) {
+ if (strict && token.type === Token.Keyword && syntax.isStrictModeReservedWord(token.value)) {
+ throwErrorTolerant(token, Messages.StrictReservedWord);
+ } else {
+ throwUnexpected(token);
+ }
+ }
+
+ return markerApply(marker, astNodeFactory.createIdentifier(token.value));
+}
+
+function parseVariableDeclaration(kind) {
+ var id,
+ marker = markerCreate(),
+ init = null;
+ if (match("{")) {
+ id = parseObjectInitialiser();
+ reinterpretAsAssignmentBindingPattern(id);
+ } else if (match("[")) {
+ id = parseArrayInitialiser();
+ reinterpretAsAssignmentBindingPattern(id);
+ } else {
+ /* istanbul ignore next */
+ id = state.allowKeyword ? parseNonComputedProperty() : parseVariableIdentifier();
+ // 12.2.1
+ if (strict && syntax.isRestrictedWord(id.name)) {
+ throwErrorTolerant({}, Messages.StrictVarName);
+ }
+ }
+
+ // TODO: Verify against feature flags
+ if (kind === "const") {
+ if (!match("=")) {
+ throwError({}, Messages.NoUnintializedConst);
+ }
+ expect("=");
+ init = parseAssignmentExpression();
+ } else if (match("=")) {
+ lex();
+ init = parseAssignmentExpression();
+ }
+
+ return markerApply(marker, astNodeFactory.createVariableDeclarator(id, init));
+}
+
+function parseVariableDeclarationList(kind) {
+ var list = [];
+
+ do {
+ list.push(parseVariableDeclaration(kind));
+ if (!match(",")) {
+ break;
+ }
+ lex();
+ } while (index < length);
+
+ return list;
+}
+
+function parseVariableStatement() {
+ var declarations;
+
+ expectKeyword("var");
+
+ declarations = parseVariableDeclarationList();
+
+ consumeSemicolon();
+
+ return astNodeFactory.createVariableDeclaration(declarations, "var");
+}
+
+// kind may be `const` or `let`
+// Both are experimental and not in the specification yet.
+// see http://wiki.ecmascript.org/doku.php?id=harmony:const
+// and http://wiki.ecmascript.org/doku.php?id=harmony:let
+function parseConstLetDeclaration(kind) {
+ var declarations,
+ marker = markerCreate();
+
+ expectKeyword(kind);
+
+ declarations = parseVariableDeclarationList(kind);
+
+ consumeSemicolon();
+
+ return markerApply(marker, astNodeFactory.createVariableDeclaration(declarations, kind));
+}
+
+
+function parseRestElement() {
+ var param,
+ marker = markerCreate();
+
+ lex();
+
+ if (match("{")) {
+ throwError(lookahead, Messages.ObjectPatternAsRestParameter);
+ }
+
+ param = parseVariableIdentifier();
+
+ if (match("=")) {
+ throwError(lookahead, Messages.DefaultRestParameter);
+ }
+
+ if (!match(")")) {
+ throwError(lookahead, Messages.ParameterAfterRestParameter);
+ }
+
+ return markerApply(marker, astNodeFactory.createRestElement(param));
+}
+
+// 12.3 Empty Statement
+
+function parseEmptyStatement() {
+ expect(";");
+ return astNodeFactory.createEmptyStatement();
+}
+
+// 12.4 Expression Statement
+
+function parseExpressionStatement() {
+ var expr = parseExpression();
+ consumeSemicolon();
+ return astNodeFactory.createExpressionStatement(expr);
+}
+
+// 12.5 If statement
+
+function parseIfStatement() {
+ var test, consequent, alternate;
+
+ expectKeyword("if");
+
+ expect("(");
+
+ test = parseExpression();
+
+ expect(")");
+
+ consequent = parseStatement();
+
+ if (matchKeyword("else")) {
+ lex();
+ alternate = parseStatement();
+ } else {
+ alternate = null;
+ }
+
+ return astNodeFactory.createIfStatement(test, consequent, alternate);
+}
+
+// 12.6 Iteration Statements
+
+function parseDoWhileStatement() {
+ var body, test, oldInIteration;
+
+ expectKeyword("do");
+
+ oldInIteration = state.inIteration;
+ state.inIteration = true;
+
+ body = parseStatement();
+
+ state.inIteration = oldInIteration;
+
+ expectKeyword("while");
+
+ expect("(");
+
+ test = parseExpression();
+
+ expect(")");
+
+ if (match(";")) {
+ lex();
+ }
+
+ return astNodeFactory.createDoWhileStatement(test, body);
+}
+
+function parseWhileStatement() {
+ var test, body, oldInIteration;
+
+ expectKeyword("while");
+
+ expect("(");
+
+ test = parseExpression();
+
+ expect(")");
+
+ oldInIteration = state.inIteration;
+ state.inIteration = true;
+
+ body = parseStatement();
+
+ state.inIteration = oldInIteration;
+
+ return astNodeFactory.createWhileStatement(test, body);
+}
+
+function parseForVariableDeclaration() {
+ var token, declarations,
+ marker = markerCreate();
+
+ token = lex();
+ declarations = parseVariableDeclarationList();
+
+ return markerApply(marker, astNodeFactory.createVariableDeclaration(declarations, token.value));
+}
+
+function parseForStatement(opts) {
+ var init, test, update, left, right, body, operator, oldInIteration;
+ var allowForOf = extra.ecmaFeatures.forOf,
+ allowBlockBindings = extra.ecmaFeatures.blockBindings;
+
+ init = test = update = null;
+
+ expectKeyword("for");
+
+ expect("(");
+
+ if (match(";")) {
+ lex();
+ } else {
+
+ if (matchKeyword("var") ||
+ (allowBlockBindings && (matchKeyword("let") || matchKeyword("const")))
+ ) {
+ state.allowIn = false;
+ init = parseForVariableDeclaration();
+ state.allowIn = true;
+
+ if (init.declarations.length === 1) {
+ if (matchKeyword("in") || (allowForOf && matchContextualKeyword("of"))) {
+ operator = lookahead;
+
+ // TODO: is "var" check here really needed? wasn"t in 1.2.2
+ if (!((operator.value === "in" || init.kind !== "var") && init.declarations[0].init)) {
+ lex();
+ left = init;
+ right = parseExpression();
+ init = null;
+ }
+ }
+ }
+
+ } else {
+ state.allowIn = false;
+ init = parseExpression();
+ state.allowIn = true;
+
+ if (allowForOf && matchContextualKeyword("of")) {
+ operator = lex();
+ left = init;
+ right = parseExpression();
+ init = null;
+ } else if (matchKeyword("in")) {
+ // LeftHandSideExpression
+ if (!isLeftHandSide(init)) {
+ throwErrorTolerant({}, Messages.InvalidLHSInForIn);
+ }
+
+ operator = lex();
+ left = init;
+ right = parseExpression();
+ init = null;
+ }
+ }
+
+ if (typeof left === "undefined") {
+ expect(";");
+ }
+ }
+
+ if (typeof left === "undefined") {
+
+ if (!match(";")) {
+ test = parseExpression();
+ }
+ expect(";");
+
+ if (!match(")")) {
+ update = parseExpression();
+ }
+ }
+
+ expect(")");
+
+ oldInIteration = state.inIteration;
+ state.inIteration = true;
+
+ if (!(opts !== undefined && opts.ignoreBody)) {
+ body = parseStatement();
+ }
+
+ state.inIteration = oldInIteration;
+
+ if (typeof left === "undefined") {
+ return astNodeFactory.createForStatement(init, test, update, body);
+ }
+
+ if (extra.ecmaFeatures.forOf && operator.value === "of") {
+ return astNodeFactory.createForOfStatement(left, right, body);
+ }
+
+ return astNodeFactory.createForInStatement(left, right, body);
+}
+
+// 12.7 The continue statement
+
+function parseContinueStatement() {
+ var label = null;
+
+ expectKeyword("continue");
+
+ // Optimize the most common form: "continue;".
+ if (source.charCodeAt(index) === 0x3B) {
+ lex();
+
+ if (!state.inIteration) {
+ throwError({}, Messages.IllegalContinue);
+ }
+
+ return astNodeFactory.createContinueStatement(null);
+ }
+
+ if (peekLineTerminator()) {
+ if (!state.inIteration) {
+ throwError({}, Messages.IllegalContinue);
+ }
+
+ return astNodeFactory.createContinueStatement(null);
+ }
+
+ if (lookahead.type === Token.Identifier) {
+ label = parseVariableIdentifier();
+
+ if (!state.labelSet.has(label.name)) {
+ throwError({}, Messages.UnknownLabel, label.name);
+ }
+ }
+
+ consumeSemicolon();
+
+ if (label === null && !state.inIteration) {
+ throwError({}, Messages.IllegalContinue);
+ }
+
+ return astNodeFactory.createContinueStatement(label);
+}
+
+// 12.8 The break statement
+
+function parseBreakStatement() {
+ var label = null;
+
+ expectKeyword("break");
+
+ // Catch the very common case first: immediately a semicolon (U+003B).
+ if (source.charCodeAt(index) === 0x3B) {
+ lex();
+
+ if (!(state.inIteration || state.inSwitch)) {
+ throwError({}, Messages.IllegalBreak);
+ }
+
+ return astNodeFactory.createBreakStatement(null);
+ }
+
+ if (peekLineTerminator()) {
+ if (!(state.inIteration || state.inSwitch)) {
+ throwError({}, Messages.IllegalBreak);
+ }
+
+ return astNodeFactory.createBreakStatement(null);
+ }
+
+ if (lookahead.type === Token.Identifier) {
+ label = parseVariableIdentifier();
+
+ if (!state.labelSet.has(label.name)) {
+ throwError({}, Messages.UnknownLabel, label.name);
+ }
+ }
+
+ consumeSemicolon();
+
+ if (label === null && !(state.inIteration || state.inSwitch)) {
+ throwError({}, Messages.IllegalBreak);
+ }
+
+ return astNodeFactory.createBreakStatement(label);
+}
+
+// 12.9 The return statement
+
+function parseReturnStatement() {
+ var argument = null;
+
+ expectKeyword("return");
+
+ if (!state.inFunctionBody && !extra.ecmaFeatures.globalReturn) {
+ throwErrorTolerant({}, Messages.IllegalReturn);
+ }
+
+ // "return" followed by a space and an identifier is very common.
+ if (source.charCodeAt(index) === 0x20) {
+ if (syntax.isIdentifierStart(source.charCodeAt(index + 1))) {
+ argument = parseExpression();
+ consumeSemicolon();
+ return astNodeFactory.createReturnStatement(argument);
+ }
+ }
+
+ if (peekLineTerminator()) {
+ return astNodeFactory.createReturnStatement(null);
+ }
+
+ if (!match(";")) {
+ if (!match("}") && lookahead.type !== Token.EOF) {
+ argument = parseExpression();
+ }
+ }
+
+ consumeSemicolon();
+
+ return astNodeFactory.createReturnStatement(argument);
+}
+
+// 12.10 The with statement
+
+function parseWithStatement() {
+ var object, body;
+
+ if (strict) {
+ // TODO(ikarienator): Should we update the test cases instead?
+ skipComment();
+ throwErrorTolerant({}, Messages.StrictModeWith);
+ }
+
+ expectKeyword("with");
+
+ expect("(");
+
+ object = parseExpression();
+
+ expect(")");
+
+ body = parseStatement();
+
+ return astNodeFactory.createWithStatement(object, body);
+}
+
+// 12.10 The swith statement
+
+function parseSwitchCase() {
+ var test, consequent = [], statement,
+ marker = markerCreate();
+
+ if (matchKeyword("default")) {
+ lex();
+ test = null;
+ } else {
+ expectKeyword("case");
+ test = parseExpression();
+ }
+ expect(":");
+
+ while (index < length) {
+ if (match("}") || matchKeyword("default") || matchKeyword("case")) {
+ break;
+ }
+ statement = parseSourceElement();
+ if (typeof statement === "undefined") {
+ break;
+ }
+ consequent.push(statement);
+ }
+
+ return markerApply(marker, astNodeFactory.createSwitchCase(test, consequent));
+}
+
+function parseSwitchStatement() {
+ var discriminant, cases, clause, oldInSwitch, defaultFound;
+
+ expectKeyword("switch");
+
+ expect("(");
+
+ discriminant = parseExpression();
+
+ expect(")");
+
+ expect("{");
+
+ cases = [];
+
+ if (match("}")) {
+ lex();
+ return astNodeFactory.createSwitchStatement(discriminant, cases);
+ }
+
+ oldInSwitch = state.inSwitch;
+ state.inSwitch = true;
+ defaultFound = false;
+
+ while (index < length) {
+ if (match("}")) {
+ break;
+ }
+ clause = parseSwitchCase();
+ if (clause.test === null) {
+ if (defaultFound) {
+ throwError({}, Messages.MultipleDefaultsInSwitch);
+ }
+ defaultFound = true;
+ }
+ cases.push(clause);
+ }
+
+ state.inSwitch = oldInSwitch;
+
+ expect("}");
+
+ return astNodeFactory.createSwitchStatement(discriminant, cases);
+}
+
+// 12.13 The throw statement
+
+function parseThrowStatement() {
+ var argument;
+
+ expectKeyword("throw");
+
+ if (peekLineTerminator()) {
+ throwError({}, Messages.NewlineAfterThrow);
+ }
+
+ argument = parseExpression();
+
+ consumeSemicolon();
+
+ return astNodeFactory.createThrowStatement(argument);
+}
+
+// 12.14 The try statement
+
+function parseCatchClause() {
+ var param, body,
+ marker = markerCreate(),
+ allowDestructuring = extra.ecmaFeatures.destructuring,
+ options = {
+ paramSet: new StringMap()
+ };
+
+ expectKeyword("catch");
+
+ expect("(");
+ if (match(")")) {
+ throwUnexpected(lookahead);
+ }
+
+ if (match("[")) {
+ if (!allowDestructuring) {
+ throwUnexpected(lookahead);
+ }
+ param = parseArrayInitialiser();
+ reinterpretAsDestructuredParameter(options, param);
+ } else if (match("{")) {
+
+ if (!allowDestructuring) {
+ throwUnexpected(lookahead);
+ }
+ param = parseObjectInitialiser();
+ reinterpretAsDestructuredParameter(options, param);
+ } else {
+ param = parseVariableIdentifier();
+ }
+
+ // 12.14.1
+ if (strict && param.name && syntax.isRestrictedWord(param.name)) {
+ throwErrorTolerant({}, Messages.StrictCatchVariable);
+ }
+
+ expect(")");
+ body = parseBlock();
+ return markerApply(marker, astNodeFactory.createCatchClause(param, body));
+}
+
+function parseTryStatement() {
+ var block, handler = null, finalizer = null;
+
+ expectKeyword("try");
+
+ block = parseBlock();
+
+ if (matchKeyword("catch")) {
+ handler = parseCatchClause();
+ }
+
+ if (matchKeyword("finally")) {
+ lex();
+ finalizer = parseBlock();
+ }
+
+ if (!handler && !finalizer) {
+ throwError({}, Messages.NoCatchOrFinally);
+ }
+
+ return astNodeFactory.createTryStatement(block, handler, finalizer);
+}
+
+// 12.15 The debugger statement
+
+function parseDebuggerStatement() {
+ expectKeyword("debugger");
+
+ consumeSemicolon();
+
+ return astNodeFactory.createDebuggerStatement();
+}
+
+// 12 Statements
+
+function parseStatement() {
+ var type = lookahead.type,
+ expr,
+ labeledBody,
+ marker;
+
+ if (type === Token.EOF) {
+ throwUnexpected(lookahead);
+ }
+
+ if (type === Token.Punctuator && lookahead.value === "{") {
+ return parseBlock();
+ }
+
+ marker = markerCreate();
+
+ if (type === Token.Punctuator) {
+ switch (lookahead.value) {
+ case ";":
+ return markerApply(marker, parseEmptyStatement());
+ case "{":
+ return parseBlock();
+ case "(":
+ return markerApply(marker, parseExpressionStatement());
+ default:
+ break;
+ }
+ }
+
+ marker = markerCreate();
+
+ if (type === Token.Keyword) {
+ switch (lookahead.value) {
+ case "break":
+ return markerApply(marker, parseBreakStatement());
+ case "continue":
+ return markerApply(marker, parseContinueStatement());
+ case "debugger":
+ return markerApply(marker, parseDebuggerStatement());
+ case "do":
+ return markerApply(marker, parseDoWhileStatement());
+ case "for":
+ return markerApply(marker, parseForStatement());
+ case "function":
+ return markerApply(marker, parseFunctionDeclaration());
+ case "if":
+ return markerApply(marker, parseIfStatement());
+ case "return":
+ return markerApply(marker, parseReturnStatement());
+ case "switch":
+ return markerApply(marker, parseSwitchStatement());
+ case "throw":
+ return markerApply(marker, parseThrowStatement());
+ case "try":
+ return markerApply(marker, parseTryStatement());
+ case "var":
+ return markerApply(marker, parseVariableStatement());
+ case "while":
+ return markerApply(marker, parseWhileStatement());
+ case "with":
+ return markerApply(marker, parseWithStatement());
+ default:
+ break;
+ }
+ }
+
+ marker = markerCreate();
+ expr = parseExpression();
+
+ // 12.12 Labelled Statements
+ if ((expr.type === astNodeTypes.Identifier) && match(":")) {
+ lex();
+
+ if (state.labelSet.has(expr.name)) {
+ throwError({}, Messages.Redeclaration, "Label", expr.name);
+ }
+
+ state.labelSet.set(expr.name, true);
+ labeledBody = parseStatement();
+ state.labelSet.delete(expr.name);
+ return markerApply(marker, astNodeFactory.createLabeledStatement(expr, labeledBody));
+ }
+
+ consumeSemicolon();
+
+ return markerApply(marker, astNodeFactory.createExpressionStatement(expr));
+}
+
+// 13 Function Definition
+
+// function parseConciseBody() {
+// if (match("{")) {
+// return parseFunctionSourceElements();
+// }
+// return parseAssignmentExpression();
+// }
+
+function parseFunctionSourceElements() {
+ var sourceElement, sourceElements = [], token, directive, firstRestricted,
+ oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, oldParenthesisCount,
+ marker = markerCreate();
+
+ expect("{");
+
+ while (index < length) {
+ if (lookahead.type !== Token.StringLiteral) {
+ break;
+ }
+ token = lookahead;
+
+ sourceElement = parseSourceElement();
+ sourceElements.push(sourceElement);
+ if (sourceElement.expression.type !== astNodeTypes.Literal) {
+ // this is not directive
+ break;
+ }
+ directive = source.slice(token.range[0] + 1, token.range[1] - 1);
+ if (directive === "use strict") {
+ strict = true;
+
+ if (firstRestricted) {
+ throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
+ }
+ } else {
+ if (!firstRestricted && token.octal) {
+ firstRestricted = token;
+ }
+ }
+ }
+
+ oldLabelSet = state.labelSet;
+ oldInIteration = state.inIteration;
+ oldInSwitch = state.inSwitch;
+ oldInFunctionBody = state.inFunctionBody;
+ oldParenthesisCount = state.parenthesizedCount;
+
+ state.labelSet = new StringMap();
+ state.inIteration = false;
+ state.inSwitch = false;
+ state.inFunctionBody = true;
+
+ while (index < length) {
+
+ if (match("}")) {
+ break;
+ }
+
+ sourceElement = parseSourceElement();
+
+ if (typeof sourceElement === "undefined") {
+ break;
+ }
+
+ sourceElements.push(sourceElement);
+ }
+
+ expect("}");
+
+ state.labelSet = oldLabelSet;
+ state.inIteration = oldInIteration;
+ state.inSwitch = oldInSwitch;
+ state.inFunctionBody = oldInFunctionBody;
+ state.parenthesizedCount = oldParenthesisCount;
+
+ return markerApply(marker, astNodeFactory.createBlockStatement(sourceElements));
+}
+
+function validateParam(options, param, name) {
+
+ if (strict) {
+ if (syntax.isRestrictedWord(name)) {
+ options.stricted = param;
+ options.message = Messages.StrictParamName;
+ }
+
+ if (options.paramSet.has(name)) {
+ options.stricted = param;
+ options.message = Messages.StrictParamDupe;
+ }
+ } else if (!options.firstRestricted) {
+ if (syntax.isRestrictedWord(name)) {
+ options.firstRestricted = param;
+ options.message = Messages.StrictParamName;
+ } else if (syntax.isStrictModeReservedWord(name)) {
+ options.firstRestricted = param;
+ options.message = Messages.StrictReservedWord;
+ } else if (options.paramSet.has(name)) {
+ options.firstRestricted = param;
+ options.message = Messages.StrictParamDupe;
+ }
+ }
+ options.paramSet.set(name, true);
+}
+
+function parseParam(options) {
+ var token, param, def,
+ allowRestParams = extra.ecmaFeatures.restParams,
+ allowDestructuring = extra.ecmaFeatures.destructuring,
+ allowDefaultParams = extra.ecmaFeatures.defaultParams,
+ marker = markerCreate();
+
+ token = lookahead;
+ if (token.value === "...") {
+ if (!allowRestParams) {
+ throwUnexpected(lookahead);
+ }
+ param = parseRestElement();
+ validateParam(options, param.argument, param.argument.name);
+ options.params.push(param);
+ return false;
+ }
+
+ if (match("[")) {
+ if (!allowDestructuring) {
+ throwUnexpected(lookahead);
+ }
+ param = parseArrayInitialiser();
+ reinterpretAsDestructuredParameter(options, param);
+ } else if (match("{")) {
+ if (!allowDestructuring) {
+ throwUnexpected(lookahead);
+ }
+ param = parseObjectInitialiser();
+ reinterpretAsDestructuredParameter(options, param);
+ } else {
+ param = parseVariableIdentifier();
+ validateParam(options, token, token.value);
+ }
+
+ if (match("=")) {
+ if (allowDefaultParams || allowDestructuring) {
+ lex();
+ def = parseAssignmentExpression();
+ ++options.defaultCount;
+ } else {
+ throwUnexpected(lookahead);
+ }
+ }
+
+ if (def) {
+ options.params.push(markerApply(
+ marker,
+ astNodeFactory.createAssignmentPattern(
+ param,
+ def
+ )
+ ));
+ } else {
+ options.params.push(param);
+ }
+
+ return !match(")");
+}
+
+
+function parseParams(firstRestricted) {
+ var options;
+
+ options = {
+ params: [],
+ defaultCount: 0,
+ firstRestricted: firstRestricted
+ };
+
+ expect("(");
+
+ if (!match(")")) {
+ options.paramSet = new StringMap();
+ while (index < length) {
+ if (!parseParam(options)) {
+ break;
+ }
+ expect(",");
+ }
+ }
+
+ expect(")");
+
+ return {
+ params: options.params,
+ stricted: options.stricted,
+ firstRestricted: options.firstRestricted,
+ message: options.message
+ };
+}
+
+function parseFunctionDeclaration(identifierIsOptional) {
+ var id = null, body, token, tmp, firstRestricted, message, previousStrict, previousYieldAllowed, generator,
+ marker = markerCreate(),
+ allowGenerators = extra.ecmaFeatures.generators;
+
+ expectKeyword("function");
+
+ generator = false;
+ if (allowGenerators && match("*")) {
+ lex();
+ generator = true;
+ }
+
+ if (!identifierIsOptional || !match("(")) {
+
+ token = lookahead;
+
+ id = parseVariableIdentifier();
+
+ if (strict) {
+ if (syntax.isRestrictedWord(token.value)) {
+ throwErrorTolerant(token, Messages.StrictFunctionName);
+ }
+ } else {
+ if (syntax.isRestrictedWord(token.value)) {
+ firstRestricted = token;
+ message = Messages.StrictFunctionName;
+ } else if (syntax.isStrictModeReservedWord(token.value)) {
+ firstRestricted = token;
+ message = Messages.StrictReservedWord;
+ }
+ }
+ }
+
+ tmp = parseParams(firstRestricted);
+ firstRestricted = tmp.firstRestricted;
+ if (tmp.message) {
+ message = tmp.message;
+ }
+
+ previousStrict = strict;
+ previousYieldAllowed = state.yieldAllowed;
+ state.yieldAllowed = generator;
+
+ body = parseFunctionSourceElements();
+
+ if (strict && firstRestricted) {
+ throwError(firstRestricted, message);
+ }
+ if (strict && tmp.stricted) {
+ throwErrorTolerant(tmp.stricted, message);
+ }
+ strict = previousStrict;
+ state.yieldAllowed = previousYieldAllowed;
+
+ return markerApply(
+ marker,
+ astNodeFactory.createFunctionDeclaration(
+ id,
+ tmp.params,
+ body,
+ generator,
+ false
+ )
+ );
+ }
+
+function parseFunctionExpression() {
+ var token, id = null, firstRestricted, message, tmp, body, previousStrict, previousYieldAllowed, generator,
+ marker = markerCreate(),
+ allowGenerators = extra.ecmaFeatures.generators;
+
+ expectKeyword("function");
+
+ generator = false;
+
+ if (allowGenerators && match("*")) {
+ lex();
+ generator = true;
+ }
+
+ if (!match("(")) {
+ token = lookahead;
+ id = parseVariableIdentifier();
+ if (strict) {
+ if (syntax.isRestrictedWord(token.value)) {
+ throwErrorTolerant(token, Messages.StrictFunctionName);
+ }
+ } else {
+ if (syntax.isRestrictedWord(token.value)) {
+ firstRestricted = token;
+ message = Messages.StrictFunctionName;
+ } else if (syntax.isStrictModeReservedWord(token.value)) {
+ firstRestricted = token;
+ message = Messages.StrictReservedWord;
+ }
+ }
+ }
+
+ tmp = parseParams(firstRestricted);
+ firstRestricted = tmp.firstRestricted;
+ if (tmp.message) {
+ message = tmp.message;
+ }
+
+ previousStrict = strict;
+ previousYieldAllowed = state.yieldAllowed;
+ state.yieldAllowed = generator;
+
+ body = parseFunctionSourceElements();
+
+ if (strict && firstRestricted) {
+ throwError(firstRestricted, message);
+ }
+ if (strict && tmp.stricted) {
+ throwErrorTolerant(tmp.stricted, message);
+ }
+ strict = previousStrict;
+ state.yieldAllowed = previousYieldAllowed;
+
+ return markerApply(
+ marker,
+ astNodeFactory.createFunctionExpression(
+ id,
+ tmp.params,
+ body,
+ generator,
+ false
+ )
+ );
+}
+
+function parseYieldExpression() {
+ var yieldToken, delegateFlag, expr, marker = markerCreate();
+
+ yieldToken = lex();
+ assert(yieldToken.value === "yield", "Called parseYieldExpression with non-yield lookahead.");
+
+ if (!state.yieldAllowed) {
+ throwErrorTolerant({}, Messages.IllegalYield);
+ }
+
+ delegateFlag = false;
+ if (match("*")) {
+ lex();
+ delegateFlag = true;
+ }
+
+ if (peekLineTerminator()) {
+ return markerApply(marker, astNodeFactory.createYieldExpression(null, delegateFlag));
+ }
+
+ if (!match(";") && !match(")")) {
+ if (!match("}") && lookahead.type !== Token.EOF) {
+ expr = parseAssignmentExpression();
+ }
+ }
+
+ return markerApply(marker, astNodeFactory.createYieldExpression(expr, delegateFlag));
+}
+
+// Modules grammar from:
+// people.mozilla.org/~jorendorff/es6-draft.html
+
+function parseModuleSpecifier() {
+ var marker = markerCreate(),
+ specifier;
+
+ if (lookahead.type !== Token.StringLiteral) {
+ throwError({}, Messages.InvalidModuleSpecifier);
+ }
+ specifier = astNodeFactory.createLiteralFromSource(lex(), source);
+ return markerApply(marker, specifier);
+}
+
+function parseExportSpecifier() {
+ var exported, local, marker = markerCreate();
+ if (matchKeyword("default")) {
+ lex();
+ local = markerApply(marker, astNodeFactory.createIdentifier("default"));
+ // export {default} from "something";
+ } else {
+ local = parseVariableIdentifier();
+ }
+ if (matchContextualKeyword("as")) {
+ lex();
+ exported = parseNonComputedProperty();
+ }
+ return markerApply(marker, astNodeFactory.createExportSpecifier(local, exported));
+}
+
+function parseExportNamedDeclaration() {
+ var declaration = null,
+ isExportFromIdentifier,
+ src = null, specifiers = [],
+ marker = markerCreate();
+
+ expectKeyword("export");
+
+ // non-default export
+ if (lookahead.type === Token.Keyword) {
+ // covers:
+ // export var f = 1;
+ switch (lookahead.value) {
+ case "let":
+ case "const":
+ case "var":
+ case "class":
+ case "function":
+ declaration = parseSourceElement();
+ return markerApply(marker, astNodeFactory.createExportNamedDeclaration(declaration, specifiers, null));
+ default:
+ break;
+ }
+ }
+
+ expect("{");
+ if (!match("}")) {
+ do {
+ isExportFromIdentifier = isExportFromIdentifier || matchKeyword("default");
+ specifiers.push(parseExportSpecifier());
+ } while (match(",") && lex());
+ }
+ expect("}");
+
+ if (matchContextualKeyword("from")) {
+ // covering:
+ // export {default} from "foo";
+ // export {foo} from "foo";
+ lex();
+ src = parseModuleSpecifier();
+ consumeSemicolon();
+ } else if (isExportFromIdentifier) {
+ // covering:
+ // export {default}; // missing fromClause
+ throwError({}, lookahead.value ?
+ Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
+ } else {
+ // cover
+ // export {foo};
+ consumeSemicolon();
+ }
+ return markerApply(marker, astNodeFactory.createExportNamedDeclaration(declaration, specifiers, src));
+}
+
+function parseExportDefaultDeclaration() {
+ var declaration = null,
+ expression = null,
+ possibleIdentifierToken,
+ allowClasses = extra.ecmaFeatures.classes,
+ marker = markerCreate();
+
+ // covers:
+ // export default ...
+ expectKeyword("export");
+ expectKeyword("default");
+
+ if (matchKeyword("function") || matchKeyword("class")) {
+ possibleIdentifierToken = lookahead2();
+ if (possibleIdentifierToken.type === Token.Identifier) {
+ // covers:
+ // export default function foo () {}
+ // export default class foo {}
+ declaration = parseSourceElement();
+ return markerApply(marker, astNodeFactory.createExportDefaultDeclaration(declaration));
+ }
+ // covers:
+ // export default function () {}
+ // export default class {}
+ if (lookahead.value === "function") {
+ declaration = parseFunctionDeclaration(true);
+ return markerApply(marker, astNodeFactory.createExportDefaultDeclaration(declaration));
+ } else if (allowClasses && lookahead.value === "class") {
+ declaration = parseClassDeclaration(true);
+ return markerApply(marker, astNodeFactory.createExportDefaultDeclaration(declaration));
+ }
+ }
+
+ if (matchContextualKeyword("from")) {
+ throwError({}, Messages.UnexpectedToken, lookahead.value);
+ }
+
+ // covers:
+ // export default {};
+ // export default [];
+ // export default (1 + 2);
+ if (match("{")) {
+ expression = parseObjectInitialiser();
+ } else if (match("[")) {
+ expression = parseArrayInitialiser();
+ } else {
+ expression = parseAssignmentExpression();
+ }
+ consumeSemicolon();
+ return markerApply(marker, astNodeFactory.createExportDefaultDeclaration(expression));
+}
+
+
+function parseExportAllDeclaration() {
+ var src,
+ marker = markerCreate();
+
+ // covers:
+ // export * from "foo";
+ expectKeyword("export");
+ expect("*");
+ if (!matchContextualKeyword("from")) {
+ throwError({}, lookahead.value ?
+ Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
+ }
+ lex();
+ src = parseModuleSpecifier();
+ consumeSemicolon();
+
+ return markerApply(marker, astNodeFactory.createExportAllDeclaration(src));
+}
+
+function parseExportDeclaration() {
+ if (state.inFunctionBody) {
+ throwError({}, Messages.IllegalExportDeclaration);
+ }
+ var declarationType = lookahead2().value;
+ if (declarationType === "default") {
+ return parseExportDefaultDeclaration();
+ } else if (declarationType === "*") {
+ return parseExportAllDeclaration();
+ } else {
+ return parseExportNamedDeclaration();
+ }
+}
+
+function parseImportSpecifier() {
+ // import {<foo as bar>} ...;
+ var local, imported, marker = markerCreate();
+
+ imported = parseNonComputedProperty();
+ if (matchContextualKeyword("as")) {
+ lex();
+ local = parseVariableIdentifier();
+ }
+
+ return markerApply(marker, astNodeFactory.createImportSpecifier(local, imported));
+}
+
+function parseNamedImports() {
+ var specifiers = [];
+ // {foo, bar as bas}
+ expect("{");
+ if (!match("}")) {
+ do {
+ specifiers.push(parseImportSpecifier());
+ } while (match(",") && lex());
+ }
+ expect("}");
+ return specifiers;
+}
+
+function parseImportDefaultSpecifier() {
+ // import <foo> ...;
+ var local, marker = markerCreate();
+
+ local = parseNonComputedProperty();
+
+ return markerApply(marker, astNodeFactory.createImportDefaultSpecifier(local));
+}
+
+function parseImportNamespaceSpecifier() {
+ // import <* as foo> ...;
+ var local, marker = markerCreate();
+
+ expect("*");
+ if (!matchContextualKeyword("as")) {
+ throwError({}, Messages.NoAsAfterImportNamespace);
+ }
+ lex();
+ local = parseNonComputedProperty();
+
+ return markerApply(marker, astNodeFactory.createImportNamespaceSpecifier(local));
+}
+
+function parseImportDeclaration() {
+ var specifiers, src, marker = markerCreate();
+
+ if (state.inFunctionBody) {
+ throwError({}, Messages.IllegalImportDeclaration);
+ }
+
+ expectKeyword("import");
+ specifiers = [];
+
+ if (lookahead.type === Token.StringLiteral) {
+ // covers:
+ // import "foo";
+ src = parseModuleSpecifier();
+ consumeSemicolon();
+ return markerApply(marker, astNodeFactory.createImportDeclaration(specifiers, src));
+ }
+
+ if (!matchKeyword("default") && isIdentifierName(lookahead)) {
+ // covers:
+ // import foo
+ // import foo, ...
+ specifiers.push(parseImportDefaultSpecifier());
+ if (match(",")) {
+ lex();
+ }
+ }
+ if (match("*")) {
+ // covers:
+ // import foo, * as foo
+ // import * as foo
+ specifiers.push(parseImportNamespaceSpecifier());
+ } else if (match("{")) {
+ // covers:
+ // import foo, {bar}
+ // import {bar}
+ specifiers = specifiers.concat(parseNamedImports());
+ }
+
+ if (!matchContextualKeyword("from")) {
+ throwError({}, lookahead.value ?
+ Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value);
+ }
+ lex();
+ src = parseModuleSpecifier();
+ consumeSemicolon();
+
+ return markerApply(marker, astNodeFactory.createImportDeclaration(specifiers, src));
+}
+
+// 14 Functions and classes
+
+// 14.1 Functions is defined above (13 in ES5)
+// 14.2 Arrow Functions Definitions is defined in (7.3 assignments)
+
+// 14.3 Method Definitions
+// 14.3.7
+
+// 14.5 Class Definitions
+
+function parseClassBody() {
+ var hasConstructor = false, generator = false,
+ allowGenerators = extra.ecmaFeatures.generators,
+ token, isStatic, body = [], method, computed, key;
+
+ var existingProps = {},
+ topMarker = markerCreate(),
+ marker;
+
+ existingProps.static = new StringMap();
+ existingProps.prototype = new StringMap();
+
+ expect("{");
+
+ while (!match("}")) {
+
+ // extra semicolons are fine
+ if (match(";")) {
+ lex();
+ continue;
+ }
+
+ token = lookahead;
+ isStatic = false;
+ generator = match("*");
+ computed = match("[");
+ marker = markerCreate();
+
+ if (generator) {
+ if (!allowGenerators) {
+ throwUnexpected(lookahead);
+ }
+ lex();
+ }
+
+ key = parseObjectPropertyKey();
+
+ // static generator methods
+ if (key.name === "static" && match("*")) {
+ if (!allowGenerators) {
+ throwUnexpected(lookahead);
+ }
+ generator = true;
+ lex();
+ }
+
+ if (key.name === "static" && lookaheadPropertyName()) {
+ token = lookahead;
+ isStatic = true;
+ computed = match("[");
+ key = parseObjectPropertyKey();
+ }
+
+ if (generator) {
+ method = parseGeneratorProperty(key, marker);
+ } else {
+ method = tryParseMethodDefinition(token, key, computed, marker, generator);
+ }
+
+ if (method) {
+ method.static = isStatic;
+ if (method.kind === "init") {
+ method.kind = "method";
+ }
+
+ if (!isStatic) {
+
+ if (!method.computed && (method.key.name || (method.key.value && method.key.value.toString())) === "constructor") {
+ if (method.kind !== "method" || !method.method || method.value.generator) {
+ throwUnexpected(token, Messages.ConstructorSpecialMethod);
+ }
+ if (hasConstructor) {
+ throwUnexpected(token, Messages.DuplicateConstructor);
+ } else {
+ hasConstructor = true;
+ }
+ method.kind = "constructor";
+ }
+ } else {
+ if (!method.computed && (method.key.name || method.key.value.toString()) === "prototype") {
+ throwUnexpected(token, Messages.StaticPrototype);
+ }
+ }
+ method.type = astNodeTypes.MethodDefinition;
+ delete method.method;
+ delete method.shorthand;
+ body.push(method);
+ } else {
+ throwUnexpected(lookahead);
+ }
+ }
+
+ lex();
+ return markerApply(topMarker, astNodeFactory.createClassBody(body));
+}
+
+function parseClassExpression() {
+ var id = null, superClass = null, marker = markerCreate(),
+ previousStrict = strict, classBody;
+
+ // classes run in strict mode
+ strict = true;
+
+ expectKeyword("class");
+
+ if (lookahead.type === Token.Identifier) {
+ id = parseVariableIdentifier();
+ }
+
+ if (matchKeyword("extends")) {
+ lex();
+ superClass = parseLeftHandSideExpressionAllowCall();
+ }
+
+ classBody = parseClassBody();
+ strict = previousStrict;
+
+ return markerApply(marker, astNodeFactory.createClassExpression(id, superClass, classBody));
+}
+
+function parseClassDeclaration(identifierIsOptional) {
+ var id = null, superClass = null, marker = markerCreate(),
+ previousStrict = strict, classBody;
+
+ // classes run in strict mode
+ strict = true;
+
+ expectKeyword("class");
+
+ if (!identifierIsOptional || lookahead.type === Token.Identifier) {
+ id = parseVariableIdentifier();
+ }
+
+ if (matchKeyword("extends")) {
+ lex();
+ superClass = parseLeftHandSideExpressionAllowCall();
+ }
+
+ classBody = parseClassBody();
+ strict = previousStrict;
+
+ return markerApply(marker, astNodeFactory.createClassDeclaration(id, superClass, classBody));
+}
+
+// 15 Program
+
+function parseSourceElement() {
+
+ var allowClasses = extra.ecmaFeatures.classes,
+ allowModules = extra.ecmaFeatures.modules,
+ allowBlockBindings = extra.ecmaFeatures.blockBindings;
+
+ if (lookahead.type === Token.Keyword) {
+ switch (lookahead.value) {
+ case "export":
+ if (!allowModules) {
+ throwErrorTolerant({}, Messages.IllegalExportDeclaration);
+ }
+ return parseExportDeclaration();
+ case "import":
+ if (!allowModules) {
+ throwErrorTolerant({}, Messages.IllegalImportDeclaration);
+ }
+ return parseImportDeclaration();
+ case "function":
+ return parseFunctionDeclaration();
+ case "class":
+ if (allowClasses) {
+ return parseClassDeclaration();
+ }
+ break;
+ case "const":
+ case "let":
+ if (allowBlockBindings) {
+ return parseConstLetDeclaration(lookahead.value);
+ }
+ /* falls through */
+ default:
+ return parseStatement();
+ }
+ }
+
+ if (lookahead.type !== Token.EOF) {
+ return parseStatement();
+ }
+}
+
+function parseSourceElements() {
+ var sourceElement, sourceElements = [], token, directive, firstRestricted;
+
+ while (index < length) {
+ token = lookahead;
+ if (token.type !== Token.StringLiteral) {
+ break;
+ }
+
+ sourceElement = parseSourceElement();
+ sourceElements.push(sourceElement);
+ if (sourceElement.expression.type !== astNodeTypes.Literal) {
+ // this is not directive
+ break;
+ }
+ directive = source.slice(token.range[0] + 1, token.range[1] - 1);
+ if (directive === "use strict") {
+ strict = true;
+ if (firstRestricted) {
+ throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
+ }
+ } else {
+ if (!firstRestricted && token.octal) {
+ firstRestricted = token;
+ }
+ }
+ }
+
+ while (index < length) {
+ sourceElement = parseSourceElement();
+ /* istanbul ignore if */
+ if (typeof sourceElement === "undefined") {
+ break;
+ }
+ sourceElements.push(sourceElement);
+ }
+ return sourceElements;
+}
+
+function parseProgram() {
+ var body,
+ marker,
+ isModule = !!extra.ecmaFeatures.modules;
+
+ skipComment();
+ peek();
+ marker = markerCreate();
+ strict = isModule;
+
+ body = parseSourceElements();
+ return markerApply(marker, astNodeFactory.createProgram(body, isModule ? "module" : "script"));
+}
+
+function filterTokenLocation() {
+ var i, entry, token, tokens = [];
+
+ for (i = 0; i < extra.tokens.length; ++i) {
+ entry = extra.tokens[i];
+ token = {
+ type: entry.type,
+ value: entry.value
+ };
+ if (entry.regex) {
+ token.regex = {
+ pattern: entry.regex.pattern,
+ flags: entry.regex.flags
+ };
+ }
+ if (extra.range) {
+ token.range = entry.range;
+ }
+ if (extra.loc) {
+ token.loc = entry.loc;
+ }
+ tokens.push(token);
+ }
+
+ extra.tokens = tokens;
+}
+
+//------------------------------------------------------------------------------
+// Tokenizer
+//------------------------------------------------------------------------------
+
+function tokenize(code, options) {
+ var toString,
+ tokens;
+
+ toString = String;
+ if (typeof code !== "string" && !(code instanceof String)) {
+ code = toString(code);
+ }
+
+ source = code;
+ index = 0;
+ lineNumber = (source.length > 0) ? 1 : 0;
+ lineStart = 0;
+ length = source.length;
+ lookahead = null;
+ state = {
+ allowIn: true,
+ labelSet: {},
+ parenthesisCount: 0,
+ inFunctionBody: false,
+ inIteration: false,
+ inSwitch: false,
+ lastCommentStart: -1,
+ yieldAllowed: false,
+ curlyStack: [],
+ curlyLastIndex: 0,
+ inJSXSpreadAttribute: false,
+ inJSXChild: false,
+ inJSXTag: false
+ };
+
+ extra = {
+ ecmaFeatures: defaultFeatures
+ };
+
+ // Options matching.
+ options = options || {};
+
+ // Of course we collect tokens here.
+ options.tokens = true;
+ extra.tokens = [];
+ extra.tokenize = true;
+
+ // The following two fields are necessary to compute the Regex tokens.
+ extra.openParenToken = -1;
+ extra.openCurlyToken = -1;
+
+ extra.range = (typeof options.range === "boolean") && options.range;
+ extra.loc = (typeof options.loc === "boolean") && options.loc;
+
+ if (typeof options.comment === "boolean" && options.comment) {
+ extra.comments = [];
+ }
+ if (typeof options.tolerant === "boolean" && options.tolerant) {
+ extra.errors = [];
+ }
+
+ // apply parsing flags
+ if (options.ecmaFeatures && typeof options.ecmaFeatures === "object") {
+ extra.ecmaFeatures = options.ecmaFeatures;
+ }
+
+ try {
+ peek();
+ if (lookahead.type === Token.EOF) {
+ return extra.tokens;
+ }
+
+ lex();
+ while (lookahead.type !== Token.EOF) {
+ try {
+ lex();
+ } catch (lexError) {
+ if (extra.errors) {
+ extra.errors.push(lexError);
+ // We have to break on the first error
+ // to avoid infinite loops.
+ break;
+ } else {
+ throw lexError;
+ }
+ }
+ }
+
+ filterTokenLocation();
+ tokens = extra.tokens;
+
+ if (typeof extra.comments !== "undefined") {
+ tokens.comments = extra.comments;
+ }
+ if (typeof extra.errors !== "undefined") {
+ tokens.errors = extra.errors;
+ }
+ } catch (e) {
+ throw e;
+ } finally {
+ extra = {};
+ }
+ return tokens;
+}
+
+//------------------------------------------------------------------------------
+// Parser
+//------------------------------------------------------------------------------
+
+function parse(code, options) {
+ var program, toString;
+
+ toString = String;
+ if (typeof code !== "string" && !(code instanceof String)) {
+ code = toString(code);
+ }
+
+ source = code;
+ index = 0;
+ lineNumber = (source.length > 0) ? 1 : 0;
+ lineStart = 0;
+ length = source.length;
+ lookahead = null;
+ state = {
+ allowIn: true,
+ labelSet: new StringMap(),
+ parenthesisCount: 0,
+ inFunctionBody: false,
+ inIteration: false,
+ inSwitch: false,
+ lastCommentStart: -1,
+ yieldAllowed: false,
+ curlyStack: [],
+ curlyLastIndex: 0,
+ inJSXSpreadAttribute: false,
+ inJSXChild: false,
+ inJSXTag: false
+ };
+
+ extra = {
+ ecmaFeatures: Object.create(defaultFeatures)
+ };
+
+ // for template strings
+ state.curlyStack = [];
+
+ if (typeof options !== "undefined") {
+ extra.range = (typeof options.range === "boolean") && options.range;
+ extra.loc = (typeof options.loc === "boolean") && options.loc;
+ extra.attachComment = (typeof options.attachComment === "boolean") && options.attachComment;
+
+ if (extra.loc && options.source !== null && options.source !== undefined) {
+ extra.source = toString(options.source);
+ }
+
+ if (typeof options.tokens === "boolean" && options.tokens) {
+ extra.tokens = [];
+ }
+ if (typeof options.comment === "boolean" && options.comment) {
+ extra.comments = [];
+ }
+ if (typeof options.tolerant === "boolean" && options.tolerant) {
+ extra.errors = [];
+ }
+ if (extra.attachComment) {
+ extra.range = true;
+ extra.comments = [];
+ commentAttachment.reset();
+ }
+
+ if (options.sourceType === "module") {
+ extra.ecmaFeatures = {
+ arrowFunctions: true,
+ blockBindings: true,
+ regexUFlag: true,
+ regexYFlag: true,
+ templateStrings: true,
+ binaryLiterals: true,
+ octalLiterals: true,
+ unicodeCodePointEscapes: true,
+ superInFunctions: true,
+ defaultParams: true,
+ restParams: true,
+ forOf: true,
+ objectLiteralComputedProperties: true,
+ objectLiteralShorthandMethods: true,
+ objectLiteralShorthandProperties: true,
+ objectLiteralDuplicateProperties: true,
+ generators: true,
+ destructuring: true,
+ classes: true,
+ modules: true
+ };
+ }
+
+ // apply parsing flags after sourceType to allow overriding
+ if (options.ecmaFeatures && typeof options.ecmaFeatures === "object") {
+
+ // if it's a module, augment the ecmaFeatures
+ if (options.sourceType === "module") {
+ Object.keys(options.ecmaFeatures).forEach(function(key) {
+ extra.ecmaFeatures[key] = options.ecmaFeatures[key];
+ });
+ } else {
+ extra.ecmaFeatures = options.ecmaFeatures;
+ }
+ }
+
+ }
+
+ try {
+ program = parseProgram();
+ if (typeof extra.comments !== "undefined") {
+ program.comments = extra.comments;
+ }
+ if (typeof extra.tokens !== "undefined") {
+ filterTokenLocation();
+ program.tokens = extra.tokens;
+ }
+ if (typeof extra.errors !== "undefined") {
+ program.errors = extra.errors;
+ }
+ } catch (e) {
+ throw e;
+ } finally {
+ extra = {};
+ }
+
+ return program;
+}
+
+//------------------------------------------------------------------------------
+// Public
+//------------------------------------------------------------------------------
+
+exports.version = require("./package.json").version;
+
+exports.tokenize = tokenize;
+
+exports.parse = parse;
+
+// Deep copy.
+/* istanbul ignore next */
+exports.Syntax = (function () {
+ var name, types = {};
+
+ if (typeof Object.create === "function") {
+ types = Object.create(null);
+ }
+
+ for (name in astNodeTypes) {
+ if (astNodeTypes.hasOwnProperty(name)) {
+ types[name] = astNodeTypes[name];
+ }
+ }
+
+ if (typeof Object.freeze === "function") {
+ Object.freeze(types);
+ }
+
+ return types;
+}());
+
+},{"./lib/ast-node-factory":62,"./lib/ast-node-types":63,"./lib/comment-attachment":64,"./lib/features":65,"./lib/messages":66,"./lib/string-map":67,"./lib/syntax":68,"./lib/token-info":69,"./lib/xhtml-entities":70,"./package.json":71}],62:[function(require,module,exports){
+/**
+ * @fileoverview A factory for creating AST nodes
+ * @author Fred K. Schott
+ * @copyright 2014 Fred K. Schott. All rights reserved.
+ * @copyright 2011-2013 Ariya Hidayat <ariya.hidayat@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+var astNodeTypes = require("./ast-node-types");
+
+//------------------------------------------------------------------------------
+// Public
+//------------------------------------------------------------------------------
+
+module.exports = {
+
+ /**
+ * Create an Array Expression ASTNode out of an array of elements
+ * @param {ASTNode[]} elements An array of ASTNode elements
+ * @returns {ASTNode} An ASTNode representing the entire array expression
+ */
+ createArrayExpression: function(elements) {
+ return {
+ type: astNodeTypes.ArrayExpression,
+ elements: elements
+ };
+ },
+
+ /**
+ * Create an Arrow Function Expression ASTNode
+ * @param {ASTNode} params The function arguments
+ * @param {ASTNode} body The function body
+ * @param {boolean} expression True if the arrow function is created via an expression.
+ * Always false for declarations, but kept here to be in sync with
+ * FunctionExpression objects.
+ * @returns {ASTNode} An ASTNode representing the entire arrow function expression
+ */
+ createArrowFunctionExpression: function (params, body, expression) {
+ return {
+ type: astNodeTypes.ArrowFunctionExpression,
+ id: null,
+ params: params,
+ body: body,
+ generator: false,
+ expression: expression
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of an assignment expression
+ * @param {ASTNode} operator The assignment operator
+ * @param {ASTNode} left The left operand
+ * @param {ASTNode} right The right operand
+ * @returns {ASTNode} An ASTNode representing the entire assignment expression
+ */
+ createAssignmentExpression: function(operator, left, right) {
+ return {
+ type: astNodeTypes.AssignmentExpression,
+ operator: operator,
+ left: left,
+ right: right
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of an assignment pattern (default parameters)
+ * @param {ASTNode} left The left operand
+ * @param {ASTNode} right The right operand
+ * @returns {ASTNode} An ASTNode representing the entire assignment pattern
+ */
+ createAssignmentPattern: function(left, right) {
+ return {
+ type: astNodeTypes.AssignmentPattern,
+ left: left,
+ right: right
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a binary expression
+ * @param {ASTNode} operator The assignment operator
+ * @param {ASTNode} left The left operand
+ * @param {ASTNode} right The right operand
+ * @returns {ASTNode} An ASTNode representing the entire binary expression
+ */
+ createBinaryExpression: function(operator, left, right) {
+ var type = (operator === "||" || operator === "&&") ? astNodeTypes.LogicalExpression :
+ astNodeTypes.BinaryExpression;
+ return {
+ type: type,
+ operator: operator,
+ left: left,
+ right: right
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a block statement
+ * @param {ASTNode} body The block statement body
+ * @returns {ASTNode} An ASTNode representing the entire block statement
+ */
+ createBlockStatement: function(body) {
+ return {
+ type: astNodeTypes.BlockStatement,
+ body: body
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a break statement
+ * @param {ASTNode} label The break statement label
+ * @returns {ASTNode} An ASTNode representing the break statement
+ */
+ createBreakStatement: function(label) {
+ return {
+ type: astNodeTypes.BreakStatement,
+ label: label
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a call expression
+ * @param {ASTNode} callee The function being called
+ * @param {ASTNode[]} args An array of ASTNodes representing the function call arguments
+ * @returns {ASTNode} An ASTNode representing the entire call expression
+ */
+ createCallExpression: function(callee, args) {
+ return {
+ type: astNodeTypes.CallExpression,
+ callee: callee,
+ "arguments": args
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a catch clause/block
+ * @param {ASTNode} param Any catch clause exeption/conditional parameter information
+ * @param {ASTNode} body The catch block body
+ * @returns {ASTNode} An ASTNode representing the entire catch clause
+ */
+ createCatchClause: function(param, body) {
+ return {
+ type: astNodeTypes.CatchClause,
+ param: param,
+ body: body
+ };
+ },
+
+ /**
+ * Creates an ASTNode representation of a class body.
+ * @param {ASTNode} body The node representing the body of the class.
+ * @returns {ASTNode} An ASTNode representing the class body.
+ */
+ createClassBody: function(body) {
+ return {
+ type: astNodeTypes.ClassBody,
+ body: body
+ };
+ },
+
+ createClassExpression: function(id, superClass, body) {
+ return {
+ type: astNodeTypes.ClassExpression,
+ id: id,
+ superClass: superClass,
+ body: body
+ };
+ },
+
+ createClassDeclaration: function(id, superClass, body) {
+ return {
+ type: astNodeTypes.ClassDeclaration,
+ id: id,
+ superClass: superClass,
+ body: body
+ };
+ },
+
+ createMethodDefinition: function(propertyType, kind, key, value, computed) {
+ return {
+ type: astNodeTypes.MethodDefinition,
+ key: key,
+ value: value,
+ kind: kind,
+ "static": propertyType === "static",
+ computed: computed
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a conditional expression
+ * @param {ASTNode} test The conditional to evaluate
+ * @param {ASTNode} consequent The code to be run if the test returns true
+ * @param {ASTNode} alternate The code to be run if the test returns false
+ * @returns {ASTNode} An ASTNode representing the entire conditional expression
+ */
+ createConditionalExpression: function(test, consequent, alternate) {
+ return {
+ type: astNodeTypes.ConditionalExpression,
+ test: test,
+ consequent: consequent,
+ alternate: alternate
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a continue statement
+ * @param {?ASTNode} label The optional continue label (null if not set)
+ * @returns {ASTNode} An ASTNode representing the continue statement
+ */
+ createContinueStatement: function(label) {
+ return {
+ type: astNodeTypes.ContinueStatement,
+ label: label
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a debugger statement
+ * @returns {ASTNode} An ASTNode representing the debugger statement
+ */
+ createDebuggerStatement: function() {
+ return {
+ type: astNodeTypes.DebuggerStatement
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of an empty statement
+ * @returns {ASTNode} An ASTNode representing an empty statement
+ */
+ createEmptyStatement: function() {
+ return {
+ type: astNodeTypes.EmptyStatement
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of an expression statement
+ * @param {ASTNode} expression The expression
+ * @returns {ASTNode} An ASTNode representing an expression statement
+ */
+ createExpressionStatement: function(expression) {
+ return {
+ type: astNodeTypes.ExpressionStatement,
+ expression: expression
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a while statement
+ * @param {ASTNode} test The while conditional
+ * @param {ASTNode} body The while loop body
+ * @returns {ASTNode} An ASTNode representing a while statement
+ */
+ createWhileStatement: function(test, body) {
+ return {
+ type: astNodeTypes.WhileStatement,
+ test: test,
+ body: body
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a do..while statement
+ * @param {ASTNode} test The do..while conditional
+ * @param {ASTNode} body The do..while loop body
+ * @returns {ASTNode} An ASTNode representing a do..while statement
+ */
+ createDoWhileStatement: function(test, body) {
+ return {
+ type: astNodeTypes.DoWhileStatement,
+ body: body,
+ test: test
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a for statement
+ * @param {ASTNode} init The initialization expression
+ * @param {ASTNode} test The conditional test expression
+ * @param {ASTNode} update The update expression
+ * @param {ASTNode} body The statement body
+ * @returns {ASTNode} An ASTNode representing a for statement
+ */
+ createForStatement: function(init, test, update, body) {
+ return {
+ type: astNodeTypes.ForStatement,
+ init: init,
+ test: test,
+ update: update,
+ body: body
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a for..in statement
+ * @param {ASTNode} left The left-side variable for the property name
+ * @param {ASTNode} right The right-side object
+ * @param {ASTNode} body The statement body
+ * @returns {ASTNode} An ASTNode representing a for..in statement
+ */
+ createForInStatement: function(left, right, body) {
+ return {
+ type: astNodeTypes.ForInStatement,
+ left: left,
+ right: right,
+ body: body,
+ each: false
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a for..of statement
+ * @param {ASTNode} left The left-side variable for the property value
+ * @param {ASTNode} right The right-side object
+ * @param {ASTNode} body The statement body
+ * @returns {ASTNode} An ASTNode representing a for..of statement
+ */
+ createForOfStatement: function(left, right, body) {
+ return {
+ type: astNodeTypes.ForOfStatement,
+ left: left,
+ right: right,
+ body: body
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a function declaration
+ * @param {ASTNode} id The function name
+ * @param {ASTNode} params The function arguments
+ * @param {ASTNode} body The function body
+ * @param {boolean} generator True if the function is a generator, false if not.
+ * @param {boolean} expression True if the function is created via an expression.
+ * Always false for declarations, but kept here to be in sync with
+ * FunctionExpression objects.
+ * @returns {ASTNode} An ASTNode representing a function declaration
+ */
+ createFunctionDeclaration: function (id, params, body, generator, expression) {
+ return {
+ type: astNodeTypes.FunctionDeclaration,
+ id: id,
+ params: params || [],
+ body: body,
+ generator: !!generator,
+ expression: !!expression
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a function expression
+ * @param {ASTNode} id The function name
+ * @param {ASTNode} params The function arguments
+ * @param {ASTNode} body The function body
+ * @param {boolean} generator True if the function is a generator, false if not.
+ * @param {boolean} expression True if the function is created via an expression.
+ * @returns {ASTNode} An ASTNode representing a function declaration
+ */
+ createFunctionExpression: function (id, params, body, generator, expression) {
+ return {
+ type: astNodeTypes.FunctionExpression,
+ id: id,
+ params: params || [],
+ body: body,
+ generator: !!generator,
+ expression: !!expression
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of an identifier
+ * @param {ASTNode} name The identifier name
+ * @returns {ASTNode} An ASTNode representing an identifier
+ */
+ createIdentifier: function(name) {
+ return {
+ type: astNodeTypes.Identifier,
+ name: name
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of an if statement
+ * @param {ASTNode} test The if conditional expression
+ * @param {ASTNode} consequent The consequent if statement to run
+ * @param {ASTNode} alternate the "else" alternate statement
+ * @returns {ASTNode} An ASTNode representing an if statement
+ */
+ createIfStatement: function(test, consequent, alternate) {
+ return {
+ type: astNodeTypes.IfStatement,
+ test: test,
+ consequent: consequent,
+ alternate: alternate
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a labeled statement
+ * @param {ASTNode} label The statement label
+ * @param {ASTNode} body The labeled statement body
+ * @returns {ASTNode} An ASTNode representing a labeled statement
+ */
+ createLabeledStatement: function(label, body) {
+ return {
+ type: astNodeTypes.LabeledStatement,
+ label: label,
+ body: body
+ };
+ },
+
+ /**
+ * Create an ASTNode literal from the source code
+ * @param {ASTNode} token The ASTNode token
+ * @param {string} source The source code to get the literal from
+ * @returns {ASTNode} An ASTNode representing the new literal
+ */
+ createLiteralFromSource: function(token, source) {
+ var node = {
+ type: astNodeTypes.Literal,
+ value: token.value,
+ raw: source.slice(token.range[0], token.range[1])
+ };
+
+ // regular expressions have regex properties
+ if (token.regex) {
+ node.regex = token.regex;
+ }
+
+ return node;
+ },
+
+ /**
+ * Create an ASTNode template element
+ * @param {Object} value Data on the element value
+ * @param {string} value.raw The raw template string
+ * @param {string} value.cooked The processed template string
+ * @param {boolean} tail True if this is the final element in a template string
+ * @returns {ASTNode} An ASTNode representing the template string element
+ */
+ createTemplateElement: function(value, tail) {
+ return {
+ type: astNodeTypes.TemplateElement,
+ value: value,
+ tail: tail
+ };
+ },
+
+ /**
+ * Create an ASTNode template literal
+ * @param {ASTNode[]} quasis An array of the template string elements
+ * @param {ASTNode[]} expressions An array of the template string expressions
+ * @returns {ASTNode} An ASTNode representing the template string
+ */
+ createTemplateLiteral: function(quasis, expressions) {
+ return {
+ type: astNodeTypes.TemplateLiteral,
+ quasis: quasis,
+ expressions: expressions
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a spread element
+ * @param {ASTNode} argument The array being spread
+ * @returns {ASTNode} An ASTNode representing a spread element
+ */
+ createSpreadElement: function(argument) {
+ return {
+ type: astNodeTypes.SpreadElement,
+ argument: argument
+ };
+ },
+
+ /**
+ * Create an ASTNode tagged template expression
+ * @param {ASTNode} tag The tag expression
+ * @param {ASTNode} quasi A TemplateLiteral ASTNode representing
+ * the template string itself.
+ * @returns {ASTNode} An ASTNode representing the tagged template
+ */
+ createTaggedTemplateExpression: function(tag, quasi) {
+ return {
+ type: astNodeTypes.TaggedTemplateExpression,
+ tag: tag,
+ quasi: quasi
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a member expression
+ * @param {string} accessor The member access method (bracket or period)
+ * @param {ASTNode} object The object being referenced
+ * @param {ASTNode} property The object-property being referenced
+ * @returns {ASTNode} An ASTNode representing a member expression
+ */
+ createMemberExpression: function(accessor, object, property) {
+ return {
+ type: astNodeTypes.MemberExpression,
+ computed: accessor === "[",
+ object: object,
+ property: property
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a new expression
+ * @param {ASTNode} callee The constructor for the new object type
+ * @param {ASTNode} args The arguments passed to the constructor
+ * @returns {ASTNode} An ASTNode representing a new expression
+ */
+ createNewExpression: function(callee, args) {
+ return {
+ type: astNodeTypes.NewExpression,
+ callee: callee,
+ "arguments": args
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a new object expression
+ * @param {ASTNode[]} properties An array of ASTNodes that represent all object
+ * properties and associated values
+ * @returns {ASTNode} An ASTNode representing a new object expression
+ */
+ createObjectExpression: function(properties) {
+ return {
+ type: astNodeTypes.ObjectExpression,
+ properties: properties
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a postfix expression
+ * @param {string} operator The postfix operator ("++", "--", etc.)
+ * @param {ASTNode} argument The operator argument
+ * @returns {ASTNode} An ASTNode representing a postfix expression
+ */
+ createPostfixExpression: function(operator, argument) {
+ return {
+ type: astNodeTypes.UpdateExpression,
+ operator: operator,
+ argument: argument,
+ prefix: false
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of an entire program
+ * @param {ASTNode} body The program body
+ * @param {string} sourceType Either "module" or "script".
+ * @returns {ASTNode} An ASTNode representing an entire program
+ */
+ createProgram: function(body, sourceType) {
+ return {
+ type: astNodeTypes.Program,
+ body: body,
+ sourceType: sourceType
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of an object property
+ * @param {string} kind The type of property represented ("get", "set", etc.)
+ * @param {ASTNode} key The property key
+ * @param {ASTNode} value The new property value
+ * @param {boolean} method True if the property is also a method (value is a function)
+ * @param {boolean} shorthand True if the property is shorthand
+ * @param {boolean} computed True if the property value has been computed
+ * @returns {ASTNode} An ASTNode representing an object property
+ */
+ createProperty: function(kind, key, value, method, shorthand, computed) {
+ return {
+ type: astNodeTypes.Property,
+ key: key,
+ value: value,
+ kind: kind,
+ method: method,
+ shorthand: shorthand,
+ computed: computed
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a rest element
+ * @param {ASTNode} argument The rest argument
+ * @returns {ASTNode} An ASTNode representing a rest element
+ */
+ createRestElement: function (argument) {
+ return {
+ type: astNodeTypes.RestElement,
+ argument: argument
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a return statement
+ * @param {?ASTNode} argument The return argument, null if no argument is provided
+ * @returns {ASTNode} An ASTNode representing a return statement
+ */
+ createReturnStatement: function(argument) {
+ return {
+ type: astNodeTypes.ReturnStatement,
+ argument: argument
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a sequence of expressions
+ * @param {ASTNode[]} expressions An array containing each expression, in order
+ * @returns {ASTNode} An ASTNode representing a sequence of expressions
+ */
+ createSequenceExpression: function(expressions) {
+ return {
+ type: astNodeTypes.SequenceExpression,
+ expressions: expressions
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of super
+ * @returns {ASTNode} An ASTNode representing super
+ */
+ createSuper: function() {
+ return {
+ type: astNodeTypes.Super
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a switch case statement
+ * @param {ASTNode} test The case value to test against the switch value
+ * @param {ASTNode} consequent The consequent case statement
+ * @returns {ASTNode} An ASTNode representing a switch case
+ */
+ createSwitchCase: function(test, consequent) {
+ return {
+ type: astNodeTypes.SwitchCase,
+ test: test,
+ consequent: consequent
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a switch statement
+ * @param {ASTNode} discriminant An expression to test against each case value
+ * @param {ASTNode[]} cases An array of switch case statements
+ * @returns {ASTNode} An ASTNode representing a switch statement
+ */
+ createSwitchStatement: function(discriminant, cases) {
+ return {
+ type: astNodeTypes.SwitchStatement,
+ discriminant: discriminant,
+ cases: cases
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a this statement
+ * @returns {ASTNode} An ASTNode representing a this statement
+ */
+ createThisExpression: function() {
+ return {
+ type: astNodeTypes.ThisExpression
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a throw statement
+ * @param {ASTNode} argument The argument to throw
+ * @returns {ASTNode} An ASTNode representing a throw statement
+ */
+ createThrowStatement: function(argument) {
+ return {
+ type: astNodeTypes.ThrowStatement,
+ argument: argument
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a try statement
+ * @param {ASTNode} block The try block
+ * @param {ASTNode} handler A catch handler
+ * @param {?ASTNode} finalizer The final code block to run after the try/catch has run
+ * @returns {ASTNode} An ASTNode representing a try statement
+ */
+ createTryStatement: function(block, handler, finalizer) {
+ return {
+ type: astNodeTypes.TryStatement,
+ block: block,
+ handler: handler,
+ finalizer: finalizer
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a unary expression
+ * @param {string} operator The unary operator
+ * @param {ASTNode} argument The unary operand
+ * @returns {ASTNode} An ASTNode representing a unary expression
+ */
+ createUnaryExpression: function(operator, argument) {
+ if (operator === "++" || operator === "--") {
+ return {
+ type: astNodeTypes.UpdateExpression,
+ operator: operator,
+ argument: argument,
+ prefix: true
+ };
+ }
+ return {
+ type: astNodeTypes.UnaryExpression,
+ operator: operator,
+ argument: argument,
+ prefix: true
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a variable declaration
+ * @param {ASTNode[]} declarations An array of variable declarations
+ * @param {string} kind The kind of variable created ("var", "let", etc.)
+ * @returns {ASTNode} An ASTNode representing a variable declaration
+ */
+ createVariableDeclaration: function(declarations, kind) {
+ return {
+ type: astNodeTypes.VariableDeclaration,
+ declarations: declarations,
+ kind: kind
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a variable declarator
+ * @param {ASTNode} id The variable ID
+ * @param {ASTNode} init The variable's initial value
+ * @returns {ASTNode} An ASTNode representing a variable declarator
+ */
+ createVariableDeclarator: function(id, init) {
+ return {
+ type: astNodeTypes.VariableDeclarator,
+ id: id,
+ init: init
+ };
+ },
+
+ /**
+ * Create an ASTNode representation of a with statement
+ * @param {ASTNode} object The with statement object expression
+ * @param {ASTNode} body The with statement body
+ * @returns {ASTNode} An ASTNode representing a with statement
+ */
+ createWithStatement: function(object, body) {
+ return {
+ type: astNodeTypes.WithStatement,
+ object: object,
+ body: body
+ };
+ },
+
+ createYieldExpression: function(argument, delegate) {
+ return {
+ type: astNodeTypes.YieldExpression,
+ argument: argument || null,
+ delegate: delegate
+ };
+ },
+
+ createJSXAttribute: function(name, value) {
+ return {
+ type: astNodeTypes.JSXAttribute,
+ name: name,
+ value: value || null
+ };
+ },
+
+ createJSXSpreadAttribute: function(argument) {
+ return {
+ type: astNodeTypes.JSXSpreadAttribute,
+ argument: argument
+ };
+ },
+
+ createJSXIdentifier: function(name) {
+ return {
+ type: astNodeTypes.JSXIdentifier,
+ name: name
+ };
+ },
+
+ createJSXNamespacedName: function(namespace, name) {
+ return {
+ type: astNodeTypes.JSXNamespacedName,
+ namespace: namespace,
+ name: name
+ };
+ },
+
+ createJSXMemberExpression: function(object, property) {
+ return {
+ type: astNodeTypes.JSXMemberExpression,
+ object: object,
+ property: property
+ };
+ },
+
+ createJSXElement: function(openingElement, closingElement, children) {
+ return {
+ type: astNodeTypes.JSXElement,
+ openingElement: openingElement,
+ closingElement: closingElement,
+ children: children
+ };
+ },
+
+ createJSXEmptyExpression: function() {
+ return {
+ type: astNodeTypes.JSXEmptyExpression
+ };
+ },
+
+ createJSXExpressionContainer: function(expression) {
+ return {
+ type: astNodeTypes.JSXExpressionContainer,
+ expression: expression
+ };
+ },
+
+ createJSXOpeningElement: function(name, attributes, selfClosing) {
+ return {
+ type: astNodeTypes.JSXOpeningElement,
+ name: name,
+ selfClosing: selfClosing,
+ attributes: attributes
+ };
+ },
+
+ createJSXClosingElement: function(name) {
+ return {
+ type: astNodeTypes.JSXClosingElement,
+ name: name
+ };
+ },
+
+ createExportSpecifier: function(local, exported) {
+ return {
+ type: astNodeTypes.ExportSpecifier,
+ exported: exported || local,
+ local: local
+ };
+ },
+
+ createImportDefaultSpecifier: function(local) {
+ return {
+ type: astNodeTypes.ImportDefaultSpecifier,
+ local: local
+ };
+ },
+
+ createImportNamespaceSpecifier: function(local) {
+ return {
+ type: astNodeTypes.ImportNamespaceSpecifier,
+ local: local
+ };
+ },
+
+ createExportNamedDeclaration: function(declaration, specifiers, source) {
+ return {
+ type: astNodeTypes.ExportNamedDeclaration,
+ declaration: declaration,
+ specifiers: specifiers,
+ source: source
+ };
+ },
+
+ createExportDefaultDeclaration: function(declaration) {
+ return {
+ type: astNodeTypes.ExportDefaultDeclaration,
+ declaration: declaration
+ };
+ },
+
+ createExportAllDeclaration: function(source) {
+ return {
+ type: astNodeTypes.ExportAllDeclaration,
+ source: source
+ };
+ },
+
+ createImportSpecifier: function(local, imported) {
+ return {
+ type: astNodeTypes.ImportSpecifier,
+ local: local || imported,
+ imported: imported
+ };
+ },
+
+ createImportDeclaration: function(specifiers, source) {
+ return {
+ type: astNodeTypes.ImportDeclaration,
+ specifiers: specifiers,
+ source: source
+ };
+ }
+
+};
+
+},{"./ast-node-types":63}],63:[function(require,module,exports){
+/**
+ * @fileoverview The AST node types produced by the parser.
+ * @author Nicholas C. Zakas
+ * @copyright 2014 Nicholas C. Zakas. All rights reserved.
+ * @copyright 2011-2013 Ariya Hidayat <ariya.hidayat@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+// None!
+
+//------------------------------------------------------------------------------
+// Public
+//------------------------------------------------------------------------------
+
+module.exports = {
+ AssignmentExpression: "AssignmentExpression",
+ AssignmentPattern: "AssignmentPattern",
+ ArrayExpression: "ArrayExpression",
+ ArrayPattern: "ArrayPattern",
+ ArrowFunctionExpression: "ArrowFunctionExpression",
+ BlockStatement: "BlockStatement",
+ BinaryExpression: "BinaryExpression",
+ BreakStatement: "BreakStatement",
+ CallExpression: "CallExpression",
+ CatchClause: "CatchClause",
+ ClassBody: "ClassBody",
+ ClassDeclaration: "ClassDeclaration",
+ ClassExpression: "ClassExpression",
+ ConditionalExpression: "ConditionalExpression",
+ ContinueStatement: "ContinueStatement",
+ DoWhileStatement: "DoWhileStatement",
+ DebuggerStatement: "DebuggerStatement",
+ EmptyStatement: "EmptyStatement",
+ ExpressionStatement: "ExpressionStatement",
+ ForStatement: "ForStatement",
+ ForInStatement: "ForInStatement",
+ ForOfStatement: "ForOfStatement",
+ FunctionDeclaration: "FunctionDeclaration",
+ FunctionExpression: "FunctionExpression",
+ Identifier: "Identifier",
+ IfStatement: "IfStatement",
+ Literal: "Literal",
+ LabeledStatement: "LabeledStatement",
+ LogicalExpression: "LogicalExpression",
+ MemberExpression: "MemberExpression",
+ MethodDefinition: "MethodDefinition",
+ NewExpression: "NewExpression",
+ ObjectExpression: "ObjectExpression",
+ ObjectPattern: "ObjectPattern",
+ Program: "Program",
+ Property: "Property",
+ RestElement: "RestElement",
+ ReturnStatement: "ReturnStatement",
+ SequenceExpression: "SequenceExpression",
+ SpreadElement: "SpreadElement",
+ Super: "Super",
+ SwitchCase: "SwitchCase",
+ SwitchStatement: "SwitchStatement",
+ TaggedTemplateExpression: "TaggedTemplateExpression",
+ TemplateElement: "TemplateElement",
+ TemplateLiteral: "TemplateLiteral",
+ ThisExpression: "ThisExpression",
+ ThrowStatement: "ThrowStatement",
+ TryStatement: "TryStatement",
+ UnaryExpression: "UnaryExpression",
+ UpdateExpression: "UpdateExpression",
+ VariableDeclaration: "VariableDeclaration",
+ VariableDeclarator: "VariableDeclarator",
+ WhileStatement: "WhileStatement",
+ WithStatement: "WithStatement",
+ YieldExpression: "YieldExpression",
+ JSXIdentifier: "JSXIdentifier",
+ JSXNamespacedName: "JSXNamespacedName",
+ JSXMemberExpression: "JSXMemberExpression",
+ JSXEmptyExpression: "JSXEmptyExpression",
+ JSXExpressionContainer: "JSXExpressionContainer",
+ JSXElement: "JSXElement",
+ JSXClosingElement: "JSXClosingElement",
+ JSXOpeningElement: "JSXOpeningElement",
+ JSXAttribute: "JSXAttribute",
+ JSXSpreadAttribute: "JSXSpreadAttribute",
+ JSXText: "JSXText",
+ ExportDefaultDeclaration: "ExportDefaultDeclaration",
+ ExportNamedDeclaration: "ExportNamedDeclaration",
+ ExportAllDeclaration: "ExportAllDeclaration",
+ ExportSpecifier: "ExportSpecifier",
+ ImportDeclaration: "ImportDeclaration",
+ ImportSpecifier: "ImportSpecifier",
+ ImportDefaultSpecifier: "ImportDefaultSpecifier",
+ ImportNamespaceSpecifier: "ImportNamespaceSpecifier"
+};
+
+},{}],64:[function(require,module,exports){
+/**
+ * @fileoverview Attaches comments to the AST.
+ * @author Nicholas C. Zakas
+ * @copyright 2015 Nicholas C. Zakas. All rights reserved.
+ * @copyright 2011-2013 Ariya Hidayat <ariya.hidayat@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+var astNodeTypes = require("./ast-node-types");
+
+//------------------------------------------------------------------------------
+// Private
+//------------------------------------------------------------------------------
+
+var extra = {
+ trailingComments: [],
+ leadingComments: [],
+ bottomRightStack: []
+ };
+
+//------------------------------------------------------------------------------
+// Public
+//------------------------------------------------------------------------------
+
+module.exports = {
+
+ reset: function() {
+ extra.trailingComments = [];
+ extra.leadingComments = [];
+ extra.bottomRightStack = [];
+ },
+
+ addComment: function(comment) {
+ extra.trailingComments.push(comment);
+ extra.leadingComments.push(comment);
+ },
+
+ processComment: function(node) {
+ var lastChild,
+ trailingComments,
+ i;
+
+ if (node.type === astNodeTypes.Program) {
+ if (node.body.length > 0) {
+ return;
+ }
+ }
+
+ if (extra.trailingComments.length > 0) {
+
+ /*
+ * If the first comment in trailingComments comes after the
+ * current node, then we're good - all comments in the array will
+ * come after the node and so it's safe to add then as official
+ * trailingComments.
+ */
+ if (extra.trailingComments[0].range[0] >= node.range[1]) {
+ trailingComments = extra.trailingComments;
+ extra.trailingComments = [];
+ } else {
+
+ /*
+ * Otherwise, if the first comment doesn't come after the
+ * current node, that means we have a mix of leading and trailing
+ * comments in the array and that leadingComments contains the
+ * same items as trailingComments. Reset trailingComments to
+ * zero items and we'll handle this by evaluating leadingComments
+ * later.
+ */
+ extra.trailingComments.length = 0;
+ }
+ } else {
+ if (extra.bottomRightStack.length > 0 &&
+ extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments &&
+ extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments[0].range[0] >= node.range[1]) {
+ trailingComments = extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments;
+ delete extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments;
+ }
+ }
+
+ // Eating the stack.
+ while (extra.bottomRightStack.length > 0 && extra.bottomRightStack[extra.bottomRightStack.length - 1].range[0] >= node.range[0]) {
+ lastChild = extra.bottomRightStack.pop();
+ }
+
+ if (lastChild) {
+ if (lastChild.leadingComments && lastChild.leadingComments[lastChild.leadingComments.length - 1].range[1] <= node.range[0]) {
+ node.leadingComments = lastChild.leadingComments;
+ delete lastChild.leadingComments;
+ }
+ } else if (extra.leadingComments.length > 0) {
+
+ if (extra.leadingComments[extra.leadingComments.length - 1].range[1] <= node.range[0]) {
+ node.leadingComments = extra.leadingComments;
+ extra.leadingComments = [];
+ } else {
+
+ // https://github.com/eslint/espree/issues/2
+
+ /*
+ * In special cases, such as return (without a value) and
+ * debugger, all comments will end up as leadingComments and
+ * will otherwise be eliminated. This extra step runs when the
+ * bottomRightStack is empty and there are comments left
+ * in leadingComments.
+ *
+ * This loop figures out the stopping point between the actual
+ * leading and trailing comments by finding the location of the
+ * first comment that comes after the given node.
+ */
+ for (i = 0; i < extra.leadingComments.length; i++) {
+ if (extra.leadingComments[i].range[1] > node.range[0]) {
+ break;
+ }
+ }
+
+ /*
+ * Split the array based on the location of the first comment
+ * that comes after the node. Keep in mind that this could
+ * result in an empty array, and if so, the array must be
+ * deleted.
+ */
+ node.leadingComments = extra.leadingComments.slice(0, i);
+ if (node.leadingComments.length === 0) {
+ delete node.leadingComments;
+ }
+
+ /*
+ * Similarly, trailing comments are attached later. The variable
+ * must be reset to null if there are no trailing comments.
+ */
+ trailingComments = extra.leadingComments.slice(i);
+ if (trailingComments.length === 0) {
+ trailingComments = null;
+ }
+ }
+ }
+
+ if (trailingComments) {
+ node.trailingComments = trailingComments;
+ }
+
+ extra.bottomRightStack.push(node);
+ }
+
+};
+
+},{"./ast-node-types":63}],65:[function(require,module,exports){
+/**
+ * @fileoverview The list of feature flags supported by the parser and their default
+ * settings.
+ * @author Nicholas C. Zakas
+ * @copyright 2015 Fred K. Schott. All rights reserved.
+ * @copyright 2014 Nicholas C. Zakas. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+// None!
+
+//------------------------------------------------------------------------------
+// Public
+//------------------------------------------------------------------------------
+
+module.exports = {
+
+ // enable parsing of arrow functions
+ arrowFunctions: false,
+
+ // enable parsing of let and const
+ blockBindings: true,
+
+ // enable parsing of destructured arrays and objects
+ destructuring: false,
+
+ // enable parsing of regex u flag
+ regexUFlag: false,
+
+ // enable parsing of regex y flag
+ regexYFlag: false,
+
+ // enable parsing of template strings
+ templateStrings: false,
+
+ // enable parsing binary literals
+ binaryLiterals: false,
+
+ // enable parsing ES6 octal literals
+ octalLiterals: false,
+
+ // enable parsing unicode code point escape sequences
+ unicodeCodePointEscapes: true,
+
+ // enable parsing of default parameters
+ defaultParams: false,
+
+ // enable parsing of rest parameters
+ restParams: false,
+
+ // enable parsing of for-of statements
+ forOf: false,
+
+ // enable parsing computed object literal properties
+ objectLiteralComputedProperties: false,
+
+ // enable parsing of shorthand object literal methods
+ objectLiteralShorthandMethods: false,
+
+ // enable parsing of shorthand object literal properties
+ objectLiteralShorthandProperties: false,
+
+ // Allow duplicate object literal properties (except '__proto__')
+ objectLiteralDuplicateProperties: false,
+
+ // enable parsing of generators/yield
+ generators: false,
+
+ // support the spread operator
+ spread: false,
+
+ // enable super in functions
+ superInFunctions: false,
+
+ // enable parsing of classes
+ classes: false,
+
+ // enable parsing of modules
+ modules: false,
+
+ // React JSX parsing
+ jsx: false,
+
+ // allow return statement in global scope
+ globalReturn: false
+};
+
+},{}],66:[function(require,module,exports){
+/**
+ * @fileoverview Error messages returned by the parser.
+ * @author Nicholas C. Zakas
+ * @copyright 2014 Nicholas C. Zakas. All rights reserved.
+ * @copyright 2011-2013 Ariya Hidayat <ariya.hidayat@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+// None!
+
+//------------------------------------------------------------------------------
+// Public
+//------------------------------------------------------------------------------
+
+// error messages should be identical to V8 where possible
+module.exports = {
+ UnexpectedToken: "Unexpected token %0",
+ UnexpectedNumber: "Unexpected number",
+ UnexpectedString: "Unexpected string",
+ UnexpectedIdentifier: "Unexpected identifier",
+ UnexpectedReserved: "Unexpected reserved word",
+ UnexpectedTemplate: "Unexpected quasi %0",
+ UnexpectedEOS: "Unexpected end of input",
+ NewlineAfterThrow: "Illegal newline after throw",
+ InvalidRegExp: "Invalid regular expression",
+ InvalidRegExpFlag: "Invalid regular expression flag",
+ UnterminatedRegExp: "Invalid regular expression: missing /",
+ InvalidLHSInAssignment: "Invalid left-hand side in assignment",
+ InvalidLHSInFormalsList: "Invalid left-hand side in formals list",
+ InvalidLHSInForIn: "Invalid left-hand side in for-in",
+ MultipleDefaultsInSwitch: "More than one default clause in switch statement",
+ NoCatchOrFinally: "Missing catch or finally after try",
+ NoUnintializedConst: "Const must be initialized",
+ UnknownLabel: "Undefined label '%0'",
+ Redeclaration: "%0 '%1' has already been declared",
+ IllegalContinue: "Illegal continue statement",
+ IllegalBreak: "Illegal break statement",
+ IllegalReturn: "Illegal return statement",
+ IllegalYield: "Illegal yield expression",
+ IllegalSpread: "Illegal spread element",
+ StrictModeWith: "Strict mode code may not include a with statement",
+ StrictCatchVariable: "Catch variable may not be eval or arguments in strict mode",
+ StrictVarName: "Variable name may not be eval or arguments in strict mode",
+ StrictParamName: "Parameter name eval or arguments is not allowed in strict mode",
+ StrictParamDupe: "Strict mode function may not have duplicate parameter names",
+ TemplateOctalLiteral: "Octal literals are not allowed in template strings.",
+ ParameterAfterRestParameter: "Rest parameter must be last formal parameter",
+ DefaultRestParameter: "Rest parameter can not have a default value",
+ ElementAfterSpreadElement: "Spread must be the final element of an element list",
+ ObjectPatternAsRestParameter: "Invalid rest parameter",
+ ObjectPatternAsSpread: "Invalid spread argument",
+ StrictFunctionName: "Function name may not be eval or arguments in strict mode",
+ StrictOctalLiteral: "Octal literals are not allowed in strict mode.",
+ StrictDelete: "Delete of an unqualified identifier in strict mode.",
+ StrictDuplicateProperty: "Duplicate data property in object literal not allowed in strict mode",
+ DuplicatePrototypeProperty: "Duplicate '__proto__' property in object literal are not allowed",
+ ConstructorSpecialMethod: "Class constructor may not be an accessor",
+ DuplicateConstructor: "A class may only have one constructor",
+ StaticPrototype: "Classes may not have static property named prototype",
+ AccessorDataProperty: "Object literal may not have data and accessor property with the same name",
+ AccessorGetSet: "Object literal may not have multiple get/set accessors with the same name",
+ StrictLHSAssignment: "Assignment to eval or arguments is not allowed in strict mode",
+ StrictLHSPostfix: "Postfix increment/decrement may not have eval or arguments operand in strict mode",
+ StrictLHSPrefix: "Prefix increment/decrement may not have eval or arguments operand in strict mode",
+ StrictReservedWord: "Use of future reserved word in strict mode",
+ InvalidJSXAttributeValue: "JSX value should be either an expression or a quoted JSX text",
+ ExpectedJSXClosingTag: "Expected corresponding JSX closing tag for %0",
+ AdjacentJSXElements: "Adjacent JSX elements must be wrapped in an enclosing tag",
+ MissingFromClause: "Missing from clause",
+ NoAsAfterImportNamespace: "Missing as after import *",
+ InvalidModuleSpecifier: "Invalid module specifier",
+ IllegalImportDeclaration: "Illegal import declaration",
+ IllegalExportDeclaration: "Illegal export declaration"
+};
+
+},{}],67:[function(require,module,exports){
+/**
+ * @fileoverview A simple map that helps avoid collisions on the Object prototype.
+ * @author Jamund Ferguson
+ * @copyright 2015 Jamund Ferguson. All rights reserved.
+ * @copyright 2011-2013 Ariya Hidayat <ariya.hidayat@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+"use strict";
+
+function StringMap() {
+ this.$data = {};
+}
+
+StringMap.prototype.get = function (key) {
+ key = "$" + key;
+ return this.$data[key];
+};
+
+StringMap.prototype.set = function (key, value) {
+ key = "$" + key;
+ this.$data[key] = value;
+ return this;
+};
+
+StringMap.prototype.has = function (key) {
+ key = "$" + key;
+ return Object.prototype.hasOwnProperty.call(this.$data, key);
+};
+
+StringMap.prototype.delete = function (key) {
+ key = "$" + key;
+ return delete this.$data[key];
+};
+
+module.exports = StringMap;
+
+},{}],68:[function(require,module,exports){
+/**
+ * @fileoverview Various syntax/pattern checks for parsing.
+ * @author Nicholas C. Zakas
+ * @copyright 2014 Nicholas C. Zakas. All rights reserved.
+ * @copyright 2011-2013 Ariya Hidayat <ariya.hidayat@gmail.com>
+ * @copyright 2012-2013 Mathias Bynens <mathias@qiwi.be>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+// None!
+
+//------------------------------------------------------------------------------
+// Private
+//------------------------------------------------------------------------------
+
+// See also tools/generate-identifier-regex.js.
+var Regex = {
+ NonAsciiIdentifierStart: new RegExp("[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]"),
+ NonAsciiIdentifierPart: new RegExp("[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0\u08A2-\u08AC\u08E4-\u08FE\u0900-\u0963\u0966-\u096F\u0971-\u0977\u0979-\u097F\u0981-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C82\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D02\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191C\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1D00-\u1DE6\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA697\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7B\uAA80-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE26\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]"),
+ LeadingZeros: new RegExp("^0+(?!$)")
+};
+
+//------------------------------------------------------------------------------
+// Public
+//------------------------------------------------------------------------------
+
+module.exports = {
+
+ Regex: Regex,
+
+ isDecimalDigit: function(ch) {
+ return (ch >= 48 && ch <= 57); // 0..9
+ },
+
+ isHexDigit: function(ch) {
+ return "0123456789abcdefABCDEF".indexOf(ch) >= 0;
+ },
+
+ isOctalDigit: function(ch) {
+ return "01234567".indexOf(ch) >= 0;
+ },
+
+ // 7.2 White Space
+
+ isWhiteSpace: function(ch) {
+ return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
+ (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0);
+ },
+
+ // 7.3 Line Terminators
+
+ isLineTerminator: function(ch) {
+ return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029);
+ },
+
+ // 7.6 Identifier Names and Identifiers
+
+ isIdentifierStart: function(ch) {
+ return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore)
+ (ch >= 0x41 && ch <= 0x5A) || // A..Z
+ (ch >= 0x61 && ch <= 0x7A) || // a..z
+ (ch === 0x5C) || // \ (backslash)
+ ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
+ },
+
+ isIdentifierPart: function(ch) {
+ return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore)
+ (ch >= 0x41 && ch <= 0x5A) || // A..Z
+ (ch >= 0x61 && ch <= 0x7A) || // a..z
+ (ch >= 0x30 && ch <= 0x39) || // 0..9
+ (ch === 0x5C) || // \ (backslash)
+ ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
+ },
+
+ // 7.6.1.2 Future Reserved Words
+
+ isFutureReservedWord: function(id) {
+ switch (id) {
+ case "class":
+ case "enum":
+ case "export":
+ case "extends":
+ case "import":
+ case "super":
+ return true;
+ default:
+ return false;
+ }
+ },
+
+ isStrictModeReservedWord: function(id) {
+ switch (id) {
+ case "implements":
+ case "interface":
+ case "package":
+ case "private":
+ case "protected":
+ case "public":
+ case "static":
+ case "yield":
+ case "let":
+ return true;
+ default:
+ return false;
+ }
+ },
+
+ isRestrictedWord: function(id) {
+ return id === "eval" || id === "arguments";
+ },
+
+ // 7.6.1.1 Keywords
+
+ isKeyword: function(id, strict, ecmaFeatures) {
+
+ if (strict && this.isStrictModeReservedWord(id)) {
+ return true;
+ }
+
+ // "const" is specialized as Keyword in V8.
+ // "yield" and "let" are for compatiblity with SpiderMonkey and ES.next.
+ // Some others are from future reserved words.
+
+ switch (id.length) {
+ case 2:
+ return (id === "if") || (id === "in") || (id === "do");
+ case 3:
+ return (id === "var") || (id === "for") || (id === "new") ||
+ (id === "try") || (id === "let");
+ case 4:
+ return (id === "this") || (id === "else") || (id === "case") ||
+ (id === "void") || (id === "with") || (id === "enum");
+ case 5:
+ return (id === "while") || (id === "break") || (id === "catch") ||
+ (id === "throw") || (id === "const") || (!ecmaFeatures.generators && id === "yield") ||
+ (id === "class") || (id === "super");
+ case 6:
+ return (id === "return") || (id === "typeof") || (id === "delete") ||
+ (id === "switch") || (id === "export") || (id === "import");
+ case 7:
+ return (id === "default") || (id === "finally") || (id === "extends");
+ case 8:
+ return (id === "function") || (id === "continue") || (id === "debugger");
+ case 10:
+ return (id === "instanceof");
+ default:
+ return false;
+ }
+ },
+
+ isJSXIdentifierStart: function(ch) {
+ // exclude backslash (\)
+ return (ch !== 92) && this.isIdentifierStart(ch);
+ },
+
+ isJSXIdentifierPart: function(ch) {
+ // exclude backslash (\) and add hyphen (-)
+ return (ch !== 92) && (ch === 45 || this.isIdentifierPart(ch));
+ }
+
+
+};
+
+},{}],69:[function(require,module,exports){
+/**
+ * @fileoverview Contains token information.
+ * @author Nicholas C. Zakas
+ * @copyright 2014 Nicholas C. Zakas. All rights reserved.
+ * @copyright 2013 Thaddee Tyl <thaddee.tyl@gmail.com>
+ * @copyright 2011-2013 Ariya Hidayat <ariya.hidayat@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+// None!
+
+//------------------------------------------------------------------------------
+// Private
+//------------------------------------------------------------------------------
+
+var Token = {
+ BooleanLiteral: 1,
+ EOF: 2,
+ Identifier: 3,
+ Keyword: 4,
+ NullLiteral: 5,
+ NumericLiteral: 6,
+ Punctuator: 7,
+ StringLiteral: 8,
+ RegularExpression: 9,
+ Template: 10,
+ JSXIdentifier: 11,
+ JSXText: 12
+};
+
+var TokenName = {};
+TokenName[Token.BooleanLiteral] = "Boolean";
+TokenName[Token.EOF] = "<end>";
+TokenName[Token.Identifier] = "Identifier";
+TokenName[Token.Keyword] = "Keyword";
+TokenName[Token.NullLiteral] = "Null";
+TokenName[Token.NumericLiteral] = "Numeric";
+TokenName[Token.Punctuator] = "Punctuator";
+TokenName[Token.StringLiteral] = "String";
+TokenName[Token.RegularExpression] = "RegularExpression";
+TokenName[Token.Template] = "Template";
+TokenName[Token.JSXIdentifier] = "JSXIdentifier";
+TokenName[Token.JSXText] = "JSXText";
+
+// A function following one of those tokens is an expression.
+var FnExprTokens = ["(", "{", "[", "in", "typeof", "instanceof", "new",
+ "return", "case", "delete", "throw", "void",
+ // assignment operators
+ "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=",
+ "&=", "|=", "^=", ",",
+ // binary/unary operators
+ "+", "-", "*", "/", "%", "++", "--", "<<", ">>", ">>>", "&",
+ "|", "^", "!", "~", "&&", "||", "?", ":", "===", "==", ">=",
+ "<=", "<", ">", "!=", "!=="];
+
+
+//------------------------------------------------------------------------------
+// Public
+//------------------------------------------------------------------------------
+
+module.exports = {
+ Token: Token,
+ TokenName: TokenName,
+ FnExprTokens: FnExprTokens
+};
+
+},{}],70:[function(require,module,exports){
+/**
+ * @fileoverview The list of XHTML entities that are valid in JSX.
+ * @author Nicholas C. Zakas
+ * @copyright 2014 Nicholas C. Zakas. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+// None!
+
+//------------------------------------------------------------------------------
+// Public
+//------------------------------------------------------------------------------
+
+module.exports = {
+ quot: "\u0022",
+ amp: "&",
+ apos: "\u0027",
+ lt: "<",
+ gt: ">",
+ nbsp: "\u00A0",
+ iexcl: "\u00A1",
+ cent: "\u00A2",
+ pound: "\u00A3",
+ curren: "\u00A4",
+ yen: "\u00A5",
+ brvbar: "\u00A6",
+ sect: "\u00A7",
+ uml: "\u00A8",
+ copy: "\u00A9",
+ ordf: "\u00AA",
+ laquo: "\u00AB",
+ not: "\u00AC",
+ shy: "\u00AD",
+ reg: "\u00AE",
+ macr: "\u00AF",
+ deg: "\u00B0",
+ plusmn: "\u00B1",
+ sup2: "\u00B2",
+ sup3: "\u00B3",
+ acute: "\u00B4",
+ micro: "\u00B5",
+ para: "\u00B6",
+ middot: "\u00B7",
+ cedil: "\u00B8",
+ sup1: "\u00B9",
+ ordm: "\u00BA",
+ raquo: "\u00BB",
+ frac14: "\u00BC",
+ frac12: "\u00BD",
+ frac34: "\u00BE",
+ iquest: "\u00BF",
+ Agrave: "\u00C0",
+ Aacute: "\u00C1",
+ Acirc: "\u00C2",
+ Atilde: "\u00C3",
+ Auml: "\u00C4",
+ Aring: "\u00C5",
+ AElig: "\u00C6",
+ Ccedil: "\u00C7",
+ Egrave: "\u00C8",
+ Eacute: "\u00C9",
+ Ecirc: "\u00CA",
+ Euml: "\u00CB",
+ Igrave: "\u00CC",
+ Iacute: "\u00CD",
+ Icirc: "\u00CE",
+ Iuml: "\u00CF",
+ ETH: "\u00D0",
+ Ntilde: "\u00D1",
+ Ograve: "\u00D2",
+ Oacute: "\u00D3",
+ Ocirc: "\u00D4",
+ Otilde: "\u00D5",
+ Ouml: "\u00D6",
+ times: "\u00D7",
+ Oslash: "\u00D8",
+ Ugrave: "\u00D9",
+ Uacute: "\u00DA",
+ Ucirc: "\u00DB",
+ Uuml: "\u00DC",
+ Yacute: "\u00DD",
+ THORN: "\u00DE",
+ szlig: "\u00DF",
+ agrave: "\u00E0",
+ aacute: "\u00E1",
+ acirc: "\u00E2",
+ atilde: "\u00E3",
+ auml: "\u00E4",
+ aring: "\u00E5",
+ aelig: "\u00E6",
+ ccedil: "\u00E7",
+ egrave: "\u00E8",
+ eacute: "\u00E9",
+ ecirc: "\u00EA",
+ euml: "\u00EB",
+ igrave: "\u00EC",
+ iacute: "\u00ED",
+ icirc: "\u00EE",
+ iuml: "\u00EF",
+ eth: "\u00F0",
+ ntilde: "\u00F1",
+ ograve: "\u00F2",
+ oacute: "\u00F3",
+ ocirc: "\u00F4",
+ otilde: "\u00F5",
+ ouml: "\u00F6",
+ divide: "\u00F7",
+ oslash: "\u00F8",
+ ugrave: "\u00F9",
+ uacute: "\u00FA",
+ ucirc: "\u00FB",
+ uuml: "\u00FC",
+ yacute: "\u00FD",
+ thorn: "\u00FE",
+ yuml: "\u00FF",
+ OElig: "\u0152",
+ oelig: "\u0153",
+ Scaron: "\u0160",
+ scaron: "\u0161",
+ Yuml: "\u0178",
+ fnof: "\u0192",
+ circ: "\u02C6",
+ tilde: "\u02DC",
+ Alpha: "\u0391",
+ Beta: "\u0392",
+ Gamma: "\u0393",
+ Delta: "\u0394",
+ Epsilon: "\u0395",
+ Zeta: "\u0396",
+ Eta: "\u0397",
+ Theta: "\u0398",
+ Iota: "\u0399",
+ Kappa: "\u039A",
+ Lambda: "\u039B",
+ Mu: "\u039C",
+ Nu: "\u039D",
+ Xi: "\u039E",
+ Omicron: "\u039F",
+ Pi: "\u03A0",
+ Rho: "\u03A1",
+ Sigma: "\u03A3",
+ Tau: "\u03A4",
+ Upsilon: "\u03A5",
+ Phi: "\u03A6",
+ Chi: "\u03A7",
+ Psi: "\u03A8",
+ Omega: "\u03A9",
+ alpha: "\u03B1",
+ beta: "\u03B2",
+ gamma: "\u03B3",
+ delta: "\u03B4",
+ epsilon: "\u03B5",
+ zeta: "\u03B6",
+ eta: "\u03B7",
+ theta: "\u03B8",
+ iota: "\u03B9",
+ kappa: "\u03BA",
+ lambda: "\u03BB",
+ mu: "\u03BC",
+ nu: "\u03BD",
+ xi: "\u03BE",
+ omicron: "\u03BF",
+ pi: "\u03C0",
+ rho: "\u03C1",
+ sigmaf: "\u03C2",
+ sigma: "\u03C3",
+ tau: "\u03C4",
+ upsilon: "\u03C5",
+ phi: "\u03C6",
+ chi: "\u03C7",
+ psi: "\u03C8",
+ omega: "\u03C9",
+ thetasym: "\u03D1",
+ upsih: "\u03D2",
+ piv: "\u03D6",
+ ensp: "\u2002",
+ emsp: "\u2003",
+ thinsp: "\u2009",
+ zwnj: "\u200C",
+ zwj: "\u200D",
+ lrm: "\u200E",
+ rlm: "\u200F",
+ ndash: "\u2013",
+ mdash: "\u2014",
+ lsquo: "\u2018",
+ rsquo: "\u2019",
+ sbquo: "\u201A",
+ ldquo: "\u201C",
+ rdquo: "\u201D",
+ bdquo: "\u201E",
+ dagger: "\u2020",
+ Dagger: "\u2021",
+ bull: "\u2022",
+ hellip: "\u2026",
+ permil: "\u2030",
+ prime: "\u2032",
+ Prime: "\u2033",
+ lsaquo: "\u2039",
+ rsaquo: "\u203A",
+ oline: "\u203E",
+ frasl: "\u2044",
+ euro: "\u20AC",
+ image: "\u2111",
+ weierp: "\u2118",
+ real: "\u211C",
+ trade: "\u2122",
+ alefsym: "\u2135",
+ larr: "\u2190",
+ uarr: "\u2191",
+ rarr: "\u2192",
+ darr: "\u2193",
+ harr: "\u2194",
+ crarr: "\u21B5",
+ lArr: "\u21D0",
+ uArr: "\u21D1",
+ rArr: "\u21D2",
+ dArr: "\u21D3",
+ hArr: "\u21D4",
+ forall: "\u2200",
+ part: "\u2202",
+ exist: "\u2203",
+ empty: "\u2205",
+ nabla: "\u2207",
+ isin: "\u2208",
+ notin: "\u2209",
+ ni: "\u220B",
+ prod: "\u220F",
+ sum: "\u2211",
+ minus: "\u2212",
+ lowast: "\u2217",
+ radic: "\u221A",
+ prop: "\u221D",
+ infin: "\u221E",
+ ang: "\u2220",
+ and: "\u2227",
+ or: "\u2228",
+ cap: "\u2229",
+ cup: "\u222A",
+ "int": "\u222B",
+ there4: "\u2234",
+ sim: "\u223C",
+ cong: "\u2245",
+ asymp: "\u2248",
+ ne: "\u2260",
+ equiv: "\u2261",
+ le: "\u2264",
+ ge: "\u2265",
+ sub: "\u2282",
+ sup: "\u2283",
+ nsub: "\u2284",
+ sube: "\u2286",
+ supe: "\u2287",
+ oplus: "\u2295",
+ otimes: "\u2297",
+ perp: "\u22A5",
+ sdot: "\u22C5",
+ lceil: "\u2308",
+ rceil: "\u2309",
+ lfloor: "\u230A",
+ rfloor: "\u230B",
+ lang: "\u2329",
+ rang: "\u232A",
+ loz: "\u25CA",
+ spades: "\u2660",
+ clubs: "\u2663",
+ hearts: "\u2665",
+ diams: "\u2666"
+};
+
+},{}],71:[function(require,module,exports){
+module.exports={
+ "name": "espree",
+ "description": "An actively-maintained fork of Esprima, the ECMAScript parsing infrastructure for multipurpose analysis",
+ "author": {
+ "name": "Nicholas C. Zakas",
+ "email": "nicholas+npm@nczconsulting.com"
+ },
+ "homepage": "https://github.com/eslint/espree",
+ "main": "espree.js",
+ "bin": {
+ "esparse": "./bin/esparse.js",
+ "esvalidate": "./bin/esvalidate.js"
+ },
+ "version": "2.0.3",
+ "files": [
+ "bin",
+ "lib",
+ "test/run.js",
+ "test/runner.js",
+ "test/test.js",
+ "test/compat.js",
+ "test/reflect.js",
+ "espree.js"
+ ],
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/eslint/espree.git"
+ },
+ "bugs": {
+ "url": "http://github.com/eslint/espree.git"
+ },
+ "licenses": [
+ {
+ "type": "BSD",
+ "url": "http://github.com/nzakas/espree/raw/master/LICENSE"
+ }
+ ],
+ "devDependencies": {
+ "browserify": "^7.0.0",
+ "chai": "^1.10.0",
+ "complexity-report": "~0.6.1",
+ "dateformat": "^1.0.11",
+ "eslint": "^0.9.2",
+ "esprima": "git://github.com/jquery/esprima",
+ "esprima-fb": "^8001.2001.0-dev-harmony-fb",
+ "istanbul": "~0.2.6",
+ "json-diff": "~0.3.1",
+ "leche": "^1.0.1",
+ "mocha": "^2.0.1",
+ "npm-license": "^0.2.3",
+ "optimist": "~0.6.0",
+ "regenerate": "~0.5.4",
+ "semver": "^4.1.1",
+ "shelljs": "^0.3.0",
+ "shelljs-nodecli": "^0.1.1",
+ "unicode-6.3.0": "~0.1.0"
+ },
+ "keywords": [
+ "ast",
+ "ecmascript",
+ "javascript",
+ "parser",
+ "syntax"
+ ],
+ "scripts": {
+ "generate-regex": "node tools/generate-identifier-regex.js",
+ "test": "npm run-script lint && node Makefile.js test && node test/run.js",
+ "lint": "node Makefile.js lint",
+ "patch": "node Makefile.js patch",
+ "minor": "node Makefile.js minor",
+ "major": "node Makefile.js major",
+ "browserify": "node Makefile.js browserify",
+ "coverage": "npm run-script analyze-coverage && npm run-script check-coverage",
+ "analyze-coverage": "node node_modules/istanbul/lib/cli.js cover test/runner.js",
+ "check-coverage": "node node_modules/istanbul/lib/cli.js check-coverage --statement 99 --branch 99 --function 99",
+ "complexity": "npm run-script analyze-complexity && npm run-script check-complexity",
+ "analyze-complexity": "node tools/list-complexity.js",
+ "check-complexity": "node node_modules/complexity-report/src/cli.js --maxcc 14 --silent -l -w espree.js",
+ "benchmark": "node test/benchmarks.js",
+ "benchmark-quick": "node test/benchmarks.js quick"
+ },
+ "dependencies": {},
+ "gitHead": "b60b597cfe4834aacd16c90179ce73e22705c132",
+ "_id": "espree@2.0.3",
+ "_shasum": "1fbdff60a410bd0d416b1ab3d6230d34b7a450e1",
+ "_from": "espree@>=2.0.1 <3.0.0",
+ "_npmVersion": "1.4.28",
+ "_npmUser": {
+ "name": "nzakas",
+ "email": "nicholas@nczconsulting.com"
+ },
+ "maintainers": [
+ {
+ "name": "nzakas",
+ "email": "nicholas@nczconsulting.com"
+ }
+ ],
+ "dist": {
+ "shasum": "1fbdff60a410bd0d416b1ab3d6230d34b7a450e1",
+ "tarball": "http://registry.npmjs.org/espree/-/espree-2.0.3.tgz"
+ },
+ "directories": {},
+ "_resolved": "https://registry.npmjs.org/espree/-/espree-2.0.3.tgz",
+ "readme": "ERROR: No README data found!"
+}
+
+},{}],72:[function(require,module,exports){
+/*
+ Copyright (C) 2012-2013 Yusuke Suzuki <utatane.tea@gmail.com>
+ Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*jslint vars:false, bitwise:true*/
+/*jshint indent:4*/
+/*global exports:true*/
+(function clone(exports) {
+ 'use strict';
+
+ var Syntax,
+ isArray,
+ VisitorOption,
+ VisitorKeys,
+ objectCreate,
+ objectKeys,
+ BREAK,
+ SKIP,
+ REMOVE;
+
+ function ignoreJSHintError() { }
+
+ isArray = Array.isArray;
+ if (!isArray) {
+ isArray = function isArray(array) {
+ return Object.prototype.toString.call(array) === '[object Array]';
+ };
+ }
+
+ function deepCopy(obj) {
+ var ret = {}, key, val;
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ val = obj[key];
+ if (typeof val === 'object' && val !== null) {
+ ret[key] = deepCopy(val);
+ } else {
+ ret[key] = val;
+ }
+ }
+ }
+ return ret;
+ }
+
+ function shallowCopy(obj) {
+ var ret = {}, key;
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ ret[key] = obj[key];
+ }
+ }
+ return ret;
+ }
+ ignoreJSHintError(shallowCopy);
+
+ // based on LLVM libc++ upper_bound / lower_bound
+ // MIT License
+
+ function upperBound(array, func) {
+ var diff, len, i, current;
+
+ len = array.length;
+ i = 0;
+
+ while (len) {
+ diff = len >>> 1;
+ current = i + diff;
+ if (func(array[current])) {
+ len = diff;
+ } else {
+ i = current + 1;
+ len -= diff + 1;
+ }
+ }
+ return i;
+ }
+
+ function lowerBound(array, func) {
+ var diff, len, i, current;
+
+ len = array.length;
+ i = 0;
+
+ while (len) {
+ diff = len >>> 1;
+ current = i + diff;
+ if (func(array[current])) {
+ i = current + 1;
+ len -= diff + 1;
+ } else {
+ len = diff;
+ }
+ }
+ return i;
+ }
+ ignoreJSHintError(lowerBound);
+
+ objectCreate = Object.create || (function () {
+ function F() { }
+
+ return function (o) {
+ F.prototype = o;
+ return new F();
+ };
+ })();
+
+ objectKeys = Object.keys || function (o) {
+ var keys = [], key;
+ for (key in o) {
+ keys.push(key);
+ }
+ return keys;
+ };
+
+ function extend(to, from) {
+ var keys = objectKeys(from), key, i, len;
+ for (i = 0, len = keys.length; i < len; i += 1) {
+ key = keys[i];
+ to[key] = from[key];
+ }
+ return to;
+ }
+
+ Syntax = {
+ AssignmentExpression: 'AssignmentExpression',
+ AssignmentPattern: 'AssignmentPattern',
+ ArrayExpression: 'ArrayExpression',
+ ArrayPattern: 'ArrayPattern',
+ ArrowFunctionExpression: 'ArrowFunctionExpression',
+ AwaitExpression: 'AwaitExpression', // CAUTION: It's deferred to ES7.
+ BlockStatement: 'BlockStatement',
+ BinaryExpression: 'BinaryExpression',
+ BreakStatement: 'BreakStatement',
+ CallExpression: 'CallExpression',
+ CatchClause: 'CatchClause',
+ ClassBody: 'ClassBody',
+ ClassDeclaration: 'ClassDeclaration',
+ ClassExpression: 'ClassExpression',
+ ComprehensionBlock: 'ComprehensionBlock', // CAUTION: It's deferred to ES7.
+ ComprehensionExpression: 'ComprehensionExpression', // CAUTION: It's deferred to ES7.
+ ConditionalExpression: 'ConditionalExpression',
+ ContinueStatement: 'ContinueStatement',
+ DebuggerStatement: 'DebuggerStatement',
+ DirectiveStatement: 'DirectiveStatement',
+ DoWhileStatement: 'DoWhileStatement',
+ EmptyStatement: 'EmptyStatement',
+ ExportAllDeclaration: 'ExportAllDeclaration',
+ ExportDefaultDeclaration: 'ExportDefaultDeclaration',
+ ExportNamedDeclaration: 'ExportNamedDeclaration',
+ ExportSpecifier: 'ExportSpecifier',
+ ExpressionStatement: 'ExpressionStatement',
+ ForStatement: 'ForStatement',
+ ForInStatement: 'ForInStatement',
+ ForOfStatement: 'ForOfStatement',
+ FunctionDeclaration: 'FunctionDeclaration',
+ FunctionExpression: 'FunctionExpression',
+ GeneratorExpression: 'GeneratorExpression', // CAUTION: It's deferred to ES7.
+ Identifier: 'Identifier',
+ IfStatement: 'IfStatement',
+ ImportDeclaration: 'ImportDeclaration',
+ ImportDefaultSpecifier: 'ImportDefaultSpecifier',
+ ImportNamespaceSpecifier: 'ImportNamespaceSpecifier',
+ ImportSpecifier: 'ImportSpecifier',
+ Literal: 'Literal',
+ LabeledStatement: 'LabeledStatement',
+ LogicalExpression: 'LogicalExpression',
+ MemberExpression: 'MemberExpression',
+ MethodDefinition: 'MethodDefinition',
+ ModuleSpecifier: 'ModuleSpecifier',
+ NewExpression: 'NewExpression',
+ ObjectExpression: 'ObjectExpression',
+ ObjectPattern: 'ObjectPattern',
+ Program: 'Program',
+ Property: 'Property',
+ RestElement: 'RestElement',
+ ReturnStatement: 'ReturnStatement',
+ SequenceExpression: 'SequenceExpression',
+ SpreadElement: 'SpreadElement',
+ SuperExpression: 'SuperExpression',
+ SwitchStatement: 'SwitchStatement',
+ SwitchCase: 'SwitchCase',
+ TaggedTemplateExpression: 'TaggedTemplateExpression',
+ TemplateElement: 'TemplateElement',
+ TemplateLiteral: 'TemplateLiteral',
+ ThisExpression: 'ThisExpression',
+ ThrowStatement: 'ThrowStatement',
+ TryStatement: 'TryStatement',
+ UnaryExpression: 'UnaryExpression',
+ UpdateExpression: 'UpdateExpression',
+ VariableDeclaration: 'VariableDeclaration',
+ VariableDeclarator: 'VariableDeclarator',
+ WhileStatement: 'WhileStatement',
+ WithStatement: 'WithStatement',
+ YieldExpression: 'YieldExpression'
+ };
+
+ VisitorKeys = {
+ AssignmentExpression: ['left', 'right'],
+ AssignmentPattern: ['left', 'right'],
+ ArrayExpression: ['elements'],
+ ArrayPattern: ['elements'],
+ ArrowFunctionExpression: ['params', 'body'],
+ AwaitExpression: ['argument'], // CAUTION: It's deferred to ES7.
+ BlockStatement: ['body'],
+ BinaryExpression: ['left', 'right'],
+ BreakStatement: ['label'],
+ CallExpression: ['callee', 'arguments'],
+ CatchClause: ['param', 'body'],
+ ClassBody: ['body'],
+ ClassDeclaration: ['id', 'superClass', 'body'],
+ ClassExpression: ['id', 'superClass', 'body'],
+ ComprehensionBlock: ['left', 'right'], // CAUTION: It's deferred to ES7.
+ ComprehensionExpression: ['blocks', 'filter', 'body'], // CAUTION: It's deferred to ES7.
+ ConditionalExpression: ['test', 'consequent', 'alternate'],
+ ContinueStatement: ['label'],
+ DebuggerStatement: [],
+ DirectiveStatement: [],
+ DoWhileStatement: ['body', 'test'],
+ EmptyStatement: [],
+ ExportAllDeclaration: ['source'],
+ ExportDefaultDeclaration: ['declaration'],
+ ExportNamedDeclaration: ['declaration', 'specifiers', 'source'],
+ ExportSpecifier: ['exported', 'local'],
+ ExpressionStatement: ['expression'],
+ ForStatement: ['init', 'test', 'update', 'body'],
+ ForInStatement: ['left', 'right', 'body'],
+ ForOfStatement: ['left', 'right', 'body'],
+ FunctionDeclaration: ['id', 'params', 'body'],
+ FunctionExpression: ['id', 'params', 'body'],
+ GeneratorExpression: ['blocks', 'filter', 'body'], // CAUTION: It's deferred to ES7.
+ Identifier: [],
+ IfStatement: ['test', 'consequent', 'alternate'],
+ ImportDeclaration: ['specifiers', 'source'],
+ ImportDefaultSpecifier: ['local'],
+ ImportNamespaceSpecifier: ['local'],
+ ImportSpecifier: ['imported', 'local'],
+ Literal: [],
+ LabeledStatement: ['label', 'body'],
+ LogicalExpression: ['left', 'right'],
+ MemberExpression: ['object', 'property'],
+ MethodDefinition: ['key', 'value'],
+ ModuleSpecifier: [],
+ NewExpression: ['callee', 'arguments'],
+ ObjectExpression: ['properties'],
+ ObjectPattern: ['properties'],
+ Program: ['body'],
+ Property: ['key', 'value'],
+ RestElement: [ 'argument' ],
+ ReturnStatement: ['argument'],
+ SequenceExpression: ['expressions'],
+ SpreadElement: ['argument'],
+ SuperExpression: ['super'],
+ SwitchStatement: ['discriminant', 'cases'],
+ SwitchCase: ['test', 'consequent'],
+ TaggedTemplateExpression: ['tag', 'quasi'],
+ TemplateElement: [],
+ TemplateLiteral: ['quasis', 'expressions'],
+ ThisExpression: [],
+ ThrowStatement: ['argument'],
+ TryStatement: ['block', 'handler', 'finalizer'],
+ UnaryExpression: ['argument'],
+ UpdateExpression: ['argument'],
+ VariableDeclaration: ['declarations'],
+ VariableDeclarator: ['id', 'init'],
+ WhileStatement: ['test', 'body'],
+ WithStatement: ['object', 'body'],
+ YieldExpression: ['argument']
+ };
+
+ // unique id
+ BREAK = {};
+ SKIP = {};
+ REMOVE = {};
+
+ VisitorOption = {
+ Break: BREAK,
+ Skip: SKIP,
+ Remove: REMOVE
+ };
+
+ function Reference(parent, key) {
+ this.parent = parent;
+ this.key = key;
+ }
+
+ Reference.prototype.replace = function replace(node) {
+ this.parent[this.key] = node;
+ };
+
+ Reference.prototype.remove = function remove() {
+ if (isArray(this.parent)) {
+ this.parent.splice(this.key, 1);
+ return true;
+ } else {
+ this.replace(null);
+ return false;
+ }
+ };
+
+ function Element(node, path, wrap, ref) {
+ this.node = node;
+ this.path = path;
+ this.wrap = wrap;
+ this.ref = ref;
+ }
+
+ function Controller() { }
+
+ // API:
+ // return property path array from root to current node
+ Controller.prototype.path = function path() {
+ var i, iz, j, jz, result, element;
+
+ function addToPath(result, path) {
+ if (isArray(path)) {
+ for (j = 0, jz = path.length; j < jz; ++j) {
+ result.push(path[j]);
+ }
+ } else {
+ result.push(path);
+ }
+ }
+
+ // root node
+ if (!this.__current.path) {
+ return null;
+ }
+
+ // first node is sentinel, second node is root element
+ result = [];
+ for (i = 2, iz = this.__leavelist.length; i < iz; ++i) {
+ element = this.__leavelist[i];
+ addToPath(result, element.path);
+ }
+ addToPath(result, this.__current.path);
+ return result;
+ };
+
+ // API:
+ // return type of current node
+ Controller.prototype.type = function () {
+ var node = this.current();
+ return node.type || this.__current.wrap;
+ };
+
+ // API:
+ // return array of parent elements
+ Controller.prototype.parents = function parents() {
+ var i, iz, result;
+
+ // first node is sentinel
+ result = [];
+ for (i = 1, iz = this.__leavelist.length; i < iz; ++i) {
+ result.push(this.__leavelist[i].node);
+ }
+
+ return result;
+ };
+
+ // API:
+ // return current node
+ Controller.prototype.current = function current() {
+ return this.__current.node;
+ };
+
+ Controller.prototype.__execute = function __execute(callback, element) {
+ var previous, result;
+
+ result = undefined;
+
+ previous = this.__current;
+ this.__current = element;
+ this.__state = null;
+ if (callback) {
+ result = callback.call(this, element.node, this.__leavelist[this.__leavelist.length - 1].node);
+ }
+ this.__current = previous;
+
+ return result;
+ };
+
+ // API:
+ // notify control skip / break
+ Controller.prototype.notify = function notify(flag) {
+ this.__state = flag;
+ };
+
+ // API:
+ // skip child nodes of current node
+ Controller.prototype.skip = function () {
+ this.notify(SKIP);
+ };
+
+ // API:
+ // break traversals
+ Controller.prototype['break'] = function () {
+ this.notify(BREAK);
+ };
+
+ // API:
+ // remove node
+ Controller.prototype.remove = function () {
+ this.notify(REMOVE);
+ };
+
+ Controller.prototype.__initialize = function(root, visitor) {
+ this.visitor = visitor;
+ this.root = root;
+ this.__worklist = [];
+ this.__leavelist = [];
+ this.__current = null;
+ this.__state = null;
+ this.__fallback = visitor.fallback === 'iteration';
+ this.__keys = VisitorKeys;
+ if (visitor.keys) {
+ this.__keys = extend(objectCreate(this.__keys), visitor.keys);
+ }
+ };
+
+ function isNode(node) {
+ if (node == null) {
+ return false;
+ }
+ return typeof node === 'object' && typeof node.type === 'string';
+ }
+
+ function isProperty(nodeType, key) {
+ return (nodeType === Syntax.ObjectExpression || nodeType === Syntax.ObjectPattern) && 'properties' === key;
+ }
+
+ Controller.prototype.traverse = function traverse(root, visitor) {
+ var worklist,
+ leavelist,
+ element,
+ node,
+ nodeType,
+ ret,
+ key,
+ current,
+ current2,
+ candidates,
+ candidate,
+ sentinel;
+
+ this.__initialize(root, visitor);
+
+ sentinel = {};
+
+ // reference
+ worklist = this.__worklist;
+ leavelist = this.__leavelist;
+
+ // initialize
+ worklist.push(new Element(root, null, null, null));
+ leavelist.push(new Element(null, null, null, null));
+
+ while (worklist.length) {
+ element = worklist.pop();
+
+ if (element === sentinel) {
+ element = leavelist.pop();
+
+ ret = this.__execute(visitor.leave, element);
+
+ if (this.__state === BREAK || ret === BREAK) {
+ return;
+ }
+ continue;
+ }
+
+ if (element.node) {
+
+ ret = this.__execute(visitor.enter, element);
+
+ if (this.__state === BREAK || ret === BREAK) {
+ return;
+ }
+
+ worklist.push(sentinel);
+ leavelist.push(element);
+
+ if (this.__state === SKIP || ret === SKIP) {
+ continue;
+ }
+
+ node = element.node;
+ nodeType = element.wrap || node.type;
+ candidates = this.__keys[nodeType];
+ if (!candidates) {
+ if (this.__fallback) {
+ candidates = objectKeys(node);
+ } else {
+ throw new Error('Unknown node type ' + nodeType + '.');
+ }
+ }
+
+ current = candidates.length;
+ while ((current -= 1) >= 0) {
+ key = candidates[current];
+ candidate = node[key];
+ if (!candidate) {
+ continue;
+ }
+
+ if (isArray(candidate)) {
+ current2 = candidate.length;
+ while ((current2 -= 1) >= 0) {
+ if (!candidate[current2]) {
+ continue;
+ }
+ if (isProperty(nodeType, candidates[current])) {
+ element = new Element(candidate[current2], [key, current2], 'Property', null);
+ } else if (isNode(candidate[current2])) {
+ element = new Element(candidate[current2], [key, current2], null, null);
+ } else {
+ continue;
+ }
+ worklist.push(element);
+ }
+ } else if (isNode(candidate)) {
+ worklist.push(new Element(candidate, key, null, null));
+ }
+ }
+ }
+ }
+ };
+
+ Controller.prototype.replace = function replace(root, visitor) {
+ function removeElem(element) {
+ var i,
+ key,
+ nextElem,
+ parent;
+
+ if (element.ref.remove()) {
+ // When the reference is an element of an array.
+ key = element.ref.key;
+ parent = element.ref.parent;
+
+ // If removed from array, then decrease following items' keys.
+ i = worklist.length;
+ while (i--) {
+ nextElem = worklist[i];
+ if (nextElem.ref && nextElem.ref.parent === parent) {
+ if (nextElem.ref.key < key) {
+ break;
+ }
+ --nextElem.ref.key;
+ }
+ }
+ }
+ }
+
+ var worklist,
+ leavelist,
+ node,
+ nodeType,
+ target,
+ element,
+ current,
+ current2,
+ candidates,
+ candidate,
+ sentinel,
+ outer,
+ key;
+
+ this.__initialize(root, visitor);
+
+ sentinel = {};
+
+ // reference
+ worklist = this.__worklist;
+ leavelist = this.__leavelist;
+
+ // initialize
+ outer = {
+ root: root
+ };
+ element = new Element(root, null, null, new Reference(outer, 'root'));
+ worklist.push(element);
+ leavelist.push(element);
+
+ while (worklist.length) {
+ element = worklist.pop();
+
+ if (element === sentinel) {
+ element = leavelist.pop();
+
+ target = this.__execute(visitor.leave, element);
+
+ // node may be replaced with null,
+ // so distinguish between undefined and null in this place
+ if (target !== undefined && target !== BREAK && target !== SKIP && target !== REMOVE) {
+ // replace
+ element.ref.replace(target);
+ }
+
+ if (this.__state === REMOVE || target === REMOVE) {
+ removeElem(element);
+ }
+
+ if (this.__state === BREAK || target === BREAK) {
+ return outer.root;
+ }
+ continue;
+ }
+
+ target = this.__execute(visitor.enter, element);
+
+ // node may be replaced with null,
+ // so distinguish between undefined and null in this place
+ if (target !== undefined && target !== BREAK && target !== SKIP && target !== REMOVE) {
+ // replace
+ element.ref.replace(target);
+ element.node = target;
+ }
+
+ if (this.__state === REMOVE || target === REMOVE) {
+ removeElem(element);
+ element.node = null;
+ }
+
+ if (this.__state === BREAK || target === BREAK) {
+ return outer.root;
+ }
+
+ // node may be null
+ node = element.node;
+ if (!node) {
+ continue;
+ }
+
+ worklist.push(sentinel);
+ leavelist.push(element);
+
+ if (this.__state === SKIP || target === SKIP) {
+ continue;
+ }
+
+ nodeType = element.wrap || node.type;
+ candidates = this.__keys[nodeType];
+ if (!candidates) {
+ if (this.__fallback) {
+ candidates = objectKeys(node);
+ } else {
+ throw new Error('Unknown node type ' + nodeType + '.');
+ }
+ }
+
+ current = candidates.length;
+ while ((current -= 1) >= 0) {
+ key = candidates[current];
+ candidate = node[key];
+ if (!candidate) {
+ continue;
+ }
+
+ if (isArray(candidate)) {
+ current2 = candidate.length;
+ while ((current2 -= 1) >= 0) {
+ if (!candidate[current2]) {
+ continue;
+ }
+ if (isProperty(nodeType, candidates[current])) {
+ element = new Element(candidate[current2], [key, current2], 'Property', new Reference(candidate, current2));
+ } else if (isNode(candidate[current2])) {
+ element = new Element(candidate[current2], [key, current2], null, new Reference(candidate, current2));
+ } else {
+ continue;
+ }
+ worklist.push(element);
+ }
+ } else if (isNode(candidate)) {
+ worklist.push(new Element(candidate, key, null, new Reference(node, key)));
+ }
+ }
+ }
+
+ return outer.root;
+ };
+
+ function traverse(root, visitor) {
+ var controller = new Controller();
+ return controller.traverse(root, visitor);
+ }
+
+ function replace(root, visitor) {
+ var controller = new Controller();
+ return controller.replace(root, visitor);
+ }
+
+ function extendCommentRange(comment, tokens) {
+ var target;
+
+ target = upperBound(tokens, function search(token) {
+ return token.range[0] > comment.range[0];
+ });
+
+ comment.extendedRange = [comment.range[0], comment.range[1]];
+
+ if (target !== tokens.length) {
+ comment.extendedRange[1] = tokens[target].range[0];
+ }
+
+ target -= 1;
+ if (target >= 0) {
+ comment.extendedRange[0] = tokens[target].range[1];
+ }
+
+ return comment;
+ }
+
+ function attachComments(tree, providedComments, tokens) {
+ // At first, we should calculate extended comment ranges.
+ var comments = [], comment, len, i, cursor;
+
+ if (!tree.range) {
+ throw new Error('attachComments needs range information');
+ }
+
+ // tokens array is empty, we attach comments to tree as 'leadingComments'
+ if (!tokens.length) {
+ if (providedComments.length) {
+ for (i = 0, len = providedComments.length; i < len; i += 1) {
+ comment = deepCopy(providedComments[i]);
+ comment.extendedRange = [0, tree.range[0]];
+ comments.push(comment);
+ }
+ tree.leadingComments = comments;
+ }
+ return tree;
+ }
+
+ for (i = 0, len = providedComments.length; i < len; i += 1) {
+ comments.push(extendCommentRange(deepCopy(providedComments[i]), tokens));
+ }
+
+ // This is based on John Freeman's implementation.
+ cursor = 0;
+ traverse(tree, {
+ enter: function (node) {
+ var comment;
+
+ while (cursor < comments.length) {
+ comment = comments[cursor];
+ if (comment.extendedRange[1] > node.range[0]) {
+ break;
+ }
+
+ if (comment.extendedRange[1] === node.range[0]) {
+ if (!node.leadingComments) {
+ node.leadingComments = [];
+ }
+ node.leadingComments.push(comment);
+ comments.splice(cursor, 1);
+ } else {
+ cursor += 1;
+ }
+ }
+
+ // already out of owned node
+ if (cursor === comments.length) {
+ return VisitorOption.Break;
+ }
+
+ if (comments[cursor].extendedRange[0] > node.range[1]) {
+ return VisitorOption.Skip;
+ }
+ }
+ });
+
+ cursor = 0;
+ traverse(tree, {
+ leave: function (node) {
+ var comment;
+
+ while (cursor < comments.length) {
+ comment = comments[cursor];
+ if (node.range[1] < comment.extendedRange[0]) {
+ break;
+ }
+
+ if (node.range[1] === comment.extendedRange[0]) {
+ if (!node.trailingComments) {
+ node.trailingComments = [];
+ }
+ node.trailingComments.push(comment);
+ comments.splice(cursor, 1);
+ } else {
+ cursor += 1;
+ }
+ }
+
+ // already out of owned node
+ if (cursor === comments.length) {
+ return VisitorOption.Break;
+ }
+
+ if (comments[cursor].extendedRange[0] > node.range[1]) {
+ return VisitorOption.Skip;
+ }
+ }
+ });
+
+ return tree;
+ }
+
+ exports.version = require('./package.json').version;
+ exports.Syntax = Syntax;
+ exports.traverse = traverse;
+ exports.replace = replace;
+ exports.attachComments = attachComments;
+ exports.VisitorKeys = VisitorKeys;
+ exports.VisitorOption = VisitorOption;
+ exports.Controller = Controller;
+ exports.cloneEnvironment = function () { return clone({}); };
+
+ return exports;
+}(exports));
+/* vim: set sw=4 ts=4 et tw=80 : */
+
+},{"./package.json":73}],73:[function(require,module,exports){
+module.exports={
+ "name": "estraverse",
+ "description": "ECMAScript JS AST traversal functions",
+ "homepage": "https://github.com/estools/estraverse",
+ "main": "estraverse.js",
+ "version": "3.1.0",
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "maintainers": [
+ {
+ "name": "constellation",
+ "email": "utatane.tea@gmail.com"
+ },
+ {
+ "name": "michaelficarra",
+ "email": "npm@michael.ficarra.me"
+ }
+ ],
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/estools/estraverse.git"
+ },
+ "devDependencies": {
+ "chai": "^2.1.1",
+ "coffee-script": "^1.8.0",
+ "espree": "^1.11.0",
+ "gulp": "^3.8.10",
+ "gulp-bump": "^0.2.2",
+ "gulp-filter": "^2.0.0",
+ "gulp-git": "^1.0.1",
+ "gulp-tag-version": "^1.2.1",
+ "jshint": "^2.5.6",
+ "mocha": "^2.1.0"
+ },
+ "licenses": [
+ {
+ "type": "BSD",
+ "url": "http://github.com/estools/estraverse/raw/master/LICENSE.BSD"
+ }
+ ],
+ "scripts": {
+ "test": "npm run-script lint && npm run-script unit-test",
+ "lint": "jshint estraverse.js",
+ "unit-test": "mocha --compilers coffee:coffee-script/register"
+ },
+ "gitHead": "166ebbe0a8d45ceb2391b6f5ef5d1bab6bfb267a",
+ "bugs": {
+ "url": "https://github.com/estools/estraverse/issues"
+ },
+ "_id": "estraverse@3.1.0",
+ "_shasum": "15e28a446b8b82bc700ccc8b96c78af4da0d6cba",
+ "_from": "estraverse@>=3.1.0 <4.0.0",
+ "_npmVersion": "2.0.0-alpha-5",
+ "_npmUser": {
+ "name": "constellation",
+ "email": "utatane.tea@gmail.com"
+ },
+ "dist": {
+ "shasum": "15e28a446b8b82bc700ccc8b96c78af4da0d6cba",
+ "tarball": "http://registry.npmjs.org/estraverse/-/estraverse-3.1.0.tgz"
+ },
+ "directories": {},
+ "_resolved": "https://registry.npmjs.org/estraverse/-/estraverse-3.1.0.tgz",
+ "readme": "ERROR: No README data found!"
+}
+
+},{}],74:[function(require,module,exports){
+(function (process){
+(function (global, undefined) {
+ "use strict";
+
+ if (global.setImmediate) {
+ return;
+ }
+
+ var nextHandle = 1; // Spec says greater than zero
+ var tasksByHandle = {};
+ var currentlyRunningATask = false;
+ var doc = global.document;
+ var setImmediate;
+
+ function addFromSetImmediateArguments(args) {
+ tasksByHandle[nextHandle] = partiallyApplied.apply(undefined, args);
+ return nextHandle++;
+ }
+
+ // This function accepts the same arguments as setImmediate, but
+ // returns a function that requires no arguments.
+ function partiallyApplied(handler) {
+ var args = [].slice.call(arguments, 1);
+ return function() {
+ if (typeof handler === "function") {
+ handler.apply(undefined, args);
+ } else {
+ (new Function("" + handler))();
+ }
+ };
+ }
+
+ function runIfPresent(handle) {
+ // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
+ // So if we're currently running a task, we'll need to delay this invocation.
+ if (currentlyRunningATask) {
+ // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
+ // "too much recursion" error.
+ setTimeout(partiallyApplied(runIfPresent, handle), 0);
+ } else {
+ var task = tasksByHandle[handle];
+ if (task) {
+ currentlyRunningATask = true;
+ try {
+ task();
+ } finally {
+ clearImmediate(handle);
+ currentlyRunningATask = false;
+ }
+ }
+ }
+ }
+
+ function clearImmediate(handle) {
+ delete tasksByHandle[handle];
+ }
+
+ function installNextTickImplementation() {
+ setImmediate = function() {
+ var handle = addFromSetImmediateArguments(arguments);
+ process.nextTick(partiallyApplied(runIfPresent, handle));
+ return handle;
+ };
+ }
+
+ function canUsePostMessage() {
+ // The test against `importScripts` prevents this implementation from being installed inside a web worker,
+ // where `global.postMessage` means something completely different and can't be used for this purpose.
+ if (global.postMessage && !global.importScripts) {
+ var postMessageIsAsynchronous = true;
+ var oldOnMessage = global.onmessage;
+ global.onmessage = function() {
+ postMessageIsAsynchronous = false;
+ };
+ global.postMessage("", "*");
+ global.onmessage = oldOnMessage;
+ return postMessageIsAsynchronous;
+ }
+ }
+
+ function installPostMessageImplementation() {
+ // Installs an event handler on `global` for the `message` event: see
+ // * https://developer.mozilla.org/en/DOM/window.postMessage
+ // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
+
+ var messagePrefix = "setImmediate$" + Math.random() + "$";
+ var onGlobalMessage = function(event) {
+ if (event.source === global &&
+ typeof event.data === "string" &&
+ event.data.indexOf(messagePrefix) === 0) {
+ runIfPresent(+event.data.slice(messagePrefix.length));
+ }
+ };
+
+ if (global.addEventListener) {
+ global.addEventListener("message", onGlobalMessage, false);
+ } else {
+ global.attachEvent("onmessage", onGlobalMessage);
+ }
+
+ setImmediate = function() {
+ var handle = addFromSetImmediateArguments(arguments);
+ global.postMessage(messagePrefix + handle, "*");
+ return handle;
+ };
+ }
+
+ function installMessageChannelImplementation() {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = function(event) {
+ var handle = event.data;
+ runIfPresent(handle);
+ };
+
+ setImmediate = function() {
+ var handle = addFromSetImmediateArguments(arguments);
+ channel.port2.postMessage(handle);
+ return handle;
+ };
+ }
+
+ function installReadyStateChangeImplementation() {
+ var html = doc.documentElement;
+ setImmediate = function() {
+ var handle = addFromSetImmediateArguments(arguments);
+ // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
+ // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
+ var script = doc.createElement("script");
+ script.onreadystatechange = function () {
+ runIfPresent(handle);
+ script.onreadystatechange = null;
+ html.removeChild(script);
+ script = null;
+ };
+ html.appendChild(script);
+ return handle;
+ };
+ }
+
+ function installSetTimeoutImplementation() {
+ setImmediate = function() {
+ var handle = addFromSetImmediateArguments(arguments);
+ setTimeout(partiallyApplied(runIfPresent, handle), 0);
+ return handle;
+ };
+ }
+
+ // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
+ var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
+ attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
+
+ // Don't get fooled by e.g. browserify environments.
+ if ({}.toString.call(global.process) === "[object process]") {
+ // For Node.js before 0.9
+ installNextTickImplementation();
+
+ } else if (canUsePostMessage()) {
+ // For non-IE10 modern browsers
+ installPostMessageImplementation();
+
+ } else if (global.MessageChannel) {
+ // For web workers, where supported
+ installMessageChannelImplementation();
+
+ } else if (doc && "onreadystatechange" in doc.createElement("script")) {
+ // For IE 6–8
+ installReadyStateChangeImplementation();
+
+ } else {
+ // For older browsers
+ installSetTimeoutImplementation();
+ }
+
+ attachTo.setImmediate = setImmediate;
+ attachTo.clearImmediate = clearImmediate;
+}(new Function("return this")()));
+
+}).call(this,require('_process'))
+
+},{"_process":21}],"hydrolysis":[function(require,module,exports){
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+ /*jslint node: true */
+'use strict';
+
+/**
+ * Static analysis for Polymer.
+ * @namespace hydrolysis
+ */
+module.exports = {
+ Analyzer: require('./lib/analyzer'),
+ docs: require('./lib/ast-utils/docs'),
+ FSResolver: require('./lib/loader/fs-resolver'),
+ jsdoc: require('./lib/ast-utils/jsdoc'),
+ Loader: require('./lib/loader/file-loader'),
+ NoopResolver: require('./lib/loader/noop-resolver'),
+ XHRResolver: require('./lib/loader/xhr-resolver'),
+ _jsParse: require('./lib/ast-utils/js-parse'),
+ _importParse: require('./lib/ast-utils/import-parse'),
+};
+
+},{"./lib/analyzer":1,"./lib/ast-utils/docs":5,"./lib/ast-utils/import-parse":10,"./lib/ast-utils/js-parse":11,"./lib/ast-utils/jsdoc":12,"./lib/loader/file-loader":13,"./lib/loader/fs-resolver":14,"./lib/loader/noop-resolver":15,"./lib/loader/xhr-resolver":16}]},{},[])
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJsaWIvYW5hbHl6ZXIuanMiLCJsaWIvYXN0LXV0aWxzL2FuYWx5emUtcHJvcGVydGllcy5qcyIsImxpYi9hc3QtdXRpbHMvYXN0LXZhbHVlLmpzIiwibGliL2FzdC11dGlscy9iZWhhdmlvci1maW5kZXIuanMiLCJsaWIvYXN0LXV0aWxzL2RvY3MuanMiLCJsaWIvYXN0LXV0aWxzL2VsZW1lbnQtZmluZGVyLmpzIiwibGliL2FzdC11dGlscy9lc3V0aWwuanMiLCJsaWIvYXN0LXV0aWxzL2ZlYXR1cmUtZmluZGVyLmpzIiwibGliL2FzdC11dGlscy9maW5kLWFsaWFzLmpzIiwibGliL2FzdC11dGlscy9pbXBvcnQtcGFyc2UuanMiLCJsaWIvYXN0LXV0aWxzL2pzLXBhcnNlLmpzIiwibGliL2FzdC11dGlscy9qc2RvYy5qcyIsImxpYi9sb2FkZXIvZmlsZS1sb2FkZXIuanMiLCJsaWIvbG9hZGVyL2ZzLXJlc29sdmVyLmpzIiwibGliL2xvYWRlci9ub29wLXJlc29sdmVyLmpzIiwibGliL2xvYWRlci94aHItcmVzb2x2ZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9saWIvX2VtcHR5LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Fzc2VydC9hc3NlcnQuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9wYXRoLWJyb3dzZXJpZnkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3B1bnljb2RlL3B1bnljb2RlLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3F1ZXJ5c3RyaW5nLWVzMy9kZWNvZGUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcXVlcnlzdHJpbmctZXMzL2VuY29kZS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9xdWVyeXN0cmluZy1lczMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvdXJsL3VybC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy91dGlsL3N1cHBvcnQvaXNCdWZmZXJCcm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3V0aWwvdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9kb2N0cmluZS9saWIvZG9jdHJpbmUuanMiLCJub2RlX21vZHVsZXMvZG9jdHJpbmUvbGliL3R5cGVkLmpzIiwibm9kZV9tb2R1bGVzL2RvY3RyaW5lL2xpYi91dGlsaXR5LmpzIiwibm9kZV9tb2R1bGVzL2RvY3RyaW5lL25vZGVfbW9kdWxlcy9lc3V0aWxzL2xpYi9hc3QuanMiLCJub2RlX21vZHVsZXMvZG9jdHJpbmUvbm9kZV9tb2R1bGVzL2VzdXRpbHMvbGliL2NvZGUuanMiLCJub2RlX21vZHVsZXMvZG9jdHJpbmUvbm9kZV9tb2R1bGVzL2VzdXRpbHMvbGliL2tleXdvcmQuanMiLCJub2RlX21vZHVsZXMvZG9jdHJpbmUvbm9kZV9tb2R1bGVzL2VzdXRpbHMvbGliL3V0aWxzLmpzIiwibm9kZV9tb2R1bGVzL2RvY3RyaW5lL25vZGVfbW9kdWxlcy9pc2FycmF5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2RvY3RyaW5lL3BhY2thZ2UuanNvbiIsIm5vZGVfbW9kdWxlcy9kb201L2RvbTUuanMiLCJub2RlX21vZHVsZXMvZG9tNS9ub2RlX21vZHVsZXMvcGFyc2U1L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2RvbTUvbm9kZV9tb2R1bGVzL3BhcnNlNS9saWIvY29tbW9uL2RvY3R5cGUuanMiLCJub2RlX21vZHVsZXMvZG9tNS9ub2RlX21vZHVsZXMvcGFyc2U1L2xpYi9jb21tb24vZm9yZWlnbl9jb250ZW50LmpzIiwibm9kZV9tb2R1bGVzL2RvbTUvbm9kZV9tb2R1bGVzL3BhcnNlNS9saWIvY29tbW9uL2h0bWwuanMiLCJub2RlX21vZHVsZXMvZG9tNS9ub2RlX21vZHVsZXMvcGFyc2U1L2xpYi9jb21tb24vdW5pY29kZS5qcyIsIm5vZGVfbW9kdWxlcy9kb201L25vZGVfbW9kdWxlcy9wYXJzZTUvbGliL2NvbW1vbi91dGlscy5qcyIsIm5vZGVfbW9kdWxlcy9kb201L25vZGVfbW9kdWxlcy9wYXJzZTUvbGliL2pzZG9tL2pzZG9tX3BhcnNlci5qcyIsIm5vZGVfbW9kdWxlcy9kb201L25vZGVfbW9kdWxlcy9wYXJzZTUvbGliL2pzZG9tL3BhcnNpbmdfdW5pdC5qcyIsIm5vZGVfbW9kdWxlcy9kb201L25vZGVfbW9kdWxlcy9wYXJzZTUvbGliL3NlcmlhbGl6YXRpb24vc2VyaWFsaXplci5qcyIsIm5vZGVfbW9kdWxlcy9kb201L25vZGVfbW9kdWxlcy9wYXJzZTUvbGliL3NpbXBsZV9hcGkvc2ltcGxlX2FwaV9wYXJzZXIuanMiLCJub2RlX21vZHVsZXMvZG9tNS9ub2RlX21vZHVsZXMvcGFyc2U1L2xpYi9zaW1wbGVfYXBpL3Rva2VuaXplcl9wcm94eS5qcyIsIm5vZGVfbW9kdWxlcy9kb201L25vZGVfbW9kdWxlcy9wYXJzZTUvbGliL3Rva2VuaXphdGlvbi9sb2NhdGlvbl9pbmZvX21peGluLmpzIiwibm9kZV9tb2R1bGVzL2RvbTUvbm9kZV9tb2R1bGVzL3BhcnNlNS9saWIvdG9rZW5pemF0aW9uL25hbWVkX2VudGl0eV90cmllLmpzIiwibm9kZV9tb2R1bGVzL2RvbTUvbm9kZV9tb2R1bGVzL3BhcnNlNS9saWIvdG9rZW5pemF0aW9uL3ByZXByb2Nlc3Nvci5qcyIsIm5vZGVfbW9kdWxlcy9kb201L25vZGVfbW9kdWxlcy9wYXJzZTUvbGliL3Rva2VuaXphdGlvbi90b2tlbml6ZXIuanMiLCJub2RlX21vZHVsZXMvZG9tNS9ub2RlX21vZHVsZXMvcGFyc2U1L2xpYi90cmVlX2FkYXB0ZXJzL2RlZmF1bHQuanMiLCJub2RlX21vZHVsZXMvZG9tNS9ub2RlX21vZHVsZXMvcGFyc2U1L2xpYi90cmVlX2FkYXB0ZXJzL2h0bWxwYXJzZXIyLmpzIiwibm9kZV9tb2R1bGVzL2RvbTUvbm9kZV9tb2R1bGVzL3BhcnNlNS9saWIvdHJlZV9jb25zdHJ1Y3Rpb24vZm9ybWF0dGluZ19lbGVtZW50X2xpc3QuanMiLCJub2RlX21vZHVsZXMvZG9tNS9ub2RlX21vZHVsZXMvcGFyc2U1L2xpYi90cmVlX2NvbnN0cnVjdGlvbi9sb2NhdGlvbl9pbmZvX21peGluLmpzIiwibm9kZV9tb2R1bGVzL2RvbTUvbm9kZV9tb2R1bGVzL3BhcnNlNS9saWIvdHJlZV9jb25zdHJ1Y3Rpb24vb3Blbl9lbGVtZW50X3N0YWNrLmpzIiwibm9kZV9tb2R1bGVzL2RvbTUvbm9kZV9tb2R1bGVzL3BhcnNlNS9saWIvdHJlZV9jb25zdHJ1Y3Rpb24vcGFyc2VyLmpzIiwibm9kZV9tb2R1bGVzL2VzNi1wcm9taXNlL2Rpc3QvZXM2LXByb21pc2UuanMiLCJub2RlX21vZHVsZXMvZXNwcmVlL2VzcHJlZS5qcyIsIm5vZGVfbW9kdWxlcy9lc3ByZWUvbGliL2FzdC1ub2RlLWZhY3RvcnkuanMiLCJub2RlX21vZHVsZXMvZXNwcmVlL2xpYi9hc3Qtbm9kZS10eXBlcy5qcyIsIm5vZGVfbW9kdWxlcy9lc3ByZWUvbGliL2NvbW1lbnQtYXR0YWNobWVudC5qcyIsIm5vZGVfbW9kdWxlcy9lc3ByZWUvbGliL2ZlYXR1cmVzLmpzIiwibm9kZV9tb2R1bGVzL2VzcHJlZS9saWIvbWVzc2FnZXMuanMiLCJub2RlX21vZHVsZXMvZXNwcmVlL2xpYi9zdHJpbmctbWFwLmpzIiwibm9kZV9tb2R1bGVzL2VzcHJlZS9saWIvc3ludGF4LmpzIiwibm9kZV9tb2R1bGVzL2VzcHJlZS9saWIvdG9rZW4taW5mby5qcyIsIm5vZGVfbW9kdWxlcy9lc3ByZWUvbGliL3hodG1sLWVudGl0aWVzLmpzIiwibm9kZV9tb2R1bGVzL2VzcHJlZS9wYWNrYWdlLmpzb24iLCJub2RlX21vZHVsZXMvZXN0cmF2ZXJzZS9lc3RyYXZlcnNlLmpzIiwibm9kZV9tb2R1bGVzL2VzdHJhdmVyc2UvcGFja2FnZS5qc29uIiwibm9kZV9tb2R1bGVzL3NldGltbWVkaWF0ZS9zZXRJbW1lZGlhdGUuanMiLCJpbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN4ZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JZQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNySEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDL05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2V0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDaE9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbnNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMxa0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1eUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN3VDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BnQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDalFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN3dFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeE1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3VEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzN3RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM1OEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcDJLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcDZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3owQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL0tBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAoYykgMjAxNSBUaGUgUG9seW1lciBQcm9qZWN0IEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBUaGlzIGNvZGUgbWF5IG9ubHkgYmUgdXNlZCB1bmRlciB0aGUgQlNEIHN0eWxlIGxpY2Vuc2UgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0xJQ0VOU0UudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGF1dGhvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9BVVRIT1JTLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBjb250cmlidXRvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9DT05UUklCVVRPUlMudHh0XG4gKiBDb2RlIGRpc3RyaWJ1dGVkIGJ5IEdvb2dsZSBhcyBwYXJ0IG9mIHRoZSBwb2x5bWVyIHByb2plY3QgaXMgYWxzb1xuICogc3ViamVjdCB0byBhbiBhZGRpdGlvbmFsIElQIHJpZ2h0cyBncmFudCBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vUEFURU5UUy50eHRcbiAqL1xuLy8ganNoaW50IG5vZGU6IHRydWVcbid1c2Ugc3RyaWN0Jztcbi8vIGpzaGludCAtVzA3OVxudmFyIFByb21pc2UgPSBnbG9iYWwuUHJvbWlzZSB8fCByZXF1aXJlKCdlczYtcHJvbWlzZScpLlByb21pc2U7XG5yZXF1aXJlKFwic2V0aW1tZWRpYXRlXCIpO1xuLy8ganNoaW50ICtXMDc5XG5cbnZhciBkb201ID0gcmVxdWlyZSgnZG9tNScpO1xudmFyIHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuXG52YXIgZG9jcyA9IHJlcXVpcmUoJy4vYXN0LXV0aWxzL2RvY3MnKTtcbnZhciBGaWxlTG9hZGVyID0gcmVxdWlyZSgnLi9sb2FkZXIvZmlsZS1sb2FkZXInKTtcbnZhciBpbXBvcnRQYXJzZSA9IHJlcXVpcmUoJy4vYXN0LXV0aWxzL2ltcG9ydC1wYXJzZScpO1xudmFyIGpzUGFyc2UgPSByZXF1aXJlKCcuL2FzdC11dGlscy9qcy1wYXJzZScpO1xudmFyIE5vb3BSZXNvbHZlciA9IHJlcXVpcmUoJy4vbG9hZGVyL25vb3AtcmVzb2x2ZXInKTtcblxuZnVuY3Rpb24gcmVkdWNlTWV0YWRhdGEobTEsIG0yKSB7XG4gIHJldHVybiB7XG4gICAgZWxlbWVudHM6ICBtMS5lbGVtZW50cy5jb25jYXQobTIuZWxlbWVudHMpLFxuICAgIGZlYXR1cmVzOiAgbTEuZmVhdHVyZXMuY29uY2F0KG0yLmZlYXR1cmVzKSxcbiAgICBiZWhhdmlvcnM6IG0xLmJlaGF2aW9ycy5jb25jYXQobTIuYmVoYXZpb3JzKSxcbiAgfTtcbn1cblxudmFyIEVNUFRZX01FVEFEQVRBID0ge2VsZW1lbnRzOiBbXSwgZmVhdHVyZXM6IFtdLCBiZWhhdmlvcnM6IFtdfTtcblxuLyoqXG4gKiBQYXJzZTUncyByZXByZXNlbnRhdGlvbiBvZiBhIHBhcnNlZCBodG1sIGRvY3VtZW50XG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBEb2N1bWVudEFTVFxuICogQG1lbWJlcm9mIGh5ZHJvbHlzaXNcbiAqL1xuXG4vKipcbiAqIFRoZSBtZXRhZGF0YSBmb3IgYSBzaW5nbGUgcG9seW1lciBlbGVtZW50XG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBFbGVtZW50RGVzY3JpcHRvclxuICogQG1lbWJlcm9mIGh5ZHJvbHlzaXNcbiAqL1xuXG4vKipcbiAqIFRoZSBtZXRhZGF0YSBmb3IgYSBQb2x5bWVyIGZlYXR1cmUuXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBGZWF0dXJlRGVzY3JpcHRvclxuICogQG1lbWJlcm9mIGh5ZHJvbHlzaXNcbiAqL1xuXG4vKipcbiAqIFRoZSBtZXRhZGF0YSBmb3IgYSBQb2x5bWVyIGJlaGF2aW9yIG1peGluLlxuICogQHR5cGVkZWYge09iamVjdH0gQmVoYXZpb3JEZXNjcmlwdG9yXG4gKiBAbWVtYmVyb2YgaHlkcm9seXNpc1xuICovXG5cbi8qKlxuICogVGhlIG1ldGFkYXRhIGZvciBhbGwgZmVhdHVyZXMgYW5kIGVsZW1lbnRzIGRlZmluZWQgaW4gb25lIGRvY3VtZW50XG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBEb2N1bWVudERlc2NyaXB0b3JcbiAqIEBtZW1iZXJvZiBoeWRyb2x5c2lzXG4gKiBAcHJvcGVydHkge0FycmF5PEVsZW1lbnREZXNjcmlwdG9yPn0gZWxlbWVudHMgVGhlIGVsZW1lbnRzIGZyb20gdGhlIGRvY3VtZW50XG4gKiBAcHJvcGVydHkge0FycmF5PEZlYXR1cmVEZXNjcmlwdG9yPn0gIGZlYXR1cmVzIFRoZSBmZWF0dXJlcyBmcm9tIHRoZSBkb2N1bWVudFxuICogQHByb3BlcnR5IHtBcnJheTxGZWF0dXJlRGVzY3JpcHRvcj59ICBiZWhhdmlvcnMgVGhlIGJlaGF2aW9ycyBmcm9tIHRoZSBkb2N1bWVudFxuICovXG5cbi8qKlxuICogVGhlIG1ldGFkYXRhIG9mIGFuIGVudGlyZSBIVE1MIGRvY3VtZW50LCBpbiBwcm9taXNlcy5cbiAqIEB0eXBlZGVmIHtPYmplY3R9IEFuYWx5emVkRG9jdW1lbnRcbiAqIEBtZW1iZXJvZiBoeWRyb2x5c2lzXG4gKiBAcHJvcGVydHkge3N0cmluZ30gaHJlZiBUaGUgdXJsIG9mIHRoZSBkb2N1bWVudC5cbiAqIEBwcm9wZXJ0eSB7UHJvbWlzZTxQYXJzZWRJbXBvcnQ+fSAgaHRtbExvYWRlZCBUaGUgcGFyc2VkIHJlcHJlc2VudGF0aW9uIG9mXG4gKiAgICAgdGhlIGRvYy4gVXNlIHRoZSBgYXN0YCBwcm9wZXJ0eSB0byBnZXQgdGhlIGZ1bGwgYHBhcnNlNWAgYXN0XG4gKlxuICogQHByb3BlcnR5IHtQcm9taXNlPEFycmF5PHN0cmluZz4+fSBkZXBzTG9hZGVkIFJlc29sdmVzIHRvIHRoZSBsaXN0IG9mIHRoaXNcbiAqICAgICBEb2N1bWVudCdzIHRyYW5zaXRpdmUgaW1wb3J0IGRlcGVuZGVuY2llc1xuICpcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8c3RyaW5nPn0gZGVwSHJlZnMgVGhlIGRpcmVjdCBkZXBlbmRlbmNpZXMgb2YgdGhlIGRvY3VtZW50LlxuICpcbiAqIEBwcm9wZXJ0eSB7UHJvbWlzZTxEb2N1bWVudERlc2NyaXB0b3I+fSBtZXRhZGF0YUxvYWRlZCBSZXNvbHZlcyB0byB0aGUgbGlzdCBvZlxuICogICAgIHRoaXMgRG9jdW1lbnQncyBpbXBvcnQgZGVwZW5kZW5jaWVzXG4gKi9cblxuLyoqXG4gKiBBIGRhdGFiYXNlIG9mIFBvbHltZXIgbWV0YWRhdGEgZGVmaW5lZCBpbiBIVE1MXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAbWVtYmVyT2YgaHlkcm9seXNpc1xuICogQHBhcmFtICB7Ym9vbGVhbn0gYXR0YWNoQVNUICBJZiB0cnVlLCBhdHRhY2ggYSBwYXJzZTUgY29tcGxpYW50IEFTVFxuICogQHBhcmFtICB7RmlsZUxvYWRlcj19IGxvYWRlciBBbiBvcHRpb25hbCBgRmlsZUxvYWRlcmAgdXNlZCB0byBsb2FkIGV4dGVybmFsXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc291cmNlc1xuICovXG52YXIgQW5hbHl6ZXIgPSBmdW5jdGlvbiBBbmFseXplcihhdHRhY2hBU1QsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2FkZXIpIHtcbiAgdGhpcy5sb2FkZXIgPSBsb2FkZXI7XG5cbiAgLyoqXG4gICAqIEEgbGlzdCBvZiBhbGwgZWxlbWVudHMgdGhlIGBBbmFseXplcmAgaGFzIG1ldGFkYXRhIGZvci5cbiAgICogQG1lbWJlciB7QXJyYXkuPEVsZW1lbnREZXNjcmlwdG9yPn1cbiAgICovXG4gIHRoaXMuZWxlbWVudHMgPSBbXTtcblxuICAvKipcbiAgICogQSB2aWV3IGludG8gYGVsZW1lbnRzYCwga2V5ZWQgYnkgdGFnIG5hbWUuXG4gICAqIEBtZW1iZXIge09iamVjdC48c3RyaW5nLEVsZW1lbnREZXNjcmlwdG9yPn1cbiAgICovXG4gIHRoaXMuZWxlbWVudHNCeVRhZ05hbWUgPSB7fTtcblxuICAvKipcbiAgICogQSBsaXN0IG9mIEFQSSBmZWF0dXJlcyBhZGRlZCB0byBgUG9seW1lci5CYXNlYCBlbmNvdW50ZXJlZCBieSB0aGVcbiAgICogYW5hbHl6ZXIuXG4gICAqIEBtZW1iZXIge0FycmF5PEZlYXR1cmVEZXNjcmlwdG9yPn1cbiAgICovXG4gIHRoaXMuZmVhdHVyZXMgPSBbXTtcblxuICAvKipcbiAgICogVGhlIGJlaGF2aW9ycyBjb2xsZWN0ZWQgYnkgdGhlIGFuYWx5c2lzIHBhc3MuXG4gICAqXG4gICAqIEBtZW1iZXIge0FycmF5PEJlaGF2aW9yRGVzY3JpcHRvcj59XG4gICAqL1xuICB0aGlzLmJlaGF2aW9ycyA9IFtdO1xuXG4gIC8qKlxuICAgKiBBIG1hcCwga2V5ZWQgYnkgYWJzb2x1dGUgcGF0aCwgb2YgRG9jdW1lbnQgbWV0YWRhdGEuXG4gICAqIEBtZW1iZXIge09iamVjdDxzdHJpbmcsQW5hbHl6ZWREb2N1bWVudD59XG4gICAqL1xuICB0aGlzLmh0bWwgPSB7fTtcblxuICAvKipcbiAgICogQSBtYXAsIGtleWVkIGJ5IHBhdGgsIG9mIEhUTUwgZG9jdW1lbnQgQVNUcy5cbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHRoaXMucGFyc2VkRG9jdW1lbnRzID0ge307XG59O1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGBBbmFseXplci5hbmFsenllYFxuICogQHR5cGVkZWYge09iamVjdH0gTG9hZE9wdGlvbnNcbiAqIEBtZW1iZXJvZiBoeWRyb2x5c2lzXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IG5vQW5ub3RhdGlvbnMgV2hldGhlciBgYW5ub3RhdGUoKWAgc2hvdWxkIGJlIHNraXBwZWQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGNsZWFuIFdoZXRoZXIgdGhlIGdlbmVyYXRlZCBkZXNjcmlwdG9ycyBzaG91bGQgYmUgY2xlYW5lZFxuICogICAgIG9mIHJlZHVuZGFudCBkYXRhLlxuICogQHByb3BlcnR5IHtmdW5jdGlvbihzdHJpbmcpOiBib29sZWFufSBmaWx0ZXIgQSBwcmVkaWNhdGUgZnVuY3Rpb24gdGhhdFxuICogICAgIGluZGljYXRlcyB3aGljaCBmaWxlcyBzaG91bGQgYmUgaWdub3JlZCBieSB0aGUgbG9hZGVyLiBCeSBkZWZhdWx0IGFsbFxuICogICAgIGZpbGVzIG5vdCBsb2NhdGVkIHVuZGVyIHRoZSBkaXJuYW1lIG9mIGBocmVmYCB3aWxsIGJlIGlnbm9yZWQuXG4gKi9cblxuLyoqXG4gKiBTaG9ydGhhbmQgZm9yIHRyYW5zaXRpdmVseSBsb2FkaW5nIGFuZCBwcm9jZXNzaW5nIGFsbCBpbXBvcnRzIGJlZ2lubmluZyBhdFxuICogYGhyZWZgLlxuICpcbiAqIEluIG9yZGVyIHRvIHByb3Blcmx5IGZpbHRlciBwYXRocywgYGhyZWZgIF9tdXN0XyBiZSBhbiBhYnNvbHV0ZSBVUkkuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGhyZWYgVGhlIHJvb3QgaW1wb3J0IHRvIGJlZ2luIGxvYWRpbmcgZnJvbS5cbiAqIEBwYXJhbSB7TG9hZE9wdGlvbnM9fSBvcHRpb25zIEFueSBhZGRpdGlvbmFsIG9wdGlvbnMgZm9yIHRoZSBsb2FkLlxuICogQHJldHVybiB7UHJvbWlzZTxBbmFseXplcj59IEEgcHJvbWlzZSB0aGF0IHdpbGwgcmVzb2x2ZSBvbmNlIGBocmVmYCBhbmQgaXRzXG4gKiAgICAgZGVwZW5kZW5jaWVzIGhhdmUgYmVlbiBsb2FkZWQgYW5kIGFuYWx5emVkLlxuICovXG5BbmFseXplci5hbmFseXplID0gZnVuY3Rpb24gYW5hbHl6ZShocmVmLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBvcHRpb25zLmZpbHRlciA9IG9wdGlvbnMuZmlsdGVyIHx8IF9kZWZhdWx0RmlsdGVyKGhyZWYpO1xuXG4gIHZhciBsb2FkZXIgPSBuZXcgRmlsZUxvYWRlcigpO1xuICB2YXIgUHJpbWFyeVJlc29sdmVyID0gdHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZSgnLi9sb2FkZXIvZnMtcmVzb2x2ZXInKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlKCcuL2xvYWRlci94aHItcmVzb2x2ZXInKTtcbiAgbG9hZGVyLmFkZFJlc29sdmVyKG5ldyBQcmltYXJ5UmVzb2x2ZXIob3B0aW9ucykpO1xuICBsb2FkZXIuYWRkUmVzb2x2ZXIobmV3IE5vb3BSZXNvbHZlcih7dGVzdDogb3B0aW9ucy5maWx0ZXJ9KSk7XG5cbiAgdmFyIGFuYWx5emVyID0gbmV3IHRoaXMobnVsbCwgbG9hZGVyKTtcbiAgcmV0dXJuIGFuYWx5emVyLm1ldGFkYXRhVHJlZShocmVmKS50aGVuKGZ1bmN0aW9uKHJvb3QpIHtcbiAgICBpZiAoIW9wdGlvbnMubm9Bbm5vdGF0aW9ucykge1xuICAgICAgYW5hbHl6ZXIuYW5ub3RhdGUoKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMuY2xlYW4pIHtcbiAgICAgIGFuYWx5emVyLmNsZWFuKCk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoYW5hbHl6ZXIpO1xuICB9KTtcbn07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBocmVmXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihzdHJpbmcpOiBib29sZWFufVxuICovXG5mdW5jdGlvbiBfZGVmYXVsdEZpbHRlcihocmVmKSB7XG4gIC8vIEV2ZXJ5dGhpbmcgdXAgdG8gdGhlIGxhc3QgYC9gIG9yIGBcXGAuXG4gIHZhciBiYXNlID0gaHJlZi5tYXRjaCgvXiguKj8pW15cXC9cXFxcXSokLylbMV07XG4gIHJldHVybiBmdW5jdGlvbih1cmkpIHtcbiAgICByZXR1cm4gdXJpLmluZGV4T2YoYmFzZSkgIT09IDA7XG4gIH07XG59XG5cbkFuYWx5emVyLnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24gbG9hZChocmVmKSB7XG4gIHJldHVybiB0aGlzLmxvYWRlci5yZXF1ZXN0KGhyZWYpLnRoZW4oZnVuY3Rpb24oY29udGVudCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgICAgcmVzb2x2ZSh0aGlzLl9wYXJzZUhUTUwoY29udGVudCwgaHJlZikpO1xuICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICB9LmJpbmQodGhpcykpO1xuICB9LmJpbmQodGhpcykpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGFuIGBBbmFseXplZERvY3VtZW50YCByZXByZXNlbnRpbmcgdGhlIHByb3ZpZGVkIGRvY3VtZW50XG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtICB7c3RyaW5nfSBodG1sSW1wb3J0IFJhdyB0ZXh0IG9mIGFuIEhUTUwgZG9jdW1lbnRcbiAqIEBwYXJhbSAge3N0cmluZ30gaHJlZiAgICAgICBUaGUgZG9jdW1lbnQncyBVUkwuXG4gKiBAcmV0dXJuIHtBbmFseXplZERvY3VtZW50fSAgICAgICBBbiAgYEFuYWx5emVkRG9jdW1lbnRgXG4gKi9cbkFuYWx5emVyLnByb3RvdHlwZS5fcGFyc2VIVE1MID0gZnVuY3Rpb24gX3BhcnNlSFRNTChodG1sSW1wb3J0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBocmVmKSB7XG4gIGlmIChocmVmIGluIHRoaXMuaHRtbCkge1xuICAgIHJldHVybiB0aGlzLmh0bWxbaHJlZl07XG4gIH1cbiAgdmFyIGRlcHNMb2FkZWQgPSBbXTtcbiAgdmFyIGRlcEhyZWZzID0gW107XG4gIHZhciBtZXRhZGF0YUxvYWRlZCA9IFByb21pc2UucmVzb2x2ZShFTVBUWV9NRVRBREFUQSk7XG4gIHZhciBwYXJzZWQ7XG4gIHRyeSB7XG4gICAgcGFyc2VkID0gaW1wb3J0UGFyc2UoaHRtbEltcG9ydCwgaHJlZik7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHBhcnNpbmchJyk7XG4gICAgdGhyb3cgZXJyO1xuICB9XG4gIHZhciBodG1sTG9hZGVkID0gUHJvbWlzZS5yZXNvbHZlKHBhcnNlZCk7XG4gIGlmIChwYXJzZWQuc2NyaXB0KSB7XG4gICAgbWV0YWRhdGFMb2FkZWQgPSB0aGlzLl9wcm9jZXNzU2NyaXB0cyhwYXJzZWQuc2NyaXB0LCBocmVmKTtcbiAgICBkZXBzTG9hZGVkLnB1c2gobWV0YWRhdGFMb2FkZWQpO1xuICB9XG5cbiAgaWYgKHRoaXMubG9hZGVyKSB7XG4gICAgdmFyIGJhc2VVcmkgPSBocmVmO1xuICAgIGlmIChwYXJzZWQuYmFzZS5sZW5ndGggPiAxKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFwiT25seSBvbmUgYmFzZSB0YWcgcGVyIGRvY3VtZW50IVwiKTtcbiAgICAgIHRocm93IFwiTXVsdGlwbGUgYmFzZSB0YWdzIGluIFwiICsgaHJlZjtcbiAgICB9IGVsc2UgaWYgKHBhcnNlZC5iYXNlLmxlbmd0aCA9PSAxKSB7XG4gICAgICB2YXIgYmFzZUhyZWYgPSBkb201LmdldEF0dHJpYnV0ZShwYXJzZWQuYmFzZVswXSwgXCJocmVmXCIpO1xuICAgICAgaWYgKGJhc2VIcmVmKSB7XG4gICAgICAgIGJhc2VIcmVmID0gYmFzZUhyZWYgKyBcIi9cIjtcbiAgICAgICAgYmFzZVVyaSA9IHVybC5yZXNvbHZlKGJhc2VVcmksIGJhc2VIcmVmKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcGFyc2VkLmltcG9ydC5mb3JFYWNoKGZ1bmN0aW9uKGxpbmspIHtcbiAgICAgIHZhciBsaW5rdXJsID0gZG9tNS5nZXRBdHRyaWJ1dGUobGluaywgJ2hyZWYnKTtcbiAgICAgIGlmIChsaW5rdXJsKSB7XG4gICAgICAgIHZhciByZXNvbHZlZFVybCA9IHVybC5yZXNvbHZlKGJhc2VVcmksIGxpbmt1cmwpO1xuICAgICAgICBkZXBIcmVmcy5wdXNoKHJlc29sdmVkVXJsKTtcbiAgICAgICAgZGVwc0xvYWRlZC5wdXNoKHRoaXMuX2RlcGVuZGVuY2llc0xvYWRlZEZvcihyZXNvbHZlZFVybCwgaHJlZikpO1xuICAgICAgfVxuICAgIH0uYmluZCh0aGlzKSk7XG4gIH1cbiAgZGVwc0xvYWRlZCA9IFByb21pc2UuYWxsKGRlcHNMb2FkZWQpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uKCkge3JldHVybiBkZXBIcmVmczt9KVxuICAgICAgICAuY2F0Y2goZnVuY3Rpb24oZXJyKSB7dGhyb3cgZXJyO30pO1xuICB0aGlzLnBhcnNlZERvY3VtZW50c1tocmVmXSA9IHBhcnNlZC5hc3Q7XG4gIHRoaXMuaHRtbFtocmVmXSA9IHtcbiAgICAgIGhyZWY6IGhyZWYsXG4gICAgICBodG1sTG9hZGVkOiBodG1sTG9hZGVkLFxuICAgICAgbWV0YWRhdGFMb2FkZWQ6IG1ldGFkYXRhTG9hZGVkLFxuICAgICAgZGVwSHJlZnM6IGRlcEhyZWZzLFxuICAgICAgZGVwc0xvYWRlZDogZGVwc0xvYWRlZFxuICB9O1xuICByZXR1cm4gdGhpcy5odG1sW2hyZWZdO1xufTtcblxuQW5hbHl6ZXIucHJvdG90eXBlLl9wcm9jZXNzU2NyaXB0cyA9IGZ1bmN0aW9uIF9wcm9jZXNzU2NyaXB0cyhzY3JpcHRzLCBocmVmKSB7XG4gIHZhciBzY3JpcHRQcm9taXNlcyA9IFtdO1xuICBzY3JpcHRzLmZvckVhY2goZnVuY3Rpb24oc2NyaXB0KSB7XG4gICAgc2NyaXB0UHJvbWlzZXMucHVzaCh0aGlzLl9wcm9jZXNzU2NyaXB0KHNjcmlwdCwgaHJlZikpO1xuICB9LmJpbmQodGhpcykpO1xuICByZXR1cm4gUHJvbWlzZS5hbGwoc2NyaXB0UHJvbWlzZXMpLnRoZW4oZnVuY3Rpb24obWV0YWRhdGFMaXN0KSB7XG4gICAgcmV0dXJuIG1ldGFkYXRhTGlzdC5yZWR1Y2UocmVkdWNlTWV0YWRhdGEsIEVNUFRZX01FVEFEQVRBKTtcbiAgfSk7XG59O1xuXG5BbmFseXplci5wcm90b3R5cGUuX3Byb2Nlc3NTY3JpcHQgPSBmdW5jdGlvbiBfcHJvY2Vzc1NjcmlwdChzY3JpcHQsIGhyZWYpIHtcbiAgdmFyIHNyYyA9IGRvbTUuZ2V0QXR0cmlidXRlKHNjcmlwdCwgJ3NyYycpO1xuICB2YXIgcGFyc2VkSnM7XG4gIGlmICghc3JjKSB7XG4gICAgdHJ5IHtcbiAgICAgIHBhcnNlZEpzID0ganNQYXJzZShzY3JpcHQuY2hpbGROb2Rlc1swXS52YWx1ZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBGaWd1cmUgb3V0IHRoZSBjb3JyZWN0IGxpbmUgbnVtYmVyIGZvciB0aGUgZXJyb3IuXG4gICAgICB2YXIgbGluZSA9IDA7XG4gICAgICB2YXIgY29sID0gMDtcbiAgICAgIGlmIChzY3JpcHQuX19vd25lckRvY3VtZW50ICYmIHNjcmlwdC5fX293bmVyRG9jdW1lbnQgPT0gaHJlZikge1xuICAgICAgICBsaW5lID0gc2NyaXB0Ll9fbG9jYXRpb25EZXRhaWwubGluZSAtIDE7XG4gICAgICAgIGNvbCA9IHNjcmlwdC5fX2xvY2F0aW9uRGV0YWlsLmxpbmUgLSAxO1xuICAgICAgfVxuICAgICAgbGluZSArPSBlcnIubGluZU51bWJlcjtcbiAgICAgIGNvbCArPSBlcnIuY29sdW1uO1xuICAgICAgdmFyIG1lc3NhZ2UgPSBcIkVycm9yIHBhcnNpbmcgc2NyaXB0IGluIFwiICsgaHJlZiArIFwiIGF0IFwiICsgbGluZSArIFwiOlwiICsgY29sO1xuICAgICAgbWVzc2FnZSArPSBcIlxcblwiICsgZXJyLmRlc2NyaXB0aW9uO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgIH1cbiAgICBpZiAocGFyc2VkSnMuZWxlbWVudHMpIHtcbiAgICAgIHBhcnNlZEpzLmVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICBlbGVtZW50LnNjcmlwdEVsZW1lbnQgPSBzY3JpcHQ7XG4gICAgICAgIHRoaXMuZWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICAgICAgaWYgKGVsZW1lbnQuaXMgaW4gdGhpcy5lbGVtZW50c0J5VGFnTmFtZSkge1xuICAgICAgICAgIGNvbnNvbGUud2FybignSWdub3JpbmcgZHVwbGljYXRlIGVsZW1lbnQgZGVmaW5pdGlvbjogJyArIGVsZW1lbnQuaXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuZWxlbWVudHNCeVRhZ05hbWVbZWxlbWVudC5pc10gPSBlbGVtZW50O1xuICAgICAgICB9XG4gICAgICB9LmJpbmQodGhpcykpO1xuICAgIH1cbiAgICBpZiAocGFyc2VkSnMuZmVhdHVyZXMpIHtcbiAgICAgIHRoaXMuZmVhdHVyZXMgPSB0aGlzLmZlYXR1cmVzLmNvbmNhdChwYXJzZWRKcy5mZWF0dXJlcyk7XG4gICAgfVxuICAgIGlmIChwYXJzZWRKcy5iZWhhdmlvcnMpIHtcbiAgICAgIHRoaXMuYmVoYXZpb3JzID0gdGhpcy5iZWhhdmlvcnMuY29uY2F0KHBhcnNlZEpzLmJlaGF2aW9ycyk7XG4gICAgfVxuICAgIHJldHVybiBwYXJzZWRKcztcbiAgfVxuICBpZiAodGhpcy5sb2FkZXIpIHtcbiAgICB2YXIgcmVzb2x2ZWRTcmMgPSB1cmwucmVzb2x2ZShocmVmLCBzcmMpO1xuICAgIHJldHVybiB0aGlzLmxvYWRlci5yZXF1ZXN0KHJlc29sdmVkU3JjKS50aGVuKGZ1bmN0aW9uKGNvbnRlbnQpIHtcbiAgICAgIHZhciByZXNvbHZlZFNjcmlwdCA9IE9iamVjdC5jcmVhdGUoc2NyaXB0KTtcbiAgICAgIHJlc29sdmVkU2NyaXB0LmNoaWxkTm9kZXMgPSBbe3ZhbHVlOiBjb250ZW50fV07XG4gICAgICByZXNvbHZlZFNjcmlwdC5hdHRycyA9IHJlc29sdmVkU2NyaXB0LmF0dHJzLnNsaWNlKCk7XG4gICAgICBkb201LnJlbW92ZUF0dHJpYnV0ZShyZXNvbHZlZFNjcmlwdCwgJ3NyYycpO1xuICAgICAgcmV0dXJuIHRoaXMuX3Byb2Nlc3NTY3JpcHQocmVzb2x2ZWRTY3JpcHQsIGhyZWYpO1xuICAgIH0uYmluZCh0aGlzKSkuY2F0Y2goZnVuY3Rpb24oZXJyKSB7dGhyb3cgZXJyO30pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoRU1QVFlfTUVUQURBVEEpO1xuICB9XG59O1xuXG5BbmFseXplci5wcm90b3R5cGUuX2RlcGVuZGVuY2llc0xvYWRlZEZvciA9IGZ1bmN0aW9uIF9kZXBlbmRlbmNpZXNMb2FkZWRGb3IoaHJlZiwgcm9vdCkge1xuICB2YXIgZm91bmQgPSB7fTtcbiAgaWYgKHJvb3QgIT09IHVuZGVmaW5lZCkge1xuICAgIGZvdW5kW3Jvb3RdID0gdHJ1ZTtcbiAgfVxuICByZXR1cm4gdGhpcy5fZ2V0RGVwZW5kZW5jaWVzKGhyZWYsIGZvdW5kKS50aGVuKGZ1bmN0aW9uKGRlcHMpIHtcbiAgICB2YXIgZGVwTWV0YWRhdGFMb2FkZWQgPSBbXTtcbiAgICB2YXIgZGVwUHJvbWlzZXMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXBIcmVmKXtcbiAgICAgIHJldHVybiB0aGlzLmxvYWQoZGVwSHJlZikudGhlbihmdW5jdGlvbihodG1sTW9ub21lcikge1xuICAgICAgICByZXR1cm4gaHRtbE1vbm9tZXIubWV0YWRhdGFMb2FkZWQ7XG4gICAgICB9KTtcbiAgICB9LmJpbmQodGhpcykpO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChkZXBQcm9taXNlcyk7XG4gIH0uYmluZCh0aGlzKSk7XG59O1xuXG4vKipcbiAqIExpc3QgYWxsIHRoZSBodG1sIGRlcGVuZGVuY2llcyBmb3IgdGhlIGRvY3VtZW50IGF0IGBocmVmYC5cbiAqIEBwYXJhbSAge3N0cmluZ30gICAgICAgICAgICAgICAgICAgaHJlZiAgICAgIFRoZSBocmVmIHRvIGdldCBkZXBlbmRlbmNpZXMgZm9yLlxuICogQHBhcmFtICB7T2JqZWN0LjxzdHJpbmcsYm9vbGVhbj49fSBmb3VuZCAgICAgQW4gb2JqZWN0IGtleWVkIGJ5IFVSTCBvZiB0aGVcbiAqICAgICBhbHJlYWR5IHJlc29sdmVkIGRlcGVuZGVuY2llcy5cbiAqIEBwYXJhbSAge2Jvb2xlYW49fSAgICAgICAgICAgICAgICB0cmFuc2l0aXZlIFdoZXRoZXIgdG8gbG9hZCB0cmFuc2l0aXZlXG4gKiAgICAgZGVwZW5kZW5jaWVzLiBEZWZhdWx0cyB0byB0cnVlLlxuICogQHJldHVybiB7QXJyYXkuPHN0cmluZz59ICBBIGxpc3Qgb2YgYWxsIHRoZSBodG1sIGRlcGVuZGVuY2llcy5cbiAqL1xuQW5hbHl6ZXIucHJvdG90eXBlLl9nZXREZXBlbmRlbmNpZXMgPSBmdW5jdGlvbiBfZ2V0RGVwZW5kZW5jaWVzKGhyZWYsIGZvdW5kLCB0cmFuc2l0aXZlKSB7XG4gIGlmIChmb3VuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZm91bmQgPSB7fTtcbiAgICBmb3VuZFtocmVmXSA9IHRydWU7XG4gIH1cbiAgaWYgKHRyYW5zaXRpdmUgPT09IHVuZGVmaW5lZCkge1xuICAgIHRyYW5zaXRpdmUgPSB0cnVlO1xuICB9XG4gIHZhciBkZXBzID0gW107XG4gIHJldHVybiB0aGlzLmxvYWQoaHJlZikudGhlbihmdW5jdGlvbihodG1sTW9ub21lcikge1xuICAgIHZhciB0cmFuc2l0aXZlRGVwcyA9IFtdO1xuICAgIGh0bWxNb25vbWVyLmRlcEhyZWZzLmZvckVhY2goZnVuY3Rpb24oZGVwSHJlZil7XG4gICAgICBpZiAoZm91bmRbZGVwSHJlZl0pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZGVwcy5wdXNoKGRlcEhyZWYpO1xuICAgICAgZm91bmRbZGVwSHJlZl0gPSB0cnVlO1xuICAgICAgaWYgKHRyYW5zaXRpdmUpIHtcbiAgICAgICAgdHJhbnNpdGl2ZURlcHMucHVzaCh0aGlzLl9nZXREZXBlbmRlbmNpZXMoZGVwSHJlZiwgZm91bmQpKTtcbiAgICAgIH1cbiAgICB9LmJpbmQodGhpcykpO1xuICAgIHJldHVybiBQcm9taXNlLmFsbCh0cmFuc2l0aXZlRGVwcyk7XG4gIH0uYmluZCh0aGlzKSkudGhlbihmdW5jdGlvbih0cmFuc2l0aXZlRGVwcykge1xuICAgIHZhciBhbGxkZXBzID0gdHJhbnNpdGl2ZURlcHMucmVkdWNlKGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgIHJldHVybiBhLmNvbmNhdChiKTtcbiAgICB9LCBbXSkuY29uY2F0KGRlcHMpO1xuICAgIHJldHVybiBhbGxkZXBzO1xuICB9KTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIFBPSk8gcmVwcmVzZW50YXRpb24gb2YgdGhlIGltcG9ydFxuICogdHJlZSwgaW4gYSBmb3JtYXQgdGhhdCBtYWludGFpbnMgdGhlIG9yZGVyaW5nIG9mIHRoZSBIVE1MIGltcG9ydHMgc3BlYy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBocmVmIHRoZSBpbXBvcnQgdG8gZ2V0IG1ldGFkYXRhIGZvci5cbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKi9cbkFuYWx5emVyLnByb3RvdHlwZS5tZXRhZGF0YVRyZWUgPSBmdW5jdGlvbiBtZXRhZGF0YVRyZWUoaHJlZikge1xuICByZXR1cm4gdGhpcy5sb2FkKGhyZWYpLnRoZW4oZnVuY3Rpb24obW9ub21lcil7XG4gICAgdmFyIGxvYWRlZEhyZWZzID0ge307XG4gICAgbG9hZGVkSHJlZnNbaHJlZl0gPSB0cnVlO1xuICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVRyZWUobW9ub21lciwgbG9hZGVkSHJlZnMpO1xuICB9LmJpbmQodGhpcykpO1xufTtcblxuQW5hbHl6ZXIucHJvdG90eXBlLl9tZXRhZGF0YVRyZWUgPSBmdW5jdGlvbiBfbWV0YWRhdGFUcmVlKGh0bWxNb25vbWVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRlZEhyZWZzKSB7XG4gIGlmIChsb2FkZWRIcmVmcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbG9hZGVkSHJlZnMgPSB7fTtcbiAgfVxuICByZXR1cm4gaHRtbE1vbm9tZXIubWV0YWRhdGFMb2FkZWQudGhlbihmdW5jdGlvbihtZXRhZGF0YSkge1xuICAgIG1ldGFkYXRhID0ge1xuICAgICAgZWxlbWVudHM6IG1ldGFkYXRhLmVsZW1lbnRzLFxuICAgICAgZmVhdHVyZXM6IG1ldGFkYXRhLmZlYXR1cmVzLFxuICAgICAgaHJlZjogaHRtbE1vbm9tZXIuaHJlZlxuICAgIH07XG4gICAgcmV0dXJuIGh0bWxNb25vbWVyLmRlcHNMb2FkZWQudGhlbihmdW5jdGlvbihocmVmcykge1xuICAgICAgdmFyIGRlcE1ldGFkYXRhID0gW107XG4gICAgICBocmVmcy5mb3JFYWNoKGZ1bmN0aW9uKGhyZWYpIHtcbiAgICAgICAgdmFyIG1ldGFkYXRhUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgaWYgKGRlcE1ldGFkYXRhLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBtZXRhZGF0YVByb21pc2UgPSBkZXBNZXRhZGF0YVtkZXBNZXRhZGF0YS5sZW5ndGggLSAxXTtcbiAgICAgICAgfVxuICAgICAgICBtZXRhZGF0YVByb21pc2UgPSBtZXRhZGF0YVByb21pc2UudGhlbihmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZiAoIWxvYWRlZEhyZWZzW2hyZWZdKSB7XG4gICAgICAgICAgICBsb2FkZWRIcmVmc1tocmVmXSA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFUcmVlKHRoaXMuaHRtbFtocmVmXSwgbG9hZGVkSHJlZnMpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICAgIGRlcE1ldGFkYXRhLnB1c2gobWV0YWRhdGFQcm9taXNlKTtcbiAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGwoZGVwTWV0YWRhdGEpLnRoZW4oZnVuY3Rpb24oaW1wb3J0TWV0YWRhdGEpIHtcbiAgICAgICAgbWV0YWRhdGEuaW1wb3J0cyA9IGltcG9ydE1ldGFkYXRhO1xuICAgICAgICByZXR1cm4gaHRtbE1vbm9tZXIuaHRtbExvYWRlZC50aGVuKGZ1bmN0aW9uKHBhcnNlZEh0bWwpIHtcbiAgICAgICAgICBtZXRhZGF0YS5odG1sID0gcGFyc2VkSHRtbDtcbiAgICAgICAgICBpZiAobWV0YWRhdGEuZWxlbWVudHMpIHtcbiAgICAgICAgICAgIG1ldGFkYXRhLmVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICAgICAgICBhdHRhY2hEb21Nb2R1bGUocGFyc2VkSHRtbCwgZWxlbWVudCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG1ldGFkYXRhO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0uYmluZCh0aGlzKSk7XG4gIH0uYmluZCh0aGlzKSk7XG59O1xuXG4vKipcbiAqIENhbGxzIGBkb201Lm5vZGVXYWxrYCBvbiBlYWNoIGRvY3VtZW50IHRoYXQgYEFuYXl6bGVyYCBoYXMgbGFvZGVkLlxuICogQHBhcmFtICB7T2JqZWN0fSBwcmVkaWNhdGUgQSBkb201IHByZWRpY2F0ZS5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuQW5hbHl6ZXIucHJvdG90eXBlLm5vZGVXYWxrRG9jdW1lbnRzID0gZnVuY3Rpb24gbm9kZVdhbGtEb2N1bWVudHMocHJlZGljYXRlKSB7XG4gIHZhciByZXN1bHRzID0gW107XG4gIGZvciAodmFyIGhyZWYgaW4gdGhpcy5wYXJzZWREb2N1bWVudHMpIHtcbiAgICB2YXIgbmV3Tm9kZXMgPSBkb201Lm5vZGVXYWxrQWxsKHRoaXMucGFyc2VkRG9jdW1lbnRzW2hyZWZdLCBwcmVkaWNhdGUpO1xuICAgIHJlc3VsdHMgPSByZXN1bHRzLmNvbmNhdChuZXdOb2Rlcyk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdHM7XG59O1xuXG4vKiogQW5ub3RhdGVzIGFsbCBsb2FkZWQgbWV0YWRhdGEgd2l0aCBpdHMgZG9jdW1lbnRhdGlvbi4gKi9cbkFuYWx5emVyLnByb3RvdHlwZS5hbm5vdGF0ZSA9IGZ1bmN0aW9uIGFubm90YXRlKCkge1xuICBpZiAodGhpcy5mZWF0dXJlcy5sZW5ndGggPiAwKSB7XG4gICAgdmFyIGZlYXR1cmVFbCA9IGRvY3MuZmVhdHVyZUVsZW1lbnQodGhpcy5mZWF0dXJlcyk7XG4gICAgdGhpcy5lbGVtZW50cy51bnNoaWZ0KGZlYXR1cmVFbCk7XG4gICAgdGhpcy5lbGVtZW50c0J5VGFnTmFtZVtmZWF0dXJlRWwuaXNdID0gZmVhdHVyZUVsO1xuICB9XG5cbiAgdGhpcy5lbGVtZW50cy5mb3JFYWNoKGRvY3MuYW5ub3RhdGVFbGVtZW50KTtcbiAgdGhpcy5iZWhhdmlvcnMuZm9yRWFjaChkb2NzLmFubm90YXRlRWxlbWVudCk7IC8vIFNhbWUgc2hhcGUuXG59O1xuXG5mdW5jdGlvbiBhdHRhY2hEb21Nb2R1bGUocGFyc2VkSW1wb3J0LCBlbGVtZW50KSB7XG4gIHZhciBkb21Nb2R1bGVzID0gcGFyc2VkSW1wb3J0Wydkb20tbW9kdWxlJ107XG4gIGZvciAodmFyIGkgPSAwLCBkb21Nb2R1bGU7IGkgPCBkb21Nb2R1bGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgZG9tTW9kdWxlID0gZG9tTW9kdWxlc1tpXTtcbiAgICBpZiAoZG9tNS5nZXRBdHRyaWJ1dGUoZG9tTW9kdWxlLCAnaWQnKSA9PT0gZWxlbWVudC5pcykge1xuICAgICAgZWxlbWVudC5kb21Nb2R1bGUgPSBkb21Nb2R1bGU7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG59XG5cbi8qKiBSZW1vdmVzIHJlZHVuZGFudCBwcm9wZXJ0aWVzIGZyb20gdGhlIGNvbGxlY3RlZCBkZXNjcmlwdG9ycy4gKi9cbkFuYWx5emVyLnByb3RvdHlwZS5jbGVhbiA9IGZ1bmN0aW9uIGNsZWFuKCkge1xuICB0aGlzLmVsZW1lbnRzLmZvckVhY2goZG9jcy5jbGVhbkVsZW1lbnQpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBBbmFseXplcjtcbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAoYykgMjAxNSBUaGUgUG9seW1lciBQcm9qZWN0IEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBUaGlzIGNvZGUgbWF5IG9ubHkgYmUgdXNlZCB1bmRlciB0aGUgQlNEIHN0eWxlIGxpY2Vuc2UgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0xJQ0VOU0UudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGF1dGhvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9BVVRIT1JTLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBjb250cmlidXRvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9DT05UUklCVVRPUlMudHh0XG4gKiBDb2RlIGRpc3RyaWJ1dGVkIGJ5IEdvb2dsZSBhcyBwYXJ0IG9mIHRoZSBwb2x5bWVyIHByb2plY3QgaXMgYWxzb1xuICogc3ViamVjdCB0byBhbiBhZGRpdGlvbmFsIElQIHJpZ2h0cyBncmFudCBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vUEFURU5UUy50eHRcbiAqL1xuLy8ganNoaW50IG5vZGU6IHRydWVcbid1c2Ugc3RyaWN0JztcblxudmFyIGVzdXRpbCAgICA9IHJlcXVpcmUoJy4vZXN1dGlsJyk7XG52YXIgYXN0VmFsdWUgPSByZXF1aXJlKCcuL2FzdC12YWx1ZScpO1xuXG52YXIgYW5hbHl6ZVByb3BlcnRpZXMgPSBmdW5jdGlvbihub2RlKSB7XG5cbiAgdmFyIGFuYWx5emVkUHJvcHMgPSBbXTtcblxuICBpZiAobm9kZS50eXBlICE9ICdPYmplY3RFeHByZXNzaW9uJykge1xuICAgIHJldHVybiBhbmFseXplZFByb3BzO1xuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5wcm9wZXJ0aWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHByb3BlcnR5ID0gbm9kZS5wcm9wZXJ0aWVzW2ldO1xuICAgIHZhciBwcm9wID0gZXN1dGlsLnRvUHJvcGVydHlEZXNjcmlwdG9yKHByb3BlcnR5KTtcbiAgICBwcm9wLnB1Ymxpc2hlZCA9IHRydWU7XG5cbiAgICBpZiAocHJvcGVydHkudmFsdWUudHlwZSA9PSAnT2JqZWN0RXhwcmVzc2lvbicpIHtcbiAgICAgIC8qKlxuICAgICAgICogUGFyc2UgdGhlIGV4cHJlc3Npb24gaW5zaWRlIGEgcHJvcGVydHkgb2JqZWN0IGJsb2NrLlxuICAgICAgICogcHJvcGVydHk6IHtcbiAgICAgICAqICAga2V5OiB7XG4gICAgICAgKiAgICAgdHlwZTogU3RyaW5nLFxuICAgICAgICogICAgIG5vdGlmeTogdHJ1ZSxcbiAgICAgICAqICAgICB2YWx1ZTogLTEsXG4gICAgICAgKiAgICAgcmVhZE9ubHk6IHRydWUsXG4gICAgICAgKiAgICAgcmVmbGVjdFRvQXR0cmlidXRlOiB0cnVlXG4gICAgICAgKiAgIH1cbiAgICAgICAqIH1cbiAgICAgICAqL1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBwcm9wZXJ0eS52YWx1ZS5wcm9wZXJ0aWVzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIHZhciBwcm9wZXJ0eUFyZyA9IHByb3BlcnR5LnZhbHVlLnByb3BlcnRpZXNbal07XG4gICAgICAgIHZhciBwcm9wZXJ0eUtleSA9IGVzdXRpbC5vYmplY3RLZXlUb1N0cmluZyhwcm9wZXJ0eUFyZy5rZXkpO1xuXG4gICAgICAgIHN3aXRjaChwcm9wZXJ0eUtleSkge1xuICAgICAgICAgIGNhc2UgJ3R5cGUnOiB7XG4gICAgICAgICAgICBwcm9wLnR5cGUgPSBlc3V0aWwub2JqZWN0S2V5VG9TdHJpbmcocHJvcGVydHlBcmcudmFsdWUpO1xuICAgICAgICAgICAgaWYgKHByb3AudHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIHRocm93IHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnSW52YWxpZCB0eXBlIGluIHByb3BlcnR5IG9iamVjdC4nLFxuICAgICAgICAgICAgICAgIGxvY2F0aW9uOiBwcm9wZXJ0eUFyZy5sb2Muc3RhcnRcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnbm90aWZ5Jzoge1xuICAgICAgICAgICAgcHJvcC5ub3RpZnkgPSBhc3RWYWx1ZS5leHByZXNzaW9uVG9WYWx1ZShwcm9wZXJ0eUFyZy52YWx1ZSk7XG4gICAgICAgICAgICBpZiAocHJvcC5ub3RpZnkgPT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgICAgcHJvcC5ub3RpZnkgPSBhc3RWYWx1ZS5DQU5UX0NPTlZFUlQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3JlYWRPbmx5Jzoge1xuICAgICAgICAgICAgcHJvcC5yZWFkT25seSA9IGFzdFZhbHVlLmV4cHJlc3Npb25Ub1ZhbHVlKHByb3BlcnR5QXJnLnZhbHVlKTtcbiAgICAgICAgICAgIGlmIChwcm9wLnJlYWRPbmx5ID09PSB1bmRlZmluZWQpXG4gICAgICAgICAgICAgIHByb3AucmVhZE9ubHkgPSBhc3RWYWx1ZS5DQU5UX0NPTlZFUlQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3JlZmxlY3RUb0F0dHJpYnV0ZSc6IHtcbiAgICAgICAgICAgIHByb3AucmVmbGVjdFRvQXR0cmlidXRlID0gYXN0VmFsdWUuZXhwcmVzc2lvblRvVmFsdWUocHJvcGVydHlBcmcpO1xuICAgICAgICAgICAgaWYgKHByb3AucmVmbGVjdFRvQXR0cmlidXRlID09PSB1bmRlZmluZWQpXG4gICAgICAgICAgICAgIHByb3AucmVmbGVjdFRvQXR0cmlidXRlID0gYXN0VmFsdWUuQ0FOVF9DT05WRVJUO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICd2YWx1ZSc6IHtcbiAgICAgICAgICAgIHByb3AuZGVmYXVsdCA9IGFzdFZhbHVlLmV4cHJlc3Npb25Ub1ZhbHVlKHByb3BlcnR5QXJnLnZhbHVlKTtcbiAgICAgICAgICAgIGlmIChwcm9wLmRlZmF1bHQgPT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgICAgcHJvcC5kZWZhdWx0ID0gYXN0VmFsdWUuQ0FOVF9DT05WRVJUO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFwcm9wLnR5cGUpIHtcbiAgICAgIHRocm93IHtcbiAgICAgICAgbWVzc2FnZTogJ1VuYWJsZSB0byBkZXRlcm1pbmUgbmFtZSBmb3IgcHJvcGVydHkga2V5LicsXG4gICAgICAgIGxvY2F0aW9uOiBub2RlLmxvYy5zdGFydFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBhbmFseXplZFByb3BzLnB1c2gocHJvcCk7XG4gIH1cbiAgcmV0dXJuIGFuYWx5emVkUHJvcHM7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gYW5hbHl6ZVByb3BlcnRpZXM7XG5cbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAoYykgMjAxNSBUaGUgUG9seW1lciBQcm9qZWN0IEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBUaGlzIGNvZGUgbWF5IG9ubHkgYmUgdXNlZCB1bmRlciB0aGUgQlNEIHN0eWxlIGxpY2Vuc2UgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0xJQ0VOU0UudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGF1dGhvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9BVVRIT1JTLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBjb250cmlidXRvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9DT05UUklCVVRPUlMudHh0XG4gKiBDb2RlIGRpc3RyaWJ1dGVkIGJ5IEdvb2dsZSBhcyBwYXJ0IG9mIHRoZSBwb2x5bWVyIHByb2plY3QgaXMgYWxzb1xuICogc3ViamVjdCB0byBhbiBhZGRpdGlvbmFsIElQIHJpZ2h0cyBncmFudCBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vUEFURU5UUy50eHRcbiAqL1xuLy8ganNoaW50IG5vZGU6IHRydWVcbid1c2Ugc3RyaWN0JztcblxuLy8gdXNlZnVsIHRvb2wgdG8gdmlzdWFsaXplIEFTVDogaHR0cDovL2VzcHJpbWEub3JnL2RlbW8vcGFyc2UuaHRtbFxuXG4vKipcbiAqIGNvbnZlcnRzIGxpdGVyYWw6IHtcInR5cGVcIjogXCJMaXRlcmFsXCIsIFwidmFsdWVcIjogNSwgIFwicmF3XCI6IFwiNVwiIH1cbiAqIHRvIHN0cmluZ1xuICovXG5mdW5jdGlvbiBsaXRlcmFsVG9WYWx1ZShsaXRlcmFsKSB7XG4gIHJldHVybiBsaXRlcmFsLnZhbHVlO1xufVxuXG4vKipcbiAqIGNvbnZlcnRzIHVuYXJ5IHRvIHN0cmluZ1xuICogdW5hcnk6IHsgdHlwZTogJ1VuYXJ5RXhwcmVzc2lvbicsIG9wZXJhdG9yOiAnLScsIGFyZ3VtZW50OiB7IC4uLiB9IH1cbiAqL1xuZnVuY3Rpb24gdW5hcnlUb1ZhbHVlKHVuYXJ5KSB7XG4gIHZhciBhcmdWYWx1ZSA9IGV4cHJlc3Npb25Ub1ZhbHVlKHVuYXJ5LmFyZ3VtZW50KTtcbiAgaWYgKGFyZ1ZhbHVlID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuO1xuICByZXR1cm4gdW5hcnkub3BlcmF0b3IgKyBhcmdWYWx1ZTtcbn1cblxuLyoqXG4gKiBjb252ZXJ0cyBpZGVudGlmaWVyIHRvIGl0cyB2YWx1ZVxuICogaWRlbnRpZmllciB7IFwidHlwZVwiOiBcIklkZW50aWZpZXJcIiwgXCJuYW1lXCI6IFwiTnVtYmVyIH1cbiAqL1xuZnVuY3Rpb24gaWRlbnRpZmllclRvVmFsdWUoaWRlbnRpZmllcikge1xuICByZXR1cm4gaWRlbnRpZmllci5uYW1lO1xufVxuXG4vKipcbiAqIEZ1bmN0aW9uIGlzIGEgYmxvY2sgc3RhdGVtZW50LlxuICovXG5mdW5jdGlvbiBmdW5jdGlvbkRlY2xhcmF0aW9uVG9WYWx1ZShmbikge1xuICBpZiAoZm4uYm9keS50eXBlID09IFwiQmxvY2tTdGF0ZW1lbnRcIilcbiAgICByZXR1cm4gYmxvY2tTdGF0ZW1lbnRUb1ZhbHVlKGZuLmJvZHkpO1xufVxuXG5mdW5jdGlvbiBmdW5jdGlvbkV4cHJlc3Npb25Ub1ZhbHVlKGZuKSB7XG4gIGlmIChmbi5ib2R5LnR5cGUgPT0gXCJCbG9ja1N0YXRlbWVudFwiKVxuICAgIHJldHVybiBibG9ja1N0YXRlbWVudFRvVmFsdWUoZm4uYm9keSk7XG59XG4vKipcbiAqIEJsb2NrIHN0YXRlbWVudDogZmluZCBsYXN0IHJldHVybiBzdGF0ZW1lbnQsIGFuZCByZXR1cm4gaXRzIHZhbHVlXG4gKi9cbmZ1bmN0aW9uIGJsb2NrU3RhdGVtZW50VG9WYWx1ZShibG9jaykge1xuICBmb3IgKHZhciBpPWJsb2NrLmJvZHkubGVuZ3RoIC0gMTsgaT49IDA7IGktLSkge1xuICAgIGlmIChibG9jay5ib2R5W2ldLnR5cGUgPT09IFwiUmV0dXJuU3RhdGVtZW50XCIpXG4gICAgICByZXR1cm4gcmV0dXJuU3RhdGVtZW50VG9WYWx1ZShibG9jay5ib2R5W2ldKTtcbiAgfVxufVxuXG4vKipcbiAqIEV2YWx1YXRlcyByZXR1cm4ncyBhcmd1bWVudFxuICovXG5mdW5jdGlvbiByZXR1cm5TdGF0ZW1lbnRUb1ZhbHVlKHJldCkge1xuICByZXR1cm4gZXhwcmVzc2lvblRvVmFsdWUocmV0LmFyZ3VtZW50KTtcbn1cblxuLyoqXG4gKiBFbmNsb3NlIGNvbnRhaW5pbmcgdmFsdWVzIGluIFtdXG4gKi9cbmZ1bmN0aW9uIGFycmF5RXhwcmVzc2lvblRvVmFsdWUoYXJyeSkge1xuICB2YXIgdmFsdWUgPSAnWyc7XG4gIGZvciAodmFyIGk9MDsgaTxhcnJ5LmVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHYgPSBleHByZXNzaW9uVG9WYWx1ZShhcnJ5LmVsZW1lbnRzW2ldKTtcbiAgICBpZiAodiA9PT0gdW5kZWZpbmVkKVxuICAgICAgdiA9IENBTlRfQ09OVkVSVDtcbiAgICBpZiAoaSAhPT0gMClcbiAgICAgIHZhbHVlICs9ICcsICc7XG4gICAgdmFsdWUgKz0gdjtcbiAgfVxuICB2YWx1ZSArPSAnXSc7XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBNYWtlIGl0IGxvb2sgbGlrZSBhbiBvYmplY3RcbiAqL1xuZnVuY3Rpb24gb2JqZWN0RXhwcmVzc2lvblRvVmFsdWUob2JqKSB7XG4gIHZhciB2YWx1ZSA9ICd7JztcbiAgZm9yICh2YXIgaT0wOyBpPG9iai5wcm9wZXJ0aWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGsgPSBleHByZXNzaW9uVG9WYWx1ZShvYmoucHJvcGVydGllc1tpXS5rZXkpO1xuICAgIHZhciB2ID0gZXhwcmVzc2lvblRvVmFsdWUob2JqLnByb3BlcnRpZXNbaV0udmFsdWUpO1xuICAgIGlmICh2ID09PSB1bmRlZmluZWQpXG4gICAgICB2ID0gQ0FOVF9DT05WRVJUO1xuICAgIGlmIChpICE9PSAwKVxuICAgICAgdmFsdWUgKz0gJywgJztcbiAgICB2YWx1ZSArPSAnXCInICsgayArICdcIjogJyArIHY7XG4gIH1cbiAgdmFsdWUgKz0gJ30nO1xuICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogTWVtYmVyRXhwcmVzc2lvbiByZWZlcmVuY2VzIGEgdmFyaWFibGUgd2l0aCBuYW1lXG4gKi9cbmZ1bmN0aW9uIG1lbWJlckV4cHJlc3Npb25Ub1ZhbHVlKG1lbWJlcikge1xuICByZXR1cm4gZXhwcmVzc2lvblRvVmFsdWUobWVtYmVyLm9iamVjdCkgKyBcIi5cIiArIGV4cHJlc3Npb25Ub1ZhbHVlKG1lbWJlci5wcm9wZXJ0eSk7XG59XG5cbi8qKlxuICogVHJpZXMgdG8gZ2V0IGEgdmFsdWUgZnJvbSBleHByZXNzaW9uLiBIYW5kbGVzIExpdGVyYWwsIFVuYXJ5RXhwcmVzc2lvblxuICogcmV0dXJucyB1bmRlZmluZWQgb24gZmFpbHVyZVxuICogdmFsdWVFeHByZXNzaW9uIGV4YW1wbGU6XG4gKiB7IHR5cGU6IFwiTGl0ZXJhbFwiLFxuICovXG5mdW5jdGlvbiBleHByZXNzaW9uVG9WYWx1ZSh2YWx1ZUV4cHJlc3Npb24pIHtcbiAgc3dpdGNoKHZhbHVlRXhwcmVzc2lvbi50eXBlKSB7XG4gICAgY2FzZSAnTGl0ZXJhbCc6XG4gICAgICByZXR1cm4gbGl0ZXJhbFRvVmFsdWUodmFsdWVFeHByZXNzaW9uKTtcbiAgICBjYXNlICdVbmFyeUV4cHJlc3Npb24nOlxuICAgICAgcmV0dXJuIHVuYXJ5VG9WYWx1ZSh2YWx1ZUV4cHJlc3Npb24pO1xuICAgIGNhc2UgJ0lkZW50aWZpZXInOlxuICAgICAgcmV0dXJuIGlkZW50aWZpZXJUb1ZhbHVlKHZhbHVlRXhwcmVzc2lvbik7XG4gICAgY2FzZSAnRnVuY3Rpb25EZWNsYXJhdGlvbic6XG4gICAgICByZXR1cm4gZnVuY3Rpb25EZWNsYXJhdGlvblRvVmFsdWUodmFsdWVFeHByZXNzaW9uKTtcbiAgICBjYXNlICdGdW5jdGlvbkV4cHJlc3Npb24nOlxuICAgICAgcmV0dXJuIGZ1bmN0aW9uRXhwcmVzc2lvblRvVmFsdWUodmFsdWVFeHByZXNzaW9uKTtcbiAgICBjYXNlICdBcnJheUV4cHJlc3Npb24nOlxuICAgICAgcmV0dXJuIGFycmF5RXhwcmVzc2lvblRvVmFsdWUodmFsdWVFeHByZXNzaW9uKTtcbiAgICBjYXNlICdPYmplY3RFeHByZXNzaW9uJzpcbiAgICAgIHJldHVybiBvYmplY3RFeHByZXNzaW9uVG9WYWx1ZSh2YWx1ZUV4cHJlc3Npb24pO1xuICAgIGNhc2UgJ0lkZW50aWZpZXInOlxuICAgICAgcmV0dXJuIGlkZW50aWZpZXJUb1ZhbHVlKHZhbHVlRXhwcmVzc2lvbik7XG4gICAgY2FzZSAnTWVtYmVyRXhwcmVzc2lvbic6XG4gICAgICByZXR1cm4gbWVtYmVyRXhwcmVzc2lvblRvVmFsdWUodmFsdWVFeHByZXNzaW9uKTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuO1xuICB9XG59XG5cbnZhciBDQU5UX0NPTlZFUlQgPSAnVU5LTk9XTic7XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQ0FOVF9DT05WRVJUOiBDQU5UX0NPTlZFUlQsXG4gIGV4cHJlc3Npb25Ub1ZhbHVlOiBleHByZXNzaW9uVG9WYWx1ZVxufTtcbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAoYykgMjAxNSBUaGUgUG9seW1lciBQcm9qZWN0IEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBUaGlzIGNvZGUgbWF5IG9ubHkgYmUgdXNlZCB1bmRlciB0aGUgQlNEIHN0eWxlIGxpY2Vuc2UgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0xJQ0VOU0UudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGF1dGhvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9BVVRIT1JTLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBjb250cmlidXRvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9DT05UUklCVVRPUlMudHh0XG4gKiBDb2RlIGRpc3RyaWJ1dGVkIGJ5IEdvb2dsZSBhcyBwYXJ0IG9mIHRoZSBwb2x5bWVyIHByb2plY3QgaXMgYWxzb1xuICogc3ViamVjdCB0byBhbiBhZGRpdGlvbmFsIElQIHJpZ2h0cyBncmFudCBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vUEFURU5UUy50eHRcbiAqL1xuLy8ganNoaW50IG5vZGU6IHRydWVcbid1c2Ugc3RyaWN0JztcbnZhciBlc3RyYXZlcnNlID0gcmVxdWlyZSgnZXN0cmF2ZXJzZScpO1xuXG52YXIgZG9jcyAgID0gcmVxdWlyZSgnLi9kb2NzJyk7XG52YXIgZXN1dGlsID0gcmVxdWlyZSgnLi9lc3V0aWwnKTtcbnZhciBqc2RvYyAgPSByZXF1aXJlKCcuL2pzZG9jJyk7XG52YXIgYW5hbHl6ZVByb3BlcnRpZXMgPSByZXF1aXJlKCcuL2FuYWx5emUtcHJvcGVydGllcycpO1xudmFyIGFzdFZhbHVlID0gcmVxdWlyZSgnLi9hc3QtdmFsdWUuanMnKTtcblxudmFyIG51bUZlYXR1cmVzID0gMDtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiZWhhdmlvckZpbmRlcigpIHtcbiAgLyoqIEB0eXBlIHshQXJyYXk8QmVoYXZpb3JEZXNjcmlwdG9yPn0gVGhlIGJlaGF2aW9ycyB3ZSd2ZSBmb3VuZC4gKi9cbiAgdmFyIGJlaGF2aW9ycyA9IFtdO1xuXG4gIHZhciBjdXJyZW50QmVoYXZpb3IgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBzcGVjaWFsLWNhc2UgcHJvcGVydGllc1xuICAgKi9cbiAgdmFyIHByb3BlcnR5SGFuZGxlcnMgPSB7XG4gICAgcHJvcGVydGllczogZnVuY3Rpb24obm9kZSkge1xuICAgICAgdmFyIHByb3BzID0gYW5hbHl6ZVByb3BlcnRpZXMobm9kZSk7XG5cbiAgICAgIGZvciAodmFyIGk9MDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGN1cnJlbnRCZWhhdmlvci5wcm9wZXJ0aWVzLnB1c2gocHJvcHNbaV0pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogbWVyZ2VzIGJlaGF2aW9yIHdpdGggcHJlZXhpc3RpbmcgYmVoYXZpb3Igd2l0aCB0aGUgc2FtZSBuYW1lLlxuICAgKiBoZXJlIHRvIHN1cHBvcnQgbXVsdGlwbGUgQHBvbHltZXJCZWhhdmlvciB0YWdzIHJlZmVycmluZ1xuICAgKiB0byBzYW1lIGJlaGF2aW9yLiBTZWUgaXJvbi1tdWx0aS1zZWxlY3RhYmxlIGZvciBleGFtcGxlLlxuICAgKi9cbiAgZnVuY3Rpb24gbWVyZ2VCZWhhdmlvcihuZXdCZWhhdmlvcikge1xuICAgIHZhciBpc0JlaGF2aW9ySW1wbCA9IGZ1bmN0aW9uKGIpIHsgLy8gZmlsdGVyIG91dCBCZWhhdmlvckltcGxcbiAgICAgIHJldHVybiBiLmluZGV4T2YobmV3QmVoYXZpb3IuaXMpID09PSAtMTtcbiAgICB9O1xuICAgIGZvciAodmFyIGk9MDsgaTxiZWhhdmlvcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChuZXdCZWhhdmlvci5pcyAhPT0gYmVoYXZpb3JzW2ldLmlzKVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIC8vIG1lcmdlIGRlc2MsIGxvbmdlc3QgZGVzYyB3aW5zXG4gICAgICBpZiAobmV3QmVoYXZpb3IuZGVzYykge1xuICAgICAgICBpZiAoYmVoYXZpb3JzW2ldLmRlc2MpIHtcbiAgICAgICAgICBpZiAobmV3QmVoYXZpb3IuZGVzYy5sZW5ndGggPiBiZWhhdmlvcnNbaV0uZGVzYy5sZW5ndGgpXG4gICAgICAgICAgICBiZWhhdmlvcnNbaV0uZGVzYyA9IG5ld0JlaGF2aW9yLmRlc2M7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgYmVoYXZpb3JzW2ldLmRlc2MgPSBuZXdCZWhhdmlvci5kZXNjO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBtZXJnZSBkZW1vc1xuICAgICAgYmVoYXZpb3JzW2ldLmRlbW9zID0gKGJlaGF2aW9yc1tpXS5kZW1vcyB8fCBbXSkuY29uY2F0KG5ld0JlaGF2aW9yLmRlbW9zIHx8IFtdKTtcbiAgICAgIC8vIG1lcmdlIGV2ZW50cyxcbiAgICAgIGJlaGF2aW9yc1tpXS5ldmVudHMgPSAoYmVoYXZpb3JzW2ldLmV2ZW50cyB8fCBbXSkuY29uY2F0KG5ld0JlaGF2aW9yLmV2ZW50cyB8fCBbXSk7XG4gICAgICAvLyBtZXJnZSBwcm9wZXJ0aWVzXG4gICAgICBiZWhhdmlvcnNbaV0ucHJvcGVydGllcyA9IChiZWhhdmlvcnNbaV0ucHJvcGVydGllcyB8fCBbXSkuY29uY2F0KG5ld0JlaGF2aW9yLnByb3BlcnRpZXMgfHwgW10pO1xuICAgICAgLy8gbWVyZ2UgYmVoYXZpb3JzXG4gICAgICBiZWhhdmlvcnNbaV0uYmVoYXZpb3JzID1cbiAgICAgICAgKGJlaGF2aW9yc1tpXS5iZWhhdmlvcnMgfHwgW10pLmNvbmNhdChuZXdCZWhhdmlvci5iZWhhdmlvcnMgfHwgW10pXG4gICAgICAgIC5maWx0ZXIoaXNCZWhhdmlvckltcGwpO1xuICAgICAgcmV0dXJuIGJlaGF2aW9yc1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIG5ld0JlaGF2aW9yO1xuICB9XG5cbiAgdmFyIHZpc2l0b3JzID0ge1xuXG4gICAgLyoqXG4gICAgICogTG9vayBmb3Igb2JqZWN0IGRlY2xhcmF0aW9ucyB3aXRoIEBiZWhhdmlvciBpbiB0aGUgZG9jcy5cbiAgICAgKi9cbiAgICBlbnRlclZhcmlhYmxlRGVjbGFyYXRpb246IGZ1bmN0aW9uKG5vZGUsIHBhcmVudCkge1xuICAgICAgaWYgKG5vZGUuZGVjbGFyYXRpb25zLmxlbmd0aCAhPT0gMSkgcmV0dXJuOyAgLy8gQW1iaWd1b3VzLlxuICAgICAgdGhpcy5faW5pdEJlaGF2aW9yKG5vZGUsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGVzdXRpbC5vYmplY3RLZXlUb1N0cmluZyhub2RlLmRlY2xhcmF0aW9uc1swXS5pZCk7XG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogTG9vayBmb3Igb2JqZWN0IGFzc2lnbm1lbnRzIHdpdGggQHBvbHltZXJCZWhhdmlvciBpbiB0aGUgZG9jcy5cbiAgICAgKi9cbiAgICBlbnRlckFzc2lnbm1lbnRFeHByZXNzaW9uOiBmdW5jdGlvbihub2RlLCBwYXJlbnQpIHtcbiAgICAgIHRoaXMuX2luaXRCZWhhdmlvcihwYXJlbnQsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGVzdXRpbC5vYmplY3RLZXlUb1N0cmluZyhub2RlLmxlZnQpO1xuICAgICAgfSk7XG4gICAgfSxcblxuICAgIF9wYXJzZUNoYWluZWRCZWhhdmlvcnM6IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIC8vIGlmIGN1cnJlbnQgYmVoYXZpb3IgaXMgcGFydCBvZiBhbiBhcnJheSwgaXQgZ2V0cyBleHRlbmRlZCBieSBvdGhlciBiZWhhdmlvcnNcbiAgICAgIC8vIGluc2lkZSB0aGUgYXJyYXkuIEV4OlxuICAgICAgLy8gUG9seW1lci5Jcm9uTXVsdGlTZWxlY3RhYmxlQmVoYXZpb3IgPSBbIHsuLi4ufSwgUG9seW1lci5Jcm9uU2VsZWN0YWJsZUJlaGF2aW9yXVxuICAgICAgLy8gV2UgYWRkIHRoZXNlIHRvIGJlaGF2aW9ycyBhcnJheVxuICAgICAgdmFyIGV4cHJlc3Npb247XG4gICAgICBzd2l0Y2gobm9kZS50eXBlKSB7XG4gICAgICAgIGNhc2UgJ0V4cHJlc3Npb25TdGF0ZW1lbnQnOlxuICAgICAgICAgIGV4cHJlc3Npb24gPSBub2RlLmV4cHJlc3Npb24ucmlnaHQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdWYXJpYWJsZURlY2xhcmF0aW9uJzpcbiAgICAgICAgICBleHByZXNzaW9uID0gbm9kZS5kZWNsYXJhdGlvbnMubGVuZ3RoID4gMCA/IG5vZGUuZGVjbGFyYXRpb25zWzBdLmluaXQgOiBudWxsO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIHZhciBjaGFpbmVkID0gW107XG4gICAgICBpZiAoZXhwcmVzc2lvbiAmJiBleHByZXNzaW9uLnR5cGUgPT09ICdBcnJheUV4cHJlc3Npb24nKSB7XG4gICAgICAgIGZvciAodmFyIGk9MDsgaSA8IGV4cHJlc3Npb24uZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZiAoZXhwcmVzc2lvbi5lbGVtZW50c1tpXS50eXBlID09PSAnTWVtYmVyRXhwcmVzc2lvbicpXG4gICAgICAgICAgICBjaGFpbmVkLnB1c2goYXN0VmFsdWUuZXhwcmVzc2lvblRvVmFsdWUoZXhwcmVzc2lvbi5lbGVtZW50c1tpXSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGFpbmVkLmxlbmd0aCA+IDApXG4gICAgICAgICAgY3VycmVudEJlaGF2aW9yLmJlaGF2aW9ycyA9IGNoYWluZWQ7XG4gICAgICB9XG4gICAgfSxcblxuICAgIF9pbml0QmVoYXZpb3I6IGZ1bmN0aW9uKG5vZGUsIGdldE5hbWUpIHtcbiAgICAgIHZhciBjb21tZW50ID0gZXN1dGlsLmdldEF0dGFjaGVkQ29tbWVudChub2RlKTtcbiAgICAgIC8vIFF1aWNrbHkgZmlsdGVyIGRvd24gdG8gcG90ZW50aWFsIGNhbmRpZGF0ZXMuXG4gICAgICBpZiAoIWNvbW1lbnQgfHwgY29tbWVudC5pbmRleE9mKCdAcG9seW1lckJlaGF2aW9yJykgPT09IC0xKSByZXR1cm47XG5cblxuICAgICAgY3VycmVudEJlaGF2aW9yID0ge1xuICAgICAgICB0eXBlOiAnYmVoYXZpb3InLFxuICAgICAgICBkZXNjOiBjb21tZW50LFxuICAgICAgICBldmVudHM6IGVzdXRpbC5nZXRFdmVudENvbW1lbnRzKG5vZGUpLm1hcCggZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICByZXR1cm4geyBkZXNjOiBldmVudH07XG4gICAgICAgIH0pXG4gICAgICB9O1xuXG4gICAgICBkb2NzLmFubm90YXRlQmVoYXZpb3IoY3VycmVudEJlaGF2aW9yKTtcbiAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHdlIGFjdHVhbGx5IHBhcnNlZCBhIGJlaGF2aW9yIHRhZyFcbiAgICAgIGlmICghanNkb2MuaGFzVGFnKGN1cnJlbnRCZWhhdmlvci5qc2RvYywgJ3BvbHltZXJCZWhhdmlvcicpKSB7XG4gICAgICAgIGN1cnJlbnRCZWhhdmlvciA9IG51bGw7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIG5hbWUgPSBqc2RvYy5nZXRUYWcoY3VycmVudEJlaGF2aW9yLmpzZG9jLCAncG9seW1lckJlaGF2aW9yJywgJ25hbWUnKTtcbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICBuYW1lID0gZ2V0TmFtZSgpO1xuICAgICAgfVxuICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignVW5hYmxlIHRvIGRldGVybWluZSBuYW1lIGZvciBAcG9seW1lckJlaGF2aW9yOicsIGNvbW1lbnQpO1xuICAgICAgfVxuICAgICAgY3VycmVudEJlaGF2aW9yLmlzID0gbmFtZTtcblxuICAgICAgdGhpcy5fcGFyc2VDaGFpbmVkQmVoYXZpb3JzKG5vZGUpO1xuXG4gICAgICBjdXJyZW50QmVoYXZpb3IgPSBtZXJnZUJlaGF2aW9yKGN1cnJlbnRCZWhhdmlvcik7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFdlIGFzc3VtZSB0aGF0IHRoZSBvYmplY3QgZXhwcmVzc2lvbiBhZnRlciBzdWNoIGFuIGFzc2lnbm1lbnQgaXMgdGhlXG4gICAgICogYmVoYXZpb3IncyBkZWNsYXJhdGlvbi4gU2VlbXMgdG8gYmUgYSBkZWNlbnQgYXNzdW1wdGlvbiBmb3Igbm93LlxuICAgICAqL1xuICAgIGVudGVyT2JqZWN0RXhwcmVzc2lvbjogZnVuY3Rpb24obm9kZSwgcGFyZW50KSB7XG4gICAgICBpZiAoIWN1cnJlbnRCZWhhdmlvciB8fCBjdXJyZW50QmVoYXZpb3IucHJvcGVydGllcykgcmV0dXJuO1xuXG4gICAgICBjdXJyZW50QmVoYXZpb3IucHJvcGVydGllcyA9IGN1cnJlbnRCZWhhdmlvci5wcm9wZXJ0aWVzIHx8IFtdO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2RlLnByb3BlcnRpZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHByb3AgPSBub2RlLnByb3BlcnRpZXNbaV07XG4gICAgICAgIHZhciBuYW1lID0gZXN1dGlsLm9iamVjdEtleVRvU3RyaW5nKHByb3Aua2V5KTtcbiAgICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgICAgdGhyb3cge1xuICAgICAgICAgICAgbWVzc2FnZTogJ0NhbnQgZGV0ZXJtaW5lIG5hbWUgZm9yIHByb3BlcnR5IGtleS4nLFxuICAgICAgICAgICAgbG9jYXRpb246IG5vZGUubG9jLnN0YXJ0XG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmFtZSBpbiBwcm9wZXJ0eUhhbmRsZXJzKSB7XG4gICAgICAgICAgcHJvcGVydHlIYW5kbGVyc1tuYW1lXShwcm9wLnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBjdXJyZW50QmVoYXZpb3IucHJvcGVydGllcy5wdXNoKGVzdXRpbC50b1Byb3BlcnR5RGVzY3JpcHRvcihwcm9wKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJlaGF2aW9ycy5wdXNoKGN1cnJlbnRCZWhhdmlvcik7XG4gICAgICBjdXJyZW50QmVoYXZpb3IgPSBudWxsO1xuICAgIH0sXG5cbiAgfTtcblxuICByZXR1cm4ge3Zpc2l0b3JzOiB2aXNpdG9ycywgYmVoYXZpb3JzOiBiZWhhdmlvcnN9O1xufTtcbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAoYykgMjAxNSBUaGUgUG9seW1lciBQcm9qZWN0IEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBUaGlzIGNvZGUgbWF5IG9ubHkgYmUgdXNlZCB1bmRlciB0aGUgQlNEIHN0eWxlIGxpY2Vuc2UgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0xJQ0VOU0UudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGF1dGhvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9BVVRIT1JTLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBjb250cmlidXRvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9DT05UUklCVVRPUlMudHh0XG4gKiBDb2RlIGRpc3RyaWJ1dGVkIGJ5IEdvb2dsZSBhcyBwYXJ0IG9mIHRoZSBwb2x5bWVyIHByb2plY3QgaXMgYWxzb1xuICogc3ViamVjdCB0byBhbiBhZGRpdGlvbmFsIElQIHJpZ2h0cyBncmFudCBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vUEFURU5UUy50eHRcbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG4vLyBqc2hpbnQgbm9kZTp0cnVlXG5cbnZhciBqc2RvYyA9IHJlcXVpcmUoJy4vanNkb2MnKTtcblxudmFyIGRvbTUgPSByZXF1aXJlKCdkb201Jyk7XG5cbi8qKiBQcm9wZXJ0aWVzIG9uIGVsZW1lbnQgcHJvdG90eXBlcyB0aGF0IGFyZSBwdXJlbHkgY29uZmlndXJhdGlvbi4gKi9cbnZhciBFTEVNRU5UX0NPTkZJR1VSQVRJT04gPSBbXG4gICdhdHRhY2hlZCcsXG4gICdhdHRyaWJ1dGVDaGFuZ2VkJyxcbiAgJ2NvbmZpZ3VyZScsXG4gICdjb25zdHJ1Y3RvcicsXG4gICdjcmVhdGVkJyxcbiAgJ2RldGFjaGVkJyxcbiAgJ2VuYWJsZUN1c3RvbVN0eWxlUHJvcGVydGllcycsXG4gICdleHRlbmRzJyxcbiAgJ2hvc3RBdHRyaWJ1dGVzJyxcbiAgJ2lzJyxcbiAgJ2xpc3RlbmVycycsXG4gICdtaXhpbnMnLFxuICAnb2JzZXJ2ZXJzJyxcbiAgJ3Byb3BlcnRpZXMnLFxuICAncmVhZHknLFxuICAncmVnaXN0ZXJlZCdcbl07XG5cbi8qKiBUYWdzIHVuZGVyc3Rvb2QgYnkgdGhlIGFubm90YXRpb24gcHJvY2VzcywgdG8gYmUgcmVtb3ZlZCBkdXJpbmcgYGNsZWFuYC4gKi9cbnZhciBIQU5ETEVEX1RBR1MgPSBbXG4gICdwYXJhbScsXG4gICdyZXR1cm4nLFxuICAndHlwZScsXG5dO1xuXG4vKipcbiAqIEFubm90YXRlcyBIeWRyb2x5c2lzIGRlc2NyaXB0b3JzLCBwcm9jZXNzaW5nIGFueSBgZGVzY2AgcHJvcGVydGllcyBhcyBKU0RvYy5cbiAqXG4gKiBZb3UgcHJvYmFibHkgd2FudCB0byB1c2UgYSBtb3JlIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgdGhpcywgc3VjaCBhc1xuICogYGFubm90YXRlRWxlbWVudGAuXG4gKlxuICogUHJvY2Vzc2VkIEpTRG9jIHZhbHVlcyB3aWxsIGJlIG1hZGUgYXZhaWxhYmxlIHZpYSB0aGUgYGpzZG9jYCBwcm9wZXJ0eSBvbiBhXG4gKiBkZXNjcmlwdG9yIG5vZGUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgVGhlIGRlc2NyaXB0b3Igbm9kZSB0byBwcm9jZXNzLlxuICogQHJldHVybiB7T2JqZWN0fSBUaGUgZGVzY3JpcHRvciB0aGF0IHdhcyBnaXZlbi5cbiAqL1xuZnVuY3Rpb24gYW5ub3RhdGUoZGVzY3JpcHRvcikge1xuICBpZiAoIWRlc2NyaXB0b3IgfHwgZGVzY3JpcHRvci5qc2RvYykgcmV0dXJuIGRlc2NyaXB0b3I7XG5cbiAgaWYgKHR5cGVvZiBkZXNjcmlwdG9yLmRlc2MgPT09ICdzdHJpbmcnKSB7XG4gICAgZGVzY3JpcHRvci5qc2RvYyA9IGpzZG9jLnBhcnNlSnNkb2MoZGVzY3JpcHRvci5kZXNjKTtcbiAgICAvLyBXZSB3YW50IHRvIHByZXNlbnQgdGhlIG5vcm1hbGl6ZWQgZm9ybSBvZiBhIGRlc2NyaXB0b3IuXG4gICAgZGVzY3JpcHRvci5qc2RvYy5vcmlnID0gZGVzY3JpcHRvci5kZXNjO1xuICAgIGRlc2NyaXB0b3IuZGVzYyAgICAgICA9IGRlc2NyaXB0b3IuanNkb2MuZGVzY3JpcHRpb247XG4gIH1cblxuICByZXR1cm4gZGVzY3JpcHRvcjtcbn1cblxuLyoqXG4gKiBBbm5vdGF0ZXMgQGV2ZW50LCBAaGVybywgJiBAZGVtbyB0YWdzXG4gKi9cbmZ1bmN0aW9uIGFubm90YXRlRWxlbWVudEhlYWRlcihkZXNjcmlwdG9yKSB7XG4gIGlmIChkZXNjcmlwdG9yLmV2ZW50cykge1xuICAgIGRlc2NyaXB0b3IuZXZlbnRzLmZvckVhY2goZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgIF9hbm5vdGF0ZUV2ZW50KGV2ZW50KTtcbiAgICB9KTtcbiAgICBkZXNjcmlwdG9yLmV2ZW50cy5zb3J0KCBmdW5jdGlvbihhLGIpIHtcbiAgICAgIHJldHVybiBhLm5hbWUubG9jYWxlQ29tcGFyZShiLm5hbWUpO1xuICAgIH0pO1xuICB9XG4gIGRlc2NyaXB0b3IuZGVtb3MgPSBbXTtcbiAgaWYgKGRlc2NyaXB0b3IuanNkb2MgJiYgZGVzY3JpcHRvci5qc2RvYy50YWdzKSB7XG4gICAgZGVzY3JpcHRvci5qc2RvYy50YWdzLmZvckVhY2goIGZ1bmN0aW9uKHRhZykge1xuICAgICAgc3dpdGNoKHRhZy50YWcpIHtcbiAgICAgICAgY2FzZSAnaGVybyc6XG4gICAgICAgICAgZGVzY3JpcHRvci5oZXJvID0gdGFnLm5hbWUgfHwgJ2hlcm8ucG5nJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnZGVtbyc6XG4gICAgICAgICAgZGVzY3JpcHRvci5kZW1vcy5wdXNoKHtcbiAgICAgICAgICAgIGRlc2M6IHRhZy5kZXNjcmlwdGlvbiB8fCAnZGVtbycsXG4gICAgICAgICAgICBwYXRoOiB0YWcubmFtZSB8fCAnZGVtby9pbmRleC5odG1sJ1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogQW5ub3RhdGVzIGRvY3VtZW50YXRpb24gZm91bmQgd2l0aGluIGEgSHlkcm9seXNpcyBlbGVtZW50IGRlc2NyaXB0b3IuIEFsc29cbiAqIHN1cHBvcnRzIGJlaGF2aW9ycy5cbiAqXG4gKiBJZiB0aGUgZWxlbWVudCB3YXMgcHJvY2Vzc2VkIHZpYSBgaHlkcm9saXplYCwgdGhlIGVsZW1lbnQncyBkb2N1bWVudGF0aW9uXG4gKiB3aWxsIGFsc28gYmUgZXh0cmFjdGVkIHZpYSBpdHMgPGRvbS1tb2R1bGU+LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIFRoZSBlbGVtZW50IGRlc2NyaXB0b3IuXG4gKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBkZXNjcmlwdG9yIHRoYXQgd2FzIGdpdmVuLlxuICovXG5mdW5jdGlvbiBhbm5vdGF0ZUVsZW1lbnQoZGVzY3JpcHRvcikge1xuICBpZiAoIWRlc2NyaXB0b3IuZGVzYyAmJiBkZXNjcmlwdG9yLnR5cGUgPT09ICdlbGVtZW50Jykge1xuICAgIGRlc2NyaXB0b3IuZGVzYyA9IF9maW5kRWxlbWVudERvY3MoZGVzY3JpcHRvci5pcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3IuZG9tTW9kdWxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci5zY3JpcHRFbGVtZW50KTtcbiAgfVxuICBhbm5vdGF0ZShkZXNjcmlwdG9yKTtcblxuICAvLyBUaGUgYDxkb20tbW9kdWxlPmAgaXMgdG9vIGxvdyBsZXZlbCBmb3IgbW9zdCBuZWVkcywgYW5kIGl0IGlzIF9ub3RfXG4gIC8vIHNlcmlhbGl6YWJsZS4gU28gd2UgZHJvcCBpdCBub3cgdGhhdCB3ZSd2ZSBleHRyYWN0ZWQgYWxsIHRoZSB1c2VmdWwgYml0c1xuICAvLyBmcm9tIGl0LlxuICBkZWxldGUgZGVzY3JpcHRvci5kb21Nb2R1bGU7XG5cbiAgLy8gRGVzY3JpcHRvcnMgdGhhdCBzaG91bGQgaGF2ZSB0aGVpciBgZGVzY2AgcHJvcGVydGllcyBwYXJzZWQgYXMgSlNEb2MuXG4gIGRlc2NyaXB0b3IucHJvcGVydGllcy5mb3JFYWNoKGZ1bmN0aW9uKHByb3BlcnR5KSB7XG4gICAgLy8gRmVhdHVyZSBwcm9wZXJ0aWVzIGFyZSBzcGVjaWFsLCBjb25maWd1cmF0aW9uIGlzIHJlYWxseSBqdXN0IGEgbWF0dGVyIG9mXG4gICAgLy8gaW5oZXJpdGFuY2UuLi5cbiAgICBhbm5vdGF0ZVByb3BlcnR5KHByb3BlcnR5LCBkZXNjcmlwdG9yLmFic3RyYWN0KTtcbiAgfSk7XG5cbiAgLy8gSXQgbWF5IHNlZW0gbGlrZSBvdmVya2lsbCB0byBhbHdheXMgc29ydCwgYnV0IHdlIGhhdmUgYW4gYXNzdW1wdGlvbiB0aGF0XG4gIC8vIHRoZXNlIHByb3BlcnRpZXMgYXJlIHR5cGljYWxseSBiZWluZyBjb25zdW1lZCBieSB1c2VyLXZpc2libGUgdG9vbGluZy5cbiAgLy8gQXMgc3VjaCwgaXQncyBnb29kIHRvIGhhdmUgY29uc2lzdGVudCBvdXRwdXQvb3JkZXJpbmcgdG8gYWlkIHRoZSB1c2VyLlxuICBkZXNjcmlwdG9yLnByb3BlcnRpZXMuc29ydChmdW5jdGlvbihhLCBiKSB7XG4gICAgLy8gUHJpdmF0ZSBwcm9wZXJ0aWVzIGFyZSBhbHdheXMgbGFzdC5cbiAgICBpZiAoYS5wcml2YXRlICYmICFiLnByaXZhdGUpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH0gZWxzZSBpZiAoIWEucHJpdmF0ZSAmJiBiLnByaXZhdGUpIHtcbiAgICAgIHJldHVybiAtMTtcbiAgICAvLyBPdGhlcndpc2UsIHdlJ3JlIGp1c3Qgc29ydGluZyBhbHBoYWJldGljYWxseS5cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSk7XG4gICAgfVxuICB9KTtcblxuICBhbm5vdGF0ZUVsZW1lbnRIZWFkZXIoZGVzY3JpcHRvcik7XG5cbiAgcmV0dXJuIGRlc2NyaXB0b3I7XG59XG5cbi8qKlxuICogQW5ub3RhdGVzIGJlaGF2aW9yIGRlc2NyaXB0b3IuXG4gKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciBiZWhhdmlvciBkZXNjcmlwdG9yXG4gKiBAcmV0dXJuIHtPYmplY3R9IGRlc2NyaXB0b3IgcGFzc2VkIGluIGFzIHBhcmFtXG4gKi9cbmZ1bmN0aW9uIGFubm90YXRlQmVoYXZpb3IoZGVzY3JpcHRvcikge1xuICBhbm5vdGF0ZShkZXNjcmlwdG9yKTtcblxuICBhbm5vdGF0ZUVsZW1lbnRIZWFkZXIoZGVzY3JpcHRvcik7XG5cbiAgcmV0dXJuIGRlc2NyaXB0b3I7XG59XG5cbi8qKlxuICogQW5ub3RhdGVzIGV2ZW50IGRvY3VtZW50YXRpb25cbiAqL1xuZnVuY3Rpb24gX2Fubm90YXRlRXZlbnQoZGVzY3JpcHRvcikge1xuICBhbm5vdGF0ZShkZXNjcmlwdG9yKTtcbiAgLy8gcHJvY2VzcyBAZXZlbnRcbiAgdmFyIGV2ZW50VGFnID0ganNkb2MuZ2V0VGFnKGRlc2NyaXB0b3IuanNkb2MsICdldmVudCcpO1xuICBkZXNjcmlwdG9yLm5hbWUgPSBldmVudFRhZyA/IGV2ZW50VGFnLmRlc2NyaXB0aW9uIDogXCJOL0FcIjtcblxuICAvLyBwcm9jZXNzIEBwYXJhbXNcbiAgZGVzY3JpcHRvci5wYXJhbXMgPSAoZGVzY3JpcHRvci5qc2RvYy50YWdzIHx8IFtdKVxuICAgIC5maWx0ZXIoIGZ1bmN0aW9uKHRhZykge1xuICAgICAgcmV0dXJuIHRhZy50YWcgPT09ICdwYXJhbSc7XG4gICAgfSlcbiAgICAubWFwKCBmdW5jdGlvbih0YWcpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IHRhZy50eXBlIHx8IFwiTi9BXCIsXG4gICAgICAgIGRlc2M6IHRhZy5kZXNjcmlwdGlvbixcbiAgICAgICAgbmFtZTogdGFnLm5hbWUgfHwgXCJOL0FcIlxuICAgICAgfTtcbiAgICB9KTtcbiAgLy8gcHJvY2VzcyBAcGFyYW1zXG4gIHJldHVybiBkZXNjcmlwdG9yO1xufVxuXG4vKipcbiAqIEFubm90YXRlcyBkb2N1bWVudGF0aW9uIGZvdW5kIGFib3V0IGEgSHlkcm9seXNpcyBwcm9wZXJ0eSBkZXNjcmlwdG9yLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yIFRoZSBwcm9wZXJ0eSBkZXNjcmlwdG9yLlxuICogQHBhcmFtIHtib29sZWFufSBpZ25vcmVDb25maWd1cmF0aW9uIElmIHRydWUsIGBjb25maWd1cmF0aW9uYCBpcyBub3Qgc2V0LlxuICogQHJldHVybiB7T2JqZWN0fSBUaGUgZGVzY3JpcHRpb3IgdGhhdCB3YXMgZ2l2ZW4uXG4gKi9cbmZ1bmN0aW9uIGFubm90YXRlUHJvcGVydHkoZGVzY3JpcHRvciwgaWdub3JlQ29uZmlndXJhdGlvbikge1xuICBhbm5vdGF0ZShkZXNjcmlwdG9yKTtcbiAgaWYgKGRlc2NyaXB0b3IubmFtZVswXSA9PT0gJ18nIHx8IGpzZG9jLmhhc1RhZyhkZXNjcmlwdG9yLmpzZG9jLCAncHJpdmF0ZScpKSB7XG4gICAgZGVzY3JpcHRvci5wcml2YXRlID0gdHJ1ZTtcbiAgfVxuXG4gIGlmICghaWdub3JlQ29uZmlndXJhdGlvbiAmJiBFTEVNRU5UX0NPTkZJR1VSQVRJT04uaW5kZXhPZihkZXNjcmlwdG9yLm5hbWUpICE9PSAtMSkge1xuICAgIGRlc2NyaXB0b3IucHJpdmF0ZSAgICAgICA9IHRydWU7XG4gICAgZGVzY3JpcHRvci5jb25maWd1cmF0aW9uID0gdHJ1ZTtcbiAgfVxuXG4gIC8vIEB0eXBlIEpTRG9jIHdpbnNcbiAgZGVzY3JpcHRvci50eXBlID0ganNkb2MuZ2V0VGFnKGRlc2NyaXB0b3IuanNkb2MsICd0eXBlJywgJ3R5cGUnKSB8fCBkZXNjcmlwdG9yLnR5cGU7XG5cbiAgaWYgKGRlc2NyaXB0b3IudHlwZS5tYXRjaCgvXmZ1bmN0aW9uL2kpKSB7XG4gICAgX2Fubm90YXRlRnVuY3Rpb25Qcm9wZXJ0eShkZXNjcmlwdG9yKTtcbiAgfVxuXG4gIC8vIEBkZWZhdWx0IEpTRG9jIHdpbnNcbiAgdmFyIGRlZmF1bHRUYWcgPSBqc2RvYy5nZXRUYWcoZGVzY3JpcHRvci5qc2RvYywgJ2RlZmF1bHQnKTtcbiAgaWYgKGRlZmF1bHRUYWcgIT09IG51bGwpIHtcbiAgICBkZXNjcmlwdG9yLmRlZmF1bHQgPSAoZGVmYXVsdFRhZy5uYW1lIHx8ICcnKSArIChkZWZhdWx0VGFnLmRlc2NyaXB0aW9uIHx8ICcnKTtcbiAgfVxuXG4gIHJldHVybiBkZXNjcmlwdG9yO1xufVxuXG4vKiogQHBhcmFtIHtPYmplY3R9IGRlc2NyaXB0b3IgKi9cbmZ1bmN0aW9uIF9hbm5vdGF0ZUZ1bmN0aW9uUHJvcGVydHkoZGVzY3JpcHRvcikge1xuICBkZXNjcmlwdG9yLmZ1bmN0aW9uID0gdHJ1ZTtcblxuICB2YXIgcmV0dXJuVGFnID0ganNkb2MuZ2V0VGFnKGRlc2NyaXB0b3IuanNkb2MsICdyZXR1cm4nKTtcbiAgaWYgKHJldHVyblRhZykge1xuICAgIGRlc2NyaXB0b3IucmV0dXJuID0ge1xuICAgICAgdHlwZTogcmV0dXJuVGFnLnR5cGUsXG4gICAgICBkZXNjOiByZXR1cm5UYWcuZGVzY3JpcHRpb24sXG4gICAgfTtcbiAgfVxuXG4gIHZhciBwYXJhbXNCeU5hbWUgPSB7fTtcbiAgKGRlc2NyaXB0b3IucGFyYW1zIHx8IFtdKS5mb3JFYWNoKGZ1bmN0aW9uKHBhcmFtKSB7XG4gICAgcGFyYW1zQnlOYW1lW3BhcmFtLm5hbWVdID0gcGFyYW07XG4gIH0pO1xuICAoZGVzY3JpcHRvci5qc2RvYyAmJiBkZXNjcmlwdG9yLmpzZG9jLnRhZ3MgfHwgW10pLmZvckVhY2goZnVuY3Rpb24odGFnKSB7XG4gICAgaWYgKHRhZy50YWcgIT09ICdwYXJhbScpIHJldHVybjtcbiAgICB2YXIgcGFyYW0gPSBwYXJhbXNCeU5hbWVbdGFnLm5hbWVdO1xuICAgIGlmICghcGFyYW0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwYXJhbS50eXBlID0gdGFnLnR5cGUgfHwgcGFyYW0udHlwZTtcbiAgICBwYXJhbS5kZXNjID0gdGFnLmRlc2NyaXB0aW9uO1xuICB9KTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyByYXcgZmVhdHVyZXMgaW50byBhbiBhYnN0cmFjdCBgUG9seW1lci5CYXNlYCBlbGVtZW50LlxuICpcbiAqIE5vdGUgdGhhdCBkb2NzIG9uIHRoaXMgZWxlbWVudCBfYXJlIG5vdCBwcm9jZXNzZWRfLiBZb3UgbXVzdCBjYWxsXG4gKiBgYW5ub3RhdGVFbGVtZW50YCBvbiBpdCB5b3Vyc2VsZiBpZiB5b3Ugd2lzaCB0aGF0LlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8RmVhdHVyZURlc2NyaXB0b3I+fSBmZWF0dXJlc1xuICogQHJldHVybiB7RWxlbWVudERlc2NyaXB0b3J9XG4gKi9cbmZ1bmN0aW9uIGZlYXR1cmVFbGVtZW50KGZlYXR1cmVzKSB7XG4gIHZhciBwcm9wZXJ0aWVzID0gZmVhdHVyZXMucmVkdWNlKGZ1bmN0aW9uKHJlc3VsdCwgZmVhdHVyZSkge1xuICAgIHJldHVybiByZXN1bHQuY29uY2F0KGZlYXR1cmUucHJvcGVydGllcyk7XG4gIH0sIFtdKTtcblxuICByZXR1cm4ge1xuICAgIHR5cGU6ICAgICAgICdlbGVtZW50JyxcbiAgICBpczogICAgICAgICAnUG9seW1lci5CYXNlJyxcbiAgICBhYnN0cmFjdDogICB0cnVlLFxuICAgIHByb3BlcnRpZXM6IHByb3BlcnRpZXMsXG4gICAgZGVzYzogJ2BQb2x5bWVyLkJhc2VgIGFjdHMgYXMgYSBiYXNlIHByb3RvdHlwZSBmb3IgYWxsIFBvbHltZXIgJyArXG4gICAgICAgICAgJ2VsZW1lbnRzLiBJdCBpcyBjb21wb3NlZCB2aWEgdmFyaW91cyBjYWxscyB0byAnICtcbiAgICAgICAgICAnYFBvbHltZXIuQmFzZS5fYWRkRmVhdHVyZSgpYC5cXG4nICtcbiAgICAgICAgICAnXFxuJyArXG4gICAgICAgICAgJ1RoZSBwcm9wZXJ0aWVzIHJlZmxlY3RlZCBoZXJlIGFyZSB0aGUgY29tYmluZWQgdmlldyBvZiBhbGwgJyArXG4gICAgICAgICAgJ2ZlYXR1cmVzIGZvdW5kIGluIHRoaXMgbGlicmFyeS4gVGhlcmUgbWF5IGJlIG1vcmUgcHJvcGVydGllcyAnICtcbiAgICAgICAgICAnYWRkZWQgdmlhIG90aGVyIGxpYnJhcmllcywgYXMgd2VsbC4nLFxuICB9O1xufVxuXG4vKipcbiAqIENsZWFucyByZWR1bmRhbnQgcHJvcGVydGllcyBmcm9tIGEgZGVzY3JpcHRvciwgYXNzdW1pbmcgdGhhdCB5b3UgaGF2ZSBhbHJlYWR5XG4gKiBjYWxsZWQgYGFubm90YXRlYC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvclxuICovXG5mdW5jdGlvbiBjbGVhbihkZXNjcmlwdG9yKSB7XG4gIGlmICghZGVzY3JpcHRvci5qc2RvYykgcmV0dXJuO1xuICAvLyBUaGUgZG9jdGV4dCB3YXMgd3JpdHRlbiB0byBgZGVzY3JpcHRvci5kZXNjYFxuICBkZWxldGUgZGVzY3JpcHRvci5qc2RvYy5kZXNjcmlwdGlvbjtcbiAgZGVsZXRlIGRlc2NyaXB0b3IuanNkb2Mub3JpZztcblxuICB2YXIgY2xlYW5UYWdzID0gW107XG4gIChkZXNjcmlwdG9yLmpzZG9jLnRhZ3MgfHwgW10pLmZvckVhY2goZnVuY3Rpb24odGFnKSB7XG4gICAgLy8gRHJvcCBhbnkgdGFncyB3ZSd2ZSBjb25zdW1lZC5cbiAgICBpZiAoSEFORExFRF9UQUdTLmluZGV4T2YodGFnLnRhZykgIT09IC0xKSByZXR1cm47XG4gICAgY2xlYW5UYWdzLnB1c2godGFnKTtcbiAgfSk7XG5cbiAgaWYgKGNsZWFuVGFncy5sZW5ndGggPT09IDApIHtcbiAgICAvLyBObyB0YWdzPyBubyBkb2NzIGxlZnQhXG4gICAgZGVsZXRlIGRlc2NyaXB0b3IuanNkb2M7XG4gIH0gZWxzZSB7XG4gICAgZGVzY3JpcHRvci5qc2RvYy50YWdzID0gY2xlYW5UYWdzO1xuICB9XG59XG5cbi8qKlxuICogQ2xlYW5zIHJlZHVuZGFudCBwcm9wZXJ0aWVzIGZyb20gYW4gZWxlbWVudCwgYXNzdW1pbmcgdGhhdCB5b3UgaGF2ZSBhbHJlYWR5XG4gKiBjYWxsZWQgYGFubm90YXRlRWxlbWVudGAuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50RGVzY3JpcHRvcnxCZWhhdmlvckRlc2NyaXB0b3J9IGVsZW1lbnRcbiAqL1xuZnVuY3Rpb24gY2xlYW5FbGVtZW50KGVsZW1lbnQpIHtcbiAgY2xlYW4oZWxlbWVudCk7XG4gIGVsZW1lbnQucHJvcGVydGllcy5mb3JFYWNoKGNsZWFuUHJvcGVydHkpO1xufVxuXG4vKipcbiAqIENsZWFucyByZWR1bmRhbnQgcHJvcGVydGllcyBmcm9tIGEgcHJvcGVydHksIGFzc3VtaW5nIHRoYXQgeW91IGhhdmUgYWxyZWFkeVxuICogY2FsbGVkIGBhbm5vdGF0ZVByb3BlcnR5YC5cbiAqXG4gKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcbiAqL1xuZnVuY3Rpb24gY2xlYW5Qcm9wZXJ0eShwcm9wZXJ0eSkge1xuICBjbGVhbihwcm9wZXJ0eSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGVsZW1lbnRJZFxuICogQHBhcmFtIHtEb2N1bWVudEFTVH0gZG9tTW9kdWxlXG4gKiBAcGFyYW0ge0RvY3VtZW50QVNUfSBzY3JpcHRFbGVtZW50IFRoZSBzY3JpcHQgdGhhdCB0aGUgZWxlbWVudCB3YXMgZGVmaW5lZCBpbi5cbiAqL1xuZnVuY3Rpb24gX2ZpbmRFbGVtZW50RG9jcyhlbGVtZW50SWQsIGRvbU1vZHVsZSwgc2NyaXB0RWxlbWVudCkge1xuICAvLyBOb3RlIHRoYXQgd2UgY29uY2F0ZW5hdGUgZG9jcyBmcm9tIGFsbCBzb3VyY2VzIGlmIHdlIGZpbmQgdGhlbS5cbiAgLy8gZWxlbWVudCBjYW4gYmUgZGVmaW5lZCBpbjpcbiAgLy8gaHRtbCBjb21tZW50IHJpZ2h0IGJlZm9yZSBkb20tbW9kdWxlXG4gIC8vIGh0bWwgY29tbW5ldCByaWdodCBiZWZvcmUgc2NyaXB0IGRlZmluaW5nIHRoZSBtb2R1bGUsIGlmIGRvbS1tb2R1bGUgaXMgZW1wdHlcblxuICB2YXIgZm91bmQgPSBbXTtcblxuICAvLyBEbyB3ZSBoYXZlIGEgSFRNTCBjb21tZW50IG9uIHRoZSBgPGRvbS1tb2R1bGU+YCBvciBgPHNjcmlwdD5gP1xuICAvL1xuICAvLyBDb25mdXNpbmdseSwgd2l0aCBvdXIgY3VycmVudCBzdHlsZSwgdGhlIGNvbW1lbnQgd2lsbCBiZSBhdHRhY2hlZCB0b1xuICAvLyBgPGhlYWQ+YCwgcmF0aGVyIHRoYW4gYmVpbmcgYSBzaWJsaW5nIHRvIHRoZSBgPGRvbS1tb2R1bGU+YFxuICB2YXIgc2VhcmNoUm9vdCA9IGRvbU1vZHVsZSB8fCBzY3JpcHRFbGVtZW50O1xuICB2YXIgcGFyZW50cyA9IGRvbTUubm9kZVdhbGtBbGxQcmlvcihzZWFyY2hSb290LCBkb201LmlzQ29tbWVudE5vZGUpO1xuICB2YXIgY29tbWVudCA9IHBhcmVudHMubGVuZ3RoID4gMCA/IHBhcmVudHNbMF0gOiBudWxsO1xuICBpZiAoY29tbWVudCAmJiBjb21tZW50LmRhdGEpIHtcbiAgICBmb3VuZC5wdXNoKGNvbW1lbnQuZGF0YSk7XG4gIH1cbiAgaWYgKGZvdW5kLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG4gIHJldHVybiBmb3VuZFxuICAgIC5maWx0ZXIoZnVuY3Rpb24oY29tbWVudCkge1xuICAgICAgLy8gc2tpcCBAbGljZW5zZSBjb21tZW50c1xuICAgICAgaWYgKGNvbW1lbnQgJiYgY29tbWVudC5pbmRleE9mKCdAbGljZW5zZScgPT09IC0xKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSlcbiAgICAubWFwKGpzZG9jLnVuaW5kZW50KS5qb2luKCdcXG4nKTtcbn1cblxuZnVuY3Rpb24gX2ZpbmRMYXN0Q2hpbGROYW1lZChuYW1lLCBwYXJlbnQpIHtcbiAgdmFyIGNoaWxkcmVuID0gcGFyZW50LmNoaWxkTm9kZXM7XG4gIGZvciAodmFyIGkgPSBjaGlsZHJlbi5sZW5ndGggLSAxLCBjaGlsZDsgaSA+PSAwOyBpLS0pIHtcbiAgICBjaGlsZCA9IGNoaWxkcmVuW2ldO1xuICAgIGlmIChjaGlsZC5ub2RlTmFtZSA9PT0gbmFtZSkgcmV0dXJuIGNoaWxkO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vLyBUT0RPKG5ldmlyKTogcGFyc2U1LXV0aWxzIVxuZnVuY3Rpb24gX2dldE5vZGVBdHRyaWJ1dGUobm9kZSwgbmFtZSkge1xuICBmb3IgKHZhciBpID0gMCwgYXR0cjsgaSA8IG5vZGUuYXR0cnMubGVuZ3RoOyBpKyspIHtcbiAgICBhdHRyID0gbm9kZS5hdHRyc1tpXTtcbiAgICBpZiAoYXR0ci5uYW1lID09PSBuYW1lKSB7XG4gICAgICByZXR1cm4gYXR0ci52YWx1ZTtcbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGFubm90YXRlOiAgICAgICAgYW5ub3RhdGUsXG4gIGFubm90YXRlRWxlbWVudDogYW5ub3RhdGVFbGVtZW50LFxuICBhbm5vdGF0ZUJlaGF2aW9yOiBhbm5vdGF0ZUJlaGF2aW9yLFxuICBjbGVhbjogICAgICAgICAgIGNsZWFuLFxuICBjbGVhbkVsZW1lbnQ6ICAgIGNsZWFuRWxlbWVudCxcbiAgZmVhdHVyZUVsZW1lbnQ6ICBmZWF0dXJlRWxlbWVudCxcbn07XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTUgVGhlIFBvbHltZXIgUHJvamVjdCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogVGhpcyBjb2RlIG1heSBvbmx5IGJlIHVzZWQgdW5kZXIgdGhlIEJTRCBzdHlsZSBsaWNlbnNlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9MSUNFTlNFLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBhdXRob3JzIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vQVVUSE9SUy50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgY29udHJpYnV0b3JzIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vQ09OVFJJQlVUT1JTLnR4dFxuICogQ29kZSBkaXN0cmlidXRlZCBieSBHb29nbGUgYXMgcGFydCBvZiB0aGUgcG9seW1lciBwcm9qZWN0IGlzIGFsc29cbiAqIHN1YmplY3QgdG8gYW4gYWRkaXRpb25hbCBJUCByaWdodHMgZ3JhbnQgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL1BBVEVOVFMudHh0XG4gKi9cbi8vIGpzaGludCBub2RlOiB0cnVlXG4ndXNlIHN0cmljdCc7XG52YXIgZXN0cmF2ZXJzZSA9IHJlcXVpcmUoJ2VzdHJhdmVyc2UnKTtcblxudmFyIGVzdXRpbCAgICA9IHJlcXVpcmUoJy4vZXN1dGlsJyk7XG52YXIgZmluZEFsaWFzID0gcmVxdWlyZSgnLi9maW5kLWFsaWFzJyk7XG52YXIgYW5hbHl6ZVByb3BlcnRpZXMgPSByZXF1aXJlKCcuL2FuYWx5emUtcHJvcGVydGllcycpO1xudmFyIGFzdFZhbHVlID0gcmVxdWlyZSgnLi9hc3QtdmFsdWUnKTtcblxudmFyIGVsZW1lbnRGaW5kZXIgPSBmdW5jdGlvbiBlbGVtZW50RmluZGVyKCkge1xuICAvKipcbiAgICogVGhlIGxpc3Qgb2YgZWxlbWVudHMgZXhwb3J0ZWQgYnkgZWFjaCB0cmF2ZXJzZWQgc2NyaXB0LlxuICAgKi9cbiAgdmFyIGVsZW1lbnRzID0gW107XG5cbiAgLyoqXG4gICAqIFRoZSBlbGVtZW50IGJlaW5nIGJ1aWx0IGR1cmluZyBhIHRyYXZlcnNhbDtcbiAgICovXG4gIHZhciBlbGVtZW50O1xuXG4gIC8qKlxuICAgKiBhIHNldCBvZiBzcGVjaWFsIGNhc2UgcHJvcGVydGllcy4gdGhlc2Ugc2hvdWxkIG9ubHkgYmUgY2FsbGVkXG4gICAqIHdoZW4gd2Uga25vdyB3ZSdyZSBpbnNpZGUgYW4gZWxlbWVudCBkZWZpbml0aW9uLlxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgdmFyIHByb3BlcnR5SGFuZGxlcnMgPSB7XG4gICAgaXM6IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIGlmIChub2RlLnR5cGUgPT0gJ0xpdGVyYWwnKSB7XG4gICAgICAgIGVsZW1lbnQuaXMgPSBub2RlLnZhbHVlO1xuICAgICAgfVxuICAgIH0sXG4gICAgcHJvcGVydGllczogZnVuY3Rpb24obm9kZSkge1xuXG4gICAgICB2YXIgcHJvcHMgPSBhbmFseXplUHJvcGVydGllcyhub2RlKTtcblxuICAgICAgZm9yICh2YXIgaT0wOyBpPHByb3BzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGVsZW1lbnQucHJvcGVydGllcy5wdXNoKHByb3BzW2ldKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGJlaGF2aW9yczogZnVuY3Rpb24obm9kZSkge1xuICAgICAgaWYgKG5vZGUudHlwZSAhPSAnQXJyYXlFeHByZXNzaW9uJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBlbGVtZW50LmJlaGF2aW9ycyA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBpPTA7IGk8bm9kZS5lbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgdiA9IGFzdFZhbHVlLmV4cHJlc3Npb25Ub1ZhbHVlKG5vZGUuZWxlbWVudHNbaV0pO1xuICAgICAgICBpZiAodiA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHYgPSBhc3RWYWx1ZS5DQU5UX0NPTlZFUlQ7XG4gICAgICAgIGVsZW1lbnQuYmVoYXZpb3JzLnB1c2godik7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHZhciB2aXNpdG9ycyA9IHtcbiAgICBlbnRlckNhbGxFeHByZXNzaW9uOiBmdW5jdGlvbiBlbnRlckNhbGxFeHByZXNzaW9uKG5vZGUsIHBhcmVudCkge1xuICAgICAgdmFyIGNhbGxlZSA9IG5vZGUuY2FsbGVlO1xuICAgICAgaWYgKGNhbGxlZS50eXBlID09ICdJZGVudGlmaWVyJykge1xuXG4gICAgICAgIGlmIChjYWxsZWUubmFtZSA9PSAnUG9seW1lcicpIHtcbiAgICAgICAgICBlbGVtZW50ID0ge1xuICAgICAgICAgICAgdHlwZTogJ2VsZW1lbnQnLFxuICAgICAgICAgICAgZGVzYzogZXN1dGlsLmdldEF0dGFjaGVkQ29tbWVudChwYXJlbnQpLFxuICAgICAgICAgICAgZXZlbnRzOiBlc3V0aWwuZ2V0RXZlbnRDb21tZW50cyhwYXJlbnQpLm1hcCggZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHtkZXNjOiBldmVudH07XG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIGxlYXZlQ2FsbEV4cHJlc3Npb246IGZ1bmN0aW9uIGxlYXZlQ2FsbEV4cHJlc3Npb24obm9kZSwgcGFyZW50KSB7XG4gICAgICB2YXIgY2FsbGVlID0gbm9kZS5jYWxsZWU7XG4gICAgICBpZiAoY2FsbGVlLnR5cGUgPT0gJ0lkZW50aWZpZXInKSB7XG4gICAgICAgIGlmIChjYWxsZWUubmFtZSA9PSAnUG9seW1lcicpIHtcbiAgICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgZWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICAgICAgICAgIGVsZW1lbnQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBlbnRlck9iamVjdEV4cHJlc3Npb246IGZ1bmN0aW9uIGVudGVyT2JqZWN0RXhwcmVzc2lvbihub2RlLCBwYXJlbnQpIHtcbiAgICAgIGlmIChlbGVtZW50ICYmICFlbGVtZW50LnByb3BlcnRpZXMpIHtcbiAgICAgICAgZWxlbWVudC5wcm9wZXJ0aWVzID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5wcm9wZXJ0aWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIHByb3AgPSBub2RlLnByb3BlcnRpZXNbaV07XG4gICAgICAgICAgdmFyIG5hbWUgPSBlc3V0aWwub2JqZWN0S2V5VG9TdHJpbmcocHJvcC5rZXkpO1xuICAgICAgICAgIGlmICghbmFtZSkge1xuICAgICAgICAgICAgdGhyb3cge1xuICAgICAgICAgICAgICBtZXNzYWdlOiAnQ2FudCBkZXRlcm1pbmUgbmFtZSBmb3IgcHJvcGVydHkga2V5LicsXG4gICAgICAgICAgICAgIGxvY2F0aW9uOiBub2RlLmxvYy5zdGFydFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobmFtZSBpbiBwcm9wZXJ0eUhhbmRsZXJzKSB7XG4gICAgICAgICAgICBwcm9wZXJ0eUhhbmRsZXJzW25hbWVdKHByb3AudmFsdWUpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsZW1lbnQucHJvcGVydGllcy5wdXNoKGVzdXRpbC50b1Byb3BlcnR5RGVzY3JpcHRvcihwcm9wKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGVzdHJhdmVyc2UuVmlzaXRvck9wdGlvbi5Ta2lwO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgcmV0dXJuIHt2aXNpdG9yczogdmlzaXRvcnMsIGVsZW1lbnRzOiBlbGVtZW50c307XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGVsZW1lbnRGaW5kZXI7XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTUgVGhlIFBvbHltZXIgUHJvamVjdCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogVGhpcyBjb2RlIG1heSBvbmx5IGJlIHVzZWQgdW5kZXIgdGhlIEJTRCBzdHlsZSBsaWNlbnNlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9MSUNFTlNFLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBhdXRob3JzIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vQVVUSE9SUy50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgY29udHJpYnV0b3JzIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vQ09OVFJJQlVUT1JTLnR4dFxuICogQ29kZSBkaXN0cmlidXRlZCBieSBHb29nbGUgYXMgcGFydCBvZiB0aGUgcG9seW1lciBwcm9qZWN0IGlzIGFsc29cbiAqIHN1YmplY3QgdG8gYW4gYWRkaXRpb25hbCBJUCByaWdodHMgZ3JhbnQgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL1BBVEVOVFMudHh0XG4gKi9cbi8vIGpzaGludCBub2RlOiB0cnVlXG4ndXNlIHN0cmljdCc7XG52YXIgZXN0cmF2ZXJzZSA9IHJlcXVpcmUoXCJlc3RyYXZlcnNlXCIpO1xuXG4vKipcbiAqIFJldHVybnMgd2hldGhlciBhbiBFc3ByZWUgbm9kZSBtYXRjaGVzIGEgcGFydGljdWxhciBvYmplY3QgcGF0aC5cbiAqXG4gKiBlLmcuIHlvdSBoYXZlIGEgTWVtYmVyRXhwcmVzc2lvbiBub2RlLCBhbmQgd2FudCB0byBzZWUgd2hldGhlciBpdCByZXByZXNlbnRzXG4gKiBgRm9vLkJhci5CYXpgOlxuICpcbiAqICAgICBtYXRjaGVzQ2FsbEV4cHJlc3Npb24obm9kZSwgWydGb28nLCAnQmFyJywgJ0JheiddKVxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gZXhwcmVzc2lvbiBUaGUgRXNwcmVlIG5vZGUgdG8gbWF0Y2ggYWdhaW5zdC5cbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gcGF0aCBUaGUgcGF0aCB0byBsb29rIGZvci5cbiAqL1xuZnVuY3Rpb24gbWF0Y2hlc0NhbGxFeHByZXNzaW9uKGV4cHJlc3Npb24sIHBhdGgpIHtcbiAgaWYgKCFleHByZXNzaW9uLnByb3BlcnR5IHx8ICFleHByZXNzaW9uLm9iamVjdCkgcmV0dXJuO1xuICBjb25zb2xlLmFzc2VydChwYXRoLmxlbmd0aCA+PSAyKTtcblxuICAvLyBVbnJhdmVsIGJhY2t3YXJkcywgbWFrZSBzdXJlIHByb3BlcnRpZXMgbWF0Y2ggZWFjaCBzdGVwIG9mIHRoZSB3YXkuXG4gIGlmIChleHByZXNzaW9uLnByb3BlcnR5Lm5hbWUgIT09IHBhdGhbcGF0aC5sZW5ndGggLSAxXSkgcmV0dXJuIGZhbHNlO1xuICAvLyBXZSd2ZSBnb3Qgb3Vyc2VsdmVzIGEgZmluYWwgbWVtYmVyIGV4cHJlc3Npb24uXG4gIGlmIChwYXRoLmxlbmd0aCA9PSAyICYmIGV4cHJlc3Npb24ub2JqZWN0LnR5cGUgPT09ICdJZGVudGlmaWVyJykge1xuICAgIHJldHVybiBleHByZXNzaW9uLm9iamVjdC5uYW1lID09PSBwYXRoWzBdO1xuICB9XG4gIC8vIE5lc3RlZCBleHByZXNzaW9ucy5cbiAgaWYgKHBhdGgubGVuZ3RoID4gMiAmJiBleHByZXNzaW9uLm9iamVjdC50eXBlID09ICdNZW1iZXJFeHByZXNzaW9uJykge1xuICAgIHJldHVybiBtYXRjaGVzQ2FsbEV4cHJlc3Npb24oZXhwcmVzc2lvbi5vYmplY3QsIHBhdGguc2xpY2UoMCwgcGF0aC5sZW5ndGggLSAxKSk7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQHBhcmFtIHtOb2RlfSBrZXkgVGhlIG5vZGUgcmVwcmVzZW50aW5nIGFuIG9iamVjdCBrZXkgb3IgZXhwcmVzc2lvbi5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIG5hbWUgb2YgdGhhdCBrZXkuXG4gKi9cbmZ1bmN0aW9uIG9iamVjdEtleVRvU3RyaW5nKGtleSkge1xuICBpZiAoa2V5LnR5cGUgPT0gJ0lkZW50aWZpZXInKSB7XG4gICAgcmV0dXJuIGtleS5uYW1lO1xuICB9XG4gIGlmIChrZXkudHlwZSA9PSAnTGl0ZXJhbCcpIHtcbiAgICByZXR1cm4ga2V5LnZhbHVlO1xuICB9XG4gIGlmIChrZXkudHlwZSA9PSAnTWVtYmVyRXhwcmVzc2lvbicpIHtcbiAgICByZXR1cm4gb2JqZWN0S2V5VG9TdHJpbmcoa2V5Lm9iamVjdCkgKyAnLicgKyBvYmplY3RLZXlUb1N0cmluZyhrZXkucHJvcGVydHkpO1xuICB9XG59XG5cbnZhciBDTE9TVVJFX0NPTlNUUlVDVE9SX01BUCA9IHtcbiAgJ0Jvb2xlYW4nOiAnYm9vbGVhbicsXG4gICdOdW1iZXInOiAgJ251bWJlcicsXG4gICdTdHJpbmcnOiAgJ3N0cmluZycsXG59O1xuXG4vKipcbiAqIEFTVCBleHByZXNzaW9uIC0+IENsb3N1cmUgdHlwZS5cbiAqXG4gKiBBY2NlcHRzIGxpdGVyYWwgdmFsdWVzLCBhbmQgbmF0aXZlIGNvbnN0cnVjdG9ycy5cbiAqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgQW4gRXNwcmVlIGV4cHJlc3Npb24gbm9kZS5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHR5cGUgb2YgdGhhdCBleHByZXNzaW9uLCBpbiBDbG9zdXJlIHRlcm1zLlxuICovXG5mdW5jdGlvbiBjbG9zdXJlVHlwZShub2RlKSB7XG4gIGlmIChub2RlLnR5cGUubWF0Y2goL0V4cHJlc3Npb24kLykpIHtcbiAgICByZXR1cm4gbm9kZS50eXBlLnN1YnN0cigwLCBub2RlLnR5cGUubGVuZ3RoIC0gMTApO1xuICB9IGVsc2UgaWYgKG5vZGUudHlwZSA9PT0gJ0xpdGVyYWwnKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBub2RlLnZhbHVlO1xuICB9IGVsc2UgaWYgKG5vZGUudHlwZSA9PT0gJ0lkZW50aWZpZXInKSB7XG4gICAgcmV0dXJuIENMT1NVUkVfQ09OU1RSVUNUT1JfTUFQW25vZGUubmFtZV0gfHwgbm9kZS5uYW1lO1xuICB9IGVsc2Uge1xuICAgIHRocm93IHtcbiAgICAgIG1lc3NhZ2U6ICdVbmtub3duIENsb3N1cmUgdHlwZSBmb3Igbm9kZTogJyArIG5vZGUudHlwZSxcbiAgICAgIGxvY2F0aW9uOiBub2RlLmxvYy5zdGFydCxcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtOb2RlfSBub2RlXG4gKiBAcmV0dXJuIHs/c3RyaW5nfVxuICovXG5mdW5jdGlvbiBnZXRBdHRhY2hlZENvbW1lbnQobm9kZSkge1xuICB2YXIgY29tbWVudHMgPSBnZXRMZWFkaW5nQ29tbWVudHMobm9kZSkgfHwgZ2V0TGVhZGluZ0NvbW1lbnRzKG5vZGUua2V5KTtcbiAgaWYgKCFjb21tZW50cykge1xuICAgIHJldHVybjtcbiAgfVxuICByZXR1cm4gY29tbWVudHNbY29tbWVudHMubGVuZ3RoIC0gMV07XG59XG5cbi8qKlxuICogUmV0dXJucyBhbGwgY29tbWVudHMgZnJvbSBhIHRyZWUgZGVmaW5lZCB3aXRoIEBldmVudC5cbiAqIEBwYXJhbSAge05vZGV9IG5vZGUgW2Rlc2NyaXB0aW9uXVxuICogQHJldHVybiB7W3R5cGVdfSAgICAgIFtkZXNjcmlwdGlvbl1cbiAqL1xuZnVuY3Rpb24gZ2V0RXZlbnRDb21tZW50cyhub2RlKSB7XG4gIHZhciBldmVudENvbW1lbnRzID0gW107XG4gIGVzdHJhdmVyc2UudHJhdmVyc2Uobm9kZSwge1xuICAgIGVudGVyOiBmdW5jdGlvbiAobm9kZSkge1xuICAgICAgdmFyIGNvbW1lbnRzID0gKG5vZGUubGVhZGluZ0NvbW1lbnRzIHx8IFtdKS5jb25jYXQobm9kZS50cmFpbGluZ0NvbW1lbnRzIHx8IFtdKVxuICAgICAgICAubWFwKCBmdW5jdGlvbihjb21tZW50QVNUKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbW1lbnRBU1QudmFsdWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5maWx0ZXIoIGZ1bmN0aW9uKGNvbW1lbnQpIHtcbiAgICAgICAgICByZXR1cm4gY29tbWVudC5pbmRleE9mKFwiQGV2ZW50XCIpICE9IC0xO1xuICAgICAgICB9KTtcbiAgICAgIGV2ZW50Q29tbWVudHMgPSBldmVudENvbW1lbnRzLmNvbmNhdChjb21tZW50cyk7XG4gICAgfVxuICB9KTtcbiAgLy8gZGVkdXBcbiAgcmV0dXJuIGV2ZW50Q29tbWVudHMuZmlsdGVyKCBmdW5jdGlvbihlbCwgaW5kZXgsIGFycmF5KSB7XG4gICAgcmV0dXJuIGFycmF5LmluZGV4T2YoZWwpID09PSBpbmRleDtcbiAgfSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtOb2RlfSBub2RlXG4gKiBAcGFyYW1cbiAqIEByZXR1cm4ge0FycmF5LjxzdHJpbmc+fVxuICovXG5mdW5jdGlvbiBnZXRMZWFkaW5nQ29tbWVudHMobm9kZSkge1xuICBpZiAoIW5vZGUpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGNvbW1lbnRzID0gbm9kZS5sZWFkaW5nQ29tbWVudHM7XG4gIGlmICghY29tbWVudHMgfHwgY29tbWVudHMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gIHJldHVybiBjb21tZW50cy5tYXAoZnVuY3Rpb24oY29tbWVudCkge1xuICAgIHJldHVybiBjb21tZW50LnZhbHVlO1xuICB9KTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHBhcnNlNSBQcm9wZXJ0eSBBU1Qgbm9kZSBpbnRvIGl0cyBIeWRyb2x5c2lzIHJlcHJlc2VudGF0aW9uLlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICogQHJldHVybiB7UHJvcGVydHlEZXNjcmlwdG9yfVxuICovXG5mdW5jdGlvbiB0b1Byb3BlcnR5RGVzY3JpcHRvcihub2RlKSB7XG4gIHZhciByZXN1bHQgPSB7XG4gICAgbmFtZTogb2JqZWN0S2V5VG9TdHJpbmcobm9kZS5rZXkpLFxuICAgIHR5cGU6IGNsb3N1cmVUeXBlKG5vZGUudmFsdWUpLFxuICAgIGRlc2M6IGdldEF0dGFjaGVkQ29tbWVudChub2RlKVxuICB9O1xuXG4gIGlmIChub2RlLnZhbHVlLnR5cGUgPT09ICdGdW5jdGlvbkV4cHJlc3Npb24nKSB7XG4gICAgcmVzdWx0LnBhcmFtcyA9IChub2RlLnZhbHVlLnBhcmFtcyB8fCBbXSkubWFwKGZ1bmN0aW9uKHBhcmFtKSB7XG4gICAgICByZXR1cm4ge25hbWU6IHBhcmFtLm5hbWV9O1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGNsb3N1cmVUeXBlOiAgICAgICAgICAgY2xvc3VyZVR5cGUsXG4gIGdldEF0dGFjaGVkQ29tbWVudDogICAgZ2V0QXR0YWNoZWRDb21tZW50LFxuICBnZXRFdmVudENvbW1lbnRzOiAgICAgIGdldEV2ZW50Q29tbWVudHMsXG4gIG1hdGNoZXNDYWxsRXhwcmVzc2lvbjogbWF0Y2hlc0NhbGxFeHByZXNzaW9uLFxuICBvYmplY3RLZXlUb1N0cmluZzogICAgIG9iamVjdEtleVRvU3RyaW5nLFxuICB0b1Byb3BlcnR5RGVzY3JpcHRvcjogIHRvUHJvcGVydHlEZXNjcmlwdG9yLFxufTtcbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAoYykgMjAxNSBUaGUgUG9seW1lciBQcm9qZWN0IEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBUaGlzIGNvZGUgbWF5IG9ubHkgYmUgdXNlZCB1bmRlciB0aGUgQlNEIHN0eWxlIGxpY2Vuc2UgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0xJQ0VOU0UudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGF1dGhvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9BVVRIT1JTLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBjb250cmlidXRvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9DT05UUklCVVRPUlMudHh0XG4gKiBDb2RlIGRpc3RyaWJ1dGVkIGJ5IEdvb2dsZSBhcyBwYXJ0IG9mIHRoZSBwb2x5bWVyIHByb2plY3QgaXMgYWxzb1xuICogc3ViamVjdCB0byBhbiBhZGRpdGlvbmFsIElQIHJpZ2h0cyBncmFudCBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vUEFURU5UUy50eHRcbiAqL1xuLy8ganNoaW50IG5vZGU6IHRydWVcbid1c2Ugc3RyaWN0JztcbnZhciBlc3RyYXZlcnNlID0gcmVxdWlyZSgnZXN0cmF2ZXJzZScpO1xuXG52YXIgZXN1dGlsID0gcmVxdWlyZSgnLi9lc3V0aWwnKTtcblxudmFyIG51bUZlYXR1cmVzID0gMDtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBmZWF0dXJlRmluZGVyKCkge1xuICAvKiogQHR5cGUgeyFBcnJheTxGZWF0dXJlRGVzY3JpcHRvcj59IFRoZSBmZWF0dXJlcyB3ZSd2ZSBmb3VuZC4gKi9cbiAgdmFyIGZlYXR1cmVzID0gW107XG5cbiAgdmFyIHZpc2l0b3JzID0ge1xuXG4gICAgZW50ZXJDYWxsRXhwcmVzc2lvbjogZnVuY3Rpb24gZW50ZXJDYWxsRXhwcmVzc2lvbihub2RlLCBwYXJlbnQpIHtcbiAgICAgIGlmICghZXN1dGlsLm1hdGNoZXNDYWxsRXhwcmVzc2lvbihub2RlLmNhbGxlZSwgWydQb2x5bWVyJywgJ0Jhc2UnLCAnX2FkZEZlYXR1cmUnXSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLyoqIEB0eXBlIHshRmVhdHVyZURlc2NyaXB0b3J9ICovXG4gICAgICB2YXIgZmVhdHVyZSA9IHt9O1xuICAgICAgdGhpcy5fZXh0cmFjdERlc2MoZmVhdHVyZSwgbm9kZSwgcGFyZW50KTtcbiAgICAgIHRoaXMuX2V4dHJhY3RQcm9wZXJ0aWVzKGZlYXR1cmUsIG5vZGUsIHBhcmVudCk7XG5cbiAgICAgIGZlYXR1cmVzLnB1c2goZmVhdHVyZSk7XG4gICAgfSxcblxuICAgIF9leHRyYWN0RGVzYzogZnVuY3Rpb24gX2V4dHJhY3REZXNjKGZlYXR1cmUsIG5vZGUsIHBhcmVudCkge1xuICAgICAgZmVhdHVyZS5kZXNjID0gZXN1dGlsLmdldEF0dGFjaGVkQ29tbWVudChwYXJlbnQpO1xuICAgIH0sXG5cbiAgICBfZXh0cmFjdFByb3BlcnRpZXM6IGZ1bmN0aW9uIF9leHRyYWN0UHJvcGVydGllcyhmZWF0dXJlLCBub2RlLCBwYXJlbnQpIHtcbiAgICAgIHZhciBmZWF0dXJlTm9kZSA9IG5vZGUuYXJndW1lbnRzWzBdO1xuICAgICAgaWYgKGZlYXR1cmVOb2RlLnR5cGUgIT09ICdPYmplY3RFeHByZXNzaW9uJykge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAnRXhwZWN0ZWQgZmlyc3QgYXJndW1lbnQgdG8gUG9seW1lci5CYXNlLl9hZGRGZWF0dXJlIHRvIGJlIGFuIG9iamVjdC4nLFxuICAgICAgICAgICAgJ0dvdCcsIGZlYXR1cmVOb2RlLnR5cGUsICdpbnN0ZWFkLicpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoIWZlYXR1cmVOb2RlLnByb3BlcnRpZXMpIHJldHVybjtcblxuICAgICAgZmVhdHVyZS5wcm9wZXJ0aWVzID0gZmVhdHVyZU5vZGUucHJvcGVydGllcy5tYXAoZXN1dGlsLnRvUHJvcGVydHlEZXNjcmlwdG9yKTtcbiAgICB9LFxuXG4gIH07XG5cbiAgcmV0dXJuIHt2aXNpdG9yczogdmlzaXRvcnMsIGZlYXR1cmVzOiBmZWF0dXJlc307XG59O1xuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IChjKSAyMDE1IFRoZSBQb2x5bWVyIFByb2plY3QgQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFRoaXMgY29kZSBtYXkgb25seSBiZSB1c2VkIHVuZGVyIHRoZSBCU0Qgc3R5bGUgbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vTElDRU5TRS50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgYXV0aG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0FVVEhPUlMudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGNvbnRyaWJ1dG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0NPTlRSSUJVVE9SUy50eHRcbiAqIENvZGUgZGlzdHJpYnV0ZWQgYnkgR29vZ2xlIGFzIHBhcnQgb2YgdGhlIHBvbHltZXIgcHJvamVjdCBpcyBhbHNvXG4gKiBzdWJqZWN0IHRvIGFuIGFkZGl0aW9uYWwgSVAgcmlnaHRzIGdyYW50IGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9QQVRFTlRTLnR4dFxuICovXG4vLyBqc2hpbnQgbm9kZTogdHJ1ZVxuJ3VzZSBzdHJpY3QnO1xudmFyIGZpbmRBbGlhcyA9IGZ1bmN0aW9uIGZpbmRBbGlhcyhuYW1lcywgYWxpYXNlcywgbmFtZSkge1xuICBpZiAoIW5hbWVzKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIGFsaWFzZXNbbmFtZXMuaW5kZXhPZihuYW1lKV07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZpbmRBbGlhcztcbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAoYykgMjAxNSBUaGUgUG9seW1lciBQcm9qZWN0IEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBUaGlzIGNvZGUgbWF5IG9ubHkgYmUgdXNlZCB1bmRlciB0aGUgQlNEIHN0eWxlIGxpY2Vuc2UgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0xJQ0VOU0UudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGF1dGhvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9BVVRIT1JTLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBjb250cmlidXRvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9DT05UUklCVVRPUlMudHh0XG4gKiBDb2RlIGRpc3RyaWJ1dGVkIGJ5IEdvb2dsZSBhcyBwYXJ0IG9mIHRoZSBwb2x5bWVyIHByb2plY3QgaXMgYWxzb1xuICogc3ViamVjdCB0byBhbiBhZGRpdGlvbmFsIElQIHJpZ2h0cyBncmFudCBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vUEFURU5UUy50eHRcbiAqL1xuLy8ganNoaW50IG5vZGU6IHRydWVcbid1c2Ugc3RyaWN0JztcbnZhciBkb201ID0gcmVxdWlyZSgnZG9tNScpO1xuXG52YXIgcCA9IGRvbTUucHJlZGljYXRlcztcblxudmFyIGlzSHRtbEltcG9ydE5vZGUgPSBwLkFORChcbiAgcC5oYXNUYWdOYW1lKCdsaW5rJyksXG4gIHAuaGFzQXR0clZhbHVlKCdyZWwnLCAnaW1wb3J0JyksXG4gIHAuTk9UKFxuICAgIHAuaGFzQXR0clZhbHVlKCd0eXBlJywgJ2NzcycpXG4gIClcbik7XG5cbnZhciBpc1N0eWxlTm9kZSA9IHAuT1IoXG4gIC8vIGlubGluZSBzdHlsZVxuICBwLmhhc1RhZ05hbWUoJ3N0eWxlJyksXG4gIC8vIGV4dGVybmFsIHN0eWxlc2hlZXRcbiAgcC5BTkQoXG4gICAgcC5oYXNUYWdOYW1lKCdsaW5rJyksXG4gICAgcC5oYXNBdHRyVmFsdWUoJ3JlbCcsICdzdHlsZXNoZWV0JylcbiAgKSxcbiAgLy8gcG9seW1lciBzcGVjaWZpYyBleHRlcm5hbCBzdHlsZXNoZWV0XG4gIHAuQU5EKFxuICAgIHAuaGFzVGFnTmFtZSgnbGluaycpLFxuICAgIHAuaGFzQXR0clZhbHVlKCdyZWwnLCAnaW1wb3J0JyksXG4gICAgcC5oYXNBdHRyVmFsdWUoJ3R5cGUnLCAnY3NzJylcbiAgKVxuKTtcblxuZnVuY3Rpb24gYWRkTm9kZShub2RlLCByZWdpc3RyeSkge1xuICBpZiAoaXNIdG1sSW1wb3J0Tm9kZShub2RlKSkge1xuICAgIHJlZ2lzdHJ5LmltcG9ydC5wdXNoKG5vZGUpO1xuICB9IGVsc2UgaWYgKGlzU3R5bGVOb2RlKG5vZGUpKSB7XG4gICAgcmVnaXN0cnkuc3R5bGUucHVzaChub2RlKTtcbiAgfSBlbHNlIGlmIChyZWdpc3RyeS5oYXNPd25Qcm9wZXJ0eShub2RlLnRhZ05hbWUpKSB7XG4gICAgcmVnaXN0cnlbbm9kZS50YWdOYW1lXS5wdXNoKG5vZGUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldExpbmVBbmRDb2x1bW4oc3RyaW5nLCBjaGFyTnVtYmVyKSB7XG4gIGlmIChjaGFyTnVtYmVyID4gc3RyaW5nLmxlbmd0aCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgLy8gVE9ETyhham8pOiBDYWNoaW5nIHRoZSBsaW5lIGxlbmd0aHMgb2YgZWFjaCBkb2N1bWVudCBjb3VsZCBiZSBtdWNoIGZhc3Rlci5cbiAgdmFyIHNsaWNlZCA9IHN0cmluZy5zbGljZSgwLGNoYXJOdW1iZXIrMSk7XG4gIHZhciBzcGxpdCA9IHNsaWNlZC5zcGxpdCgnXFxuJyk7XG4gIHZhciBsaW5lID0gc3BsaXQubGVuZ3RoO1xuICB2YXIgY29sdW1uID0gc3BsaXRbc3BsaXQubGVuZ3RoIC0gMV0ubGVuZ3RoO1xuICByZXR1cm4ge2xpbmU6IGxpbmUsIGNvbHVtbjogY29sdW1ufTtcbn1cblxuLyoqXG4qIFBhcnNlNSdzIHJlcHJlc2VudGF0aW9uIG9mIGEgcGFyc2VkIGh0bWwgZG9jdW1lbnQuXG4qIEB0eXBlZGVmIHtPYmplY3R9IERvY3VtZW50QVNUXG4qL1xuXG4vKipcbiogVGhlIEFTVHMgb2YgdGhlIEhUTUwgZWxlbWVudHMgbmVlZGVkIHRvIHJlcHJlc2VudCBQb2x5bWVyIGVsZW1lbnRzLlxuKiBAdHlwZWRlZiB7T2JqZWN0fSBQYXJzZWRJbXBvcnRcbiogQHByb3BlcnR5IHtBcnJheTxEb2N1bWVudEFTVD59IHRlbXBsYXRlIFRoZSBlbnRyeSBwb2ludHMgdG8gdGhlIEFTVCBhdCBlYWNoIG91dGVybW9zdCB0ZW1wbGF0ZSB0YWcuXG4qIEBwcm9wZXJ0eSB7QXJyYXk8RG9jdW1lbnRBU1Q+fSBzY3JpcHQgVGhlIGVudHJ5IHBvaW50cyB0byB0aGUgQVNUIGF0IGVhY2ggc2NyaXB0IHRhZyBub3QgaW5zaWRlIGEgdGVtcGxhdGUuXG4qIEBwcm9wZXJ0eSB7QXJyYXk8RG9jdW1lbnRBU1Q+fSBzdHlsZSBUaGUgZW50cnkgcG9pbnRzIHRvIHRoZSBBU1QgYXQgc3R5bGUgdGFnIG91dHNpZGUgYSB0ZW1wbGF0ZS5cbiogQHByb3BlcnR5IHtBcnJheTxEb2N1bWVudEFTVD59IGRvbS1tb2R1bGUgVGhlIGVudHJ5IHBvaW50cyB0byB0aGUgQVNUIGF0IGVhY2ggb3V0ZXJtb3N0IGRvbS1tb2R1bGUgZWxlbWVudC5cbiogQHByb3BlcnR5IHtEb2N1bWVudEFTVH0gYXN0IFRoZSBmdWxsIHBhcnNlNSBhc3QgZm9yIHRoZSBkb2N1bWVudC5cbiovXG5cbi8qKlxuKiBQYXJzZSBodG1sIGludG8gQVNUcy5cbiogQHBhcmFtIHtzdHJpbmd9IGh0bWxTdHJpbmcgQSB1dGY4LCBodG1sNSBkb2N1bWVudCBjb250YWluaW5nIHBvbHltZXIgZWxlbWVudCBvciBtb2R1bGUgZGVmaW5pdG9ucy5cbiogQHBhcmFtIHtzdHJpbmd9IGhyZWYgICAgICAgVGhlIHBhdGggb2YgdGhlIGRvY3VtZW50LlxuKiBAcmV0dXJuIHtQYXJzZWRJbXBvcnR9XG4qL1xudmFyIGltcG9ydFBhcnNlID0gZnVuY3Rpb24gaW1wb3J0UGFyc2UoaHRtbFN0cmluZywgaHJlZikge1xuICB2YXIgZG9jO1xuICB0cnkge1xuICAgIGRvYyA9IGRvbTUucGFyc2UoaHRtbFN0cmluZywge2xvY2F0aW9uSW5mbzogdHJ1ZX0pO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBjb25zb2xlLmxvZyhlcnIpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gQWRkIGxpbmUvY29sdW1uIGluZm9ybWF0aW9uXG4gIGRvbTUudHJlZU1hcChkb2MsIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAobm9kZS5fX2xvY2F0aW9uICYmIG5vZGUuX19sb2NhdGlvbi5zdGFydCA+PSAwKSB7XG4gICAgICBub2RlLl9fbG9jYXRpb25EZXRhaWwgPSBnZXRMaW5lQW5kQ29sdW1uKGh0bWxTdHJpbmcsIG5vZGUuX19sb2NhdGlvbi5zdGFydCk7XG4gICAgICBpZiAoaHJlZikge1xuICAgICAgICBub2RlLl9fb3duZXJEb2N1bWVudCA9IGhyZWY7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICB2YXIgcmVnaXN0cnkgPSB7XG4gICAgICBiYXNlOiBbXSxcbiAgICAgIHRlbXBsYXRlOiBbXSxcbiAgICAgIHNjcmlwdDogW10sXG4gICAgICBzdHlsZTogW10sXG4gICAgICBpbXBvcnQ6IFtdLFxuICAgICAgJ2RvbS1tb2R1bGUnOiBbXX07XG5cbiAgdmFyIHF1ZXVlID0gW10uY29uY2F0KGRvYy5jaGlsZE5vZGVzKTtcbiAgdmFyIG5leHROb2RlO1xuICB3aGlsZSAocXVldWUubGVuZ3RoID4gMCkge1xuICAgIG5leHROb2RlID0gcXVldWUuc2hpZnQoKTtcbiAgICBpZiAobmV4dE5vZGUgJiYgbmV4dE5vZGUudGFnTmFtZSkge1xuICAgICAgcXVldWUgPSBxdWV1ZS5jb25jYXQobmV4dE5vZGUuY2hpbGROb2Rlcyk7XG4gICAgICBhZGROb2RlKG5leHROb2RlLCByZWdpc3RyeSk7XG4gICAgfVxuICB9XG4gIHJlZ2lzdHJ5LmFzdCA9IGRvYztcbiAgcmV0dXJuIHJlZ2lzdHJ5O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBpbXBvcnRQYXJzZTtcbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAoYykgMjAxNSBUaGUgUG9seW1lciBQcm9qZWN0IEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBUaGlzIGNvZGUgbWF5IG9ubHkgYmUgdXNlZCB1bmRlciB0aGUgQlNEIHN0eWxlIGxpY2Vuc2UgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0xJQ0VOU0UudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGF1dGhvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9BVVRIT1JTLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBjb250cmlidXRvcnMgbWF5IGJlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9DT05UUklCVVRPUlMudHh0XG4gKiBDb2RlIGRpc3RyaWJ1dGVkIGJ5IEdvb2dsZSBhcyBwYXJ0IG9mIHRoZSBwb2x5bWVyIHByb2plY3QgaXMgYWxzb1xuICogc3ViamVjdCB0byBhbiBhZGRpdGlvbmFsIElQIHJpZ2h0cyBncmFudCBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vUEFURU5UUy50eHRcbiAqL1xuLyoqXG4qIEZpbmRzIGFuZCBhbm5vdGF0ZXMgdGhlIFBvbHltZXIoKSBhbmQgbW9kdWxhdGUoKSBjYWxscyBpbiBqYXZhc2NyaXB0LlxuKi9cbi8vIGpzaGludCBub2RlOiB0cnVlXG4ndXNlIHN0cmljdCc7XG52YXIgZXNwcmVlID0gcmVxdWlyZSgnZXNwcmVlJyk7XG52YXIgZXN0cmF2ZXJzZSA9IHJlcXVpcmUoJ2VzdHJhdmVyc2UnKTtcblxudmFyIGJlaGF2aW9yRmluZGVyID0gcmVxdWlyZSgnLi9iZWhhdmlvci1maW5kZXInKTtcbnZhciBlbGVtZW50RmluZGVyICA9IHJlcXVpcmUoJy4vZWxlbWVudC1maW5kZXInKTtcbnZhciBmZWF0dXJlRmluZGVyICA9IHJlcXVpcmUoJy4vZmVhdHVyZS1maW5kZXInKTtcblxuZnVuY3Rpb24gdHJhdmVyc2UodmlzaXRvclJlZ2lzdHJpZXMpIHtcbiAgdmFyIHZpc2l0b3I7XG4gIGZ1bmN0aW9uIGFwcGx5VmlzaXRvcnMobmFtZSwgbm9kZSwgcGFyZW50KSB7XG4gICAgdmFyIHJldHVyblZhbDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZpc2l0b3JSZWdpc3RyaWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAobmFtZSBpbiB2aXNpdG9yUmVnaXN0cmllc1tpXSkge1xuICAgICAgICByZXR1cm5WYWwgPSB2aXNpdG9yUmVnaXN0cmllc1tpXVtuYW1lXShub2RlLCBwYXJlbnQpO1xuICAgICAgICBpZiAocmV0dXJuVmFsKSB7XG4gICAgICAgICAgcmV0dXJuIHJldHVyblZhbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4ge1xuICAgIGVudGVyOiBmdW5jdGlvbihub2RlLCBwYXJlbnQpIHtcbiAgICAgIHZpc2l0b3IgPSAnZW50ZXInICsgbm9kZS50eXBlO1xuICAgICAgcmV0dXJuIGFwcGx5VmlzaXRvcnModmlzaXRvciwgbm9kZSwgcGFyZW50KTtcbiAgICB9LFxuICAgIGxlYXZlOiBmdW5jdGlvbihub2RlLCBwYXJlbnQpIHtcbiAgICAgIHZpc2l0b3IgPSAnbGVhdmUnICsgbm9kZS50eXBlO1xuICAgICAgcmV0dXJuIGFwcGx5VmlzaXRvcnModmlzaXRvciwgbm9kZSwgcGFyZW50KTtcbiAgICB9XG4gIH07XG59XG5cbnZhciBqc1BhcnNlID0gZnVuY3Rpb24ganNQYXJzZShqc1N0cmluZykge1xuICB2YXIgc2NyaXB0ID0gZXNwcmVlLnBhcnNlKGpzU3RyaW5nLCB7XG4gICAgYXR0YWNoQ29tbWVudDogdHJ1ZSxcbiAgICBjb21tZW50OiB0cnVlLFxuICAgIGxvYzogdHJ1ZSxcbiAgICBlY21hRmVhdHVyZXM6IHtcbiAgICAgIGFycm93RnVuY3Rpb25zOiB0cnVlLFxuICAgICAgYmxvY2tCaW5kaW5nczogdHJ1ZSxcbiAgICAgIGRlc3RydWN0dXJpbmc6IHRydWUsXG4gICAgICByZWdleFlGbGFnOiB0cnVlLFxuICAgICAgcmVnZXhVRmxhZzogdHJ1ZSxcbiAgICAgIHRlbXBsYXRlU3RyaW5nczogdHJ1ZSxcbiAgICAgIGJpbmFyeUxpdGVyYWxzOiB0cnVlLFxuICAgICAgdW5pY29kZUNvZGVQb2ludEVzY2FwZXM6IHRydWUsXG4gICAgICBkZWZhdWx0UGFyYW1zOiB0cnVlLFxuICAgICAgcmVzdFBhcmFtczogdHJ1ZSxcbiAgICAgIGZvck9mOiB0cnVlLFxuICAgICAgb2JqZWN0TGl0ZXJhbENvbXB1dGVkUHJvcGVydGllczogdHJ1ZSxcbiAgICAgIG9iamVjdExpdGVyYWxTaG9ydGhhbmRNZXRob2RzOiB0cnVlLFxuICAgICAgb2JqZWN0TGl0ZXJhbFNob3J0aGFuZFByb3BlcnRpZXM6IHRydWUsXG4gICAgICBvYmplY3RMaXRlcmFsRHVwbGljYXRlUHJvcGVydGllczogdHJ1ZSxcbiAgICAgIGdlbmVyYXRvcnM6IHRydWUsXG4gICAgICBzcHJlYWQ6IHRydWUsXG4gICAgICBjbGFzc2VzOiB0cnVlLFxuICAgICAgbW9kdWxlczogdHJ1ZSxcbiAgICAgIGpzeDogdHJ1ZSxcbiAgICAgIGdsb2JhbFJldHVybjogdHJ1ZSxcbiAgICB9XG4gIH0pO1xuXG4gIHZhciBmZWF0dXJlSW5mbyA9IGZlYXR1cmVGaW5kZXIoKTtcbiAgdmFyIGJlaGF2aW9ySW5mbyA9IGJlaGF2aW9yRmluZGVyKCk7XG4gIHZhciBlbGVtZW50SW5mbyA9IGVsZW1lbnRGaW5kZXIoKTtcblxuICB2YXIgdmlzaXRvcnMgPSBbZmVhdHVyZUluZm8sIGJlaGF2aW9ySW5mbywgZWxlbWVudEluZm9dLm1hcChmdW5jdGlvbihpbmZvKSB7XG4gICAgcmV0dXJuIGluZm8udmlzaXRvcnM7XG4gIH0pO1xuICBlc3RyYXZlcnNlLnRyYXZlcnNlKHNjcmlwdCwgdHJhdmVyc2UodmlzaXRvcnMpKTtcblxuICByZXR1cm4ge1xuICAgIGJlaGF2aW9yczogYmVoYXZpb3JJbmZvLmJlaGF2aW9ycyxcbiAgICBlbGVtZW50czogIGVsZW1lbnRJbmZvLmVsZW1lbnRzLFxuICAgIGZlYXR1cmVzOiAgZmVhdHVyZUluZm8uZmVhdHVyZXMsXG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGpzUGFyc2U7XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTUgVGhlIFBvbHltZXIgUHJvamVjdCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogVGhpcyBjb2RlIG1heSBvbmx5IGJlIHVzZWQgdW5kZXIgdGhlIEJTRCBzdHlsZSBsaWNlbnNlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9MSUNFTlNFLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBhdXRob3JzIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vQVVUSE9SUy50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgY29udHJpYnV0b3JzIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vQ09OVFJJQlVUT1JTLnR4dFxuICogQ29kZSBkaXN0cmlidXRlZCBieSBHb29nbGUgYXMgcGFydCBvZiB0aGUgcG9seW1lciBwcm9qZWN0IGlzIGFsc29cbiAqIHN1YmplY3QgdG8gYW4gYWRkaXRpb25hbCBJUCByaWdodHMgZ3JhbnQgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL1BBVEVOVFMudHh0XG4gKi9cbi8vIGpzaGludCBub2RlOiB0cnVlXG4ndXNlIHN0cmljdCc7XG5cbnZhciBkb2N0cmluZSA9IHJlcXVpcmUoJ2RvY3RyaW5lJyk7XG5cbi8qKlxuICogQW4gYW5ub3RhdGVkIEpTRG9jIGJsb2NrIHRhZywgYWxsIGZpZWxkcyBhcmUgb3B0aW9uYWxseSBwcm9jZXNzZWQgZXhjZXB0IGZvclxuICogdGhlIHRhZzpcbiAqXG4gKiAgICAgQFRBRyB7VFlQRX0gTkFNRSBERVNDXG4gKlxuICogYGxpbmVgIGFuZCBgY29sYCBpbmRpY2F0ZSB0aGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0ZXh0IHRoYXRcbiAqIHRoZSB0YWcgd2FzIGV4dHJhY3RlZCBmcm9tIC0gcmVsYXRpdmUgdG8gdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgY29tbWVudFxuICogY29udGVudHMgKGUuZy4gdGhlIHZhbHVlIG9mIGBkZXNjYCBvbiBhIGRlc2NyaXB0b3Igbm9kZSkuIExpbmVzIGFyZVxuICogMS1pbmRleGVkLlxuICpcbiAqIEB0eXBlZGVmIHt7XG4gKiAgIHRhZzogICBzdHJpbmcsXG4gKiAgIHR5cGU6ID9zdHJpbmcsXG4gKiAgIG5hbWU6ID9zdHJpbmcsXG4gKiAgIGRlc2NyaXB0aW9uOiA/c3RyaW5nLFxuICogfX1cbiAqL1xudmFyIEpzZG9jVGFnO1xuXG4vKipcbiAqIFRoZSBwYXJzZWQgcmVwcmVzZW50YXRpb24gb2YgYSBKU0RvYyBjb21tZW50LlxuICpcbiAqIEB0eXBlZGVmIHt7XG4gKiAgIGRlc2NyaXB0aW9uOiA/c3RyaW5nLFxuICogICB0YWdzOiBBcnJheTxKc2RvY1RhZz4sXG4gKiB9fVxuICovXG52YXIgSnNkb2NBbm5vdGF0aW9uO1xuXG4vKipcbiAqIGRvY3RyaW5lIGNvbmZpZ3VyYXRpb24sXG4gKiBDVVJSRU5UTFkgVU5VU0VEIEJFQ0FVU0UgUFJJVkFURVxuICovXG4vLyBmdW5jdGlvbiBjb25maWd1cmVEb2N0cmluZSgpIHtcblxuLy8gICAvLyBAaGVybyBbcGF0aC90by9pbWFnZV1cbi8vICAgZG9jdHJpbmUuUnVsZXNbJ2hlcm8nXSA9IFsncGFyc2VOYW1lUGF0aE9wdGlvbmFsJywgJ2Vuc3VyZUVuZCddO1xuXG4vLyAgIC8vIC8vIEBkZW1vIFtwYXRoL3RvL2RlbW9dIFtEZW1vIHRpdGxlXVxuLy8gICBkb2N0cmluZS5SdWxlc1snZGVtbyddID0gWydwYXJzZU5hbWVQYXRoT3B0aW9uYWwnLCAncGFyc2VEZXNjcmlwdGlvbicsICdlbnN1cmVFbmQnXTtcblxuLy8gICAvLyAvLyBAcG9seW1lckJlaGF2aW9yIFtQb2x5bWVyLkJlaGF2aW9yTmFtZV1cbi8vICAgZG9jdHJpbmUuUnVsZXNbJ3BvbHltZXJCZWhhdmlvciddID0gWydwYXJzZU5hbWVQYXRoT3B0aW9uYWwnLCAnZW5zdXJlRW5kJ107XG4vLyB9XG4vLyBjb25maWd1cmVEb2N0cmluZSgpO1xuXG4vLyBAZGVtbyBbcGF0aF0gW3RpdGxlXVxuZnVuY3Rpb24gcGFyc2VEZW1vKHRhZykge1xuICB2YXIgbWF0Y2ggPSAodGFnLmRlc2NyaXB0aW9uIHx8IFwiXCIpLm1hdGNoKC9eXFxzKihcXFMqKVxccyooLiopJC8pO1xuICByZXR1cm4ge1xuICAgIHRhZzogJ2RlbW8nLFxuICAgIHR5cGU6IG51bGwsXG4gICAgbmFtZTogbWF0Y2ggPyBtYXRjaFsxXSA6IG51bGwsXG4gICAgZGVzY3JpcHRpb246IG1hdGNoID8gbWF0Y2hbMl0gOiBudWxsXG4gIH07XG59XG5cbi8vIEBoZXJvIFtwYXRoXVxuZnVuY3Rpb24gcGFyc2VIZXJvKHRhZykge1xuICByZXR1cm4ge1xuICAgIHRhZzogIHRhZy50aXRsZSxcbiAgICB0eXBlOiBudWxsLFxuICAgIG5hbWU6IHRhZy5kZXNjcmlwdGlvbixcbiAgICBkZXNjcmlwdGlvbjogbnVsbFxuICB9O1xufVxuXG4vLyBAcG9seW1lckJlaGF2aW9yIFtuYW1lXVxuZnVuY3Rpb24gcGFyc2VQb2x5bWVyQmVoYXZpb3IodGFnKSB7XG4gIHJldHVybiB7XG4gICAgdGFnOiAgdGFnLnRpdGxlLFxuICAgIHR5cGU6IG51bGwsXG4gICAgbmFtZTogdGFnLmRlc2NyaXB0aW9uLFxuICAgIGRlc2NyaXB0aW9uOiBudWxsXG4gIH07XG59XG5cbi8vIEBwc2V1ZG9FbGVtZW50IG5hbWVcbmZ1bmN0aW9uIHBhcnNlUHNldWRvRWxlbWVudCh0YWcpIHtcbiAgcmV0dXJuIHtcbiAgICB0YWc6ICB0YWcudGl0bGUsXG4gICAgdHlwZTogbnVsbCxcbiAgICBuYW1lOiB0YWcuZGVzY3JpcHRpb24sXG4gICAgZGVzY3JpcHRpb246IG51bGxcbiAgfTtcbn1cblxudmFyIENVU1RPTV9UQUdTID0ge1xuICBkZW1vOiBwYXJzZURlbW8sXG4gIGhlcm86IHBhcnNlSGVybyxcbiAgcG9seW1lckJlaGF2aW9yOiBwYXJzZVBvbHltZXJCZWhhdmlvcixcbiAgcHNldWRvRWxlbWVudDogcGFyc2VQc2V1ZG9FbGVtZW50XG59O1xuXG4vKipcbiAqIENvbnZlcnQgZG9jdHJpbmUgdGFncyB0byBoeWRyb2x5c2lzIHRhZyBmb3JtYXRcbiAqL1xuZnVuY3Rpb24gX3RhZ3NUb0h5ZHJvVGFncyh0YWdzKSB7XG4gIGlmICghdGFncylcbiAgICByZXR1cm4gbnVsbDtcbiAgcmV0dXJuIHRhZ3MubWFwKCBmdW5jdGlvbih0YWcpIHtcbiAgICBpZiAodGFnLnRpdGxlIGluIENVU1RPTV9UQUdTKSB7XG4gICAgICByZXR1cm4gQ1VTVE9NX1RBR1NbdGFnLnRpdGxlXSh0YWcpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRhZzogIHRhZy50aXRsZSxcbiAgICAgICAgdHlwZTogdGFnLnR5cGUgPyBkb2N0cmluZS50eXBlLnN0cmluZ2lmeSh0YWcudHlwZSkgOiBudWxsLFxuICAgICAgICBuYW1lOiB0YWcubmFtZSxcbiAgICAgICAgZGVzY3JpcHRpb246IHRhZy5kZXNjcmlwdGlvbixcbiAgICAgIH07XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiByZW1vdmVzIGxlYWRpbmcgKiwgYW5kIGFueSBzcGFjZSBiZWZvcmUgaXRcbiAqIEBwYXJhbSB7c3RyaW5nfSBkZXNjcmlwdGlvbiAtLSBqcyBkb2MgZGVzY3JpcHRpb25cbiAqL1xuZnVuY3Rpb24gX3JlbW92ZUxlYWRpbmdBc3Rlcmlza3MoZGVzY3JpcHRpb24pIHtcbiAgaWYgKCh0eXBlb2YgZGVzY3JpcHRpb24pICE9PSAnc3RyaW5nJylcbiAgICByZXR1cm4gZGVzY3JpcHRpb247XG5cbiAgcmV0dXJuIGRlc2NyaXB0aW9uXG4gICAgLnNwbGl0KCdcXG4nKVxuICAgIC5tYXAoIGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgIC8vIHJlbW92ZSBsZWFkaW5nICdcXHMqJyBmcm9tIGVhY2ggbGluZVxuICAgICAgdmFyIG1hdGNoID0gbGluZS5tYXRjaCgvXltcXHNdKlxcKlxccz8oLiopJC8pO1xuICAgICAgcmV0dXJuIG1hdGNoID8gbWF0Y2hbMV0gOiBsaW5lO1xuICAgIH0pXG4gICAgLmpvaW4oJ1xcbicpO1xufVxuXG4vKipcbiAqIEdpdmVuIGEgSlNEb2Mgc3RyaW5nIChtaW51cyBvcGVuaW5nL2Nsb3NpbmcgY29tbWVudCBkZWxpbWl0ZXJzKSwgZXh0cmFjdCBpdHNcbiAqIGRlc2NyaXB0aW9uIGFuZCB0YWdzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBkb2NzXG4gKiBAcmV0dXJuIHs/SnNkb2NBbm5vdGF0aW9ufVxuICovXG5mdW5jdGlvbiBwYXJzZUpzZG9jKGRvY3MpIHtcbiAgZG9jcyA9IF9yZW1vdmVMZWFkaW5nQXN0ZXJpc2tzKGRvY3MpO1xuICB2YXIgZCA9IGRvY3RyaW5lLnBhcnNlKGRvY3MsIHtcbiAgICB1bndyYXA6IGZhbHNlLFxuICAgIGxpbmVOdW1iZXI6IHRydWUsXG4gICAgcHJlc2VydmVXaGl0ZXNwYWNlOiB0cnVlXG4gIH0pO1xuICByZXR1cm4ge1xuICAgIGRlc2NyaXB0aW9uOiBkLmRlc2NyaXB0aW9uLFxuICAgIHRhZ3M6IF90YWdzVG9IeWRyb1RhZ3MoZC50YWdzKVxuICB9O1xufVxuXG4vLyBVdGlsaXR5XG5cbi8qKlxuICogQHBhcmFtIHtKc2RvY0Fubm90YXRpb259IGpzZG9jXG4gKiBAcGFyYW0ge3N0cmluZ30gdGFnTmFtZVxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaGFzVGFnKGpzZG9jLCB0YWdOYW1lKSB7XG4gIGlmICghanNkb2MgfHwgIWpzZG9jLnRhZ3MpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIGpzZG9jLnRhZ3Muc29tZShmdW5jdGlvbih0YWcpIHsgcmV0dXJuIHRhZy50YWcgPT09IHRhZ05hbWU7IH0pO1xufVxuXG4vKipcbiAqIEZpbmRzIHRoZSBmaXJzdCBKU0RvYyB0YWcgbWF0Y2hpbmcgYG5hbWVgIGFuZCByZXR1cm5zIGl0cyB2YWx1ZSBhdCBga2V5YC5cbiAqXG4gKiBAcGFyYW0ge0pzZG9jQW5ub3RhdGlvbn0ganNkb2NcbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWdOYW1lXG4gKiBAcGFyYW0ge3N0cmluZz19IGtleSBJZiBvbWl0dGVkLCB0aGUgZW50aXJlIHRhZyBvYmplY3QgaXMgcmV0dXJuZWQuXG4gKiBAcmV0dXJuIHs/c3RyaW5nfE9iamVjdH1cbiAqL1xuZnVuY3Rpb24gZ2V0VGFnKGpzZG9jLCB0YWdOYW1lLCBrZXkpIHtcbiAgaWYgKCFqc2RvYyB8fCAhanNkb2MudGFncykgcmV0dXJuIGZhbHNlO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGpzZG9jLnRhZ3MubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgdGFnID0ganNkb2MudGFnc1tpXTtcbiAgICBpZiAodGFnLnRhZyA9PT0gdGFnTmFtZSkge1xuICAgICAgcmV0dXJuIGtleSA/IHRhZ1trZXldIDogdGFnO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBAcGFyYW0gez9zdHJpbmd9IHRleHRcbiAqIEByZXR1cm4gez9zdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIHVuaW5kZW50KHRleHQpIHtcbiAgaWYgKCF0ZXh0KSByZXR1cm4gdGV4dDtcbiAgdmFyIGxpbmVzICA9IHRleHQucmVwbGFjZSgvXFx0L2csICcgICcpLnNwbGl0KCdcXG4nKTtcbiAgdmFyIGluZGVudCA9IGxpbmVzLnJlZHVjZShmdW5jdGlvbihwcmV2LCBsaW5lKSB7XG4gICAgaWYgKC9eXFxzKiQvLnRlc3QobGluZSkpIHJldHVybiBwcmV2OyAgLy8gQ29tcGxldGVseSBpZ25vcmUgYmxhbmsgbGluZXMuXG5cbiAgICB2YXIgbGluZUluZGVudCA9IGxpbmUubWF0Y2goL14oXFxzKikvKVswXS5sZW5ndGg7XG4gICAgaWYgKHByZXYgPT09IG51bGwpIHJldHVybiBsaW5lSW5kZW50O1xuICAgIHJldHVybiBsaW5lSW5kZW50IDwgcHJldiA/IGxpbmVJbmRlbnQgOiBwcmV2O1xuICB9LCBudWxsKTtcblxuICByZXR1cm4gbGluZXMubWFwKGZ1bmN0aW9uKGwpIHsgcmV0dXJuIGwuc3Vic3RyKGluZGVudCk7IH0pLmpvaW4oJ1xcbicpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZ2V0VGFnOiAgICAgZ2V0VGFnLFxuICBoYXNUYWc6ICAgICBoYXNUYWcsXG4gIHBhcnNlSnNkb2M6IHBhcnNlSnNkb2MsXG4gIHVuaW5kZW50OiAgIHVuaW5kZW50XG59O1xuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IChjKSAyMDE1IFRoZSBQb2x5bWVyIFByb2plY3QgQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFRoaXMgY29kZSBtYXkgb25seSBiZSB1c2VkIHVuZGVyIHRoZSBCU0Qgc3R5bGUgbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vTElDRU5TRS50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgYXV0aG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0FVVEhPUlMudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGNvbnRyaWJ1dG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0NPTlRSSUJVVE9SUy50eHRcbiAqIENvZGUgZGlzdHJpYnV0ZWQgYnkgR29vZ2xlIGFzIHBhcnQgb2YgdGhlIHBvbHltZXIgcHJvamVjdCBpcyBhbHNvXG4gKiBzdWJqZWN0IHRvIGFuIGFkZGl0aW9uYWwgSVAgcmlnaHRzIGdyYW50IGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9QQVRFTlRTLnR4dFxuICovXG5cbi8vIGpzaGludCBub2RlOnRydWVcbid1c2Ugc3RyaWN0JztcblxuLy8ganNoaW50IC1XMDc5XG4vLyBQcm9taXNlIHBvbHlmaWxsXG52YXIgUHJvbWlzZSA9IGdsb2JhbC5Qcm9taXNlIHx8IHJlcXVpcmUoJ2VzNi1wcm9taXNlJykuUHJvbWlzZTtcbi8vIGpzaGludCArVzA3OVxuXG5mdW5jdGlvbiBEZWZlcnJlZCgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLnByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICBzZWxmLnJlc29sdmUgPSByZXNvbHZlO1xuICAgIHNlbGYucmVqZWN0ID0gcmVqZWN0O1xuICB9KTtcbn1cblxuLyoqXG4gKiBBbiBvYmplY3QgdGhhdCBrbm93cyBob3cgdG8gcmVzb2x2ZSByZXNvdXJjZXMuXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBSZXNvbHZlclxuICogQG1lbWJlcm9mIGh5ZHJvbHlzaXNcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oc3RyaW5nLCBEZWZlcnJlZCk6IGJvb2xlYW59IGFjY2VwdCBBdHRlbXB0IHRvIHJlc29sdmVcbiAqICAgICBgZGVmZXJyZWRgIHdpdGggdGhlIGNvbnRlbnRzIHRoZSBzcGVjaWZpZWQgVVJMLiBSZXR1cm5zIGZhbHNlIGlmIHRoZVxuICogICAgIFJlc29sdmVyIGlzIHVuYWJsZSB0byByZXNvbHZlIHRoZSBVUkwuXG4gKi9cblxuXG4vKipcbiAqIEEgRmlsZUxvYWRlciBsZXRzIHlvdSByZXNvbHZlIFVSTHMgd2l0aCBhIHNldCBvZiBwb3RlbnRpYWwgcmVzb2x2ZXJzLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAbWVtYmVyb2YgaHlkcm9seXNpc1xuICovXG5mdW5jdGlvbiBGaWxlTG9hZGVyKCkge1xuICB0aGlzLnJlc29sdmVycyA9IFtdO1xuICAvLyBtYXAgdXJsIC0+IERlZmVycmVkXG4gIHRoaXMucmVxdWVzdHMgPSB7fTtcbn1cbkZpbGVMb2FkZXIucHJvdG90eXBlID0ge1xuXG4gIC8qKlxuICAgKiBBZGQgYW4gaW5zdGFuY2Ugb2YgYSBSZXNvbHZlciBjbGFzcyB0byB0aGUgbGlzdCBvZiB1cmwgcmVzb2x2ZXJzXG4gICAqXG4gICAqIE9yZGVyaW5nIG9mIHJlc29sdmVycyBpcyBtb3N0IHRvIGxlYXN0IHJlY2VudGx5IGFkZGVkXG4gICAqIFRoZSBmaXJzdCByZXNvbHZlciB0byBcImFjY2VwdFwiIHRoZSB1cmwgd2lucy5cbiAgICogQHBhcmFtIHtSZXNvbHZlcn0gcmVzb2x2ZXIgVGhlIHJlc29sdmVyIHRvIGFkZC5cbiAgICovXG4gIGFkZFJlc29sdmVyOiBmdW5jdGlvbihyZXNvbHZlcikge1xuICAgIHRoaXMucmVzb2x2ZXJzLnB1c2gocmVzb2x2ZXIpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBwcm9taXNlIGZvciBhbiBhYnNvbHV0ZSB1cmxcbiAgICpcbiAgICogVXJsIHJlcXVlc3RzIGFyZSBkZWR1cGxpY2F0ZWQgYnkgdGhlIGxvYWRlciwgcmV0dXJuaW5nIHRoZSBzYW1lIFByb21pc2UgZm9yXG4gICAqIGlkZW50aWNhbCB1cmxzXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgICAgICAgIFRoZSBhYnNvbHV0ZSB1cmwgdG8gcmVxdWVzdC5cbiAgICogQHJldHVybiB7UHJvbWlzZS48c3RyaW5nPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGNvbnRlbnRzIG9mIHRoZSBVUkwuXG4gICAqL1xuICByZXF1ZXN0OiBmdW5jdGlvbih1cmkpIHtcbiAgICB2YXIgcHJvbWlzZTtcblxuICAgIGlmICghKHVyaSBpbiB0aGlzLnJlcXVlc3RzKSkge1xuICAgICAgdmFyIGhhbmRsZWQgPSBmYWxzZTtcbiAgICAgIHZhciBkZWZlcnJlZCA9IG5ldyBEZWZlcnJlZCgpO1xuICAgICAgdGhpcy5yZXF1ZXN0c1t1cmldID0gZGVmZXJyZWQ7XG5cbiAgICAgIC8vIGxvb3AgYmFja3dhcmRzIHRocm91Z2ggcmVzb2x2ZXJzIHVudGlsIG9uZSBcImFjY2VwdHNcIiB0aGUgcmVxdWVzdFxuICAgICAgZm9yICh2YXIgaSA9IHRoaXMucmVzb2x2ZXJzLmxlbmd0aCAtIDEsIHI7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIHIgPSB0aGlzLnJlc29sdmVyc1tpXTtcbiAgICAgICAgaWYgKHIuYWNjZXB0KHVyaSwgZGVmZXJyZWQpKSB7XG4gICAgICAgICAgaGFuZGxlZCA9IHRydWU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFoYW5kbGVkKSB7XG4gICAgICAgIGRlZmVycmVkLnJlamVjdCgnbm8gcmVzb2x2ZXIgZm91bmQnKTtcbiAgICAgIH1cblxuICAgICAgcHJvbWlzZSA9IGRlZmVycmVkLnByb21pc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb21pc2UgPSB0aGlzLnJlcXVlc3RzW3VyaV0ucHJvbWlzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBGaWxlTG9hZGVyO1xuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IChjKSAyMDE1IFRoZSBQb2x5bWVyIFByb2plY3QgQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFRoaXMgY29kZSBtYXkgb25seSBiZSB1c2VkIHVuZGVyIHRoZSBCU0Qgc3R5bGUgbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vTElDRU5TRS50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgYXV0aG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0FVVEhPUlMudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGNvbnRyaWJ1dG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0NPTlRSSUJVVE9SUy50eHRcbiAqIENvZGUgZGlzdHJpYnV0ZWQgYnkgR29vZ2xlIGFzIHBhcnQgb2YgdGhlIHBvbHltZXIgcHJvamVjdCBpcyBhbHNvXG4gKiBzdWJqZWN0IHRvIGFuIGFkZGl0aW9uYWwgSVAgcmlnaHRzIGdyYW50IGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9QQVRFTlRTLnR4dFxuICovXG5cbi8vIGpzaGludCBub2RlOnRydWVcbid1c2Ugc3RyaWN0JztcblxudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xudmFyIHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuXG5mdW5jdGlvbiBnZXRGaWxlKGZpbGVwYXRoLCBkZWZlcnJlZCkge1xuICBmcy5yZWFkRmlsZShmaWxlcGF0aCwgJ3V0Zi04JywgZnVuY3Rpb24oZXJyLCBjb250ZW50KSB7XG4gICAgaWYgKGVycikge1xuICAgICAgZGVmZXJyZWQucmVqZWN0KGVycik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlZmVycmVkLnJlc29sdmUoY29udGVudCk7XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgYHBhdGhhYCBpcyBhIHNpYmxpbmcgb3IgYXVudCBvZiBgcGF0aGJgLlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNTaWJsaW5nT3JBdW50KHBhdGhhLCBwYXRoYikge1xuICB2YXIgcGFyZW50ID0gcGF0aC5kaXJuYW1lKHBhdGhhKTtcbiAgaWYgKHBhdGhiLmluZGV4T2YocGF0aGEpID09PSAtMSAmJiBwYXRoYi5pbmRleE9mKHBhcmVudCkgPT09IDApIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ2hhbmdlIGBsb2NhbFBhdGhgIGZyb20gYSBzaWJsaW5nIG9mIGBiYXNlUGF0aGAgdG8gYmUgYSBjaGlsZCBvZlxuICogYGJhc2VQYXRoYCBqb2luZWQgd2l0aCBgcmVkaXJlY3RgLlxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiByZWRpcmVjdFNpYmxpbmcoYmFzZVBhdGgsIGxvY2FsUGF0aCwgcmVkaXJlY3QpIHtcbiAgdmFyIHBhcmVudCA9IHBhdGguZGlybmFtZShiYXNlUGF0aCk7XG4gIHZhciByZWRpcmVjdGVkID0gcGF0aC5qb2luKGJhc2VQYXRoLCByZWRpcmVjdCwgbG9jYWxQYXRoLnNsaWNlKHBhcmVudC5sZW5ndGgpKTtcbiAgcmV0dXJuIHJlZGlyZWN0ZWQ7XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgcmVxdWVzdHMgdmlhIHRoZSBmaWxlIHN5c3RlbS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQG1lbWJlcm9mIGh5ZHJvbHlzaXNcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb25maWcuaG9zdCBIb3N0bmFtZSB0byBtYXRjaCBmb3IgYWJzb2x1dGUgdXJscy5cbiAqICAgICBNYXRjaGVzIFwiL1wiIGJ5IGRlZmF1bHRcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb25maWcuYmFzZVBhdGggUHJlZml4IGRpcmVjdG9yeSBmb3IgY29tcG9uZW50cyBpbiB1cmwuXG4gKiAgICAgRGVmYXVsdHMgdG8gXCIvXCIuXG4gKiBAcGFyYW0ge3N0cmluZ30gY29uZmlnLnJvb3QgRmlsZXN5c3RlbSByb290IHRvIHNlYXJjaC4gRGVmYXVsdHMgdG8gdGhlXG4gKiAgICAgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb25maWcucmVkaXJlY3QgV2hlcmUgdG8gcmVkaXJlY3QgbG9va3VwcyB0byBzaWJsaW5ncy5cbiAqL1xuZnVuY3Rpb24gRlNSZXNvbHZlcihjb25maWcpIHtcbiAgdGhpcy5jb25maWcgPSBjb25maWcgfHwge307XG59XG5GU1Jlc29sdmVyLnByb3RvdHlwZSA9IHtcbiAgYWNjZXB0OiBmdW5jdGlvbih1cmksIGRlZmVycmVkKSB7XG4gICAgdmFyIHBhcnNlZCA9IHVybC5wYXJzZSh1cmkpO1xuICAgIHZhciBob3N0ID0gdGhpcy5jb25maWcuaG9zdDtcbiAgICB2YXIgYmFzZSA9IHRoaXMuY29uZmlnLmJhc2VQYXRoICYmIGRlY29kZVVSSUNvbXBvbmVudCh0aGlzLmNvbmZpZy5iYXNlUGF0aCk7XG4gICAgdmFyIHJvb3QgPSB0aGlzLmNvbmZpZy5yb290ICYmIHBhdGgubm9ybWFsaXplKHRoaXMuY29uZmlnLnJvb3QpO1xuICAgIHZhciByZWRpcmVjdCA9IHRoaXMuY29uZmlnLnJlZGlyZWN0O1xuXG4gICAgdmFyIGxvY2FsO1xuXG4gICAgaWYgKCFwYXJzZWQuaG9zdG5hbWUgfHwgcGFyc2VkLmhvc3RuYW1lID09PSBob3N0KSB7XG4gICAgICBsb2NhbCA9IHBhcnNlZC5wYXRobmFtZTtcbiAgICB9XG5cbiAgICBpZiAobG9jYWwpIHtcbiAgICAgIC8vIHVuLWVzY2FwZSBIVE1MIGVzY2FwZXNcbiAgICAgIGxvY2FsID0gZGVjb2RlVVJJQ29tcG9uZW50KGxvY2FsKTtcblxuICAgICAgaWYgKGJhc2UpIHtcbiAgICAgICAgbG9jYWwgPSBwYXRoLnJlbGF0aXZlKGJhc2UsIGxvY2FsKTtcbiAgICAgIH1cbiAgICAgIGlmIChyb290KSB7XG4gICAgICAgIGxvY2FsID0gcGF0aC5qb2luKHJvb3QsIGxvY2FsKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlZGlyZWN0ICYmIGlzU2libGluZ09yQXVudChyb290LCBsb2NhbCkpIHtcbiAgICAgICAgbG9jYWwgPSByZWRpcmVjdFNpYmxpbmcocm9vdCwgbG9jYWwsIHJlZGlyZWN0KTtcbiAgICAgIH1cblxuICAgICAgZ2V0RmlsZShsb2NhbCwgZGVmZXJyZWQpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEZTUmVzb2x2ZXI7XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTUgVGhlIFBvbHltZXIgUHJvamVjdCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogVGhpcyBjb2RlIG1heSBvbmx5IGJlIHVzZWQgdW5kZXIgdGhlIEJTRCBzdHlsZSBsaWNlbnNlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9MSUNFTlNFLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBhdXRob3JzIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vQVVUSE9SUy50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgY29udHJpYnV0b3JzIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vQ09OVFJJQlVUT1JTLnR4dFxuICogQ29kZSBkaXN0cmlidXRlZCBieSBHb29nbGUgYXMgcGFydCBvZiB0aGUgcG9seW1lciBwcm9qZWN0IGlzIGFsc29cbiAqIHN1YmplY3QgdG8gYW4gYWRkaXRpb25hbCBJUCByaWdodHMgZ3JhbnQgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL1BBVEVOVFMudHh0XG4gKi9cblxuLy8ganNoaW50IG5vZGU6dHJ1ZVxuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIEEgcmVzb2x2ZXIgdGhhdCByZXNvbHZlcyB0byBudWxsIGFueSB1cmkgbWF0Y2hpbmcgY29uZmlnLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAbWVtYmVyb2YgaHlkcm9seXNpc1xuICogQHBhcmFtIHtzdHJpbmd9IGNvbmZpZyBUaGUgdXJsIHRvIGBhY2NlcHRgLlxuICovXG5mdW5jdGlvbiBOb29wUmVzb2x2ZXIoY29uZmlnKSB7XG4gIHRoaXMuY29uZmlnID0gY29uZmlnO1xufVxuXG5Ob29wUmVzb2x2ZXIucHJvdG90eXBlID0ge1xuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gICAgdXJpICAgICAgVGhlIGFic29sdXRlIFVSSSBiZWluZyByZXF1ZXN0ZWQuXG4gICAqIEBwYXJhbSB7IURlZmVycmVkfSBkZWZlcnJlZCBUaGUgZGVmZXJyZWQgcHJvbWlzZSB0aGF0IHNob3VsZCBiZSByZXNvbHZlZCBpZlxuICAgKiAgICAgdGhpcyByZXNvbHZlciBoYW5kbGVzIHRoZSBVUkkuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdGhlIFVSSSBpcyBoYW5kbGVkIGJ5IHRoaXMgcmVzb2x2ZXIuXG4gICAqL1xuICBhY2NlcHQ6IGZ1bmN0aW9uKHVyaSwgZGVmZXJyZWQpIHtcbiAgICBpZiAoIXRoaXMuY29uZmlnLnRlc3QpIHtcbiAgICAgIGlmICh1cmkuc2VhcmNoKHRoaXMuY29uZmlnKSA9PSAtMSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghdGhpcy5jb25maWcudGVzdCh1cmkpKSByZXR1cm4gZmFsc2U7XG5cbiAgICBkZWZlcnJlZC5yZXNvbHZlKCcnKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBOb29wUmVzb2x2ZXI7XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTUgVGhlIFBvbHltZXIgUHJvamVjdCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogVGhpcyBjb2RlIG1heSBvbmx5IGJlIHVzZWQgdW5kZXIgdGhlIEJTRCBzdHlsZSBsaWNlbnNlIGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9MSUNFTlNFLnR4dFxuICogVGhlIGNvbXBsZXRlIHNldCBvZiBhdXRob3JzIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vQVVUSE9SUy50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgY29udHJpYnV0b3JzIG1heSBiZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vQ09OVFJJQlVUT1JTLnR4dFxuICogQ29kZSBkaXN0cmlidXRlZCBieSBHb29nbGUgYXMgcGFydCBvZiB0aGUgcG9seW1lciBwcm9qZWN0IGlzIGFsc29cbiAqIHN1YmplY3QgdG8gYW4gYWRkaXRpb25hbCBJUCByaWdodHMgZ3JhbnQgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL1BBVEVOVFMudHh0XG4gKi9cblxuLy8ganNoaW50IG5vZGU6dHJ1ZVxuJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBnZXRGaWxlKHVybCwgZGVmZXJyZWQsIGNvbmZpZykge1xuICAvKiBnbG9iYWwgWE1MSHR0cFJlcXVlc3Q6ZmFsc2UgKi9cbiAgdmFyIHggPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgeC5vbmxvYWQgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgc3RhdHVzID0geC5zdGF0dXMgfHwgMDtcbiAgICBpZiAoc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDApIHtcbiAgICAgIGRlZmVycmVkLnJlc29sdmUoeC5yZXNwb25zZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlZmVycmVkLnJlamVjdCgneGhyIHN0YXR1czogJyArIHN0YXR1cyk7XG4gICAgfVxuICB9O1xuICB4Lm9uZXJyb3IgPSBmdW5jdGlvbihlKSB7XG4gICAgZGVmZXJyZWQucmVqZWN0KGUpO1xuICB9O1xuICB4Lm9wZW4oJ0dFVCcsIHVybCwgdHJ1ZSk7XG4gIGlmIChjb25maWcgJiYgY29uZmlnLnJlc3BvbnNlVHlwZSkge1xuICAgIHgucmVzcG9uc2VUeXBlID0gY29uZmlnLnJlc3BvbnNlVHlwZTtcbiAgfVxuICB4LnNlbmQoKTtcbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3QgYSByZXNvbHZlciB0aGF0IHJlcXVlc3RzIHJlc291cmNlcyBvdmVyIFhIUi5cbiAqIEBjb25zdHJ1Y3RvclxuICogQG1lbWJlcm9mIGh5ZHJvbHlzaXNcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb24gYXJndW1lbnRzLlxuICogQHBhcmFtIHtzdHJpbmd9IGNvbmZpZy5yZXNwb25zZVR5cGUgVHlwZSBvZiBvYmplY3QgdG8gYmUgcmV0dXJuZWQgYnkgdGhlXG4gKiAgICAgWEhSLiBEZWZhdWx0cyB0byAndGV4dCcsIGFjY2VwdHMgJ2RvY3VtZW50JywgJ2FycmF5YnVmZmVyJywgYW5kICdqc29uJy5cbiAqL1xuZnVuY3Rpb24gWEhSUmVzb2x2ZXIoY29uZmlnKSB7XG4gIHRoaXMuY29uZmlnID0gY29uZmlnO1xufVxuWEhSUmVzb2x2ZXIucHJvdG90eXBlID0ge1xuICBhY2NlcHQ6IGZ1bmN0aW9uKHVyaSwgZGVmZXJyZWQpIHtcbiAgICBnZXRGaWxlKHVyaSwgZGVmZXJyZWQsIHRoaXMuY29uZmlnKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBYSFJSZXNvbHZlcjtcbiIsbnVsbCwiLy8gaHR0cDovL3dpa2kuY29tbW9uanMub3JnL3dpa2kvVW5pdF9UZXN0aW5nLzEuMFxuLy9cbi8vIFRISVMgSVMgTk9UIFRFU1RFRCBOT1IgTElLRUxZIFRPIFdPUksgT1VUU0lERSBWOCFcbi8vXG4vLyBPcmlnaW5hbGx5IGZyb20gbmFyd2hhbC5qcyAoaHR0cDovL25hcndoYWxqcy5vcmcpXG4vLyBDb3B5cmlnaHQgKGMpIDIwMDkgVGhvbWFzIFJvYmluc29uIDwyODBub3J0aC5jb20+XG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgJ1NvZnR3YXJlJyksIHRvXG4vLyBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuLy8gcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICdBUyBJUycsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTlxuLy8gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTlxuLy8gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIHdoZW4gdXNlZCBpbiBub2RlLCB0aGlzIHdpbGwgYWN0dWFsbHkgbG9hZCB0aGUgdXRpbCBtb2R1bGUgd2UgZGVwZW5kIG9uXG4vLyB2ZXJzdXMgbG9hZGluZyB0aGUgYnVpbHRpbiB1dGlsIG1vZHVsZSBhcyBoYXBwZW5zIG90aGVyd2lzZVxuLy8gdGhpcyBpcyBhIGJ1ZyBpbiBub2RlIG1vZHVsZSBsb2FkaW5nIGFzIGZhciBhcyBJIGFtIGNvbmNlcm5lZFxudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsLycpO1xuXG52YXIgcFNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbi8vIDEuIFRoZSBhc3NlcnQgbW9kdWxlIHByb3ZpZGVzIGZ1bmN0aW9ucyB0aGF0IHRocm93XG4vLyBBc3NlcnRpb25FcnJvcidzIHdoZW4gcGFydGljdWxhciBjb25kaXRpb25zIGFyZSBub3QgbWV0LiBUaGVcbi8vIGFzc2VydCBtb2R1bGUgbXVzdCBjb25mb3JtIHRvIHRoZSBmb2xsb3dpbmcgaW50ZXJmYWNlLlxuXG52YXIgYXNzZXJ0ID0gbW9kdWxlLmV4cG9ydHMgPSBvaztcblxuLy8gMi4gVGhlIEFzc2VydGlvbkVycm9yIGlzIGRlZmluZWQgaW4gYXNzZXJ0LlxuLy8gbmV3IGFzc2VydC5Bc3NlcnRpb25FcnJvcih7IG1lc3NhZ2U6IG1lc3NhZ2UsXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0dWFsOiBhY3R1YWwsXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkIH0pXG5cbmFzc2VydC5Bc3NlcnRpb25FcnJvciA9IGZ1bmN0aW9uIEFzc2VydGlvbkVycm9yKG9wdGlvbnMpIHtcbiAgdGhpcy5uYW1lID0gJ0Fzc2VydGlvbkVycm9yJztcbiAgdGhpcy5hY3R1YWwgPSBvcHRpb25zLmFjdHVhbDtcbiAgdGhpcy5leHBlY3RlZCA9IG9wdGlvbnMuZXhwZWN0ZWQ7XG4gIHRoaXMub3BlcmF0b3IgPSBvcHRpb25zLm9wZXJhdG9yO1xuICBpZiAob3B0aW9ucy5tZXNzYWdlKSB7XG4gICAgdGhpcy5tZXNzYWdlID0gb3B0aW9ucy5tZXNzYWdlO1xuICAgIHRoaXMuZ2VuZXJhdGVkTWVzc2FnZSA9IGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIHRoaXMubWVzc2FnZSA9IGdldE1lc3NhZ2UodGhpcyk7XG4gICAgdGhpcy5nZW5lcmF0ZWRNZXNzYWdlID0gdHJ1ZTtcbiAgfVxuICB2YXIgc3RhY2tTdGFydEZ1bmN0aW9uID0gb3B0aW9ucy5zdGFja1N0YXJ0RnVuY3Rpb24gfHwgZmFpbDtcblxuICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBzdGFja1N0YXJ0RnVuY3Rpb24pO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIG5vbiB2OCBicm93c2VycyBzbyB3ZSBjYW4gaGF2ZSBhIHN0YWNrdHJhY2VcbiAgICB2YXIgZXJyID0gbmV3IEVycm9yKCk7XG4gICAgaWYgKGVyci5zdGFjaykge1xuICAgICAgdmFyIG91dCA9IGVyci5zdGFjaztcblxuICAgICAgLy8gdHJ5IHRvIHN0cmlwIHVzZWxlc3MgZnJhbWVzXG4gICAgICB2YXIgZm5fbmFtZSA9IHN0YWNrU3RhcnRGdW5jdGlvbi5uYW1lO1xuICAgICAgdmFyIGlkeCA9IG91dC5pbmRleE9mKCdcXG4nICsgZm5fbmFtZSk7XG4gICAgICBpZiAoaWR4ID49IDApIHtcbiAgICAgICAgLy8gb25jZSB3ZSBoYXZlIGxvY2F0ZWQgdGhlIGZ1bmN0aW9uIGZyYW1lXG4gICAgICAgIC8vIHdlIG5lZWQgdG8gc3RyaXAgb3V0IGV2ZXJ5dGhpbmcgYmVmb3JlIGl0IChhbmQgaXRzIGxpbmUpXG4gICAgICAgIHZhciBuZXh0X2xpbmUgPSBvdXQuaW5kZXhPZignXFxuJywgaWR4ICsgMSk7XG4gICAgICAgIG91dCA9IG91dC5zdWJzdHJpbmcobmV4dF9saW5lICsgMSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc3RhY2sgPSBvdXQ7XG4gICAgfVxuICB9XG59O1xuXG4vLyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IgaW5zdGFuY2VvZiBFcnJvclxudXRpbC5pbmhlcml0cyhhc3NlcnQuQXNzZXJ0aW9uRXJyb3IsIEVycm9yKTtcblxuZnVuY3Rpb24gcmVwbGFjZXIoa2V5LCB2YWx1ZSkge1xuICBpZiAodXRpbC5pc1VuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gJycgKyB2YWx1ZTtcbiAgfVxuICBpZiAodXRpbC5pc051bWJlcih2YWx1ZSkgJiYgIWlzRmluaXRlKHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuICB9XG4gIGlmICh1dGlsLmlzRnVuY3Rpb24odmFsdWUpIHx8IHV0aWwuaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlLnRvU3RyaW5nKCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiB0cnVuY2F0ZShzLCBuKSB7XG4gIGlmICh1dGlsLmlzU3RyaW5nKHMpKSB7XG4gICAgcmV0dXJuIHMubGVuZ3RoIDwgbiA/IHMgOiBzLnNsaWNlKDAsIG4pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldE1lc3NhZ2Uoc2VsZikge1xuICByZXR1cm4gdHJ1bmNhdGUoSlNPTi5zdHJpbmdpZnkoc2VsZi5hY3R1YWwsIHJlcGxhY2VyKSwgMTI4KSArICcgJyArXG4gICAgICAgICBzZWxmLm9wZXJhdG9yICsgJyAnICtcbiAgICAgICAgIHRydW5jYXRlKEpTT04uc3RyaW5naWZ5KHNlbGYuZXhwZWN0ZWQsIHJlcGxhY2VyKSwgMTI4KTtcbn1cblxuLy8gQXQgcHJlc2VudCBvbmx5IHRoZSB0aHJlZSBrZXlzIG1lbnRpb25lZCBhYm92ZSBhcmUgdXNlZCBhbmRcbi8vIHVuZGVyc3Rvb2QgYnkgdGhlIHNwZWMuIEltcGxlbWVudGF0aW9ucyBvciBzdWIgbW9kdWxlcyBjYW4gcGFzc1xuLy8gb3RoZXIga2V5cyB0byB0aGUgQXNzZXJ0aW9uRXJyb3IncyBjb25zdHJ1Y3RvciAtIHRoZXkgd2lsbCBiZVxuLy8gaWdub3JlZC5cblxuLy8gMy4gQWxsIG9mIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIG11c3QgdGhyb3cgYW4gQXNzZXJ0aW9uRXJyb3Jcbi8vIHdoZW4gYSBjb3JyZXNwb25kaW5nIGNvbmRpdGlvbiBpcyBub3QgbWV0LCB3aXRoIGEgbWVzc2FnZSB0aGF0XG4vLyBtYXkgYmUgdW5kZWZpbmVkIGlmIG5vdCBwcm92aWRlZC4gIEFsbCBhc3NlcnRpb24gbWV0aG9kcyBwcm92aWRlXG4vLyBib3RoIHRoZSBhY3R1YWwgYW5kIGV4cGVjdGVkIHZhbHVlcyB0byB0aGUgYXNzZXJ0aW9uIGVycm9yIGZvclxuLy8gZGlzcGxheSBwdXJwb3Nlcy5cblxuZnVuY3Rpb24gZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCBvcGVyYXRvciwgc3RhY2tTdGFydEZ1bmN0aW9uKSB7XG4gIHRocm93IG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3Ioe1xuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgIG9wZXJhdG9yOiBvcGVyYXRvcixcbiAgICBzdGFja1N0YXJ0RnVuY3Rpb246IHN0YWNrU3RhcnRGdW5jdGlvblxuICB9KTtcbn1cblxuLy8gRVhURU5TSU9OISBhbGxvd3MgZm9yIHdlbGwgYmVoYXZlZCBlcnJvcnMgZGVmaW5lZCBlbHNld2hlcmUuXG5hc3NlcnQuZmFpbCA9IGZhaWw7XG5cbi8vIDQuIFB1cmUgYXNzZXJ0aW9uIHRlc3RzIHdoZXRoZXIgYSB2YWx1ZSBpcyB0cnV0aHksIGFzIGRldGVybWluZWRcbi8vIGJ5ICEhZ3VhcmQuXG4vLyBhc3NlcnQub2soZ3VhcmQsIG1lc3NhZ2Vfb3B0KTtcbi8vIFRoaXMgc3RhdGVtZW50IGlzIGVxdWl2YWxlbnQgdG8gYXNzZXJ0LmVxdWFsKHRydWUsICEhZ3VhcmQsXG4vLyBtZXNzYWdlX29wdCk7LiBUbyB0ZXN0IHN0cmljdGx5IGZvciB0aGUgdmFsdWUgdHJ1ZSwgdXNlXG4vLyBhc3NlcnQuc3RyaWN0RXF1YWwodHJ1ZSwgZ3VhcmQsIG1lc3NhZ2Vfb3B0KTsuXG5cbmZ1bmN0aW9uIG9rKHZhbHVlLCBtZXNzYWdlKSB7XG4gIGlmICghdmFsdWUpIGZhaWwodmFsdWUsIHRydWUsIG1lc3NhZ2UsICc9PScsIGFzc2VydC5vayk7XG59XG5hc3NlcnQub2sgPSBvaztcblxuLy8gNS4gVGhlIGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzaGFsbG93LCBjb2VyY2l2ZSBlcXVhbGl0eSB3aXRoXG4vLyA9PS5cbi8vIGFzc2VydC5lcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5lcXVhbCA9IGZ1bmN0aW9uIGVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCAhPSBleHBlY3RlZCkgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnPT0nLCBhc3NlcnQuZXF1YWwpO1xufTtcblxuLy8gNi4gVGhlIG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHdoZXRoZXIgdHdvIG9iamVjdHMgYXJlIG5vdCBlcXVhbFxuLy8gd2l0aCAhPSBhc3NlcnQubm90RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90RXF1YWwgPSBmdW5jdGlvbiBub3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICchPScsIGFzc2VydC5ub3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDcuIFRoZSBlcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgYSBkZWVwIGVxdWFsaXR5IHJlbGF0aW9uLlxuLy8gYXNzZXJ0LmRlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5kZWVwRXF1YWwgPSBmdW5jdGlvbiBkZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoIV9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdkZWVwRXF1YWwnLCBhc3NlcnQuZGVlcEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkKSB7XG4gIC8vIDcuMS4gQWxsIGlkZW50aWNhbCB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGFzIGRldGVybWluZWQgYnkgPT09LlxuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIHJldHVybiB0cnVlO1xuXG4gIH0gZWxzZSBpZiAodXRpbC5pc0J1ZmZlcihhY3R1YWwpICYmIHV0aWwuaXNCdWZmZXIoZXhwZWN0ZWQpKSB7XG4gICAgaWYgKGFjdHVhbC5sZW5ndGggIT0gZXhwZWN0ZWQubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFjdHVhbC5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFjdHVhbFtpXSAhPT0gZXhwZWN0ZWRbaV0pIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcblxuICAvLyA3LjIuIElmIHRoZSBleHBlY3RlZCB2YWx1ZSBpcyBhIERhdGUgb2JqZWN0LCB0aGUgYWN0dWFsIHZhbHVlIGlzXG4gIC8vIGVxdWl2YWxlbnQgaWYgaXQgaXMgYWxzbyBhIERhdGUgb2JqZWN0IHRoYXQgcmVmZXJzIHRvIHRoZSBzYW1lIHRpbWUuXG4gIH0gZWxzZSBpZiAodXRpbC5pc0RhdGUoYWN0dWFsKSAmJiB1dGlsLmlzRGF0ZShleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsLmdldFRpbWUoKSA9PT0gZXhwZWN0ZWQuZ2V0VGltZSgpO1xuXG4gIC8vIDcuMyBJZiB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMgYSBSZWdFeHAgb2JqZWN0LCB0aGUgYWN0dWFsIHZhbHVlIGlzXG4gIC8vIGVxdWl2YWxlbnQgaWYgaXQgaXMgYWxzbyBhIFJlZ0V4cCBvYmplY3Qgd2l0aCB0aGUgc2FtZSBzb3VyY2UgYW5kXG4gIC8vIHByb3BlcnRpZXMgKGBnbG9iYWxgLCBgbXVsdGlsaW5lYCwgYGxhc3RJbmRleGAsIGBpZ25vcmVDYXNlYCkuXG4gIH0gZWxzZSBpZiAodXRpbC5pc1JlZ0V4cChhY3R1YWwpICYmIHV0aWwuaXNSZWdFeHAoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGFjdHVhbC5zb3VyY2UgPT09IGV4cGVjdGVkLnNvdXJjZSAmJlxuICAgICAgICAgICBhY3R1YWwuZ2xvYmFsID09PSBleHBlY3RlZC5nbG9iYWwgJiZcbiAgICAgICAgICAgYWN0dWFsLm11bHRpbGluZSA9PT0gZXhwZWN0ZWQubXVsdGlsaW5lICYmXG4gICAgICAgICAgIGFjdHVhbC5sYXN0SW5kZXggPT09IGV4cGVjdGVkLmxhc3RJbmRleCAmJlxuICAgICAgICAgICBhY3R1YWwuaWdub3JlQ2FzZSA9PT0gZXhwZWN0ZWQuaWdub3JlQ2FzZTtcblxuICAvLyA3LjQuIE90aGVyIHBhaXJzIHRoYXQgZG8gbm90IGJvdGggcGFzcyB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcsXG4gIC8vIGVxdWl2YWxlbmNlIGlzIGRldGVybWluZWQgYnkgPT0uXG4gIH0gZWxzZSBpZiAoIXV0aWwuaXNPYmplY3QoYWN0dWFsKSAmJiAhdXRpbC5pc09iamVjdChleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsID09IGV4cGVjdGVkO1xuXG4gIC8vIDcuNSBGb3IgYWxsIG90aGVyIE9iamVjdCBwYWlycywgaW5jbHVkaW5nIEFycmF5IG9iamVjdHMsIGVxdWl2YWxlbmNlIGlzXG4gIC8vIGRldGVybWluZWQgYnkgaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChhcyB2ZXJpZmllZFxuICAvLyB3aXRoIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCksIHRoZSBzYW1lIHNldCBvZiBrZXlzXG4gIC8vIChhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgdGhlIHNhbWUgb3JkZXIpLCBlcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnlcbiAgLy8gY29ycmVzcG9uZGluZyBrZXksIGFuZCBhbiBpZGVudGljYWwgJ3Byb3RvdHlwZScgcHJvcGVydHkuIE5vdGU6IHRoaXNcbiAgLy8gYWNjb3VudHMgZm9yIGJvdGggbmFtZWQgYW5kIGluZGV4ZWQgcHJvcGVydGllcyBvbiBBcnJheXMuXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG9iakVxdWl2KGFjdHVhbCwgZXhwZWN0ZWQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT0gJ1tvYmplY3QgQXJndW1lbnRzXSc7XG59XG5cbmZ1bmN0aW9uIG9iakVxdWl2KGEsIGIpIHtcbiAgaWYgKHV0aWwuaXNOdWxsT3JVbmRlZmluZWQoYSkgfHwgdXRpbC5pc051bGxPclVuZGVmaW5lZChiKSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vIGFuIGlkZW50aWNhbCAncHJvdG90eXBlJyBwcm9wZXJ0eS5cbiAgaWYgKGEucHJvdG90eXBlICE9PSBiLnByb3RvdHlwZSkgcmV0dXJuIGZhbHNlO1xuICAvLyBpZiBvbmUgaXMgYSBwcmltaXRpdmUsIHRoZSBvdGhlciBtdXN0IGJlIHNhbWVcbiAgaWYgKHV0aWwuaXNQcmltaXRpdmUoYSkgfHwgdXRpbC5pc1ByaW1pdGl2ZShiKSkge1xuICAgIHJldHVybiBhID09PSBiO1xuICB9XG4gIHZhciBhSXNBcmdzID0gaXNBcmd1bWVudHMoYSksXG4gICAgICBiSXNBcmdzID0gaXNBcmd1bWVudHMoYik7XG4gIGlmICgoYUlzQXJncyAmJiAhYklzQXJncykgfHwgKCFhSXNBcmdzICYmIGJJc0FyZ3MpKVxuICAgIHJldHVybiBmYWxzZTtcbiAgaWYgKGFJc0FyZ3MpIHtcbiAgICBhID0gcFNsaWNlLmNhbGwoYSk7XG4gICAgYiA9IHBTbGljZS5jYWxsKGIpO1xuICAgIHJldHVybiBfZGVlcEVxdWFsKGEsIGIpO1xuICB9XG4gIHZhciBrYSA9IG9iamVjdEtleXMoYSksXG4gICAgICBrYiA9IG9iamVjdEtleXMoYiksXG4gICAgICBrZXksIGk7XG4gIC8vIGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoa2V5cyBpbmNvcnBvcmF0ZXNcbiAgLy8gaGFzT3duUHJvcGVydHkpXG4gIGlmIChrYS5sZW5ndGggIT0ga2IubGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy90aGUgc2FtZSBzZXQgb2Yga2V5cyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSxcbiAga2Euc29ydCgpO1xuICBrYi5zb3J0KCk7XG4gIC8vfn5+Y2hlYXAga2V5IHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoa2FbaV0gIT0ga2JbaV0pXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy9lcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnkgY29ycmVzcG9uZGluZyBrZXksIGFuZFxuICAvL35+fnBvc3NpYmx5IGV4cGVuc2l2ZSBkZWVwIHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBrZXkgPSBrYVtpXTtcbiAgICBpZiAoIV9kZWVwRXF1YWwoYVtrZXldLCBiW2tleV0pKSByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8vIDguIFRoZSBub24tZXF1aXZhbGVuY2UgYXNzZXJ0aW9uIHRlc3RzIGZvciBhbnkgZGVlcCBpbmVxdWFsaXR5LlxuLy8gYXNzZXJ0Lm5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3REZWVwRXF1YWwgPSBmdW5jdGlvbiBub3REZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ25vdERlZXBFcXVhbCcsIGFzc2VydC5ub3REZWVwRXF1YWwpO1xuICB9XG59O1xuXG4vLyA5LiBUaGUgc3RyaWN0IGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzdHJpY3QgZXF1YWxpdHksIGFzIGRldGVybWluZWQgYnkgPT09LlxuLy8gYXNzZXJ0LnN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LnN0cmljdEVxdWFsID0gZnVuY3Rpb24gc3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsICE9PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJz09PScsIGFzc2VydC5zdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDEwLiBUaGUgc3RyaWN0IG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHN0cmljdCBpbmVxdWFsaXR5LCBhc1xuLy8gZGV0ZXJtaW5lZCBieSAhPT0uICBhc3NlcnQubm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90U3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBub3RTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnIT09JywgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkge1xuICBpZiAoIWFjdHVhbCB8fCAhZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGV4cGVjdGVkKSA9PSAnW29iamVjdCBSZWdFeHBdJykge1xuICAgIHJldHVybiBleHBlY3RlZC50ZXN0KGFjdHVhbCk7XG4gIH0gZWxzZSBpZiAoYWN0dWFsIGluc3RhbmNlb2YgZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChleHBlY3RlZC5jYWxsKHt9LCBhY3R1YWwpID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIF90aHJvd3Moc2hvdWxkVGhyb3csIGJsb2NrLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICB2YXIgYWN0dWFsO1xuXG4gIGlmICh1dGlsLmlzU3RyaW5nKGV4cGVjdGVkKSkge1xuICAgIG1lc3NhZ2UgPSBleHBlY3RlZDtcbiAgICBleHBlY3RlZCA9IG51bGw7XG4gIH1cblxuICB0cnkge1xuICAgIGJsb2NrKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBhY3R1YWwgPSBlO1xuICB9XG5cbiAgbWVzc2FnZSA9IChleHBlY3RlZCAmJiBleHBlY3RlZC5uYW1lID8gJyAoJyArIGV4cGVjdGVkLm5hbWUgKyAnKS4nIDogJy4nKSArXG4gICAgICAgICAgICAobWVzc2FnZSA/ICcgJyArIG1lc3NhZ2UgOiAnLicpO1xuXG4gIGlmIChzaG91bGRUaHJvdyAmJiAhYWN0dWFsKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCAnTWlzc2luZyBleHBlY3RlZCBleGNlcHRpb24nICsgbWVzc2FnZSk7XG4gIH1cblxuICBpZiAoIXNob3VsZFRocm93ICYmIGV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCAnR290IHVud2FudGVkIGV4Y2VwdGlvbicgKyBtZXNzYWdlKTtcbiAgfVxuXG4gIGlmICgoc2hvdWxkVGhyb3cgJiYgYWN0dWFsICYmIGV4cGVjdGVkICYmXG4gICAgICAhZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkpIHx8ICghc2hvdWxkVGhyb3cgJiYgYWN0dWFsKSkge1xuICAgIHRocm93IGFjdHVhbDtcbiAgfVxufVxuXG4vLyAxMS4gRXhwZWN0ZWQgdG8gdGhyb3cgYW4gZXJyb3I6XG4vLyBhc3NlcnQudGhyb3dzKGJsb2NrLCBFcnJvcl9vcHQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LnRocm93cyA9IGZ1bmN0aW9uKGJsb2NrLCAvKm9wdGlvbmFsKi9lcnJvciwgLypvcHRpb25hbCovbWVzc2FnZSkge1xuICBfdGhyb3dzLmFwcGx5KHRoaXMsIFt0cnVlXS5jb25jYXQocFNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xufTtcblxuLy8gRVhURU5TSU9OISBUaGlzIGlzIGFubm95aW5nIHRvIHdyaXRlIG91dHNpZGUgdGhpcyBtb2R1bGUuXG5hc3NlcnQuZG9lc05vdFRocm93ID0gZnVuY3Rpb24oYmxvY2ssIC8qb3B0aW9uYWwqL21lc3NhZ2UpIHtcbiAgX3Rocm93cy5hcHBseSh0aGlzLCBbZmFsc2VdLmNvbmNhdChwU2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG59O1xuXG5hc3NlcnQuaWZFcnJvciA9IGZ1bmN0aW9uKGVycikgeyBpZiAoZXJyKSB7dGhyb3cgZXJyO319O1xuXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChoYXNPd24uY2FsbChvYmosIGtleSkpIGtleXMucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiBrZXlzO1xufTtcbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUsIHtcbiAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgfVxuICAgIH0pO1xuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgVGVtcEN0b3IucHJvdG90eXBlID0gc3VwZXJDdG9yLnByb3RvdHlwZVxuICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIHJlc29sdmVzIC4gYW5kIC4uIGVsZW1lbnRzIGluIGEgcGF0aCBhcnJheSB3aXRoIGRpcmVjdG9yeSBuYW1lcyB0aGVyZVxuLy8gbXVzdCBiZSBubyBzbGFzaGVzLCBlbXB0eSBlbGVtZW50cywgb3IgZGV2aWNlIG5hbWVzIChjOlxcKSBpbiB0aGUgYXJyYXlcbi8vIChzbyBhbHNvIG5vIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHNsYXNoZXMgLSBpdCBkb2VzIG5vdCBkaXN0aW5ndWlzaFxuLy8gcmVsYXRpdmUgYW5kIGFic29sdXRlIHBhdGhzKVxuZnVuY3Rpb24gbm9ybWFsaXplQXJyYXkocGFydHMsIGFsbG93QWJvdmVSb290KSB7XG4gIC8vIGlmIHRoZSBwYXRoIHRyaWVzIHRvIGdvIGFib3ZlIHRoZSByb290LCBgdXBgIGVuZHMgdXAgPiAwXG4gIHZhciB1cCA9IDA7XG4gIGZvciAodmFyIGkgPSBwYXJ0cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIHZhciBsYXN0ID0gcGFydHNbaV07XG4gICAgaWYgKGxhc3QgPT09ICcuJykge1xuICAgICAgcGFydHMuc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSBpZiAobGFzdCA9PT0gJy4uJykge1xuICAgICAgcGFydHMuc3BsaWNlKGksIDEpO1xuICAgICAgdXArKztcbiAgICB9IGVsc2UgaWYgKHVwKSB7XG4gICAgICBwYXJ0cy5zcGxpY2UoaSwgMSk7XG4gICAgICB1cC0tO1xuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHRoZSBwYXRoIGlzIGFsbG93ZWQgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIHJlc3RvcmUgbGVhZGluZyAuLnNcbiAgaWYgKGFsbG93QWJvdmVSb290KSB7XG4gICAgZm9yICg7IHVwLS07IHVwKSB7XG4gICAgICBwYXJ0cy51bnNoaWZ0KCcuLicpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYXJ0cztcbn1cblxuLy8gU3BsaXQgYSBmaWxlbmFtZSBpbnRvIFtyb290LCBkaXIsIGJhc2VuYW1lLCBleHRdLCB1bml4IHZlcnNpb25cbi8vICdyb290JyBpcyBqdXN0IGEgc2xhc2gsIG9yIG5vdGhpbmcuXG52YXIgc3BsaXRQYXRoUmUgPVxuICAgIC9eKFxcLz98KShbXFxzXFxTXSo/KSgoPzpcXC57MSwyfXxbXlxcL10rP3wpKFxcLlteLlxcL10qfCkpKD86W1xcL10qKSQvO1xudmFyIHNwbGl0UGF0aCA9IGZ1bmN0aW9uKGZpbGVuYW1lKSB7XG4gIHJldHVybiBzcGxpdFBhdGhSZS5leGVjKGZpbGVuYW1lKS5zbGljZSgxKTtcbn07XG5cbi8vIHBhdGgucmVzb2x2ZShbZnJvbSAuLi5dLCB0bylcbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMucmVzb2x2ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcmVzb2x2ZWRQYXRoID0gJycsXG4gICAgICByZXNvbHZlZEFic29sdXRlID0gZmFsc2U7XG5cbiAgZm9yICh2YXIgaSA9IGFyZ3VtZW50cy5sZW5ndGggLSAxOyBpID49IC0xICYmICFyZXNvbHZlZEFic29sdXRlOyBpLS0pIHtcbiAgICB2YXIgcGF0aCA9IChpID49IDApID8gYXJndW1lbnRzW2ldIDogcHJvY2Vzcy5jd2QoKTtcblxuICAgIC8vIFNraXAgZW1wdHkgYW5kIGludmFsaWQgZW50cmllc1xuICAgIGlmICh0eXBlb2YgcGF0aCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyB0byBwYXRoLnJlc29sdmUgbXVzdCBiZSBzdHJpbmdzJyk7XG4gICAgfSBlbHNlIGlmICghcGF0aCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgcmVzb2x2ZWRQYXRoID0gcGF0aCArICcvJyArIHJlc29sdmVkUGF0aDtcbiAgICByZXNvbHZlZEFic29sdXRlID0gcGF0aC5jaGFyQXQoMCkgPT09ICcvJztcbiAgfVxuXG4gIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHBhdGggc2hvdWxkIGJlIHJlc29sdmVkIHRvIGEgZnVsbCBhYnNvbHV0ZSBwYXRoLCBidXRcbiAgLy8gaGFuZGxlIHJlbGF0aXZlIHBhdGhzIHRvIGJlIHNhZmUgKG1pZ2h0IGhhcHBlbiB3aGVuIHByb2Nlc3MuY3dkKCkgZmFpbHMpXG5cbiAgLy8gTm9ybWFsaXplIHRoZSBwYXRoXG4gIHJlc29sdmVkUGF0aCA9IG5vcm1hbGl6ZUFycmF5KGZpbHRlcihyZXNvbHZlZFBhdGguc3BsaXQoJy8nKSwgZnVuY3Rpb24ocCkge1xuICAgIHJldHVybiAhIXA7XG4gIH0pLCAhcmVzb2x2ZWRBYnNvbHV0ZSkuam9pbignLycpO1xuXG4gIHJldHVybiAoKHJlc29sdmVkQWJzb2x1dGUgPyAnLycgOiAnJykgKyByZXNvbHZlZFBhdGgpIHx8ICcuJztcbn07XG5cbi8vIHBhdGgubm9ybWFsaXplKHBhdGgpXG4vLyBwb3NpeCB2ZXJzaW9uXG5leHBvcnRzLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgdmFyIGlzQWJzb2x1dGUgPSBleHBvcnRzLmlzQWJzb2x1dGUocGF0aCksXG4gICAgICB0cmFpbGluZ1NsYXNoID0gc3Vic3RyKHBhdGgsIC0xKSA9PT0gJy8nO1xuXG4gIC8vIE5vcm1hbGl6ZSB0aGUgcGF0aFxuICBwYXRoID0gbm9ybWFsaXplQXJyYXkoZmlsdGVyKHBhdGguc3BsaXQoJy8nKSwgZnVuY3Rpb24ocCkge1xuICAgIHJldHVybiAhIXA7XG4gIH0pLCAhaXNBYnNvbHV0ZSkuam9pbignLycpO1xuXG4gIGlmICghcGF0aCAmJiAhaXNBYnNvbHV0ZSkge1xuICAgIHBhdGggPSAnLic7XG4gIH1cbiAgaWYgKHBhdGggJiYgdHJhaWxpbmdTbGFzaCkge1xuICAgIHBhdGggKz0gJy8nO1xuICB9XG5cbiAgcmV0dXJuIChpc0Fic29sdXRlID8gJy8nIDogJycpICsgcGF0aDtcbn07XG5cbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMuaXNBYnNvbHV0ZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgcmV0dXJuIHBhdGguY2hhckF0KDApID09PSAnLyc7XG59O1xuXG4vLyBwb3NpeCB2ZXJzaW9uXG5leHBvcnRzLmpvaW4gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhdGhzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcbiAgcmV0dXJuIGV4cG9ydHMubm9ybWFsaXplKGZpbHRlcihwYXRocywgZnVuY3Rpb24ocCwgaW5kZXgpIHtcbiAgICBpZiAodHlwZW9mIHAgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgdG8gcGF0aC5qb2luIG11c3QgYmUgc3RyaW5ncycpO1xuICAgIH1cbiAgICByZXR1cm4gcDtcbiAgfSkuam9pbignLycpKTtcbn07XG5cblxuLy8gcGF0aC5yZWxhdGl2ZShmcm9tLCB0bylcbi8vIHBvc2l4IHZlcnNpb25cbmV4cG9ydHMucmVsYXRpdmUgPSBmdW5jdGlvbihmcm9tLCB0bykge1xuICBmcm9tID0gZXhwb3J0cy5yZXNvbHZlKGZyb20pLnN1YnN0cigxKTtcbiAgdG8gPSBleHBvcnRzLnJlc29sdmUodG8pLnN1YnN0cigxKTtcblxuICBmdW5jdGlvbiB0cmltKGFycikge1xuICAgIHZhciBzdGFydCA9IDA7XG4gICAgZm9yICg7IHN0YXJ0IDwgYXJyLmxlbmd0aDsgc3RhcnQrKykge1xuICAgICAgaWYgKGFycltzdGFydF0gIT09ICcnKSBicmVhaztcbiAgICB9XG5cbiAgICB2YXIgZW5kID0gYXJyLmxlbmd0aCAtIDE7XG4gICAgZm9yICg7IGVuZCA+PSAwOyBlbmQtLSkge1xuICAgICAgaWYgKGFycltlbmRdICE9PSAnJykgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKHN0YXJ0ID4gZW5kKSByZXR1cm4gW107XG4gICAgcmV0dXJuIGFyci5zbGljZShzdGFydCwgZW5kIC0gc3RhcnQgKyAxKTtcbiAgfVxuXG4gIHZhciBmcm9tUGFydHMgPSB0cmltKGZyb20uc3BsaXQoJy8nKSk7XG4gIHZhciB0b1BhcnRzID0gdHJpbSh0by5zcGxpdCgnLycpKTtcblxuICB2YXIgbGVuZ3RoID0gTWF0aC5taW4oZnJvbVBhcnRzLmxlbmd0aCwgdG9QYXJ0cy5sZW5ndGgpO1xuICB2YXIgc2FtZVBhcnRzTGVuZ3RoID0gbGVuZ3RoO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGZyb21QYXJ0c1tpXSAhPT0gdG9QYXJ0c1tpXSkge1xuICAgICAgc2FtZVBhcnRzTGVuZ3RoID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHZhciBvdXRwdXRQYXJ0cyA9IFtdO1xuICBmb3IgKHZhciBpID0gc2FtZVBhcnRzTGVuZ3RoOyBpIDwgZnJvbVBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgb3V0cHV0UGFydHMucHVzaCgnLi4nKTtcbiAgfVxuXG4gIG91dHB1dFBhcnRzID0gb3V0cHV0UGFydHMuY29uY2F0KHRvUGFydHMuc2xpY2Uoc2FtZVBhcnRzTGVuZ3RoKSk7XG5cbiAgcmV0dXJuIG91dHB1dFBhcnRzLmpvaW4oJy8nKTtcbn07XG5cbmV4cG9ydHMuc2VwID0gJy8nO1xuZXhwb3J0cy5kZWxpbWl0ZXIgPSAnOic7XG5cbmV4cG9ydHMuZGlybmFtZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgdmFyIHJlc3VsdCA9IHNwbGl0UGF0aChwYXRoKSxcbiAgICAgIHJvb3QgPSByZXN1bHRbMF0sXG4gICAgICBkaXIgPSByZXN1bHRbMV07XG5cbiAgaWYgKCFyb290ICYmICFkaXIpIHtcbiAgICAvLyBObyBkaXJuYW1lIHdoYXRzb2V2ZXJcbiAgICByZXR1cm4gJy4nO1xuICB9XG5cbiAgaWYgKGRpcikge1xuICAgIC8vIEl0IGhhcyBhIGRpcm5hbWUsIHN0cmlwIHRyYWlsaW5nIHNsYXNoXG4gICAgZGlyID0gZGlyLnN1YnN0cigwLCBkaXIubGVuZ3RoIC0gMSk7XG4gIH1cblxuICByZXR1cm4gcm9vdCArIGRpcjtcbn07XG5cblxuZXhwb3J0cy5iYXNlbmFtZSA9IGZ1bmN0aW9uKHBhdGgsIGV4dCkge1xuICB2YXIgZiA9IHNwbGl0UGF0aChwYXRoKVsyXTtcbiAgLy8gVE9ETzogbWFrZSB0aGlzIGNvbXBhcmlzb24gY2FzZS1pbnNlbnNpdGl2ZSBvbiB3aW5kb3dzP1xuICBpZiAoZXh0ICYmIGYuc3Vic3RyKC0xICogZXh0Lmxlbmd0aCkgPT09IGV4dCkge1xuICAgIGYgPSBmLnN1YnN0cigwLCBmLmxlbmd0aCAtIGV4dC5sZW5ndGgpO1xuICB9XG4gIHJldHVybiBmO1xufTtcblxuXG5leHBvcnRzLmV4dG5hbWUgPSBmdW5jdGlvbihwYXRoKSB7XG4gIHJldHVybiBzcGxpdFBhdGgocGF0aClbM107XG59O1xuXG5mdW5jdGlvbiBmaWx0ZXIgKHhzLCBmKSB7XG4gICAgaWYgKHhzLmZpbHRlcikgcmV0dXJuIHhzLmZpbHRlcihmKTtcbiAgICB2YXIgcmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoZih4c1tpXSwgaSwgeHMpKSByZXMucHVzaCh4c1tpXSk7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG59XG5cbi8vIFN0cmluZy5wcm90b3R5cGUuc3Vic3RyIC0gbmVnYXRpdmUgaW5kZXggZG9uJ3Qgd29yayBpbiBJRThcbnZhciBzdWJzdHIgPSAnYWInLnN1YnN0cigtMSkgPT09ICdiJ1xuICAgID8gZnVuY3Rpb24gKHN0ciwgc3RhcnQsIGxlbikgeyByZXR1cm4gc3RyLnN1YnN0cihzdGFydCwgbGVuKSB9XG4gICAgOiBmdW5jdGlvbiAoc3RyLCBzdGFydCwgbGVuKSB7XG4gICAgICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gc3RyLmxlbmd0aCArIHN0YXJ0O1xuICAgICAgICByZXR1cm4gc3RyLnN1YnN0cihzdGFydCwgbGVuKTtcbiAgICB9XG47XG4iLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcblxudmFyIHByb2Nlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcblxuZnVuY3Rpb24gZHJhaW5RdWV1ZSgpIHtcbiAgICBpZiAoZHJhaW5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IHRydWU7XG4gICAgdmFyIGN1cnJlbnRRdWV1ZTtcbiAgICB2YXIgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIHdoaWxlKGxlbikge1xuICAgICAgICBjdXJyZW50UXVldWUgPSBxdWV1ZTtcbiAgICAgICAgcXVldWUgPSBbXTtcbiAgICAgICAgdmFyIGkgPSAtMTtcbiAgICAgICAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgICAgICAgICAgY3VycmVudFF1ZXVlW2ldKCk7XG4gICAgICAgIH1cbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xufVxucHJvY2Vzcy5uZXh0VGljayA9IGZ1bmN0aW9uIChmdW4pIHtcbiAgICBxdWV1ZS5wdXNoKGZ1bik7XG4gICAgaWYgKCFkcmFpbmluZykge1xuICAgICAgICBzZXRUaW1lb3V0KGRyYWluUXVldWUsIDApO1xuICAgIH1cbn07XG5cbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xucHJvY2Vzcy52ZXJzaW9uID0gJyc7IC8vIGVtcHR5IHN0cmluZyB0byBhdm9pZCByZWdleHAgaXNzdWVzXG5wcm9jZXNzLnZlcnNpb25zID0ge307XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG5wcm9jZXNzLm9uID0gbm9vcDtcbnByb2Nlc3MuYWRkTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5vbmNlID0gbm9vcDtcbnByb2Nlc3Mub2ZmID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xucHJvY2Vzcy5lbWl0ID0gbm9vcDtcblxucHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG4vLyBUT0RPKHNodHlsbWFuKVxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuIiwiLyohIGh0dHA6Ly9tdGhzLmJlL3B1bnljb2RlIHYxLjIuNCBieSBAbWF0aGlhcyAqL1xuOyhmdW5jdGlvbihyb290KSB7XG5cblx0LyoqIERldGVjdCBmcmVlIHZhcmlhYmxlcyAqL1xuXHR2YXIgZnJlZUV4cG9ydHMgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzO1xuXHR2YXIgZnJlZU1vZHVsZSA9IHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmXG5cdFx0bW9kdWxlLmV4cG9ydHMgPT0gZnJlZUV4cG9ydHMgJiYgbW9kdWxlO1xuXHR2YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuXHRpZiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwpIHtcblx0XHRyb290ID0gZnJlZUdsb2JhbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgYHB1bnljb2RlYCBvYmplY3QuXG5cdCAqIEBuYW1lIHB1bnljb2RlXG5cdCAqIEB0eXBlIE9iamVjdFxuXHQgKi9cblx0dmFyIHB1bnljb2RlLFxuXG5cdC8qKiBIaWdoZXN0IHBvc2l0aXZlIHNpZ25lZCAzMi1iaXQgZmxvYXQgdmFsdWUgKi9cblx0bWF4SW50ID0gMjE0NzQ4MzY0NywgLy8gYWthLiAweDdGRkZGRkZGIG9yIDJeMzEtMVxuXG5cdC8qKiBCb290c3RyaW5nIHBhcmFtZXRlcnMgKi9cblx0YmFzZSA9IDM2LFxuXHR0TWluID0gMSxcblx0dE1heCA9IDI2LFxuXHRza2V3ID0gMzgsXG5cdGRhbXAgPSA3MDAsXG5cdGluaXRpYWxCaWFzID0gNzIsXG5cdGluaXRpYWxOID0gMTI4LCAvLyAweDgwXG5cdGRlbGltaXRlciA9ICctJywgLy8gJ1xceDJEJ1xuXG5cdC8qKiBSZWd1bGFyIGV4cHJlc3Npb25zICovXG5cdHJlZ2V4UHVueWNvZGUgPSAvXnhuLS0vLFxuXHRyZWdleE5vbkFTQ0lJID0gL1teIC1+XS8sIC8vIHVucHJpbnRhYmxlIEFTQ0lJIGNoYXJzICsgbm9uLUFTQ0lJIGNoYXJzXG5cdHJlZ2V4U2VwYXJhdG9ycyA9IC9cXHgyRXxcXHUzMDAyfFxcdUZGMEV8XFx1RkY2MS9nLCAvLyBSRkMgMzQ5MCBzZXBhcmF0b3JzXG5cblx0LyoqIEVycm9yIG1lc3NhZ2VzICovXG5cdGVycm9ycyA9IHtcblx0XHQnb3ZlcmZsb3cnOiAnT3ZlcmZsb3c6IGlucHV0IG5lZWRzIHdpZGVyIGludGVnZXJzIHRvIHByb2Nlc3MnLFxuXHRcdCdub3QtYmFzaWMnOiAnSWxsZWdhbCBpbnB1dCA+PSAweDgwIChub3QgYSBiYXNpYyBjb2RlIHBvaW50KScsXG5cdFx0J2ludmFsaWQtaW5wdXQnOiAnSW52YWxpZCBpbnB1dCdcblx0fSxcblxuXHQvKiogQ29udmVuaWVuY2Ugc2hvcnRjdXRzICovXG5cdGJhc2VNaW51c1RNaW4gPSBiYXNlIC0gdE1pbixcblx0Zmxvb3IgPSBNYXRoLmZsb29yLFxuXHRzdHJpbmdGcm9tQ2hhckNvZGUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLFxuXG5cdC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgKi9cblx0a2V5O1xuXG5cdC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5cdC8qKlxuXHQgKiBBIGdlbmVyaWMgZXJyb3IgdXRpbGl0eSBmdW5jdGlvbi5cblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgVGhlIGVycm9yIHR5cGUuXG5cdCAqIEByZXR1cm5zIHtFcnJvcn0gVGhyb3dzIGEgYFJhbmdlRXJyb3JgIHdpdGggdGhlIGFwcGxpY2FibGUgZXJyb3IgbWVzc2FnZS5cblx0ICovXG5cdGZ1bmN0aW9uIGVycm9yKHR5cGUpIHtcblx0XHR0aHJvdyBSYW5nZUVycm9yKGVycm9yc1t0eXBlXSk7XG5cdH1cblxuXHQvKipcblx0ICogQSBnZW5lcmljIGBBcnJheSNtYXBgIHV0aWxpdHkgZnVuY3Rpb24uXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG5cdCAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBmdW5jdGlvbiB0aGF0IGdldHMgY2FsbGVkIGZvciBldmVyeSBhcnJheVxuXHQgKiBpdGVtLlxuXHQgKiBAcmV0dXJucyB7QXJyYXl9IEEgbmV3IGFycmF5IG9mIHZhbHVlcyByZXR1cm5lZCBieSB0aGUgY2FsbGJhY2sgZnVuY3Rpb24uXG5cdCAqL1xuXHRmdW5jdGlvbiBtYXAoYXJyYXksIGZuKSB7XG5cdFx0dmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblx0XHR3aGlsZSAobGVuZ3RoLS0pIHtcblx0XHRcdGFycmF5W2xlbmd0aF0gPSBmbihhcnJheVtsZW5ndGhdKTtcblx0XHR9XG5cdFx0cmV0dXJuIGFycmF5O1xuXHR9XG5cblx0LyoqXG5cdCAqIEEgc2ltcGxlIGBBcnJheSNtYXBgLWxpa2Ugd3JhcHBlciB0byB3b3JrIHdpdGggZG9tYWluIG5hbWUgc3RyaW5ncy5cblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtTdHJpbmd9IGRvbWFpbiBUaGUgZG9tYWluIG5hbWUuXG5cdCAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBmdW5jdGlvbiB0aGF0IGdldHMgY2FsbGVkIGZvciBldmVyeVxuXHQgKiBjaGFyYWN0ZXIuXG5cdCAqIEByZXR1cm5zIHtBcnJheX0gQSBuZXcgc3RyaW5nIG9mIGNoYXJhY3RlcnMgcmV0dXJuZWQgYnkgdGhlIGNhbGxiYWNrXG5cdCAqIGZ1bmN0aW9uLlxuXHQgKi9cblx0ZnVuY3Rpb24gbWFwRG9tYWluKHN0cmluZywgZm4pIHtcblx0XHRyZXR1cm4gbWFwKHN0cmluZy5zcGxpdChyZWdleFNlcGFyYXRvcnMpLCBmbikuam9pbignLicpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYW4gYXJyYXkgY29udGFpbmluZyB0aGUgbnVtZXJpYyBjb2RlIHBvaW50cyBvZiBlYWNoIFVuaWNvZGVcblx0ICogY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcuIFdoaWxlIEphdmFTY3JpcHQgdXNlcyBVQ1MtMiBpbnRlcm5hbGx5LFxuXHQgKiB0aGlzIGZ1bmN0aW9uIHdpbGwgY29udmVydCBhIHBhaXIgb2Ygc3Vycm9nYXRlIGhhbHZlcyAoZWFjaCBvZiB3aGljaFxuXHQgKiBVQ1MtMiBleHBvc2VzIGFzIHNlcGFyYXRlIGNoYXJhY3RlcnMpIGludG8gYSBzaW5nbGUgY29kZSBwb2ludCxcblx0ICogbWF0Y2hpbmcgVVRGLTE2LlxuXHQgKiBAc2VlIGBwdW55Y29kZS51Y3MyLmVuY29kZWBcblx0ICogQHNlZSA8aHR0cDovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvamF2YXNjcmlwdC1lbmNvZGluZz5cblx0ICogQG1lbWJlck9mIHB1bnljb2RlLnVjczJcblx0ICogQG5hbWUgZGVjb2RlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHJpbmcgVGhlIFVuaWNvZGUgaW5wdXQgc3RyaW5nIChVQ1MtMikuXG5cdCAqIEByZXR1cm5zIHtBcnJheX0gVGhlIG5ldyBhcnJheSBvZiBjb2RlIHBvaW50cy5cblx0ICovXG5cdGZ1bmN0aW9uIHVjczJkZWNvZGUoc3RyaW5nKSB7XG5cdFx0dmFyIG91dHB1dCA9IFtdLFxuXHRcdCAgICBjb3VudGVyID0gMCxcblx0XHQgICAgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aCxcblx0XHQgICAgdmFsdWUsXG5cdFx0ICAgIGV4dHJhO1xuXHRcdHdoaWxlIChjb3VudGVyIDwgbGVuZ3RoKSB7XG5cdFx0XHR2YWx1ZSA9IHN0cmluZy5jaGFyQ29kZUF0KGNvdW50ZXIrKyk7XG5cdFx0XHRpZiAodmFsdWUgPj0gMHhEODAwICYmIHZhbHVlIDw9IDB4REJGRiAmJiBjb3VudGVyIDwgbGVuZ3RoKSB7XG5cdFx0XHRcdC8vIGhpZ2ggc3Vycm9nYXRlLCBhbmQgdGhlcmUgaXMgYSBuZXh0IGNoYXJhY3RlclxuXHRcdFx0XHRleHRyYSA9IHN0cmluZy5jaGFyQ29kZUF0KGNvdW50ZXIrKyk7XG5cdFx0XHRcdGlmICgoZXh0cmEgJiAweEZDMDApID09IDB4REMwMCkgeyAvLyBsb3cgc3Vycm9nYXRlXG5cdFx0XHRcdFx0b3V0cHV0LnB1c2goKCh2YWx1ZSAmIDB4M0ZGKSA8PCAxMCkgKyAoZXh0cmEgJiAweDNGRikgKyAweDEwMDAwKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQvLyB1bm1hdGNoZWQgc3Vycm9nYXRlOyBvbmx5IGFwcGVuZCB0aGlzIGNvZGUgdW5pdCwgaW4gY2FzZSB0aGUgbmV4dFxuXHRcdFx0XHRcdC8vIGNvZGUgdW5pdCBpcyB0aGUgaGlnaCBzdXJyb2dhdGUgb2YgYSBzdXJyb2dhdGUgcGFpclxuXHRcdFx0XHRcdG91dHB1dC5wdXNoKHZhbHVlKTtcblx0XHRcdFx0XHRjb3VudGVyLS07XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG91dHB1dC5wdXNoKHZhbHVlKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgc3RyaW5nIGJhc2VkIG9uIGFuIGFycmF5IG9mIG51bWVyaWMgY29kZSBwb2ludHMuXG5cdCAqIEBzZWUgYHB1bnljb2RlLnVjczIuZGVjb2RlYFxuXHQgKiBAbWVtYmVyT2YgcHVueWNvZGUudWNzMlxuXHQgKiBAbmFtZSBlbmNvZGVcblx0ICogQHBhcmFtIHtBcnJheX0gY29kZVBvaW50cyBUaGUgYXJyYXkgb2YgbnVtZXJpYyBjb2RlIHBvaW50cy5cblx0ICogQHJldHVybnMge1N0cmluZ30gVGhlIG5ldyBVbmljb2RlIHN0cmluZyAoVUNTLTIpLlxuXHQgKi9cblx0ZnVuY3Rpb24gdWNzMmVuY29kZShhcnJheSkge1xuXHRcdHJldHVybiBtYXAoYXJyYXksIGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0XHR2YXIgb3V0cHV0ID0gJyc7XG5cdFx0XHRpZiAodmFsdWUgPiAweEZGRkYpIHtcblx0XHRcdFx0dmFsdWUgLT0gMHgxMDAwMDtcblx0XHRcdFx0b3V0cHV0ICs9IHN0cmluZ0Zyb21DaGFyQ29kZSh2YWx1ZSA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMCk7XG5cdFx0XHRcdHZhbHVlID0gMHhEQzAwIHwgdmFsdWUgJiAweDNGRjtcblx0XHRcdH1cblx0XHRcdG91dHB1dCArPSBzdHJpbmdGcm9tQ2hhckNvZGUodmFsdWUpO1xuXHRcdFx0cmV0dXJuIG91dHB1dDtcblx0XHR9KS5qb2luKCcnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIGJhc2ljIGNvZGUgcG9pbnQgaW50byBhIGRpZ2l0L2ludGVnZXIuXG5cdCAqIEBzZWUgYGRpZ2l0VG9CYXNpYygpYFxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge051bWJlcn0gY29kZVBvaW50IFRoZSBiYXNpYyBudW1lcmljIGNvZGUgcG9pbnQgdmFsdWUuXG5cdCAqIEByZXR1cm5zIHtOdW1iZXJ9IFRoZSBudW1lcmljIHZhbHVlIG9mIGEgYmFzaWMgY29kZSBwb2ludCAoZm9yIHVzZSBpblxuXHQgKiByZXByZXNlbnRpbmcgaW50ZWdlcnMpIGluIHRoZSByYW5nZSBgMGAgdG8gYGJhc2UgLSAxYCwgb3IgYGJhc2VgIGlmXG5cdCAqIHRoZSBjb2RlIHBvaW50IGRvZXMgbm90IHJlcHJlc2VudCBhIHZhbHVlLlxuXHQgKi9cblx0ZnVuY3Rpb24gYmFzaWNUb0RpZ2l0KGNvZGVQb2ludCkge1xuXHRcdGlmIChjb2RlUG9pbnQgLSA0OCA8IDEwKSB7XG5cdFx0XHRyZXR1cm4gY29kZVBvaW50IC0gMjI7XG5cdFx0fVxuXHRcdGlmIChjb2RlUG9pbnQgLSA2NSA8IDI2KSB7XG5cdFx0XHRyZXR1cm4gY29kZVBvaW50IC0gNjU7XG5cdFx0fVxuXHRcdGlmIChjb2RlUG9pbnQgLSA5NyA8IDI2KSB7XG5cdFx0XHRyZXR1cm4gY29kZVBvaW50IC0gOTc7XG5cdFx0fVxuXHRcdHJldHVybiBiYXNlO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIGEgZGlnaXQvaW50ZWdlciBpbnRvIGEgYmFzaWMgY29kZSBwb2ludC5cblx0ICogQHNlZSBgYmFzaWNUb0RpZ2l0KClgXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBkaWdpdCBUaGUgbnVtZXJpYyB2YWx1ZSBvZiBhIGJhc2ljIGNvZGUgcG9pbnQuXG5cdCAqIEByZXR1cm5zIHtOdW1iZXJ9IFRoZSBiYXNpYyBjb2RlIHBvaW50IHdob3NlIHZhbHVlICh3aGVuIHVzZWQgZm9yXG5cdCAqIHJlcHJlc2VudGluZyBpbnRlZ2VycykgaXMgYGRpZ2l0YCwgd2hpY2ggbmVlZHMgdG8gYmUgaW4gdGhlIHJhbmdlXG5cdCAqIGAwYCB0byBgYmFzZSAtIDFgLiBJZiBgZmxhZ2AgaXMgbm9uLXplcm8sIHRoZSB1cHBlcmNhc2UgZm9ybSBpc1xuXHQgKiB1c2VkOyBlbHNlLCB0aGUgbG93ZXJjYXNlIGZvcm0gaXMgdXNlZC4gVGhlIGJlaGF2aW9yIGlzIHVuZGVmaW5lZFxuXHQgKiBpZiBgZmxhZ2AgaXMgbm9uLXplcm8gYW5kIGBkaWdpdGAgaGFzIG5vIHVwcGVyY2FzZSBmb3JtLlxuXHQgKi9cblx0ZnVuY3Rpb24gZGlnaXRUb0Jhc2ljKGRpZ2l0LCBmbGFnKSB7XG5cdFx0Ly8gIDAuLjI1IG1hcCB0byBBU0NJSSBhLi56IG9yIEEuLlpcblx0XHQvLyAyNi4uMzUgbWFwIHRvIEFTQ0lJIDAuLjlcblx0XHRyZXR1cm4gZGlnaXQgKyAyMiArIDc1ICogKGRpZ2l0IDwgMjYpIC0gKChmbGFnICE9IDApIDw8IDUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEJpYXMgYWRhcHRhdGlvbiBmdW5jdGlvbiBhcyBwZXIgc2VjdGlvbiAzLjQgb2YgUkZDIDM0OTIuXG5cdCAqIGh0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzM0OTIjc2VjdGlvbi0zLjRcblx0ICogQHByaXZhdGVcblx0ICovXG5cdGZ1bmN0aW9uIGFkYXB0KGRlbHRhLCBudW1Qb2ludHMsIGZpcnN0VGltZSkge1xuXHRcdHZhciBrID0gMDtcblx0XHRkZWx0YSA9IGZpcnN0VGltZSA/IGZsb29yKGRlbHRhIC8gZGFtcCkgOiBkZWx0YSA+PiAxO1xuXHRcdGRlbHRhICs9IGZsb29yKGRlbHRhIC8gbnVtUG9pbnRzKTtcblx0XHRmb3IgKC8qIG5vIGluaXRpYWxpemF0aW9uICovOyBkZWx0YSA+IGJhc2VNaW51c1RNaW4gKiB0TWF4ID4+IDE7IGsgKz0gYmFzZSkge1xuXHRcdFx0ZGVsdGEgPSBmbG9vcihkZWx0YSAvIGJhc2VNaW51c1RNaW4pO1xuXHRcdH1cblx0XHRyZXR1cm4gZmxvb3IoayArIChiYXNlTWludXNUTWluICsgMSkgKiBkZWx0YSAvIChkZWx0YSArIHNrZXcpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBhIFB1bnljb2RlIHN0cmluZyBvZiBBU0NJSS1vbmx5IHN5bWJvbHMgdG8gYSBzdHJpbmcgb2YgVW5pY29kZVxuXHQgKiBzeW1ib2xzLlxuXHQgKiBAbWVtYmVyT2YgcHVueWNvZGVcblx0ICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFRoZSBQdW55Y29kZSBzdHJpbmcgb2YgQVNDSUktb25seSBzeW1ib2xzLlxuXHQgKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgcmVzdWx0aW5nIHN0cmluZyBvZiBVbmljb2RlIHN5bWJvbHMuXG5cdCAqL1xuXHRmdW5jdGlvbiBkZWNvZGUoaW5wdXQpIHtcblx0XHQvLyBEb24ndCB1c2UgVUNTLTJcblx0XHR2YXIgb3V0cHV0ID0gW10sXG5cdFx0ICAgIGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoLFxuXHRcdCAgICBvdXQsXG5cdFx0ICAgIGkgPSAwLFxuXHRcdCAgICBuID0gaW5pdGlhbE4sXG5cdFx0ICAgIGJpYXMgPSBpbml0aWFsQmlhcyxcblx0XHQgICAgYmFzaWMsXG5cdFx0ICAgIGosXG5cdFx0ICAgIGluZGV4LFxuXHRcdCAgICBvbGRpLFxuXHRcdCAgICB3LFxuXHRcdCAgICBrLFxuXHRcdCAgICBkaWdpdCxcblx0XHQgICAgdCxcblx0XHQgICAgLyoqIENhY2hlZCBjYWxjdWxhdGlvbiByZXN1bHRzICovXG5cdFx0ICAgIGJhc2VNaW51c1Q7XG5cblx0XHQvLyBIYW5kbGUgdGhlIGJhc2ljIGNvZGUgcG9pbnRzOiBsZXQgYGJhc2ljYCBiZSB0aGUgbnVtYmVyIG9mIGlucHV0IGNvZGVcblx0XHQvLyBwb2ludHMgYmVmb3JlIHRoZSBsYXN0IGRlbGltaXRlciwgb3IgYDBgIGlmIHRoZXJlIGlzIG5vbmUsIHRoZW4gY29weVxuXHRcdC8vIHRoZSBmaXJzdCBiYXNpYyBjb2RlIHBvaW50cyB0byB0aGUgb3V0cHV0LlxuXG5cdFx0YmFzaWMgPSBpbnB1dC5sYXN0SW5kZXhPZihkZWxpbWl0ZXIpO1xuXHRcdGlmIChiYXNpYyA8IDApIHtcblx0XHRcdGJhc2ljID0gMDtcblx0XHR9XG5cblx0XHRmb3IgKGogPSAwOyBqIDwgYmFzaWM7ICsraikge1xuXHRcdFx0Ly8gaWYgaXQncyBub3QgYSBiYXNpYyBjb2RlIHBvaW50XG5cdFx0XHRpZiAoaW5wdXQuY2hhckNvZGVBdChqKSA+PSAweDgwKSB7XG5cdFx0XHRcdGVycm9yKCdub3QtYmFzaWMnKTtcblx0XHRcdH1cblx0XHRcdG91dHB1dC5wdXNoKGlucHV0LmNoYXJDb2RlQXQoaikpO1xuXHRcdH1cblxuXHRcdC8vIE1haW4gZGVjb2RpbmcgbG9vcDogc3RhcnQganVzdCBhZnRlciB0aGUgbGFzdCBkZWxpbWl0ZXIgaWYgYW55IGJhc2ljIGNvZGVcblx0XHQvLyBwb2ludHMgd2VyZSBjb3BpZWQ7IHN0YXJ0IGF0IHRoZSBiZWdpbm5pbmcgb3RoZXJ3aXNlLlxuXG5cdFx0Zm9yIChpbmRleCA9IGJhc2ljID4gMCA/IGJhc2ljICsgMSA6IDA7IGluZGV4IDwgaW5wdXRMZW5ndGg7IC8qIG5vIGZpbmFsIGV4cHJlc3Npb24gKi8pIHtcblxuXHRcdFx0Ly8gYGluZGV4YCBpcyB0aGUgaW5kZXggb2YgdGhlIG5leHQgY2hhcmFjdGVyIHRvIGJlIGNvbnN1bWVkLlxuXHRcdFx0Ly8gRGVjb2RlIGEgZ2VuZXJhbGl6ZWQgdmFyaWFibGUtbGVuZ3RoIGludGVnZXIgaW50byBgZGVsdGFgLFxuXHRcdFx0Ly8gd2hpY2ggZ2V0cyBhZGRlZCB0byBgaWAuIFRoZSBvdmVyZmxvdyBjaGVja2luZyBpcyBlYXNpZXJcblx0XHRcdC8vIGlmIHdlIGluY3JlYXNlIGBpYCBhcyB3ZSBnbywgdGhlbiBzdWJ0cmFjdCBvZmYgaXRzIHN0YXJ0aW5nXG5cdFx0XHQvLyB2YWx1ZSBhdCB0aGUgZW5kIHRvIG9idGFpbiBgZGVsdGFgLlxuXHRcdFx0Zm9yIChvbGRpID0gaSwgdyA9IDEsIGsgPSBiYXNlOyAvKiBubyBjb25kaXRpb24gKi87IGsgKz0gYmFzZSkge1xuXG5cdFx0XHRcdGlmIChpbmRleCA+PSBpbnB1dExlbmd0aCkge1xuXHRcdFx0XHRcdGVycm9yKCdpbnZhbGlkLWlucHV0Jyk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRkaWdpdCA9IGJhc2ljVG9EaWdpdChpbnB1dC5jaGFyQ29kZUF0KGluZGV4KyspKTtcblxuXHRcdFx0XHRpZiAoZGlnaXQgPj0gYmFzZSB8fCBkaWdpdCA+IGZsb29yKChtYXhJbnQgLSBpKSAvIHcpKSB7XG5cdFx0XHRcdFx0ZXJyb3IoJ292ZXJmbG93Jyk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpICs9IGRpZ2l0ICogdztcblx0XHRcdFx0dCA9IGsgPD0gYmlhcyA/IHRNaW4gOiAoayA+PSBiaWFzICsgdE1heCA/IHRNYXggOiBrIC0gYmlhcyk7XG5cblx0XHRcdFx0aWYgKGRpZ2l0IDwgdCkge1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0YmFzZU1pbnVzVCA9IGJhc2UgLSB0O1xuXHRcdFx0XHRpZiAodyA+IGZsb29yKG1heEludCAvIGJhc2VNaW51c1QpKSB7XG5cdFx0XHRcdFx0ZXJyb3IoJ292ZXJmbG93Jyk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR3ICo9IGJhc2VNaW51c1Q7XG5cblx0XHRcdH1cblxuXHRcdFx0b3V0ID0gb3V0cHV0Lmxlbmd0aCArIDE7XG5cdFx0XHRiaWFzID0gYWRhcHQoaSAtIG9sZGksIG91dCwgb2xkaSA9PSAwKTtcblxuXHRcdFx0Ly8gYGlgIHdhcyBzdXBwb3NlZCB0byB3cmFwIGFyb3VuZCBmcm9tIGBvdXRgIHRvIGAwYCxcblx0XHRcdC8vIGluY3JlbWVudGluZyBgbmAgZWFjaCB0aW1lLCBzbyB3ZSdsbCBmaXggdGhhdCBub3c6XG5cdFx0XHRpZiAoZmxvb3IoaSAvIG91dCkgPiBtYXhJbnQgLSBuKSB7XG5cdFx0XHRcdGVycm9yKCdvdmVyZmxvdycpO1xuXHRcdFx0fVxuXG5cdFx0XHRuICs9IGZsb29yKGkgLyBvdXQpO1xuXHRcdFx0aSAlPSBvdXQ7XG5cblx0XHRcdC8vIEluc2VydCBgbmAgYXQgcG9zaXRpb24gYGlgIG9mIHRoZSBvdXRwdXRcblx0XHRcdG91dHB1dC5zcGxpY2UoaSsrLCAwLCBuKTtcblxuXHRcdH1cblxuXHRcdHJldHVybiB1Y3MyZW5jb2RlKG91dHB1dCk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBzdHJpbmcgb2YgVW5pY29kZSBzeW1ib2xzIHRvIGEgUHVueWNvZGUgc3RyaW5nIG9mIEFTQ0lJLW9ubHlcblx0ICogc3ltYm9scy5cblx0ICogQG1lbWJlck9mIHB1bnljb2RlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBUaGUgc3RyaW5nIG9mIFVuaWNvZGUgc3ltYm9scy5cblx0ICogQHJldHVybnMge1N0cmluZ30gVGhlIHJlc3VsdGluZyBQdW55Y29kZSBzdHJpbmcgb2YgQVNDSUktb25seSBzeW1ib2xzLlxuXHQgKi9cblx0ZnVuY3Rpb24gZW5jb2RlKGlucHV0KSB7XG5cdFx0dmFyIG4sXG5cdFx0ICAgIGRlbHRhLFxuXHRcdCAgICBoYW5kbGVkQ1BDb3VudCxcblx0XHQgICAgYmFzaWNMZW5ndGgsXG5cdFx0ICAgIGJpYXMsXG5cdFx0ICAgIGosXG5cdFx0ICAgIG0sXG5cdFx0ICAgIHEsXG5cdFx0ICAgIGssXG5cdFx0ICAgIHQsXG5cdFx0ICAgIGN1cnJlbnRWYWx1ZSxcblx0XHQgICAgb3V0cHV0ID0gW10sXG5cdFx0ICAgIC8qKiBgaW5wdXRMZW5ndGhgIHdpbGwgaG9sZCB0aGUgbnVtYmVyIG9mIGNvZGUgcG9pbnRzIGluIGBpbnB1dGAuICovXG5cdFx0ICAgIGlucHV0TGVuZ3RoLFxuXHRcdCAgICAvKiogQ2FjaGVkIGNhbGN1bGF0aW9uIHJlc3VsdHMgKi9cblx0XHQgICAgaGFuZGxlZENQQ291bnRQbHVzT25lLFxuXHRcdCAgICBiYXNlTWludXNULFxuXHRcdCAgICBxTWludXNUO1xuXG5cdFx0Ly8gQ29udmVydCB0aGUgaW5wdXQgaW4gVUNTLTIgdG8gVW5pY29kZVxuXHRcdGlucHV0ID0gdWNzMmRlY29kZShpbnB1dCk7XG5cblx0XHQvLyBDYWNoZSB0aGUgbGVuZ3RoXG5cdFx0aW5wdXRMZW5ndGggPSBpbnB1dC5sZW5ndGg7XG5cblx0XHQvLyBJbml0aWFsaXplIHRoZSBzdGF0ZVxuXHRcdG4gPSBpbml0aWFsTjtcblx0XHRkZWx0YSA9IDA7XG5cdFx0YmlhcyA9IGluaXRpYWxCaWFzO1xuXG5cdFx0Ly8gSGFuZGxlIHRoZSBiYXNpYyBjb2RlIHBvaW50c1xuXHRcdGZvciAoaiA9IDA7IGogPCBpbnB1dExlbmd0aDsgKytqKSB7XG5cdFx0XHRjdXJyZW50VmFsdWUgPSBpbnB1dFtqXTtcblx0XHRcdGlmIChjdXJyZW50VmFsdWUgPCAweDgwKSB7XG5cdFx0XHRcdG91dHB1dC5wdXNoKHN0cmluZ0Zyb21DaGFyQ29kZShjdXJyZW50VmFsdWUpKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRoYW5kbGVkQ1BDb3VudCA9IGJhc2ljTGVuZ3RoID0gb3V0cHV0Lmxlbmd0aDtcblxuXHRcdC8vIGBoYW5kbGVkQ1BDb3VudGAgaXMgdGhlIG51bWJlciBvZiBjb2RlIHBvaW50cyB0aGF0IGhhdmUgYmVlbiBoYW5kbGVkO1xuXHRcdC8vIGBiYXNpY0xlbmd0aGAgaXMgdGhlIG51bWJlciBvZiBiYXNpYyBjb2RlIHBvaW50cy5cblxuXHRcdC8vIEZpbmlzaCB0aGUgYmFzaWMgc3RyaW5nIC0gaWYgaXQgaXMgbm90IGVtcHR5IC0gd2l0aCBhIGRlbGltaXRlclxuXHRcdGlmIChiYXNpY0xlbmd0aCkge1xuXHRcdFx0b3V0cHV0LnB1c2goZGVsaW1pdGVyKTtcblx0XHR9XG5cblx0XHQvLyBNYWluIGVuY29kaW5nIGxvb3A6XG5cdFx0d2hpbGUgKGhhbmRsZWRDUENvdW50IDwgaW5wdXRMZW5ndGgpIHtcblxuXHRcdFx0Ly8gQWxsIG5vbi1iYXNpYyBjb2RlIHBvaW50cyA8IG4gaGF2ZSBiZWVuIGhhbmRsZWQgYWxyZWFkeS4gRmluZCB0aGUgbmV4dFxuXHRcdFx0Ly8gbGFyZ2VyIG9uZTpcblx0XHRcdGZvciAobSA9IG1heEludCwgaiA9IDA7IGogPCBpbnB1dExlbmd0aDsgKytqKSB7XG5cdFx0XHRcdGN1cnJlbnRWYWx1ZSA9IGlucHV0W2pdO1xuXHRcdFx0XHRpZiAoY3VycmVudFZhbHVlID49IG4gJiYgY3VycmVudFZhbHVlIDwgbSkge1xuXHRcdFx0XHRcdG0gPSBjdXJyZW50VmFsdWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gSW5jcmVhc2UgYGRlbHRhYCBlbm91Z2ggdG8gYWR2YW5jZSB0aGUgZGVjb2RlcidzIDxuLGk+IHN0YXRlIHRvIDxtLDA+LFxuXHRcdFx0Ly8gYnV0IGd1YXJkIGFnYWluc3Qgb3ZlcmZsb3dcblx0XHRcdGhhbmRsZWRDUENvdW50UGx1c09uZSA9IGhhbmRsZWRDUENvdW50ICsgMTtcblx0XHRcdGlmIChtIC0gbiA+IGZsb29yKChtYXhJbnQgLSBkZWx0YSkgLyBoYW5kbGVkQ1BDb3VudFBsdXNPbmUpKSB7XG5cdFx0XHRcdGVycm9yKCdvdmVyZmxvdycpO1xuXHRcdFx0fVxuXG5cdFx0XHRkZWx0YSArPSAobSAtIG4pICogaGFuZGxlZENQQ291bnRQbHVzT25lO1xuXHRcdFx0biA9IG07XG5cblx0XHRcdGZvciAoaiA9IDA7IGogPCBpbnB1dExlbmd0aDsgKytqKSB7XG5cdFx0XHRcdGN1cnJlbnRWYWx1ZSA9IGlucHV0W2pdO1xuXG5cdFx0XHRcdGlmIChjdXJyZW50VmFsdWUgPCBuICYmICsrZGVsdGEgPiBtYXhJbnQpIHtcblx0XHRcdFx0XHRlcnJvcignb3ZlcmZsb3cnKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChjdXJyZW50VmFsdWUgPT0gbikge1xuXHRcdFx0XHRcdC8vIFJlcHJlc2VudCBkZWx0YSBhcyBhIGdlbmVyYWxpemVkIHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyXG5cdFx0XHRcdFx0Zm9yIChxID0gZGVsdGEsIGsgPSBiYXNlOyAvKiBubyBjb25kaXRpb24gKi87IGsgKz0gYmFzZSkge1xuXHRcdFx0XHRcdFx0dCA9IGsgPD0gYmlhcyA/IHRNaW4gOiAoayA+PSBiaWFzICsgdE1heCA/IHRNYXggOiBrIC0gYmlhcyk7XG5cdFx0XHRcdFx0XHRpZiAocSA8IHQpIHtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRxTWludXNUID0gcSAtIHQ7XG5cdFx0XHRcdFx0XHRiYXNlTWludXNUID0gYmFzZSAtIHQ7XG5cdFx0XHRcdFx0XHRvdXRwdXQucHVzaChcblx0XHRcdFx0XHRcdFx0c3RyaW5nRnJvbUNoYXJDb2RlKGRpZ2l0VG9CYXNpYyh0ICsgcU1pbnVzVCAlIGJhc2VNaW51c1QsIDApKVxuXHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdHEgPSBmbG9vcihxTWludXNUIC8gYmFzZU1pbnVzVCk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0b3V0cHV0LnB1c2goc3RyaW5nRnJvbUNoYXJDb2RlKGRpZ2l0VG9CYXNpYyhxLCAwKSkpO1xuXHRcdFx0XHRcdGJpYXMgPSBhZGFwdChkZWx0YSwgaGFuZGxlZENQQ291bnRQbHVzT25lLCBoYW5kbGVkQ1BDb3VudCA9PSBiYXNpY0xlbmd0aCk7XG5cdFx0XHRcdFx0ZGVsdGEgPSAwO1xuXHRcdFx0XHRcdCsraGFuZGxlZENQQ291bnQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0KytkZWx0YTtcblx0XHRcdCsrbjtcblxuXHRcdH1cblx0XHRyZXR1cm4gb3V0cHV0LmpvaW4oJycpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIGEgUHVueWNvZGUgc3RyaW5nIHJlcHJlc2VudGluZyBhIGRvbWFpbiBuYW1lIHRvIFVuaWNvZGUuIE9ubHkgdGhlXG5cdCAqIFB1bnljb2RlZCBwYXJ0cyBvZiB0aGUgZG9tYWluIG5hbWUgd2lsbCBiZSBjb252ZXJ0ZWQsIGkuZS4gaXQgZG9lc24ndFxuXHQgKiBtYXR0ZXIgaWYgeW91IGNhbGwgaXQgb24gYSBzdHJpbmcgdGhhdCBoYXMgYWxyZWFkeSBiZWVuIGNvbnZlcnRlZCB0b1xuXHQgKiBVbmljb2RlLlxuXHQgKiBAbWVtYmVyT2YgcHVueWNvZGVcblx0ICogQHBhcmFtIHtTdHJpbmd9IGRvbWFpbiBUaGUgUHVueWNvZGUgZG9tYWluIG5hbWUgdG8gY29udmVydCB0byBVbmljb2RlLlxuXHQgKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgVW5pY29kZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gUHVueWNvZGVcblx0ICogc3RyaW5nLlxuXHQgKi9cblx0ZnVuY3Rpb24gdG9Vbmljb2RlKGRvbWFpbikge1xuXHRcdHJldHVybiBtYXBEb21haW4oZG9tYWluLCBmdW5jdGlvbihzdHJpbmcpIHtcblx0XHRcdHJldHVybiByZWdleFB1bnljb2RlLnRlc3Qoc3RyaW5nKVxuXHRcdFx0XHQ/IGRlY29kZShzdHJpbmcuc2xpY2UoNCkudG9Mb3dlckNhc2UoKSlcblx0XHRcdFx0OiBzdHJpbmc7XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgYSBVbmljb2RlIHN0cmluZyByZXByZXNlbnRpbmcgYSBkb21haW4gbmFtZSB0byBQdW55Y29kZS4gT25seSB0aGVcblx0ICogbm9uLUFTQ0lJIHBhcnRzIG9mIHRoZSBkb21haW4gbmFtZSB3aWxsIGJlIGNvbnZlcnRlZCwgaS5lLiBpdCBkb2Vzbid0XG5cdCAqIG1hdHRlciBpZiB5b3UgY2FsbCBpdCB3aXRoIGEgZG9tYWluIHRoYXQncyBhbHJlYWR5IGluIEFTQ0lJLlxuXHQgKiBAbWVtYmVyT2YgcHVueWNvZGVcblx0ICogQHBhcmFtIHtTdHJpbmd9IGRvbWFpbiBUaGUgZG9tYWluIG5hbWUgdG8gY29udmVydCwgYXMgYSBVbmljb2RlIHN0cmluZy5cblx0ICogQHJldHVybnMge1N0cmluZ30gVGhlIFB1bnljb2RlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBkb21haW4gbmFtZS5cblx0ICovXG5cdGZ1bmN0aW9uIHRvQVNDSUkoZG9tYWluKSB7XG5cdFx0cmV0dXJuIG1hcERvbWFpbihkb21haW4sIGZ1bmN0aW9uKHN0cmluZykge1xuXHRcdFx0cmV0dXJuIHJlZ2V4Tm9uQVNDSUkudGVzdChzdHJpbmcpXG5cdFx0XHRcdD8gJ3huLS0nICsgZW5jb2RlKHN0cmluZylcblx0XHRcdFx0OiBzdHJpbmc7XG5cdFx0fSk7XG5cdH1cblxuXHQvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuXHQvKiogRGVmaW5lIHRoZSBwdWJsaWMgQVBJICovXG5cdHB1bnljb2RlID0ge1xuXHRcdC8qKlxuXHRcdCAqIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBQdW55Y29kZS5qcyB2ZXJzaW9uIG51bWJlci5cblx0XHQgKiBAbWVtYmVyT2YgcHVueWNvZGVcblx0XHQgKiBAdHlwZSBTdHJpbmdcblx0XHQgKi9cblx0XHQndmVyc2lvbic6ICcxLjIuNCcsXG5cdFx0LyoqXG5cdFx0ICogQW4gb2JqZWN0IG9mIG1ldGhvZHMgdG8gY29udmVydCBmcm9tIEphdmFTY3JpcHQncyBpbnRlcm5hbCBjaGFyYWN0ZXJcblx0XHQgKiByZXByZXNlbnRhdGlvbiAoVUNTLTIpIHRvIFVuaWNvZGUgY29kZSBwb2ludHMsIGFuZCBiYWNrLlxuXHRcdCAqIEBzZWUgPGh0dHA6Ly9tYXRoaWFzYnluZW5zLmJlL25vdGVzL2phdmFzY3JpcHQtZW5jb2Rpbmc+XG5cdFx0ICogQG1lbWJlck9mIHB1bnljb2RlXG5cdFx0ICogQHR5cGUgT2JqZWN0XG5cdFx0ICovXG5cdFx0J3VjczInOiB7XG5cdFx0XHQnZGVjb2RlJzogdWNzMmRlY29kZSxcblx0XHRcdCdlbmNvZGUnOiB1Y3MyZW5jb2RlXG5cdFx0fSxcblx0XHQnZGVjb2RlJzogZGVjb2RlLFxuXHRcdCdlbmNvZGUnOiBlbmNvZGUsXG5cdFx0J3RvQVNDSUknOiB0b0FTQ0lJLFxuXHRcdCd0b1VuaWNvZGUnOiB0b1VuaWNvZGVcblx0fTtcblxuXHQvKiogRXhwb3NlIGBwdW55Y29kZWAgKi9cblx0Ly8gU29tZSBBTUQgYnVpbGQgb3B0aW1pemVycywgbGlrZSByLmpzLCBjaGVjayBmb3Igc3BlY2lmaWMgY29uZGl0aW9uIHBhdHRlcm5zXG5cdC8vIGxpa2UgdGhlIGZvbGxvd2luZzpcblx0aWYgKFxuXHRcdHR5cGVvZiBkZWZpbmUgPT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBkZWZpbmUuYW1kID09ICdvYmplY3QnICYmXG5cdFx0ZGVmaW5lLmFtZFxuXHQpIHtcblx0XHRkZWZpbmUoJ3B1bnljb2RlJywgZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gcHVueWNvZGU7XG5cdFx0fSk7XG5cdH0gZWxzZSBpZiAoZnJlZUV4cG9ydHMgJiYgIWZyZWVFeHBvcnRzLm5vZGVUeXBlKSB7XG5cdFx0aWYgKGZyZWVNb2R1bGUpIHsgLy8gaW4gTm9kZS5qcyBvciBSaW5nb0pTIHYwLjguMCtcblx0XHRcdGZyZWVNb2R1bGUuZXhwb3J0cyA9IHB1bnljb2RlO1xuXHRcdH0gZWxzZSB7IC8vIGluIE5hcndoYWwgb3IgUmluZ29KUyB2MC43LjAtXG5cdFx0XHRmb3IgKGtleSBpbiBwdW55Y29kZSkge1xuXHRcdFx0XHRwdW55Y29kZS5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIChmcmVlRXhwb3J0c1trZXldID0gcHVueWNvZGVba2V5XSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9IGVsc2UgeyAvLyBpbiBSaGlubyBvciBhIHdlYiBicm93c2VyXG5cdFx0cm9vdC5wdW55Y29kZSA9IHB1bnljb2RlO1xuXHR9XG5cbn0odGhpcykpO1xuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbid1c2Ugc3RyaWN0JztcblxuLy8gSWYgb2JqLmhhc093blByb3BlcnR5IGhhcyBiZWVuIG92ZXJyaWRkZW4sIHRoZW4gY2FsbGluZ1xuLy8gb2JqLmhhc093blByb3BlcnR5KHByb3ApIHdpbGwgYnJlYWsuXG4vLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9qb3llbnQvbm9kZS9pc3N1ZXMvMTcwN1xuZnVuY3Rpb24gaGFzT3duUHJvcGVydHkob2JqLCBwcm9wKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihxcywgc2VwLCBlcSwgb3B0aW9ucykge1xuICBzZXAgPSBzZXAgfHwgJyYnO1xuICBlcSA9IGVxIHx8ICc9JztcbiAgdmFyIG9iaiA9IHt9O1xuXG4gIGlmICh0eXBlb2YgcXMgIT09ICdzdHJpbmcnIHx8IHFzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICB2YXIgcmVnZXhwID0gL1xcKy9nO1xuICBxcyA9IHFzLnNwbGl0KHNlcCk7XG5cbiAgdmFyIG1heEtleXMgPSAxMDAwO1xuICBpZiAob3B0aW9ucyAmJiB0eXBlb2Ygb3B0aW9ucy5tYXhLZXlzID09PSAnbnVtYmVyJykge1xuICAgIG1heEtleXMgPSBvcHRpb25zLm1heEtleXM7XG4gIH1cblxuICB2YXIgbGVuID0gcXMubGVuZ3RoO1xuICAvLyBtYXhLZXlzIDw9IDAgbWVhbnMgdGhhdCB3ZSBzaG91bGQgbm90IGxpbWl0IGtleXMgY291bnRcbiAgaWYgKG1heEtleXMgPiAwICYmIGxlbiA+IG1heEtleXMpIHtcbiAgICBsZW4gPSBtYXhLZXlzO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgIHZhciB4ID0gcXNbaV0ucmVwbGFjZShyZWdleHAsICclMjAnKSxcbiAgICAgICAgaWR4ID0geC5pbmRleE9mKGVxKSxcbiAgICAgICAga3N0ciwgdnN0ciwgaywgdjtcblxuICAgIGlmIChpZHggPj0gMCkge1xuICAgICAga3N0ciA9IHguc3Vic3RyKDAsIGlkeCk7XG4gICAgICB2c3RyID0geC5zdWJzdHIoaWR4ICsgMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGtzdHIgPSB4O1xuICAgICAgdnN0ciA9ICcnO1xuICAgIH1cblxuICAgIGsgPSBkZWNvZGVVUklDb21wb25lbnQoa3N0cik7XG4gICAgdiA9IGRlY29kZVVSSUNvbXBvbmVudCh2c3RyKTtcblxuICAgIGlmICghaGFzT3duUHJvcGVydHkob2JqLCBrKSkge1xuICAgICAgb2JqW2tdID0gdjtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkob2JqW2tdKSkge1xuICAgICAgb2JqW2tdLnB1c2godik7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9ialtrXSA9IFtvYmpba10sIHZdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvYmo7XG59O1xuXG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKHhzKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoeHMpID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBzdHJpbmdpZnlQcmltaXRpdmUgPSBmdW5jdGlvbih2KSB7XG4gIHN3aXRjaCAodHlwZW9mIHYpIHtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgcmV0dXJuIHY7XG5cbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHJldHVybiB2ID8gJ3RydWUnIDogJ2ZhbHNlJztcblxuICAgIGNhc2UgJ251bWJlcic6XG4gICAgICByZXR1cm4gaXNGaW5pdGUodikgPyB2IDogJyc7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuICcnO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9iaiwgc2VwLCBlcSwgbmFtZSkge1xuICBzZXAgPSBzZXAgfHwgJyYnO1xuICBlcSA9IGVxIHx8ICc9JztcbiAgaWYgKG9iaiA9PT0gbnVsbCkge1xuICAgIG9iaiA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBtYXAob2JqZWN0S2V5cyhvYmopLCBmdW5jdGlvbihrKSB7XG4gICAgICB2YXIga3MgPSBlbmNvZGVVUklDb21wb25lbnQoc3RyaW5naWZ5UHJpbWl0aXZlKGspKSArIGVxO1xuICAgICAgaWYgKGlzQXJyYXkob2JqW2tdKSkge1xuICAgICAgICByZXR1cm4gbWFwKG9ialtrXSwgZnVuY3Rpb24odikge1xuICAgICAgICAgIHJldHVybiBrcyArIGVuY29kZVVSSUNvbXBvbmVudChzdHJpbmdpZnlQcmltaXRpdmUodikpO1xuICAgICAgICB9KS5qb2luKHNlcCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4ga3MgKyBlbmNvZGVVUklDb21wb25lbnQoc3RyaW5naWZ5UHJpbWl0aXZlKG9ialtrXSkpO1xuICAgICAgfVxuICAgIH0pLmpvaW4oc2VwKTtcblxuICB9XG5cbiAgaWYgKCFuYW1lKSByZXR1cm4gJyc7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoc3RyaW5naWZ5UHJpbWl0aXZlKG5hbWUpKSArIGVxICtcbiAgICAgICAgIGVuY29kZVVSSUNvbXBvbmVudChzdHJpbmdpZnlQcmltaXRpdmUob2JqKSk7XG59O1xuXG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKHhzKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoeHMpID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxuZnVuY3Rpb24gbWFwICh4cywgZikge1xuICBpZiAoeHMubWFwKSByZXR1cm4geHMubWFwKGYpO1xuICB2YXIgcmVzID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICByZXMucHVzaChmKHhzW2ldLCBpKSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cblxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciByZXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSByZXMucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiByZXM7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLmRlY29kZSA9IGV4cG9ydHMucGFyc2UgPSByZXF1aXJlKCcuL2RlY29kZScpO1xuZXhwb3J0cy5lbmNvZGUgPSBleHBvcnRzLnN0cmluZ2lmeSA9IHJlcXVpcmUoJy4vZW5jb2RlJyk7XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIHB1bnljb2RlID0gcmVxdWlyZSgncHVueWNvZGUnKTtcblxuZXhwb3J0cy5wYXJzZSA9IHVybFBhcnNlO1xuZXhwb3J0cy5yZXNvbHZlID0gdXJsUmVzb2x2ZTtcbmV4cG9ydHMucmVzb2x2ZU9iamVjdCA9IHVybFJlc29sdmVPYmplY3Q7XG5leHBvcnRzLmZvcm1hdCA9IHVybEZvcm1hdDtcblxuZXhwb3J0cy5VcmwgPSBVcmw7XG5cbmZ1bmN0aW9uIFVybCgpIHtcbiAgdGhpcy5wcm90b2NvbCA9IG51bGw7XG4gIHRoaXMuc2xhc2hlcyA9IG51bGw7XG4gIHRoaXMuYXV0aCA9IG51bGw7XG4gIHRoaXMuaG9zdCA9IG51bGw7XG4gIHRoaXMucG9ydCA9IG51bGw7XG4gIHRoaXMuaG9zdG5hbWUgPSBudWxsO1xuICB0aGlzLmhhc2ggPSBudWxsO1xuICB0aGlzLnNlYXJjaCA9IG51bGw7XG4gIHRoaXMucXVlcnkgPSBudWxsO1xuICB0aGlzLnBhdGhuYW1lID0gbnVsbDtcbiAgdGhpcy5wYXRoID0gbnVsbDtcbiAgdGhpcy5ocmVmID0gbnVsbDtcbn1cblxuLy8gUmVmZXJlbmNlOiBSRkMgMzk4NiwgUkZDIDE4MDgsIFJGQyAyMzk2XG5cbi8vIGRlZmluZSB0aGVzZSBoZXJlIHNvIGF0IGxlYXN0IHRoZXkgb25seSBoYXZlIHRvIGJlXG4vLyBjb21waWxlZCBvbmNlIG9uIHRoZSBmaXJzdCBtb2R1bGUgbG9hZC5cbnZhciBwcm90b2NvbFBhdHRlcm4gPSAvXihbYS16MC05ListXSs6KS9pLFxuICAgIHBvcnRQYXR0ZXJuID0gLzpbMC05XSokLyxcblxuICAgIC8vIFJGQyAyMzk2OiBjaGFyYWN0ZXJzIHJlc2VydmVkIGZvciBkZWxpbWl0aW5nIFVSTHMuXG4gICAgLy8gV2UgYWN0dWFsbHkganVzdCBhdXRvLWVzY2FwZSB0aGVzZS5cbiAgICBkZWxpbXMgPSBbJzwnLCAnPicsICdcIicsICdgJywgJyAnLCAnXFxyJywgJ1xcbicsICdcXHQnXSxcblxuICAgIC8vIFJGQyAyMzk2OiBjaGFyYWN0ZXJzIG5vdCBhbGxvd2VkIGZvciB2YXJpb3VzIHJlYXNvbnMuXG4gICAgdW53aXNlID0gWyd7JywgJ30nLCAnfCcsICdcXFxcJywgJ14nLCAnYCddLmNvbmNhdChkZWxpbXMpLFxuXG4gICAgLy8gQWxsb3dlZCBieSBSRkNzLCBidXQgY2F1c2Ugb2YgWFNTIGF0dGFja3MuICBBbHdheXMgZXNjYXBlIHRoZXNlLlxuICAgIGF1dG9Fc2NhcGUgPSBbJ1xcJyddLmNvbmNhdCh1bndpc2UpLFxuICAgIC8vIENoYXJhY3RlcnMgdGhhdCBhcmUgbmV2ZXIgZXZlciBhbGxvd2VkIGluIGEgaG9zdG5hbWUuXG4gICAgLy8gTm90ZSB0aGF0IGFueSBpbnZhbGlkIGNoYXJzIGFyZSBhbHNvIGhhbmRsZWQsIGJ1dCB0aGVzZVxuICAgIC8vIGFyZSB0aGUgb25lcyB0aGF0IGFyZSAqZXhwZWN0ZWQqIHRvIGJlIHNlZW4sIHNvIHdlIGZhc3QtcGF0aFxuICAgIC8vIHRoZW0uXG4gICAgbm9uSG9zdENoYXJzID0gWyclJywgJy8nLCAnPycsICc7JywgJyMnXS5jb25jYXQoYXV0b0VzY2FwZSksXG4gICAgaG9zdEVuZGluZ0NoYXJzID0gWycvJywgJz8nLCAnIyddLFxuICAgIGhvc3RuYW1lTWF4TGVuID0gMjU1LFxuICAgIGhvc3RuYW1lUGFydFBhdHRlcm4gPSAvXlthLXowLTlBLVpfLV17MCw2M30kLyxcbiAgICBob3N0bmFtZVBhcnRTdGFydCA9IC9eKFthLXowLTlBLVpfLV17MCw2M30pKC4qKSQvLFxuICAgIC8vIHByb3RvY29scyB0aGF0IGNhbiBhbGxvdyBcInVuc2FmZVwiIGFuZCBcInVud2lzZVwiIGNoYXJzLlxuICAgIHVuc2FmZVByb3RvY29sID0ge1xuICAgICAgJ2phdmFzY3JpcHQnOiB0cnVlLFxuICAgICAgJ2phdmFzY3JpcHQ6JzogdHJ1ZVxuICAgIH0sXG4gICAgLy8gcHJvdG9jb2xzIHRoYXQgbmV2ZXIgaGF2ZSBhIGhvc3RuYW1lLlxuICAgIGhvc3RsZXNzUHJvdG9jb2wgPSB7XG4gICAgICAnamF2YXNjcmlwdCc6IHRydWUsXG4gICAgICAnamF2YXNjcmlwdDonOiB0cnVlXG4gICAgfSxcbiAgICAvLyBwcm90b2NvbHMgdGhhdCBhbHdheXMgY29udGFpbiBhIC8vIGJpdC5cbiAgICBzbGFzaGVkUHJvdG9jb2wgPSB7XG4gICAgICAnaHR0cCc6IHRydWUsXG4gICAgICAnaHR0cHMnOiB0cnVlLFxuICAgICAgJ2Z0cCc6IHRydWUsXG4gICAgICAnZ29waGVyJzogdHJ1ZSxcbiAgICAgICdmaWxlJzogdHJ1ZSxcbiAgICAgICdodHRwOic6IHRydWUsXG4gICAgICAnaHR0cHM6JzogdHJ1ZSxcbiAgICAgICdmdHA6JzogdHJ1ZSxcbiAgICAgICdnb3BoZXI6JzogdHJ1ZSxcbiAgICAgICdmaWxlOic6IHRydWVcbiAgICB9LFxuICAgIHF1ZXJ5c3RyaW5nID0gcmVxdWlyZSgncXVlcnlzdHJpbmcnKTtcblxuZnVuY3Rpb24gdXJsUGFyc2UodXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCkge1xuICBpZiAodXJsICYmIGlzT2JqZWN0KHVybCkgJiYgdXJsIGluc3RhbmNlb2YgVXJsKSByZXR1cm4gdXJsO1xuXG4gIHZhciB1ID0gbmV3IFVybDtcbiAgdS5wYXJzZSh1cmwsIHBhcnNlUXVlcnlTdHJpbmcsIHNsYXNoZXNEZW5vdGVIb3N0KTtcbiAgcmV0dXJuIHU7XG59XG5cblVybC5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbih1cmwsIHBhcnNlUXVlcnlTdHJpbmcsIHNsYXNoZXNEZW5vdGVIb3N0KSB7XG4gIGlmICghaXNTdHJpbmcodXJsKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQYXJhbWV0ZXIgJ3VybCcgbXVzdCBiZSBhIHN0cmluZywgbm90IFwiICsgdHlwZW9mIHVybCk7XG4gIH1cblxuICB2YXIgcmVzdCA9IHVybDtcblxuICAvLyB0cmltIGJlZm9yZSBwcm9jZWVkaW5nLlxuICAvLyBUaGlzIGlzIHRvIHN1cHBvcnQgcGFyc2Ugc3R1ZmYgbGlrZSBcIiAgaHR0cDovL2Zvby5jb20gIFxcblwiXG4gIHJlc3QgPSByZXN0LnRyaW0oKTtcblxuICB2YXIgcHJvdG8gPSBwcm90b2NvbFBhdHRlcm4uZXhlYyhyZXN0KTtcbiAgaWYgKHByb3RvKSB7XG4gICAgcHJvdG8gPSBwcm90b1swXTtcbiAgICB2YXIgbG93ZXJQcm90byA9IHByb3RvLnRvTG93ZXJDYXNlKCk7XG4gICAgdGhpcy5wcm90b2NvbCA9IGxvd2VyUHJvdG87XG4gICAgcmVzdCA9IHJlc3Quc3Vic3RyKHByb3RvLmxlbmd0aCk7XG4gIH1cblxuICAvLyBmaWd1cmUgb3V0IGlmIGl0J3MgZ290IGEgaG9zdFxuICAvLyB1c2VyQHNlcnZlciBpcyAqYWx3YXlzKiBpbnRlcnByZXRlZCBhcyBhIGhvc3RuYW1lLCBhbmQgdXJsXG4gIC8vIHJlc29sdXRpb24gd2lsbCB0cmVhdCAvL2Zvby9iYXIgYXMgaG9zdD1mb28scGF0aD1iYXIgYmVjYXVzZSB0aGF0J3NcbiAgLy8gaG93IHRoZSBicm93c2VyIHJlc29sdmVzIHJlbGF0aXZlIFVSTHMuXG4gIGlmIChzbGFzaGVzRGVub3RlSG9zdCB8fCBwcm90byB8fCByZXN0Lm1hdGNoKC9eXFwvXFwvW15AXFwvXStAW15AXFwvXSsvKSkge1xuICAgIHZhciBzbGFzaGVzID0gcmVzdC5zdWJzdHIoMCwgMikgPT09ICcvLyc7XG4gICAgaWYgKHNsYXNoZXMgJiYgIShwcm90byAmJiBob3N0bGVzc1Byb3RvY29sW3Byb3RvXSkpIHtcbiAgICAgIHJlc3QgPSByZXN0LnN1YnN0cigyKTtcbiAgICAgIHRoaXMuc2xhc2hlcyA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFob3N0bGVzc1Byb3RvY29sW3Byb3RvXSAmJlxuICAgICAgKHNsYXNoZXMgfHwgKHByb3RvICYmICFzbGFzaGVkUHJvdG9jb2xbcHJvdG9dKSkpIHtcblxuICAgIC8vIHRoZXJlJ3MgYSBob3N0bmFtZS5cbiAgICAvLyB0aGUgZmlyc3QgaW5zdGFuY2Ugb2YgLywgPywgOywgb3IgIyBlbmRzIHRoZSBob3N0LlxuICAgIC8vXG4gICAgLy8gSWYgdGhlcmUgaXMgYW4gQCBpbiB0aGUgaG9zdG5hbWUsIHRoZW4gbm9uLWhvc3QgY2hhcnMgKmFyZSogYWxsb3dlZFxuICAgIC8vIHRvIHRoZSBsZWZ0IG9mIHRoZSBsYXN0IEAgc2lnbiwgdW5sZXNzIHNvbWUgaG9zdC1lbmRpbmcgY2hhcmFjdGVyXG4gICAgLy8gY29tZXMgKmJlZm9yZSogdGhlIEAtc2lnbi5cbiAgICAvLyBVUkxzIGFyZSBvYm5veGlvdXMuXG4gICAgLy9cbiAgICAvLyBleDpcbiAgICAvLyBodHRwOi8vYUBiQGMvID0+IHVzZXI6YUBiIGhvc3Q6Y1xuICAgIC8vIGh0dHA6Ly9hQGI/QGMgPT4gdXNlcjphIGhvc3Q6YyBwYXRoOi8/QGNcblxuICAgIC8vIHYwLjEyIFRPRE8oaXNhYWNzKTogVGhpcyBpcyBub3QgcXVpdGUgaG93IENocm9tZSBkb2VzIHRoaW5ncy5cbiAgICAvLyBSZXZpZXcgb3VyIHRlc3QgY2FzZSBhZ2FpbnN0IGJyb3dzZXJzIG1vcmUgY29tcHJlaGVuc2l2ZWx5LlxuXG4gICAgLy8gZmluZCB0aGUgZmlyc3QgaW5zdGFuY2Ugb2YgYW55IGhvc3RFbmRpbmdDaGFyc1xuICAgIHZhciBob3N0RW5kID0gLTE7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBob3N0RW5kaW5nQ2hhcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBoZWMgPSByZXN0LmluZGV4T2YoaG9zdEVuZGluZ0NoYXJzW2ldKTtcbiAgICAgIGlmIChoZWMgIT09IC0xICYmIChob3N0RW5kID09PSAtMSB8fCBoZWMgPCBob3N0RW5kKSlcbiAgICAgICAgaG9zdEVuZCA9IGhlYztcbiAgICB9XG5cbiAgICAvLyBhdCB0aGlzIHBvaW50LCBlaXRoZXIgd2UgaGF2ZSBhbiBleHBsaWNpdCBwb2ludCB3aGVyZSB0aGVcbiAgICAvLyBhdXRoIHBvcnRpb24gY2Fubm90IGdvIHBhc3QsIG9yIHRoZSBsYXN0IEAgY2hhciBpcyB0aGUgZGVjaWRlci5cbiAgICB2YXIgYXV0aCwgYXRTaWduO1xuICAgIGlmIChob3N0RW5kID09PSAtMSkge1xuICAgICAgLy8gYXRTaWduIGNhbiBiZSBhbnl3aGVyZS5cbiAgICAgIGF0U2lnbiA9IHJlc3QubGFzdEluZGV4T2YoJ0AnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gYXRTaWduIG11c3QgYmUgaW4gYXV0aCBwb3J0aW9uLlxuICAgICAgLy8gaHR0cDovL2FAYi9jQGQgPT4gaG9zdDpiIGF1dGg6YSBwYXRoOi9jQGRcbiAgICAgIGF0U2lnbiA9IHJlc3QubGFzdEluZGV4T2YoJ0AnLCBob3N0RW5kKTtcbiAgICB9XG5cbiAgICAvLyBOb3cgd2UgaGF2ZSBhIHBvcnRpb24gd2hpY2ggaXMgZGVmaW5pdGVseSB0aGUgYXV0aC5cbiAgICAvLyBQdWxsIHRoYXQgb2ZmLlxuICAgIGlmIChhdFNpZ24gIT09IC0xKSB7XG4gICAgICBhdXRoID0gcmVzdC5zbGljZSgwLCBhdFNpZ24pO1xuICAgICAgcmVzdCA9IHJlc3Quc2xpY2UoYXRTaWduICsgMSk7XG4gICAgICB0aGlzLmF1dGggPSBkZWNvZGVVUklDb21wb25lbnQoYXV0aCk7XG4gICAgfVxuXG4gICAgLy8gdGhlIGhvc3QgaXMgdGhlIHJlbWFpbmluZyB0byB0aGUgbGVmdCBvZiB0aGUgZmlyc3Qgbm9uLWhvc3QgY2hhclxuICAgIGhvc3RFbmQgPSAtMTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vbkhvc3RDaGFycy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGhlYyA9IHJlc3QuaW5kZXhPZihub25Ib3N0Q2hhcnNbaV0pO1xuICAgICAgaWYgKGhlYyAhPT0gLTEgJiYgKGhvc3RFbmQgPT09IC0xIHx8IGhlYyA8IGhvc3RFbmQpKVxuICAgICAgICBob3N0RW5kID0gaGVjO1xuICAgIH1cbiAgICAvLyBpZiB3ZSBzdGlsbCBoYXZlIG5vdCBoaXQgaXQsIHRoZW4gdGhlIGVudGlyZSB0aGluZyBpcyBhIGhvc3QuXG4gICAgaWYgKGhvc3RFbmQgPT09IC0xKVxuICAgICAgaG9zdEVuZCA9IHJlc3QubGVuZ3RoO1xuXG4gICAgdGhpcy5ob3N0ID0gcmVzdC5zbGljZSgwLCBob3N0RW5kKTtcbiAgICByZXN0ID0gcmVzdC5zbGljZShob3N0RW5kKTtcblxuICAgIC8vIHB1bGwgb3V0IHBvcnQuXG4gICAgdGhpcy5wYXJzZUhvc3QoKTtcblxuICAgIC8vIHdlJ3ZlIGluZGljYXRlZCB0aGF0IHRoZXJlIGlzIGEgaG9zdG5hbWUsXG4gICAgLy8gc28gZXZlbiBpZiBpdCdzIGVtcHR5LCBpdCBoYXMgdG8gYmUgcHJlc2VudC5cbiAgICB0aGlzLmhvc3RuYW1lID0gdGhpcy5ob3N0bmFtZSB8fCAnJztcblxuICAgIC8vIGlmIGhvc3RuYW1lIGJlZ2lucyB3aXRoIFsgYW5kIGVuZHMgd2l0aCBdXG4gICAgLy8gYXNzdW1lIHRoYXQgaXQncyBhbiBJUHY2IGFkZHJlc3MuXG4gICAgdmFyIGlwdjZIb3N0bmFtZSA9IHRoaXMuaG9zdG5hbWVbMF0gPT09ICdbJyAmJlxuICAgICAgICB0aGlzLmhvc3RuYW1lW3RoaXMuaG9zdG5hbWUubGVuZ3RoIC0gMV0gPT09ICddJztcblxuICAgIC8vIHZhbGlkYXRlIGEgbGl0dGxlLlxuICAgIGlmICghaXB2Nkhvc3RuYW1lKSB7XG4gICAgICB2YXIgaG9zdHBhcnRzID0gdGhpcy5ob3N0bmFtZS5zcGxpdCgvXFwuLyk7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGhvc3RwYXJ0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgdmFyIHBhcnQgPSBob3N0cGFydHNbaV07XG4gICAgICAgIGlmICghcGFydCkgY29udGludWU7XG4gICAgICAgIGlmICghcGFydC5tYXRjaChob3N0bmFtZVBhcnRQYXR0ZXJuKSkge1xuICAgICAgICAgIHZhciBuZXdwYXJ0ID0gJyc7XG4gICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGsgPSBwYXJ0Lmxlbmd0aDsgaiA8IGs7IGorKykge1xuICAgICAgICAgICAgaWYgKHBhcnQuY2hhckNvZGVBdChqKSA+IDEyNykge1xuICAgICAgICAgICAgICAvLyB3ZSByZXBsYWNlIG5vbi1BU0NJSSBjaGFyIHdpdGggYSB0ZW1wb3JhcnkgcGxhY2Vob2xkZXJcbiAgICAgICAgICAgICAgLy8gd2UgbmVlZCB0aGlzIHRvIG1ha2Ugc3VyZSBzaXplIG9mIGhvc3RuYW1lIGlzIG5vdFxuICAgICAgICAgICAgICAvLyBicm9rZW4gYnkgcmVwbGFjaW5nIG5vbi1BU0NJSSBieSBub3RoaW5nXG4gICAgICAgICAgICAgIG5ld3BhcnQgKz0gJ3gnO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgbmV3cGFydCArPSBwYXJ0W2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvLyB3ZSB0ZXN0IGFnYWluIHdpdGggQVNDSUkgY2hhciBvbmx5XG4gICAgICAgICAgaWYgKCFuZXdwYXJ0Lm1hdGNoKGhvc3RuYW1lUGFydFBhdHRlcm4pKSB7XG4gICAgICAgICAgICB2YXIgdmFsaWRQYXJ0cyA9IGhvc3RwYXJ0cy5zbGljZSgwLCBpKTtcbiAgICAgICAgICAgIHZhciBub3RIb3N0ID0gaG9zdHBhcnRzLnNsaWNlKGkgKyAxKTtcbiAgICAgICAgICAgIHZhciBiaXQgPSBwYXJ0Lm1hdGNoKGhvc3RuYW1lUGFydFN0YXJ0KTtcbiAgICAgICAgICAgIGlmIChiaXQpIHtcbiAgICAgICAgICAgICAgdmFsaWRQYXJ0cy5wdXNoKGJpdFsxXSk7XG4gICAgICAgICAgICAgIG5vdEhvc3QudW5zaGlmdChiaXRbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG5vdEhvc3QubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIHJlc3QgPSAnLycgKyBub3RIb3N0LmpvaW4oJy4nKSArIHJlc3Q7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmhvc3RuYW1lID0gdmFsaWRQYXJ0cy5qb2luKCcuJyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5ob3N0bmFtZS5sZW5ndGggPiBob3N0bmFtZU1heExlbikge1xuICAgICAgdGhpcy5ob3N0bmFtZSA9ICcnO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBob3N0bmFtZXMgYXJlIGFsd2F5cyBsb3dlciBjYXNlLlxuICAgICAgdGhpcy5ob3N0bmFtZSA9IHRoaXMuaG9zdG5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICB9XG5cbiAgICBpZiAoIWlwdjZIb3N0bmFtZSkge1xuICAgICAgLy8gSUROQSBTdXBwb3J0OiBSZXR1cm5zIGEgcHVueSBjb2RlZCByZXByZXNlbnRhdGlvbiBvZiBcImRvbWFpblwiLlxuICAgICAgLy8gSXQgb25seSBjb252ZXJ0cyB0aGUgcGFydCBvZiB0aGUgZG9tYWluIG5hbWUgdGhhdFxuICAgICAgLy8gaGFzIG5vbiBBU0NJSSBjaGFyYWN0ZXJzLiBJLmUuIGl0IGRvc2VudCBtYXR0ZXIgaWZcbiAgICAgIC8vIHlvdSBjYWxsIGl0IHdpdGggYSBkb21haW4gdGhhdCBhbHJlYWR5IGlzIGluIEFTQ0lJLlxuICAgICAgdmFyIGRvbWFpbkFycmF5ID0gdGhpcy5ob3N0bmFtZS5zcGxpdCgnLicpO1xuICAgICAgdmFyIG5ld091dCA9IFtdO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkb21haW5BcnJheS5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgcyA9IGRvbWFpbkFycmF5W2ldO1xuICAgICAgICBuZXdPdXQucHVzaChzLm1hdGNoKC9bXkEtWmEtejAtOV8tXS8pID9cbiAgICAgICAgICAgICd4bi0tJyArIHB1bnljb2RlLmVuY29kZShzKSA6IHMpO1xuICAgICAgfVxuICAgICAgdGhpcy5ob3N0bmFtZSA9IG5ld091dC5qb2luKCcuJyk7XG4gICAgfVxuXG4gICAgdmFyIHAgPSB0aGlzLnBvcnQgPyAnOicgKyB0aGlzLnBvcnQgOiAnJztcbiAgICB2YXIgaCA9IHRoaXMuaG9zdG5hbWUgfHwgJyc7XG4gICAgdGhpcy5ob3N0ID0gaCArIHA7XG4gICAgdGhpcy5ocmVmICs9IHRoaXMuaG9zdDtcblxuICAgIC8vIHN0cmlwIFsgYW5kIF0gZnJvbSB0aGUgaG9zdG5hbWVcbiAgICAvLyB0aGUgaG9zdCBmaWVsZCBzdGlsbCByZXRhaW5zIHRoZW0sIHRob3VnaFxuICAgIGlmIChpcHY2SG9zdG5hbWUpIHtcbiAgICAgIHRoaXMuaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lLnN1YnN0cigxLCB0aGlzLmhvc3RuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgaWYgKHJlc3RbMF0gIT09ICcvJykge1xuICAgICAgICByZXN0ID0gJy8nICsgcmVzdDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBub3cgcmVzdCBpcyBzZXQgdG8gdGhlIHBvc3QtaG9zdCBzdHVmZi5cbiAgLy8gY2hvcCBvZmYgYW55IGRlbGltIGNoYXJzLlxuICBpZiAoIXVuc2FmZVByb3RvY29sW2xvd2VyUHJvdG9dKSB7XG5cbiAgICAvLyBGaXJzdCwgbWFrZSAxMDAlIHN1cmUgdGhhdCBhbnkgXCJhdXRvRXNjYXBlXCIgY2hhcnMgZ2V0XG4gICAgLy8gZXNjYXBlZCwgZXZlbiBpZiBlbmNvZGVVUklDb21wb25lbnQgZG9lc24ndCB0aGluayB0aGV5XG4gICAgLy8gbmVlZCB0byBiZS5cbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGF1dG9Fc2NhcGUubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICB2YXIgYWUgPSBhdXRvRXNjYXBlW2ldO1xuICAgICAgdmFyIGVzYyA9IGVuY29kZVVSSUNvbXBvbmVudChhZSk7XG4gICAgICBpZiAoZXNjID09PSBhZSkge1xuICAgICAgICBlc2MgPSBlc2NhcGUoYWUpO1xuICAgICAgfVxuICAgICAgcmVzdCA9IHJlc3Quc3BsaXQoYWUpLmpvaW4oZXNjKTtcbiAgICB9XG4gIH1cblxuXG4gIC8vIGNob3Agb2ZmIGZyb20gdGhlIHRhaWwgZmlyc3QuXG4gIHZhciBoYXNoID0gcmVzdC5pbmRleE9mKCcjJyk7XG4gIGlmIChoYXNoICE9PSAtMSkge1xuICAgIC8vIGdvdCBhIGZyYWdtZW50IHN0cmluZy5cbiAgICB0aGlzLmhhc2ggPSByZXN0LnN1YnN0cihoYXNoKTtcbiAgICByZXN0ID0gcmVzdC5zbGljZSgwLCBoYXNoKTtcbiAgfVxuICB2YXIgcW0gPSByZXN0LmluZGV4T2YoJz8nKTtcbiAgaWYgKHFtICE9PSAtMSkge1xuICAgIHRoaXMuc2VhcmNoID0gcmVzdC5zdWJzdHIocW0pO1xuICAgIHRoaXMucXVlcnkgPSByZXN0LnN1YnN0cihxbSArIDEpO1xuICAgIGlmIChwYXJzZVF1ZXJ5U3RyaW5nKSB7XG4gICAgICB0aGlzLnF1ZXJ5ID0gcXVlcnlzdHJpbmcucGFyc2UodGhpcy5xdWVyeSk7XG4gICAgfVxuICAgIHJlc3QgPSByZXN0LnNsaWNlKDAsIHFtKTtcbiAgfSBlbHNlIGlmIChwYXJzZVF1ZXJ5U3RyaW5nKSB7XG4gICAgLy8gbm8gcXVlcnkgc3RyaW5nLCBidXQgcGFyc2VRdWVyeVN0cmluZyBzdGlsbCByZXF1ZXN0ZWRcbiAgICB0aGlzLnNlYXJjaCA9ICcnO1xuICAgIHRoaXMucXVlcnkgPSB7fTtcbiAgfVxuICBpZiAocmVzdCkgdGhpcy5wYXRobmFtZSA9IHJlc3Q7XG4gIGlmIChzbGFzaGVkUHJvdG9jb2xbbG93ZXJQcm90b10gJiZcbiAgICAgIHRoaXMuaG9zdG5hbWUgJiYgIXRoaXMucGF0aG5hbWUpIHtcbiAgICB0aGlzLnBhdGhuYW1lID0gJy8nO1xuICB9XG5cbiAgLy90byBzdXBwb3J0IGh0dHAucmVxdWVzdFxuICBpZiAodGhpcy5wYXRobmFtZSB8fCB0aGlzLnNlYXJjaCkge1xuICAgIHZhciBwID0gdGhpcy5wYXRobmFtZSB8fCAnJztcbiAgICB2YXIgcyA9IHRoaXMuc2VhcmNoIHx8ICcnO1xuICAgIHRoaXMucGF0aCA9IHAgKyBzO1xuICB9XG5cbiAgLy8gZmluYWxseSwgcmVjb25zdHJ1Y3QgdGhlIGhyZWYgYmFzZWQgb24gd2hhdCBoYXMgYmVlbiB2YWxpZGF0ZWQuXG4gIHRoaXMuaHJlZiA9IHRoaXMuZm9ybWF0KCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gZm9ybWF0IGEgcGFyc2VkIG9iamVjdCBpbnRvIGEgdXJsIHN0cmluZ1xuZnVuY3Rpb24gdXJsRm9ybWF0KG9iaikge1xuICAvLyBlbnN1cmUgaXQncyBhbiBvYmplY3QsIGFuZCBub3QgYSBzdHJpbmcgdXJsLlxuICAvLyBJZiBpdCdzIGFuIG9iaiwgdGhpcyBpcyBhIG5vLW9wLlxuICAvLyB0aGlzIHdheSwgeW91IGNhbiBjYWxsIHVybF9mb3JtYXQoKSBvbiBzdHJpbmdzXG4gIC8vIHRvIGNsZWFuIHVwIHBvdGVudGlhbGx5IHdvbmt5IHVybHMuXG4gIGlmIChpc1N0cmluZyhvYmopKSBvYmogPSB1cmxQYXJzZShvYmopO1xuICBpZiAoIShvYmogaW5zdGFuY2VvZiBVcmwpKSByZXR1cm4gVXJsLnByb3RvdHlwZS5mb3JtYXQuY2FsbChvYmopO1xuICByZXR1cm4gb2JqLmZvcm1hdCgpO1xufVxuXG5VcmwucHJvdG90eXBlLmZvcm1hdCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgYXV0aCA9IHRoaXMuYXV0aCB8fCAnJztcbiAgaWYgKGF1dGgpIHtcbiAgICBhdXRoID0gZW5jb2RlVVJJQ29tcG9uZW50KGF1dGgpO1xuICAgIGF1dGggPSBhdXRoLnJlcGxhY2UoLyUzQS9pLCAnOicpO1xuICAgIGF1dGggKz0gJ0AnO1xuICB9XG5cbiAgdmFyIHByb3RvY29sID0gdGhpcy5wcm90b2NvbCB8fCAnJyxcbiAgICAgIHBhdGhuYW1lID0gdGhpcy5wYXRobmFtZSB8fCAnJyxcbiAgICAgIGhhc2ggPSB0aGlzLmhhc2ggfHwgJycsXG4gICAgICBob3N0ID0gZmFsc2UsXG4gICAgICBxdWVyeSA9ICcnO1xuXG4gIGlmICh0aGlzLmhvc3QpIHtcbiAgICBob3N0ID0gYXV0aCArIHRoaXMuaG9zdDtcbiAgfSBlbHNlIGlmICh0aGlzLmhvc3RuYW1lKSB7XG4gICAgaG9zdCA9IGF1dGggKyAodGhpcy5ob3N0bmFtZS5pbmRleE9mKCc6JykgPT09IC0xID9cbiAgICAgICAgdGhpcy5ob3N0bmFtZSA6XG4gICAgICAgICdbJyArIHRoaXMuaG9zdG5hbWUgKyAnXScpO1xuICAgIGlmICh0aGlzLnBvcnQpIHtcbiAgICAgIGhvc3QgKz0gJzonICsgdGhpcy5wb3J0O1xuICAgIH1cbiAgfVxuXG4gIGlmICh0aGlzLnF1ZXJ5ICYmXG4gICAgICBpc09iamVjdCh0aGlzLnF1ZXJ5KSAmJlxuICAgICAgT2JqZWN0LmtleXModGhpcy5xdWVyeSkubGVuZ3RoKSB7XG4gICAgcXVlcnkgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkodGhpcy5xdWVyeSk7XG4gIH1cblxuICB2YXIgc2VhcmNoID0gdGhpcy5zZWFyY2ggfHwgKHF1ZXJ5ICYmICgnPycgKyBxdWVyeSkpIHx8ICcnO1xuXG4gIGlmIChwcm90b2NvbCAmJiBwcm90b2NvbC5zdWJzdHIoLTEpICE9PSAnOicpIHByb3RvY29sICs9ICc6JztcblxuICAvLyBvbmx5IHRoZSBzbGFzaGVkUHJvdG9jb2xzIGdldCB0aGUgLy8uICBOb3QgbWFpbHRvOiwgeG1wcDosIGV0Yy5cbiAgLy8gdW5sZXNzIHRoZXkgaGFkIHRoZW0gdG8gYmVnaW4gd2l0aC5cbiAgaWYgKHRoaXMuc2xhc2hlcyB8fFxuICAgICAgKCFwcm90b2NvbCB8fCBzbGFzaGVkUHJvdG9jb2xbcHJvdG9jb2xdKSAmJiBob3N0ICE9PSBmYWxzZSkge1xuICAgIGhvc3QgPSAnLy8nICsgKGhvc3QgfHwgJycpO1xuICAgIGlmIChwYXRobmFtZSAmJiBwYXRobmFtZS5jaGFyQXQoMCkgIT09ICcvJykgcGF0aG5hbWUgPSAnLycgKyBwYXRobmFtZTtcbiAgfSBlbHNlIGlmICghaG9zdCkge1xuICAgIGhvc3QgPSAnJztcbiAgfVxuXG4gIGlmIChoYXNoICYmIGhhc2guY2hhckF0KDApICE9PSAnIycpIGhhc2ggPSAnIycgKyBoYXNoO1xuICBpZiAoc2VhcmNoICYmIHNlYXJjaC5jaGFyQXQoMCkgIT09ICc/Jykgc2VhcmNoID0gJz8nICsgc2VhcmNoO1xuXG4gIHBhdGhuYW1lID0gcGF0aG5hbWUucmVwbGFjZSgvWz8jXS9nLCBmdW5jdGlvbihtYXRjaCkge1xuICAgIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQobWF0Y2gpO1xuICB9KTtcbiAgc2VhcmNoID0gc2VhcmNoLnJlcGxhY2UoJyMnLCAnJTIzJyk7XG5cbiAgcmV0dXJuIHByb3RvY29sICsgaG9zdCArIHBhdGhuYW1lICsgc2VhcmNoICsgaGFzaDtcbn07XG5cbmZ1bmN0aW9uIHVybFJlc29sdmUoc291cmNlLCByZWxhdGl2ZSkge1xuICByZXR1cm4gdXJsUGFyc2Uoc291cmNlLCBmYWxzZSwgdHJ1ZSkucmVzb2x2ZShyZWxhdGl2ZSk7XG59XG5cblVybC5wcm90b3R5cGUucmVzb2x2ZSA9IGZ1bmN0aW9uKHJlbGF0aXZlKSB7XG4gIHJldHVybiB0aGlzLnJlc29sdmVPYmplY3QodXJsUGFyc2UocmVsYXRpdmUsIGZhbHNlLCB0cnVlKSkuZm9ybWF0KCk7XG59O1xuXG5mdW5jdGlvbiB1cmxSZXNvbHZlT2JqZWN0KHNvdXJjZSwgcmVsYXRpdmUpIHtcbiAgaWYgKCFzb3VyY2UpIHJldHVybiByZWxhdGl2ZTtcbiAgcmV0dXJuIHVybFBhcnNlKHNvdXJjZSwgZmFsc2UsIHRydWUpLnJlc29sdmVPYmplY3QocmVsYXRpdmUpO1xufVxuXG5VcmwucHJvdG90eXBlLnJlc29sdmVPYmplY3QgPSBmdW5jdGlvbihyZWxhdGl2ZSkge1xuICBpZiAoaXNTdHJpbmcocmVsYXRpdmUpKSB7XG4gICAgdmFyIHJlbCA9IG5ldyBVcmwoKTtcbiAgICByZWwucGFyc2UocmVsYXRpdmUsIGZhbHNlLCB0cnVlKTtcbiAgICByZWxhdGl2ZSA9IHJlbDtcbiAgfVxuXG4gIHZhciByZXN1bHQgPSBuZXcgVXJsKCk7XG4gIE9iamVjdC5rZXlzKHRoaXMpLmZvckVhY2goZnVuY3Rpb24oaykge1xuICAgIHJlc3VsdFtrXSA9IHRoaXNba107XG4gIH0sIHRoaXMpO1xuXG4gIC8vIGhhc2ggaXMgYWx3YXlzIG92ZXJyaWRkZW4sIG5vIG1hdHRlciB3aGF0LlxuICAvLyBldmVuIGhyZWY9XCJcIiB3aWxsIHJlbW92ZSBpdC5cbiAgcmVzdWx0Lmhhc2ggPSByZWxhdGl2ZS5oYXNoO1xuXG4gIC8vIGlmIHRoZSByZWxhdGl2ZSB1cmwgaXMgZW1wdHksIHRoZW4gdGhlcmUncyBub3RoaW5nIGxlZnQgdG8gZG8gaGVyZS5cbiAgaWYgKHJlbGF0aXZlLmhyZWYgPT09ICcnKSB7XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIGhyZWZzIGxpa2UgLy9mb28vYmFyIGFsd2F5cyBjdXQgdG8gdGhlIHByb3RvY29sLlxuICBpZiAocmVsYXRpdmUuc2xhc2hlcyAmJiAhcmVsYXRpdmUucHJvdG9jb2wpIHtcbiAgICAvLyB0YWtlIGV2ZXJ5dGhpbmcgZXhjZXB0IHRoZSBwcm90b2NvbCBmcm9tIHJlbGF0aXZlXG4gICAgT2JqZWN0LmtleXMocmVsYXRpdmUpLmZvckVhY2goZnVuY3Rpb24oaykge1xuICAgICAgaWYgKGsgIT09ICdwcm90b2NvbCcpXG4gICAgICAgIHJlc3VsdFtrXSA9IHJlbGF0aXZlW2tdO1xuICAgIH0pO1xuXG4gICAgLy91cmxQYXJzZSBhcHBlbmRzIHRyYWlsaW5nIC8gdG8gdXJscyBsaWtlIGh0dHA6Ly93d3cuZXhhbXBsZS5jb21cbiAgICBpZiAoc2xhc2hlZFByb3RvY29sW3Jlc3VsdC5wcm90b2NvbF0gJiZcbiAgICAgICAgcmVzdWx0Lmhvc3RuYW1lICYmICFyZXN1bHQucGF0aG5hbWUpIHtcbiAgICAgIHJlc3VsdC5wYXRoID0gcmVzdWx0LnBhdGhuYW1lID0gJy8nO1xuICAgIH1cblxuICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBpZiAocmVsYXRpdmUucHJvdG9jb2wgJiYgcmVsYXRpdmUucHJvdG9jb2wgIT09IHJlc3VsdC5wcm90b2NvbCkge1xuICAgIC8vIGlmIGl0J3MgYSBrbm93biB1cmwgcHJvdG9jb2wsIHRoZW4gY2hhbmdpbmdcbiAgICAvLyB0aGUgcHJvdG9jb2wgZG9lcyB3ZWlyZCB0aGluZ3NcbiAgICAvLyBmaXJzdCwgaWYgaXQncyBub3QgZmlsZTosIHRoZW4gd2UgTVVTVCBoYXZlIGEgaG9zdCxcbiAgICAvLyBhbmQgaWYgdGhlcmUgd2FzIGEgcGF0aFxuICAgIC8vIHRvIGJlZ2luIHdpdGgsIHRoZW4gd2UgTVVTVCBoYXZlIGEgcGF0aC5cbiAgICAvLyBpZiBpdCBpcyBmaWxlOiwgdGhlbiB0aGUgaG9zdCBpcyBkcm9wcGVkLFxuICAgIC8vIGJlY2F1c2UgdGhhdCdzIGtub3duIHRvIGJlIGhvc3RsZXNzLlxuICAgIC8vIGFueXRoaW5nIGVsc2UgaXMgYXNzdW1lZCB0byBiZSBhYnNvbHV0ZS5cbiAgICBpZiAoIXNsYXNoZWRQcm90b2NvbFtyZWxhdGl2ZS5wcm90b2NvbF0pIHtcbiAgICAgIE9iamVjdC5rZXlzKHJlbGF0aXZlKS5mb3JFYWNoKGZ1bmN0aW9uKGspIHtcbiAgICAgICAgcmVzdWx0W2tdID0gcmVsYXRpdmVba107XG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICByZXN1bHQucHJvdG9jb2wgPSByZWxhdGl2ZS5wcm90b2NvbDtcbiAgICBpZiAoIXJlbGF0aXZlLmhvc3QgJiYgIWhvc3RsZXNzUHJvdG9jb2xbcmVsYXRpdmUucHJvdG9jb2xdKSB7XG4gICAgICB2YXIgcmVsUGF0aCA9IChyZWxhdGl2ZS5wYXRobmFtZSB8fCAnJykuc3BsaXQoJy8nKTtcbiAgICAgIHdoaWxlIChyZWxQYXRoLmxlbmd0aCAmJiAhKHJlbGF0aXZlLmhvc3QgPSByZWxQYXRoLnNoaWZ0KCkpKTtcbiAgICAgIGlmICghcmVsYXRpdmUuaG9zdCkgcmVsYXRpdmUuaG9zdCA9ICcnO1xuICAgICAgaWYgKCFyZWxhdGl2ZS5ob3N0bmFtZSkgcmVsYXRpdmUuaG9zdG5hbWUgPSAnJztcbiAgICAgIGlmIChyZWxQYXRoWzBdICE9PSAnJykgcmVsUGF0aC51bnNoaWZ0KCcnKTtcbiAgICAgIGlmIChyZWxQYXRoLmxlbmd0aCA8IDIpIHJlbFBhdGgudW5zaGlmdCgnJyk7XG4gICAgICByZXN1bHQucGF0aG5hbWUgPSByZWxQYXRoLmpvaW4oJy8nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0LnBhdGhuYW1lID0gcmVsYXRpdmUucGF0aG5hbWU7XG4gICAgfVxuICAgIHJlc3VsdC5zZWFyY2ggPSByZWxhdGl2ZS5zZWFyY2g7XG4gICAgcmVzdWx0LnF1ZXJ5ID0gcmVsYXRpdmUucXVlcnk7XG4gICAgcmVzdWx0Lmhvc3QgPSByZWxhdGl2ZS5ob3N0IHx8ICcnO1xuICAgIHJlc3VsdC5hdXRoID0gcmVsYXRpdmUuYXV0aDtcbiAgICByZXN1bHQuaG9zdG5hbWUgPSByZWxhdGl2ZS5ob3N0bmFtZSB8fCByZWxhdGl2ZS5ob3N0O1xuICAgIHJlc3VsdC5wb3J0ID0gcmVsYXRpdmUucG9ydDtcbiAgICAvLyB0byBzdXBwb3J0IGh0dHAucmVxdWVzdFxuICAgIGlmIChyZXN1bHQucGF0aG5hbWUgfHwgcmVzdWx0LnNlYXJjaCkge1xuICAgICAgdmFyIHAgPSByZXN1bHQucGF0aG5hbWUgfHwgJyc7XG4gICAgICB2YXIgcyA9IHJlc3VsdC5zZWFyY2ggfHwgJyc7XG4gICAgICByZXN1bHQucGF0aCA9IHAgKyBzO1xuICAgIH1cbiAgICByZXN1bHQuc2xhc2hlcyA9IHJlc3VsdC5zbGFzaGVzIHx8IHJlbGF0aXZlLnNsYXNoZXM7XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHZhciBpc1NvdXJjZUFicyA9IChyZXN1bHQucGF0aG5hbWUgJiYgcmVzdWx0LnBhdGhuYW1lLmNoYXJBdCgwKSA9PT0gJy8nKSxcbiAgICAgIGlzUmVsQWJzID0gKFxuICAgICAgICAgIHJlbGF0aXZlLmhvc3QgfHxcbiAgICAgICAgICByZWxhdGl2ZS5wYXRobmFtZSAmJiByZWxhdGl2ZS5wYXRobmFtZS5jaGFyQXQoMCkgPT09ICcvJ1xuICAgICAgKSxcbiAgICAgIG11c3RFbmRBYnMgPSAoaXNSZWxBYnMgfHwgaXNTb3VyY2VBYnMgfHxcbiAgICAgICAgICAgICAgICAgICAgKHJlc3VsdC5ob3N0ICYmIHJlbGF0aXZlLnBhdGhuYW1lKSksXG4gICAgICByZW1vdmVBbGxEb3RzID0gbXVzdEVuZEFicyxcbiAgICAgIHNyY1BhdGggPSByZXN1bHQucGF0aG5hbWUgJiYgcmVzdWx0LnBhdGhuYW1lLnNwbGl0KCcvJykgfHwgW10sXG4gICAgICByZWxQYXRoID0gcmVsYXRpdmUucGF0aG5hbWUgJiYgcmVsYXRpdmUucGF0aG5hbWUuc3BsaXQoJy8nKSB8fCBbXSxcbiAgICAgIHBzeWNob3RpYyA9IHJlc3VsdC5wcm90b2NvbCAmJiAhc2xhc2hlZFByb3RvY29sW3Jlc3VsdC5wcm90b2NvbF07XG5cbiAgLy8gaWYgdGhlIHVybCBpcyBhIG5vbi1zbGFzaGVkIHVybCwgdGhlbiByZWxhdGl2ZVxuICAvLyBsaW5rcyBsaWtlIC4uLy4uIHNob3VsZCBiZSBhYmxlXG4gIC8vIHRvIGNyYXdsIHVwIHRvIHRoZSBob3N0bmFtZSwgYXMgd2VsbC4gIFRoaXMgaXMgc3RyYW5nZS5cbiAgLy8gcmVzdWx0LnByb3RvY29sIGhhcyBhbHJlYWR5IGJlZW4gc2V0IGJ5IG5vdy5cbiAgLy8gTGF0ZXIgb24sIHB1dCB0aGUgZmlyc3QgcGF0aCBwYXJ0IGludG8gdGhlIGhvc3QgZmllbGQuXG4gIGlmIChwc3ljaG90aWMpIHtcbiAgICByZXN1bHQuaG9zdG5hbWUgPSAnJztcbiAgICByZXN1bHQucG9ydCA9IG51bGw7XG4gICAgaWYgKHJlc3VsdC5ob3N0KSB7XG4gICAgICBpZiAoc3JjUGF0aFswXSA9PT0gJycpIHNyY1BhdGhbMF0gPSByZXN1bHQuaG9zdDtcbiAgICAgIGVsc2Ugc3JjUGF0aC51bnNoaWZ0KHJlc3VsdC5ob3N0KTtcbiAgICB9XG4gICAgcmVzdWx0Lmhvc3QgPSAnJztcbiAgICBpZiAocmVsYXRpdmUucHJvdG9jb2wpIHtcbiAgICAgIHJlbGF0aXZlLmhvc3RuYW1lID0gbnVsbDtcbiAgICAgIHJlbGF0aXZlLnBvcnQgPSBudWxsO1xuICAgICAgaWYgKHJlbGF0aXZlLmhvc3QpIHtcbiAgICAgICAgaWYgKHJlbFBhdGhbMF0gPT09ICcnKSByZWxQYXRoWzBdID0gcmVsYXRpdmUuaG9zdDtcbiAgICAgICAgZWxzZSByZWxQYXRoLnVuc2hpZnQocmVsYXRpdmUuaG9zdCk7XG4gICAgICB9XG4gICAgICByZWxhdGl2ZS5ob3N0ID0gbnVsbDtcbiAgICB9XG4gICAgbXVzdEVuZEFicyA9IG11c3RFbmRBYnMgJiYgKHJlbFBhdGhbMF0gPT09ICcnIHx8IHNyY1BhdGhbMF0gPT09ICcnKTtcbiAgfVxuXG4gIGlmIChpc1JlbEFicykge1xuICAgIC8vIGl0J3MgYWJzb2x1dGUuXG4gICAgcmVzdWx0Lmhvc3QgPSAocmVsYXRpdmUuaG9zdCB8fCByZWxhdGl2ZS5ob3N0ID09PSAnJykgP1xuICAgICAgICAgICAgICAgICAgcmVsYXRpdmUuaG9zdCA6IHJlc3VsdC5ob3N0O1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9IChyZWxhdGl2ZS5ob3N0bmFtZSB8fCByZWxhdGl2ZS5ob3N0bmFtZSA9PT0gJycpID9cbiAgICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZS5ob3N0bmFtZSA6IHJlc3VsdC5ob3N0bmFtZTtcbiAgICByZXN1bHQuc2VhcmNoID0gcmVsYXRpdmUuc2VhcmNoO1xuICAgIHJlc3VsdC5xdWVyeSA9IHJlbGF0aXZlLnF1ZXJ5O1xuICAgIHNyY1BhdGggPSByZWxQYXRoO1xuICAgIC8vIGZhbGwgdGhyb3VnaCB0byB0aGUgZG90LWhhbmRsaW5nIGJlbG93LlxuICB9IGVsc2UgaWYgKHJlbFBhdGgubGVuZ3RoKSB7XG4gICAgLy8gaXQncyByZWxhdGl2ZVxuICAgIC8vIHRocm93IGF3YXkgdGhlIGV4aXN0aW5nIGZpbGUsIGFuZCB0YWtlIHRoZSBuZXcgcGF0aCBpbnN0ZWFkLlxuICAgIGlmICghc3JjUGF0aCkgc3JjUGF0aCA9IFtdO1xuICAgIHNyY1BhdGgucG9wKCk7XG4gICAgc3JjUGF0aCA9IHNyY1BhdGguY29uY2F0KHJlbFBhdGgpO1xuICAgIHJlc3VsdC5zZWFyY2ggPSByZWxhdGl2ZS5zZWFyY2g7XG4gICAgcmVzdWx0LnF1ZXJ5ID0gcmVsYXRpdmUucXVlcnk7XG4gIH0gZWxzZSBpZiAoIWlzTnVsbE9yVW5kZWZpbmVkKHJlbGF0aXZlLnNlYXJjaCkpIHtcbiAgICAvLyBqdXN0IHB1bGwgb3V0IHRoZSBzZWFyY2guXG4gICAgLy8gbGlrZSBocmVmPSc/Zm9vJy5cbiAgICAvLyBQdXQgdGhpcyBhZnRlciB0aGUgb3RoZXIgdHdvIGNhc2VzIGJlY2F1c2UgaXQgc2ltcGxpZmllcyB0aGUgYm9vbGVhbnNcbiAgICBpZiAocHN5Y2hvdGljKSB7XG4gICAgICByZXN1bHQuaG9zdG5hbWUgPSByZXN1bHQuaG9zdCA9IHNyY1BhdGguc2hpZnQoKTtcbiAgICAgIC8vb2NjYXRpb25hbHkgdGhlIGF1dGggY2FuIGdldCBzdHVjayBvbmx5IGluIGhvc3RcbiAgICAgIC8vdGhpcyBlc3BlY2lhbHkgaGFwcGVucyBpbiBjYXNlcyBsaWtlXG4gICAgICAvL3VybC5yZXNvbHZlT2JqZWN0KCdtYWlsdG86bG9jYWwxQGRvbWFpbjEnLCAnbG9jYWwyQGRvbWFpbjInKVxuICAgICAgdmFyIGF1dGhJbkhvc3QgPSByZXN1bHQuaG9zdCAmJiByZXN1bHQuaG9zdC5pbmRleE9mKCdAJykgPiAwID9cbiAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0Lmhvc3Quc3BsaXQoJ0AnKSA6IGZhbHNlO1xuICAgICAgaWYgKGF1dGhJbkhvc3QpIHtcbiAgICAgICAgcmVzdWx0LmF1dGggPSBhdXRoSW5Ib3N0LnNoaWZ0KCk7XG4gICAgICAgIHJlc3VsdC5ob3N0ID0gcmVzdWx0Lmhvc3RuYW1lID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXN1bHQuc2VhcmNoID0gcmVsYXRpdmUuc2VhcmNoO1xuICAgIHJlc3VsdC5xdWVyeSA9IHJlbGF0aXZlLnF1ZXJ5O1xuICAgIC8vdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgICBpZiAoIWlzTnVsbChyZXN1bHQucGF0aG5hbWUpIHx8ICFpc051bGwocmVzdWx0LnNlYXJjaCkpIHtcbiAgICAgIHJlc3VsdC5wYXRoID0gKHJlc3VsdC5wYXRobmFtZSA/IHJlc3VsdC5wYXRobmFtZSA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAgIChyZXN1bHQuc2VhcmNoID8gcmVzdWx0LnNlYXJjaCA6ICcnKTtcbiAgICB9XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGlmICghc3JjUGF0aC5sZW5ndGgpIHtcbiAgICAvLyBubyBwYXRoIGF0IGFsbC4gIGVhc3kuXG4gICAgLy8gd2UndmUgYWxyZWFkeSBoYW5kbGVkIHRoZSBvdGhlciBzdHVmZiBhYm92ZS5cbiAgICByZXN1bHQucGF0aG5hbWUgPSBudWxsO1xuICAgIC8vdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgICBpZiAocmVzdWx0LnNlYXJjaCkge1xuICAgICAgcmVzdWx0LnBhdGggPSAnLycgKyByZXN1bHQuc2VhcmNoO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQucGF0aCA9IG51bGw7XG4gICAgfVxuICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBpZiBhIHVybCBFTkRzIGluIC4gb3IgLi4sIHRoZW4gaXQgbXVzdCBnZXQgYSB0cmFpbGluZyBzbGFzaC5cbiAgLy8gaG93ZXZlciwgaWYgaXQgZW5kcyBpbiBhbnl0aGluZyBlbHNlIG5vbi1zbGFzaHksXG4gIC8vIHRoZW4gaXQgbXVzdCBOT1QgZ2V0IGEgdHJhaWxpbmcgc2xhc2guXG4gIHZhciBsYXN0ID0gc3JjUGF0aC5zbGljZSgtMSlbMF07XG4gIHZhciBoYXNUcmFpbGluZ1NsYXNoID0gKFxuICAgICAgKHJlc3VsdC5ob3N0IHx8IHJlbGF0aXZlLmhvc3QpICYmIChsYXN0ID09PSAnLicgfHwgbGFzdCA9PT0gJy4uJykgfHxcbiAgICAgIGxhc3QgPT09ICcnKTtcblxuICAvLyBzdHJpcCBzaW5nbGUgZG90cywgcmVzb2x2ZSBkb3VibGUgZG90cyB0byBwYXJlbnQgZGlyXG4gIC8vIGlmIHRoZSBwYXRoIHRyaWVzIHRvIGdvIGFib3ZlIHRoZSByb290LCBgdXBgIGVuZHMgdXAgPiAwXG4gIHZhciB1cCA9IDA7XG4gIGZvciAodmFyIGkgPSBzcmNQYXRoLmxlbmd0aDsgaSA+PSAwOyBpLS0pIHtcbiAgICBsYXN0ID0gc3JjUGF0aFtpXTtcbiAgICBpZiAobGFzdCA9PSAnLicpIHtcbiAgICAgIHNyY1BhdGguc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSBpZiAobGFzdCA9PT0gJy4uJykge1xuICAgICAgc3JjUGF0aC5zcGxpY2UoaSwgMSk7XG4gICAgICB1cCsrO1xuICAgIH0gZWxzZSBpZiAodXApIHtcbiAgICAgIHNyY1BhdGguc3BsaWNlKGksIDEpO1xuICAgICAgdXAtLTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgcGF0aCBpcyBhbGxvd2VkIHRvIGdvIGFib3ZlIHRoZSByb290LCByZXN0b3JlIGxlYWRpbmcgLi5zXG4gIGlmICghbXVzdEVuZEFicyAmJiAhcmVtb3ZlQWxsRG90cykge1xuICAgIGZvciAoOyB1cC0tOyB1cCkge1xuICAgICAgc3JjUGF0aC51bnNoaWZ0KCcuLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChtdXN0RW5kQWJzICYmIHNyY1BhdGhbMF0gIT09ICcnICYmXG4gICAgICAoIXNyY1BhdGhbMF0gfHwgc3JjUGF0aFswXS5jaGFyQXQoMCkgIT09ICcvJykpIHtcbiAgICBzcmNQYXRoLnVuc2hpZnQoJycpO1xuICB9XG5cbiAgaWYgKGhhc1RyYWlsaW5nU2xhc2ggJiYgKHNyY1BhdGguam9pbignLycpLnN1YnN0cigtMSkgIT09ICcvJykpIHtcbiAgICBzcmNQYXRoLnB1c2goJycpO1xuICB9XG5cbiAgdmFyIGlzQWJzb2x1dGUgPSBzcmNQYXRoWzBdID09PSAnJyB8fFxuICAgICAgKHNyY1BhdGhbMF0gJiYgc3JjUGF0aFswXS5jaGFyQXQoMCkgPT09ICcvJyk7XG5cbiAgLy8gcHV0IHRoZSBob3N0IGJhY2tcbiAgaWYgKHBzeWNob3RpYykge1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gaXNBYnNvbHV0ZSA/ICcnIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyY1BhdGgubGVuZ3RoID8gc3JjUGF0aC5zaGlmdCgpIDogJyc7XG4gICAgLy9vY2NhdGlvbmFseSB0aGUgYXV0aCBjYW4gZ2V0IHN0dWNrIG9ubHkgaW4gaG9zdFxuICAgIC8vdGhpcyBlc3BlY2lhbHkgaGFwcGVucyBpbiBjYXNlcyBsaWtlXG4gICAgLy91cmwucmVzb2x2ZU9iamVjdCgnbWFpbHRvOmxvY2FsMUBkb21haW4xJywgJ2xvY2FsMkBkb21haW4yJylcbiAgICB2YXIgYXV0aEluSG9zdCA9IHJlc3VsdC5ob3N0ICYmIHJlc3VsdC5ob3N0LmluZGV4T2YoJ0AnKSA+IDAgP1xuICAgICAgICAgICAgICAgICAgICAgcmVzdWx0Lmhvc3Quc3BsaXQoJ0AnKSA6IGZhbHNlO1xuICAgIGlmIChhdXRoSW5Ib3N0KSB7XG4gICAgICByZXN1bHQuYXV0aCA9IGF1dGhJbkhvc3Quc2hpZnQoKTtcbiAgICAgIHJlc3VsdC5ob3N0ID0gcmVzdWx0Lmhvc3RuYW1lID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgIH1cbiAgfVxuXG4gIG11c3RFbmRBYnMgPSBtdXN0RW5kQWJzIHx8IChyZXN1bHQuaG9zdCAmJiBzcmNQYXRoLmxlbmd0aCk7XG5cbiAgaWYgKG11c3RFbmRBYnMgJiYgIWlzQWJzb2x1dGUpIHtcbiAgICBzcmNQYXRoLnVuc2hpZnQoJycpO1xuICB9XG5cbiAgaWYgKCFzcmNQYXRoLmxlbmd0aCkge1xuICAgIHJlc3VsdC5wYXRobmFtZSA9IG51bGw7XG4gICAgcmVzdWx0LnBhdGggPSBudWxsO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdC5wYXRobmFtZSA9IHNyY1BhdGguam9pbignLycpO1xuICB9XG5cbiAgLy90byBzdXBwb3J0IHJlcXVlc3QuaHR0cFxuICBpZiAoIWlzTnVsbChyZXN1bHQucGF0aG5hbWUpIHx8ICFpc051bGwocmVzdWx0LnNlYXJjaCkpIHtcbiAgICByZXN1bHQucGF0aCA9IChyZXN1bHQucGF0aG5hbWUgPyByZXN1bHQucGF0aG5hbWUgOiAnJykgK1xuICAgICAgICAgICAgICAgICAgKHJlc3VsdC5zZWFyY2ggPyByZXN1bHQuc2VhcmNoIDogJycpO1xuICB9XG4gIHJlc3VsdC5hdXRoID0gcmVsYXRpdmUuYXV0aCB8fCByZXN1bHQuYXV0aDtcbiAgcmVzdWx0LnNsYXNoZXMgPSByZXN1bHQuc2xhc2hlcyB8fCByZWxhdGl2ZS5zbGFzaGVzO1xuICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cblVybC5wcm90b3R5cGUucGFyc2VIb3N0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBob3N0ID0gdGhpcy5ob3N0O1xuICB2YXIgcG9ydCA9IHBvcnRQYXR0ZXJuLmV4ZWMoaG9zdCk7XG4gIGlmIChwb3J0KSB7XG4gICAgcG9ydCA9IHBvcnRbMF07XG4gICAgaWYgKHBvcnQgIT09ICc6Jykge1xuICAgICAgdGhpcy5wb3J0ID0gcG9ydC5zdWJzdHIoMSk7XG4gICAgfVxuICAgIGhvc3QgPSBob3N0LnN1YnN0cigwLCBob3N0Lmxlbmd0aCAtIHBvcnQubGVuZ3RoKTtcbiAgfVxuICBpZiAoaG9zdCkgdGhpcy5ob3N0bmFtZSA9IGhvc3Q7XG59O1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09IFwic3RyaW5nXCI7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuICBhcmcgPT0gbnVsbDtcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNCdWZmZXIoYXJnKSB7XG4gIHJldHVybiBhcmcgJiYgdHlwZW9mIGFyZyA9PT0gJ29iamVjdCdcbiAgICAmJiB0eXBlb2YgYXJnLmNvcHkgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLmZpbGwgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLnJlYWRVSW50OCA9PT0gJ2Z1bmN0aW9uJztcbn0iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIGZvcm1hdFJlZ0V4cCA9IC8lW3NkaiVdL2c7XG5leHBvcnRzLmZvcm1hdCA9IGZ1bmN0aW9uKGYpIHtcbiAgaWYgKCFpc1N0cmluZyhmKSkge1xuICAgIHZhciBvYmplY3RzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIG9iamVjdHMucHVzaChpbnNwZWN0KGFyZ3VtZW50c1tpXSkpO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0cy5qb2luKCcgJyk7XG4gIH1cblxuICB2YXIgaSA9IDE7XG4gIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICB2YXIgbGVuID0gYXJncy5sZW5ndGg7XG4gIHZhciBzdHIgPSBTdHJpbmcoZikucmVwbGFjZShmb3JtYXRSZWdFeHAsIGZ1bmN0aW9uKHgpIHtcbiAgICBpZiAoeCA9PT0gJyUlJykgcmV0dXJuICclJztcbiAgICBpZiAoaSA+PSBsZW4pIHJldHVybiB4O1xuICAgIHN3aXRjaCAoeCkge1xuICAgICAgY2FzZSAnJXMnOiByZXR1cm4gU3RyaW5nKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclZCc6IHJldHVybiBOdW1iZXIoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVqJzpcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoYXJnc1tpKytdKTtcbiAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgIHJldHVybiAnW0NpcmN1bGFyXSc7XG4gICAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB4O1xuICAgIH1cbiAgfSk7XG4gIGZvciAodmFyIHggPSBhcmdzW2ldOyBpIDwgbGVuOyB4ID0gYXJnc1srK2ldKSB7XG4gICAgaWYgKGlzTnVsbCh4KSB8fCAhaXNPYmplY3QoeCkpIHtcbiAgICAgIHN0ciArPSAnICcgKyB4O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgKz0gJyAnICsgaW5zcGVjdCh4KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn07XG5cblxuLy8gTWFyayB0aGF0IGEgbWV0aG9kIHNob3VsZCBub3QgYmUgdXNlZC5cbi8vIFJldHVybnMgYSBtb2RpZmllZCBmdW5jdGlvbiB3aGljaCB3YXJucyBvbmNlIGJ5IGRlZmF1bHQuXG4vLyBJZiAtLW5vLWRlcHJlY2F0aW9uIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuZXhwb3J0cy5kZXByZWNhdGUgPSBmdW5jdGlvbihmbiwgbXNnKSB7XG4gIC8vIEFsbG93IGZvciBkZXByZWNhdGluZyB0aGluZ3MgaW4gdGhlIHByb2Nlc3Mgb2Ygc3RhcnRpbmcgdXAuXG4gIGlmIChpc1VuZGVmaW5lZChnbG9iYWwucHJvY2VzcykpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZXhwb3J0cy5kZXByZWNhdGUoZm4sIG1zZykuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG5cbiAgaWYgKHByb2Nlc3Mubm9EZXByZWNhdGlvbiA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBmbjtcbiAgfVxuXG4gIHZhciB3YXJuZWQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gZGVwcmVjYXRlZCgpIHtcbiAgICBpZiAoIXdhcm5lZCkge1xuICAgICAgaWYgKHByb2Nlc3MudGhyb3dEZXByZWNhdGlvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy50cmFjZURlcHJlY2F0aW9uKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobXNnKTtcbiAgICAgIH1cbiAgICAgIHdhcm5lZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgcmV0dXJuIGRlcHJlY2F0ZWQ7XG59O1xuXG5cbnZhciBkZWJ1Z3MgPSB7fTtcbnZhciBkZWJ1Z0Vudmlyb247XG5leHBvcnRzLmRlYnVnbG9nID0gZnVuY3Rpb24oc2V0KSB7XG4gIGlmIChpc1VuZGVmaW5lZChkZWJ1Z0Vudmlyb24pKVxuICAgIGRlYnVnRW52aXJvbiA9IHByb2Nlc3MuZW52Lk5PREVfREVCVUcgfHwgJyc7XG4gIHNldCA9IHNldC50b1VwcGVyQ2FzZSgpO1xuICBpZiAoIWRlYnVnc1tzZXRdKSB7XG4gICAgaWYgKG5ldyBSZWdFeHAoJ1xcXFxiJyArIHNldCArICdcXFxcYicsICdpJykudGVzdChkZWJ1Z0Vudmlyb24pKSB7XG4gICAgICB2YXIgcGlkID0gcHJvY2Vzcy5waWQ7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbXNnID0gZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKTtcbiAgICAgICAgY29uc29sZS5lcnJvcignJXMgJWQ6ICVzJywgc2V0LCBwaWQsIG1zZyk7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge307XG4gICAgfVxuICB9XG4gIHJldHVybiBkZWJ1Z3Nbc2V0XTtcbn07XG5cblxuLyoqXG4gKiBFY2hvcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJ5cyB0byBwcmludCB0aGUgdmFsdWUgb3V0XG4gKiBpbiB0aGUgYmVzdCB3YXkgcG9zc2libGUgZ2l2ZW4gdGhlIGRpZmZlcmVudCB0eXBlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gcHJpbnQgb3V0LlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHMgT3B0aW9uYWwgb3B0aW9ucyBvYmplY3QgdGhhdCBhbHRlcnMgdGhlIG91dHB1dC5cbiAqL1xuLyogbGVnYWN5OiBvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMqL1xuZnVuY3Rpb24gaW5zcGVjdChvYmosIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCBvcHRpb25zXG4gIHZhciBjdHggPSB7XG4gICAgc2VlbjogW10sXG4gICAgc3R5bGl6ZTogc3R5bGl6ZU5vQ29sb3JcbiAgfTtcbiAgLy8gbGVnYWN5Li4uXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIGN0eC5kZXB0aCA9IGFyZ3VtZW50c1syXTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNCkgY3R4LmNvbG9ycyA9IGFyZ3VtZW50c1szXTtcbiAgaWYgKGlzQm9vbGVhbihvcHRzKSkge1xuICAgIC8vIGxlZ2FjeS4uLlxuICAgIGN0eC5zaG93SGlkZGVuID0gb3B0cztcbiAgfSBlbHNlIGlmIChvcHRzKSB7XG4gICAgLy8gZ290IGFuIFwib3B0aW9uc1wiIG9iamVjdFxuICAgIGV4cG9ydHMuX2V4dGVuZChjdHgsIG9wdHMpO1xuICB9XG4gIC8vIHNldCBkZWZhdWx0IG9wdGlvbnNcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5zaG93SGlkZGVuKSkgY3R4LnNob3dIaWRkZW4gPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5kZXB0aCkpIGN0eC5kZXB0aCA9IDI7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY29sb3JzKSkgY3R4LmNvbG9ycyA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmN1c3RvbUluc3BlY3QpKSBjdHguY3VzdG9tSW5zcGVjdCA9IHRydWU7XG4gIGlmIChjdHguY29sb3JzKSBjdHguc3R5bGl6ZSA9IHN0eWxpemVXaXRoQ29sb3I7XG4gIHJldHVybiBmb3JtYXRWYWx1ZShjdHgsIG9iaiwgY3R4LmRlcHRoKTtcbn1cbmV4cG9ydHMuaW5zcGVjdCA9IGluc3BlY3Q7XG5cblxuLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlI2dyYXBoaWNzXG5pbnNwZWN0LmNvbG9ycyA9IHtcbiAgJ2JvbGQnIDogWzEsIDIyXSxcbiAgJ2l0YWxpYycgOiBbMywgMjNdLFxuICAndW5kZXJsaW5lJyA6IFs0LCAyNF0sXG4gICdpbnZlcnNlJyA6IFs3LCAyN10sXG4gICd3aGl0ZScgOiBbMzcsIDM5XSxcbiAgJ2dyZXknIDogWzkwLCAzOV0sXG4gICdibGFjaycgOiBbMzAsIDM5XSxcbiAgJ2JsdWUnIDogWzM0LCAzOV0sXG4gICdjeWFuJyA6IFszNiwgMzldLFxuICAnZ3JlZW4nIDogWzMyLCAzOV0sXG4gICdtYWdlbnRhJyA6IFszNSwgMzldLFxuICAncmVkJyA6IFszMSwgMzldLFxuICAneWVsbG93JyA6IFszMywgMzldXG59O1xuXG4vLyBEb24ndCB1c2UgJ2JsdWUnIG5vdCB2aXNpYmxlIG9uIGNtZC5leGVcbmluc3BlY3Quc3R5bGVzID0ge1xuICAnc3BlY2lhbCc6ICdjeWFuJyxcbiAgJ251bWJlcic6ICd5ZWxsb3cnLFxuICAnYm9vbGVhbic6ICd5ZWxsb3cnLFxuICAndW5kZWZpbmVkJzogJ2dyZXknLFxuICAnbnVsbCc6ICdib2xkJyxcbiAgJ3N0cmluZyc6ICdncmVlbicsXG4gICdkYXRlJzogJ21hZ2VudGEnLFxuICAvLyBcIm5hbWVcIjogaW50ZW50aW9uYWxseSBub3Qgc3R5bGluZ1xuICAncmVnZXhwJzogJ3JlZCdcbn07XG5cblxuZnVuY3Rpb24gc3R5bGl6ZVdpdGhDb2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICB2YXIgc3R5bGUgPSBpbnNwZWN0LnN0eWxlc1tzdHlsZVR5cGVdO1xuXG4gIGlmIChzdHlsZSkge1xuICAgIHJldHVybiAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzBdICsgJ20nICsgc3RyICtcbiAgICAgICAgICAgJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVsxXSArICdtJztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG59XG5cblxuZnVuY3Rpb24gc3R5bGl6ZU5vQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgcmV0dXJuIHN0cjtcbn1cblxuXG5mdW5jdGlvbiBhcnJheVRvSGFzaChhcnJheSkge1xuICB2YXIgaGFzaCA9IHt9O1xuXG4gIGFycmF5LmZvckVhY2goZnVuY3Rpb24odmFsLCBpZHgpIHtcbiAgICBoYXNoW3ZhbF0gPSB0cnVlO1xuICB9KTtcblxuICByZXR1cm4gaGFzaDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRWYWx1ZShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMpIHtcbiAgLy8gUHJvdmlkZSBhIGhvb2sgZm9yIHVzZXItc3BlY2lmaWVkIGluc3BlY3QgZnVuY3Rpb25zLlxuICAvLyBDaGVjayB0aGF0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFuIGluc3BlY3QgZnVuY3Rpb24gb24gaXRcbiAgaWYgKGN0eC5jdXN0b21JbnNwZWN0ICYmXG4gICAgICB2YWx1ZSAmJlxuICAgICAgaXNGdW5jdGlvbih2YWx1ZS5pbnNwZWN0KSAmJlxuICAgICAgLy8gRmlsdGVyIG91dCB0aGUgdXRpbCBtb2R1bGUsIGl0J3MgaW5zcGVjdCBmdW5jdGlvbiBpcyBzcGVjaWFsXG4gICAgICB2YWx1ZS5pbnNwZWN0ICE9PSBleHBvcnRzLmluc3BlY3QgJiZcbiAgICAgIC8vIEFsc28gZmlsdGVyIG91dCBhbnkgcHJvdG90eXBlIG9iamVjdHMgdXNpbmcgdGhlIGNpcmN1bGFyIGNoZWNrLlxuICAgICAgISh2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IHZhbHVlKSkge1xuICAgIHZhciByZXQgPSB2YWx1ZS5pbnNwZWN0KHJlY3Vyc2VUaW1lcywgY3R4KTtcbiAgICBpZiAoIWlzU3RyaW5nKHJldCkpIHtcbiAgICAgIHJldCA9IGZvcm1hdFZhbHVlKGN0eCwgcmV0LCByZWN1cnNlVGltZXMpO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLy8gUHJpbWl0aXZlIHR5cGVzIGNhbm5vdCBoYXZlIHByb3BlcnRpZXNcbiAgdmFyIHByaW1pdGl2ZSA9IGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKTtcbiAgaWYgKHByaW1pdGl2ZSkge1xuICAgIHJldHVybiBwcmltaXRpdmU7XG4gIH1cblxuICAvLyBMb29rIHVwIHRoZSBrZXlzIG9mIHRoZSBvYmplY3QuXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXModmFsdWUpO1xuICB2YXIgdmlzaWJsZUtleXMgPSBhcnJheVRvSGFzaChrZXlzKTtcblxuICBpZiAoY3R4LnNob3dIaWRkZW4pIHtcbiAgICBrZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModmFsdWUpO1xuICB9XG5cbiAgLy8gSUUgZG9lc24ndCBtYWtlIGVycm9yIGZpZWxkcyBub24tZW51bWVyYWJsZVxuICAvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvZHd3NTJzYnQodj12cy45NCkuYXNweFxuICBpZiAoaXNFcnJvcih2YWx1ZSlcbiAgICAgICYmIChrZXlzLmluZGV4T2YoJ21lc3NhZ2UnKSA+PSAwIHx8IGtleXMuaW5kZXhPZignZGVzY3JpcHRpb24nKSA+PSAwKSkge1xuICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICAvLyBTb21lIHR5cGUgb2Ygb2JqZWN0IHdpdGhvdXQgcHJvcGVydGllcyBjYW4gYmUgc2hvcnRjdXR0ZWQuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgICAgdmFyIG5hbWUgPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW0Z1bmN0aW9uJyArIG5hbWUgKyAnXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfVxuICAgIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdkYXRlJyk7XG4gICAgfVxuICAgIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB2YXIgYmFzZSA9ICcnLCBhcnJheSA9IGZhbHNlLCBicmFjZXMgPSBbJ3snLCAnfSddO1xuXG4gIC8vIE1ha2UgQXJyYXkgc2F5IHRoYXQgdGhleSBhcmUgQXJyYXlcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgYXJyYXkgPSB0cnVlO1xuICAgIGJyYWNlcyA9IFsnWycsICddJ107XG4gIH1cblxuICAvLyBNYWtlIGZ1bmN0aW9ucyBzYXkgdGhhdCB0aGV5IGFyZSBmdW5jdGlvbnNcbiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgdmFyIG4gPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICBiYXNlID0gJyBbRnVuY3Rpb24nICsgbiArICddJztcbiAgfVxuXG4gIC8vIE1ha2UgUmVnRXhwcyBzYXkgdGhhdCB0aGV5IGFyZSBSZWdFeHBzXG4gIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZGF0ZXMgd2l0aCBwcm9wZXJ0aWVzIGZpcnN0IHNheSB0aGUgZGF0ZVxuICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBEYXRlLnByb3RvdHlwZS50b1VUQ1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZXJyb3Igd2l0aCBtZXNzYWdlIGZpcnN0IHNheSB0aGUgZXJyb3JcbiAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCAmJiAoIWFycmF5IHx8IHZhbHVlLmxlbmd0aCA9PSAwKSkge1xuICAgIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgYnJhY2VzWzFdO1xuICB9XG5cbiAgaWYgKHJlY3Vyc2VUaW1lcyA8IDApIHtcbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tPYmplY3RdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cblxuICBjdHguc2Vlbi5wdXNoKHZhbHVlKTtcblxuICB2YXIgb3V0cHV0O1xuICBpZiAoYXJyYXkpIHtcbiAgICBvdXRwdXQgPSBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKTtcbiAgfSBlbHNlIHtcbiAgICBvdXRwdXQgPSBrZXlzLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KTtcbiAgICB9KTtcbiAgfVxuXG4gIGN0eC5zZWVuLnBvcCgpO1xuXG4gIHJldHVybiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcbiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBzaW1wbGUgPSAnXFwnJyArIEpTT04uc3RyaW5naWZ5KHZhbHVlKS5yZXBsYWNlKC9eXCJ8XCIkL2csICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKSArICdcXCcnO1xuICAgIHJldHVybiBjdHguc3R5bGl6ZShzaW1wbGUsICdzdHJpbmcnKTtcbiAgfVxuICBpZiAoaXNOdW1iZXIodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnbnVtYmVyJyk7XG4gIGlmIChpc0Jvb2xlYW4odmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnYm9vbGVhbicpO1xuICAvLyBGb3Igc29tZSByZWFzb24gdHlwZW9mIG51bGwgaXMgXCJvYmplY3RcIiwgc28gc3BlY2lhbCBjYXNlIGhlcmUuXG4gIGlmIChpc051bGwodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnbnVsbCcsICdudWxsJyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0RXJyb3IodmFsdWUpIHtcbiAgcmV0dXJuICdbJyArIEVycm9yLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSArICddJztcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKSB7XG4gIHZhciBvdXRwdXQgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB2YWx1ZS5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkodmFsdWUsIFN0cmluZyhpKSkpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAgU3RyaW5nKGkpLCB0cnVlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICB9XG4gIH1cbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICgha2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBrZXksIHRydWUpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb3V0cHV0O1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpIHtcbiAgdmFyIG5hbWUsIHN0ciwgZGVzYztcbiAgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodmFsdWUsIGtleSkgfHwgeyB2YWx1ZTogdmFsdWVba2V5XSB9O1xuICBpZiAoZGVzYy5nZXQpIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyL1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmICghaGFzT3duUHJvcGVydHkodmlzaWJsZUtleXMsIGtleSkpIHtcbiAgICBuYW1lID0gJ1snICsga2V5ICsgJ10nO1xuICB9XG4gIGlmICghc3RyKSB7XG4gICAgaWYgKGN0eC5zZWVuLmluZGV4T2YoZGVzYy52YWx1ZSkgPCAwKSB7XG4gICAgICBpZiAoaXNOdWxsKHJlY3Vyc2VUaW1lcykpIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgcmVjdXJzZVRpbWVzIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgaWYgKGFycmF5KSB7XG4gICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpLnN1YnN0cigyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdHIgPSAnXFxuJyArIHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICBpZiAoYXJyYXkgJiYga2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgbmFtZSA9IEpTT04uc3RyaW5naWZ5KCcnICsga2V5KTtcbiAgICBpZiAobmFtZS5tYXRjaCgvXlwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXCIkLykpIHtcbiAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigxLCBuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICduYW1lJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oXlwifFwiJCkvZywgXCInXCIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICdzdHJpbmcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZSArICc6ICcgKyBzdHI7XG59XG5cblxuZnVuY3Rpb24gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpIHtcbiAgdmFyIG51bUxpbmVzRXN0ID0gMDtcbiAgdmFyIGxlbmd0aCA9IG91dHB1dC5yZWR1Y2UoZnVuY3Rpb24ocHJldiwgY3VyKSB7XG4gICAgbnVtTGluZXNFc3QrKztcbiAgICBpZiAoY3VyLmluZGV4T2YoJ1xcbicpID49IDApIG51bUxpbmVzRXN0Kys7XG4gICAgcmV0dXJuIHByZXYgKyBjdXIucmVwbGFjZSgvXFx1MDAxYlxcW1xcZFxcZD9tL2csICcnKS5sZW5ndGggKyAxO1xuICB9LCAwKTtcblxuICBpZiAobGVuZ3RoID4gNjApIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICtcbiAgICAgICAgICAgKGJhc2UgPT09ICcnID8gJycgOiBiYXNlICsgJ1xcbiAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIG91dHB1dC5qb2luKCcsXFxuICAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIGJyYWNlc1sxXTtcbiAgfVxuXG4gIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgJyAnICsgb3V0cHV0LmpvaW4oJywgJykgKyAnICcgKyBicmFjZXNbMV07XG59XG5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cbmZ1bmN0aW9uIGlzQXJyYXkoYXIpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXIpO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gaXNPYmplY3QocmUpICYmIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5leHBvcnRzLmlzUmVnRXhwID0gaXNSZWdFeHA7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuZXhwb3J0cy5pc09iamVjdCA9IGlzT2JqZWN0O1xuXG5mdW5jdGlvbiBpc0RhdGUoZCkge1xuICByZXR1cm4gaXNPYmplY3QoZCkgJiYgb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cbmV4cG9ydHMuaXNEYXRlID0gaXNEYXRlO1xuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGUpICYmXG4gICAgICAob2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXScgfHwgZSBpbnN0YW5jZW9mIEVycm9yKTtcbn1cbmV4cG9ydHMuaXNFcnJvciA9IGlzRXJyb3I7XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuZXhwb3J0cy5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjtcblxuZnVuY3Rpb24gaXNQcmltaXRpdmUoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGwgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3ltYm9sJyB8fCAgLy8gRVM2IHN5bWJvbFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3VuZGVmaW5lZCc7XG59XG5leHBvcnRzLmlzUHJpbWl0aXZlID0gaXNQcmltaXRpdmU7XG5cbmV4cG9ydHMuaXNCdWZmZXIgPSByZXF1aXJlKCcuL3N1cHBvcnQvaXNCdWZmZXInKTtcblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuXG5cbmZ1bmN0aW9uIHBhZChuKSB7XG4gIHJldHVybiBuIDwgMTAgPyAnMCcgKyBuLnRvU3RyaW5nKDEwKSA6IG4udG9TdHJpbmcoMTApO1xufVxuXG5cbnZhciBtb250aHMgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJyxcbiAgICAgICAgICAgICAgJ09jdCcsICdOb3YnLCAnRGVjJ107XG5cbi8vIDI2IEZlYiAxNjoxOTozNFxuZnVuY3Rpb24gdGltZXN0YW1wKCkge1xuICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gIHZhciB0aW1lID0gW3BhZChkLmdldEhvdXJzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRNaW51dGVzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRTZWNvbmRzKCkpXS5qb2luKCc6Jyk7XG4gIHJldHVybiBbZC5nZXREYXRlKCksIG1vbnRoc1tkLmdldE1vbnRoKCldLCB0aW1lXS5qb2luKCcgJyk7XG59XG5cblxuLy8gbG9nIGlzIGp1c3QgYSB0aGluIHdyYXBwZXIgdG8gY29uc29sZS5sb2cgdGhhdCBwcmVwZW5kcyBhIHRpbWVzdGFtcFxuZXhwb3J0cy5sb2cgPSBmdW5jdGlvbigpIHtcbiAgY29uc29sZS5sb2coJyVzIC0gJXMnLCB0aW1lc3RhbXAoKSwgZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKSk7XG59O1xuXG5cbi8qKlxuICogSW5oZXJpdCB0aGUgcHJvdG90eXBlIG1ldGhvZHMgZnJvbSBvbmUgY29uc3RydWN0b3IgaW50byBhbm90aGVyLlxuICpcbiAqIFRoZSBGdW5jdGlvbi5wcm90b3R5cGUuaW5oZXJpdHMgZnJvbSBsYW5nLmpzIHJld3JpdHRlbiBhcyBhIHN0YW5kYWxvbmVcbiAqIGZ1bmN0aW9uIChub3Qgb24gRnVuY3Rpb24ucHJvdG90eXBlKS4gTk9URTogSWYgdGhpcyBmaWxlIGlzIHRvIGJlIGxvYWRlZFxuICogZHVyaW5nIGJvb3RzdHJhcHBpbmcgdGhpcyBmdW5jdGlvbiBuZWVkcyB0byBiZSByZXdyaXR0ZW4gdXNpbmcgc29tZSBuYXRpdmVcbiAqIGZ1bmN0aW9ucyBhcyBwcm90b3R5cGUgc2V0dXAgdXNpbmcgbm9ybWFsIEphdmFTY3JpcHQgZG9lcyBub3Qgd29yayBhc1xuICogZXhwZWN0ZWQgZHVyaW5nIGJvb3RzdHJhcHBpbmcgKHNlZSBtaXJyb3IuanMgaW4gcjExNDkwMykuXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB3aGljaCBuZWVkcyB0byBpbmhlcml0IHRoZVxuICogICAgIHByb3RvdHlwZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IHN1cGVyQ3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB0byBpbmhlcml0IHByb3RvdHlwZSBmcm9tLlxuICovXG5leHBvcnRzLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxuZXhwb3J0cy5fZXh0ZW5kID0gZnVuY3Rpb24ob3JpZ2luLCBhZGQpIHtcbiAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgYWRkIGlzbid0IGFuIG9iamVjdFxuICBpZiAoIWFkZCB8fCAhaXNPYmplY3QoYWRkKSkgcmV0dXJuIG9yaWdpbjtcblxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGFkZCk7XG4gIHZhciBpID0ga2V5cy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICBvcmlnaW5ba2V5c1tpXV0gPSBhZGRba2V5c1tpXV07XG4gIH1cbiAgcmV0dXJuIG9yaWdpbjtcbn07XG5cbmZ1bmN0aW9uIGhhc093blByb3BlcnR5KG9iaiwgcHJvcCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG59XG4iLCIvKlxuICBDb3B5cmlnaHQgKEMpIDIwMTItMjAxNCBZdXN1a2UgU3V6dWtpIDx1dGF0YW5lLnRlYUBnbWFpbC5jb20+XG4gIENvcHlyaWdodCAoQykgMjAxNCBEYW4gVGFvIDxkYW5pZWwudGFvQGdtYWlsLmNvbT5cbiAgQ29weXJpZ2h0IChDKSAyMDEzIEFuZHJldyBFaXNlbmJlcmcgPGFuZHJld0BlaXNlbmJlcmcuYXM+XG5cbiAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuXG4gICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiAgICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG5cbiAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4gIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcbiAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4gIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuKGZ1bmN0aW9uICgpIHtcbiAgICAndXNlIHN0cmljdCc7XG5cbiAgICB2YXIgdHlwZWQsXG4gICAgICAgIHV0aWxpdHksXG4gICAgICAgIGlzQXJyYXksXG4gICAgICAgIGpzZG9jLFxuICAgICAgICBlc3V0aWxzLFxuICAgICAgICBoYXNPd25Qcm9wZXJ0eTtcblxuICAgIGVzdXRpbHMgPSByZXF1aXJlKCdlc3V0aWxzJyk7XG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKTtcbiAgICB0eXBlZCA9IHJlcXVpcmUoJy4vdHlwZWQnKTtcbiAgICB1dGlsaXR5ID0gcmVxdWlyZSgnLi91dGlsaXR5Jyk7XG5cbiAgICBmdW5jdGlvbiBzbGljZVNvdXJjZShzb3VyY2UsIGluZGV4LCBsYXN0KSB7XG4gICAgICAgIHJldHVybiBzb3VyY2Uuc2xpY2UoaW5kZXgsIGxhc3QpO1xuICAgIH1cblxuICAgIGhhc093blByb3BlcnR5ID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZ1bmMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gaGFzT3duUHJvcGVydHkob2JqLCBuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuYy5jYWxsKG9iaiwgbmFtZSk7XG4gICAgICAgIH07XG4gICAgfSgpKTtcblxuICAgIGZ1bmN0aW9uIHNoYWxsb3dDb3B5KG9iaikge1xuICAgICAgICB2YXIgcmV0ID0ge30sIGtleTtcbiAgICAgICAgZm9yIChrZXkgaW4gb2JqKSB7XG4gICAgICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICByZXRba2V5XSA9IG9ialtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNBU0NJSUFscGhhbnVtZXJpYyhjaCkge1xuICAgICAgICByZXR1cm4gKGNoID49IDB4NjEgIC8qICdhJyAqLyAmJiBjaCA8PSAweDdBICAvKiAneicgKi8pIHx8XG4gICAgICAgICAgICAoY2ggPj0gMHg0MSAgLyogJ0EnICovICYmIGNoIDw9IDB4NUEgIC8qICdaJyAqLykgfHxcbiAgICAgICAgICAgIChjaCA+PSAweDMwICAvKiAnMCcgKi8gJiYgY2ggPD0gMHgzOSAgLyogJzknICovKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1BhcmFtVGl0bGUodGl0bGUpIHtcbiAgICAgICAgcmV0dXJuIHRpdGxlID09PSAncGFyYW0nIHx8IHRpdGxlID09PSAnYXJndW1lbnQnIHx8IHRpdGxlID09PSAnYXJnJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1Byb3BlcnR5KHRpdGxlKSB7XG4gICAgICAgIHJldHVybiB0aXRsZSA9PT0gJ3Byb3BlcnR5JyB8fCB0aXRsZSA9PT0gJ3Byb3AnO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzTmFtZVBhcmFtZXRlclJlcXVpcmVkKHRpdGxlKSB7XG4gICAgICAgIHJldHVybiBpc1BhcmFtVGl0bGUodGl0bGUpIHx8IGlzUHJvcGVydHkodGl0bGUpIHx8XG4gICAgICAgICAgICB0aXRsZSA9PT0gJ2FsaWFzJyB8fCB0aXRsZSA9PT0gJ3RoaXMnIHx8IHRpdGxlID09PSAnbWl4ZXMnIHx8IHRpdGxlID09PSAncmVxdWlyZXMnO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzQWxsb3dlZE5hbWUodGl0bGUpIHtcbiAgICAgICAgcmV0dXJuIGlzTmFtZVBhcmFtZXRlclJlcXVpcmVkKHRpdGxlKSB8fCB0aXRsZSA9PT0gJ2NvbnN0JyB8fCB0aXRsZSA9PT0gJ2NvbnN0YW50JztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0FsbG93ZWROZXN0ZWQodGl0bGUpIHtcbiAgICAgICAgcmV0dXJuIGlzUHJvcGVydHkodGl0bGUpIHx8IGlzUGFyYW1UaXRsZSh0aXRsZSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNUeXBlUGFyYW1ldGVyUmVxdWlyZWQodGl0bGUpIHtcbiAgICAgICAgcmV0dXJuIGlzUGFyYW1UaXRsZSh0aXRsZSkgfHwgdGl0bGUgPT09ICdkZWZpbmUnIHx8IHRpdGxlID09PSAnZW51bScgfHxcbiAgICAgICAgICAgIHRpdGxlID09PSAnaW1wbGVtZW50cycgfHwgdGl0bGUgPT09ICdyZXR1cm4nIHx8XG4gICAgICAgICAgICB0aXRsZSA9PT0gJ3RoaXMnIHx8IHRpdGxlID09PSAndHlwZScgfHwgdGl0bGUgPT09ICd0eXBlZGVmJyB8fFxuICAgICAgICAgICAgdGl0bGUgPT09ICdyZXR1cm5zJyB8fCBpc1Byb3BlcnR5KHRpdGxlKTtcbiAgICB9XG5cbiAgICAvLyBDb25zaWRlciBkZXByZWNhdGlvbiBpbnN0ZWFkIHVzaW5nICdpc1R5cGVQYXJhbWV0ZXJSZXF1aXJlZCcgYW5kICdSdWxlcycgZGVjbGFyYXRpb24gdG8gcGljayB3aGVuIGEgdHlwZSBpcyBvcHRpb25hbC9yZXF1aXJlZFxuICAgIC8vIFRoaXMgd291bGQgcmVxdWlyZSBjaGFuZ2VzIHRvICdwYXJzZVR5cGUnXG4gICAgZnVuY3Rpb24gaXNBbGxvd2VkVHlwZSh0aXRsZSkge1xuICAgICAgICByZXR1cm4gaXNUeXBlUGFyYW1ldGVyUmVxdWlyZWQodGl0bGUpIHx8IHRpdGxlID09PSAndGhyb3dzJyB8fCB0aXRsZSA9PT0gJ2NvbnN0JyB8fCB0aXRsZSA9PT0gJ2NvbnN0YW50JyB8fFxuICAgICAgICAgICAgdGl0bGUgPT09ICduYW1lc3BhY2UnIHx8IHRpdGxlID09PSAnbWVtYmVyJyB8fCB0aXRsZSA9PT0gJ3ZhcicgfHwgdGl0bGUgPT09ICdtb2R1bGUnIHx8XG4gICAgICAgICAgICB0aXRsZSA9PT0gJ2NvbnN0cnVjdG9yJyB8fCB0aXRsZSA9PT0gJ2NsYXNzJyB8fCB0aXRsZSA9PT0gJ2V4dGVuZHMnIHx8IHRpdGxlID09PSAnYXVnbWVudHMnIHx8XG4gICAgICAgICAgICB0aXRsZSA9PT0gJ3B1YmxpYycgfHwgdGl0bGUgPT09ICdwcml2YXRlJyB8fCB0aXRsZSA9PT0gJ3Byb3RlY3RlZCc7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdHJpbShzdHIpIHtcbiAgICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzKy8sICcnKS5yZXBsYWNlKC9cXHMrJC8sICcnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB1bndyYXBDb21tZW50KGRvYykge1xuICAgICAgICAvLyBKU0RvYyBjb21tZW50IGlzIGZvbGxvd2luZyBmb3JtXG4gICAgICAgIC8vICAgLyoqXG4gICAgICAgIC8vICAgICogLi4uLi4uLlxuICAgICAgICAvLyAgICAqL1xuICAgICAgICAvLyByZW1vdmUgLyoqLCAqLyBhbmQgKlxuICAgICAgICB2YXIgQkVGT1JFX1NUQVIgPSAwLFxuICAgICAgICAgICAgU1RBUiA9IDEsXG4gICAgICAgICAgICBBRlRFUl9TVEFSID0gMixcbiAgICAgICAgICAgIGluZGV4LFxuICAgICAgICAgICAgbGVuLFxuICAgICAgICAgICAgbW9kZSxcbiAgICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICAgIGNoO1xuXG4gICAgICAgIGRvYyA9IGRvYy5yZXBsYWNlKC9eXFwvXFwqXFwqPy8sICcnKS5yZXBsYWNlKC9cXCpcXC8kLywgJycpO1xuICAgICAgICBpbmRleCA9IDA7XG4gICAgICAgIGxlbiA9IGRvYy5sZW5ndGg7XG4gICAgICAgIG1vZGUgPSBCRUZPUkVfU1RBUjtcbiAgICAgICAgcmVzdWx0ID0gJyc7XG5cbiAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBjaCA9IGRvYy5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgICAgIHN3aXRjaCAobW9kZSkge1xuICAgICAgICAgICAgY2FzZSBCRUZPUkVfU1RBUjpcbiAgICAgICAgICAgICAgICBpZiAoZXN1dGlscy5jb2RlLmlzTGluZVRlcm1pbmF0b3IoY2gpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09PSAweDJBICAvKiAnKicgKi8pIHtcbiAgICAgICAgICAgICAgICAgICAgbW9kZSA9IFNUQVI7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghZXN1dGlscy5jb2RlLmlzV2hpdGVTcGFjZShjaCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2gpO1xuICAgICAgICAgICAgICAgICAgICBtb2RlID0gQUZURVJfU1RBUjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgU1RBUjpcbiAgICAgICAgICAgICAgICBpZiAoIWVzdXRpbHMuY29kZS5pc1doaXRlU3BhY2UoY2gpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbW9kZSA9IGVzdXRpbHMuY29kZS5pc0xpbmVUZXJtaW5hdG9yKGNoKSA/IEJFRk9SRV9TVEFSIDogQUZURVJfU1RBUjtcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSBBRlRFUl9TVEFSOlxuICAgICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNoKTtcbiAgICAgICAgICAgICAgICBpZiAoZXN1dGlscy5jb2RlLmlzTGluZVRlcm1pbmF0b3IoY2gpKSB7XG4gICAgICAgICAgICAgICAgICAgIG1vZGUgPSBCRUZPUkVfU1RBUjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvLyBKU0RvYyBUYWcgUGFyc2VyXG5cbiAgICAoZnVuY3Rpb24gKGV4cG9ydHMpIHtcbiAgICAgICAgdmFyIFJ1bGVzLFxuICAgICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgICBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgbGVuZ3RoLFxuICAgICAgICAgICAgc291cmNlLFxuICAgICAgICAgICAgcmVjb3ZlcmFibGUsXG4gICAgICAgICAgICBzbG9wcHksXG4gICAgICAgICAgICBzdHJpY3Q7XG5cbiAgICAgICAgZnVuY3Rpb24gYWR2YW5jZSgpIHtcbiAgICAgICAgICAgIHZhciBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgICAgIGluZGV4ICs9IDE7XG4gICAgICAgICAgICBpZiAoZXN1dGlscy5jb2RlLmlzTGluZVRlcm1pbmF0b3IoY2gpICYmICEoY2ggPT09IDB4MEQgIC8qICdcXHInICovICYmIHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSA9PT0gMHgwQSAgLyogJ1xcbicgKi8pKSB7XG4gICAgICAgICAgICAgICAgbGluZU51bWJlciArPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoY2gpO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gc2NhblRpdGxlKCkge1xuICAgICAgICAgICAgdmFyIHRpdGxlID0gJyc7XG4gICAgICAgICAgICAvLyB3YXN0ZSAnQCdcbiAgICAgICAgICAgIGFkdmFuY2UoKTtcblxuICAgICAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoICYmIGlzQVNDSUlBbHBoYW51bWVyaWMoc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpKSkge1xuICAgICAgICAgICAgICAgIHRpdGxlICs9IGFkdmFuY2UoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRpdGxlO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gc2Vla0NvbnRlbnQoKSB7XG4gICAgICAgICAgICB2YXIgY2gsIHdhaXRpbmcsIGxhc3QgPSBpbmRleDtcblxuICAgICAgICAgICAgd2FpdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgd2hpbGUgKGxhc3QgPCBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGxhc3QpO1xuICAgICAgICAgICAgICAgIGlmIChlc3V0aWxzLmNvZGUuaXNMaW5lVGVybWluYXRvcihjaCkgJiYgIShjaCA9PT0gMHgwRCAgLyogJ1xccicgKi8gJiYgc291cmNlLmNoYXJDb2RlQXQobGFzdCArIDEpID09PSAweDBBICAvKiAnXFxuJyAqLykpIHtcbiAgICAgICAgICAgICAgICAgICAgbGluZU51bWJlciArPSAxO1xuICAgICAgICAgICAgICAgICAgICB3YWl0aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHdhaXRpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoID09PSAweDQwICAvKiAnQCcgKi8pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghZXN1dGlscy5jb2RlLmlzV2hpdGVTcGFjZShjaCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdhaXRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsYXN0ICs9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbGFzdDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHR5cGUgZXhwcmVzc2lvbiBtYXkgaGF2ZSBuZXN0IGJyYWNlLCBzdWNoIGFzLFxuICAgICAgICAvLyB7IHsgb2s6IHN0cmluZyB9IH1cbiAgICAgICAgLy9cbiAgICAgICAgLy8gdGhlcmVmb3JlLCBzY2FubmluZyB0eXBlIGV4cHJlc3Npb24gd2l0aCBiYWxhbmNpbmcgYnJhY2VzLlxuICAgICAgICBmdW5jdGlvbiBwYXJzZVR5cGUodGl0bGUsIGxhc3QpIHtcbiAgICAgICAgICAgIHZhciBjaCwgYnJhY2UsIHR5cGUsIGRpcmVjdCA9IGZhbHNlO1xuXG5cbiAgICAgICAgICAgIC8vIHNlYXJjaCAneydcbiAgICAgICAgICAgIHdoaWxlIChpbmRleCA8IGxhc3QpIHtcbiAgICAgICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgICAgICAgICBpZiAoZXN1dGlscy5jb2RlLmlzV2hpdGVTcGFjZShjaCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYWR2YW5jZSgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPT09IDB4N0IgIC8qICd7JyAqLykge1xuICAgICAgICAgICAgICAgICAgICBhZHZhbmNlKCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgZGlyZWN0IHBhdHRlcm5cbiAgICAgICAgICAgICAgICAgICAgZGlyZWN0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgIGlmIChkaXJlY3QpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdHlwZSBleHByZXNzaW9uIHsgaXMgZm91bmRcbiAgICAgICAgICAgIGJyYWNlID0gMTtcbiAgICAgICAgICAgIHR5cGUgPSAnJztcbiAgICAgICAgICAgIHdoaWxlIChpbmRleCA8IGxhc3QpIHtcbiAgICAgICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgICAgICAgICBpZiAoZXN1dGlscy5jb2RlLmlzTGluZVRlcm1pbmF0b3IoY2gpKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkdmFuY2UoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPT09IDB4N0QgIC8qICd9JyAqLykge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJhY2UgLT0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChicmFjZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkdmFuY2UoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PT0gMHg3QiAgLyogJ3snICovKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmFjZSArPSAxO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgKz0gYWR2YW5jZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGJyYWNlICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgLy8gYnJhY2VzIGlzIG5vdCBiYWxhbmNlZFxuICAgICAgICAgICAgICAgIHJldHVybiB1dGlsaXR5LnRocm93RXJyb3IoJ0JyYWNlcyBhcmUgbm90IGJhbGFuY2VkJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc1BhcmFtVGl0bGUodGl0bGUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVkLnBhcnNlUGFyYW1UeXBlKHR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHR5cGVkLnBhcnNlVHlwZSh0eXBlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIHNjYW5JZGVudGlmaWVyKGxhc3QpIHtcbiAgICAgICAgICAgIHZhciBpZGVudGlmaWVyO1xuICAgICAgICAgICAgaWYgKCFlc3V0aWxzLmNvZGUuaXNJZGVudGlmaWVyU3RhcnQoc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWRlbnRpZmllciA9IGFkdmFuY2UoKTtcbiAgICAgICAgICAgIHdoaWxlIChpbmRleCA8IGxhc3QgJiYgZXN1dGlscy5jb2RlLmlzSWRlbnRpZmllclBhcnQoc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpKSkge1xuICAgICAgICAgICAgICAgIGlkZW50aWZpZXIgKz0gYWR2YW5jZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGlkZW50aWZpZXI7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBza2lwV2hpdGVTcGFjZShsYXN0KSB7XG4gICAgICAgICAgICB3aGlsZSAoaW5kZXggPCBsYXN0ICYmIChlc3V0aWxzLmNvZGUuaXNXaGl0ZVNwYWNlKHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSkgfHwgZXN1dGlscy5jb2RlLmlzTGluZVRlcm1pbmF0b3Ioc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpKSkpIHtcbiAgICAgICAgICAgICAgICBhZHZhbmNlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBwYXJzZU5hbWUobGFzdCwgYWxsb3dCcmFja2V0cywgYWxsb3dOZXN0ZWRQYXJhbXMpIHtcbiAgICAgICAgICAgIHZhciBuYW1lID0gJycsIHVzZUJyYWNrZXRzO1xuXG4gICAgICAgICAgICBza2lwV2hpdGVTcGFjZShsYXN0KTtcblxuICAgICAgICAgICAgaWYgKGluZGV4ID49IGxhc3QpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGFsbG93QnJhY2tldHMgJiYgc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpID09PSAweDVCICAvKiAnWycgKi8pIHtcbiAgICAgICAgICAgICAgICB1c2VCcmFja2V0cyA9IHRydWU7XG4gICAgICAgICAgICAgICAgbmFtZSA9IGFkdmFuY2UoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFlc3V0aWxzLmNvZGUuaXNJZGVudGlmaWVyU3RhcnQoc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBuYW1lICs9IHNjYW5JZGVudGlmaWVyKGxhc3QpO1xuXG4gICAgICAgICAgICBpZiAoYWxsb3dOZXN0ZWRQYXJhbXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpID09PSAweDNBIC8qICc6JyAqLyAmJiAoXG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lID09PSAnbW9kdWxlJyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9PT0gJ2V4dGVybmFsJyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9PT0gJ2V2ZW50JykpIHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZSArPSBhZHZhbmNlKCk7XG4gICAgICAgICAgICAgICAgICAgIG5hbWUgKz0gc2NhbklkZW50aWZpZXIobGFzdCk7XG5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgd2hpbGUgKHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSA9PT0gMHgyRSAgLyogJy4nICovIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UuY2hhckNvZGVBdChpbmRleCkgPT09IDB4MjMgIC8qICcjJyAqLyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpID09PSAweDdFICAvKiAnficgKi8pIHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZSArPSBhZHZhbmNlKCk7XG4gICAgICAgICAgICAgICAgICAgIG5hbWUgKz0gc2NhbklkZW50aWZpZXIobGFzdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodXNlQnJhY2tldHMpIHtcbiAgICAgICAgICAgICAgICAvLyBkbyB3ZSBoYXZlIGEgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcz9cbiAgICAgICAgICAgICAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpID09PSAweDNEICAvKiAnPScgKi8pIHtcblxuICAgICAgICAgICAgICAgICAgICAvLyBjb25zdW1lIHRoZSAnPScnIHN5bWJvbFxuICAgICAgICAgICAgICAgICAgICBuYW1lICs9IGFkdmFuY2UoKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gc2NhbiBpbiB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaW5kZXggPCBsYXN0ICYmIHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSAhPT0gMHg1RCAgLyogJ10nICovKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lICs9IGFkdmFuY2UoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChpbmRleCA+PSBsYXN0ICB8fCBzb3VyY2UuY2hhckNvZGVBdChpbmRleCkgIT09IDB4NUQgIC8qICddJyAqLykge1xuICAgICAgICAgICAgICAgICAgICAvLyB3ZSBuZXZlciBmb3VuZCBhIGNsb3NpbmcgJ10nXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIGNvbGxlY3QgdGhlIGxhc3QgJ10nXG4gICAgICAgICAgICAgICAgbmFtZSArPSBhZHZhbmNlKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBuYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gc2tpcFRvVGFnKCkge1xuICAgICAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoICYmIHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSAhPT0gMHg0MCAgLyogJ0AnICovKSB7XG4gICAgICAgICAgICAgICAgYWR2YW5jZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGluZGV4ID49IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHV0aWxpdHkuYXNzZXJ0KHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSA9PT0gMHg0MCAgLyogJ0AnICovKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gVGFnUGFyc2VyKG9wdGlvbnMsIHRpdGxlKSB7XG4gICAgICAgICAgICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcbiAgICAgICAgICAgIHRoaXMuX3RpdGxlID0gdGl0bGU7XG4gICAgICAgICAgICB0aGlzLl90YWcgPSB7XG4gICAgICAgICAgICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBudWxsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMubGluZU51bWJlcnMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90YWcubGluZU51bWJlciA9IGxpbmVOdW1iZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9sYXN0ID0gMDtcbiAgICAgICAgICAgIC8vIHNwYWNlIHRvIHNhdmUgc3BlY2lhbCBpbmZvcm1hdGlvbiBmb3IgdGl0bGUgcGFyc2Vycy5cbiAgICAgICAgICAgIHRoaXMuX2V4dHJhID0geyB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYWRkRXJyb3IoZXJyLCAuLi4pXG4gICAgICAgIFRhZ1BhcnNlci5wcm90b3R5cGUuYWRkRXJyb3IgPSBmdW5jdGlvbiBhZGRFcnJvcihlcnJvclRleHQpIHtcbiAgICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgICAgICAgICBtc2cgPSBlcnJvclRleHQucmVwbGFjZShcbiAgICAgICAgICAgICAgICAgICAgLyUoXFxkKS9nLFxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAod2hvbGUsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1dGlsaXR5LmFzc2VydChpbmRleCA8IGFyZ3MubGVuZ3RoLCAnTWVzc2FnZSByZWZlcmVuY2UgbXVzdCBiZSBpbiByYW5nZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFyZ3NbaW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLl90YWcuZXJyb3JzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGFnLmVycm9ycyA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHN0cmljdCkge1xuICAgICAgICAgICAgICAgIHV0aWxpdHkudGhyb3dFcnJvcihtc2cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fdGFnLmVycm9ycy5wdXNoKG1zZyk7XG4gICAgICAgICAgICByZXR1cm4gcmVjb3ZlcmFibGU7XG4gICAgICAgIH07XG5cbiAgICAgICAgVGFnUGFyc2VyLnByb3RvdHlwZS5wYXJzZVR5cGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyB0eXBlIHJlcXVpcmVkIHRpdGxlc1xuICAgICAgICAgICAgaWYgKGlzVHlwZVBhcmFtZXRlclJlcXVpcmVkKHRoaXMuX3RpdGxlKSkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3RhZy50eXBlID0gcGFyc2VUeXBlKHRoaXMuX3RpdGxlLCB0aGlzLl9sYXN0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLl90YWcudHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1BhcmFtVGl0bGUodGhpcy5fdGl0bGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmFkZEVycm9yKCdNaXNzaW5nIG9yIGludmFsaWQgdGFnIHR5cGUnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGFnLnR5cGUgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuYWRkRXJyb3IoZXJyb3IubWVzc2FnZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNBbGxvd2VkVHlwZSh0aGlzLl90aXRsZSkpIHtcbiAgICAgICAgICAgICAgICAvLyBvcHRpb25hbCB0eXBlc1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3RhZy50eXBlID0gcGFyc2VUeXBlKHRoaXMuX3RpdGxlLCB0aGlzLl9sYXN0KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vRm9yIG9wdGlvbmFsIHR5cGVzLCBsZXRzIGRyb3AgdGhlIHRocm93biBlcnJvciB3aGVuIHdlIGhpdCB0aGUgZW5kIG9mIHRoZSBmaWxlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG5cbiAgICAgICAgVGFnUGFyc2VyLnByb3RvdHlwZS5fcGFyc2VOYW1lUGF0aCA9IGZ1bmN0aW9uIChvcHRpb25hbCkge1xuICAgICAgICAgICAgdmFyIG5hbWU7XG4gICAgICAgICAgICBuYW1lID0gcGFyc2VOYW1lKHRoaXMuX2xhc3QsIHNsb3BweSAmJiBpc1BhcmFtVGl0bGUodGhpcy5fdGl0bGUpLCB0cnVlKTtcbiAgICAgICAgICAgIGlmICghbmFtZSkge1xuICAgICAgICAgICAgICAgIGlmICghb3B0aW9uYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmFkZEVycm9yKCdNaXNzaW5nIG9yIGludmFsaWQgdGFnIG5hbWUnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fdGFnLm5hbWUgPSBuYW1lO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG5cbiAgICAgICAgVGFnUGFyc2VyLnByb3RvdHlwZS5wYXJzZU5hbWVQYXRoID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnNlTmFtZVBhdGgoZmFsc2UpO1xuICAgICAgICB9O1xuXG4gICAgICAgIFRhZ1BhcnNlci5wcm90b3R5cGUucGFyc2VOYW1lUGF0aE9wdGlvbmFsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnNlTmFtZVBhdGgodHJ1ZSk7XG4gICAgICAgIH07XG5cblxuICAgICAgICBUYWdQYXJzZXIucHJvdG90eXBlLnBhcnNlTmFtZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBhc3NpZ24sIG5hbWU7XG5cbiAgICAgICAgICAgIC8vIHBhcmFtLCBwcm9wZXJ0eSByZXF1aXJlcyBuYW1lXG4gICAgICAgICAgICBpZiAoaXNBbGxvd2VkTmFtZSh0aGlzLl90aXRsZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90YWcubmFtZSA9IHBhcnNlTmFtZSh0aGlzLl9sYXN0LCBzbG9wcHkgJiYgaXNQYXJhbVRpdGxlKHRoaXMuX3RpdGxlKSwgaXNBbGxvd2VkTmVzdGVkKHRoaXMuX3RpdGxlKSk7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl90YWcubmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWlzTmFtZVBhcmFtZXRlclJlcXVpcmVkKHRoaXMuX3RpdGxlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBpdCdzIHBvc3NpYmxlIHRoZSBuYW1lIGhhcyBhbHJlYWR5IGJlZW4gcGFyc2VkIGJ1dCBpbnRlcnByZXRlZCBhcyBhIHR5cGVcbiAgICAgICAgICAgICAgICAgICAgLy8gaXQncyBhbHNvIHBvc3NpYmxlIHRoaXMgaXMgYSBzbG9wcHkgZGVjbGFyYXRpb24sIGluIHdoaWNoIGNhc2UgaXQgd2lsbCBiZVxuICAgICAgICAgICAgICAgICAgICAvLyBmaXhlZCBhdCB0aGUgZW5kXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc1BhcmFtVGl0bGUodGhpcy5fdGl0bGUpICYmIHRoaXMuX3RhZy50eXBlICYmIHRoaXMuX3RhZy50eXBlLm5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2V4dHJhLm5hbWUgPSB0aGlzLl90YWcudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3RhZy5uYW1lID0gdGhpcy5fdGFnLnR5cGUubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3RhZy50eXBlID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5hZGRFcnJvcignTWlzc2luZyBvciBpbnZhbGlkIHRhZyBuYW1lJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBuYW1lID0gdGhpcy5fdGFnLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lLmNoYXJBdCgwKSA9PT0gJ1snICYmIG5hbWUuY2hhckF0KG5hbWUubGVuZ3RoIC0gMSkgPT09ICddJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXh0cmFjdCB0aGUgZGVmYXVsdCB2YWx1ZSBpZiB0aGVyZSBpcyBvbmVcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4YW1wbGU6IEBwYXJhbSB7c3RyaW5nfSBbc29tZWJvZHk9Sm9obiBEb2VdIGRlc2NyaXB0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBhc3NpZ24gPSBuYW1lLnN1YnN0cmluZygxLCBuYW1lLmxlbmd0aCAtIDEpLnNwbGl0KCc9Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXNzaWduWzFdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGFnWydkZWZhdWx0J10gPSBhc3NpZ25bMV07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl90YWcubmFtZSA9IGFzc2lnblswXTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29udmVydCB0byBhbiBvcHRpb25hbCB0eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fdGFnLnR5cGUgJiYgdGhpcy5fdGFnLnR5cGUudHlwZSAhPT0gJ09wdGlvbmFsVHlwZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl90YWcudHlwZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ09wdGlvbmFsVHlwZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IHRoaXMuX3RhZy50eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG5cbiAgICAgICAgVGFnUGFyc2VyLnByb3RvdHlwZS5wYXJzZURlc2NyaXB0aW9uID0gZnVuY3Rpb24gcGFyc2VEZXNjcmlwdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBkZXNjcmlwdGlvbiA9IHRyaW0oc2xpY2VTb3VyY2Uoc291cmNlLCBpbmRleCwgdGhpcy5fbGFzdCkpO1xuICAgICAgICAgICAgaWYgKGRlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgaWYgKCgvXi1cXHMrLykudGVzdChkZXNjcmlwdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbi5zdWJzdHJpbmcoMik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX3RhZy5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG5cbiAgICAgICAgVGFnUGFyc2VyLnByb3RvdHlwZS5wYXJzZUtpbmQgPSBmdW5jdGlvbiBwYXJzZUtpbmQoKSB7XG4gICAgICAgICAgICB2YXIga2luZCwga2luZHM7XG4gICAgICAgICAgICBraW5kcyA9IHtcbiAgICAgICAgICAgICAgICAnY2xhc3MnOiB0cnVlLFxuICAgICAgICAgICAgICAgICdjb25zdGFudCc6IHRydWUsXG4gICAgICAgICAgICAgICAgJ2V2ZW50JzogdHJ1ZSxcbiAgICAgICAgICAgICAgICAnZXh0ZXJuYWwnOiB0cnVlLFxuICAgICAgICAgICAgICAgICdmaWxlJzogdHJ1ZSxcbiAgICAgICAgICAgICAgICAnZnVuY3Rpb24nOiB0cnVlLFxuICAgICAgICAgICAgICAgICdtZW1iZXInOiB0cnVlLFxuICAgICAgICAgICAgICAgICdtaXhpbic6IHRydWUsXG4gICAgICAgICAgICAgICAgJ21vZHVsZSc6IHRydWUsXG4gICAgICAgICAgICAgICAgJ25hbWVzcGFjZSc6IHRydWUsXG4gICAgICAgICAgICAgICAgJ3R5cGVkZWYnOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAga2luZCA9IHRyaW0oc2xpY2VTb3VyY2Uoc291cmNlLCBpbmRleCwgdGhpcy5fbGFzdCkpO1xuICAgICAgICAgICAgdGhpcy5fdGFnLmtpbmQgPSBraW5kO1xuICAgICAgICAgICAgaWYgKCFoYXNPd25Qcm9wZXJ0eShraW5kcywga2luZCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuYWRkRXJyb3IoJ0ludmFsaWQga2luZCBuYW1lIFxcJyUwXFwnJywga2luZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIFRhZ1BhcnNlci5wcm90b3R5cGUucGFyc2VBY2Nlc3MgPSBmdW5jdGlvbiBwYXJzZUFjY2VzcygpIHtcbiAgICAgICAgICAgIHZhciBhY2Nlc3M7XG4gICAgICAgICAgICBhY2Nlc3MgPSB0cmltKHNsaWNlU291cmNlKHNvdXJjZSwgaW5kZXgsIHRoaXMuX2xhc3QpKTtcbiAgICAgICAgICAgIHRoaXMuX3RhZy5hY2Nlc3MgPSBhY2Nlc3M7XG4gICAgICAgICAgICBpZiAoYWNjZXNzICE9PSAncHJpdmF0ZScgJiYgYWNjZXNzICE9PSAncHJvdGVjdGVkJyAmJiBhY2Nlc3MgIT09ICdwdWJsaWMnKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmFkZEVycm9yKCdJbnZhbGlkIGFjY2VzcyBuYW1lIFxcJyUwXFwnJywgYWNjZXNzKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG5cbiAgICAgICAgVGFnUGFyc2VyLnByb3RvdHlwZS5wYXJzZVZhcmlhdGlvbiA9IGZ1bmN0aW9uIHBhcnNlVmFyaWF0aW9uKCkge1xuICAgICAgICAgICAgdmFyIHZhcmlhdGlvbiwgdGV4dDtcbiAgICAgICAgICAgIHRleHQgPSB0cmltKHNsaWNlU291cmNlKHNvdXJjZSwgaW5kZXgsIHRoaXMuX2xhc3QpKTtcbiAgICAgICAgICAgIHZhcmlhdGlvbiA9IHBhcnNlRmxvYXQodGV4dCwgMTApO1xuICAgICAgICAgICAgdGhpcy5fdGFnLnZhcmlhdGlvbiA9IHZhcmlhdGlvbjtcbiAgICAgICAgICAgIGlmIChpc05hTih2YXJpYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmFkZEVycm9yKCdJbnZhbGlkIHZhcmlhdGlvbiBcXCclMFxcJycsIHRleHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfTtcblxuICAgICAgICBUYWdQYXJzZXIucHJvdG90eXBlLmVuc3VyZUVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBzaG91bGRCZUVtcHR5ID0gdHJpbShzbGljZVNvdXJjZShzb3VyY2UsIGluZGV4LCB0aGlzLl9sYXN0KSk7XG4gICAgICAgICAgICBpZiAoc2hvdWxkQmVFbXB0eSkge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5hZGRFcnJvcignVW5rbm93biBjb250ZW50IFxcJyUwXFwnJywgc2hvdWxkQmVFbXB0eSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIFRhZ1BhcnNlci5wcm90b3R5cGUuZXBpbG9ndWUgPSBmdW5jdGlvbiBlcGlsb2d1ZSgpIHtcbiAgICAgICAgICAgIHZhciBkZXNjcmlwdGlvbjtcblxuICAgICAgICAgICAgZGVzY3JpcHRpb24gPSB0aGlzLl90YWcuZGVzY3JpcHRpb247XG4gICAgICAgICAgICAvLyB1bi1maXggcG90ZW50aWFsbHkgc2xvcHB5IGRlY2xhcmF0aW9uXG4gICAgICAgICAgICBpZiAoaXNQYXJhbVRpdGxlKHRoaXMuX3RpdGxlKSAmJiAhdGhpcy5fdGFnLnR5cGUgJiYgZGVzY3JpcHRpb24gJiYgZGVzY3JpcHRpb24uY2hhckF0KDApID09PSAnWycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90YWcudHlwZSA9IHRoaXMuX2V4dHJhLm5hbWU7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGFnLm5hbWUgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoIXNsb3BweSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuYWRkRXJyb3IoJ01pc3Npbmcgb3IgaW52YWxpZCB0YWcgbmFtZScpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIFJ1bGVzID0ge1xuICAgICAgICAgICAgLy8gaHR0cDovL3VzZWpzZG9jLm9yZy90YWdzLWFjY2Vzcy5odG1sXG4gICAgICAgICAgICAnYWNjZXNzJzogWydwYXJzZUFjY2VzcyddLFxuICAgICAgICAgICAgLy8gaHR0cDovL3VzZWpzZG9jLm9yZy90YWdzLWFsaWFzLmh0bWxcbiAgICAgICAgICAgICdhbGlhcyc6IFsncGFyc2VOYW1lUGF0aCcsICdlbnN1cmVFbmQnXSxcbiAgICAgICAgICAgIC8vIGh0dHA6Ly91c2Vqc2RvYy5vcmcvdGFncy1hdWdtZW50cy5odG1sXG4gICAgICAgICAgICAnYXVnbWVudHMnOiBbJ3BhcnNlVHlwZScsICdwYXJzZU5hbWVQYXRoT3B0aW9uYWwnLCAnZW5zdXJlRW5kJ10sXG4gICAgICAgICAgICAvLyBodHRwOi8vdXNlanNkb2Mub3JnL3RhZ3MtY29uc3RydWN0b3IuaHRtbFxuICAgICAgICAgICAgJ2NvbnN0cnVjdG9yJzogWydwYXJzZVR5cGUnLCAncGFyc2VOYW1lUGF0aE9wdGlvbmFsJywgJ2Vuc3VyZUVuZCddLFxuICAgICAgICAgICAgLy8gU3lub255bTogaHR0cDovL3VzZWpzZG9jLm9yZy90YWdzLWNvbnN0cnVjdG9yLmh0bWxcbiAgICAgICAgICAgICdjbGFzcyc6IFsncGFyc2VUeXBlJywgJ3BhcnNlTmFtZVBhdGhPcHRpb25hbCcsICdlbnN1cmVFbmQnXSxcbiAgICAgICAgICAgIC8vIFN5bm9ueW06IGh0dHA6Ly91c2Vqc2RvYy5vcmcvdGFncy1leHRlbmRzLmh0bWxcbiAgICAgICAgICAgICdleHRlbmRzJzogWydwYXJzZVR5cGUnLCAncGFyc2VOYW1lUGF0aE9wdGlvbmFsJywgJ2Vuc3VyZUVuZCddLFxuICAgICAgICAgICAgLy8gaHR0cDovL3VzZWpzZG9jLm9yZy90YWdzLWRlcHJlY2F0ZWQuaHRtbFxuICAgICAgICAgICAgJ2RlcHJlY2F0ZWQnOiBbJ3BhcnNlRGVzY3JpcHRpb24nXSxcbiAgICAgICAgICAgIC8vIGh0dHA6Ly91c2Vqc2RvYy5vcmcvdGFncy1nbG9iYWwuaHRtbFxuICAgICAgICAgICAgJ2dsb2JhbCc6IFsnZW5zdXJlRW5kJ10sXG4gICAgICAgICAgICAvLyBodHRwOi8vdXNlanNkb2Mub3JnL3RhZ3MtaW5uZXIuaHRtbFxuICAgICAgICAgICAgJ2lubmVyJzogWydlbnN1cmVFbmQnXSxcbiAgICAgICAgICAgIC8vIGh0dHA6Ly91c2Vqc2RvYy5vcmcvdGFncy1pbnN0YW5jZS5odG1sXG4gICAgICAgICAgICAnaW5zdGFuY2UnOiBbJ2Vuc3VyZUVuZCddLFxuICAgICAgICAgICAgLy8gaHR0cDovL3VzZWpzZG9jLm9yZy90YWdzLWtpbmQuaHRtbFxuICAgICAgICAgICAgJ2tpbmQnOiBbJ3BhcnNlS2luZCddLFxuICAgICAgICAgICAgLy8gaHR0cDovL3VzZWpzZG9jLm9yZy90YWdzLW1peGVzLmh0bWxcbiAgICAgICAgICAgICdtaXhlcyc6IFsncGFyc2VOYW1lUGF0aCcsICdlbnN1cmVFbmQnXSxcbiAgICAgICAgICAgIC8vIGh0dHA6Ly91c2Vqc2RvYy5vcmcvdGFncy1taXhpbi5odG1sXG4gICAgICAgICAgICAnbWl4aW4nOiBbJ3BhcnNlTmFtZVBhdGhPcHRpb25hbCcsICdlbnN1cmVFbmQnXSxcbiAgICAgICAgICAgIC8vIGh0dHA6Ly91c2Vqc2RvYy5vcmcvdGFncy1tZW1iZXIuaHRtbFxuICAgICAgICAgICAgJ21lbWJlcic6IFsncGFyc2VUeXBlJywgJ3BhcnNlTmFtZVBhdGhPcHRpb25hbCcsICdlbnN1cmVFbmQnXSxcbiAgICAgICAgICAgIC8vIGh0dHA6Ly91c2Vqc2RvYy5vcmcvdGFncy1tZXRob2QuaHRtbFxuICAgICAgICAgICAgJ21ldGhvZCc6IFsncGFyc2VOYW1lUGF0aE9wdGlvbmFsJywgJ2Vuc3VyZUVuZCddLFxuICAgICAgICAgICAgLy8gaHR0cDovL3VzZWpzZG9jLm9yZy90YWdzLW1vZHVsZS5odG1sXG4gICAgICAgICAgICAnbW9kdWxlJzogWydwYXJzZVR5cGUnLCAncGFyc2VOYW1lUGF0aE9wdGlvbmFsJywgJ2Vuc3VyZUVuZCddLFxuICAgICAgICAgICAgLy8gU3lub255bTogaHR0cDovL3VzZWpzZG9jLm9yZy90YWdzLW1ldGhvZC5odG1sXG4gICAgICAgICAgICAnZnVuYyc6IFsncGFyc2VOYW1lUGF0aE9wdGlvbmFsJywgJ2Vuc3VyZUVuZCddLFxuICAgICAgICAgICAgLy8gU3lub255bTogaHR0cDovL3VzZWpzZG9jLm9yZy90YWdzLW1ldGhvZC5odG1sXG4gICAgICAgICAgICAnZnVuY3Rpb24nOiBbJ3BhcnNlTmFtZVBhdGhPcHRpb25hbCcsICdlbnN1cmVFbmQnXSxcbiAgICAgICAgICAgIC8vIFN5bm9ueW06IGh0dHA6Ly91c2Vqc2RvYy5vcmcvdGFncy1tZW1iZXIuaHRtbFxuICAgICAgICAgICAgJ3Zhcic6IFsncGFyc2VUeXBlJywgJ3BhcnNlTmFtZVBhdGhPcHRpb25hbCcsICdlbnN1cmVFbmQnXSxcbiAgICAgICAgICAgIC8vIGh0dHA6Ly91c2Vqc2RvYy5vcmcvdGFncy1uYW1lLmh0bWxcbiAgICAgICAgICAgICduYW1lJzogWydwYXJzZU5hbWVQYXRoJywgJ2Vuc3VyZUVuZCddLFxuICAgICAgICAgICAgLy8gaHR0cDovL3VzZWpzZG9jLm9yZy90YWdzLW5hbWVzcGFjZS5odG1sXG4gICAgICAgICAgICAnbmFtZXNwYWNlJzogWydwYXJzZVR5cGUnLCAncGFyc2VOYW1lUGF0aE9wdGlvbmFsJywgJ2Vuc3VyZUVuZCddLFxuICAgICAgICAgICAgLy8gaHR0cDovL3VzZWpzZG9jLm9yZy90YWdzLXByaXZhdGUuaHRtbFxuICAgICAgICAgICAgJ3ByaXZhdGUnOiBbJ3BhcnNlVHlwZScsICdwYXJzZURlc2NyaXB0aW9uJ10sXG4gICAgICAgICAgICAvLyBodHRwOi8vdXNlanNkb2Mub3JnL3RhZ3MtcHJvdGVjdGVkLmh0bWxcbiAgICAgICAgICAgICdwcm90ZWN0ZWQnOiBbJ3BhcnNlVHlwZScsICdwYXJzZURlc2NyaXB0aW9uJ10sXG4gICAgICAgICAgICAvLyBodHRwOi8vdXNlanNkb2Mub3JnL3RhZ3MtcHVibGljLmh0bWxcbiAgICAgICAgICAgICdwdWJsaWMnOiBbJ3BhcnNlVHlwZScsICdwYXJzZURlc2NyaXB0aW9uJ10sXG4gICAgICAgICAgICAvLyBodHRwOi8vdXNlanNkb2Mub3JnL3RhZ3MtcmVhZG9ubHkuaHRtbFxuICAgICAgICAgICAgJ3JlYWRvbmx5JzogWydlbnN1cmVFbmQnXSxcbiAgICAgICAgICAgIC8vIGh0dHA6Ly91c2Vqc2RvYy5vcmcvdGFncy1yZXF1aXJlcy5odG1sXG4gICAgICAgICAgICAncmVxdWlyZXMnOiBbJ3BhcnNlTmFtZVBhdGgnLCAnZW5zdXJlRW5kJ10sXG4gICAgICAgICAgICAvLyBodHRwOi8vdXNlanNkb2Mub3JnL3RhZ3Mtc2luY2UuaHRtbFxuICAgICAgICAgICAgJ3NpbmNlJzogWydwYXJzZURlc2NyaXB0aW9uJ10sXG4gICAgICAgICAgICAvLyBodHRwOi8vdXNlanNkb2Mub3JnL3RhZ3Mtc3RhdGljLmh0bWxcbiAgICAgICAgICAgICdzdGF0aWMnOiBbJ2Vuc3VyZUVuZCddLFxuICAgICAgICAgICAgLy8gaHR0cDovL3VzZWpzZG9jLm9yZy90YWdzLXN1bW1hcnkuaHRtbFxuICAgICAgICAgICAgJ3N1bW1hcnknOiBbJ3BhcnNlRGVzY3JpcHRpb24nXSxcbiAgICAgICAgICAgIC8vIGh0dHA6Ly91c2Vqc2RvYy5vcmcvdGFncy10aGlzLmh0bWxcbiAgICAgICAgICAgICd0aGlzJzogWydwYXJzZU5hbWVQYXRoJywgJ2Vuc3VyZUVuZCddLFxuICAgICAgICAgICAgLy8gaHR0cDovL3VzZWpzZG9jLm9yZy90YWdzLXRvZG8uaHRtbFxuICAgICAgICAgICAgJ3RvZG8nOiBbJ3BhcnNlRGVzY3JpcHRpb24nXSxcbiAgICAgICAgICAgIC8vIGh0dHA6Ly91c2Vqc2RvYy5vcmcvdGFncy10eXBlZGVmLmh0bWxcbiAgICAgICAgICAgICd0eXBlZGVmJzogWydwYXJzZVR5cGUnLCAncGFyc2VOYW1lUGF0aE9wdGlvbmFsJ10sXG4gICAgICAgICAgICAvLyBodHRwOi8vdXNlanNkb2Mub3JnL3RhZ3MtdmFyaWF0aW9uLmh0bWxcbiAgICAgICAgICAgICd2YXJpYXRpb24nOiBbJ3BhcnNlVmFyaWF0aW9uJ10sXG4gICAgICAgICAgICAvLyBodHRwOi8vdXNlanNkb2Mub3JnL3RhZ3MtdmVyc2lvbi5odG1sXG4gICAgICAgICAgICAndmVyc2lvbic6IFsncGFyc2VEZXNjcmlwdGlvbiddXG4gICAgICAgIH07XG5cbiAgICAgICAgVGFnUGFyc2VyLnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uIHBhcnNlKCkge1xuICAgICAgICAgICAgdmFyIGksIGl6LCBzZXF1ZW5jZXMsIG1ldGhvZDtcblxuICAgICAgICAgICAgLy8gZW1wdHkgdGl0bGVcbiAgICAgICAgICAgIGlmICghdGhpcy5fdGl0bGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuYWRkRXJyb3IoJ01pc3Npbmcgb3IgaW52YWxpZCB0aXRsZScpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gU2VlayB0byBjb250ZW50IGxhc3QgaW5kZXguXG4gICAgICAgICAgICB0aGlzLl9sYXN0ID0gc2Vla0NvbnRlbnQodGhpcy5fdGl0bGUpO1xuXG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkoUnVsZXMsIHRoaXMuX3RpdGxlKSkge1xuICAgICAgICAgICAgICAgIHNlcXVlbmNlcyA9IFJ1bGVzW3RoaXMuX3RpdGxlXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gZGVmYXVsdCBzZXF1ZW5jZXNcbiAgICAgICAgICAgICAgICBzZXF1ZW5jZXMgPSBbJ3BhcnNlVHlwZScsICdwYXJzZU5hbWUnLCAncGFyc2VEZXNjcmlwdGlvbicsICdlcGlsb2d1ZSddO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBpeiA9IHNlcXVlbmNlcy5sZW5ndGg7IGkgPCBpejsgKytpKSB7XG4gICAgICAgICAgICAgICAgbWV0aG9kID0gc2VxdWVuY2VzW2ldO1xuICAgICAgICAgICAgICAgIGlmICghdGhpc1ttZXRob2RdKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBTZWVrIGdsb2JhbCBpbmRleCB0byBlbmQgb2YgdGhpcyB0YWcuXG4gICAgICAgICAgICBpbmRleCA9IHRoaXMuX2xhc3Q7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGFnO1xuICAgICAgICB9O1xuXG4gICAgICAgIGZ1bmN0aW9uIHBhcnNlVGFnKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHZhciB0aXRsZSwgcGFyc2VyO1xuXG4gICAgICAgICAgICAvLyBza2lwIHRvIHRhZ1xuICAgICAgICAgICAgaWYgKCFza2lwVG9UYWcoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBzY2FuIHRpdGxlXG4gICAgICAgICAgICB0aXRsZSA9IHNjYW5UaXRsZSgpO1xuXG4gICAgICAgICAgICAvLyBjb25zdHJ1Y3QgdGFnIHBhcnNlclxuICAgICAgICAgICAgcGFyc2VyID0gbmV3IFRhZ1BhcnNlcihvcHRpb25zLCB0aXRsZSk7XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VyLnBhcnNlKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvL1xuICAgICAgICAvLyBQYXJzZSBKU0RvY1xuICAgICAgICAvL1xuXG4gICAgICAgIGZ1bmN0aW9uIHNjYW5KU0RvY0Rlc2NyaXB0aW9uKHByZXNlcnZlV2hpdGVzcGFjZSkge1xuICAgICAgICAgICAgdmFyIGRlc2NyaXB0aW9uID0gJycsIGNoLCBhdEFsbG93ZWQ7XG5cbiAgICAgICAgICAgIGF0QWxsb3dlZCA9IHRydWU7XG4gICAgICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcblxuICAgICAgICAgICAgICAgIGlmIChhdEFsbG93ZWQgJiYgY2ggPT09IDB4NDAgIC8qICdAJyAqLykge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoZXN1dGlscy5jb2RlLmlzTGluZVRlcm1pbmF0b3IoY2gpKSB7XG4gICAgICAgICAgICAgICAgICAgIGF0QWxsb3dlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhdEFsbG93ZWQgJiYgIWVzdXRpbHMuY29kZS5pc1doaXRlU3BhY2UoY2gpKSB7XG4gICAgICAgICAgICAgICAgICAgIGF0QWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICs9IGFkdmFuY2UoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHByZXNlcnZlV2hpdGVzcGFjZSA/IGRlc2NyaXB0aW9uIDogdHJpbShkZXNjcmlwdGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBwYXJzZShjb21tZW50LCBvcHRpb25zKSB7XG4gICAgICAgICAgICB2YXIgdGFncyA9IFtdLCB0YWcsIGRlc2NyaXB0aW9uLCBpbnRlcmVzdGluZ1RhZ3MsIGksIGl6O1xuXG4gICAgICAgICAgICBpZiAob3B0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMudW53cmFwID09PSAnYm9vbGVhbicgJiYgb3B0aW9ucy51bndyYXApIHtcbiAgICAgICAgICAgICAgICBzb3VyY2UgPSB1bndyYXBDb21tZW50KGNvbW1lbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzb3VyY2UgPSBjb21tZW50O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBhcnJheSBvZiByZWxldmFudCB0YWdzXG4gICAgICAgICAgICBpZiAob3B0aW9ucy50YWdzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzQXJyYXkob3B0aW9ucy50YWdzKSkge1xuICAgICAgICAgICAgICAgICAgICBpbnRlcmVzdGluZ1RhZ3MgPSB7IH07XG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGl6ID0gb3B0aW9ucy50YWdzLmxlbmd0aDsgaSA8IGl6OyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy50YWdzW2ldID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVyZXN0aW5nVGFnc1tvcHRpb25zLnRhZ3NbaV1dID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXRpbGl0eS50aHJvd0Vycm9yKCdJbnZhbGlkIFwidGFnc1wiIHBhcmFtZXRlcjogJyArIG9wdGlvbnMudGFncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB1dGlsaXR5LnRocm93RXJyb3IoJ0ludmFsaWQgXCJ0YWdzXCIgcGFyYW1ldGVyOiAnICsgb3B0aW9ucy50YWdzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxlbmd0aCA9IHNvdXJjZS5sZW5ndGg7XG4gICAgICAgICAgICBpbmRleCA9IDA7XG4gICAgICAgICAgICBsaW5lTnVtYmVyID0gMDtcbiAgICAgICAgICAgIHJlY292ZXJhYmxlID0gb3B0aW9ucy5yZWNvdmVyYWJsZTtcbiAgICAgICAgICAgIHNsb3BweSA9IG9wdGlvbnMuc2xvcHB5O1xuICAgICAgICAgICAgc3RyaWN0ID0gb3B0aW9ucy5zdHJpY3Q7XG5cbiAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gc2NhbkpTRG9jRGVzY3JpcHRpb24ob3B0aW9ucy5wcmVzZXJ2ZVdoaXRlc3BhY2UpO1xuXG4gICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgICAgIHRhZyA9IHBhcnNlVGFnKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGlmICghdGFnKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWludGVyZXN0aW5nVGFncyB8fCBpbnRlcmVzdGluZ1RhZ3MuaGFzT3duUHJvcGVydHkodGFnLnRpdGxlKSkge1xuICAgICAgICAgICAgICAgICAgICB0YWdzLnB1c2godGFnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgICAgIHRhZ3M6IHRhZ3NcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZXhwb3J0cy5wYXJzZSA9IHBhcnNlO1xuICAgIH0oanNkb2MgPSB7fSkpO1xuXG4gICAgZXhwb3J0cy52ZXJzaW9uID0gdXRpbGl0eS5WRVJTSU9OO1xuICAgIGV4cG9ydHMucGFyc2UgPSBqc2RvYy5wYXJzZTtcbiAgICBleHBvcnRzLnBhcnNlVHlwZSA9IHR5cGVkLnBhcnNlVHlwZTtcbiAgICBleHBvcnRzLnBhcnNlUGFyYW1UeXBlID0gdHlwZWQucGFyc2VQYXJhbVR5cGU7XG4gICAgZXhwb3J0cy51bndyYXBDb21tZW50ID0gdW53cmFwQ29tbWVudDtcbiAgICBleHBvcnRzLlN5bnRheCA9IHNoYWxsb3dDb3B5KHR5cGVkLlN5bnRheCk7XG4gICAgZXhwb3J0cy5FcnJvciA9IHV0aWxpdHkuRG9jdHJpbmVFcnJvcjtcbiAgICBleHBvcnRzLnR5cGUgPSB7XG4gICAgICAgIFN5bnRheDogZXhwb3J0cy5TeW50YXgsXG4gICAgICAgIHBhcnNlVHlwZTogdHlwZWQucGFyc2VUeXBlLFxuICAgICAgICBwYXJzZVBhcmFtVHlwZTogdHlwZWQucGFyc2VQYXJhbVR5cGUsXG4gICAgICAgIHN0cmluZ2lmeTogdHlwZWQuc3RyaW5naWZ5XG4gICAgfTtcbn0oKSk7XG4vKiB2aW06IHNldCBzdz00IHRzPTQgZXQgdHc9ODAgOiAqL1xuIiwiLypcbiAgQ29weXJpZ2h0IChDKSAyMDEyLTIwMTQgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuICBDb3B5cmlnaHQgKEMpIDIwMTQgRGFuIFRhbyA8ZGFuaWVsLnRhb0BnbWFpbC5jb20+XG4gIENvcHlyaWdodCAoQykgMjAxMyBBbmRyZXcgRWlzZW5iZXJnIDxhbmRyZXdAZWlzZW5iZXJnLmFzPlxuXG4gIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcblxuICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4gICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuXG4gIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiAgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxuICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XG4gIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxuICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbi8vIFwidHlwZWRcIiwgdGhlIFR5cGUgRXhwcmVzc2lvbiBQYXJzZXIgZm9yIGRvY3RyaW5lLlxuXG4oZnVuY3Rpb24gKCkge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIHZhciBTeW50YXgsXG4gICAgICAgIFRva2VuLFxuICAgICAgICBzb3VyY2UsXG4gICAgICAgIGxlbmd0aCxcbiAgICAgICAgaW5kZXgsXG4gICAgICAgIHByZXZpb3VzLFxuICAgICAgICB0b2tlbixcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGVzdXRpbHMsXG4gICAgICAgIHV0aWxpdHk7XG5cbiAgICBlc3V0aWxzID0gcmVxdWlyZSgnZXN1dGlscycpO1xuICAgIHV0aWxpdHkgPSByZXF1aXJlKCcuL3V0aWxpdHknKTtcblxuICAgIFN5bnRheCA9IHtcbiAgICAgICAgTnVsbGFibGVMaXRlcmFsOiAnTnVsbGFibGVMaXRlcmFsJyxcbiAgICAgICAgQWxsTGl0ZXJhbDogJ0FsbExpdGVyYWwnLFxuICAgICAgICBOdWxsTGl0ZXJhbDogJ051bGxMaXRlcmFsJyxcbiAgICAgICAgVW5kZWZpbmVkTGl0ZXJhbDogJ1VuZGVmaW5lZExpdGVyYWwnLFxuICAgICAgICBWb2lkTGl0ZXJhbDogJ1ZvaWRMaXRlcmFsJyxcbiAgICAgICAgVW5pb25UeXBlOiAnVW5pb25UeXBlJyxcbiAgICAgICAgQXJyYXlUeXBlOiAnQXJyYXlUeXBlJyxcbiAgICAgICAgUmVjb3JkVHlwZTogJ1JlY29yZFR5cGUnLFxuICAgICAgICBGaWVsZFR5cGU6ICdGaWVsZFR5cGUnLFxuICAgICAgICBGdW5jdGlvblR5cGU6ICdGdW5jdGlvblR5cGUnLFxuICAgICAgICBQYXJhbWV0ZXJUeXBlOiAnUGFyYW1ldGVyVHlwZScsXG4gICAgICAgIFJlc3RUeXBlOiAnUmVzdFR5cGUnLFxuICAgICAgICBOb25OdWxsYWJsZVR5cGU6ICdOb25OdWxsYWJsZVR5cGUnLFxuICAgICAgICBPcHRpb25hbFR5cGU6ICdPcHRpb25hbFR5cGUnLFxuICAgICAgICBOdWxsYWJsZVR5cGU6ICdOdWxsYWJsZVR5cGUnLFxuICAgICAgICBOYW1lRXhwcmVzc2lvbjogJ05hbWVFeHByZXNzaW9uJyxcbiAgICAgICAgVHlwZUFwcGxpY2F0aW9uOiAnVHlwZUFwcGxpY2F0aW9uJ1xuICAgIH07XG5cbiAgICBUb2tlbiA9IHtcbiAgICAgICAgSUxMRUdBTDogMCwgICAgLy8gSUxMRUdBTFxuICAgICAgICBET1RfTFQ6IDEsICAgICAvLyAuPFxuICAgICAgICBSRVNUOiAyLCAgICAgICAvLyAuLi5cbiAgICAgICAgTFQ6IDMsICAgICAgICAgLy8gPFxuICAgICAgICBHVDogNCwgICAgICAgICAvLyA+XG4gICAgICAgIExQQVJFTjogNSwgICAgIC8vIChcbiAgICAgICAgUlBBUkVOOiA2LCAgICAgLy8gKVxuICAgICAgICBMQlJBQ0U6IDcsICAgICAvLyB7XG4gICAgICAgIFJCUkFDRTogOCwgICAgIC8vIH1cbiAgICAgICAgTEJSQUNLOiA5LCAgICAvLyBbXG4gICAgICAgIFJCUkFDSzogMTAsICAgIC8vIF1cbiAgICAgICAgQ09NTUE6IDExLCAgICAgLy8gLFxuICAgICAgICBDT0xPTjogMTIsICAgICAvLyA6XG4gICAgICAgIFNUQVI6IDEzLCAgICAgIC8vICpcbiAgICAgICAgUElQRTogMTQsICAgICAgLy8gfFxuICAgICAgICBRVUVTVElPTjogMTUsICAvLyA/XG4gICAgICAgIEJBTkc6IDE2LCAgICAgIC8vICFcbiAgICAgICAgRVFVQUw6IDE3LCAgICAgLy8gPVxuICAgICAgICBOQU1FOiAxOCwgICAgICAvLyBuYW1lIHRva2VuXG4gICAgICAgIFNUUklORzogMTksICAgIC8vIHN0cmluZ1xuICAgICAgICBOVU1CRVI6IDIwLCAgICAvLyBudW1iZXJcbiAgICAgICAgRU9GOiAyMVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBpc1R5cGVOYW1lKGNoKSB7XG4gICAgICAgIHJldHVybiAnPjwoKXt9W10sOip8PyE9Jy5pbmRleE9mKFN0cmluZy5mcm9tQ2hhckNvZGUoY2gpKSA9PT0gLTEgJiYgIWVzdXRpbHMuY29kZS5pc1doaXRlU3BhY2UoY2gpICYmICFlc3V0aWxzLmNvZGUuaXNMaW5lVGVybWluYXRvcihjaCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gQ29udGV4dChwcmV2aW91cywgaW5kZXgsIHRva2VuLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLl9wcmV2aW91cyA9IHByZXZpb3VzO1xuICAgICAgICB0aGlzLl9pbmRleCA9IGluZGV4O1xuICAgICAgICB0aGlzLl90b2tlbiA9IHRva2VuO1xuICAgICAgICB0aGlzLl92YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIENvbnRleHQucHJvdG90eXBlLnJlc3RvcmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHByZXZpb3VzID0gdGhpcy5fcHJldmlvdXM7XG4gICAgICAgIGluZGV4ID0gdGhpcy5faW5kZXg7XG4gICAgICAgIHRva2VuID0gdGhpcy5fdG9rZW47XG4gICAgICAgIHZhbHVlID0gdGhpcy5fdmFsdWU7XG4gICAgfTtcblxuICAgIENvbnRleHQuc2F2ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBDb250ZXh0KHByZXZpb3VzLCBpbmRleCwgdG9rZW4sIHZhbHVlKTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gYWR2YW5jZSgpIHtcbiAgICAgICAgdmFyIGNoID0gc291cmNlLmNoYXJBdChpbmRleCk7XG4gICAgICAgIGluZGV4ICs9IDE7XG4gICAgICAgIHJldHVybiBjaDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzY2FuSGV4RXNjYXBlKHByZWZpeCkge1xuICAgICAgICB2YXIgaSwgbGVuLCBjaCwgY29kZSA9IDA7XG5cbiAgICAgICAgbGVuID0gKHByZWZpeCA9PT0gJ3UnKSA/IDQgOiAyO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgICAgIGlmIChpbmRleCA8IGxlbmd0aCAmJiBlc3V0aWxzLmNvZGUuaXNIZXhEaWdpdChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkpKSB7XG4gICAgICAgICAgICAgICAgY2ggPSBhZHZhbmNlKCk7XG4gICAgICAgICAgICAgICAgY29kZSA9IGNvZGUgKiAxNiArICcwMTIzNDU2Nzg5YWJjZGVmJy5pbmRleE9mKGNoLnRvTG93ZXJDYXNlKCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2NhblN0cmluZygpIHtcbiAgICAgICAgdmFyIHN0ciA9ICcnLCBxdW90ZSwgY2gsIGNvZGUsIHVuZXNjYXBlZCwgcmVzdG9yZTsgLy9UT0RPIHJldmlldyByZW1vdmFsIG9jdGFsID0gZmFsc2VcbiAgICAgICAgcXVvdGUgPSBzb3VyY2UuY2hhckF0KGluZGV4KTtcbiAgICAgICAgKytpbmRleDtcblxuICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGNoID0gYWR2YW5jZSgpO1xuXG4gICAgICAgICAgICBpZiAoY2ggPT09IHF1b3RlKSB7XG4gICAgICAgICAgICAgICAgcXVvdGUgPSAnJztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPT09ICdcXFxcJykge1xuICAgICAgICAgICAgICAgIGNoID0gYWR2YW5jZSgpO1xuICAgICAgICAgICAgICAgIGlmICghZXN1dGlscy5jb2RlLmlzTGluZVRlcm1pbmF0b3IoY2guY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjaCkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlICduJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0ciArPSAnXFxuJztcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdyJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0ciArPSAnXFxyJztcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd0JzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0ciArPSAnXFx0JztcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd1JzpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAneCc6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN0b3JlID0gaW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICB1bmVzY2FwZWQgPSBzY2FuSGV4RXNjYXBlKGNoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1bmVzY2FwZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIgKz0gdW5lc2NhcGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IHJlc3RvcmU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyICs9IGNoO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2InOlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyICs9ICdcXGInO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2YnOlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyICs9ICdcXGYnO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3YnOlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyICs9ICdcXHYnO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlc3V0aWxzLmNvZGUuaXNPY3RhbERpZ2l0KGNoLmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29kZSA9ICcwMTIzNDU2NycuaW5kZXhPZihjaCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBcXDAgaXMgbm90IG9jdGFsIGVzY2FwZSBzZXF1ZW5jZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlcHJlY2F0aW5nIHVudXNlZCBjb2RlLiBUT0RPIHJldmlldyByZW1vdmFsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiAoY29kZSAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgIG9jdGFsID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL31cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA8IGxlbmd0aCAmJiBlc3V0aWxzLmNvZGUuaXNPY3RhbERpZ2l0KHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9UT0RPIFJldmlldyBSZW1vdmFsIG9jdGFsID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29kZSA9IGNvZGUgKiA4ICsgJzAxMjM0NTY3Jy5pbmRleE9mKGFkdmFuY2UoKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gMyBkaWdpdHMgYXJlIG9ubHkgYWxsb3dlZCB3aGVuIHN0cmluZyBzdGFydHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2l0aCAwLCAxLCAyLCAzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgnMDEyMycuaW5kZXhPZihjaCkgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4IDwgbGVuZ3RoICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXN1dGlscy5jb2RlLmlzT2N0YWxEaWdpdChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2RlID0gY29kZSAqIDggKyAnMDEyMzQ1NjcnLmluZGV4T2YoYWR2YW5jZSgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyICs9IGNoO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPT09ICAnXFxyJyAmJiBzb3VyY2UuY2hhckNvZGVBdChpbmRleCkgPT09IDB4MEEgIC8qICdcXG4nICovKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChlc3V0aWxzLmNvZGUuaXNMaW5lVGVybWluYXRvcihjaC5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHIgKz0gY2g7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocXVvdGUgIT09ICcnKSB7XG4gICAgICAgICAgICB1dGlsaXR5LnRocm93RXJyb3IoJ3VuZXhwZWN0ZWQgcXVvdGUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhbHVlID0gc3RyO1xuICAgICAgICByZXR1cm4gVG9rZW4uU1RSSU5HO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNjYW5OdW1iZXIoKSB7XG4gICAgICAgIHZhciBudW1iZXIsIGNoO1xuXG4gICAgICAgIG51bWJlciA9ICcnO1xuICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcblxuICAgICAgICBpZiAoY2ggIT09IDB4MkUgIC8qICcuJyAqLykge1xuICAgICAgICAgICAgbnVtYmVyID0gYWR2YW5jZSgpO1xuICAgICAgICAgICAgY2ggPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCk7XG5cbiAgICAgICAgICAgIGlmIChudW1iZXIgPT09ICcwJykge1xuICAgICAgICAgICAgICAgIGlmIChjaCA9PT0gMHg3OCAgLyogJ3gnICovIHx8IGNoID09PSAweDU4ICAvKiAnWCcgKi8pIHtcbiAgICAgICAgICAgICAgICAgICAgbnVtYmVyICs9IGFkdmFuY2UoKTtcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZXN1dGlscy5jb2RlLmlzSGV4RGlnaXQoY2gpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBudW1iZXIgKz0gYWR2YW5jZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKG51bWJlci5sZW5ndGggPD0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gb25seSAweFxuICAgICAgICAgICAgICAgICAgICAgICAgdXRpbGl0eS50aHJvd0Vycm9yKCd1bmV4cGVjdGVkIHRva2VuJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVzdXRpbHMuY29kZS5pc0lkZW50aWZpZXJTdGFydChjaCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1dGlsaXR5LnRocm93RXJyb3IoJ3VuZXhwZWN0ZWQgdG9rZW4nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhcnNlSW50KG51bWJlciwgMTYpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVG9rZW4uTlVNQkVSO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChlc3V0aWxzLmNvZGUuaXNPY3RhbERpZ2l0KGNoKSkge1xuICAgICAgICAgICAgICAgICAgICBudW1iZXIgKz0gYWR2YW5jZSgpO1xuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFlc3V0aWxzLmNvZGUuaXNPY3RhbERpZ2l0KGNoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyICs9IGFkdmFuY2UoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXN1dGlscy5jb2RlLmlzSWRlbnRpZmllclN0YXJ0KGNoKSB8fCBlc3V0aWxzLmNvZGUuaXNEZWNpbWFsRGlnaXQoY2gpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXRpbGl0eS50aHJvd0Vycm9yKCd1bmV4cGVjdGVkIHRva2VuJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZUludChudW1iZXIsIDgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVG9rZW4uTlVNQkVSO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChlc3V0aWxzLmNvZGUuaXNEZWNpbWFsRGlnaXQoY2gpKSB7XG4gICAgICAgICAgICAgICAgICAgIHV0aWxpdHkudGhyb3dFcnJvcigndW5leHBlY3RlZCB0b2tlbicpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgY2ggPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCk7XG4gICAgICAgICAgICAgICAgaWYgKCFlc3V0aWxzLmNvZGUuaXNEZWNpbWFsRGlnaXQoY2gpKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBudW1iZXIgKz0gYWR2YW5jZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNoID09PSAweDJFICAvKiAnLicgKi8pIHtcbiAgICAgICAgICAgIG51bWJlciArPSBhZHZhbmNlKCk7XG4gICAgICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgICAgICAgICBpZiAoIWVzdXRpbHMuY29kZS5pc0RlY2ltYWxEaWdpdChjaCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG51bWJlciArPSBhZHZhbmNlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2ggPT09IDB4NjUgIC8qICdlJyAqLyB8fCBjaCA9PT0gMHg0NSAgLyogJ0UnICovKSB7XG4gICAgICAgICAgICBudW1iZXIgKz0gYWR2YW5jZSgpO1xuXG4gICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgICAgIGlmIChjaCA9PT0gMHgyQiAgLyogJysnICovIHx8IGNoID09PSAweDJEICAvKiAnLScgKi8pIHtcbiAgICAgICAgICAgICAgICBudW1iZXIgKz0gYWR2YW5jZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgICAgIGlmIChlc3V0aWxzLmNvZGUuaXNEZWNpbWFsRGlnaXQoY2gpKSB7XG4gICAgICAgICAgICAgICAgbnVtYmVyICs9IGFkdmFuY2UoKTtcbiAgICAgICAgICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY2ggPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghZXN1dGlscy5jb2RlLmlzRGVjaW1hbERpZ2l0KGNoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbnVtYmVyICs9IGFkdmFuY2UoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHV0aWxpdHkudGhyb3dFcnJvcigndW5leHBlY3RlZCB0b2tlbicpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgICAgIGlmIChlc3V0aWxzLmNvZGUuaXNJZGVudGlmaWVyU3RhcnQoY2gpKSB7XG4gICAgICAgICAgICAgICAgdXRpbGl0eS50aHJvd0Vycm9yKCd1bmV4cGVjdGVkIHRva2VuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB2YWx1ZSA9IHBhcnNlRmxvYXQobnVtYmVyKTtcbiAgICAgICAgcmV0dXJuIFRva2VuLk5VTUJFUjtcbiAgICB9XG5cblxuICAgIGZ1bmN0aW9uIHNjYW5UeXBlTmFtZSgpIHtcbiAgICAgICAgdmFyIGNoLCBjaDI7XG5cbiAgICAgICAgdmFsdWUgPSBhZHZhbmNlKCk7XG4gICAgICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCAmJiBpc1R5cGVOYW1lKHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSkpIHtcbiAgICAgICAgICAgIGNoID0gc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpO1xuICAgICAgICAgICAgaWYgKGNoID09PSAweDJFICAvKiAnLicgKi8pIHtcbiAgICAgICAgICAgICAgICBpZiAoKGluZGV4ICsgMSkgPj0gbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBUb2tlbi5JTExFR0FMO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjaDIgPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCArIDEpO1xuICAgICAgICAgICAgICAgIGlmIChjaDIgPT09IDB4M0MgIC8qICc8JyAqLykge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YWx1ZSArPSBhZHZhbmNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFRva2VuLk5BTUU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbmV4dCgpIHtcbiAgICAgICAgdmFyIGNoO1xuXG4gICAgICAgIHByZXZpb3VzID0gaW5kZXg7XG5cbiAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoICYmIGVzdXRpbHMuY29kZS5pc1doaXRlU3BhY2Uoc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpKSkge1xuICAgICAgICAgICAgYWR2YW5jZSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpbmRleCA+PSBsZW5ndGgpIHtcbiAgICAgICAgICAgIHRva2VuID0gVG9rZW4uRU9GO1xuICAgICAgICAgICAgcmV0dXJuIHRva2VuO1xuICAgICAgICB9XG5cbiAgICAgICAgY2ggPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCk7XG4gICAgICAgIHN3aXRjaCAoY2gpIHtcbiAgICAgICAgY2FzZSAweDI3OiAgLyogJycnICovXG4gICAgICAgIGNhc2UgMHgyMjogIC8qICdcIicgKi9cbiAgICAgICAgICAgIHRva2VuID0gc2NhblN0cmluZygpO1xuICAgICAgICAgICAgcmV0dXJuIHRva2VuO1xuXG4gICAgICAgIGNhc2UgMHgzQTogIC8qICc6JyAqL1xuICAgICAgICAgICAgYWR2YW5jZSgpO1xuICAgICAgICAgICAgdG9rZW4gPSBUb2tlbi5DT0xPTjtcbiAgICAgICAgICAgIHJldHVybiB0b2tlbjtcblxuICAgICAgICBjYXNlIDB4MkM6ICAvKiAnLCcgKi9cbiAgICAgICAgICAgIGFkdmFuY2UoKTtcbiAgICAgICAgICAgIHRva2VuID0gVG9rZW4uQ09NTUE7XG4gICAgICAgICAgICByZXR1cm4gdG9rZW47XG5cbiAgICAgICAgY2FzZSAweDI4OiAgLyogJygnICovXG4gICAgICAgICAgICBhZHZhbmNlKCk7XG4gICAgICAgICAgICB0b2tlbiA9IFRva2VuLkxQQVJFTjtcbiAgICAgICAgICAgIHJldHVybiB0b2tlbjtcblxuICAgICAgICBjYXNlIDB4Mjk6ICAvKiAnKScgKi9cbiAgICAgICAgICAgIGFkdmFuY2UoKTtcbiAgICAgICAgICAgIHRva2VuID0gVG9rZW4uUlBBUkVOO1xuICAgICAgICAgICAgcmV0dXJuIHRva2VuO1xuXG4gICAgICAgIGNhc2UgMHg1QjogIC8qICdbJyAqL1xuICAgICAgICAgICAgYWR2YW5jZSgpO1xuICAgICAgICAgICAgdG9rZW4gPSBUb2tlbi5MQlJBQ0s7XG4gICAgICAgICAgICByZXR1cm4gdG9rZW47XG5cbiAgICAgICAgY2FzZSAweDVEOiAgLyogJ10nICovXG4gICAgICAgICAgICBhZHZhbmNlKCk7XG4gICAgICAgICAgICB0b2tlbiA9IFRva2VuLlJCUkFDSztcbiAgICAgICAgICAgIHJldHVybiB0b2tlbjtcblxuICAgICAgICBjYXNlIDB4N0I6ICAvKiAneycgKi9cbiAgICAgICAgICAgIGFkdmFuY2UoKTtcbiAgICAgICAgICAgIHRva2VuID0gVG9rZW4uTEJSQUNFO1xuICAgICAgICAgICAgcmV0dXJuIHRva2VuO1xuXG4gICAgICAgIGNhc2UgMHg3RDogIC8qICd9JyAqL1xuICAgICAgICAgICAgYWR2YW5jZSgpO1xuICAgICAgICAgICAgdG9rZW4gPSBUb2tlbi5SQlJBQ0U7XG4gICAgICAgICAgICByZXR1cm4gdG9rZW47XG5cbiAgICAgICAgY2FzZSAweDJFOiAgLyogJy4nICovXG4gICAgICAgICAgICBpZiAoaW5kZXggKyAxIDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgY2ggPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCArIDEpO1xuICAgICAgICAgICAgICAgIGlmIChjaCA9PT0gMHgzQyAgLyogJzwnICovKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkdmFuY2UoKTsgIC8vICcuJ1xuICAgICAgICAgICAgICAgICAgICBhZHZhbmNlKCk7ICAvLyAnPCdcbiAgICAgICAgICAgICAgICAgICAgdG9rZW4gPSBUb2tlbi5ET1RfTFQ7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0b2tlbjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoY2ggPT09IDB4MkUgIC8qICcuJyAqLyAmJiBpbmRleCArIDIgPCBsZW5ndGggJiYgc291cmNlLmNoYXJDb2RlQXQoaW5kZXggKyAyKSA9PT0gMHgyRSAgLyogJy4nICovKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkdmFuY2UoKTsgIC8vICcuJ1xuICAgICAgICAgICAgICAgICAgICBhZHZhbmNlKCk7ICAvLyAnLidcbiAgICAgICAgICAgICAgICAgICAgYWR2YW5jZSgpOyAgLy8gJy4nXG4gICAgICAgICAgICAgICAgICAgIHRva2VuID0gVG9rZW4uUkVTVDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRva2VuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChlc3V0aWxzLmNvZGUuaXNEZWNpbWFsRGlnaXQoY2gpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRva2VuID0gc2Nhbk51bWJlcigpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdG9rZW47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdG9rZW4gPSBUb2tlbi5JTExFR0FMO1xuICAgICAgICAgICAgcmV0dXJuIHRva2VuO1xuXG4gICAgICAgIGNhc2UgMHgzQzogIC8qICc8JyAqL1xuICAgICAgICAgICAgYWR2YW5jZSgpO1xuICAgICAgICAgICAgdG9rZW4gPSBUb2tlbi5MVDtcbiAgICAgICAgICAgIHJldHVybiB0b2tlbjtcblxuICAgICAgICBjYXNlIDB4M0U6ICAvKiAnPicgKi9cbiAgICAgICAgICAgIGFkdmFuY2UoKTtcbiAgICAgICAgICAgIHRva2VuID0gVG9rZW4uR1Q7XG4gICAgICAgICAgICByZXR1cm4gdG9rZW47XG5cbiAgICAgICAgY2FzZSAweDJBOiAgLyogJyonICovXG4gICAgICAgICAgICBhZHZhbmNlKCk7XG4gICAgICAgICAgICB0b2tlbiA9IFRva2VuLlNUQVI7XG4gICAgICAgICAgICByZXR1cm4gdG9rZW47XG5cbiAgICAgICAgY2FzZSAweDdDOiAgLyogJ3wnICovXG4gICAgICAgICAgICBhZHZhbmNlKCk7XG4gICAgICAgICAgICB0b2tlbiA9IFRva2VuLlBJUEU7XG4gICAgICAgICAgICByZXR1cm4gdG9rZW47XG5cbiAgICAgICAgY2FzZSAweDNGOiAgLyogJz8nICovXG4gICAgICAgICAgICBhZHZhbmNlKCk7XG4gICAgICAgICAgICB0b2tlbiA9IFRva2VuLlFVRVNUSU9OO1xuICAgICAgICAgICAgcmV0dXJuIHRva2VuO1xuXG4gICAgICAgIGNhc2UgMHgyMTogIC8qICchJyAqL1xuICAgICAgICAgICAgYWR2YW5jZSgpO1xuICAgICAgICAgICAgdG9rZW4gPSBUb2tlbi5CQU5HO1xuICAgICAgICAgICAgcmV0dXJuIHRva2VuO1xuXG4gICAgICAgIGNhc2UgMHgzRDogIC8qICc9JyAqL1xuICAgICAgICAgICAgYWR2YW5jZSgpO1xuICAgICAgICAgICAgdG9rZW4gPSBUb2tlbi5FUVVBTDtcbiAgICAgICAgICAgIHJldHVybiB0b2tlbjtcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgaWYgKGVzdXRpbHMuY29kZS5pc0RlY2ltYWxEaWdpdChjaCkpIHtcbiAgICAgICAgICAgICAgICB0b2tlbiA9IHNjYW5OdW1iZXIoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdG9rZW47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHR5cGUgc3RyaW5nIHBlcm1pdHMgZm9sbG93aW5nIGNhc2UsXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gbmFtZXNwYWNlLm1vZHVsZS5NeUNsYXNzXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gdGhpcyByZWR1Y2VkIDEgdG9rZW4gVEtfTkFNRVxuICAgICAgICAgICAgdXRpbGl0eS5hc3NlcnQoaXNUeXBlTmFtZShjaCkpO1xuICAgICAgICAgICAgdG9rZW4gPSBzY2FuVHlwZU5hbWUoKTtcbiAgICAgICAgICAgIHJldHVybiB0b2tlbjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNvbnN1bWUodGFyZ2V0LCB0ZXh0KSB7XG4gICAgICAgIHV0aWxpdHkuYXNzZXJ0KHRva2VuID09PSB0YXJnZXQsIHRleHQgfHwgJ2NvbnN1bWVkIHRva2VuIG5vdCBtYXRjaGVkJyk7XG4gICAgICAgIG5leHQoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBleHBlY3QodGFyZ2V0LCBtZXNzYWdlKSB7XG4gICAgICAgIGlmICh0b2tlbiAhPT0gdGFyZ2V0KSB7XG4gICAgICAgICAgICB1dGlsaXR5LnRocm93RXJyb3IobWVzc2FnZSB8fCAndW5leHBlY3RlZCB0b2tlbicpO1xuICAgICAgICB9XG4gICAgICAgIG5leHQoKTtcbiAgICB9XG5cbiAgICAvLyBVbmlvblR5cGUgOj0gJygnIFR5cGVVbmlvbkxpc3QgJyknXG4gICAgLy9cbiAgICAvLyBUeXBlVW5pb25MaXN0IDo9XG4gICAgLy8gICAgIDw8ZW1wdHk+PlxuICAgIC8vICAgfCBOb25lbXB0eVR5cGVVbmlvbkxpc3RcbiAgICAvL1xuICAgIC8vIE5vbmVtcHR5VHlwZVVuaW9uTGlzdCA6PVxuICAgIC8vICAgICBUeXBlRXhwcmVzc2lvblxuICAgIC8vICAgfCBUeXBlRXhwcmVzc2lvbiAnfCcgTm9uZW1wdHlUeXBlVW5pb25MaXN0XG4gICAgZnVuY3Rpb24gcGFyc2VVbmlvblR5cGUoKSB7XG4gICAgICAgIHZhciBlbGVtZW50cztcbiAgICAgICAgY29uc3VtZShUb2tlbi5MUEFSRU4sICdVbmlvblR5cGUgc2hvdWxkIHN0YXJ0IHdpdGggKCcpO1xuICAgICAgICBlbGVtZW50cyA9IFtdO1xuICAgICAgICBpZiAodG9rZW4gIT09IFRva2VuLlJQQVJFTikge1xuICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKHBhcnNlVHlwZUV4cHJlc3Npb24oKSk7XG4gICAgICAgICAgICAgICAgaWYgKHRva2VuID09PSBUb2tlbi5SUEFSRU4pIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGV4cGVjdChUb2tlbi5QSVBFKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdW1lKFRva2VuLlJQQVJFTiwgJ1VuaW9uVHlwZSBzaG91bGQgZW5kIHdpdGggKScpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogU3ludGF4LlVuaW9uVHlwZSxcbiAgICAgICAgICAgIGVsZW1lbnRzOiBlbGVtZW50c1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIEFycmF5VHlwZSA6PSAnWycgRWxlbWVudFR5cGVMaXN0ICddJ1xuICAgIC8vXG4gICAgLy8gRWxlbWVudFR5cGVMaXN0IDo9XG4gICAgLy8gICAgIDw8ZW1wdHk+PlxuICAgIC8vICB8IFR5cGVFeHByZXNzaW9uXG4gICAgLy8gIHwgJy4uLicgVHlwZUV4cHJlc3Npb25cbiAgICAvLyAgfCBUeXBlRXhwcmVzc2lvbiAnLCcgRWxlbWVudFR5cGVMaXN0XG4gICAgZnVuY3Rpb24gcGFyc2VBcnJheVR5cGUoKSB7XG4gICAgICAgIHZhciBlbGVtZW50cztcbiAgICAgICAgY29uc3VtZShUb2tlbi5MQlJBQ0ssICdBcnJheVR5cGUgc2hvdWxkIHN0YXJ0IHdpdGggWycpO1xuICAgICAgICBlbGVtZW50cyA9IFtdO1xuICAgICAgICB3aGlsZSAodG9rZW4gIT09IFRva2VuLlJCUkFDSykge1xuICAgICAgICAgICAgaWYgKHRva2VuID09PSBUb2tlbi5SRVNUKSB7XG4gICAgICAgICAgICAgICAgY29uc3VtZShUb2tlbi5SRVNUKTtcbiAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogU3ludGF4LlJlc3RUeXBlLFxuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBwYXJzZVR5cGVFeHByZXNzaW9uKClcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudHMucHVzaChwYXJzZVR5cGVFeHByZXNzaW9uKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRva2VuICE9PSBUb2tlbi5SQlJBQ0spIHtcbiAgICAgICAgICAgICAgICBleHBlY3QoVG9rZW4uQ09NTUEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGV4cGVjdChUb2tlbi5SQlJBQ0spO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogU3ludGF4LkFycmF5VHlwZSxcbiAgICAgICAgICAgIGVsZW1lbnRzOiBlbGVtZW50c1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNlRmllbGROYW1lKCkge1xuICAgICAgICB2YXIgdiA9IHZhbHVlO1xuICAgICAgICBpZiAodG9rZW4gPT09IFRva2VuLk5BTUUgfHwgdG9rZW4gPT09IFRva2VuLlNUUklORykge1xuICAgICAgICAgICAgbmV4dCgpO1xuICAgICAgICAgICAgcmV0dXJuIHY7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodG9rZW4gPT09IFRva2VuLk5VTUJFUikge1xuICAgICAgICAgICAgY29uc3VtZShUb2tlbi5OVU1CRVIpO1xuICAgICAgICAgICAgcmV0dXJuIFN0cmluZyh2KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHV0aWxpdHkudGhyb3dFcnJvcigndW5leHBlY3RlZCB0b2tlbicpO1xuICAgIH1cblxuICAgIC8vIEZpZWxkVHlwZSA6PVxuICAgIC8vICAgICBGaWVsZE5hbWVcbiAgICAvLyAgIHwgRmllbGROYW1lICc6JyBUeXBlRXhwcmVzc2lvblxuICAgIC8vXG4gICAgLy8gRmllbGROYW1lIDo9XG4gICAgLy8gICAgIE5hbWVFeHByZXNzaW9uXG4gICAgLy8gICB8IFN0cmluZ0xpdGVyYWxcbiAgICAvLyAgIHwgTnVtYmVyTGl0ZXJhbFxuICAgIC8vICAgfCBSZXNlcnZlZElkZW50aWZpZXJcbiAgICBmdW5jdGlvbiBwYXJzZUZpZWxkVHlwZSgpIHtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICBrZXkgPSBwYXJzZUZpZWxkTmFtZSgpO1xuICAgICAgICBpZiAodG9rZW4gPT09IFRva2VuLkNPTE9OKSB7XG4gICAgICAgICAgICBjb25zdW1lKFRva2VuLkNPTE9OKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdHlwZTogU3ludGF4LkZpZWxkVHlwZSxcbiAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogcGFyc2VUeXBlRXhwcmVzc2lvbigpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBTeW50YXguRmllbGRUeXBlLFxuICAgICAgICAgICAga2V5OiBrZXksXG4gICAgICAgICAgICB2YWx1ZTogbnVsbFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIFJlY29yZFR5cGUgOj0gJ3snIEZpZWxkVHlwZUxpc3QgJ30nXG4gICAgLy9cbiAgICAvLyBGaWVsZFR5cGVMaXN0IDo9XG4gICAgLy8gICAgIDw8ZW1wdHk+PlxuICAgIC8vICAgfCBGaWVsZFR5cGVcbiAgICAvLyAgIHwgRmllbGRUeXBlICcsJyBGaWVsZFR5cGVMaXN0XG4gICAgZnVuY3Rpb24gcGFyc2VSZWNvcmRUeXBlKCkge1xuICAgICAgICB2YXIgZmllbGRzO1xuXG4gICAgICAgIGNvbnN1bWUoVG9rZW4uTEJSQUNFLCAnUmVjb3JkVHlwZSBzaG91bGQgc3RhcnQgd2l0aCB7Jyk7XG4gICAgICAgIGZpZWxkcyA9IFtdO1xuICAgICAgICBpZiAodG9rZW4gPT09IFRva2VuLkNPTU1BKSB7XG4gICAgICAgICAgICBjb25zdW1lKFRva2VuLkNPTU1BKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdoaWxlICh0b2tlbiAhPT0gVG9rZW4uUkJSQUNFKSB7XG4gICAgICAgICAgICAgICAgZmllbGRzLnB1c2gocGFyc2VGaWVsZFR5cGUoKSk7XG4gICAgICAgICAgICAgICAgaWYgKHRva2VuICE9PSBUb2tlbi5SQlJBQ0UpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KFRva2VuLkNPTU1BKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZXhwZWN0KFRva2VuLlJCUkFDRSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBTeW50YXguUmVjb3JkVHlwZSxcbiAgICAgICAgICAgIGZpZWxkczogZmllbGRzXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gTmFtZUV4cHJlc3Npb24gOj1cbiAgICAvLyAgICBJZGVudGlmaWVyXG4gICAgLy8gIHwgVGFnSWRlbnRpZmllciAnOicgSWRlbnRpZmllclxuICAgIC8vXG4gICAgLy8gVGFnIGlkZW50aWZpZXIgaXMgb25lIG9mIFwibW9kdWxlXCIsIFwiZXh0ZXJuYWxcIiBvciBcImV2ZW50XCJcbiAgICAvLyBJZGVudGlmaWVyIGlzIHRoZSBzYW1lIGFzIFRva2VuLk5BTUUsIGluY2x1ZGluZyBhbnkgZG90cywgc29tZXRoaW5nIGxpa2VcbiAgICAvLyBuYW1lc3BhY2UubW9kdWxlLk15Q2xhc3NcbiAgICBmdW5jdGlvbiBwYXJzZU5hbWVFeHByZXNzaW9uKCkge1xuICAgICAgICB2YXIgbmFtZSA9IHZhbHVlO1xuICAgICAgICBleHBlY3QoVG9rZW4uTkFNRSk7XG5cbiAgICAgICAgaWYgKHRva2VuID09PSBUb2tlbi5DT0xPTiAmJiAoXG4gICAgICAgICAgICAgICAgbmFtZSA9PT0gJ21vZHVsZScgfHxcbiAgICAgICAgICAgICAgICBuYW1lID09PSAnZXh0ZXJuYWwnIHx8XG4gICAgICAgICAgICAgICAgbmFtZSA9PT0gJ2V2ZW50JykpIHtcbiAgICAgICAgICAgIGNvbnN1bWUoVG9rZW4uQ09MT04pO1xuICAgICAgICAgICAgbmFtZSArPSAnOicgKyB2YWx1ZTtcbiAgICAgICAgICAgIGV4cGVjdChUb2tlbi5OQU1FKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBTeW50YXguTmFtZUV4cHJlc3Npb24sXG4gICAgICAgICAgICBuYW1lOiBuYW1lXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gVHlwZUV4cHJlc3Npb25MaXN0IDo9XG4gICAgLy8gICAgIFRvcExldmVsVHlwZUV4cHJlc3Npb25cbiAgICAvLyAgIHwgVG9wTGV2ZWxUeXBlRXhwcmVzc2lvbiAnLCcgVHlwZUV4cHJlc3Npb25MaXN0XG4gICAgZnVuY3Rpb24gcGFyc2VUeXBlRXhwcmVzc2lvbkxpc3QoKSB7XG4gICAgICAgIHZhciBlbGVtZW50cyA9IFtdO1xuXG4gICAgICAgIGVsZW1lbnRzLnB1c2gocGFyc2VUb3AoKSk7XG4gICAgICAgIHdoaWxlICh0b2tlbiA9PT0gVG9rZW4uQ09NTUEpIHtcbiAgICAgICAgICAgIGNvbnN1bWUoVG9rZW4uQ09NTUEpO1xuICAgICAgICAgICAgZWxlbWVudHMucHVzaChwYXJzZVRvcCgpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZWxlbWVudHM7XG4gICAgfVxuXG4gICAgLy8gVHlwZU5hbWUgOj1cbiAgICAvLyAgICAgTmFtZUV4cHJlc3Npb25cbiAgICAvLyAgIHwgTmFtZUV4cHJlc3Npb24gVHlwZUFwcGxpY2F0aW9uXG4gICAgLy9cbiAgICAvLyBUeXBlQXBwbGljYXRpb24gOj1cbiAgICAvLyAgICAgJy48JyBUeXBlRXhwcmVzc2lvbkxpc3QgJz4nXG4gICAgLy8gICB8ICc8JyBUeXBlRXhwcmVzc2lvbkxpc3QgJz4nICAgLy8gdGhpcyBpcyBleHRlbnNpb24gb2YgZG9jdHJpbmVcbiAgICBmdW5jdGlvbiBwYXJzZVR5cGVOYW1lKCkge1xuICAgICAgICB2YXIgZXhwciwgYXBwbGljYXRpb25zO1xuXG4gICAgICAgIGV4cHIgPSBwYXJzZU5hbWVFeHByZXNzaW9uKCk7XG4gICAgICAgIGlmICh0b2tlbiA9PT0gVG9rZW4uRE9UX0xUIHx8IHRva2VuID09PSBUb2tlbi5MVCkge1xuICAgICAgICAgICAgbmV4dCgpO1xuICAgICAgICAgICAgYXBwbGljYXRpb25zID0gcGFyc2VUeXBlRXhwcmVzc2lvbkxpc3QoKTtcbiAgICAgICAgICAgIGV4cGVjdChUb2tlbi5HVCk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHR5cGU6IFN5bnRheC5UeXBlQXBwbGljYXRpb24sXG4gICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogZXhwcixcbiAgICAgICAgICAgICAgICBhcHBsaWNhdGlvbnM6IGFwcGxpY2F0aW9uc1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZXhwcjtcbiAgICB9XG5cbiAgICAvLyBSZXN1bHRUeXBlIDo9XG4gICAgLy8gICAgIDw8ZW1wdHk+PlxuICAgIC8vICAgfCAnOicgdm9pZFxuICAgIC8vICAgfCAnOicgVHlwZUV4cHJlc3Npb25cbiAgICAvL1xuICAgIC8vIEJORiBpcyBhYm92ZVxuICAgIC8vIGJ1dCwgd2UgcmVtb3ZlIDw8ZW1wdHk+PiBwYXR0ZXJuLCBzbyB0b2tlbiBpcyBhbHdheXMgVHlwZVRva2VuOjpDT0xPTlxuICAgIGZ1bmN0aW9uIHBhcnNlUmVzdWx0VHlwZSgpIHtcbiAgICAgICAgY29uc3VtZShUb2tlbi5DT0xPTiwgJ1Jlc3VsdFR5cGUgc2hvdWxkIHN0YXJ0IHdpdGggOicpO1xuICAgICAgICBpZiAodG9rZW4gPT09IFRva2VuLk5BTUUgJiYgdmFsdWUgPT09ICd2b2lkJykge1xuICAgICAgICAgICAgY29uc3VtZShUb2tlbi5OQU1FKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdHlwZTogU3ludGF4LlZvaWRMaXRlcmFsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwYXJzZVR5cGVFeHByZXNzaW9uKCk7XG4gICAgfVxuXG4gICAgLy8gUGFyYW1ldGVyc1R5cGUgOj1cbiAgICAvLyAgICAgUmVzdFBhcmFtZXRlclR5cGVcbiAgICAvLyAgIHwgTm9uUmVzdFBhcmFtZXRlcnNUeXBlXG4gICAgLy8gICB8IE5vblJlc3RQYXJhbWV0ZXJzVHlwZSAnLCcgUmVzdFBhcmFtZXRlclR5cGVcbiAgICAvL1xuICAgIC8vIFJlc3RQYXJhbWV0ZXJUeXBlIDo9XG4gICAgLy8gICAgICcuLi4nXG4gICAgLy8gICAgICcuLi4nIElkZW50aWZpZXJcbiAgICAvL1xuICAgIC8vIE5vblJlc3RQYXJhbWV0ZXJzVHlwZSA6PVxuICAgIC8vICAgICBQYXJhbWV0ZXJUeXBlICcsJyBOb25SZXN0UGFyYW1ldGVyc1R5cGVcbiAgICAvLyAgIHwgUGFyYW1ldGVyVHlwZVxuICAgIC8vICAgfCBPcHRpb25hbFBhcmFtZXRlcnNUeXBlXG4gICAgLy9cbiAgICAvLyBPcHRpb25hbFBhcmFtZXRlcnNUeXBlIDo9XG4gICAgLy8gICAgIE9wdGlvbmFsUGFyYW1ldGVyVHlwZVxuICAgIC8vICAgfCBPcHRpb25hbFBhcmFtZXRlclR5cGUsIE9wdGlvbmFsUGFyYW1ldGVyc1R5cGVcbiAgICAvL1xuICAgIC8vIE9wdGlvbmFsUGFyYW1ldGVyVHlwZSA6PSBQYXJhbWV0ZXJUeXBlPVxuICAgIC8vXG4gICAgLy8gUGFyYW1ldGVyVHlwZSA6PSBUeXBlRXhwcmVzc2lvbiB8IElkZW50aWZpZXIgJzonIFR5cGVFeHByZXNzaW9uXG4gICAgLy9cbiAgICAvLyBJZGVudGlmaWVyIGlzIFwibmV3XCIgb3IgXCJ0aGlzXCJcbiAgICBmdW5jdGlvbiBwYXJzZVBhcmFtZXRlcnNUeXBlKCkge1xuICAgICAgICB2YXIgcGFyYW1zID0gW10sIG9wdGlvbmFsU2VxdWVuY2UgPSBmYWxzZSwgZXhwciwgcmVzdCA9IGZhbHNlO1xuXG4gICAgICAgIHdoaWxlICh0b2tlbiAhPT0gVG9rZW4uUlBBUkVOKSB7XG4gICAgICAgICAgICBpZiAodG9rZW4gPT09IFRva2VuLlJFU1QpIHtcbiAgICAgICAgICAgICAgICAvLyBSZXN0UGFyYW1ldGVyVHlwZVxuICAgICAgICAgICAgICAgIGNvbnN1bWUoVG9rZW4uUkVTVCk7XG4gICAgICAgICAgICAgICAgcmVzdCA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGV4cHIgPSBwYXJzZVR5cGVFeHByZXNzaW9uKCk7XG4gICAgICAgICAgICBpZiAoZXhwci50eXBlID09PSBTeW50YXguTmFtZUV4cHJlc3Npb24gJiYgdG9rZW4gPT09IFRva2VuLkNPTE9OKSB7XG4gICAgICAgICAgICAgICAgLy8gSWRlbnRpZmllciAnOicgVHlwZUV4cHJlc3Npb25cbiAgICAgICAgICAgICAgICBjb25zdW1lKFRva2VuLkNPTE9OKTtcbiAgICAgICAgICAgICAgICBleHByID0ge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiBTeW50YXguUGFyYW1ldGVyVHlwZSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogZXhwci5uYW1lLFxuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBwYXJzZVR5cGVFeHByZXNzaW9uKClcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRva2VuID09PSBUb2tlbi5FUVVBTCkge1xuICAgICAgICAgICAgICAgIGNvbnN1bWUoVG9rZW4uRVFVQUwpO1xuICAgICAgICAgICAgICAgIGV4cHIgPSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFN5bnRheC5PcHRpb25hbFR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGV4cHJcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG9wdGlvbmFsU2VxdWVuY2UgPSB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9uYWxTZXF1ZW5jZSkge1xuICAgICAgICAgICAgICAgICAgICB1dGlsaXR5LnRocm93RXJyb3IoJ3VuZXhwZWN0ZWQgdG9rZW4nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzdCkge1xuICAgICAgICAgICAgICAgIGV4cHIgPSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFN5bnRheC5SZXN0VHlwZSxcbiAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogZXhwclxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwYXJhbXMucHVzaChleHByKTtcbiAgICAgICAgICAgIGlmICh0b2tlbiAhPT0gVG9rZW4uUlBBUkVOKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KFRva2VuLkNPTU1BKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGFyYW1zO1xuICAgIH1cblxuICAgIC8vIEZ1bmN0aW9uVHlwZSA6PSAnZnVuY3Rpb24nIEZ1bmN0aW9uU2lnbmF0dXJlVHlwZVxuICAgIC8vXG4gICAgLy8gRnVuY3Rpb25TaWduYXR1cmVUeXBlIDo9XG4gICAgLy8gICB8IFR5cGVQYXJhbWV0ZXJzICcoJyAnKScgUmVzdWx0VHlwZVxuICAgIC8vICAgfCBUeXBlUGFyYW1ldGVycyAnKCcgUGFyYW1ldGVyc1R5cGUgJyknIFJlc3VsdFR5cGVcbiAgICAvLyAgIHwgVHlwZVBhcmFtZXRlcnMgJygnICd0aGlzJyAnOicgVHlwZU5hbWUgJyknIFJlc3VsdFR5cGVcbiAgICAvLyAgIHwgVHlwZVBhcmFtZXRlcnMgJygnICd0aGlzJyAnOicgVHlwZU5hbWUgJywnIFBhcmFtZXRlcnNUeXBlICcpJyBSZXN1bHRUeXBlXG4gICAgZnVuY3Rpb24gcGFyc2VGdW5jdGlvblR5cGUoKSB7XG4gICAgICAgIHZhciBpc05ldywgdGhpc0JpbmRpbmcsIHBhcmFtcywgcmVzdWx0LCBmblR5cGU7XG4gICAgICAgIHV0aWxpdHkuYXNzZXJ0KHRva2VuID09PSBUb2tlbi5OQU1FICYmIHZhbHVlID09PSAnZnVuY3Rpb24nLCAnRnVuY3Rpb25UeXBlIHNob3VsZCBzdGFydCB3aXRoIFxcJ2Z1bmN0aW9uXFwnJyk7XG4gICAgICAgIGNvbnN1bWUoVG9rZW4uTkFNRSk7XG5cbiAgICAgICAgLy8gR29vZ2xlIENsb3N1cmUgQ29tcGlsZXIgaXMgbm90IGltcGxlbWVudGluZyBUeXBlUGFyYW1ldGVycy5cbiAgICAgICAgLy8gU28gd2UgZG8gbm90LiBpZiB3ZSBkb24ndCBnZXQgJygnLCB3ZSBzZWUgaXQgYXMgZXJyb3IuXG4gICAgICAgIGV4cGVjdChUb2tlbi5MUEFSRU4pO1xuXG4gICAgICAgIGlzTmV3ID0gZmFsc2U7XG4gICAgICAgIHBhcmFtcyA9IFtdO1xuICAgICAgICB0aGlzQmluZGluZyA9IG51bGw7XG4gICAgICAgIGlmICh0b2tlbiAhPT0gVG9rZW4uUlBBUkVOKSB7XG4gICAgICAgICAgICAvLyBQYXJhbWV0ZXJzVHlwZSBvciAndGhpcydcbiAgICAgICAgICAgIGlmICh0b2tlbiA9PT0gVG9rZW4uTkFNRSAmJlxuICAgICAgICAgICAgICAgICAgICAodmFsdWUgPT09ICd0aGlzJyB8fCB2YWx1ZSA9PT0gJ25ldycpKSB7XG4gICAgICAgICAgICAgICAgLy8gJ3RoaXMnIG9yICduZXcnXG4gICAgICAgICAgICAgICAgLy8gJ25ldycgaXMgQ2xvc3VyZSBDb21waWxlciBleHRlbnNpb25cbiAgICAgICAgICAgICAgICBpc05ldyA9IHZhbHVlID09PSAnbmV3JztcbiAgICAgICAgICAgICAgICBjb25zdW1lKFRva2VuLk5BTUUpO1xuICAgICAgICAgICAgICAgIGV4cGVjdChUb2tlbi5DT0xPTik7XG4gICAgICAgICAgICAgICAgdGhpc0JpbmRpbmcgPSBwYXJzZVR5cGVOYW1lKCk7XG4gICAgICAgICAgICAgICAgaWYgKHRva2VuID09PSBUb2tlbi5DT01NQSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdW1lKFRva2VuLkNPTU1BKTtcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gcGFyc2VQYXJhbWV0ZXJzVHlwZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcGFyYW1zID0gcGFyc2VQYXJhbWV0ZXJzVHlwZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZXhwZWN0KFRva2VuLlJQQVJFTik7XG5cbiAgICAgICAgcmVzdWx0ID0gbnVsbDtcbiAgICAgICAgaWYgKHRva2VuID09PSBUb2tlbi5DT0xPTikge1xuICAgICAgICAgICAgcmVzdWx0ID0gcGFyc2VSZXN1bHRUeXBlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBmblR5cGUgPSB7XG4gICAgICAgICAgICB0eXBlOiBTeW50YXguRnVuY3Rpb25UeXBlLFxuICAgICAgICAgICAgcGFyYW1zOiBwYXJhbXMsXG4gICAgICAgICAgICByZXN1bHQ6IHJlc3VsdFxuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpc0JpbmRpbmcpIHtcbiAgICAgICAgICAgIC8vIGF2b2lkIGFkZGluZyBudWxsICduZXcnIGFuZCAndGhpcycgcHJvcGVydGllc1xuICAgICAgICAgICAgZm5UeXBlWyd0aGlzJ10gPSB0aGlzQmluZGluZztcbiAgICAgICAgICAgIGlmIChpc05ldykge1xuICAgICAgICAgICAgICAgIGZuVHlwZVsnbmV3J10gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmblR5cGU7XG4gICAgfVxuXG4gICAgLy8gQmFzaWNUeXBlRXhwcmVzc2lvbiA6PVxuICAgIC8vICAgICAnKidcbiAgICAvLyAgIHwgJ251bGwnXG4gICAgLy8gICB8ICd1bmRlZmluZWQnXG4gICAgLy8gICB8IFR5cGVOYW1lXG4gICAgLy8gICB8IEZ1bmN0aW9uVHlwZVxuICAgIC8vICAgfCBVbmlvblR5cGVcbiAgICAvLyAgIHwgUmVjb3JkVHlwZVxuICAgIC8vICAgfCBBcnJheVR5cGVcbiAgICBmdW5jdGlvbiBwYXJzZUJhc2ljVHlwZUV4cHJlc3Npb24oKSB7XG4gICAgICAgIHZhciBjb250ZXh0O1xuICAgICAgICBzd2l0Y2ggKHRva2VuKSB7XG4gICAgICAgIGNhc2UgVG9rZW4uU1RBUjpcbiAgICAgICAgICAgIGNvbnN1bWUoVG9rZW4uU1RBUik7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHR5cGU6IFN5bnRheC5BbGxMaXRlcmFsXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgIGNhc2UgVG9rZW4uTFBBUkVOOlxuICAgICAgICAgICAgcmV0dXJuIHBhcnNlVW5pb25UeXBlKCk7XG5cbiAgICAgICAgY2FzZSBUb2tlbi5MQlJBQ0s6XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VBcnJheVR5cGUoKTtcblxuICAgICAgICBjYXNlIFRva2VuLkxCUkFDRTpcbiAgICAgICAgICAgIHJldHVybiBwYXJzZVJlY29yZFR5cGUoKTtcblxuICAgICAgICBjYXNlIFRva2VuLk5BTUU6XG4gICAgICAgICAgICBpZiAodmFsdWUgPT09ICdudWxsJykge1xuICAgICAgICAgICAgICAgIGNvbnN1bWUoVG9rZW4uTkFNRSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogU3ludGF4Lk51bGxMaXRlcmFsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHZhbHVlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIGNvbnN1bWUoVG9rZW4uTkFNRSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogU3ludGF4LlVuZGVmaW5lZExpdGVyYWxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb250ZXh0ID0gQ29udGV4dC5zYXZlKCk7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VGdW5jdGlvblR5cGUoKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQucmVzdG9yZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHBhcnNlVHlwZU5hbWUoKTtcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdXRpbGl0eS50aHJvd0Vycm9yKCd1bmV4cGVjdGVkIHRva2VuJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUeXBlRXhwcmVzc2lvbiA6PVxuICAgIC8vICAgICBCYXNpY1R5cGVFeHByZXNzaW9uXG4gICAgLy8gICB8ICc/JyBCYXNpY1R5cGVFeHByZXNzaW9uXG4gICAgLy8gICB8ICchJyBCYXNpY1R5cGVFeHByZXNzaW9uXG4gICAgLy8gICB8IEJhc2ljVHlwZUV4cHJlc3Npb24gJz8nXG4gICAgLy8gICB8IEJhc2ljVHlwZUV4cHJlc3Npb24gJyEnXG4gICAgLy8gICB8ICc/J1xuICAgIC8vICAgfCBCYXNpY1R5cGVFeHByZXNzaW9uICdbXSdcbiAgICBmdW5jdGlvbiBwYXJzZVR5cGVFeHByZXNzaW9uKCkge1xuICAgICAgICB2YXIgZXhwcjtcblxuICAgICAgICBpZiAodG9rZW4gPT09IFRva2VuLlFVRVNUSU9OKSB7XG4gICAgICAgICAgICBjb25zdW1lKFRva2VuLlFVRVNUSU9OKTtcbiAgICAgICAgICAgIGlmICh0b2tlbiA9PT0gVG9rZW4uQ09NTUEgfHwgdG9rZW4gPT09IFRva2VuLkVRVUFMIHx8IHRva2VuID09PSBUb2tlbi5SQlJBQ0UgfHxcbiAgICAgICAgICAgICAgICAgICAgdG9rZW4gPT09IFRva2VuLlJQQVJFTiB8fCB0b2tlbiA9PT0gVG9rZW4uUElQRSB8fCB0b2tlbiA9PT0gVG9rZW4uRU9GIHx8XG4gICAgICAgICAgICAgICAgICAgIHRva2VuID09PSBUb2tlbi5SQlJBQ0sgfHwgdG9rZW4gPT09IFRva2VuLkdUKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogU3ludGF4Lk51bGxhYmxlTGl0ZXJhbFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHR5cGU6IFN5bnRheC5OdWxsYWJsZVR5cGUsXG4gICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogcGFyc2VCYXNpY1R5cGVFeHByZXNzaW9uKCksXG4gICAgICAgICAgICAgICAgcHJlZml4OiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRva2VuID09PSBUb2tlbi5CQU5HKSB7XG4gICAgICAgICAgICBjb25zdW1lKFRva2VuLkJBTkcpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBTeW50YXguTm9uTnVsbGFibGVUeXBlLFxuICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IHBhcnNlQmFzaWNUeXBlRXhwcmVzc2lvbigpLFxuICAgICAgICAgICAgICAgIHByZWZpeDogdHJ1ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGV4cHIgPSBwYXJzZUJhc2ljVHlwZUV4cHJlc3Npb24oKTtcbiAgICAgICAgaWYgKHRva2VuID09PSBUb2tlbi5CQU5HKSB7XG4gICAgICAgICAgICBjb25zdW1lKFRva2VuLkJBTkcpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBTeW50YXguTm9uTnVsbGFibGVUeXBlLFxuICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGV4cHIsXG4gICAgICAgICAgICAgICAgcHJlZml4OiBmYWxzZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0b2tlbiA9PT0gVG9rZW4uUVVFU1RJT04pIHtcbiAgICAgICAgICAgIGNvbnN1bWUoVG9rZW4uUVVFU1RJT04pO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBTeW50YXguTnVsbGFibGVUeXBlLFxuICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGV4cHIsXG4gICAgICAgICAgICAgICAgcHJlZml4OiBmYWxzZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0b2tlbiA9PT0gVG9rZW4uTEJSQUNLKSB7XG4gICAgICAgICAgICBjb25zdW1lKFRva2VuLkxCUkFDSyk7XG4gICAgICAgICAgICBleHBlY3QoVG9rZW4uUkJSQUNLLCAnZXhwZWN0ZWQgYW4gYXJyYXktc3R5bGUgdHlwZSBkZWNsYXJhdGlvbiAoJyArIHZhbHVlICsgJ1tdKScpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBTeW50YXguVHlwZUFwcGxpY2F0aW9uLFxuICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogU3ludGF4Lk5hbWVFeHByZXNzaW9uLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiAnQXJyYXknXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBhcHBsaWNhdGlvbnM6IFtleHByXVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBleHByO1xuICAgIH1cblxuICAgIC8vIFRvcExldmVsVHlwZUV4cHJlc3Npb24gOj1cbiAgICAvLyAgICAgIFR5cGVFeHByZXNzaW9uXG4gICAgLy8gICAgfCBUeXBlVW5pb25MaXN0XG4gICAgLy9cbiAgICAvLyBUaGlzIHJ1bGUgaXMgR29vZ2xlIENsb3N1cmUgQ29tcGlsZXIgZXh0ZW5zaW9uLCBub3QgRVM0XG4gICAgLy8gbGlrZSxcbiAgICAvLyAgIHsgbnVtYmVyIHwgc3RyaW5nIH1cbiAgICAvLyBJZiBzdHJpY3QgdG8gRVM0LCB3ZSBzaG91bGQgd3JpdGUgaXQgYXNcbiAgICAvLyAgIHsgKG51bWJlcnxzdHJpbmcpIH1cbiAgICBmdW5jdGlvbiBwYXJzZVRvcCgpIHtcbiAgICAgICAgdmFyIGV4cHIsIGVsZW1lbnRzO1xuXG4gICAgICAgIGV4cHIgPSBwYXJzZVR5cGVFeHByZXNzaW9uKCk7XG4gICAgICAgIGlmICh0b2tlbiAhPT0gVG9rZW4uUElQRSkge1xuICAgICAgICAgICAgcmV0dXJuIGV4cHI7XG4gICAgICAgIH1cblxuICAgICAgICBlbGVtZW50cyA9IFsgZXhwciBdO1xuICAgICAgICBjb25zdW1lKFRva2VuLlBJUEUpO1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgZWxlbWVudHMucHVzaChwYXJzZVR5cGVFeHByZXNzaW9uKCkpO1xuICAgICAgICAgICAgaWYgKHRva2VuICE9PSBUb2tlbi5QSVBFKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdW1lKFRva2VuLlBJUEUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IFN5bnRheC5VbmlvblR5cGUsXG4gICAgICAgICAgICBlbGVtZW50czogZWxlbWVudHNcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZVRvcFBhcmFtVHlwZSgpIHtcbiAgICAgICAgdmFyIGV4cHI7XG5cbiAgICAgICAgaWYgKHRva2VuID09PSBUb2tlbi5SRVNUKSB7XG4gICAgICAgICAgICBjb25zdW1lKFRva2VuLlJFU1QpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBTeW50YXguUmVzdFR5cGUsXG4gICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogcGFyc2VUb3AoKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGV4cHIgPSBwYXJzZVRvcCgpO1xuICAgICAgICBpZiAodG9rZW4gPT09IFRva2VuLkVRVUFMKSB7XG4gICAgICAgICAgICBjb25zdW1lKFRva2VuLkVRVUFMKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdHlwZTogU3ludGF4Lk9wdGlvbmFsVHlwZSxcbiAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBleHByXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGV4cHI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VUeXBlKHNyYywgb3B0KSB7XG4gICAgICAgIHZhciBleHByO1xuXG4gICAgICAgIHNvdXJjZSA9IHNyYztcbiAgICAgICAgbGVuZ3RoID0gc291cmNlLmxlbmd0aDtcbiAgICAgICAgaW5kZXggPSAwO1xuICAgICAgICBwcmV2aW91cyA9IDA7XG5cbiAgICAgICAgbmV4dCgpO1xuICAgICAgICBleHByID0gcGFyc2VUb3AoKTtcblxuICAgICAgICBpZiAob3B0ICYmIG9wdC5taWRzdHJlYW0pIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogZXhwcixcbiAgICAgICAgICAgICAgICBpbmRleDogcHJldmlvdXNcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodG9rZW4gIT09IFRva2VuLkVPRikge1xuICAgICAgICAgICAgdXRpbGl0eS50aHJvd0Vycm9yKCdub3QgcmVhY2ggdG8gRU9GJyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZXhwcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZVBhcmFtVHlwZShzcmMsIG9wdCkge1xuICAgICAgICB2YXIgZXhwcjtcblxuICAgICAgICBzb3VyY2UgPSBzcmM7XG4gICAgICAgIGxlbmd0aCA9IHNvdXJjZS5sZW5ndGg7XG4gICAgICAgIGluZGV4ID0gMDtcbiAgICAgICAgcHJldmlvdXMgPSAwO1xuXG4gICAgICAgIG5leHQoKTtcbiAgICAgICAgZXhwciA9IHBhcnNlVG9wUGFyYW1UeXBlKCk7XG5cbiAgICAgICAgaWYgKG9wdCAmJiBvcHQubWlkc3RyZWFtKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGV4cHIsXG4gICAgICAgICAgICAgICAgaW5kZXg6IHByZXZpb3VzXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRva2VuICE9PSBUb2tlbi5FT0YpIHtcbiAgICAgICAgICAgIHV0aWxpdHkudGhyb3dFcnJvcignbm90IHJlYWNoIHRvIEVPRicpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGV4cHI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RyaW5naWZ5SW1wbChub2RlLCBjb21wYWN0LCB0b3BMZXZlbCkge1xuICAgICAgICB2YXIgcmVzdWx0LCBpLCBpejtcblxuICAgICAgICBzd2l0Y2ggKG5vZGUudHlwZSkge1xuICAgICAgICBjYXNlIFN5bnRheC5OdWxsYWJsZUxpdGVyYWw6XG4gICAgICAgICAgICByZXN1bHQgPSAnPyc7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFN5bnRheC5BbGxMaXRlcmFsOlxuICAgICAgICAgICAgcmVzdWx0ID0gJyonO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBTeW50YXguTnVsbExpdGVyYWw6XG4gICAgICAgICAgICByZXN1bHQgPSAnbnVsbCc7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFN5bnRheC5VbmRlZmluZWRMaXRlcmFsOlxuICAgICAgICAgICAgcmVzdWx0ID0gJ3VuZGVmaW5lZCc7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFN5bnRheC5Wb2lkTGl0ZXJhbDpcbiAgICAgICAgICAgIHJlc3VsdCA9ICd2b2lkJztcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgU3ludGF4LlVuaW9uVHlwZTpcbiAgICAgICAgICAgIGlmICghdG9wTGV2ZWwpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSAnKCc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9ICcnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBpeiA9IG5vZGUuZWxlbWVudHMubGVuZ3RoOyBpIDwgaXo7ICsraSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCArPSBzdHJpbmdpZnlJbXBsKG5vZGUuZWxlbWVudHNbaV0sIGNvbXBhY3QpO1xuICAgICAgICAgICAgICAgIGlmICgoaSArIDEpICE9PSBpeikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gJ3wnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCF0b3BMZXZlbCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCArPSAnKSc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFN5bnRheC5BcnJheVR5cGU6XG4gICAgICAgICAgICByZXN1bHQgPSAnWyc7XG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBpeiA9IG5vZGUuZWxlbWVudHMubGVuZ3RoOyBpIDwgaXo7ICsraSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCArPSBzdHJpbmdpZnlJbXBsKG5vZGUuZWxlbWVudHNbaV0sIGNvbXBhY3QpO1xuICAgICAgICAgICAgICAgIGlmICgoaSArIDEpICE9PSBpeikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gY29tcGFjdCA/ICcsJyA6ICcsICc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzdWx0ICs9ICddJztcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgU3ludGF4LlJlY29yZFR5cGU6XG4gICAgICAgICAgICByZXN1bHQgPSAneyc7XG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBpeiA9IG5vZGUuZmllbGRzLmxlbmd0aDsgaSA8IGl6OyArK2kpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gc3RyaW5naWZ5SW1wbChub2RlLmZpZWxkc1tpXSwgY29tcGFjdCk7XG4gICAgICAgICAgICAgICAgaWYgKChpICsgMSkgIT09IGl6KSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSBjb21wYWN0ID8gJywnIDogJywgJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXN1bHQgKz0gJ30nO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBTeW50YXguRmllbGRUeXBlOlxuICAgICAgICAgICAgaWYgKG5vZGUudmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBub2RlLmtleSArIChjb21wYWN0ID8gJzonIDogJzogJykgKyBzdHJpbmdpZnlJbXBsKG5vZGUudmFsdWUsIGNvbXBhY3QpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBub2RlLmtleTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgU3ludGF4LkZ1bmN0aW9uVHlwZTpcbiAgICAgICAgICAgIHJlc3VsdCA9IGNvbXBhY3QgPyAnZnVuY3Rpb24oJyA6ICdmdW5jdGlvbiAoJztcblxuICAgICAgICAgICAgaWYgKG5vZGVbJ3RoaXMnXSkge1xuICAgICAgICAgICAgICAgIGlmIChub2RlWyduZXcnXSkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gKGNvbXBhY3QgPyAnbmV3OicgOiAnbmV3OiAnKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gKGNvbXBhY3QgPyAndGhpczonIDogJ3RoaXM6ICcpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJlc3VsdCArPSBzdHJpbmdpZnlJbXBsKG5vZGVbJ3RoaXMnXSwgY29tcGFjdCk7XG5cbiAgICAgICAgICAgICAgICBpZiAobm9kZS5wYXJhbXMubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSBjb21wYWN0ID8gJywnIDogJywgJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGl6ID0gbm9kZS5wYXJhbXMubGVuZ3RoOyBpIDwgaXo7ICsraSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCArPSBzdHJpbmdpZnlJbXBsKG5vZGUucGFyYW1zW2ldLCBjb21wYWN0KTtcbiAgICAgICAgICAgICAgICBpZiAoKGkgKyAxKSAhPT0gaXopIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IGNvbXBhY3QgPyAnLCcgOiAnLCAnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmVzdWx0ICs9ICcpJztcblxuICAgICAgICAgICAgaWYgKG5vZGUucmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ICs9IChjb21wYWN0ID8gJzonIDogJzogJykgKyBzdHJpbmdpZnlJbXBsKG5vZGUucmVzdWx0LCBjb21wYWN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgU3ludGF4LlBhcmFtZXRlclR5cGU6XG4gICAgICAgICAgICByZXN1bHQgPSBub2RlLm5hbWUgKyAoY29tcGFjdCA/ICc6JyA6ICc6ICcpICsgc3RyaW5naWZ5SW1wbChub2RlLmV4cHJlc3Npb24sIGNvbXBhY3QpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBTeW50YXguUmVzdFR5cGU6XG4gICAgICAgICAgICByZXN1bHQgPSAnLi4uJztcbiAgICAgICAgICAgIGlmIChub2RlLmV4cHJlc3Npb24pIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gc3RyaW5naWZ5SW1wbChub2RlLmV4cHJlc3Npb24sIGNvbXBhY3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBTeW50YXguTm9uTnVsbGFibGVUeXBlOlxuICAgICAgICAgICAgaWYgKG5vZGUucHJlZml4KSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gJyEnICsgc3RyaW5naWZ5SW1wbChub2RlLmV4cHJlc3Npb24sIGNvbXBhY3QpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBzdHJpbmdpZnlJbXBsKG5vZGUuZXhwcmVzc2lvbiwgY29tcGFjdCkgKyAnISc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFN5bnRheC5PcHRpb25hbFR5cGU6XG4gICAgICAgICAgICByZXN1bHQgPSBzdHJpbmdpZnlJbXBsKG5vZGUuZXhwcmVzc2lvbiwgY29tcGFjdCkgKyAnPSc7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFN5bnRheC5OdWxsYWJsZVR5cGU6XG4gICAgICAgICAgICBpZiAobm9kZS5wcmVmaXgpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSAnPycgKyBzdHJpbmdpZnlJbXBsKG5vZGUuZXhwcmVzc2lvbiwgY29tcGFjdCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHN0cmluZ2lmeUltcGwobm9kZS5leHByZXNzaW9uLCBjb21wYWN0KSArICc/JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgU3ludGF4Lk5hbWVFeHByZXNzaW9uOlxuICAgICAgICAgICAgcmVzdWx0ID0gbm9kZS5uYW1lO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBTeW50YXguVHlwZUFwcGxpY2F0aW9uOlxuICAgICAgICAgICAgcmVzdWx0ID0gc3RyaW5naWZ5SW1wbChub2RlLmV4cHJlc3Npb24sIGNvbXBhY3QpICsgJy48JztcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGl6ID0gbm9kZS5hcHBsaWNhdGlvbnMubGVuZ3RoOyBpIDwgaXo7ICsraSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCArPSBzdHJpbmdpZnlJbXBsKG5vZGUuYXBwbGljYXRpb25zW2ldLCBjb21wYWN0KTtcbiAgICAgICAgICAgICAgICBpZiAoKGkgKyAxKSAhPT0gaXopIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IGNvbXBhY3QgPyAnLCcgOiAnLCAnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3VsdCArPSAnPic7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdXRpbGl0eS50aHJvd0Vycm9yKCdVbmtub3duIHR5cGUgJyArIG5vZGUudHlwZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN0cmluZ2lmeShub2RlLCBvcHRpb25zKSB7XG4gICAgICAgIGlmIChvcHRpb25zID09IG51bGwpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RyaW5naWZ5SW1wbChub2RlLCBvcHRpb25zLmNvbXBhY3QsIG9wdGlvbnMudG9wTGV2ZWwpO1xuICAgIH1cblxuICAgIGV4cG9ydHMucGFyc2VUeXBlID0gcGFyc2VUeXBlO1xuICAgIGV4cG9ydHMucGFyc2VQYXJhbVR5cGUgPSBwYXJzZVBhcmFtVHlwZTtcbiAgICBleHBvcnRzLnN0cmluZ2lmeSA9IHN0cmluZ2lmeTtcbiAgICBleHBvcnRzLlN5bnRheCA9IFN5bnRheDtcbn0oKSk7XG4vKiB2aW06IHNldCBzdz00IHRzPTQgZXQgdHc9ODAgOiAqL1xuIiwiLypcbiAgQ29weXJpZ2h0IChDKSAyMDE0IFl1c3VrZSBTdXp1a2kgPHV0YXRhbmUudGVhQGdtYWlsLmNvbT5cblxuICBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG5cbiAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cblxuICBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCA8Q09QWVJJR0hUIEhPTERFUj4gQkUgTElBQkxFIEZPUiBBTllcbiAgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuICBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5cbihmdW5jdGlvbiAoKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgdmFyIFZFUlNJT047XG5cbiAgICBWRVJTSU9OID0gcmVxdWlyZSgnLi4vcGFja2FnZS5qc29uJykudmVyc2lvbjtcbiAgICBleHBvcnRzLlZFUlNJT04gPSBWRVJTSU9OO1xuXG4gICAgZnVuY3Rpb24gRG9jdHJpbmVFcnJvcihtZXNzYWdlKSB7XG4gICAgICAgIHRoaXMubmFtZSA9ICdEb2N0cmluZUVycm9yJztcbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICB9XG4gICAgRG9jdHJpbmVFcnJvci5wcm90b3R5cGUgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgTWlkZGxlID0gZnVuY3Rpb24gKCkgeyB9O1xuICAgICAgICBNaWRkbGUucHJvdG90eXBlID0gRXJyb3IucHJvdG90eXBlO1xuICAgICAgICByZXR1cm4gbmV3IE1pZGRsZSgpO1xuICAgIH0oKSk7XG4gICAgRG9jdHJpbmVFcnJvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBEb2N0cmluZUVycm9yO1xuICAgIGV4cG9ydHMuRG9jdHJpbmVFcnJvciA9IERvY3RyaW5lRXJyb3I7XG5cbiAgICBmdW5jdGlvbiB0aHJvd0Vycm9yKG1lc3NhZ2UpIHtcbiAgICAgICAgdGhyb3cgbmV3IERvY3RyaW5lRXJyb3IobWVzc2FnZSk7XG4gICAgfVxuICAgIGV4cG9ydHMudGhyb3dFcnJvciA9IHRocm93RXJyb3I7XG5cbiAgICBleHBvcnRzLmFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpO1xufSgpKTtcblxuLyogdmltOiBzZXQgc3c9NCB0cz00IGV0IHR3PTgwIDogKi9cbiIsIi8qXG4gIENvcHlyaWdodCAoQykgMjAxMyBZdXN1a2UgU3V6dWtpIDx1dGF0YW5lLnRlYUBnbWFpbC5jb20+XG5cbiAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuXG4gICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiAgICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG5cbiAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyAnQVMgSVMnXG4gIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiAgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxuICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XG4gIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxuICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbihmdW5jdGlvbiAoKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgZnVuY3Rpb24gaXNFeHByZXNzaW9uKG5vZGUpIHtcbiAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgeyByZXR1cm4gZmFsc2U7IH1cbiAgICAgICAgc3dpdGNoIChub2RlLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ0FycmF5RXhwcmVzc2lvbic6XG4gICAgICAgICAgICBjYXNlICdBc3NpZ25tZW50RXhwcmVzc2lvbic6XG4gICAgICAgICAgICBjYXNlICdCaW5hcnlFeHByZXNzaW9uJzpcbiAgICAgICAgICAgIGNhc2UgJ0NhbGxFeHByZXNzaW9uJzpcbiAgICAgICAgICAgIGNhc2UgJ0NvbmRpdGlvbmFsRXhwcmVzc2lvbic6XG4gICAgICAgICAgICBjYXNlICdGdW5jdGlvbkV4cHJlc3Npb24nOlxuICAgICAgICAgICAgY2FzZSAnSWRlbnRpZmllcic6XG4gICAgICAgICAgICBjYXNlICdMaXRlcmFsJzpcbiAgICAgICAgICAgIGNhc2UgJ0xvZ2ljYWxFeHByZXNzaW9uJzpcbiAgICAgICAgICAgIGNhc2UgJ01lbWJlckV4cHJlc3Npb24nOlxuICAgICAgICAgICAgY2FzZSAnTmV3RXhwcmVzc2lvbic6XG4gICAgICAgICAgICBjYXNlICdPYmplY3RFeHByZXNzaW9uJzpcbiAgICAgICAgICAgIGNhc2UgJ1NlcXVlbmNlRXhwcmVzc2lvbic6XG4gICAgICAgICAgICBjYXNlICdUaGlzRXhwcmVzc2lvbic6XG4gICAgICAgICAgICBjYXNlICdVbmFyeUV4cHJlc3Npb24nOlxuICAgICAgICAgICAgY2FzZSAnVXBkYXRlRXhwcmVzc2lvbic6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzSXRlcmF0aW9uU3RhdGVtZW50KG5vZGUpIHtcbiAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkgeyByZXR1cm4gZmFsc2U7IH1cbiAgICAgICAgc3dpdGNoIChub2RlLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ0RvV2hpbGVTdGF0ZW1lbnQnOlxuICAgICAgICAgICAgY2FzZSAnRm9ySW5TdGF0ZW1lbnQnOlxuICAgICAgICAgICAgY2FzZSAnRm9yU3RhdGVtZW50JzpcbiAgICAgICAgICAgIGNhc2UgJ1doaWxlU3RhdGVtZW50JzpcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNTdGF0ZW1lbnQobm9kZSkge1xuICAgICAgICBpZiAobm9kZSA9PSBudWxsKSB7IHJldHVybiBmYWxzZTsgfVxuICAgICAgICBzd2l0Y2ggKG5vZGUudHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnQmxvY2tTdGF0ZW1lbnQnOlxuICAgICAgICAgICAgY2FzZSAnQnJlYWtTdGF0ZW1lbnQnOlxuICAgICAgICAgICAgY2FzZSAnQ29udGludWVTdGF0ZW1lbnQnOlxuICAgICAgICAgICAgY2FzZSAnRGVidWdnZXJTdGF0ZW1lbnQnOlxuICAgICAgICAgICAgY2FzZSAnRG9XaGlsZVN0YXRlbWVudCc6XG4gICAgICAgICAgICBjYXNlICdFbXB0eVN0YXRlbWVudCc6XG4gICAgICAgICAgICBjYXNlICdFeHByZXNzaW9uU3RhdGVtZW50JzpcbiAgICAgICAgICAgIGNhc2UgJ0ZvckluU3RhdGVtZW50JzpcbiAgICAgICAgICAgIGNhc2UgJ0ZvclN0YXRlbWVudCc6XG4gICAgICAgICAgICBjYXNlICdJZlN0YXRlbWVudCc6XG4gICAgICAgICAgICBjYXNlICdMYWJlbGVkU3RhdGVtZW50JzpcbiAgICAgICAgICAgIGNhc2UgJ1JldHVyblN0YXRlbWVudCc6XG4gICAgICAgICAgICBjYXNlICdTd2l0Y2hTdGF0ZW1lbnQnOlxuICAgICAgICAgICAgY2FzZSAnVGhyb3dTdGF0ZW1lbnQnOlxuICAgICAgICAgICAgY2FzZSAnVHJ5U3RhdGVtZW50JzpcbiAgICAgICAgICAgIGNhc2UgJ1ZhcmlhYmxlRGVjbGFyYXRpb24nOlxuICAgICAgICAgICAgY2FzZSAnV2hpbGVTdGF0ZW1lbnQnOlxuICAgICAgICAgICAgY2FzZSAnV2l0aFN0YXRlbWVudCc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzU291cmNlRWxlbWVudChub2RlKSB7XG4gICAgICByZXR1cm4gaXNTdGF0ZW1lbnQobm9kZSkgfHwgbm9kZSAhPSBudWxsICYmIG5vZGUudHlwZSA9PT0gJ0Z1bmN0aW9uRGVjbGFyYXRpb24nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRyYWlsaW5nU3RhdGVtZW50KG5vZGUpIHtcbiAgICAgICAgc3dpdGNoIChub2RlLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnSWZTdGF0ZW1lbnQnOlxuICAgICAgICAgICAgaWYgKG5vZGUuYWx0ZXJuYXRlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5hbHRlcm5hdGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5jb25zZXF1ZW50O1xuXG4gICAgICAgIGNhc2UgJ0xhYmVsZWRTdGF0ZW1lbnQnOlxuICAgICAgICBjYXNlICdGb3JTdGF0ZW1lbnQnOlxuICAgICAgICBjYXNlICdGb3JJblN0YXRlbWVudCc6XG4gICAgICAgIGNhc2UgJ1doaWxlU3RhdGVtZW50JzpcbiAgICAgICAgY2FzZSAnV2l0aFN0YXRlbWVudCc6XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5ib2R5O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzUHJvYmxlbWF0aWNJZlN0YXRlbWVudChub2RlKSB7XG4gICAgICAgIHZhciBjdXJyZW50O1xuXG4gICAgICAgIGlmIChub2RlLnR5cGUgIT09ICdJZlN0YXRlbWVudCcpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9kZS5hbHRlcm5hdGUgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnQgPSBub2RlLmNvbnNlcXVlbnQ7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50LnR5cGUgPT09ICdJZlN0YXRlbWVudCcpIHtcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudC5hbHRlcm5hdGUgPT0gbnVsbCkgIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3VycmVudCA9IHRyYWlsaW5nU3RhdGVtZW50KGN1cnJlbnQpO1xuICAgICAgICB9IHdoaWxlIChjdXJyZW50KTtcblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgbW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgICAgIGlzRXhwcmVzc2lvbjogaXNFeHByZXNzaW9uLFxuICAgICAgICBpc1N0YXRlbWVudDogaXNTdGF0ZW1lbnQsXG4gICAgICAgIGlzSXRlcmF0aW9uU3RhdGVtZW50OiBpc0l0ZXJhdGlvblN0YXRlbWVudCxcbiAgICAgICAgaXNTb3VyY2VFbGVtZW50OiBpc1NvdXJjZUVsZW1lbnQsXG4gICAgICAgIGlzUHJvYmxlbWF0aWNJZlN0YXRlbWVudDogaXNQcm9ibGVtYXRpY0lmU3RhdGVtZW50LFxuXG4gICAgICAgIHRyYWlsaW5nU3RhdGVtZW50OiB0cmFpbGluZ1N0YXRlbWVudFxuICAgIH07XG59KCkpO1xuLyogdmltOiBzZXQgc3c9NCB0cz00IGV0IHR3PTgwIDogKi9cbiIsIi8qXG4gIENvcHlyaWdodCAoQykgMjAxMy0yMDE0IFl1c3VrZSBTdXp1a2kgPHV0YXRhbmUudGVhQGdtYWlsLmNvbT5cbiAgQ29weXJpZ2h0IChDKSAyMDE0IEl2YW4gTmlrdWxpbiA8aWZhYWFuQGdtYWlsLmNvbT5cblxuICBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG5cbiAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cblxuICBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCA8Q09QWVJJR0hUIEhPTERFUj4gQkUgTElBQkxFIEZPUiBBTllcbiAgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuICBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG4oZnVuY3Rpb24gKCkge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIHZhciBSZWdleCwgTk9OX0FTQ0lJX1dISVRFU1BBQ0VTO1xuXG4gICAgLy8gU2VlIGB0b29scy9nZW5lcmF0ZS1pZGVudGlmaWVyLXJlZ2V4LmpzYC5cbiAgICBSZWdleCA9IHtcbiAgICAgICAgTm9uQXNjaWlJZGVudGlmaWVyU3RhcnQ6IG5ldyBSZWdFeHAoJ1tcXHhBQVxceEI1XFx4QkFcXHhDMC1cXHhENlxceEQ4LVxceEY2XFx4RjgtXFx1MDJDMVxcdTAyQzYtXFx1MDJEMVxcdTAyRTAtXFx1MDJFNFxcdTAyRUNcXHUwMkVFXFx1MDM3MC1cXHUwMzc0XFx1MDM3NlxcdTAzNzdcXHUwMzdBLVxcdTAzN0RcXHUwMzg2XFx1MDM4OC1cXHUwMzhBXFx1MDM4Q1xcdTAzOEUtXFx1MDNBMVxcdTAzQTMtXFx1MDNGNVxcdTAzRjctXFx1MDQ4MVxcdTA0OEEtXFx1MDUyN1xcdTA1MzEtXFx1MDU1NlxcdTA1NTlcXHUwNTYxLVxcdTA1ODdcXHUwNUQwLVxcdTA1RUFcXHUwNUYwLVxcdTA1RjJcXHUwNjIwLVxcdTA2NEFcXHUwNjZFXFx1MDY2RlxcdTA2NzEtXFx1MDZEM1xcdTA2RDVcXHUwNkU1XFx1MDZFNlxcdTA2RUVcXHUwNkVGXFx1MDZGQS1cXHUwNkZDXFx1MDZGRlxcdTA3MTBcXHUwNzEyLVxcdTA3MkZcXHUwNzRELVxcdTA3QTVcXHUwN0IxXFx1MDdDQS1cXHUwN0VBXFx1MDdGNFxcdTA3RjVcXHUwN0ZBXFx1MDgwMC1cXHUwODE1XFx1MDgxQVxcdTA4MjRcXHUwODI4XFx1MDg0MC1cXHUwODU4XFx1MDhBMFxcdTA4QTItXFx1MDhBQ1xcdTA5MDQtXFx1MDkzOVxcdTA5M0RcXHUwOTUwXFx1MDk1OC1cXHUwOTYxXFx1MDk3MS1cXHUwOTc3XFx1MDk3OS1cXHUwOTdGXFx1MDk4NS1cXHUwOThDXFx1MDk4RlxcdTA5OTBcXHUwOTkzLVxcdTA5QThcXHUwOUFBLVxcdTA5QjBcXHUwOUIyXFx1MDlCNi1cXHUwOUI5XFx1MDlCRFxcdTA5Q0VcXHUwOURDXFx1MDlERFxcdTA5REYtXFx1MDlFMVxcdTA5RjBcXHUwOUYxXFx1MEEwNS1cXHUwQTBBXFx1MEEwRlxcdTBBMTBcXHUwQTEzLVxcdTBBMjhcXHUwQTJBLVxcdTBBMzBcXHUwQTMyXFx1MEEzM1xcdTBBMzVcXHUwQTM2XFx1MEEzOFxcdTBBMzlcXHUwQTU5LVxcdTBBNUNcXHUwQTVFXFx1MEE3Mi1cXHUwQTc0XFx1MEE4NS1cXHUwQThEXFx1MEE4Ri1cXHUwQTkxXFx1MEE5My1cXHUwQUE4XFx1MEFBQS1cXHUwQUIwXFx1MEFCMlxcdTBBQjNcXHUwQUI1LVxcdTBBQjlcXHUwQUJEXFx1MEFEMFxcdTBBRTBcXHUwQUUxXFx1MEIwNS1cXHUwQjBDXFx1MEIwRlxcdTBCMTBcXHUwQjEzLVxcdTBCMjhcXHUwQjJBLVxcdTBCMzBcXHUwQjMyXFx1MEIzM1xcdTBCMzUtXFx1MEIzOVxcdTBCM0RcXHUwQjVDXFx1MEI1RFxcdTBCNUYtXFx1MEI2MVxcdTBCNzFcXHUwQjgzXFx1MEI4NS1cXHUwQjhBXFx1MEI4RS1cXHUwQjkwXFx1MEI5Mi1cXHUwQjk1XFx1MEI5OVxcdTBCOUFcXHUwQjlDXFx1MEI5RVxcdTBCOUZcXHUwQkEzXFx1MEJBNFxcdTBCQTgtXFx1MEJBQVxcdTBCQUUtXFx1MEJCOVxcdTBCRDBcXHUwQzA1LVxcdTBDMENcXHUwQzBFLVxcdTBDMTBcXHUwQzEyLVxcdTBDMjhcXHUwQzJBLVxcdTBDMzNcXHUwQzM1LVxcdTBDMzlcXHUwQzNEXFx1MEM1OFxcdTBDNTlcXHUwQzYwXFx1MEM2MVxcdTBDODUtXFx1MEM4Q1xcdTBDOEUtXFx1MEM5MFxcdTBDOTItXFx1MENBOFxcdTBDQUEtXFx1MENCM1xcdTBDQjUtXFx1MENCOVxcdTBDQkRcXHUwQ0RFXFx1MENFMFxcdTBDRTFcXHUwQ0YxXFx1MENGMlxcdTBEMDUtXFx1MEQwQ1xcdTBEMEUtXFx1MEQxMFxcdTBEMTItXFx1MEQzQVxcdTBEM0RcXHUwRDRFXFx1MEQ2MFxcdTBENjFcXHUwRDdBLVxcdTBEN0ZcXHUwRDg1LVxcdTBEOTZcXHUwRDlBLVxcdTBEQjFcXHUwREIzLVxcdTBEQkJcXHUwREJEXFx1MERDMC1cXHUwREM2XFx1MEUwMS1cXHUwRTMwXFx1MEUzMlxcdTBFMzNcXHUwRTQwLVxcdTBFNDZcXHUwRTgxXFx1MEU4MlxcdTBFODRcXHUwRTg3XFx1MEU4OFxcdTBFOEFcXHUwRThEXFx1MEU5NC1cXHUwRTk3XFx1MEU5OS1cXHUwRTlGXFx1MEVBMS1cXHUwRUEzXFx1MEVBNVxcdTBFQTdcXHUwRUFBXFx1MEVBQlxcdTBFQUQtXFx1MEVCMFxcdTBFQjJcXHUwRUIzXFx1MEVCRFxcdTBFQzAtXFx1MEVDNFxcdTBFQzZcXHUwRURDLVxcdTBFREZcXHUwRjAwXFx1MEY0MC1cXHUwRjQ3XFx1MEY0OS1cXHUwRjZDXFx1MEY4OC1cXHUwRjhDXFx1MTAwMC1cXHUxMDJBXFx1MTAzRlxcdTEwNTAtXFx1MTA1NVxcdTEwNUEtXFx1MTA1RFxcdTEwNjFcXHUxMDY1XFx1MTA2NlxcdTEwNkUtXFx1MTA3MFxcdTEwNzUtXFx1MTA4MVxcdTEwOEVcXHUxMEEwLVxcdTEwQzVcXHUxMEM3XFx1MTBDRFxcdTEwRDAtXFx1MTBGQVxcdTEwRkMtXFx1MTI0OFxcdTEyNEEtXFx1MTI0RFxcdTEyNTAtXFx1MTI1NlxcdTEyNThcXHUxMjVBLVxcdTEyNURcXHUxMjYwLVxcdTEyODhcXHUxMjhBLVxcdTEyOERcXHUxMjkwLVxcdTEyQjBcXHUxMkIyLVxcdTEyQjVcXHUxMkI4LVxcdTEyQkVcXHUxMkMwXFx1MTJDMi1cXHUxMkM1XFx1MTJDOC1cXHUxMkQ2XFx1MTJEOC1cXHUxMzEwXFx1MTMxMi1cXHUxMzE1XFx1MTMxOC1cXHUxMzVBXFx1MTM4MC1cXHUxMzhGXFx1MTNBMC1cXHUxM0Y0XFx1MTQwMS1cXHUxNjZDXFx1MTY2Ri1cXHUxNjdGXFx1MTY4MS1cXHUxNjlBXFx1MTZBMC1cXHUxNkVBXFx1MTZFRS1cXHUxNkYwXFx1MTcwMC1cXHUxNzBDXFx1MTcwRS1cXHUxNzExXFx1MTcyMC1cXHUxNzMxXFx1MTc0MC1cXHUxNzUxXFx1MTc2MC1cXHUxNzZDXFx1MTc2RS1cXHUxNzcwXFx1MTc4MC1cXHUxN0IzXFx1MTdEN1xcdTE3RENcXHUxODIwLVxcdTE4NzdcXHUxODgwLVxcdTE4QThcXHUxOEFBXFx1MThCMC1cXHUxOEY1XFx1MTkwMC1cXHUxOTFDXFx1MTk1MC1cXHUxOTZEXFx1MTk3MC1cXHUxOTc0XFx1MTk4MC1cXHUxOUFCXFx1MTlDMS1cXHUxOUM3XFx1MUEwMC1cXHUxQTE2XFx1MUEyMC1cXHUxQTU0XFx1MUFBN1xcdTFCMDUtXFx1MUIzM1xcdTFCNDUtXFx1MUI0QlxcdTFCODMtXFx1MUJBMFxcdTFCQUVcXHUxQkFGXFx1MUJCQS1cXHUxQkU1XFx1MUMwMC1cXHUxQzIzXFx1MUM0RC1cXHUxQzRGXFx1MUM1QS1cXHUxQzdEXFx1MUNFOS1cXHUxQ0VDXFx1MUNFRS1cXHUxQ0YxXFx1MUNGNVxcdTFDRjZcXHUxRDAwLVxcdTFEQkZcXHUxRTAwLVxcdTFGMTVcXHUxRjE4LVxcdTFGMURcXHUxRjIwLVxcdTFGNDVcXHUxRjQ4LVxcdTFGNERcXHUxRjUwLVxcdTFGNTdcXHUxRjU5XFx1MUY1QlxcdTFGNURcXHUxRjVGLVxcdTFGN0RcXHUxRjgwLVxcdTFGQjRcXHUxRkI2LVxcdTFGQkNcXHUxRkJFXFx1MUZDMi1cXHUxRkM0XFx1MUZDNi1cXHUxRkNDXFx1MUZEMC1cXHUxRkQzXFx1MUZENi1cXHUxRkRCXFx1MUZFMC1cXHUxRkVDXFx1MUZGMi1cXHUxRkY0XFx1MUZGNi1cXHUxRkZDXFx1MjA3MVxcdTIwN0ZcXHUyMDkwLVxcdTIwOUNcXHUyMTAyXFx1MjEwN1xcdTIxMEEtXFx1MjExM1xcdTIxMTVcXHUyMTE5LVxcdTIxMURcXHUyMTI0XFx1MjEyNlxcdTIxMjhcXHUyMTJBLVxcdTIxMkRcXHUyMTJGLVxcdTIxMzlcXHUyMTNDLVxcdTIxM0ZcXHUyMTQ1LVxcdTIxNDlcXHUyMTRFXFx1MjE2MC1cXHUyMTg4XFx1MkMwMC1cXHUyQzJFXFx1MkMzMC1cXHUyQzVFXFx1MkM2MC1cXHUyQ0U0XFx1MkNFQi1cXHUyQ0VFXFx1MkNGMlxcdTJDRjNcXHUyRDAwLVxcdTJEMjVcXHUyRDI3XFx1MkQyRFxcdTJEMzAtXFx1MkQ2N1xcdTJENkZcXHUyRDgwLVxcdTJEOTZcXHUyREEwLVxcdTJEQTZcXHUyREE4LVxcdTJEQUVcXHUyREIwLVxcdTJEQjZcXHUyREI4LVxcdTJEQkVcXHUyREMwLVxcdTJEQzZcXHUyREM4LVxcdTJEQ0VcXHUyREQwLVxcdTJERDZcXHUyREQ4LVxcdTJEREVcXHUyRTJGXFx1MzAwNS1cXHUzMDA3XFx1MzAyMS1cXHUzMDI5XFx1MzAzMS1cXHUzMDM1XFx1MzAzOC1cXHUzMDNDXFx1MzA0MS1cXHUzMDk2XFx1MzA5RC1cXHUzMDlGXFx1MzBBMS1cXHUzMEZBXFx1MzBGQy1cXHUzMEZGXFx1MzEwNS1cXHUzMTJEXFx1MzEzMS1cXHUzMThFXFx1MzFBMC1cXHUzMUJBXFx1MzFGMC1cXHUzMUZGXFx1MzQwMC1cXHU0REI1XFx1NEUwMC1cXHU5RkNDXFx1QTAwMC1cXHVBNDhDXFx1QTREMC1cXHVBNEZEXFx1QTUwMC1cXHVBNjBDXFx1QTYxMC1cXHVBNjFGXFx1QTYyQVxcdUE2MkJcXHVBNjQwLVxcdUE2NkVcXHVBNjdGLVxcdUE2OTdcXHVBNkEwLVxcdUE2RUZcXHVBNzE3LVxcdUE3MUZcXHVBNzIyLVxcdUE3ODhcXHVBNzhCLVxcdUE3OEVcXHVBNzkwLVxcdUE3OTNcXHVBN0EwLVxcdUE3QUFcXHVBN0Y4LVxcdUE4MDFcXHVBODAzLVxcdUE4MDVcXHVBODA3LVxcdUE4MEFcXHVBODBDLVxcdUE4MjJcXHVBODQwLVxcdUE4NzNcXHVBODgyLVxcdUE4QjNcXHVBOEYyLVxcdUE4RjdcXHVBOEZCXFx1QTkwQS1cXHVBOTI1XFx1QTkzMC1cXHVBOTQ2XFx1QTk2MC1cXHVBOTdDXFx1QTk4NC1cXHVBOUIyXFx1QTlDRlxcdUFBMDAtXFx1QUEyOFxcdUFBNDAtXFx1QUE0MlxcdUFBNDQtXFx1QUE0QlxcdUFBNjAtXFx1QUE3NlxcdUFBN0FcXHVBQTgwLVxcdUFBQUZcXHVBQUIxXFx1QUFCNVxcdUFBQjZcXHVBQUI5LVxcdUFBQkRcXHVBQUMwXFx1QUFDMlxcdUFBREItXFx1QUFERFxcdUFBRTAtXFx1QUFFQVxcdUFBRjItXFx1QUFGNFxcdUFCMDEtXFx1QUIwNlxcdUFCMDktXFx1QUIwRVxcdUFCMTEtXFx1QUIxNlxcdUFCMjAtXFx1QUIyNlxcdUFCMjgtXFx1QUIyRVxcdUFCQzAtXFx1QUJFMlxcdUFDMDAtXFx1RDdBM1xcdUQ3QjAtXFx1RDdDNlxcdUQ3Q0ItXFx1RDdGQlxcdUY5MDAtXFx1RkE2RFxcdUZBNzAtXFx1RkFEOVxcdUZCMDAtXFx1RkIwNlxcdUZCMTMtXFx1RkIxN1xcdUZCMURcXHVGQjFGLVxcdUZCMjhcXHVGQjJBLVxcdUZCMzZcXHVGQjM4LVxcdUZCM0NcXHVGQjNFXFx1RkI0MFxcdUZCNDFcXHVGQjQzXFx1RkI0NFxcdUZCNDYtXFx1RkJCMVxcdUZCRDMtXFx1RkQzRFxcdUZENTAtXFx1RkQ4RlxcdUZEOTItXFx1RkRDN1xcdUZERjAtXFx1RkRGQlxcdUZFNzAtXFx1RkU3NFxcdUZFNzYtXFx1RkVGQ1xcdUZGMjEtXFx1RkYzQVxcdUZGNDEtXFx1RkY1QVxcdUZGNjYtXFx1RkZCRVxcdUZGQzItXFx1RkZDN1xcdUZGQ0EtXFx1RkZDRlxcdUZGRDItXFx1RkZEN1xcdUZGREEtXFx1RkZEQ10nKSxcbiAgICAgICAgTm9uQXNjaWlJZGVudGlmaWVyUGFydDogbmV3IFJlZ0V4cCgnW1xceEFBXFx4QjVcXHhCQVxceEMwLVxceEQ2XFx4RDgtXFx4RjZcXHhGOC1cXHUwMkMxXFx1MDJDNi1cXHUwMkQxXFx1MDJFMC1cXHUwMkU0XFx1MDJFQ1xcdTAyRUVcXHUwMzAwLVxcdTAzNzRcXHUwMzc2XFx1MDM3N1xcdTAzN0EtXFx1MDM3RFxcdTAzODZcXHUwMzg4LVxcdTAzOEFcXHUwMzhDXFx1MDM4RS1cXHUwM0ExXFx1MDNBMy1cXHUwM0Y1XFx1MDNGNy1cXHUwNDgxXFx1MDQ4My1cXHUwNDg3XFx1MDQ4QS1cXHUwNTI3XFx1MDUzMS1cXHUwNTU2XFx1MDU1OVxcdTA1NjEtXFx1MDU4N1xcdTA1OTEtXFx1MDVCRFxcdTA1QkZcXHUwNUMxXFx1MDVDMlxcdTA1QzRcXHUwNUM1XFx1MDVDN1xcdTA1RDAtXFx1MDVFQVxcdTA1RjAtXFx1MDVGMlxcdTA2MTAtXFx1MDYxQVxcdTA2MjAtXFx1MDY2OVxcdTA2NkUtXFx1MDZEM1xcdTA2RDUtXFx1MDZEQ1xcdTA2REYtXFx1MDZFOFxcdTA2RUEtXFx1MDZGQ1xcdTA2RkZcXHUwNzEwLVxcdTA3NEFcXHUwNzRELVxcdTA3QjFcXHUwN0MwLVxcdTA3RjVcXHUwN0ZBXFx1MDgwMC1cXHUwODJEXFx1MDg0MC1cXHUwODVCXFx1MDhBMFxcdTA4QTItXFx1MDhBQ1xcdTA4RTQtXFx1MDhGRVxcdTA5MDAtXFx1MDk2M1xcdTA5NjYtXFx1MDk2RlxcdTA5NzEtXFx1MDk3N1xcdTA5NzktXFx1MDk3RlxcdTA5ODEtXFx1MDk4M1xcdTA5ODUtXFx1MDk4Q1xcdTA5OEZcXHUwOTkwXFx1MDk5My1cXHUwOUE4XFx1MDlBQS1cXHUwOUIwXFx1MDlCMlxcdTA5QjYtXFx1MDlCOVxcdTA5QkMtXFx1MDlDNFxcdTA5QzdcXHUwOUM4XFx1MDlDQi1cXHUwOUNFXFx1MDlEN1xcdTA5RENcXHUwOUREXFx1MDlERi1cXHUwOUUzXFx1MDlFNi1cXHUwOUYxXFx1MEEwMS1cXHUwQTAzXFx1MEEwNS1cXHUwQTBBXFx1MEEwRlxcdTBBMTBcXHUwQTEzLVxcdTBBMjhcXHUwQTJBLVxcdTBBMzBcXHUwQTMyXFx1MEEzM1xcdTBBMzVcXHUwQTM2XFx1MEEzOFxcdTBBMzlcXHUwQTNDXFx1MEEzRS1cXHUwQTQyXFx1MEE0N1xcdTBBNDhcXHUwQTRCLVxcdTBBNERcXHUwQTUxXFx1MEE1OS1cXHUwQTVDXFx1MEE1RVxcdTBBNjYtXFx1MEE3NVxcdTBBODEtXFx1MEE4M1xcdTBBODUtXFx1MEE4RFxcdTBBOEYtXFx1MEE5MVxcdTBBOTMtXFx1MEFBOFxcdTBBQUEtXFx1MEFCMFxcdTBBQjJcXHUwQUIzXFx1MEFCNS1cXHUwQUI5XFx1MEFCQy1cXHUwQUM1XFx1MEFDNy1cXHUwQUM5XFx1MEFDQi1cXHUwQUNEXFx1MEFEMFxcdTBBRTAtXFx1MEFFM1xcdTBBRTYtXFx1MEFFRlxcdTBCMDEtXFx1MEIwM1xcdTBCMDUtXFx1MEIwQ1xcdTBCMEZcXHUwQjEwXFx1MEIxMy1cXHUwQjI4XFx1MEIyQS1cXHUwQjMwXFx1MEIzMlxcdTBCMzNcXHUwQjM1LVxcdTBCMzlcXHUwQjNDLVxcdTBCNDRcXHUwQjQ3XFx1MEI0OFxcdTBCNEItXFx1MEI0RFxcdTBCNTZcXHUwQjU3XFx1MEI1Q1xcdTBCNURcXHUwQjVGLVxcdTBCNjNcXHUwQjY2LVxcdTBCNkZcXHUwQjcxXFx1MEI4MlxcdTBCODNcXHUwQjg1LVxcdTBCOEFcXHUwQjhFLVxcdTBCOTBcXHUwQjkyLVxcdTBCOTVcXHUwQjk5XFx1MEI5QVxcdTBCOUNcXHUwQjlFXFx1MEI5RlxcdTBCQTNcXHUwQkE0XFx1MEJBOC1cXHUwQkFBXFx1MEJBRS1cXHUwQkI5XFx1MEJCRS1cXHUwQkMyXFx1MEJDNi1cXHUwQkM4XFx1MEJDQS1cXHUwQkNEXFx1MEJEMFxcdTBCRDdcXHUwQkU2LVxcdTBCRUZcXHUwQzAxLVxcdTBDMDNcXHUwQzA1LVxcdTBDMENcXHUwQzBFLVxcdTBDMTBcXHUwQzEyLVxcdTBDMjhcXHUwQzJBLVxcdTBDMzNcXHUwQzM1LVxcdTBDMzlcXHUwQzNELVxcdTBDNDRcXHUwQzQ2LVxcdTBDNDhcXHUwQzRBLVxcdTBDNERcXHUwQzU1XFx1MEM1NlxcdTBDNThcXHUwQzU5XFx1MEM2MC1cXHUwQzYzXFx1MEM2Ni1cXHUwQzZGXFx1MEM4MlxcdTBDODNcXHUwQzg1LVxcdTBDOENcXHUwQzhFLVxcdTBDOTBcXHUwQzkyLVxcdTBDQThcXHUwQ0FBLVxcdTBDQjNcXHUwQ0I1LVxcdTBDQjlcXHUwQ0JDLVxcdTBDQzRcXHUwQ0M2LVxcdTBDQzhcXHUwQ0NBLVxcdTBDQ0RcXHUwQ0Q1XFx1MENENlxcdTBDREVcXHUwQ0UwLVxcdTBDRTNcXHUwQ0U2LVxcdTBDRUZcXHUwQ0YxXFx1MENGMlxcdTBEMDJcXHUwRDAzXFx1MEQwNS1cXHUwRDBDXFx1MEQwRS1cXHUwRDEwXFx1MEQxMi1cXHUwRDNBXFx1MEQzRC1cXHUwRDQ0XFx1MEQ0Ni1cXHUwRDQ4XFx1MEQ0QS1cXHUwRDRFXFx1MEQ1N1xcdTBENjAtXFx1MEQ2M1xcdTBENjYtXFx1MEQ2RlxcdTBEN0EtXFx1MEQ3RlxcdTBEODJcXHUwRDgzXFx1MEQ4NS1cXHUwRDk2XFx1MEQ5QS1cXHUwREIxXFx1MERCMy1cXHUwREJCXFx1MERCRFxcdTBEQzAtXFx1MERDNlxcdTBEQ0FcXHUwRENGLVxcdTBERDRcXHUwREQ2XFx1MEREOC1cXHUwRERGXFx1MERGMlxcdTBERjNcXHUwRTAxLVxcdTBFM0FcXHUwRTQwLVxcdTBFNEVcXHUwRTUwLVxcdTBFNTlcXHUwRTgxXFx1MEU4MlxcdTBFODRcXHUwRTg3XFx1MEU4OFxcdTBFOEFcXHUwRThEXFx1MEU5NC1cXHUwRTk3XFx1MEU5OS1cXHUwRTlGXFx1MEVBMS1cXHUwRUEzXFx1MEVBNVxcdTBFQTdcXHUwRUFBXFx1MEVBQlxcdTBFQUQtXFx1MEVCOVxcdTBFQkItXFx1MEVCRFxcdTBFQzAtXFx1MEVDNFxcdTBFQzZcXHUwRUM4LVxcdTBFQ0RcXHUwRUQwLVxcdTBFRDlcXHUwRURDLVxcdTBFREZcXHUwRjAwXFx1MEYxOFxcdTBGMTlcXHUwRjIwLVxcdTBGMjlcXHUwRjM1XFx1MEYzN1xcdTBGMzlcXHUwRjNFLVxcdTBGNDdcXHUwRjQ5LVxcdTBGNkNcXHUwRjcxLVxcdTBGODRcXHUwRjg2LVxcdTBGOTdcXHUwRjk5LVxcdTBGQkNcXHUwRkM2XFx1MTAwMC1cXHUxMDQ5XFx1MTA1MC1cXHUxMDlEXFx1MTBBMC1cXHUxMEM1XFx1MTBDN1xcdTEwQ0RcXHUxMEQwLVxcdTEwRkFcXHUxMEZDLVxcdTEyNDhcXHUxMjRBLVxcdTEyNERcXHUxMjUwLVxcdTEyNTZcXHUxMjU4XFx1MTI1QS1cXHUxMjVEXFx1MTI2MC1cXHUxMjg4XFx1MTI4QS1cXHUxMjhEXFx1MTI5MC1cXHUxMkIwXFx1MTJCMi1cXHUxMkI1XFx1MTJCOC1cXHUxMkJFXFx1MTJDMFxcdTEyQzItXFx1MTJDNVxcdTEyQzgtXFx1MTJENlxcdTEyRDgtXFx1MTMxMFxcdTEzMTItXFx1MTMxNVxcdTEzMTgtXFx1MTM1QVxcdTEzNUQtXFx1MTM1RlxcdTEzODAtXFx1MTM4RlxcdTEzQTAtXFx1MTNGNFxcdTE0MDEtXFx1MTY2Q1xcdTE2NkYtXFx1MTY3RlxcdTE2ODEtXFx1MTY5QVxcdTE2QTAtXFx1MTZFQVxcdTE2RUUtXFx1MTZGMFxcdTE3MDAtXFx1MTcwQ1xcdTE3MEUtXFx1MTcxNFxcdTE3MjAtXFx1MTczNFxcdTE3NDAtXFx1MTc1M1xcdTE3NjAtXFx1MTc2Q1xcdTE3NkUtXFx1MTc3MFxcdTE3NzJcXHUxNzczXFx1MTc4MC1cXHUxN0QzXFx1MTdEN1xcdTE3RENcXHUxN0REXFx1MTdFMC1cXHUxN0U5XFx1MTgwQi1cXHUxODBEXFx1MTgxMC1cXHUxODE5XFx1MTgyMC1cXHUxODc3XFx1MTg4MC1cXHUxOEFBXFx1MThCMC1cXHUxOEY1XFx1MTkwMC1cXHUxOTFDXFx1MTkyMC1cXHUxOTJCXFx1MTkzMC1cXHUxOTNCXFx1MTk0Ni1cXHUxOTZEXFx1MTk3MC1cXHUxOTc0XFx1MTk4MC1cXHUxOUFCXFx1MTlCMC1cXHUxOUM5XFx1MTlEMC1cXHUxOUQ5XFx1MUEwMC1cXHUxQTFCXFx1MUEyMC1cXHUxQTVFXFx1MUE2MC1cXHUxQTdDXFx1MUE3Ri1cXHUxQTg5XFx1MUE5MC1cXHUxQTk5XFx1MUFBN1xcdTFCMDAtXFx1MUI0QlxcdTFCNTAtXFx1MUI1OVxcdTFCNkItXFx1MUI3M1xcdTFCODAtXFx1MUJGM1xcdTFDMDAtXFx1MUMzN1xcdTFDNDAtXFx1MUM0OVxcdTFDNEQtXFx1MUM3RFxcdTFDRDAtXFx1MUNEMlxcdTFDRDQtXFx1MUNGNlxcdTFEMDAtXFx1MURFNlxcdTFERkMtXFx1MUYxNVxcdTFGMTgtXFx1MUYxRFxcdTFGMjAtXFx1MUY0NVxcdTFGNDgtXFx1MUY0RFxcdTFGNTAtXFx1MUY1N1xcdTFGNTlcXHUxRjVCXFx1MUY1RFxcdTFGNUYtXFx1MUY3RFxcdTFGODAtXFx1MUZCNFxcdTFGQjYtXFx1MUZCQ1xcdTFGQkVcXHUxRkMyLVxcdTFGQzRcXHUxRkM2LVxcdTFGQ0NcXHUxRkQwLVxcdTFGRDNcXHUxRkQ2LVxcdTFGREJcXHUxRkUwLVxcdTFGRUNcXHUxRkYyLVxcdTFGRjRcXHUxRkY2LVxcdTFGRkNcXHUyMDBDXFx1MjAwRFxcdTIwM0ZcXHUyMDQwXFx1MjA1NFxcdTIwNzFcXHUyMDdGXFx1MjA5MC1cXHUyMDlDXFx1MjBEMC1cXHUyMERDXFx1MjBFMVxcdTIwRTUtXFx1MjBGMFxcdTIxMDJcXHUyMTA3XFx1MjEwQS1cXHUyMTEzXFx1MjExNVxcdTIxMTktXFx1MjExRFxcdTIxMjRcXHUyMTI2XFx1MjEyOFxcdTIxMkEtXFx1MjEyRFxcdTIxMkYtXFx1MjEzOVxcdTIxM0MtXFx1MjEzRlxcdTIxNDUtXFx1MjE0OVxcdTIxNEVcXHUyMTYwLVxcdTIxODhcXHUyQzAwLVxcdTJDMkVcXHUyQzMwLVxcdTJDNUVcXHUyQzYwLVxcdTJDRTRcXHUyQ0VCLVxcdTJDRjNcXHUyRDAwLVxcdTJEMjVcXHUyRDI3XFx1MkQyRFxcdTJEMzAtXFx1MkQ2N1xcdTJENkZcXHUyRDdGLVxcdTJEOTZcXHUyREEwLVxcdTJEQTZcXHUyREE4LVxcdTJEQUVcXHUyREIwLVxcdTJEQjZcXHUyREI4LVxcdTJEQkVcXHUyREMwLVxcdTJEQzZcXHUyREM4LVxcdTJEQ0VcXHUyREQwLVxcdTJERDZcXHUyREQ4LVxcdTJEREVcXHUyREUwLVxcdTJERkZcXHUyRTJGXFx1MzAwNS1cXHUzMDA3XFx1MzAyMS1cXHUzMDJGXFx1MzAzMS1cXHUzMDM1XFx1MzAzOC1cXHUzMDNDXFx1MzA0MS1cXHUzMDk2XFx1MzA5OVxcdTMwOUFcXHUzMDlELVxcdTMwOUZcXHUzMEExLVxcdTMwRkFcXHUzMEZDLVxcdTMwRkZcXHUzMTA1LVxcdTMxMkRcXHUzMTMxLVxcdTMxOEVcXHUzMUEwLVxcdTMxQkFcXHUzMUYwLVxcdTMxRkZcXHUzNDAwLVxcdTREQjVcXHU0RTAwLVxcdTlGQ0NcXHVBMDAwLVxcdUE0OENcXHVBNEQwLVxcdUE0RkRcXHVBNTAwLVxcdUE2MENcXHVBNjEwLVxcdUE2MkJcXHVBNjQwLVxcdUE2NkZcXHVBNjc0LVxcdUE2N0RcXHVBNjdGLVxcdUE2OTdcXHVBNjlGLVxcdUE2RjFcXHVBNzE3LVxcdUE3MUZcXHVBNzIyLVxcdUE3ODhcXHVBNzhCLVxcdUE3OEVcXHVBNzkwLVxcdUE3OTNcXHVBN0EwLVxcdUE3QUFcXHVBN0Y4LVxcdUE4MjdcXHVBODQwLVxcdUE4NzNcXHVBODgwLVxcdUE4QzRcXHVBOEQwLVxcdUE4RDlcXHVBOEUwLVxcdUE4RjdcXHVBOEZCXFx1QTkwMC1cXHVBOTJEXFx1QTkzMC1cXHVBOTUzXFx1QTk2MC1cXHVBOTdDXFx1QTk4MC1cXHVBOUMwXFx1QTlDRi1cXHVBOUQ5XFx1QUEwMC1cXHVBQTM2XFx1QUE0MC1cXHVBQTREXFx1QUE1MC1cXHVBQTU5XFx1QUE2MC1cXHVBQTc2XFx1QUE3QVxcdUFBN0JcXHVBQTgwLVxcdUFBQzJcXHVBQURCLVxcdUFBRERcXHVBQUUwLVxcdUFBRUZcXHVBQUYyLVxcdUFBRjZcXHVBQjAxLVxcdUFCMDZcXHVBQjA5LVxcdUFCMEVcXHVBQjExLVxcdUFCMTZcXHVBQjIwLVxcdUFCMjZcXHVBQjI4LVxcdUFCMkVcXHVBQkMwLVxcdUFCRUFcXHVBQkVDXFx1QUJFRFxcdUFCRjAtXFx1QUJGOVxcdUFDMDAtXFx1RDdBM1xcdUQ3QjAtXFx1RDdDNlxcdUQ3Q0ItXFx1RDdGQlxcdUY5MDAtXFx1RkE2RFxcdUZBNzAtXFx1RkFEOVxcdUZCMDAtXFx1RkIwNlxcdUZCMTMtXFx1RkIxN1xcdUZCMUQtXFx1RkIyOFxcdUZCMkEtXFx1RkIzNlxcdUZCMzgtXFx1RkIzQ1xcdUZCM0VcXHVGQjQwXFx1RkI0MVxcdUZCNDNcXHVGQjQ0XFx1RkI0Ni1cXHVGQkIxXFx1RkJEMy1cXHVGRDNEXFx1RkQ1MC1cXHVGRDhGXFx1RkQ5Mi1cXHVGREM3XFx1RkRGMC1cXHVGREZCXFx1RkUwMC1cXHVGRTBGXFx1RkUyMC1cXHVGRTI2XFx1RkUzM1xcdUZFMzRcXHVGRTRELVxcdUZFNEZcXHVGRTcwLVxcdUZFNzRcXHVGRTc2LVxcdUZFRkNcXHVGRjEwLVxcdUZGMTlcXHVGRjIxLVxcdUZGM0FcXHVGRjNGXFx1RkY0MS1cXHVGRjVBXFx1RkY2Ni1cXHVGRkJFXFx1RkZDMi1cXHVGRkM3XFx1RkZDQS1cXHVGRkNGXFx1RkZEMi1cXHVGRkQ3XFx1RkZEQS1cXHVGRkRDXScpXG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGlzRGVjaW1hbERpZ2l0KGNoKSB7XG4gICAgICAgIHJldHVybiAoY2ggPj0gNDggJiYgY2ggPD0gNTcpOyAgIC8vIDAuLjlcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0hleERpZ2l0KGNoKSB7XG4gICAgICAgIHJldHVybiBpc0RlY2ltYWxEaWdpdChjaCkgfHwgICAgLy8gMC4uOVxuICAgICAgICAgICAgKDk3IDw9IGNoICYmIGNoIDw9IDEwMikgfHwgIC8vIGEuLmZcbiAgICAgICAgICAgICg2NSA8PSBjaCAmJiBjaCA8PSA3MCk7ICAgICAvLyBBLi5GXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNPY3RhbERpZ2l0KGNoKSB7XG4gICAgICAgIHJldHVybiAoY2ggPj0gNDggJiYgY2ggPD0gNTUpOyAgIC8vIDAuLjdcbiAgICB9XG5cbiAgICAvLyA3LjIgV2hpdGUgU3BhY2VcblxuICAgIE5PTl9BU0NJSV9XSElURVNQQUNFUyA9IFtcbiAgICAgICAgMHgxNjgwLCAweDE4MEUsXG4gICAgICAgIDB4MjAwMCwgMHgyMDAxLCAweDIwMDIsIDB4MjAwMywgMHgyMDA0LCAweDIwMDUsIDB4MjAwNiwgMHgyMDA3LCAweDIwMDgsIDB4MjAwOSwgMHgyMDBBLFxuICAgICAgICAweDIwMkYsIDB4MjA1RixcbiAgICAgICAgMHgzMDAwLFxuICAgICAgICAweEZFRkZcbiAgICBdO1xuXG4gICAgZnVuY3Rpb24gaXNXaGl0ZVNwYWNlKGNoKSB7XG4gICAgICAgIHJldHVybiAoY2ggPT09IDB4MjApIHx8IChjaCA9PT0gMHgwOSkgfHwgKGNoID09PSAweDBCKSB8fCAoY2ggPT09IDB4MEMpIHx8IChjaCA9PT0gMHhBMCkgfHxcbiAgICAgICAgICAgIChjaCA+PSAweDE2ODAgJiYgTk9OX0FTQ0lJX1dISVRFU1BBQ0VTLmluZGV4T2YoY2gpID49IDApO1xuICAgIH1cblxuICAgIC8vIDcuMyBMaW5lIFRlcm1pbmF0b3JzXG5cbiAgICBmdW5jdGlvbiBpc0xpbmVUZXJtaW5hdG9yKGNoKSB7XG4gICAgICAgIHJldHVybiAoY2ggPT09IDB4MEEpIHx8IChjaCA9PT0gMHgwRCkgfHwgKGNoID09PSAweDIwMjgpIHx8IChjaCA9PT0gMHgyMDI5KTtcbiAgICB9XG5cbiAgICAvLyA3LjYgSWRlbnRpZmllciBOYW1lcyBhbmQgSWRlbnRpZmllcnNcblxuICAgIGZ1bmN0aW9uIGlzSWRlbnRpZmllclN0YXJ0KGNoKSB7XG4gICAgICAgIHJldHVybiAoY2ggPj0gOTcgJiYgY2ggPD0gMTIyKSB8fCAgICAgLy8gYS4uelxuICAgICAgICAgICAgKGNoID49IDY1ICYmIGNoIDw9IDkwKSB8fCAgICAgICAgIC8vIEEuLlpcbiAgICAgICAgICAgIChjaCA9PT0gMzYpIHx8IChjaCA9PT0gOTUpIHx8ICAgICAvLyAkIChkb2xsYXIpIGFuZCBfICh1bmRlcnNjb3JlKVxuICAgICAgICAgICAgKGNoID09PSA5MikgfHwgICAgICAgICAgICAgICAgICAgIC8vIFxcIChiYWNrc2xhc2gpXG4gICAgICAgICAgICAoKGNoID49IDB4ODApICYmIFJlZ2V4Lk5vbkFzY2lpSWRlbnRpZmllclN0YXJ0LnRlc3QoU3RyaW5nLmZyb21DaGFyQ29kZShjaCkpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0lkZW50aWZpZXJQYXJ0KGNoKSB7XG4gICAgICAgIHJldHVybiAoY2ggPj0gOTcgJiYgY2ggPD0gMTIyKSB8fCAgICAgLy8gYS4uelxuICAgICAgICAgICAgKGNoID49IDY1ICYmIGNoIDw9IDkwKSB8fCAgICAgICAgIC8vIEEuLlpcbiAgICAgICAgICAgIChjaCA+PSA0OCAmJiBjaCA8PSA1NykgfHwgICAgICAgICAvLyAwLi45XG4gICAgICAgICAgICAoY2ggPT09IDM2KSB8fCAoY2ggPT09IDk1KSB8fCAgICAgLy8gJCAoZG9sbGFyKSBhbmQgXyAodW5kZXJzY29yZSlcbiAgICAgICAgICAgIChjaCA9PT0gOTIpIHx8ICAgICAgICAgICAgICAgICAgICAvLyBcXCAoYmFja3NsYXNoKVxuICAgICAgICAgICAgKChjaCA+PSAweDgwKSAmJiBSZWdleC5Ob25Bc2NpaUlkZW50aWZpZXJQYXJ0LnRlc3QoU3RyaW5nLmZyb21DaGFyQ29kZShjaCkpKTtcbiAgICB9XG5cbiAgICBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICAgICAgaXNEZWNpbWFsRGlnaXQ6IGlzRGVjaW1hbERpZ2l0LFxuICAgICAgICBpc0hleERpZ2l0OiBpc0hleERpZ2l0LFxuICAgICAgICBpc09jdGFsRGlnaXQ6IGlzT2N0YWxEaWdpdCxcbiAgICAgICAgaXNXaGl0ZVNwYWNlOiBpc1doaXRlU3BhY2UsXG4gICAgICAgIGlzTGluZVRlcm1pbmF0b3I6IGlzTGluZVRlcm1pbmF0b3IsXG4gICAgICAgIGlzSWRlbnRpZmllclN0YXJ0OiBpc0lkZW50aWZpZXJTdGFydCxcbiAgICAgICAgaXNJZGVudGlmaWVyUGFydDogaXNJZGVudGlmaWVyUGFydFxuICAgIH07XG59KCkpO1xuLyogdmltOiBzZXQgc3c9NCB0cz00IGV0IHR3PTgwIDogKi9cbiIsIi8qXG4gIENvcHlyaWdodCAoQykgMjAxMyBZdXN1a2UgU3V6dWtpIDx1dGF0YW5lLnRlYUBnbWFpbC5jb20+XG5cbiAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuXG4gICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiAgICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG5cbiAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4gIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcbiAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4gIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cblxuKGZ1bmN0aW9uICgpIHtcbiAgICAndXNlIHN0cmljdCc7XG5cbiAgICB2YXIgY29kZSA9IHJlcXVpcmUoJy4vY29kZScpO1xuXG4gICAgZnVuY3Rpb24gaXNTdHJpY3RNb2RlUmVzZXJ2ZWRXb3JkRVM2KGlkKSB7XG4gICAgICAgIHN3aXRjaCAoaWQpIHtcbiAgICAgICAgY2FzZSAnaW1wbGVtZW50cyc6XG4gICAgICAgIGNhc2UgJ2ludGVyZmFjZSc6XG4gICAgICAgIGNhc2UgJ3BhY2thZ2UnOlxuICAgICAgICBjYXNlICdwcml2YXRlJzpcbiAgICAgICAgY2FzZSAncHJvdGVjdGVkJzpcbiAgICAgICAgY2FzZSAncHVibGljJzpcbiAgICAgICAgY2FzZSAnc3RhdGljJzpcbiAgICAgICAgY2FzZSAnbGV0JzpcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNLZXl3b3JkRVM1KGlkLCBzdHJpY3QpIHtcbiAgICAgICAgLy8geWllbGQgc2hvdWxkIG5vdCBiZSB0cmVhdGVkIGFzIGtleXdvcmQgdW5kZXIgbm9uLXN0cmljdCBtb2RlLlxuICAgICAgICBpZiAoIXN0cmljdCAmJiBpZCA9PT0gJ3lpZWxkJykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpc0tleXdvcmRFUzYoaWQsIHN0cmljdCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNLZXl3b3JkRVM2KGlkLCBzdHJpY3QpIHtcbiAgICAgICAgaWYgKHN0cmljdCAmJiBpc1N0cmljdE1vZGVSZXNlcnZlZFdvcmRFUzYoaWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAoaWQubGVuZ3RoKSB7XG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgIHJldHVybiAoaWQgPT09ICdpZicpIHx8IChpZCA9PT0gJ2luJykgfHwgKGlkID09PSAnZG8nKTtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgcmV0dXJuIChpZCA9PT0gJ3ZhcicpIHx8IChpZCA9PT0gJ2ZvcicpIHx8IChpZCA9PT0gJ25ldycpIHx8IChpZCA9PT0gJ3RyeScpO1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICByZXR1cm4gKGlkID09PSAndGhpcycpIHx8IChpZCA9PT0gJ2Vsc2UnKSB8fCAoaWQgPT09ICdjYXNlJykgfHxcbiAgICAgICAgICAgICAgICAoaWQgPT09ICd2b2lkJykgfHwgKGlkID09PSAnd2l0aCcpIHx8IChpZCA9PT0gJ2VudW0nKTtcbiAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgcmV0dXJuIChpZCA9PT0gJ3doaWxlJykgfHwgKGlkID09PSAnYnJlYWsnKSB8fCAoaWQgPT09ICdjYXRjaCcpIHx8XG4gICAgICAgICAgICAgICAgKGlkID09PSAndGhyb3cnKSB8fCAoaWQgPT09ICdjb25zdCcpIHx8IChpZCA9PT0gJ3lpZWxkJykgfHxcbiAgICAgICAgICAgICAgICAoaWQgPT09ICdjbGFzcycpIHx8IChpZCA9PT0gJ3N1cGVyJyk7XG4gICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgIHJldHVybiAoaWQgPT09ICdyZXR1cm4nKSB8fCAoaWQgPT09ICd0eXBlb2YnKSB8fCAoaWQgPT09ICdkZWxldGUnKSB8fFxuICAgICAgICAgICAgICAgIChpZCA9PT0gJ3N3aXRjaCcpIHx8IChpZCA9PT0gJ2V4cG9ydCcpIHx8IChpZCA9PT0gJ2ltcG9ydCcpO1xuICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICByZXR1cm4gKGlkID09PSAnZGVmYXVsdCcpIHx8IChpZCA9PT0gJ2ZpbmFsbHknKSB8fCAoaWQgPT09ICdleHRlbmRzJyk7XG4gICAgICAgIGNhc2UgODpcbiAgICAgICAgICAgIHJldHVybiAoaWQgPT09ICdmdW5jdGlvbicpIHx8IChpZCA9PT0gJ2NvbnRpbnVlJykgfHwgKGlkID09PSAnZGVidWdnZXInKTtcbiAgICAgICAgY2FzZSAxMDpcbiAgICAgICAgICAgIHJldHVybiAoaWQgPT09ICdpbnN0YW5jZW9mJyk7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1Jlc2VydmVkV29yZEVTNShpZCwgc3RyaWN0KSB7XG4gICAgICAgIHJldHVybiBpZCA9PT0gJ251bGwnIHx8IGlkID09PSAndHJ1ZScgfHwgaWQgPT09ICdmYWxzZScgfHwgaXNLZXl3b3JkRVM1KGlkLCBzdHJpY3QpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzUmVzZXJ2ZWRXb3JkRVM2KGlkLCBzdHJpY3QpIHtcbiAgICAgICAgcmV0dXJuIGlkID09PSAnbnVsbCcgfHwgaWQgPT09ICd0cnVlJyB8fCBpZCA9PT0gJ2ZhbHNlJyB8fCBpc0tleXdvcmRFUzYoaWQsIHN0cmljdCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNSZXN0cmljdGVkV29yZChpZCkge1xuICAgICAgICByZXR1cm4gaWQgPT09ICdldmFsJyB8fCBpZCA9PT0gJ2FyZ3VtZW50cyc7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNJZGVudGlmaWVyTmFtZShpZCkge1xuICAgICAgICB2YXIgaSwgaXosIGNoO1xuXG4gICAgICAgIGlmIChpZC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNoID0gaWQuY2hhckNvZGVBdCgwKTtcbiAgICAgICAgaWYgKCFjb2RlLmlzSWRlbnRpZmllclN0YXJ0KGNoKSB8fCBjaCA9PT0gOTIpIHsgIC8vIFxcIChiYWNrc2xhc2gpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGkgPSAxLCBpeiA9IGlkLmxlbmd0aDsgaSA8IGl6OyArK2kpIHtcbiAgICAgICAgICAgIGNoID0gaWQuY2hhckNvZGVBdChpKTtcbiAgICAgICAgICAgIGlmICghY29kZS5pc0lkZW50aWZpZXJQYXJ0KGNoKSB8fCBjaCA9PT0gOTIpIHsgIC8vIFxcIChiYWNrc2xhc2gpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzSWRlbnRpZmllckVTNShpZCwgc3RyaWN0KSB7XG4gICAgICAgIHJldHVybiBpc0lkZW50aWZpZXJOYW1lKGlkKSAmJiAhaXNSZXNlcnZlZFdvcmRFUzUoaWQsIHN0cmljdCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNJZGVudGlmaWVyRVM2KGlkLCBzdHJpY3QpIHtcbiAgICAgICAgcmV0dXJuIGlzSWRlbnRpZmllck5hbWUoaWQpICYmICFpc1Jlc2VydmVkV29yZEVTNihpZCwgc3RyaWN0KTtcbiAgICB9XG5cbiAgICBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICAgICAgaXNLZXl3b3JkRVM1OiBpc0tleXdvcmRFUzUsXG4gICAgICAgIGlzS2V5d29yZEVTNjogaXNLZXl3b3JkRVM2LFxuICAgICAgICBpc1Jlc2VydmVkV29yZEVTNTogaXNSZXNlcnZlZFdvcmRFUzUsXG4gICAgICAgIGlzUmVzZXJ2ZWRXb3JkRVM2OiBpc1Jlc2VydmVkV29yZEVTNixcbiAgICAgICAgaXNSZXN0cmljdGVkV29yZDogaXNSZXN0cmljdGVkV29yZCxcbiAgICAgICAgaXNJZGVudGlmaWVyTmFtZTogaXNJZGVudGlmaWVyTmFtZSxcbiAgICAgICAgaXNJZGVudGlmaWVyRVM1OiBpc0lkZW50aWZpZXJFUzUsXG4gICAgICAgIGlzSWRlbnRpZmllckVTNjogaXNJZGVudGlmaWVyRVM2XG4gICAgfTtcbn0oKSk7XG4vKiB2aW06IHNldCBzdz00IHRzPTQgZXQgdHc9ODAgOiAqL1xuIiwiLypcbiAgQ29weXJpZ2h0IChDKSAyMDEzIFl1c3VrZSBTdXp1a2kgPHV0YXRhbmUudGVhQGdtYWlsLmNvbT5cblxuICBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG5cbiAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cblxuICBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCA8Q09QWVJJR0hUIEhPTERFUj4gQkUgTElBQkxFIEZPUiBBTllcbiAgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuICBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5cbihmdW5jdGlvbiAoKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgZXhwb3J0cy5hc3QgPSByZXF1aXJlKCcuL2FzdCcpO1xuICAgIGV4cG9ydHMuY29kZSA9IHJlcXVpcmUoJy4vY29kZScpO1xuICAgIGV4cG9ydHMua2V5d29yZCA9IHJlcXVpcmUoJy4va2V5d29yZCcpO1xufSgpKTtcbi8qIHZpbTogc2V0IHN3PTQgdHM9NCBldCB0dz04MCA6ICovXG4iLCJtb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFycikgPT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwibmFtZVwiOiBcImRvY3RyaW5lXCIsXG4gIFwiZGVzY3JpcHRpb25cIjogXCJKU0RvYyBwYXJzZXJcIixcbiAgXCJob21lcGFnZVwiOiBcImh0dHA6Ly9naXRodWIuY29tL0NvbnN0ZWxsYXRpb24vZG9jdHJpbmUuaHRtbFwiLFxuICBcIm1haW5cIjogXCJsaWIvZG9jdHJpbmUuanNcIixcbiAgXCJ2ZXJzaW9uXCI6IFwiMC42LjRcIixcbiAgXCJlbmdpbmVzXCI6IHtcbiAgICBcIm5vZGVcIjogXCI+PTAuMTAuMFwiXG4gIH0sXG4gIFwiZGlyZWN0b3JpZXNcIjoge1xuICAgIFwibGliXCI6IFwiLi9saWJcIlxuICB9LFxuICBcImZpbGVzXCI6IFtcbiAgICBcImxpYlwiLFxuICAgIFwiTElDRU5TRS5CU0RcIixcbiAgICBcIkxJQ0VOU0UuY2xvc3VyZS1jb21waWxlclwiLFxuICAgIFwiTElDRU5TRS5lc3ByaW1hXCIsXG4gICAgXCJSRUFETUUubWRcIlxuICBdLFxuICBcIm1haW50YWluZXJzXCI6IFtcbiAgICB7XG4gICAgICBcIm5hbWVcIjogXCJZdXN1a2UgU3V6dWtpXCIsXG4gICAgICBcImVtYWlsXCI6IFwidXRhdGFuZS50ZWFAZ21haWwuY29tXCIsXG4gICAgICBcInVybFwiOiBcImh0dHA6Ly9naXRodWIuY29tL0NvbnN0ZWxsYXRpb25cIlxuICAgIH1cbiAgXSxcbiAgXCJyZXBvc2l0b3J5XCI6IHtcbiAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICBcInVybFwiOiBcImh0dHA6Ly9naXRodWIuY29tL0NvbnN0ZWxsYXRpb24vZG9jdHJpbmUuZ2l0XCJcbiAgfSxcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiY292ZXJhbGxzXCI6IFwiXjIuMTEuMlwiLFxuICAgIFwiZ3VscFwiOiBcIl4zLjguMTBcIixcbiAgICBcImd1bHAtYnVtcFwiOiBcIl4wLjEuMTNcIixcbiAgICBcImd1bHAtZXNsaW50XCI6IFwiXjAuNS4wXCIsXG4gICAgXCJndWxwLWZpbHRlclwiOiBcIl4yLjAuMlwiLFxuICAgIFwiZ3VscC1naXRcIjogXCJeMS4wLjBcIixcbiAgICBcImd1bHAtaXN0YW5idWxcIjogXCJeMC42LjBcIixcbiAgICBcImd1bHAtanNoaW50XCI6IFwiXjEuOS4wXCIsXG4gICAgXCJndWxwLW1vY2hhXCI6IFwiXjIuMC4wXCIsXG4gICAgXCJndWxwLXRhZy12ZXJzaW9uXCI6IFwiXjEuMi4xXCIsXG4gICAgXCJqc2hpbnQtc3R5bGlzaFwiOiBcIl4xLjAuMFwiLFxuICAgIFwic2hvdWxkXCI6IFwiXjUuMC4xXCJcbiAgfSxcbiAgXCJsaWNlbnNlc1wiOiBbXG4gICAge1xuICAgICAgXCJ0eXBlXCI6IFwiQlNEXCIsXG4gICAgICBcInVybFwiOiBcImh0dHA6Ly9naXRodWIuY29tL0NvbnN0ZWxsYXRpb24vZG9jdHJpbmUvcmF3L21hc3Rlci9MSUNFTlNFLkJTRFwiXG4gICAgfVxuICBdLFxuICBcInNjcmlwdHNcIjoge1xuICAgIFwidGVzdFwiOiBcImd1bHBcIixcbiAgICBcInVuaXQtdGVzdFwiOiBcImd1bHAgdGVzdFwiLFxuICAgIFwibGludFwiOiBcImd1bHAgbGludFwiLFxuICAgIFwiY292ZXJhbGxzXCI6IFwiY2F0IC4vY292ZXJhZ2UvbGNvdi5pbmZvIHwgY292ZXJhbGxzICYmIHJtIC1yZiAuL2NvdmVyYWdlXCJcbiAgfSxcbiAgXCJkZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiZXN1dGlsc1wiOiBcIl4xLjEuNlwiLFxuICAgIFwiaXNhcnJheVwiOiBcIjAuMC4xXCJcbiAgfSxcbiAgXCJnaXRIZWFkXCI6IFwiNGY3NGM4NmVhNWNkMDNmYmQ5NDdjNGRmOTFhMjE5MmQxMzc3OWZiNVwiLFxuICBcInJlYWRtZVwiOiBcImRvY3RyaW5lIChbZG9jdHJpbmVdKGh0dHA6Ly9naXRodWIuY29tL0NvbnN0ZWxsYXRpb24vZG9jdHJpbmUpKSBpcyBKU0RvYyBwYXJzZXIuXFxuXFxuWyFbQnVpbGQgU3RhdHVzXShodHRwczovL3RyYXZpcy1jaS5vcmcvQ29uc3RlbGxhdGlvbi9kb2N0cmluZS5zdmc/YnJhbmNoPW1hc3RlcildKGh0dHBzOi8vdHJhdmlzLWNpLm9yZy9Db25zdGVsbGF0aW9uL2RvY3RyaW5lKVxcblshW0NvdmVyYWdlIFN0YXR1c10oaHR0cHM6Ly9pbWcuc2hpZWxkcy5pby9jb3ZlcmFsbHMvQ29uc3RlbGxhdGlvbi9kb2N0cmluZS5zdmcpXShodHRwczovL2NvdmVyYWxscy5pby9yL0NvbnN0ZWxsYXRpb24vZG9jdHJpbmU/YnJhbmNoPW1hc3RlcilcXG5bIVtEZXBlbmRlbmN5IFN0YXR1c10oaHR0cHM6Ly9kYXZpZC1kbS5vcmcvQ29uc3RlbGxhdGlvbi9kb2N0cmluZS5zdmcpXShodHRwczovL2RhdmlkLWRtLm9yZy9Db25zdGVsbGF0aW9uL2RvY3RyaW5lKVxcblshW2RldkRlcGVuZGVuY3kgU3RhdHVzXShodHRwczovL2RhdmlkLWRtLm9yZy9Db25zdGVsbGF0aW9uL2RvY3RyaW5lL2Rldi1zdGF0dXMuc3ZnKV0oaHR0cHM6Ly9kYXZpZC1kbS5vcmcvQ29uc3RlbGxhdGlvbi9kb2N0cmluZSNpbmZvPWRldkRlcGVuZGVuY2llcylcXG5bIVtHaXR0ZXIgY2hhdF0oaHR0cHM6Ly9iYWRnZXMuZ2l0dGVyLmltL0NvbnN0ZWxsYXRpb24vZG9jdHJpbmUucG5nKV0oaHR0cHM6Ly9naXR0ZXIuaW0vQ29uc3RlbGxhdGlvbi9kb2N0cmluZSlcXG5cXG5JdCBpcyBub3cgdXNlZCBieSBjb250ZW50IGFzc2lzdCBzeXN0ZW0gb2YgW0VjbGlwc2UgT3Jpb25dKGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvb3Jpb24vKSAoW2RldGFpbF0oaHR0cDovL3BsYW5ldG9yaW9uLm9yZy9uZXdzLzIwMTIvMTAvb3Jpb24tMS0wLXJlbGVhc2UvKSkuIEFuZCB1c2VkIGFzIEpTRG9jIHZhbGlkYXRvciBpbiBbRVNMaW50XShodHRwOi8vZXNsaW50Lm9yZy8pLlxcblxcbkRvY3RyaW5lIGNhbiBiZSB1c2VkIGluIGEgd2ViIGJyb3dzZXIgd2l0aCB1c2luZyBicm93c2VyaWZ5Llxcbm9yIGluIGEgTm9kZS5qcyBhcHBsaWNhdGlvbiB2aWEgdGhlIHBhY2thZ2UgbWFuYWdlcjpcXG5cXG4gICAgbnBtIGluc3RhbGwgZG9jdHJpbmVcXG5cXG5zaW1wbGUgZXhhbXBsZTpcXG5cXG4gICAgZG9jdHJpbmUucGFyc2UoXFxuICAgICAgICBbXFxuICAgICAgICAgICAgXFxcIi8qKlxcXCIsXFxuICAgICAgICAgICAgXFxcIiAqIFRoaXMgZnVuY3Rpb24gY29tbWVudCBpcyBwYXJzZWQgYnkgZG9jdHJpbmVcXFwiLFxcbiAgICAgICAgICAgIFxcXCIgKiBAcGFyYW0ge3tvazpTdHJpbmd9fSB1c2VyTmFtZVxcXCIsXFxuICAgICAgICAgICAgXFxcIiovXFxcIlxcbiAgICAgICAgXS5qb2luKCdcXFxcbicpLCB7IHVud3JhcDogdHJ1ZSB9KTtcXG5cXG5hbmQgZ2V0cyBmb2xsb3dpbmcgaW5mb3JtYXRpb25cXG5cXG4gICAge1xcbiAgICAgICAgXFxcImRlc2NyaXB0aW9uXFxcIjogXFxcIlRoaXMgZnVuY3Rpb24gY29tbWVudCBpcyBwYXJzZWQgYnkgZG9jdHJpbmVcXFwiLFxcbiAgICAgICAgXFxcInRhZ3NcXFwiOiBbXFxuICAgICAgICAgICAge1xcbiAgICAgICAgICAgICAgICBcXFwidGl0bGVcXFwiOiBcXFwicGFyYW1cXFwiLFxcbiAgICAgICAgICAgICAgICBcXFwiZGVzY3JpcHRpb25cXFwiOiBudWxsLFxcbiAgICAgICAgICAgICAgICBcXFwidHlwZVxcXCI6IHtcXG4gICAgICAgICAgICAgICAgICAgIFxcXCJ0eXBlXFxcIjogXFxcIlJlY29yZFR5cGVcXFwiLFxcbiAgICAgICAgICAgICAgICAgICAgXFxcImZpZWxkc1xcXCI6IFtcXG4gICAgICAgICAgICAgICAgICAgICAgICB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcXCJ0eXBlXFxcIjogXFxcIkZpZWxkVHlwZVxcXCIsXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcXCJrZXlcXFwiOiBcXFwib2tcXFwiLFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXFwidmFsdWVcXFwiOiB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXFwidHlwZVxcXCI6IFxcXCJOYW1lRXhwcmVzc2lvblxcXCIsXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXFwibmFtZVxcXCI6IFxcXCJTdHJpbmdcXFwiXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgICAgICBdXFxuICAgICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgICAgIFxcXCJuYW1lXFxcIjogXFxcInVzZXJOYW1lXFxcIlxcbiAgICAgICAgICAgIH1cXG4gICAgICAgIF1cXG4gICAgfVxcblxcbnNlZSBbZGVtbyBwYWdlXShodHRwOi8vY29uc3RlbGxhdGlvbi5naXRodWIuY29tL2RvY3RyaW5lL2RlbW8vaW5kZXguaHRtbCkgbW9yZSBkZXRhaWwuXFxuXFxuIyMjIE9wdGlvbnNcXG5cXG4jIyMjIGRvY3RyaW5lLnBhcnNlXFxuV2UgY2FuIHBhc3Mgb3B0aW9ucyB0byBgZG9jdHJpbmUucGFyc2UoY29tbWVudCwgb3B0aW9ucylgLlxcbmBgYGpzXFxue1xcbiAgICB1bndyYXA6IGJvb2xlYW4sICAgICAgICAgIC8vIGRlZmF1bHQ6IGZhbHNlXFxuICAgIHRhZ3M6IFsgc3RyaW5nIF0gfCBudWxsLCAgLy8gZGVmYXVsdDogbnVsbFxcbiAgICByZWNvdmVyYWJsZTogYm9vbGVhbiwgICAgIC8vIGRlZmF1bHQ6IGZhbHNlXFxuICAgIHNsb3BweTogYm9vbGVhbiwgICAgICAgICAgLy8gZGVmYXVsdDogZmFsc2VcXG4gICAgbGluZU51bWJlcnM6IGJvb2xlYW4gICAgICAvLyBkZWZhdWx0OiBmYWxzZVxcbn1cXG5gYGBcXG5cXG4jIyMjIyB1bndyYXBcXG5cXG5XaGVuIGB1bndyYXBgIGlzIGB0cnVlYCwgZG9jdHJpbmUgYXR0ZW1wdCB0byB1bndyYXAgY29tbWVudCBzcGVjaWZpYyBzdHJpbmcgZnJvbSBhIHByb3ZpZGVkIGNvbW1lbnQgdGV4dC4gKHJlbW92ZXMgYC8qKmAsIGAqL2AgYW5kIGAqYClcXG5Gb3IgZXhhbXBsZSwgYHVud3JhcGAgdHJhbnNmb3Jtc1xcbmBgYFxcbi8qKlxcbiAqIEBwYXJhbSB1c2VcXG4gKi9cXG5gYGBcXG50b1xcbmBgYFxcbkBwYXJhbSB1c2VcXG5gYGBcXG5JZiBhIHByb3ZpZGVkIGNvbW1lbnQgaGFzIHRoZXNlIGNvbW1lbnQgc3BlY2lmaWMgc3RyaW5ncywgeW91IG5lZWQgdG8gc3BlY2lmeSB0aGlzIGB1bndyYXBgIG9wdGlvbiB0byBgdHJ1ZWAuXFxuXFxuIyMjIyMgdGFnc1xcblxcbldoZW4gYHRhZ3NgIGFycmF5IGlzIHNwZWNpZmllZCwgZG9jdHJpbmUgb25seSBwcm9kdWNlIHRhZ3MgdGhhdCBpcyBzcGVjaWZpZWQgaW4gdGhpcyBhcnJheS5cXG5Gb3IgZXhhbXBsZSwgaWYgeW91IHNwZWNpZnkgYFsgJ3BhcmFtJyBdYCwgZG9jdHJpbmUgb25seSBwcm9kdWNlcyBgcGFyYW1gIHRhZ3MuXFxuSWYgbnVsbCBpcyBzcGVjaWZpZWQsIGRvY3RyaW5lIHByb2R1Y2VzIGFsbCB0YWdzIHRoYXQgZG9jdHJpbmUgY2FuIHJlY29nbml6ZS5cXG5cXG4jIyMjIyByZWNvdmVyYWJsZVxcblxcbldoZW4gYHJlY292ZXJhYmxlYCBpcyBgdHJ1ZWAsIGRvY3RyaW5lIGJlY29tZXMgYHJlY292ZXJhYmxlYCAtIFdoZW4gZmFpbGluZyB0byBwYXJzZSBqc2RvYyBjb21tZW50LCBkb2N0cmluZSByZWNvdmVycyBpdHMgc3RhdGUgYW5kIGF0dGVtcHQgdG8gY29udGludWUgcGFyc2luZy5cXG5cXG4jIyMjIyBzbG9wcHlcXG5cXG5XaGVuIGBzbG9wcHlgIGlzIGB0cnVlYCxcXG5gYGBcXG5AcGFyYW0gU3RyaW5nIFtmb29dXFxuYGBgXFxuJ3MgYFtmb29dYCBpcyBpbnRlcnByZXRlZCBhcyBhIG9wdGlvbmFsIHBhcmFtZXRlciwgbm90IGludGVycHJldGVkIGFzIGEgbmFtZSBvZiB0aGlzIGBAcGFyYW1gLlxcblxcbiMjIyMjIGxpbmVOdW1iZXJzXFxuXFxuV2hlbiBgbGluZU51bWJlcnNgIGlzIGB0cnVlYCwgcGFyc2VkIHRhZ3Mgd2lsbCBpbmNsdWRlIGEgYGxpbmVOdW1iZXJgIHByb3BlcnR5IGluZGljYXRpbmcgdGhlIGxpbmUgKHJlbGF0aXZlIHRvIHRoZSBzdGFydCBvZiB0aGUgY29tbWVudCBibG9jaykgd2hlcmUgZWFjaCB0YWcgaXMgbG9jYXRlZCBpbiB0aGUgc291cmNlLiBTbywgZ2l2ZW4gdGhlIGZvbGxvd2luZyBjb21tZW50OlxcbmBgYFxcbi8qKlxcbiAqIEBwYXJhbSB7U3RyaW5nfSBmb29cXG4gKiBAcmV0dXJuIHtudW1iZXJ9XFxuICovXFxuYGBgXFxuVGhlIGBAcGFyYW1gIHRhZyB3aWxsIGhhdmUgYGxpbmVOdW1iZXI6IDFgLCBhbmQgdGhlIGBAcmV0dXJuYCB0YWcgd2lsbCBoYXZlIGBsaW5lTnVtYmVyOiAyYC5cXG5cXG5cXG4jIyMgTGljZW5zZVxcblxcbiMjIyMgZG9jdHJpbmVcXG5cXG5Db3B5cmlnaHQgKEMpIDIwMTIgW1l1c3VrZSBTdXp1a2ldKGh0dHA6Ly9naXRodWIuY29tL0NvbnN0ZWxsYXRpb24pXFxuICh0d2l0dGVyOiBbQENvbnN0ZWxsYXRpb25dKGh0dHA6Ly90d2l0dGVyLmNvbS9Db25zdGVsbGF0aW9uKSkgYW5kIG90aGVyIGNvbnRyaWJ1dG9ycy5cXG5cXG5SZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcXG5tb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcXG5cXG4gICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcXG4gICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxcblxcbiAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxcbiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXFxuICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXFxuXFxuVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcXFwiQVMgSVNcXFwiXFxuQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxcbklNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXFxuQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxcbkRJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXFxuKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xcbkxPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxcbk9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXFxuKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXFxuVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cXG5cXG4jIyMjIGVzcHJpbWFcXG5cXG5zb21lIG9mIGZ1bmN0aW9ucyBpcyBkZXJpdmVkIGZyb20gZXNwcmltYVxcblxcbkNvcHlyaWdodCAoQykgMjAxMiwgMjAxMSBbQXJpeWEgSGlkYXlhdF0oaHR0cDovL2FyaXlhLm9maWxhYnMuY29tL2Fib3V0KVxcbiAodHdpdHRlcjogW0Bhcml5YWhpZGF5YXRdKGh0dHA6Ly90d2l0dGVyLmNvbS9hcml5YWhpZGF5YXQpKSBhbmQgb3RoZXIgY29udHJpYnV0b3JzLlxcblxcblJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxcbm1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxcblxcbiAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxcbiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXFxuXFxuICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0XFxuICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcXG4gICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cXG5cXG5USElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFxcXCJBUyBJU1xcXCJcXG5BTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXFxuSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcXG5BUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXFxuRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcXG4oSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XFxuTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXFxuT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcXG4oSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcXG5USElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxcblxcblxcbiMjIyMgY2xvc3VyZS1jb21waWxlclxcblxcbnNvbWUgb2YgZXh0ZW5zaW9ucyBpcyBkZXJpdmVkIGZyb20gY2xvc3VyZS1jb21waWxlclxcblxcbkFwYWNoZSBMaWNlbnNlXFxuVmVyc2lvbiAyLjAsIEphbnVhcnkgMjAwNFxcbmh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9cXG5cIixcbiAgXCJyZWFkbWVGaWxlbmFtZVwiOiBcIlJFQURNRS5tZFwiLFxuICBcImJ1Z3NcIjoge1xuICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL0NvbnN0ZWxsYXRpb24vZG9jdHJpbmUvaXNzdWVzXCJcbiAgfSxcbiAgXCJfaWRcIjogXCJkb2N0cmluZUAwLjYuNFwiLFxuICBcIl9zaGFzdW1cIjogXCI1YjhkNTM0NDEyYjQ5YjgxNzdiNTIwODJjZDk1ZGYzODBkZTM5MGFhXCIsXG4gIFwiX2Zyb21cIjogXCJnaXQ6Ly9naXRodWIuY29tL1BvbHltZXJMYWJzL2RvY3RyaW5lLmdpdCNtYXN0ZXJcIixcbiAgXCJfcmVzb2x2ZWRcIjogXCJnaXQ6Ly9naXRodWIuY29tL1BvbHltZXJMYWJzL2RvY3RyaW5lLmdpdCM0Zjc0Yzg2ZWE1Y2QwM2ZiZDk0N2M0ZGY5MWEyMTkyZDEzNzc5ZmI1XCIsXG4gIFwiX2Zyb21HaXRodWJcIjogdHJ1ZVxufVxuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IChjKSAyMDE1IFRoZSBQb2x5bWVyIFByb2plY3QgQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFRoaXMgY29kZSBtYXkgb25seSBiZSB1c2VkIHVuZGVyIHRoZSBCU0Qgc3R5bGUgbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vTElDRU5TRS50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgYXV0aG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0FVVEhPUlMudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGNvbnRyaWJ1dG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0NPTlRSSUJVVE9SUy50eHRcbiAqIENvZGUgZGlzdHJpYnV0ZWQgYnkgR29vZ2xlIGFzIHBhcnQgb2YgdGhlIHBvbHltZXIgcHJvamVjdCBpcyBhbHNvXG4gKiBzdWJqZWN0IHRvIGFuIGFkZGl0aW9uYWwgSVAgcmlnaHRzIGdyYW50IGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9QQVRFTlRTLnR4dFxuICovXG5cbi8vIGpzaGludCBub2RlOiB0cnVlXG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIGdldEF0dHJpYnV0ZUluZGV4KGVsZW1lbnQsIG5hbWUpIHtcbiAgaWYgKCFlbGVtZW50LmF0dHJzKSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG4gIHZhciBuID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGVsZW1lbnQuYXR0cnMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoZWxlbWVudC5hdHRyc1tpXS5uYW1lLnRvTG93ZXJDYXNlKCkgPT09IG4pIHtcbiAgICAgIHJldHVybiBpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gLTE7XG59XG5cbi8qKlxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZmYgW2VsZW1lbnRdIGhhcyB0aGUgYXR0cmlidXRlIFtuYW1lXSwgYGZhbHNlYFxuICogICBvdGhlcndpc2UuXG4gKi9cbmZ1bmN0aW9uIGhhc0F0dHJpYnV0ZShlbGVtZW50LCBuYW1lKSB7XG4gIHJldHVybiBnZXRBdHRyaWJ1dGVJbmRleChlbGVtZW50LCBuYW1lKSAhPT0gLTE7XG59XG5cbi8qKlxuICogQHJldHVybnMge3N0cmluZ3xudWxsfSBUaGUgc3RyaW5nIHZhbHVlIG9mIGF0dHJpYnV0ZSBgbmFtZWAsIG9yIGBudWxsYC5cbiAqL1xuZnVuY3Rpb24gZ2V0QXR0cmlidXRlKGVsZW1lbnQsIG5hbWUpIHtcbiAgdmFyIGkgPSBnZXRBdHRyaWJ1dGVJbmRleChlbGVtZW50LCBuYW1lKTtcbiAgaWYgKGkgPiAtMSkge1xuICAgIHJldHVybiBlbGVtZW50LmF0dHJzW2ldLnZhbHVlO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBzZXRBdHRyaWJ1dGUoZWxlbWVudCwgbmFtZSwgdmFsdWUpIHtcbiAgdmFyIGkgPSBnZXRBdHRyaWJ1dGVJbmRleChlbGVtZW50LCBuYW1lKTtcbiAgaWYgKGkgPiAtMSkge1xuICAgIGVsZW1lbnQuYXR0cnNbaV0udmFsdWUgPSB2YWx1ZTtcbiAgfSBlbHNlIHtcbiAgICBlbGVtZW50LmF0dHJzLnB1c2goe25hbWU6IG5hbWUsIHZhbHVlOiB2YWx1ZX0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUF0dHJpYnV0ZShlbGVtZW50LCBuYW1lKSB7XG4gIHZhciBpID0gZ2V0QXR0cmlidXRlSW5kZXgoZWxlbWVudCwgbmFtZSk7XG4gIGlmIChpID4gLTEpIHtcbiAgICBlbGVtZW50LmF0dHJzLnNwbGljZShpLCAxKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBoYXNUYWdOYW1lKG5hbWUpIHtcbiAgdmFyIG4gPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiBmdW5jdGlvbihub2RlKSB7XG4gICAgaWYgKCFub2RlLnRhZ05hbWUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIG5vZGUudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSBuO1xuICB9O1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiBgcmVnZXgubWF0Y2godGFnTmFtZSlgIGZpbmRzIGEgbWF0Y2guXG4gKlxuICogVGhpcyB3aWxsIHVzZSB0aGUgbG93ZXJjYXNlZCB0YWdOYW1lIGZvciBjb21wYXJpc29uLlxuICogXG4gKiBAcGFyYW0gIHtSZWdFeHB9IHJlZ2V4XG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBoYXNNYXRjaGluZ1RhZ05hbWUocmVnZXgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAoIW5vZGUudGFnTmFtZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gcmVnZXgudGVzdChub2RlLnRhZ05hbWUudG9Mb3dlckNhc2UoKSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGhhc0NsYXNzKG5hbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShub2RlLCAnY2xhc3MnKTtcbiAgICBpZiAoIWF0dHIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGF0dHIuc3BsaXQoJyAnKS5pbmRleE9mKG5hbWUpID4gLTE7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvbGxhcHNlVGV4dFJhbmdlKHBhcmVudCwgc3RhcnQsIGVuZCkge1xuICB2YXIgdGV4dCA9ICcnO1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPD0gZW5kOyBpKyspIHtcbiAgICB0ZXh0ICs9IGdldFRleHRDb250ZW50KHBhcmVudC5jaGlsZE5vZGVzW2ldKTtcbiAgfVxuICBwYXJlbnQuY2hpbGROb2Rlcy5zcGxpY2Uoc3RhcnQsIChlbmQgLSBzdGFydCkgKyAxKTtcbiAgaWYgKHRleHQpIHtcbiAgICB2YXIgdG4gPSBuZXdUZXh0Tm9kZSh0ZXh0KTtcbiAgICB0bi5wYXJlbnROb2RlID0gcGFyZW50O1xuICAgIHBhcmVudC5jaGlsZE5vZGVzLnNwbGljZShzdGFydCwgMCwgdG4pO1xuICB9XG59XG5cbi8qKlxuICogTm9ybWFsaXplIHRoZSB0ZXh0IGluc2lkZSBhbiBlbGVtZW50XG4gKlxuICogRXF1aXZhbGVudCB0byBgZWxlbWVudC5ub3JtYWxpemUoKWAgaW4gdGhlIGJyb3dzZXJcbiAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTm9kZS9ub3JtYWxpemVcbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplKG5vZGUpIHtcbiAgaWYgKCEoaXNFbGVtZW50KG5vZGUpIHx8IGlzRG9jdW1lbnQobm9kZSkgfHwgaXNEb2N1bWVudEZyYWdtZW50KG5vZGUpKSkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgdGV4dFJhbmdlU3RhcnQgPSAtMTtcbiAgZm9yICh2YXIgaSA9IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGggLSAxLCBuOyBpID49IDA7IGktLSkge1xuICAgIG4gPSBub2RlLmNoaWxkTm9kZXNbaV07XG4gICAgaWYgKGlzVGV4dE5vZGUobikpIHtcbiAgICAgIGlmICh0ZXh0UmFuZ2VTdGFydCA9PSAtMSkge1xuICAgICAgICB0ZXh0UmFuZ2VTdGFydCA9IGk7XG4gICAgICB9XG4gICAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgICAvLyBjb2xsYXBzZSBsZWFkaW5nIHRleHQgbm9kZXNcbiAgICAgICAgY29sbGFwc2VUZXh0UmFuZ2Uobm9kZSwgMCwgdGV4dFJhbmdlU3RhcnQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyByZWN1cnNlXG4gICAgICBub3JtYWxpemUobik7XG4gICAgICAvLyBjb2xsYXBzZSB0aGUgcmFuZ2UgYWZ0ZXIgdGhpcyBub2RlXG4gICAgICBpZiAodGV4dFJhbmdlU3RhcnQgPiAtMSkge1xuICAgICAgICBjb2xsYXBzZVRleHRSYW5nZShub2RlLCBpICsgMSwgdGV4dFJhbmdlU3RhcnQpO1xuICAgICAgICB0ZXh0UmFuZ2VTdGFydCA9IC0xO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJldHVybiB0aGUgdGV4dCB2YWx1ZSBvZiBhIG5vZGUgb3IgZWxlbWVudFxuICpcbiAqIEVxdWl2YWxlbnQgdG8gYG5vZGUudGV4dENvbnRlbnRgIGluIHRoZSBicm93c2VyXG4gKi9cbmZ1bmN0aW9uIGdldFRleHRDb250ZW50KG5vZGUpIHtcbiAgaWYgKGlzQ29tbWVudE5vZGUobm9kZSkpIHtcbiAgICByZXR1cm4gbm9kZS5kYXRhO1xuICB9XG4gIGlmIChpc1RleHROb2RlKG5vZGUpKSB7XG4gICAgcmV0dXJuIG5vZGUudmFsdWU7XG4gIH1cbiAgdmFyIHN1YnRyZWUgPSBub2RlV2Fsa0FsbChub2RlLCBpc1RleHROb2RlKTtcbiAgcmV0dXJuIHN1YnRyZWUubWFwKGdldFRleHRDb250ZW50KS5qb2luKCcnKTtcbn1cblxuLyoqXG4gKiBTZXQgdGhlIHRleHQgdmFsdWUgb2YgYSBub2RlIG9yIGVsZW1lbnRcbiAqXG4gKiBFcXVpdmFsZW50IHRvIGBub2RlLnRleHRDb250ZW50ID0gdmFsdWVgIGluIHRoZSBicm93c2VyXG4gKi9cbmZ1bmN0aW9uIHNldFRleHRDb250ZW50KG5vZGUsIHZhbHVlKSB7XG4gIGlmIChpc0NvbW1lbnROb2RlKG5vZGUpKSB7XG4gICAgbm9kZS5kYXRhID0gdmFsdWU7XG4gIH0gZWxzZSBpZiAoaXNUZXh0Tm9kZShub2RlKSkge1xuICAgIG5vZGUudmFsdWUgPSB2YWx1ZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgdG4gPSBuZXdUZXh0Tm9kZSh2YWx1ZSk7XG4gICAgdG4ucGFyZW50Tm9kZSA9IG5vZGU7XG4gICAgbm9kZS5jaGlsZE5vZGVzID0gW3RuXTtcbiAgfVxufVxuXG4vKipcbiAqIE1hdGNoIHRoZSB0ZXh0IGluc2lkZSBhbiBlbGVtZW50LCB0ZXh0bm9kZSwgb3IgY29tbWVudFxuICpcbiAqIE5vdGU6IG5vZGVXYWxrQWxsIHdpdGggaGFzVGV4dFZhbHVlIG1heSByZXR1cm4gYW4gdGV4dG5vZGUgYW5kIGl0cyBwYXJlbnQgaWZcbiAqIHRoZSB0ZXh0bm9kZSBpcyB0aGUgb25seSBjaGlsZCBpbiB0aGF0IHBhcmVudC5cbiAqL1xuZnVuY3Rpb24gaGFzVGV4dFZhbHVlKHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbihub2RlKSB7XG4gICAgcmV0dXJuIGdldFRleHRDb250ZW50KG5vZGUpID09PSB2YWx1ZTtcbiAgfTtcbn1cblxuLyoqXG4gKiBPUiBhbiBhcnJheSBvZiBwcmVkaWNhdGVzXG4gKi9cbmZ1bmN0aW9uIE9SKC8qIC4uLnJ1bGVzICovKSB7XG4gIHZhciBydWxlcyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICBydWxlc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24obm9kZSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcnVsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChydWxlc1tpXShub2RlKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xufVxuXG4vKipcbiAqIEFORCBhbiBhcnJheSBvZiBwcmVkaWNhdGVzXG4gKi9cbmZ1bmN0aW9uIEFORCgvKiAuLi5ydWxlcyAqLykge1xuICB2YXIgcnVsZXMgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgcnVsZXNbaV0gPSBhcmd1bWVudHNbaV07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJ1bGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIXJ1bGVzW2ldKG5vZGUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG59XG5cbi8qKlxuICogbmVnYXRlIGFuIGluZGl2aWR1YWwgcHJlZGljYXRlLCBvciBhIGdyb3VwIHdpdGggQU5EIG9yIE9SXG4gKi9cbmZ1bmN0aW9uIE5PVChwcmVkaWNhdGVGbikge1xuICByZXR1cm4gZnVuY3Rpb24obm9kZSkge1xuICAgIHJldHVybiAhcHJlZGljYXRlRm4obm9kZSk7XG4gIH07XG59XG5cbi8qKlxuICogUmV0dXJucyBhIHByZWRpY2F0ZSB0aGF0IG1hdGNoZXMgYW55IG5vZGUgd2l0aCBhIHBhcmVudCBtYXRjaGluZyBgcHJlZGljYXRlRm5gLlxuICovXG5mdW5jdGlvbiBwYXJlbnRNYXRjaGVzKHByZWRpY2F0ZUZuKSB7XG4gIHJldHVybiBmdW5jdGlvbihub2RlKSB7XG4gICAgdmFyIHBhcmVudCA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICB3aGlsZShwYXJlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHByZWRpY2F0ZUZuKHBhcmVudCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xufVxuXG5mdW5jdGlvbiBoYXNBdHRyKGF0dHIpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICByZXR1cm4gZ2V0QXR0cmlidXRlSW5kZXgobm9kZSwgYXR0cikgPiAtMTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gaGFzQXR0clZhbHVlKGF0dHIsIHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbihub2RlKSB7XG4gICAgcmV0dXJuIGdldEF0dHJpYnV0ZShub2RlLCBhdHRyKSA9PT0gdmFsdWU7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGlzRG9jdW1lbnQobm9kZSkge1xuICByZXR1cm4gbm9kZS5ub2RlTmFtZSA9PT0gJyNkb2N1bWVudCc7XG59XG5cbmZ1bmN0aW9uIGlzRG9jdW1lbnRGcmFnbWVudChub2RlKSB7XG4gIHJldHVybiBub2RlLm5vZGVOYW1lID09PSAnI2RvY3VtZW50LWZyYWdtZW50Jztcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50KG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUubm9kZU5hbWUgPT09IG5vZGUudGFnTmFtZTtcbn1cblxuZnVuY3Rpb24gaXNUZXh0Tm9kZShub2RlKSB7XG4gIHJldHVybiBub2RlLm5vZGVOYW1lID09PSAnI3RleHQnO1xufVxuXG5mdW5jdGlvbiBpc0NvbW1lbnROb2RlKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUubm9kZU5hbWUgPT09ICcjY29tbWVudCc7XG59XG5cbi8qKlxuICogQXBwbGllcyBgbWFwZm5gIHRvIGBub2RlYCBhbmQgdGhlIHRyZWUgYmVsb3cgYG5vZGVgLCByZXR1cm5pbmcgYSBmbGF0dGVuZWRcbiAqIGxpc3Qgb2YgcmVzdWx0cy5cbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5mdW5jdGlvbiB0cmVlTWFwKG5vZGUsIG1hcGZuKSB7XG4gIHZhciByZXN1bHRzID0gW107XG4gIG5vZGVXYWxrKG5vZGUsIGZ1bmN0aW9uKG5vZGUpe1xuICAgIHJlc3VsdHMgPSByZXN1bHRzLmNvbmNhdChtYXBmbihub2RlKSk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbi8qKlxuICogV2FsayB0aGUgdHJlZSBkb3duIGZyb20gYG5vZGVgLCBhcHBseWluZyB0aGUgYHByZWRpY2F0ZWAgZnVuY3Rpb24uXG4gKiBSZXR1cm4gdGhlIGZpcnN0IG5vZGUgdGhhdCBtYXRjaGVzIHRoZSBnaXZlbiBwcmVkaWNhdGUuXG4gKlxuICogQHJldHVybnMge05vZGV9IGBudWxsYCBpZiBubyBub2RlIG1hdGNoZXMsIHBhcnNlNSBub2RlIG9iamVjdCBpZiBhIG5vZGVcbiAqIG1hdGNoZXNcbiAqL1xuZnVuY3Rpb24gbm9kZVdhbGsobm9kZSwgcHJlZGljYXRlKSB7XG4gIGlmIChwcmVkaWNhdGUobm9kZSkpIHtcbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuICB2YXIgbWF0Y2ggPSBudWxsO1xuICBpZiAobm9kZS5jaGlsZE5vZGVzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2RlLmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIG1hdGNoID0gbm9kZVdhbGsobm9kZS5jaGlsZE5vZGVzW2ldLCBwcmVkaWNhdGUpO1xuICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gbWF0Y2g7XG59XG5cbi8qKlxuICogV2FsayB0aGUgdHJlZSBkb3duIGZyb20gYG5vZGVgLCBhcHBseWluZyB0aGUgYHByZWRpY2F0ZWAgZnVuY3Rpb24uXG4gKiBBbGwgbm9kZXMgbWF0Y2hpbmcgdGhlIHByZWRpY2F0ZSBmdW5jdGlvbiBmcm9tIGBub2RlYCB0byBsZWF2ZXMgd2lsbCBiZVxuICogcmV0dXJuZWQuXG4gKlxuICogQHJldHVybnMge0FycmF5W05vZGVdfVxuICovXG5mdW5jdGlvbiBub2RlV2Fsa0FsbChub2RlLCBwcmVkaWNhdGUsIG1hdGNoZXMpIHtcbiAgaWYgKCFtYXRjaGVzKSB7XG4gICAgbWF0Y2hlcyA9IFtdO1xuICB9XG4gIGlmIChwcmVkaWNhdGUobm9kZSkpIHtcbiAgICBtYXRjaGVzLnB1c2gobm9kZSk7XG4gIH1cbiAgaWYgKG5vZGUuY2hpbGROb2Rlcykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBub2RlV2Fsa0FsbChub2RlLmNoaWxkTm9kZXNbaV0sIHByZWRpY2F0ZSwgbWF0Y2hlcyk7XG4gICAgfVxuICB9XG4gIHJldHVybiBtYXRjaGVzO1xufVxuXG5mdW5jdGlvbiBfcmV2ZXJzZU5vZGVXYWxrQWxsKG5vZGUsIHByZWRpY2F0ZSwgbWF0Y2hlcykge1xuICBpZiAoIW1hdGNoZXMpIHtcbiAgICBtYXRjaGVzID0gW107XG4gIH1cbiAgaWYgKG5vZGUuY2hpbGROb2Rlcykge1xuICAgIGZvciAodmFyIGkgPSBub2RlLmNoaWxkTm9kZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIG5vZGVXYWxrQWxsKG5vZGUuY2hpbGROb2Rlc1tpXSwgcHJlZGljYXRlLCBtYXRjaGVzKTtcbiAgICB9XG4gIH1cbiAgaWYgKHByZWRpY2F0ZShub2RlKSkge1xuICAgIG1hdGNoZXMucHVzaChub2RlKTtcbiAgfVxuICByZXR1cm4gbWF0Y2hlcztcbn1cblxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIGBub2RlV2Fsa0FsbGAsIGJ1dCBvbmx5IHJldHVybnMgbm9kZXMgdGhhdCBhcmUgZWl0aGVyIFxuICogYW5jZXN0b3JzIG9yIGVhcmxpZXIgY291c2lucy9zaWJsaW5ncyBpbiB0aGUgZG9jdW1lbnQuXG4gKlxuICogTm9kZXMgYXJlIHJldHVybmVkIGluIHJldmVyc2UgZG9jdW1lbnQgb3JkZXIsIHN0YXJ0aW5nIGZyb20gYG5vZGVgLlxuICovXG5mdW5jdGlvbiBub2RlV2Fsa0FsbFByaW9yKG5vZGUsIHByZWRpY2F0ZSwgbWF0Y2hlcykge1xuICBpZiAoIW1hdGNoZXMpIHtcbiAgICBtYXRjaGVzID0gW107XG4gIH1cbiAgaWYgKHByZWRpY2F0ZShub2RlKSkge1xuICAgIG1hdGNoZXMucHVzaChub2RlKTtcbiAgfVxuICAvLyBTZWFyY2ggb3VyIGVhcmxpZXIgc2libGluZ3MgYW5kIHRoZWlyIGRlc2NlbmRlbnRzLlxuICB2YXIgcGFyZW50ID0gbm9kZS5wYXJlbnROb2RlO1xuICBpZiAocGFyZW50KSB7XG4gICAgdmFyIGlkeCA9IHBhcmVudC5jaGlsZE5vZGVzLmluZGV4T2Yobm9kZSk7XG4gICAgdmFyIHNpYmxpbmdzID0gcGFyZW50LmNoaWxkTm9kZXMuc2xpY2UoMCwgaWR4KTtcbiAgICBmb3IgKHZhciBpID0gc2libGluZ3MubGVuZ3RoLTE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBfcmV2ZXJzZU5vZGVXYWxrQWxsKHNpYmxpbmdzW2ldLCBwcmVkaWNhdGUsIG1hdGNoZXMpO1xuICAgIH1cbiAgICBub2RlV2Fsa0FsbFByaW9yKHBhcmVudCwgcHJlZGljYXRlLCBtYXRjaGVzKTtcbiAgfVxuICByZXR1cm4gbWF0Y2hlcztcbn1cblxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIGBub2RlV2Fsa2AsIGJ1dCBvbmx5IG1hdGNoZXMgZWxlbWVudHNcbiAqXG4gKiBAcmV0dXJucyB7RWxlbWVudH1cbiAqL1xuZnVuY3Rpb24gcXVlcnkobm9kZSwgcHJlZGljYXRlKSB7XG4gIHZhciBlbGVtZW50UHJlZGljYXRlID0gQU5EKGlzRWxlbWVudCwgcHJlZGljYXRlKTtcbiAgcmV0dXJuIG5vZGVXYWxrKG5vZGUsIGVsZW1lbnRQcmVkaWNhdGUpO1xufVxuXG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gYG5vZGVXYWxrQWxsYCwgYnV0IG9ubHkgbWF0Y2hlcyBlbGVtZW50c1xuICpcbiAqIEByZXR1cm4ge0FycmF5W0VsZW1lbnRdfVxuICovXG5mdW5jdGlvbiBxdWVyeUFsbChub2RlLCBwcmVkaWNhdGUsIG1hdGNoZXMpIHtcbiAgdmFyIGVsZW1lbnRQcmVkaWNhdGUgPSBBTkQoaXNFbGVtZW50LCBwcmVkaWNhdGUpO1xuICByZXR1cm4gbm9kZVdhbGtBbGwobm9kZSwgZWxlbWVudFByZWRpY2F0ZSwgbWF0Y2hlcyk7XG59XG5cbmZ1bmN0aW9uIG5ld1RleHROb2RlKHZhbHVlKSB7XG4gIHJldHVybiB7XG4gICAgbm9kZU5hbWU6ICcjdGV4dCcsXG4gICAgdmFsdWU6IHZhbHVlLFxuICAgIHBhcmVudE5vZGU6IG51bGxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbmV3Q29tbWVudE5vZGUoY29tbWVudCkge1xuICByZXR1cm4ge1xuICAgIG5vZGVOYW1lOiAnI2NvbW1lbnQnLFxuICAgIGRhdGE6IGNvbW1lbnQsXG4gICAgcGFyZW50Tm9kZTogbnVsbFxuICB9O1xufVxuXG5mdW5jdGlvbiBuZXdFbGVtZW50KHRhZ05hbWUsIG5hbWVzcGFjZSkge1xuICByZXR1cm4ge1xuICAgIG5vZGVOYW1lOiB0YWdOYW1lLFxuICAgIHRhZ05hbWU6IHRhZ05hbWUsXG4gICAgY2hpbGROb2RlczogW10sXG4gICAgbmFtZXNwYWNlVVJJOiBuYW1lc3BhY2UgfHwgJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwnLFxuICAgIGF0dHJzOiBbXSxcbiAgICBwYXJlbnROb2RlOiBudWxsLFxuICB9O1xufVxuXG5mdW5jdGlvbiByZXBsYWNlKG9sZE5vZGUsIG5ld05vZGUpIHtcbiAgaW5zZXJ0QmVmb3JlKG9sZE5vZGUucGFyZW50Tm9kZSwgb2xkTm9kZSwgbmV3Tm9kZSk7XG4gIHJlbW92ZShvbGROb2RlKTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlKG5vZGUpIHtcbiAgdmFyIHBhcmVudCA9IG5vZGUucGFyZW50Tm9kZTtcbiAgaWYgKHBhcmVudCkge1xuICAgIHZhciBpZHggPSBwYXJlbnQuY2hpbGROb2Rlcy5pbmRleE9mKG5vZGUpO1xuICAgIHBhcmVudC5jaGlsZE5vZGVzLnNwbGljZShpZHgsIDEpO1xuICB9XG4gIG5vZGUucGFyZW50Tm9kZSA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGluc2VydEJlZm9yZShwYXJlbnQsIG9sZE5vZGUsIG5ld05vZGUpIHtcbiAgcmVtb3ZlKG5ld05vZGUpO1xuICB2YXIgaWR4ID0gcGFyZW50LmNoaWxkTm9kZXMuaW5kZXhPZihvbGROb2RlKTtcbiAgcGFyZW50LmNoaWxkTm9kZXMuc3BsaWNlKGlkeCwgMCwgbmV3Tm9kZSk7XG4gIG5ld05vZGUucGFyZW50Tm9kZSA9IHBhcmVudDtcbn1cblxuZnVuY3Rpb24gYXBwZW5kKHBhcmVudCwgbm9kZSkge1xuICByZW1vdmUobm9kZSk7XG4gIHBhcmVudC5jaGlsZE5vZGVzLnB1c2gobm9kZSk7XG4gIG5vZGUucGFyZW50Tm9kZSA9IHBhcmVudDtcbn1cblxudmFyIHBhcnNlNSA9IHJlcXVpcmUoJ3BhcnNlNScpO1xuZnVuY3Rpb24gcGFyc2UodGV4dCwgb3B0aW9ucykge1xuICB2YXIgcGFyc2VyID0gbmV3IHBhcnNlNS5QYXJzZXIocGFyc2U1LlRyZWVBZGFwdGVycy5kZWZhdWx0LCBvcHRpb25zKTtcbiAgcmV0dXJuIHBhcnNlci5wYXJzZSh0ZXh0KTtcbn1cblxuZnVuY3Rpb24gcGFyc2VGcmFnbWVudCh0ZXh0KSB7XG4gIHZhciBwYXJzZXIgPSBuZXcgcGFyc2U1LlBhcnNlcigpO1xuICByZXR1cm4gcGFyc2VyLnBhcnNlRnJhZ21lbnQodGV4dCk7XG59XG5cbmZ1bmN0aW9uIHNlcmlhbGl6ZShhc3QpIHtcbiAgdmFyIHNlcmlhbGl6ZXIgPSBuZXcgcGFyc2U1LlNlcmlhbGl6ZXIoKTtcbiAgcmV0dXJuIHNlcmlhbGl6ZXIuc2VyaWFsaXplKGFzdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXRBdHRyaWJ1dGU6IGdldEF0dHJpYnV0ZSxcbiAgaGFzQXR0cmlidXRlOiBoYXNBdHRyaWJ1dGUsXG4gIHNldEF0dHJpYnV0ZTogc2V0QXR0cmlidXRlLFxuICByZW1vdmVBdHRyaWJ1dGU6IHJlbW92ZUF0dHJpYnV0ZSxcbiAgZ2V0VGV4dENvbnRlbnQ6IGdldFRleHRDb250ZW50LFxuICBzZXRUZXh0Q29udGVudDogc2V0VGV4dENvbnRlbnQsXG4gIHJlbW92ZTogcmVtb3ZlLFxuICByZXBsYWNlOiByZXBsYWNlLFxuICBhcHBlbmQ6IGFwcGVuZCxcbiAgaW5zZXJ0QmVmb3JlOiBpbnNlcnRCZWZvcmUsXG4gIG5vcm1hbGl6ZTogbm9ybWFsaXplLFxuICBpc0RvY3VtZW50OiBpc0RvY3VtZW50LFxuICBpc0RvY3VtZW50RnJhZ21lbnQ6IGlzRG9jdW1lbnRGcmFnbWVudCxcbiAgaXNFbGVtZW50OiBpc0VsZW1lbnQsXG4gIGlzVGV4dE5vZGU6IGlzVGV4dE5vZGUsXG4gIGlzQ29tbWVudE5vZGU6IGlzQ29tbWVudE5vZGUsXG4gIHF1ZXJ5OiBxdWVyeSxcbiAgcXVlcnlBbGw6IHF1ZXJ5QWxsLFxuICBub2RlV2Fsazogbm9kZVdhbGssXG4gIG5vZGVXYWxrQWxsOiBub2RlV2Fsa0FsbCxcbiAgbm9kZVdhbGtBbGxQcmlvcjogbm9kZVdhbGtBbGxQcmlvcixcbiAgdHJlZU1hcDogdHJlZU1hcCxcbiAgcHJlZGljYXRlczoge1xuICAgIGhhc0NsYXNzOiBoYXNDbGFzcyxcbiAgICBoYXNBdHRyOiBoYXNBdHRyLFxuICAgIGhhc0F0dHJWYWx1ZTogaGFzQXR0clZhbHVlLFxuICAgIGhhc01hdGNoaW5nVGFnTmFtZTogaGFzTWF0Y2hpbmdUYWdOYW1lLFxuICAgIGhhc1RhZ05hbWU6IGhhc1RhZ05hbWUsXG4gICAgaGFzVGV4dFZhbHVlOiBoYXNUZXh0VmFsdWUsXG4gICAgQU5EOiBBTkQsXG4gICAgT1I6IE9SLFxuICAgIE5PVDogTk9ULFxuICAgIHBhcmVudE1hdGNoZXM6IHBhcmVudE1hdGNoZXNcbiAgfSxcbiAgY29uc3RydWN0b3JzOiB7XG4gICAgdGV4dDogbmV3VGV4dE5vZGUsXG4gICAgY29tbWVudDogbmV3Q29tbWVudE5vZGUsXG4gICAgZWxlbWVudDogbmV3RWxlbWVudFxuICB9LFxuICBwYXJzZTogcGFyc2UsXG4gIHBhcnNlRnJhZ21lbnQ6IHBhcnNlRnJhZ21lbnQsXG4gIHNlcmlhbGl6ZTogc2VyaWFsaXplXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxuZXhwb3J0cy5QYXJzZXIgPSByZXF1aXJlKCcuL2xpYi90cmVlX2NvbnN0cnVjdGlvbi9wYXJzZXInKTtcclxuZXhwb3J0cy5TaW1wbGVBcGlQYXJzZXIgPSByZXF1aXJlKCcuL2xpYi9zaW1wbGVfYXBpL3NpbXBsZV9hcGlfcGFyc2VyJyk7XHJcbmV4cG9ydHMuVHJlZVNlcmlhbGl6ZXIgPVxyXG5leHBvcnRzLlNlcmlhbGl6ZXIgPSByZXF1aXJlKCcuL2xpYi9zZXJpYWxpemF0aW9uL3NlcmlhbGl6ZXInKTtcclxuZXhwb3J0cy5Kc0RvbVBhcnNlciA9IHJlcXVpcmUoJy4vbGliL2pzZG9tL2pzZG9tX3BhcnNlcicpO1xyXG5cclxuZXhwb3J0cy5UcmVlQWRhcHRlcnMgPSB7XHJcbiAgICBkZWZhdWx0OiByZXF1aXJlKCcuL2xpYi90cmVlX2FkYXB0ZXJzL2RlZmF1bHQnKSxcclxuICAgIGh0bWxwYXJzZXIyOiByZXF1aXJlKCcuL2xpYi90cmVlX2FkYXB0ZXJzL2h0bWxwYXJzZXIyJylcclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vL0NvbnN0XG52YXIgVkFMSURfRE9DVFlQRV9OQU1FID0gJ2h0bWwnLFxuICAgIFFVSVJLU19NT0RFX1NZU1RFTV9JRCA9ICdodHRwOi8vd3d3LmlibS5jb20vZGF0YS9kdGQvdjExL2libXhodG1sMS10cmFuc2l0aW9uYWwuZHRkJyxcbiAgICBRVUlSS1NfTU9ERV9QVUJMSUNfSURfUFJFRklYRVMgPSBbXG4gICAgICAgIFwiKy8vc2lsbWFyaWwvL2R0ZCBodG1sIHBybyB2MHIxMSAxOTk3MDEwMS8vZW5cIixcbiAgICAgICAgXCItLy9hZHZhc29mdCBsdGQvL2R0ZCBodG1sIDMuMCBhc3dlZGl0ICsgZXh0ZW5zaW9ucy8vZW5cIixcbiAgICAgICAgXCItLy9hcy8vZHRkIGh0bWwgMy4wIGFzd2VkaXQgKyBleHRlbnNpb25zLy9lblwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sIDIuMCBsZXZlbCAxLy9lblwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sIDIuMCBsZXZlbCAyLy9lblwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sIDIuMCBzdHJpY3QgbGV2ZWwgMS8vZW5cIixcbiAgICAgICAgXCItLy9pZXRmLy9kdGQgaHRtbCAyLjAgc3RyaWN0IGxldmVsIDIvL2VuXCIsXG4gICAgICAgIFwiLS8vaWV0Zi8vZHRkIGh0bWwgMi4wIHN0cmljdC8vZW5cIixcbiAgICAgICAgXCItLy9pZXRmLy9kdGQgaHRtbCAyLjAvL2VuXCIsXG4gICAgICAgIFwiLS8vaWV0Zi8vZHRkIGh0bWwgMi4xZS8vZW5cIixcbiAgICAgICAgXCItLy9pZXRmLy9kdGQgaHRtbCAzLjAvL2VuXCIsXG4gICAgICAgIFwiLS8vaWV0Zi8vZHRkIGh0bWwgMy4wLy9lbi8vXCIsXG4gICAgICAgIFwiLS8vaWV0Zi8vZHRkIGh0bWwgMy4yIGZpbmFsLy9lblwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sIDMuMi8vZW5cIixcbiAgICAgICAgXCItLy9pZXRmLy9kdGQgaHRtbCAzLy9lblwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sIGxldmVsIDAvL2VuXCIsXG4gICAgICAgIFwiLS8vaWV0Zi8vZHRkIGh0bWwgbGV2ZWwgMC8vZW4vLzIuMFwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sIGxldmVsIDEvL2VuXCIsXG4gICAgICAgIFwiLS8vaWV0Zi8vZHRkIGh0bWwgbGV2ZWwgMS8vZW4vLzIuMFwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sIGxldmVsIDIvL2VuXCIsXG4gICAgICAgIFwiLS8vaWV0Zi8vZHRkIGh0bWwgbGV2ZWwgMi8vZW4vLzIuMFwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sIGxldmVsIDMvL2VuXCIsXG4gICAgICAgIFwiLS8vaWV0Zi8vZHRkIGh0bWwgbGV2ZWwgMy8vZW4vLzMuMFwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sIHN0cmljdCBsZXZlbCAwLy9lblwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sIHN0cmljdCBsZXZlbCAwLy9lbi8vMi4wXCIsXG4gICAgICAgIFwiLS8vaWV0Zi8vZHRkIGh0bWwgc3RyaWN0IGxldmVsIDEvL2VuXCIsXG4gICAgICAgIFwiLS8vaWV0Zi8vZHRkIGh0bWwgc3RyaWN0IGxldmVsIDEvL2VuLy8yLjBcIixcbiAgICAgICAgXCItLy9pZXRmLy9kdGQgaHRtbCBzdHJpY3QgbGV2ZWwgMi8vZW5cIixcbiAgICAgICAgXCItLy9pZXRmLy9kdGQgaHRtbCBzdHJpY3QgbGV2ZWwgMi8vZW4vLzIuMFwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sIHN0cmljdCBsZXZlbCAzLy9lblwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sIHN0cmljdCBsZXZlbCAzLy9lbi8vMy4wXCIsXG4gICAgICAgIFwiLS8vaWV0Zi8vZHRkIGh0bWwgc3RyaWN0Ly9lblwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sIHN0cmljdC8vZW4vLzIuMFwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sIHN0cmljdC8vZW4vLzMuMFwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sLy9lblwiLFxuICAgICAgICBcIi0vL2lldGYvL2R0ZCBodG1sLy9lbi8vMi4wXCIsXG4gICAgICAgIFwiLS8vaWV0Zi8vZHRkIGh0bWwvL2VuLy8zLjBcIixcbiAgICAgICAgXCItLy9tZXRyaXVzLy9kdGQgbWV0cml1cyBwcmVzZW50YXRpb25hbC8vZW5cIixcbiAgICAgICAgXCItLy9taWNyb3NvZnQvL2R0ZCBpbnRlcm5ldCBleHBsb3JlciAyLjAgaHRtbCBzdHJpY3QvL2VuXCIsXG4gICAgICAgIFwiLS8vbWljcm9zb2Z0Ly9kdGQgaW50ZXJuZXQgZXhwbG9yZXIgMi4wIGh0bWwvL2VuXCIsXG4gICAgICAgIFwiLS8vbWljcm9zb2Z0Ly9kdGQgaW50ZXJuZXQgZXhwbG9yZXIgMi4wIHRhYmxlcy8vZW5cIixcbiAgICAgICAgXCItLy9taWNyb3NvZnQvL2R0ZCBpbnRlcm5ldCBleHBsb3JlciAzLjAgaHRtbCBzdHJpY3QvL2VuXCIsXG4gICAgICAgIFwiLS8vbWljcm9zb2Z0Ly9kdGQgaW50ZXJuZXQgZXhwbG9yZXIgMy4wIGh0bWwvL2VuXCIsXG4gICAgICAgIFwiLS8vbWljcm9zb2Z0Ly9kdGQgaW50ZXJuZXQgZXhwbG9yZXIgMy4wIHRhYmxlcy8vZW5cIixcbiAgICAgICAgXCItLy9uZXRzY2FwZSBjb21tLiBjb3JwLi8vZHRkIGh0bWwvL2VuXCIsXG4gICAgICAgIFwiLS8vbmV0c2NhcGUgY29tbS4gY29ycC4vL2R0ZCBzdHJpY3QgaHRtbC8vZW5cIixcbiAgICAgICAgXCItLy9vJ3JlaWxseSBhbmQgYXNzb2NpYXRlcy8vZHRkIGh0bWwgMi4wLy9lblwiLFxuICAgICAgICBcIi0vL28ncmVpbGx5IGFuZCBhc3NvY2lhdGVzLy9kdGQgaHRtbCBleHRlbmRlZCAxLjAvL2VuXCIsXG4gICAgICAgIFwiLS8vc3B5Z2xhc3MvL2R0ZCBodG1sIDIuMCBleHRlbmRlZC8vZW5cIixcbiAgICAgICAgXCItLy9zcS8vZHRkIGh0bWwgMi4wIGhvdG1ldGFsICsgZXh0ZW5zaW9ucy8vZW5cIixcbiAgICAgICAgXCItLy9zdW4gbWljcm9zeXN0ZW1zIGNvcnAuLy9kdGQgaG90amF2YSBodG1sLy9lblwiLFxuICAgICAgICBcIi0vL3N1biBtaWNyb3N5c3RlbXMgY29ycC4vL2R0ZCBob3RqYXZhIHN0cmljdCBodG1sLy9lblwiLFxuICAgICAgICBcIi0vL3czYy8vZHRkIGh0bWwgMyAxOTk1LTAzLTI0Ly9lblwiLFxuICAgICAgICBcIi0vL3czYy8vZHRkIGh0bWwgMy4yIGRyYWZ0Ly9lblwiLFxuICAgICAgICBcIi0vL3czYy8vZHRkIGh0bWwgMy4yIGZpbmFsLy9lblwiLFxuICAgICAgICBcIi0vL3czYy8vZHRkIGh0bWwgMy4yLy9lblwiLFxuICAgICAgICBcIi0vL3czYy8vZHRkIGh0bWwgMy4ycyBkcmFmdC8vZW5cIixcbiAgICAgICAgXCItLy93M2MvL2R0ZCBodG1sIDQuMCBmcmFtZXNldC8vZW5cIixcbiAgICAgICAgXCItLy93M2MvL2R0ZCBodG1sIDQuMCB0cmFuc2l0aW9uYWwvL2VuXCIsXG4gICAgICAgIFwiLS8vdzNjLy9kdGQgaHRtbCBleHBlcmltZW50YWwgMTk5NjA3MTIvL2VuXCIsXG4gICAgICAgIFwiLS8vdzNjLy9kdGQgaHRtbCBleHBlcmltZW50YWwgOTcwNDIxLy9lblwiLFxuICAgICAgICBcIi0vL3czYy8vZHRkIHczIGh0bWwvL2VuXCIsXG4gICAgICAgIFwiLS8vdzNvLy9kdGQgdzMgaHRtbCAzLjAvL2VuXCIsXG4gICAgICAgIFwiLS8vdzNvLy9kdGQgdzMgaHRtbCAzLjAvL2VuLy9cIixcbiAgICAgICAgXCItLy93ZWJ0ZWNocy8vZHRkIG1vemlsbGEgaHRtbCAyLjAvL2VuXCIsXG4gICAgICAgIFwiLS8vd2VidGVjaHMvL2R0ZCBtb3ppbGxhIGh0bWwvL2VuXCJcbiAgICBdLFxuICAgIFFVSVJLU19NT0RFX05PX1NZU1RFTV9JRF9QVUJMSUNfSURfUFJFRklYRVMgPSBbXG4gICAgICAgICctLy93M2MvL2R0ZCBodG1sIDQuMDEgZnJhbWVzZXQvLycsXG4gICAgICAgICctLy93M2MvL2R0ZCBodG1sIDQuMDEgdHJhbnNpdGlvbmFsLy8nXG4gICAgXSxcbiAgICBRVUlSS1NfTU9ERV9QVUJMSUNfSURTID0gW1xuICAgICAgICAnLS8vdzNvLy9kdGQgdzMgaHRtbCBzdHJpY3QgMy4wLy9lbi8vJyxcbiAgICAgICAgJy0vdzNjL2R0ZCBodG1sIDQuMCB0cmFuc2l0aW9uYWwvZW4nLFxuICAgICAgICAnaHRtbCdcbiAgICBdO1xuXG5cbi8vVXRpbHNcbmZ1bmN0aW9uIGVucXVvdGVEb2N0eXBlSWQoaWQpIHtcbiAgICB2YXIgcXVvdGUgPSBpZC5pbmRleE9mKCdcIicpICE9PSAtMSA/ICdcXCcnIDogJ1wiJztcblxuICAgIHJldHVybiBxdW90ZSArIGlkICsgcXVvdGU7XG59XG5cblxuLy9BUElcbmV4cG9ydHMuaXNRdWlya3MgPSBmdW5jdGlvbiAobmFtZSwgcHVibGljSWQsIHN5c3RlbUlkKSB7XG4gICAgaWYgKG5hbWUgIT09IFZBTElEX0RPQ1RZUEVfTkFNRSlcbiAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICBpZiAoc3lzdGVtSWQgJiYgc3lzdGVtSWQudG9Mb3dlckNhc2UoKSA9PT0gUVVJUktTX01PREVfU1lTVEVNX0lEKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIGlmIChwdWJsaWNJZCAhPT0gbnVsbCkge1xuICAgICAgICBwdWJsaWNJZCA9IHB1YmxpY0lkLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgICAgaWYgKFFVSVJLU19NT0RFX1BVQkxJQ19JRFMuaW5kZXhPZihwdWJsaWNJZCkgPiAtMSlcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgICAgIHZhciBwcmVmaXhlcyA9IFFVSVJLU19NT0RFX1BVQkxJQ19JRF9QUkVGSVhFUztcblxuICAgICAgICBpZiAoc3lzdGVtSWQgPT09IG51bGwpXG4gICAgICAgICAgICBwcmVmaXhlcyA9IHByZWZpeGVzLmNvbmNhdChRVUlSS1NfTU9ERV9OT19TWVNURU1fSURfUFVCTElDX0lEX1BSRUZJWEVTKTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByZWZpeGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAocHVibGljSWQuaW5kZXhPZihwcmVmaXhlc1tpXSkgPT09IDApXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG5leHBvcnRzLnNlcmlhbGl6ZUNvbnRlbnQgPSBmdW5jdGlvbiAobmFtZSwgcHVibGljSWQsIHN5c3RlbUlkKSB7XG4gICAgdmFyIHN0ciA9ICchRE9DVFlQRSAnICsgbmFtZTtcblxuICAgIGlmIChwdWJsaWNJZCAhPT0gbnVsbClcbiAgICAgICAgc3RyICs9ICcgUFVCTElDICcgKyBlbnF1b3RlRG9jdHlwZUlkKHB1YmxpY0lkKTtcblxuICAgIGVsc2UgaWYgKHN5c3RlbUlkICE9PSBudWxsKVxuICAgICAgICBzdHIgKz0gJyBTWVNURU0nO1xuXG4gICAgaWYgKHN5c3RlbUlkICE9PSBudWxsKVxuICAgICAgICBzdHIgKz0gJyAnICsgZW5xdW90ZURvY3R5cGVJZChzeXN0ZW1JZCk7XG5cbiAgICByZXR1cm4gc3RyO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBUb2tlbml6ZXIgPSByZXF1aXJlKCcuLi90b2tlbml6YXRpb24vdG9rZW5pemVyJyksXHJcbiAgICBIVE1MID0gcmVxdWlyZSgnLi9odG1sJyk7XHJcblxyXG4vL0FsaWFzZXNcclxudmFyICQgPSBIVE1MLlRBR19OQU1FUyxcclxuICAgIE5TID0gSFRNTC5OQU1FU1BBQ0VTLFxyXG4gICAgQVRUUlMgPSBIVE1MLkFUVFJTO1xyXG5cclxuXHJcbi8vTUlNRSB0eXBlc1xyXG52YXIgTUlNRV9UWVBFUyA9IHtcclxuICAgIFRFWFRfSFRNTDogJ3RleHQvaHRtbCcsXHJcbiAgICBBUFBMSUNBVElPTl9YTUw6ICdhcHBsaWNhdGlvbi94aHRtbCt4bWwnXHJcbn07XHJcblxyXG4vL0F0dHJpYnV0ZXNcclxudmFyIERFRklOSVRJT05fVVJMX0FUVFIgPSAnZGVmaW5pdGlvbnVybCcsXHJcbiAgICBBREpVU1RFRF9ERUZJTklUSU9OX1VSTF9BVFRSID0gJ2RlZmluaXRpb25VUkwnLFxyXG4gICAgU1ZHX0FUVFJTX0FESlVTVE1FTlRfTUFQID0ge1xyXG4gICAgICAgICdhdHRyaWJ1dGVuYW1lJzogJ2F0dHJpYnV0ZU5hbWUnLFxyXG4gICAgICAgICdhdHRyaWJ1dGV0eXBlJzogJ2F0dHJpYnV0ZVR5cGUnLFxyXG4gICAgICAgICdiYXNlZnJlcXVlbmN5JzogJ2Jhc2VGcmVxdWVuY3knLFxyXG4gICAgICAgICdiYXNlcHJvZmlsZSc6ICdiYXNlUHJvZmlsZScsXHJcbiAgICAgICAgJ2NhbGNtb2RlJzogJ2NhbGNNb2RlJyxcclxuICAgICAgICAnY2xpcHBhdGh1bml0cyc6ICdjbGlwUGF0aFVuaXRzJyxcclxuICAgICAgICAnY29udGVudHNjcmlwdHR5cGUnOiAnY29udGVudFNjcmlwdFR5cGUnLFxyXG4gICAgICAgICdjb250ZW50c3R5bGV0eXBlJzogJ2NvbnRlbnRTdHlsZVR5cGUnLFxyXG4gICAgICAgICdkaWZmdXNlY29uc3RhbnQnOiAnZGlmZnVzZUNvbnN0YW50JyxcclxuICAgICAgICAnZWRnZW1vZGUnOiAnZWRnZU1vZGUnLFxyXG4gICAgICAgICdleHRlcm5hbHJlc291cmNlc3JlcXVpcmVkJzogJ2V4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWQnLFxyXG4gICAgICAgICdmaWx0ZXJyZXMnOiAnZmlsdGVyUmVzJyxcclxuICAgICAgICAnZmlsdGVydW5pdHMnOiAnZmlsdGVyVW5pdHMnLFxyXG4gICAgICAgICdnbHlwaHJlZic6ICdnbHlwaFJlZicsXHJcbiAgICAgICAgJ2dyYWRpZW50dHJhbnNmb3JtJzogJ2dyYWRpZW50VHJhbnNmb3JtJyxcclxuICAgICAgICAnZ3JhZGllbnR1bml0cyc6ICdncmFkaWVudFVuaXRzJyxcclxuICAgICAgICAna2VybmVsbWF0cml4JzogJ2tlcm5lbE1hdHJpeCcsXHJcbiAgICAgICAgJ2tlcm5lbHVuaXRsZW5ndGgnOiAna2VybmVsVW5pdExlbmd0aCcsXHJcbiAgICAgICAgJ2tleXBvaW50cyc6ICdrZXlQb2ludHMnLFxyXG4gICAgICAgICdrZXlzcGxpbmVzJzogJ2tleVNwbGluZXMnLFxyXG4gICAgICAgICdrZXl0aW1lcyc6ICdrZXlUaW1lcycsXHJcbiAgICAgICAgJ2xlbmd0aGFkanVzdCc6ICdsZW5ndGhBZGp1c3QnLFxyXG4gICAgICAgICdsaW1pdGluZ2NvbmVhbmdsZSc6ICdsaW1pdGluZ0NvbmVBbmdsZScsXHJcbiAgICAgICAgJ21hcmtlcmhlaWdodCc6ICdtYXJrZXJIZWlnaHQnLFxyXG4gICAgICAgICdtYXJrZXJ1bml0cyc6ICdtYXJrZXJVbml0cycsXHJcbiAgICAgICAgJ21hcmtlcndpZHRoJzogJ21hcmtlcldpZHRoJyxcclxuICAgICAgICAnbWFza2NvbnRlbnR1bml0cyc6ICdtYXNrQ29udGVudFVuaXRzJyxcclxuICAgICAgICAnbWFza3VuaXRzJzogJ21hc2tVbml0cycsXHJcbiAgICAgICAgJ251bW9jdGF2ZXMnOiAnbnVtT2N0YXZlcycsXHJcbiAgICAgICAgJ3BhdGhsZW5ndGgnOiAncGF0aExlbmd0aCcsXHJcbiAgICAgICAgJ3BhdHRlcm5jb250ZW50dW5pdHMnOiAncGF0dGVybkNvbnRlbnRVbml0cycsXHJcbiAgICAgICAgJ3BhdHRlcm50cmFuc2Zvcm0nOiAncGF0dGVyblRyYW5zZm9ybScsXHJcbiAgICAgICAgJ3BhdHRlcm51bml0cyc6ICdwYXR0ZXJuVW5pdHMnLFxyXG4gICAgICAgICdwb2ludHNhdHgnOiAncG9pbnRzQXRYJyxcclxuICAgICAgICAncG9pbnRzYXR5JzogJ3BvaW50c0F0WScsXHJcbiAgICAgICAgJ3BvaW50c2F0eic6ICdwb2ludHNBdFonLFxyXG4gICAgICAgICdwcmVzZXJ2ZWFscGhhJzogJ3ByZXNlcnZlQWxwaGEnLFxyXG4gICAgICAgICdwcmVzZXJ2ZWFzcGVjdHJhdGlvJzogJ3ByZXNlcnZlQXNwZWN0UmF0aW8nLFxyXG4gICAgICAgICdwcmltaXRpdmV1bml0cyc6ICdwcmltaXRpdmVVbml0cycsXHJcbiAgICAgICAgJ3JlZngnOiAncmVmWCcsXHJcbiAgICAgICAgJ3JlZnknOiAncmVmWScsXHJcbiAgICAgICAgJ3JlcGVhdGNvdW50JzogJ3JlcGVhdENvdW50JyxcclxuICAgICAgICAncmVwZWF0ZHVyJzogJ3JlcGVhdER1cicsXHJcbiAgICAgICAgJ3JlcXVpcmVkZXh0ZW5zaW9ucyc6ICdyZXF1aXJlZEV4dGVuc2lvbnMnLFxyXG4gICAgICAgICdyZXF1aXJlZGZlYXR1cmVzJzogJ3JlcXVpcmVkRmVhdHVyZXMnLFxyXG4gICAgICAgICdzcGVjdWxhcmNvbnN0YW50JzogJ3NwZWN1bGFyQ29uc3RhbnQnLFxyXG4gICAgICAgICdzcGVjdWxhcmV4cG9uZW50JzogJ3NwZWN1bGFyRXhwb25lbnQnLFxyXG4gICAgICAgICdzcHJlYWRtZXRob2QnOiAnc3ByZWFkTWV0aG9kJyxcclxuICAgICAgICAnc3RhcnRvZmZzZXQnOiAnc3RhcnRPZmZzZXQnLFxyXG4gICAgICAgICdzdGRkZXZpYXRpb24nOiAnc3RkRGV2aWF0aW9uJyxcclxuICAgICAgICAnc3RpdGNodGlsZXMnOiAnc3RpdGNoVGlsZXMnLFxyXG4gICAgICAgICdzdXJmYWNlc2NhbGUnOiAnc3VyZmFjZVNjYWxlJyxcclxuICAgICAgICAnc3lzdGVtbGFuZ3VhZ2UnOiAnc3lzdGVtTGFuZ3VhZ2UnLFxyXG4gICAgICAgICd0YWJsZXZhbHVlcyc6ICd0YWJsZVZhbHVlcycsXHJcbiAgICAgICAgJ3RhcmdldHgnOiAndGFyZ2V0WCcsXHJcbiAgICAgICAgJ3RhcmdldHknOiAndGFyZ2V0WScsXHJcbiAgICAgICAgJ3RleHRsZW5ndGgnOiAndGV4dExlbmd0aCcsXHJcbiAgICAgICAgJ3ZpZXdib3gnOiAndmlld0JveCcsXHJcbiAgICAgICAgJ3ZpZXd0YXJnZXQnOiAndmlld1RhcmdldCcsXHJcbiAgICAgICAgJ3hjaGFubmVsc2VsZWN0b3InOiAneENoYW5uZWxTZWxlY3RvcicsXHJcbiAgICAgICAgJ3ljaGFubmVsc2VsZWN0b3InOiAneUNoYW5uZWxTZWxlY3RvcicsXHJcbiAgICAgICAgJ3pvb21hbmRwYW4nOiAnem9vbUFuZFBhbidcclxuICAgIH0sXHJcbiAgICBYTUxfQVRUUlNfQURKVVNUTUVOVF9NQVAgPSB7XHJcbiAgICAgICAgJ3hsaW5rOmFjdHVhdGUnOiB7cHJlZml4OiAneGxpbmsnLCBuYW1lOiAnYWN0dWF0ZScsIG5hbWVzcGFjZTogTlMuWExJTkt9LFxyXG4gICAgICAgICd4bGluazphcmNyb2xlJzoge3ByZWZpeDogJ3hsaW5rJywgbmFtZTogJ2FyY3JvbGUnLCBuYW1lc3BhY2U6IE5TLlhMSU5LfSxcclxuICAgICAgICAneGxpbms6aHJlZic6IHtwcmVmaXg6ICd4bGluaycsIG5hbWU6ICdocmVmJywgbmFtZXNwYWNlOiBOUy5YTElOS30sXHJcbiAgICAgICAgJ3hsaW5rOnJvbGUnOiB7cHJlZml4OiAneGxpbmsnLCBuYW1lOiAncm9sZScsIG5hbWVzcGFjZTogTlMuWExJTkt9LFxyXG4gICAgICAgICd4bGluazpzaG93Jzoge3ByZWZpeDogJ3hsaW5rJywgbmFtZTogJ3Nob3cnLCBuYW1lc3BhY2U6IE5TLlhMSU5LfSxcclxuICAgICAgICAneGxpbms6dGl0bGUnOiB7cHJlZml4OiAneGxpbmsnLCBuYW1lOiAndGl0bGUnLCBuYW1lc3BhY2U6IE5TLlhMSU5LfSxcclxuICAgICAgICAneGxpbms6dHlwZSc6IHtwcmVmaXg6ICd4bGluaycsIG5hbWU6ICd0eXBlJywgbmFtZXNwYWNlOiBOUy5YTElOS30sXHJcbiAgICAgICAgJ3htbDpiYXNlJzoge3ByZWZpeDogJ3htbCcsIG5hbWU6ICdiYXNlJywgbmFtZXNwYWNlOiBOUy5YTUx9LFxyXG4gICAgICAgICd4bWw6bGFuZyc6IHtwcmVmaXg6ICd4bWwnLCBuYW1lOiAnbGFuZycsIG5hbWVzcGFjZTogTlMuWE1MfSxcclxuICAgICAgICAneG1sOnNwYWNlJzoge3ByZWZpeDogJ3htbCcsIG5hbWU6ICdzcGFjZScsIG5hbWVzcGFjZTogTlMuWE1MfSxcclxuICAgICAgICAneG1sbnMnOiB7cHJlZml4OiAnJywgbmFtZTogJ3htbG5zJywgbmFtZXNwYWNlOiBOUy5YTUxOU30sXHJcbiAgICAgICAgJ3htbG5zOnhsaW5rJzoge3ByZWZpeDogJ3htbG5zJywgbmFtZTogJ3hsaW5rJywgbmFtZXNwYWNlOiBOUy5YTUxOU31cclxuXHJcbiAgICB9O1xyXG5cclxuLy9TVkcgdGFnIG5hbWVzIGFkanVzdG1lbnQgbWFwXHJcbnZhciBTVkdfVEFHX05BTUVTX0FESlVTVE1FTlRfTUFQID0ge1xyXG4gICAgJ2FsdGdseXBoJzogJ2FsdEdseXBoJyxcclxuICAgICdhbHRnbHlwaGRlZic6ICdhbHRHbHlwaERlZicsXHJcbiAgICAnYWx0Z2x5cGhpdGVtJzogJ2FsdEdseXBoSXRlbScsXHJcbiAgICAnYW5pbWF0ZWNvbG9yJzogJ2FuaW1hdGVDb2xvcicsXHJcbiAgICAnYW5pbWF0ZW1vdGlvbic6ICdhbmltYXRlTW90aW9uJyxcclxuICAgICdhbmltYXRldHJhbnNmb3JtJzogJ2FuaW1hdGVUcmFuc2Zvcm0nLFxyXG4gICAgJ2NsaXBwYXRoJzogJ2NsaXBQYXRoJyxcclxuICAgICdmZWJsZW5kJzogJ2ZlQmxlbmQnLFxyXG4gICAgJ2ZlY29sb3JtYXRyaXgnOiAnZmVDb2xvck1hdHJpeCcsXHJcbiAgICAnZmVjb21wb25lbnR0cmFuc2Zlcic6ICdmZUNvbXBvbmVudFRyYW5zZmVyJyxcclxuICAgICdmZWNvbXBvc2l0ZSc6ICdmZUNvbXBvc2l0ZScsXHJcbiAgICAnZmVjb252b2x2ZW1hdHJpeCc6ICdmZUNvbnZvbHZlTWF0cml4JyxcclxuICAgICdmZWRpZmZ1c2VsaWdodGluZyc6ICdmZURpZmZ1c2VMaWdodGluZycsXHJcbiAgICAnZmVkaXNwbGFjZW1lbnRtYXAnOiAnZmVEaXNwbGFjZW1lbnRNYXAnLFxyXG4gICAgJ2ZlZGlzdGFudGxpZ2h0JzogJ2ZlRGlzdGFudExpZ2h0JyxcclxuICAgICdmZWZsb29kJzogJ2ZlRmxvb2QnLFxyXG4gICAgJ2ZlZnVuY2EnOiAnZmVGdW5jQScsXHJcbiAgICAnZmVmdW5jYic6ICdmZUZ1bmNCJyxcclxuICAgICdmZWZ1bmNnJzogJ2ZlRnVuY0cnLFxyXG4gICAgJ2ZlZnVuY3InOiAnZmVGdW5jUicsXHJcbiAgICAnZmVnYXVzc2lhbmJsdXInOiAnZmVHYXVzc2lhbkJsdXInLFxyXG4gICAgJ2ZlaW1hZ2UnOiAnZmVJbWFnZScsXHJcbiAgICAnZmVtZXJnZSc6ICdmZU1lcmdlJyxcclxuICAgICdmZW1lcmdlbm9kZSc6ICdmZU1lcmdlTm9kZScsXHJcbiAgICAnZmVtb3JwaG9sb2d5JzogJ2ZlTW9ycGhvbG9neScsXHJcbiAgICAnZmVvZmZzZXQnOiAnZmVPZmZzZXQnLFxyXG4gICAgJ2ZlcG9pbnRsaWdodCc6ICdmZVBvaW50TGlnaHQnLFxyXG4gICAgJ2Zlc3BlY3VsYXJsaWdodGluZyc6ICdmZVNwZWN1bGFyTGlnaHRpbmcnLFxyXG4gICAgJ2Zlc3BvdGxpZ2h0JzogJ2ZlU3BvdExpZ2h0JyxcclxuICAgICdmZXRpbGUnOiAnZmVUaWxlJyxcclxuICAgICdmZXR1cmJ1bGVuY2UnOiAnZmVUdXJidWxlbmNlJyxcclxuICAgICdmb3JlaWdub2JqZWN0JzogJ2ZvcmVpZ25PYmplY3QnLFxyXG4gICAgJ2dseXBocmVmJzogJ2dseXBoUmVmJyxcclxuICAgICdsaW5lYXJncmFkaWVudCc6ICdsaW5lYXJHcmFkaWVudCcsXHJcbiAgICAncmFkaWFsZ3JhZGllbnQnOiAncmFkaWFsR3JhZGllbnQnLFxyXG4gICAgJ3RleHRwYXRoJzogJ3RleHRQYXRoJ1xyXG59O1xyXG5cclxuLy9UYWdzIHRoYXQgY2F1c2VzIGV4aXQgZnJvbSBmb3JlaWduIGNvbnRlbnRcclxudmFyIEVYSVRTX0ZPUkVJR05fQ09OVEVOVCA9IHt9O1xyXG5cclxuRVhJVFNfRk9SRUlHTl9DT05URU5UWyQuQl0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5CSUddID0gdHJ1ZTtcclxuRVhJVFNfRk9SRUlHTl9DT05URU5UWyQuQkxPQ0tRVU9URV0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5CT0RZXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLkJSXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLkNFTlRFUl0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5DT0RFXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLkREXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLkRJVl0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5ETF0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5EVF0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5FTV0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5FTUJFRF0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5IMV0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5IMl0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5IM10gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5INF0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5INV0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5INl0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5IRUFEXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLkhSXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLkldID0gdHJ1ZTtcclxuRVhJVFNfRk9SRUlHTl9DT05URU5UWyQuSU1HXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLkxJXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLkxJU1RJTkddID0gdHJ1ZTtcclxuRVhJVFNfRk9SRUlHTl9DT05URU5UWyQuTUVOVV0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5NRVRBXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLk5PQlJdID0gdHJ1ZTtcclxuRVhJVFNfRk9SRUlHTl9DT05URU5UWyQuT0xdID0gdHJ1ZTtcclxuRVhJVFNfRk9SRUlHTl9DT05URU5UWyQuUF0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5QUkVdID0gdHJ1ZTtcclxuRVhJVFNfRk9SRUlHTl9DT05URU5UWyQuUlVCWV0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5TXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLlNNQUxMXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLlNQQU5dID0gdHJ1ZTtcclxuRVhJVFNfRk9SRUlHTl9DT05URU5UWyQuU1RST05HXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLlNUUklLRV0gPSB0cnVlO1xyXG5FWElUU19GT1JFSUdOX0NPTlRFTlRbJC5TVUJdID0gdHJ1ZTtcclxuRVhJVFNfRk9SRUlHTl9DT05URU5UWyQuU1VQXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLlRBQkxFXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLlRUXSA9IHRydWU7XHJcbkVYSVRTX0ZPUkVJR05fQ09OVEVOVFskLlVdID0gdHJ1ZTtcclxuRVhJVFNfRk9SRUlHTl9DT05URU5UWyQuVUxdID0gdHJ1ZTtcclxuRVhJVFNfRk9SRUlHTl9DT05URU5UWyQuVkFSXSA9IHRydWU7XHJcblxyXG4vL0NoZWNrIGV4aXQgZnJvbSBmb3JlaWduIGNvbnRlbnRcclxuZXhwb3J0cy5jYXVzZXNFeGl0ID0gZnVuY3Rpb24gKHN0YXJ0VGFnVG9rZW4pIHtcclxuICAgIHZhciB0biA9IHN0YXJ0VGFnVG9rZW4udGFnTmFtZTtcclxuXHJcbiAgICBpZiAodG4gPT09ICQuRk9OVCAmJiAoVG9rZW5pemVyLmdldFRva2VuQXR0cihzdGFydFRhZ1Rva2VuLCBBVFRSUy5DT0xPUikgIT09IG51bGwgfHxcclxuICAgICAgICBUb2tlbml6ZXIuZ2V0VG9rZW5BdHRyKHN0YXJ0VGFnVG9rZW4sIEFUVFJTLlNJWkUpICE9PSBudWxsIHx8XHJcbiAgICAgICAgVG9rZW5pemVyLmdldFRva2VuQXR0cihzdGFydFRhZ1Rva2VuLCBBVFRSUy5GQUNFKSAhPT0gbnVsbCkpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gRVhJVFNfRk9SRUlHTl9DT05URU5UW3RuXTtcclxufTtcclxuXHJcbi8vVG9rZW4gYWRqdXN0bWVudHNcclxuZXhwb3J0cy5hZGp1c3RUb2tlbk1hdGhNTEF0dHJzID0gZnVuY3Rpb24gKHRva2VuKSB7XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRva2VuLmF0dHJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKHRva2VuLmF0dHJzW2ldLm5hbWUgPT09IERFRklOSVRJT05fVVJMX0FUVFIpIHtcclxuICAgICAgICAgICAgdG9rZW4uYXR0cnNbaV0ubmFtZSA9IEFESlVTVEVEX0RFRklOSVRJT05fVVJMX0FUVFI7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufTtcclxuXHJcbmV4cG9ydHMuYWRqdXN0VG9rZW5TVkdBdHRycyA9IGZ1bmN0aW9uICh0b2tlbikge1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0b2tlbi5hdHRycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIHZhciBhZGp1c3RlZEF0dHJOYW1lID0gU1ZHX0FUVFJTX0FESlVTVE1FTlRfTUFQW3Rva2VuLmF0dHJzW2ldLm5hbWVdO1xyXG5cclxuICAgICAgICBpZiAoYWRqdXN0ZWRBdHRyTmFtZSlcclxuICAgICAgICAgICAgdG9rZW4uYXR0cnNbaV0ubmFtZSA9IGFkanVzdGVkQXR0ck5hbWU7XHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnRzLmFkanVzdFRva2VuWE1MQXR0cnMgPSBmdW5jdGlvbiAodG9rZW4pIHtcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdG9rZW4uYXR0cnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICB2YXIgYWRqdXN0ZWRBdHRyRW50cnkgPSBYTUxfQVRUUlNfQURKVVNUTUVOVF9NQVBbdG9rZW4uYXR0cnNbaV0ubmFtZV07XHJcblxyXG4gICAgICAgIGlmIChhZGp1c3RlZEF0dHJFbnRyeSkge1xyXG4gICAgICAgICAgICB0b2tlbi5hdHRyc1tpXS5wcmVmaXggPSBhZGp1c3RlZEF0dHJFbnRyeS5wcmVmaXg7XHJcbiAgICAgICAgICAgIHRva2VuLmF0dHJzW2ldLm5hbWUgPSBhZGp1c3RlZEF0dHJFbnRyeS5uYW1lO1xyXG4gICAgICAgICAgICB0b2tlbi5hdHRyc1tpXS5uYW1lc3BhY2UgPSBhZGp1c3RlZEF0dHJFbnRyeS5uYW1lc3BhY2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59O1xyXG5cclxuZXhwb3J0cy5hZGp1c3RUb2tlblNWR1RhZ05hbWUgPSBmdW5jdGlvbiAodG9rZW4pIHtcclxuICAgIHZhciBhZGp1c3RlZFRhZ05hbWUgPSBTVkdfVEFHX05BTUVTX0FESlVTVE1FTlRfTUFQW3Rva2VuLnRhZ05hbWVdO1xyXG5cclxuICAgIGlmIChhZGp1c3RlZFRhZ05hbWUpXHJcbiAgICAgICAgdG9rZW4udGFnTmFtZSA9IGFkanVzdGVkVGFnTmFtZTtcclxufTtcclxuXHJcbi8vSW50ZWdyYXRpb24gcG9pbnRzXHJcbmV4cG9ydHMuaXNNYXRoTUxUZXh0SW50ZWdyYXRpb25Qb2ludCA9IGZ1bmN0aW9uICh0biwgbnMpIHtcclxuICAgIHJldHVybiBucyA9PT0gTlMuTUFUSE1MICYmICh0biA9PT0gJC5NSSB8fCB0biA9PT0gJC5NTyB8fCB0biA9PT0gJC5NTiB8fCB0biA9PT0gJC5NUyB8fCB0biA9PT0gJC5NVEVYVCk7XHJcbn07XHJcblxyXG5leHBvcnRzLmlzSHRtbEludGVncmF0aW9uUG9pbnQgPSBmdW5jdGlvbiAodG4sIG5zLCBhdHRycykge1xyXG4gICAgaWYgKG5zID09PSBOUy5NQVRITUwgJiYgdG4gPT09ICQuQU5OT1RBVElPTl9YTUwpIHtcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChhdHRyc1tpXS5uYW1lID09PSBBVFRSUy5FTkNPRElORykge1xyXG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gYXR0cnNbaV0udmFsdWUudG9Mb3dlckNhc2UoKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUgPT09IE1JTUVfVFlQRVMuVEVYVF9IVE1MIHx8IHZhbHVlID09PSBNSU1FX1RZUEVTLkFQUExJQ0FUSU9OX1hNTDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnMgPT09IE5TLlNWRyAmJiAodG4gPT09ICQuRk9SRUlHTl9PQkpFQ1QgfHwgdG4gPT09ICQuREVTQyB8fCB0biA9PT0gJC5USVRMRSk7XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBOUyA9IGV4cG9ydHMuTkFNRVNQQUNFUyA9IHtcclxuICAgIEhUTUw6ICdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sJyxcclxuICAgIE1BVEhNTDogJ2h0dHA6Ly93d3cudzMub3JnLzE5OTgvTWF0aC9NYXRoTUwnLFxyXG4gICAgU1ZHOiAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxyXG4gICAgWExJTks6ICdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rJyxcclxuICAgIFhNTDogJ2h0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZScsXHJcbiAgICBYTUxOUzogJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvJ1xyXG59O1xyXG5cclxuZXhwb3J0cy5BVFRSUyA9IHtcclxuICAgIFRZUEU6ICd0eXBlJyxcclxuICAgIEFDVElPTjogJ2FjdGlvbicsXHJcbiAgICBFTkNPRElORzogJ2VuY29kaW5nJyxcclxuICAgIFBST01QVDogJ3Byb21wdCcsXHJcbiAgICBOQU1FOiAnbmFtZScsXHJcbiAgICBDT0xPUjogJ2NvbG9yJyxcclxuICAgIEZBQ0U6ICdmYWNlJyxcclxuICAgIFNJWkU6ICdzaXplJ1xyXG59O1xyXG5cclxudmFyICQgPSBleHBvcnRzLlRBR19OQU1FUyA9IHtcclxuICAgIEE6ICdhJyxcclxuICAgIEFERFJFU1M6ICdhZGRyZXNzJyxcclxuICAgIEFOTk9UQVRJT05fWE1MOiAnYW5ub3RhdGlvbi14bWwnLFxyXG4gICAgQVBQTEVUOiAnYXBwbGV0JyxcclxuICAgIEFSRUE6ICdhcmVhJyxcclxuICAgIEFSVElDTEU6ICdhcnRpY2xlJyxcclxuICAgIEFTSURFOiAnYXNpZGUnLFxyXG5cclxuICAgIEI6ICdiJyxcclxuICAgIEJBU0U6ICdiYXNlJyxcclxuICAgIEJBU0VGT05UOiAnYmFzZWZvbnQnLFxyXG4gICAgQkdTT1VORDogJ2Jnc291bmQnLFxyXG4gICAgQklHOiAnYmlnJyxcclxuICAgIEJMT0NLUVVPVEU6ICdibG9ja3F1b3RlJyxcclxuICAgIEJPRFk6ICdib2R5JyxcclxuICAgIEJSOiAnYnInLFxyXG4gICAgQlVUVE9OOiAnYnV0dG9uJyxcclxuXHJcbiAgICBDQVBUSU9OOiAnY2FwdGlvbicsXHJcbiAgICBDRU5URVI6ICdjZW50ZXInLFxyXG4gICAgQ09ERTogJ2NvZGUnLFxyXG4gICAgQ09MOiAnY29sJyxcclxuICAgIENPTEdST1VQOiAnY29sZ3JvdXAnLFxyXG4gICAgQ09NTUFORDogJ2NvbW1hbmQnLFxyXG5cclxuICAgIEREOiAnZGQnLFxyXG4gICAgREVTQzogJ2Rlc2MnLFxyXG4gICAgREVUQUlMUzogJ2RldGFpbHMnLFxyXG4gICAgRElBTE9HOiAnZGlhbG9nJyxcclxuICAgIERJUjogJ2RpcicsXHJcbiAgICBESVY6ICdkaXYnLFxyXG4gICAgREw6ICdkbCcsXHJcbiAgICBEVDogJ2R0JyxcclxuXHJcbiAgICBFTTogJ2VtJyxcclxuICAgIEVNQkVEOiAnZW1iZWQnLFxyXG5cclxuICAgIEZJRUxEU0VUOiAnZmllbGRzZXQnLFxyXG4gICAgRklHQ0FQVElPTjogJ2ZpZ2NhcHRpb24nLFxyXG4gICAgRklHVVJFOiAnZmlndXJlJyxcclxuICAgIEZPTlQ6ICdmb250JyxcclxuICAgIEZPT1RFUjogJ2Zvb3RlcicsXHJcbiAgICBGT1JFSUdOX09CSkVDVDogJ2ZvcmVpZ25PYmplY3QnLFxyXG4gICAgRk9STTogJ2Zvcm0nLFxyXG4gICAgRlJBTUU6ICdmcmFtZScsXHJcbiAgICBGUkFNRVNFVDogJ2ZyYW1lc2V0JyxcclxuXHJcbiAgICBIMTogJ2gxJyxcclxuICAgIEgyOiAnaDInLFxyXG4gICAgSDM6ICdoMycsXHJcbiAgICBINDogJ2g0JyxcclxuICAgIEg1OiAnaDUnLFxyXG4gICAgSDY6ICdoNicsXHJcbiAgICBIRUFEOiAnaGVhZCcsXHJcbiAgICBIRUFERVI6ICdoZWFkZXInLFxyXG4gICAgSEdST1VQOiAnaGdyb3VwJyxcclxuICAgIEhSOiAnaHInLFxyXG4gICAgSFRNTDogJ2h0bWwnLFxyXG5cclxuICAgIEk6ICdpJyxcclxuICAgIElNRzogJ2ltZycsXHJcbiAgICBJTUFHRTogJ2ltYWdlJyxcclxuICAgIElOUFVUOiAnaW5wdXQnLFxyXG4gICAgSUZSQU1FOiAnaWZyYW1lJyxcclxuICAgIElTSU5ERVg6ICdpc2luZGV4JyxcclxuXHJcbiAgICBLRVlHRU46ICdrZXlnZW4nLFxyXG5cclxuICAgIExBQkVMOiAnbGFiZWwnLFxyXG4gICAgTEk6ICdsaScsXHJcbiAgICBMSU5LOiAnbGluaycsXHJcbiAgICBMSVNUSU5HOiAnbGlzdGluZycsXHJcblxyXG4gICAgTUFJTjogJ21haW4nLFxyXG4gICAgTUFMSUdOTUFSSzogJ21hbGlnbm1hcmsnLFxyXG4gICAgTUFSUVVFRTogJ21hcnF1ZWUnLFxyXG4gICAgTUFUSDogJ21hdGgnLFxyXG4gICAgTUVOVTogJ21lbnUnLFxyXG4gICAgTUVOVUlURU06ICdtZW51aXRlbScsXHJcbiAgICBNRVRBOiAnbWV0YScsXHJcbiAgICBNR0xZUEg6ICdtZ2x5cGgnLFxyXG4gICAgTUk6ICdtaScsXHJcbiAgICBNTzogJ21vJyxcclxuICAgIE1OOiAnbW4nLFxyXG4gICAgTVM6ICdtcycsXHJcbiAgICBNVEVYVDogJ210ZXh0JyxcclxuXHJcbiAgICBOQVY6ICduYXYnLFxyXG4gICAgTk9CUjogJ25vYnInLFxyXG4gICAgTk9GUkFNRVM6ICdub2ZyYW1lcycsXHJcbiAgICBOT0VNQkVEOiAnbm9lbWJlZCcsXHJcbiAgICBOT1NDUklQVDogJ25vc2NyaXB0JyxcclxuXHJcbiAgICBPQkpFQ1Q6ICdvYmplY3QnLFxyXG4gICAgT0w6ICdvbCcsXHJcbiAgICBPUFRHUk9VUDogJ29wdGdyb3VwJyxcclxuICAgIE9QVElPTjogJ29wdGlvbicsXHJcblxyXG4gICAgUDogJ3AnLFxyXG4gICAgUEFSQU06ICdwYXJhbScsXHJcbiAgICBQTEFJTlRFWFQ6ICdwbGFpbnRleHQnLFxyXG4gICAgUFJFOiAncHJlJyxcclxuXHJcbiAgICBSUDogJ3JwJyxcclxuICAgIFJUOiAncnQnLFxyXG4gICAgUlVCWTogJ3J1YnknLFxyXG5cclxuICAgIFM6ICdzJyxcclxuICAgIFNDUklQVDogJ3NjcmlwdCcsXHJcbiAgICBTRUNUSU9OOiAnc2VjdGlvbicsXHJcbiAgICBTRUxFQ1Q6ICdzZWxlY3QnLFxyXG4gICAgU09VUkNFOiAnc291cmNlJyxcclxuICAgIFNNQUxMOiAnc21hbGwnLFxyXG4gICAgU1BBTjogJ3NwYW4nLFxyXG4gICAgU1RSSUtFOiAnc3RyaWtlJyxcclxuICAgIFNUUk9ORzogJ3N0cm9uZycsXHJcbiAgICBTVFlMRTogJ3N0eWxlJyxcclxuICAgIFNVQjogJ3N1YicsXHJcbiAgICBTVU1NQVJZOiAnc3VtbWFyeScsXHJcbiAgICBTVVA6ICdzdXAnLFxyXG5cclxuICAgIFRBQkxFOiAndGFibGUnLFxyXG4gICAgVEJPRFk6ICd0Ym9keScsXHJcbiAgICBURU1QTEFURTogJ3RlbXBsYXRlJyxcclxuICAgIFRFWFRBUkVBOiAndGV4dGFyZWEnLFxyXG4gICAgVEZPT1Q6ICd0Zm9vdCcsXHJcbiAgICBURDogJ3RkJyxcclxuICAgIFRIOiAndGgnLFxyXG4gICAgVEhFQUQ6ICd0aGVhZCcsXHJcbiAgICBUSVRMRTogJ3RpdGxlJyxcclxuICAgIFRSOiAndHInLFxyXG4gICAgVFJBQ0s6ICd0cmFjaycsXHJcbiAgICBUVDogJ3R0JyxcclxuXHJcbiAgICBVOiAndScsXHJcbiAgICBVTDogJ3VsJyxcclxuXHJcbiAgICBTVkc6ICdzdmcnLFxyXG5cclxuICAgIFZBUjogJ3ZhcicsXHJcblxyXG4gICAgV0JSOiAnd2JyJyxcclxuXHJcbiAgICBYTVA6ICd4bXAnXHJcbn07XHJcblxyXG52YXIgU1BFQ0lBTF9FTEVNRU5UUyA9IGV4cG9ydHMuU1BFQ0lBTF9FTEVNRU5UUyA9IHt9O1xyXG5cclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXSA9IHt9O1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuQUREUkVTU10gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuQVBQTEVUXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5BUkVBXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5BUlRJQ0xFXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5BU0lERV0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuQkFTRV0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuQkFTRUZPTlRdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkJHU09VTkRdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkJMT0NLUVVPVEVdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkJPRFldID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkJSXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5CVVRUT05dID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkNBUFRJT05dID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkNFTlRFUl0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuQ09MXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5DT0xHUk9VUF0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuRERdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkRFVEFJTFNdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkRJUl0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuRElWXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5ETF0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuRFRdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkVNQkVEXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5GSUVMRFNFVF0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuRklHQ0FQVElPTl0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuRklHVVJFXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5GT09URVJdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkZPUk1dID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkZSQU1FXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5GUkFNRVNFVF0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuSDFdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkgyXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5IM10gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuSDRdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkg1XSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5INl0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuSEVBRF0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuSEVBREVSXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5IR1JPVVBdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkhSXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5IVE1MXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5JRlJBTUVdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLklNR10gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuSU5QVVRdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLklTSU5ERVhdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLkxJXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5MSU5LXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5MSVNUSU5HXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5NQUlOXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5NQVJRVUVFXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5NRU5VXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5NRU5VSVRFTV0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuTUVUQV0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuTkFWXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5OT0VNQkVEXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5OT0ZSQU1FU10gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuTk9TQ1JJUFRdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLk9CSkVDVF0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuT0xdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLlBdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLlBBUkFNXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5QTEFJTlRFWFRdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLlBSRV0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuU0NSSVBUXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5TRUNUSU9OXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5TRUxFQ1RdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLlNPVVJDRV0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuU1RZTEVdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLlNVTU1BUlldID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLlRBQkxFXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5UQk9EWV0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuVERdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLlRFTVBMQVRFXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5URVhUQVJFQV0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuVEZPT1RdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLlRIXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5USEVBRF0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuVElUTEVdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLlRSXSA9IHRydWU7XHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuSFRNTF1bJC5UUkFDS10gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuVUxdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5IVE1MXVskLldCUl0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLkhUTUxdWyQuWE1QXSA9IHRydWU7XHJcblxyXG5TUEVDSUFMX0VMRU1FTlRTW05TLk1BVEhNTF0gPSB7fTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5NQVRITUxdWyQuTUldID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5NQVRITUxdWyQuTU9dID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5NQVRITUxdWyQuTU5dID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5NQVRITUxdWyQuTVNdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5NQVRITUxdWyQuTVRFWFRdID0gdHJ1ZTtcclxuU1BFQ0lBTF9FTEVNRU5UU1tOUy5NQVRITUxdWyQuQU5OT1RBVElPTl9YTUxdID0gdHJ1ZTtcclxuXHJcblNQRUNJQUxfRUxFTUVOVFNbTlMuU1ZHXSA9IHt9O1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLlNWR11bJC5USVRMRV0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLlNWR11bJC5GT1JFSUdOX09CSkVDVF0gPSB0cnVlO1xyXG5TUEVDSUFMX0VMRU1FTlRTW05TLlNWR11bJC5ERVNDXSA9IHRydWU7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbmV4cG9ydHMuUkVQTEFDRU1FTlRfQ0hBUkFDVEVSID0gJ1xcdUZGRkQnO1xyXG5cclxuZXhwb3J0cy5DT0RFX1BPSU5UUyA9IHtcclxuICAgIEVPRjogLTEsXHJcbiAgICBOVUxMOiAweDAwLFxyXG4gICAgVEFCVUxBVElPTjogMHgwOSxcclxuICAgIENBUlJJQUdFX1JFVFVSTjogMHgwRCxcclxuICAgIExJTkVfRkVFRDogMHgwQSxcclxuICAgIEZPUk1fRkVFRDogMHgwQyxcclxuICAgIFNQQUNFOiAweDIwLFxyXG4gICAgRVhDTEFNQVRJT05fTUFSSzogMHgyMSxcclxuICAgIFFVT1RBVElPTl9NQVJLOiAweDIyLFxyXG4gICAgTlVNQkVSX1NJR046IDB4MjMsXHJcbiAgICBBTVBFUlNBTkQ6IDB4MjYsXHJcbiAgICBBUE9TVFJPUEhFOiAweDI3LFxyXG4gICAgSFlQSEVOX01JTlVTOiAweDJELFxyXG4gICAgU09MSURVUzogMHgyRixcclxuICAgIERJR0lUXzA6IDB4MzAsXHJcbiAgICBESUdJVF85OiAweDM5LFxyXG4gICAgU0VNSUNPTE9OOiAweDNCLFxyXG4gICAgTEVTU19USEFOX1NJR046IDB4M0MsXHJcbiAgICBFUVVBTFNfU0lHTjogMHgzRCxcclxuICAgIEdSRUFURVJfVEhBTl9TSUdOOiAweDNFLFxyXG4gICAgUVVFU1RJT05fTUFSSzogMHgzRixcclxuICAgIExBVElOX0NBUElUQUxfQTogMHg0MSxcclxuICAgIExBVElOX0NBUElUQUxfRjogMHg0NixcclxuICAgIExBVElOX0NBUElUQUxfWDogMHg1OCxcclxuICAgIExBVElOX0NBUElUQUxfWjogMHg1QSxcclxuICAgIEdSQVZFX0FDQ0VOVDogMHg2MCxcclxuICAgIExBVElOX1NNQUxMX0E6IDB4NjEsXHJcbiAgICBMQVRJTl9TTUFMTF9GOiAweDY2LFxyXG4gICAgTEFUSU5fU01BTExfWDogMHg3OCxcclxuICAgIExBVElOX1NNQUxMX1o6IDB4N0EsXHJcbiAgICBCT006IDB4RkVGRixcclxuICAgIFJFUExBQ0VNRU5UX0NIQVJBQ1RFUjogMHhGRkZEXHJcbn07XHJcblxyXG5leHBvcnRzLkNPREVfUE9JTlRfU0VRVUVOQ0VTID0ge1xyXG4gICAgREFTSF9EQVNIX1NUUklORzogWzB4MkQsIDB4MkRdLCAvLy0tXHJcbiAgICBET0NUWVBFX1NUUklORzogWzB4NDQsIDB4NEYsIDB4NDMsIDB4NTQsIDB4NTksIDB4NTAsIDB4NDVdLCAvL0RPQ1RZUEVcclxuICAgIENEQVRBX1NUQVJUX1NUUklORzogWzB4NUIsIDB4NDMsIDB4NDQsIDB4NDEsIDB4NTQsIDB4NDEsIDB4NUJdLCAvL1tDREFUQVtcclxuICAgIENEQVRBX0VORF9TVFJJTkc6IFsweDVELCAweDVELCAweDNFXSwgLy9dXT5cclxuICAgIFNDUklQVF9TVFJJTkc6IFsweDczLCAweDYzLCAweDcyLCAweDY5LCAweDcwLCAweDc0XSwgLy9zY3JpcHRcclxuICAgIFBVQkxJQ19TVFJJTkc6IFsweDUwLCAweDU1LCAweDQyLCAweDRDLCAweDQ5LCAweDQzXSwgLy9QVUJMSUNcclxuICAgIFNZU1RFTV9TVFJJTkc6IFsweDUzLCAweDU5LCAweDUzLCAweDU0LCAweDQ1LCAweDREXSAvL1NZU1RFTVxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG5leHBvcnRzLm1lcmdlT3B0aW9ucyA9IGZ1bmN0aW9uIChkZWZhdWx0cywgb3B0aW9ucykge1xyXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcblxyXG4gICAgcmV0dXJuIFtkZWZhdWx0cywgb3B0aW9uc10ucmVkdWNlKGZ1bmN0aW9uIChtZXJnZWQsIG9wdE9iaikge1xyXG4gICAgICAgIE9iamVjdC5rZXlzKG9wdE9iaikuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgICAgIG1lcmdlZFtrZXldID0gb3B0T2JqW2tleV07XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBtZXJnZWQ7XHJcbiAgICB9LCB7fSk7XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBQYXJzZXIgPSByZXF1aXJlKCcuLi90cmVlX2NvbnN0cnVjdGlvbi9wYXJzZXInKSxcclxuICAgIFBhcnNpbmdVbml0ID0gcmVxdWlyZSgnLi9wYXJzaW5nX3VuaXQnKTtcclxuXHJcbi8vQVBJXHJcbmV4cG9ydHMucGFyc2VEb2N1bWVudCA9IGZ1bmN0aW9uIChodG1sLCB0cmVlQWRhcHRlcikge1xyXG4gICAgLy9OT1RFOiB0aGlzIHNob3VsZCBiZSByZWVudHJhbnQsIHNvIHdlIGNyZWF0ZSBuZXcgcGFyc2VyIGhlcmVcclxuICAgIHZhciBwYXJzZXIgPSBuZXcgUGFyc2VyKHRyZWVBZGFwdGVyKSxcclxuICAgICAgICBwYXJzaW5nVW5pdCA9IG5ldyBQYXJzaW5nVW5pdChwYXJzZXIpO1xyXG5cclxuICAgIC8vTk9URTogb3ZlcnJpZGUgcGFyc2VyIGxvb3AgbWV0aG9kXHJcbiAgICBwYXJzZXIuX3J1blBhcnNpbmdMb29wID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHBhcnNpbmdVbml0LnBhcnNpbmdMb29wTG9jayA9IHRydWU7XHJcblxyXG4gICAgICAgIHdoaWxlICghcGFyc2luZ1VuaXQuc3VzcGVuZGVkICYmICF0aGlzLnN0b3BwZWQpXHJcbiAgICAgICAgICAgIHRoaXMuX2l0ZXJhdGVQYXJzaW5nTG9vcCgpO1xyXG5cclxuICAgICAgICBwYXJzaW5nVW5pdC5wYXJzaW5nTG9vcExvY2sgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuc3RvcHBlZClcclxuICAgICAgICAgICAgcGFyc2luZ1VuaXQuY2FsbGJhY2sodGhpcy5kb2N1bWVudCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vTk9URTogd2FpdCB3aGlsZSBwYXJzZXJDb250cm9sbGVyIHdpbGwgYmUgYWRvcHRlZCBieSBjYWxsaW5nIGNvZGUsIHRoZW5cclxuICAgIC8vc3RhcnQgcGFyc2luZ1xyXG4gICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcGFyc2VyLnBhcnNlKGh0bWwpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIHBhcnNpbmdVbml0O1xyXG59O1xyXG5cclxuZXhwb3J0cy5wYXJzZUlubmVySHRtbCA9IGZ1bmN0aW9uIChpbm5lckh0bWwsIGNvbnRleHRFbGVtZW50LCB0cmVlQWRhcHRlcikge1xyXG4gICAgLy9OT1RFOiB0aGlzIHNob3VsZCBiZSByZWVudHJhbnQsIHNvIHdlIGNyZWF0ZSBuZXcgcGFyc2VyIGhlcmVcclxuICAgIHZhciBwYXJzZXIgPSBuZXcgUGFyc2VyKHRyZWVBZGFwdGVyKTtcclxuXHJcbiAgICByZXR1cm4gcGFyc2VyLnBhcnNlRnJhZ21lbnQoaW5uZXJIdG1sLCBjb250ZXh0RWxlbWVudCk7XHJcbn07IiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIFBhcnNpbmdVbml0ID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAocGFyc2VyKSB7XHJcbiAgICB0aGlzLnBhcnNlciA9IHBhcnNlcjtcclxuICAgIHRoaXMuc3VzcGVuZGVkID0gZmFsc2U7XHJcbiAgICB0aGlzLnBhcnNpbmdMb29wTG9jayA9IGZhbHNlO1xyXG4gICAgdGhpcy5jYWxsYmFjayA9IG51bGw7XHJcbn07XHJcblxyXG5QYXJzaW5nVW5pdC5wcm90b3R5cGUuX3N0YXRlR3VhcmQgPSBmdW5jdGlvbiAoc3VzcGVuZCkge1xyXG4gICAgaWYgKHRoaXMuc3VzcGVuZGVkICYmIHN1c3BlbmQpXHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdwYXJzZTU6IFBhcnNlciB3YXMgYWxyZWFkeSBzdXNwZW5kZWQuIFBsZWFzZSwgY2hlY2sgeW91ciBjb250cm9sIGZsb3cgbG9naWMuJyk7XHJcblxyXG4gICAgZWxzZSBpZiAoIXRoaXMuc3VzcGVuZGVkICYmICFzdXNwZW5kKVxyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcigncGFyc2U1OiBQYXJzZXIgd2FzIGFscmVhZHkgcmVzdW1lZC4gUGxlYXNlLCBjaGVjayB5b3VyIGNvbnRyb2wgZmxvdyBsb2dpYy4nKTtcclxuXHJcbiAgICByZXR1cm4gc3VzcGVuZDtcclxufTtcclxuXHJcblBhcnNpbmdVbml0LnByb3RvdHlwZS5zdXNwZW5kID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdGhpcy5zdXNwZW5kZWQgPSB0aGlzLl9zdGF0ZUd1YXJkKHRydWUpO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuUGFyc2luZ1VuaXQucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHRoaXMuc3VzcGVuZGVkID0gdGhpcy5fc3RhdGVHdWFyZChmYWxzZSk7XHJcblxyXG4gICAgLy9OT1RFOiBkb24ndCBlbnRlciBwYXJzaW5nIGxvb3AgaWYgaXQgaXMgbG9ja2VkLiBXaXRob3V0IHRoaXMgbG9jayBfcnVuUGFyc2luZ0xvb3AoKSBtYXkgYmUgY2FsbGVkXHJcbiAgICAvL3doaWxlIHBhcnNpbmcgbG9vcCBpcyBzdGlsbCBydW5uaW5nLiBFLmcuIHdoZW4gc3VzcGVuZCgpIGFuZCByZXN1bWUoKSBjYWxsZWQgc3luY2hyb25vdXNseS5cclxuICAgIGlmICghdGhpcy5wYXJzaW5nTG9vcExvY2spXHJcbiAgICAgICAgdGhpcy5wYXJzZXIuX3J1blBhcnNpbmdMb29wKCk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG5QYXJzaW5nVW5pdC5wcm90b3R5cGUuZG9jdW1lbnRXcml0ZSA9IGZ1bmN0aW9uIChodG1sKSB7XHJcbiAgICB0aGlzLnBhcnNlci50b2tlbml6ZXIucHJlcHJvY2Vzc29yLndyaXRlKGh0bWwpO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuUGFyc2luZ1VuaXQucHJvdG90eXBlLmhhbmRsZVNjcmlwdHMgPSBmdW5jdGlvbiAoc2NyaXB0SGFuZGxlcikge1xyXG4gICAgdGhpcy5wYXJzZXIuc2NyaXB0SGFuZGxlciA9IHNjcmlwdEhhbmRsZXI7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG5QYXJzaW5nVW5pdC5wcm90b3R5cGUuZG9uZSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xyXG4gICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBEZWZhdWx0VHJlZUFkYXB0ZXIgPSByZXF1aXJlKCcuLi90cmVlX2FkYXB0ZXJzL2RlZmF1bHQnKSxcbiAgICBEb2N0eXBlID0gcmVxdWlyZSgnLi4vY29tbW9uL2RvY3R5cGUnKSxcbiAgICBVdGlscyA9IHJlcXVpcmUoJy4uL2NvbW1vbi91dGlscycpLFxuICAgIEhUTUwgPSByZXF1aXJlKCcuLi9jb21tb24vaHRtbCcpO1xuXG4vL0FsaWFzZXNcbnZhciAkID0gSFRNTC5UQUdfTkFNRVMsXG4gICAgTlMgPSBIVE1MLk5BTUVTUEFDRVM7XG5cbi8vRGVmYXVsdCBzZXJpYWxpemVyIG9wdGlvbnNcbnZhciBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgZW5jb2RlSHRtbEVudGl0aWVzOiB0cnVlXG59O1xuXG4vL0VzY2FwaW5nIHJlZ2V4ZXNcbnZhciBBTVBfUkVHRVggPSAvJi9nLFxuICAgIE5CU1BfUkVHRVggPSAvXFx1MDBhMC9nLFxuICAgIERPVUJMRV9RVU9URV9SRUdFWCA9IC9cIi9nLFxuICAgIExUX1JFR0VYID0gLzwvZyxcbiAgICBHVF9SRUdFWCA9IC8+L2c7XG5cbi8vRXNjYXBlIHN0cmluZ1xuZnVuY3Rpb24gZXNjYXBlU3RyaW5nKHN0ciwgYXR0ck1vZGUpIHtcbiAgICBzdHIgPSBzdHJcbiAgICAgICAgLnJlcGxhY2UoQU1QX1JFR0VYLCAnJmFtcDsnKVxuICAgICAgICAucmVwbGFjZShOQlNQX1JFR0VYLCAnJm5ic3A7Jyk7XG5cbiAgICBpZiAoYXR0ck1vZGUpXG4gICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKERPVUJMRV9RVU9URV9SRUdFWCwgJyZxdW90OycpO1xuXG4gICAgZWxzZSB7XG4gICAgICAgIHN0ciA9IHN0clxuICAgICAgICAgICAgLnJlcGxhY2UoTFRfUkVHRVgsICcmbHQ7JylcbiAgICAgICAgICAgIC5yZXBsYWNlKEdUX1JFR0VYLCAnJmd0OycpO1xuICAgIH1cblxuICAgIHJldHVybiBzdHI7XG59XG5cblxuLy9FbnF1b3RlIGRvY3R5cGUgSURcblxuXG5cbi8vU2VyaWFsaXplclxudmFyIFNlcmlhbGl6ZXIgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0cmVlQWRhcHRlciwgb3B0aW9ucykge1xuICAgIHRoaXMudHJlZUFkYXB0ZXIgPSB0cmVlQWRhcHRlciB8fCBEZWZhdWx0VHJlZUFkYXB0ZXI7XG4gICAgdGhpcy5vcHRpb25zID0gVXRpbHMubWVyZ2VPcHRpb25zKERFRkFVTFRfT1BUSU9OUywgb3B0aW9ucyk7XG59O1xuXG5cbi8vQVBJXG5TZXJpYWxpemVyLnByb3RvdHlwZS5zZXJpYWxpemUgPSBmdW5jdGlvbiAobm9kZSkge1xuICAgIHRoaXMuaHRtbCA9ICcnO1xuICAgIHRoaXMuX3NlcmlhbGl6ZUNoaWxkTm9kZXMobm9kZSk7XG5cbiAgICByZXR1cm4gdGhpcy5odG1sO1xufTtcblxuXG4vL0ludGVybmFsc1xuU2VyaWFsaXplci5wcm90b3R5cGUuX3NlcmlhbGl6ZUNoaWxkTm9kZXMgPSBmdW5jdGlvbiAocGFyZW50Tm9kZSkge1xuICAgIHZhciBjaGlsZE5vZGVzID0gdGhpcy50cmVlQWRhcHRlci5nZXRDaGlsZE5vZGVzKHBhcmVudE5vZGUpO1xuXG4gICAgaWYgKGNoaWxkTm9kZXMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGNuTGVuZ3RoID0gY2hpbGROb2Rlcy5sZW5ndGg7IGkgPCBjbkxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgY3VycmVudE5vZGUgPSBjaGlsZE5vZGVzW2ldO1xuXG4gICAgICAgICAgICBpZiAodGhpcy50cmVlQWRhcHRlci5pc0VsZW1lbnROb2RlKGN1cnJlbnROb2RlKSlcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXJpYWxpemVFbGVtZW50KGN1cnJlbnROb2RlKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy50cmVlQWRhcHRlci5pc1RleHROb2RlKGN1cnJlbnROb2RlKSlcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXJpYWxpemVUZXh0Tm9kZShjdXJyZW50Tm9kZSk7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMudHJlZUFkYXB0ZXIuaXNDb21tZW50Tm9kZShjdXJyZW50Tm9kZSkpXG4gICAgICAgICAgICAgICAgdGhpcy5fc2VyaWFsaXplQ29tbWVudE5vZGUoY3VycmVudE5vZGUpO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLnRyZWVBZGFwdGVyLmlzRG9jdW1lbnRUeXBlTm9kZShjdXJyZW50Tm9kZSkpXG4gICAgICAgICAgICAgICAgdGhpcy5fc2VyaWFsaXplRG9jdW1lbnRUeXBlTm9kZShjdXJyZW50Tm9kZSk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5TZXJpYWxpemVyLnByb3RvdHlwZS5fc2VyaWFsaXplRWxlbWVudCA9IGZ1bmN0aW9uIChub2RlKSB7XG4gICAgdmFyIHRuID0gdGhpcy50cmVlQWRhcHRlci5nZXRUYWdOYW1lKG5vZGUpLFxuICAgICAgICBucyA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0TmFtZXNwYWNlVVJJKG5vZGUpLFxuICAgICAgICBxdWFsaWZpZWRUbiA9IChucyA9PT0gTlMuSFRNTCB8fCBucyA9PT0gTlMuU1ZHIHx8IG5zID09PSBOUy5NQVRITUwpID8gdG4gOiAobnMgKyAnOicgKyB0bik7XG5cbiAgICB0aGlzLmh0bWwgKz0gJzwnICsgcXVhbGlmaWVkVG47XG4gICAgdGhpcy5fc2VyaWFsaXplQXR0cmlidXRlcyhub2RlKTtcbiAgICB0aGlzLmh0bWwgKz0gJz4nO1xuXG4gICAgaWYgKHRuICE9PSAkLkFSRUEgJiYgdG4gIT09ICQuQkFTRSAmJiB0biAhPT0gJC5CQVNFRk9OVCAmJiB0biAhPT0gJC5CR1NPVU5EICYmIHRuICE9PSAkLkJSICYmIHRuICE9PSAkLkJSICYmXG4gICAgICAgIHRuICE9PSAkLkNPTCAmJiB0biAhPT0gJC5FTUJFRCAmJiB0biAhPT0gJC5GUkFNRSAmJiB0biAhPT0gJC5IUiAmJiB0biAhPT0gJC5JTUcgJiYgdG4gIT09ICQuSU5QVVQgJiZcbiAgICAgICAgdG4gIT09ICQuS0VZR0VOICYmIHRuICE9PSAkLkxJTksgJiYgdG4gIT09ICQuTUVOVUlURU0gJiYgdG4gIT09ICQuTUVUQSAmJiB0biAhPT0gJC5QQVJBTSAmJiB0biAhPT0gJC5TT1VSQ0UgJiZcbiAgICAgICAgdG4gIT09ICQuVFJBQ0sgJiYgdG4gIT09ICQuV0JSKSB7XG5cbiAgICAgICAgaWYgKHRuID09PSAkLlBSRSB8fCB0biA9PT0gJC5URVhUQVJFQSB8fCB0biA9PT0gJC5MSVNUSU5HKSB7XG4gICAgICAgICAgICB2YXIgZmlyc3RDaGlsZCA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0Rmlyc3RDaGlsZChub2RlKTtcblxuICAgICAgICAgICAgaWYgKGZpcnN0Q2hpbGQgJiYgdGhpcy50cmVlQWRhcHRlci5pc1RleHROb2RlKGZpcnN0Q2hpbGQpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNvbnRlbnQgPSB0aGlzLnRyZWVBZGFwdGVyLmdldFRleHROb2RlQ29udGVudChmaXJzdENoaWxkKTtcblxuICAgICAgICAgICAgICAgIGlmIChjb250ZW50WzBdID09PSAnXFxuJylcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5odG1sICs9ICdcXG4nO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNoaWxkTm9kZXNIb2xkZXIgPSB0biA9PT0gJC5URU1QTEFURSAmJiBucyA9PT0gTlMuSFRNTCA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmVlQWRhcHRlci5nZXRDaGlsZE5vZGVzKG5vZGUpWzBdIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlO1xuXG4gICAgICAgIHRoaXMuX3NlcmlhbGl6ZUNoaWxkTm9kZXMoY2hpbGROb2Rlc0hvbGRlcik7XG4gICAgICAgIHRoaXMuaHRtbCArPSAnPC8nICsgcXVhbGlmaWVkVG4gKyAnPic7XG4gICAgfVxufTtcblxuU2VyaWFsaXplci5wcm90b3R5cGUuX3NlcmlhbGl6ZUF0dHJpYnV0ZXMgPSBmdW5jdGlvbiAobm9kZSkge1xuICAgIHZhciBhdHRycyA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0QXR0ckxpc3Qobm9kZSk7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgYXR0cnNMZW5ndGggPSBhdHRycy5sZW5ndGg7IGkgPCBhdHRyc0xlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBhdHRyID0gYXR0cnNbaV0sXG4gICAgICAgICAgICB2YWx1ZSA9IHRoaXMub3B0aW9ucy5lbmNvZGVIdG1sRW50aXRpZXMgPyBlc2NhcGVTdHJpbmcoYXR0ci52YWx1ZSwgdHJ1ZSkgOiBhdHRyLnZhbHVlO1xuXG4gICAgICAgIHRoaXMuaHRtbCArPSAnICc7XG5cbiAgICAgICAgaWYgKCFhdHRyLm5hbWVzcGFjZSlcbiAgICAgICAgICAgIHRoaXMuaHRtbCArPSBhdHRyLm5hbWU7XG5cbiAgICAgICAgZWxzZSBpZiAoYXR0ci5uYW1lc3BhY2UgPT09IE5TLlhNTClcbiAgICAgICAgICAgIHRoaXMuaHRtbCArPSAneG1sOicgKyBhdHRyLm5hbWU7XG5cbiAgICAgICAgZWxzZSBpZiAoYXR0ci5uYW1lc3BhY2UgPT09IE5TLlhNTE5TKSB7XG4gICAgICAgICAgICBpZiAoYXR0ci5uYW1lICE9PSAneG1sbnMnKVxuICAgICAgICAgICAgICAgIHRoaXMuaHRtbCArPSAneG1sbnM6JztcblxuICAgICAgICAgICAgdGhpcy5odG1sICs9IGF0dHIubmFtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGVsc2UgaWYgKGF0dHIubmFtZXNwYWNlID09PSBOUy5YTElOSylcbiAgICAgICAgICAgIHRoaXMuaHRtbCArPSAneGxpbms6JyArIGF0dHIubmFtZTtcblxuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aGlzLmh0bWwgKz0gYXR0ci5uYW1lc3BhY2UgKyAnOicgKyBhdHRyLm5hbWU7XG5cbiAgICAgICAgdGhpcy5odG1sICs9ICc9XCInICsgdmFsdWUgKyAnXCInO1xuICAgIH1cbn07XG5cblNlcmlhbGl6ZXIucHJvdG90eXBlLl9zZXJpYWxpemVUZXh0Tm9kZSA9IGZ1bmN0aW9uIChub2RlKSB7XG4gICAgdmFyIGNvbnRlbnQgPSB0aGlzLnRyZWVBZGFwdGVyLmdldFRleHROb2RlQ29udGVudChub2RlKSxcbiAgICAgICAgcGFyZW50ID0gdGhpcy50cmVlQWRhcHRlci5nZXRQYXJlbnROb2RlKG5vZGUpLFxuICAgICAgICBwYXJlbnRUbiA9IHZvaWQgMDtcblxuICAgIGlmIChwYXJlbnQgJiYgdGhpcy50cmVlQWRhcHRlci5pc0VsZW1lbnROb2RlKHBhcmVudCkpXG4gICAgICAgIHBhcmVudFRuID0gdGhpcy50cmVlQWRhcHRlci5nZXRUYWdOYW1lKHBhcmVudCk7XG5cbiAgICBpZiAocGFyZW50VG4gPT09ICQuU1RZTEUgfHwgcGFyZW50VG4gPT09ICQuU0NSSVBUIHx8IHBhcmVudFRuID09PSAkLlhNUCB8fCBwYXJlbnRUbiA9PT0gJC5JRlJBTUUgfHxcbiAgICAgICAgcGFyZW50VG4gPT09ICQuTk9FTUJFRCB8fCBwYXJlbnRUbiA9PT0gJC5OT0ZSQU1FUyB8fCBwYXJlbnRUbiA9PT0gJC5QTEFJTlRFWFQgfHwgcGFyZW50VG4gPT09ICQuTk9TQ1JJUFQpIHtcbiAgICAgICAgdGhpcy5odG1sICs9IGNvbnRlbnQ7XG4gICAgfVxuXG4gICAgZWxzZVxuICAgICAgICB0aGlzLmh0bWwgKz0gdGhpcy5vcHRpb25zLmVuY29kZUh0bWxFbnRpdGllcyA/IGVzY2FwZVN0cmluZyhjb250ZW50LCBmYWxzZSkgOiBjb250ZW50O1xufTtcblxuU2VyaWFsaXplci5wcm90b3R5cGUuX3NlcmlhbGl6ZUNvbW1lbnROb2RlID0gZnVuY3Rpb24gKG5vZGUpIHtcbiAgICB0aGlzLmh0bWwgKz0gJzwhLS0nICsgdGhpcy50cmVlQWRhcHRlci5nZXRDb21tZW50Tm9kZUNvbnRlbnQobm9kZSkgKyAnLS0+Jztcbn07XG5cblNlcmlhbGl6ZXIucHJvdG90eXBlLl9zZXJpYWxpemVEb2N1bWVudFR5cGVOb2RlID0gZnVuY3Rpb24gKG5vZGUpIHtcbiAgICB2YXIgbmFtZSA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0RG9jdW1lbnRUeXBlTm9kZU5hbWUobm9kZSksXG4gICAgICAgIHB1YmxpY0lkID0gdGhpcy50cmVlQWRhcHRlci5nZXREb2N1bWVudFR5cGVOb2RlUHVibGljSWQobm9kZSksXG4gICAgICAgIHN5c3RlbUlkID0gdGhpcy50cmVlQWRhcHRlci5nZXREb2N1bWVudFR5cGVOb2RlU3lzdGVtSWQobm9kZSk7XG5cbiAgICB0aGlzLmh0bWwgKz0gJzwnICsgRG9jdHlwZS5zZXJpYWxpemVDb250ZW50KG5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCkgKyAnPic7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVG9rZW5pemVyID0gcmVxdWlyZSgnLi4vdG9rZW5pemF0aW9uL3Rva2VuaXplcicpLFxuICAgIFRva2VuaXplclByb3h5ID0gcmVxdWlyZSgnLi90b2tlbml6ZXJfcHJveHknKSxcbiAgICBVdGlscyA9IHJlcXVpcmUoJy4uL2NvbW1vbi91dGlscycpO1xuXG4vL0RlZmF1bHQgb3B0aW9uc1xudmFyIERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBkZWNvZGVIdG1sRW50aXRpZXM6IHRydWUsXG4gICAgbG9jYXRpb25JbmZvOiBmYWxzZVxufTtcblxuLy9Ta2lwcGluZyBoYW5kbGVyXG5mdW5jdGlvbiBza2lwKCkge1xuICAgIC8vTk9URTogZG8gbm90aGluZyA9KVxufVxuXG4vL1NpbXBsZUFwaVBhcnNlclxudmFyIFNpbXBsZUFwaVBhcnNlciA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGhhbmRsZXJzLCBvcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0gVXRpbHMubWVyZ2VPcHRpb25zKERFRkFVTFRfT1BUSU9OUywgb3B0aW9ucyk7XG4gICAgdGhpcy5oYW5kbGVycyA9IHtcbiAgICAgICAgZG9jdHlwZTogdGhpcy5fd3JhcEhhbmRsZXIoaGFuZGxlcnMuZG9jdHlwZSksXG4gICAgICAgIHN0YXJ0VGFnOiB0aGlzLl93cmFwSGFuZGxlcihoYW5kbGVycy5zdGFydFRhZyksXG4gICAgICAgIGVuZFRhZzogdGhpcy5fd3JhcEhhbmRsZXIoaGFuZGxlcnMuZW5kVGFnKSxcbiAgICAgICAgdGV4dDogdGhpcy5fd3JhcEhhbmRsZXIoaGFuZGxlcnMudGV4dCksXG4gICAgICAgIGNvbW1lbnQ6IHRoaXMuX3dyYXBIYW5kbGVyKGhhbmRsZXJzLmNvbW1lbnQpXG4gICAgfTtcbn07XG5cblNpbXBsZUFwaVBhcnNlci5wcm90b3R5cGUuX3dyYXBIYW5kbGVyID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgICB2YXIgcGFyc2VyID0gdGhpcztcblxuICAgIGhhbmRsZXIgPSBoYW5kbGVyIHx8IHNraXA7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmxvY2F0aW9uSW5mbykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgICAgICAgICAgYXJncy5wdXNoKHBhcnNlci5jdXJyZW50VG9rZW5Mb2NhdGlvbik7XG4gICAgICAgICAgICBoYW5kbGVyLmFwcGx5KGhhbmRsZXIsIGFyZ3MpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBoYW5kbGVyO1xufTtcblxuLy9BUElcblNpbXBsZUFwaVBhcnNlci5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbiAoaHRtbCkge1xuICAgIHZhciB0b2tlbiA9IG51bGw7XG5cbiAgICB0aGlzLl9yZXNldChodG1sKTtcblxuICAgIGRvIHtcbiAgICAgICAgdG9rZW4gPSB0aGlzLnRva2VuaXplclByb3h5LmdldE5leHRUb2tlbigpO1xuXG4gICAgICAgIGlmICh0b2tlbi50eXBlID09PSBUb2tlbml6ZXIuQ0hBUkFDVEVSX1RPS0VOIHx8XG4gICAgICAgICAgICB0b2tlbi50eXBlID09PSBUb2tlbml6ZXIuV0hJVEVTUEFDRV9DSEFSQUNURVJfVE9LRU4gfHxcbiAgICAgICAgICAgIHRva2VuLnR5cGUgPT09IFRva2VuaXplci5OVUxMX0NIQVJBQ1RFUl9UT0tFTikge1xuXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmxvY2F0aW9uSW5mbykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnBlbmRpbmdUZXh0ID09PSBudWxsKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbkxvY2F0aW9uID0gdG9rZW4ubG9jYXRpb247XG5cbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFRva2VuTG9jYXRpb24uZW5kID0gdG9rZW4ubG9jYXRpb24uZW5kO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnBlbmRpbmdUZXh0ID0gKHRoaXMucGVuZGluZ1RleHQgfHwgJycpICsgdG9rZW4uY2hhcnM7XG4gICAgICAgIH1cblxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2VtaXRQZW5kaW5nVGV4dCgpO1xuICAgICAgICAgICAgdGhpcy5faGFuZGxlVG9rZW4odG9rZW4pO1xuICAgICAgICB9XG4gICAgfSB3aGlsZSAodG9rZW4udHlwZSAhPT0gVG9rZW5pemVyLkVPRl9UT0tFTik7XG59O1xuXG4vL0ludGVybmFsc1xuU2ltcGxlQXBpUGFyc2VyLnByb3RvdHlwZS5faGFuZGxlVG9rZW4gPSBmdW5jdGlvbiAodG9rZW4pIHtcbiAgICBpZiAodGhpcy5vcHRpb25zLmxvY2F0aW9uSW5mbylcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW5Mb2NhdGlvbiA9IHRva2VuLmxvY2F0aW9uO1xuXG4gICAgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuaXplci5TVEFSVF9UQUdfVE9LRU4pXG4gICAgICAgIHRoaXMuaGFuZGxlcnMuc3RhcnRUYWcodG9rZW4udGFnTmFtZSwgdG9rZW4uYXR0cnMsIHRva2VuLnNlbGZDbG9zaW5nKTtcblxuICAgIGVsc2UgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuaXplci5FTkRfVEFHX1RPS0VOKVxuICAgICAgICB0aGlzLmhhbmRsZXJzLmVuZFRhZyh0b2tlbi50YWdOYW1lKTtcblxuICAgIGVsc2UgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuaXplci5DT01NRU5UX1RPS0VOKVxuICAgICAgICB0aGlzLmhhbmRsZXJzLmNvbW1lbnQodG9rZW4uZGF0YSk7XG5cbiAgICBlbHNlIGlmICh0b2tlbi50eXBlID09PSBUb2tlbml6ZXIuRE9DVFlQRV9UT0tFTilcbiAgICAgICAgdGhpcy5oYW5kbGVycy5kb2N0eXBlKHRva2VuLm5hbWUsIHRva2VuLnB1YmxpY0lkLCB0b2tlbi5zeXN0ZW1JZCk7XG5cbn07XG5cblNpbXBsZUFwaVBhcnNlci5wcm90b3R5cGUuX3Jlc2V0ID0gZnVuY3Rpb24gKGh0bWwpIHtcbiAgICB0aGlzLnRva2VuaXplclByb3h5ID0gbmV3IFRva2VuaXplclByb3h5KGh0bWwsIHRoaXMub3B0aW9ucyk7XG4gICAgdGhpcy5wZW5kaW5nVGV4dCA9IG51bGw7XG4gICAgdGhpcy5jdXJyZW50VG9rZW5Mb2NhdGlvbiA9IG51bGw7XG59O1xuXG5TaW1wbGVBcGlQYXJzZXIucHJvdG90eXBlLl9lbWl0UGVuZGluZ1RleHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMucGVuZGluZ1RleHQgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVycy50ZXh0KHRoaXMucGVuZGluZ1RleHQpO1xuICAgICAgICB0aGlzLnBlbmRpbmdUZXh0ID0gbnVsbDtcbiAgICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVG9rZW5pemVyID0gcmVxdWlyZSgnLi4vdG9rZW5pemF0aW9uL3Rva2VuaXplcicpLFxuICAgIEZvcmVpZ25Db250ZW50ID0gcmVxdWlyZSgnLi4vY29tbW9uL2ZvcmVpZ25fY29udGVudCcpLFxuICAgIFVOSUNPREUgPSByZXF1aXJlKCcuLi9jb21tb24vdW5pY29kZScpLFxuICAgIEhUTUwgPSByZXF1aXJlKCcuLi9jb21tb24vaHRtbCcpO1xuXG4vL0FsaWFzZXNcbnZhciAkID0gSFRNTC5UQUdfTkFNRVMsXG4gICAgTlMgPSBIVE1MLk5BTUVTUEFDRVM7XG5cblxuLy9Ub2tlbml6ZXIgcHJveHlcbi8vTk9URTogdGhpcyBwcm94eSBzaW11bGF0ZXMgYWRqdXN0bWVudCBvZiB0aGUgVG9rZW5pemVyIHdoaWNoIHBlcmZvcm1lZCBieSBzdGFuZGFyZCBwYXJzZXIgZHVyaW5nIHRyZWUgY29uc3RydWN0aW9uLlxudmFyIFRva2VuaXplclByb3h5ID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaHRtbCwgb3B0aW9ucykge1xuICAgIHRoaXMudG9rZW5pemVyID0gbmV3IFRva2VuaXplcihodG1sLCBvcHRpb25zKTtcblxuICAgIHRoaXMubmFtZXNwYWNlU3RhY2sgPSBbXTtcbiAgICB0aGlzLm5hbWVzcGFjZVN0YWNrVG9wID0gLTE7XG4gICAgdGhpcy5jdXJyZW50TmFtZXNwYWNlID0gbnVsbDtcbiAgICB0aGlzLmluRm9yZWlnbkNvbnRlbnQgPSBmYWxzZTtcbn07XG5cbi8vQVBJXG5Ub2tlbml6ZXJQcm94eS5wcm90b3R5cGUuZ2V0TmV4dFRva2VuID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB0b2tlbiA9IHRoaXMudG9rZW5pemVyLmdldE5leHRUb2tlbigpO1xuXG4gICAgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuaXplci5TVEFSVF9UQUdfVE9LRU4pXG4gICAgICAgIHRoaXMuX2hhbmRsZVN0YXJ0VGFnVG9rZW4odG9rZW4pO1xuXG4gICAgZWxzZSBpZiAodG9rZW4udHlwZSA9PT0gVG9rZW5pemVyLkVORF9UQUdfVE9LRU4pXG4gICAgICAgIHRoaXMuX2hhbmRsZUVuZFRhZ1Rva2VuKHRva2VuKTtcblxuICAgIGVsc2UgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuaXplci5OVUxMX0NIQVJBQ1RFUl9UT0tFTiAmJiB0aGlzLmluRm9yZWlnbkNvbnRlbnQpIHtcbiAgICAgICAgdG9rZW4udHlwZSA9IFRva2VuaXplci5DSEFSQUNURVJfVE9LRU47XG4gICAgICAgIHRva2VuLmNoYXJzID0gVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVI7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRva2VuO1xufTtcblxuLy9OYW1lc3BhY2Ugc3RhY2sgbXV0YXRpb25zXG5Ub2tlbml6ZXJQcm94eS5wcm90b3R5cGUuX2VudGVyTmFtZXNwYWNlID0gZnVuY3Rpb24gKG5hbWVzcGFjZSkge1xuICAgIHRoaXMubmFtZXNwYWNlU3RhY2tUb3ArKztcbiAgICB0aGlzLm5hbWVzcGFjZVN0YWNrLnB1c2gobmFtZXNwYWNlKTtcblxuICAgIHRoaXMuaW5Gb3JlaWduQ29udGVudCA9IG5hbWVzcGFjZSAhPT0gTlMuSFRNTDtcbiAgICB0aGlzLmN1cnJlbnROYW1lc3BhY2UgPSBuYW1lc3BhY2U7XG4gICAgdGhpcy50b2tlbml6ZXIuYWxsb3dDREFUQSA9IHRoaXMuaW5Gb3JlaWduQ29udGVudDtcbn07XG5cblRva2VuaXplclByb3h5LnByb3RvdHlwZS5fbGVhdmVDdXJyZW50TmFtZXNwYWNlID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMubmFtZXNwYWNlU3RhY2tUb3AtLTtcbiAgICB0aGlzLm5hbWVzcGFjZVN0YWNrLnBvcCgpO1xuXG4gICAgdGhpcy5jdXJyZW50TmFtZXNwYWNlID0gdGhpcy5uYW1lc3BhY2VTdGFja1t0aGlzLm5hbWVzcGFjZVN0YWNrVG9wXTtcbiAgICB0aGlzLmluRm9yZWlnbkNvbnRlbnQgPSB0aGlzLmN1cnJlbnROYW1lc3BhY2UgIT09IE5TLkhUTUw7XG4gICAgdGhpcy50b2tlbml6ZXIuYWxsb3dDREFUQSA9IHRoaXMuaW5Gb3JlaWduQ29udGVudDtcbn07XG5cbi8vVG9rZW4gaGFuZGxlcnNcblRva2VuaXplclByb3h5LnByb3RvdHlwZS5fZW5zdXJlVG9rZW5pemVyTW9kZSA9IGZ1bmN0aW9uICh0bikge1xuICAgIGlmICh0biA9PT0gJC5URVhUQVJFQSB8fCB0biA9PT0gJC5USVRMRSlcbiAgICAgICAgdGhpcy50b2tlbml6ZXIuc3RhdGUgPSBUb2tlbml6ZXIuTU9ERS5SQ0RBVEE7XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5QTEFJTlRFWFQpXG4gICAgICAgIHRoaXMudG9rZW5pemVyLnN0YXRlID0gVG9rZW5pemVyLk1PREUuUExBSU5URVhUO1xuXG4gICAgZWxzZSBpZiAodG4gPT09ICQuU0NSSVBUKVxuICAgICAgICB0aGlzLnRva2VuaXplci5zdGF0ZSA9IFRva2VuaXplci5NT0RFLlNDUklQVF9EQVRBO1xuXG4gICAgZWxzZSBpZiAodG4gPT09ICQuU1RZTEUgfHwgdG4gPT09ICQuSUZSQU1FIHx8IHRuID09PSAkLlhNUCB8fFxuICAgICAgICAgICAgIHRuID09PSAkLk5PRU1CRUQgfHwgdG4gPT09ICQuTk9GUkFNRVMgfHwgdG4gPT09ICQuTk9TQ1JJUFQpIHtcbiAgICAgICAgdGhpcy50b2tlbml6ZXIuc3RhdGUgPSBUb2tlbml6ZXIuTU9ERS5SQVdURVhUO1xuICAgIH1cbn07XG5cblRva2VuaXplclByb3h5LnByb3RvdHlwZS5faGFuZGxlU3RhcnRUYWdUb2tlbiA9IGZ1bmN0aW9uICh0b2tlbikge1xuICAgIHZhciB0biA9IHRva2VuLnRhZ05hbWU7XG5cbiAgICBpZiAodG4gPT09ICQuU1ZHKVxuICAgICAgICB0aGlzLl9lbnRlck5hbWVzcGFjZShOUy5TVkcpO1xuXG4gICAgZWxzZSBpZiAodG4gPT09ICQuTUFUSClcbiAgICAgICAgdGhpcy5fZW50ZXJOYW1lc3BhY2UoTlMuTUFUSE1MKTtcblxuICAgIGVsc2Uge1xuICAgICAgICBpZiAodGhpcy5pbkZvcmVpZ25Db250ZW50KSB7XG4gICAgICAgICAgICBpZiAoRm9yZWlnbkNvbnRlbnQuY2F1c2VzRXhpdCh0b2tlbikpXG4gICAgICAgICAgICAgICAgdGhpcy5fbGVhdmVDdXJyZW50TmFtZXNwYWNlKCk7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKEZvcmVpZ25Db250ZW50LmlzTWF0aE1MVGV4dEludGVncmF0aW9uUG9pbnQodG4sIHRoaXMuY3VycmVudE5hbWVzcGFjZSkgfHxcbiAgICAgICAgICAgICAgICAgICAgIEZvcmVpZ25Db250ZW50LmlzSHRtbEludGVncmF0aW9uUG9pbnQodG4sIHRoaXMuY3VycmVudE5hbWVzcGFjZSwgdG9rZW4uYXR0cnMpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZW50ZXJOYW1lc3BhY2UoTlMuSFRNTCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aGlzLl9lbnN1cmVUb2tlbml6ZXJNb2RlKHRuKTtcbiAgICB9XG59O1xuXG5Ub2tlbml6ZXJQcm94eS5wcm90b3R5cGUuX2hhbmRsZUVuZFRhZ1Rva2VuID0gZnVuY3Rpb24gKHRva2VuKSB7XG4gICAgdmFyIHRuID0gdG9rZW4udGFnTmFtZTtcblxuICAgIGlmICghdGhpcy5pbkZvcmVpZ25Db250ZW50KSB7XG4gICAgICAgIHZhciBwcmV2aW91c05zID0gdGhpcy5uYW1lc3BhY2VTdGFja1t0aGlzLm5hbWVzcGFjZVN0YWNrVG9wIC0gMV07XG5cbiAgICAgICAgLy9OT1RFOiBjaGVjayBmb3IgZXhpdCBmcm9tIGludGVncmF0aW9uIHBvaW50XG4gICAgICAgIGlmIChGb3JlaWduQ29udGVudC5pc01hdGhNTFRleHRJbnRlZ3JhdGlvblBvaW50KHRuLCBwcmV2aW91c05zKSB8fFxuICAgICAgICAgICAgRm9yZWlnbkNvbnRlbnQuaXNIdG1sSW50ZWdyYXRpb25Qb2ludCh0biwgcHJldmlvdXNOcywgdG9rZW4uYXR0cnMpKSB7XG4gICAgICAgICAgICB0aGlzLl9sZWF2ZUN1cnJlbnROYW1lc3BhY2UoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGVsc2UgaWYgKHRuID09PSAkLlNDUklQVClcbiAgICAgICAgICAgIHRoaXMudG9rZW5pemVyLnN0YXRlID0gVG9rZW5pemVyLk1PREUuREFUQTtcbiAgICB9XG5cbiAgICBlbHNlIGlmICgodG4gPT09ICQuU1ZHICYmIHRoaXMuY3VycmVudE5hbWVzcGFjZSA9PT0gTlMuU1ZHKSB8fFxuICAgICAgICAgICAgICh0biA9PT0gJC5NQVRIICYmIHRoaXMuY3VycmVudE5hbWVzcGFjZSA9PT0gTlMuTUFUSE1MKSlcbiAgICAgICAgdGhpcy5fbGVhdmVDdXJyZW50TmFtZXNwYWNlKCk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxuZXhwb3J0cy5hc3NpZ24gPSBmdW5jdGlvbiAodG9rZW5pemVyKSB7XHJcbiAgICAvL05PVEU6IG9idGFpbiBUb2tlbml6ZXIgcHJvdG8gdGhpcyB3YXkgdG8gYXZvaWQgbW9kdWxlIGNpcmN1bGFyIHJlZmVyZW5jZXNcclxuICAgIHZhciB0b2tlbml6ZXJQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZih0b2tlbml6ZXIpO1xyXG5cclxuICAgIHRva2VuaXplci50b2tlblN0YXJ0TG9jID0gLTE7XHJcblxyXG4gICAgLy9OT1RFOiBhZGQgbG9jYXRpb24gaW5mbyBidWlsZGVyIG1ldGhvZFxyXG4gICAgdG9rZW5pemVyLl9hdHRhY2hMb2NhdGlvbkluZm8gPSBmdW5jdGlvbiAodG9rZW4pIHtcclxuICAgICAgICB0b2tlbi5sb2NhdGlvbiA9IHtcclxuICAgICAgICAgICAgc3RhcnQ6IHRoaXMudG9rZW5TdGFydExvYyxcclxuICAgICAgICAgICAgZW5kOiAtMVxyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG5cclxuICAgIC8vTk9URTogcGF0Y2ggdG9rZW4gY3JlYXRpb24gbWV0aG9kcyBhbmQgYXR0YWNoIGxvY2F0aW9uIG9iamVjdHNcclxuICAgIHRva2VuaXplci5fY3JlYXRlU3RhcnRUYWdUb2tlbiA9IGZ1bmN0aW9uICh0YWdOYW1lRmlyc3RDaCkge1xyXG4gICAgICAgIHRva2VuaXplclByb3RvLl9jcmVhdGVTdGFydFRhZ1Rva2VuLmNhbGwodGhpcywgdGFnTmFtZUZpcnN0Q2gpO1xyXG4gICAgICAgIHRoaXMuX2F0dGFjaExvY2F0aW9uSW5mbyh0aGlzLmN1cnJlbnRUb2tlbik7XHJcbiAgICB9O1xyXG5cclxuICAgIHRva2VuaXplci5fY3JlYXRlRW5kVGFnVG9rZW4gPSBmdW5jdGlvbiAodGFnTmFtZUZpcnN0Q2gpIHtcclxuICAgICAgICB0b2tlbml6ZXJQcm90by5fY3JlYXRlRW5kVGFnVG9rZW4uY2FsbCh0aGlzLCB0YWdOYW1lRmlyc3RDaCk7XHJcbiAgICAgICAgdGhpcy5fYXR0YWNoTG9jYXRpb25JbmZvKHRoaXMuY3VycmVudFRva2VuKTtcclxuICAgIH07XHJcblxyXG4gICAgdG9rZW5pemVyLl9jcmVhdGVDb21tZW50VG9rZW4gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdG9rZW5pemVyUHJvdG8uX2NyZWF0ZUNvbW1lbnRUb2tlbi5jYWxsKHRoaXMpO1xyXG4gICAgICAgIHRoaXMuX2F0dGFjaExvY2F0aW9uSW5mbyh0aGlzLmN1cnJlbnRUb2tlbik7XHJcbiAgICB9O1xyXG5cclxuICAgIHRva2VuaXplci5fY3JlYXRlRG9jdHlwZVRva2VuID0gZnVuY3Rpb24gKGRvY3R5cGVOYW1lRmlyc3RDaCkge1xyXG4gICAgICAgIHRva2VuaXplclByb3RvLl9jcmVhdGVEb2N0eXBlVG9rZW4uY2FsbCh0aGlzLCBkb2N0eXBlTmFtZUZpcnN0Q2gpO1xyXG4gICAgICAgIHRoaXMuX2F0dGFjaExvY2F0aW9uSW5mbyh0aGlzLmN1cnJlbnRUb2tlbik7XHJcbiAgICB9O1xyXG5cclxuICAgIHRva2VuaXplci5fY3JlYXRlQ2hhcmFjdGVyVG9rZW4gPSBmdW5jdGlvbiAodHlwZSwgY2gpIHtcclxuICAgICAgICB0b2tlbml6ZXJQcm90by5fY3JlYXRlQ2hhcmFjdGVyVG9rZW4uY2FsbCh0aGlzLCB0eXBlLCBjaCk7XHJcbiAgICAgICAgdGhpcy5fYXR0YWNoTG9jYXRpb25JbmZvKHRoaXMuY3VycmVudENoYXJhY3RlclRva2VuKTtcclxuICAgIH07XHJcblxyXG4gICAgLy9OT1RFOiBwYXRjaCB0b2tlbiBlbWlzc2lvbiBtZXRob2RzIHRvIGRldGVybWluZSBlbmQgbG9jYXRpb25cclxuICAgIHRva2VuaXplci5fZW1pdEN1cnJlbnRUb2tlbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvL05PVEU6IGlmIHdlIGhhdmUgcGVuZGluZyBjaGFyYWN0ZXIgdG9rZW4gbWFrZSBpdCdzIGVuZCBsb2NhdGlvbiBlcXVhbCB0byB0aGVcclxuICAgICAgICAvL2N1cnJlbnQgdG9rZW4ncyBzdGFydCBsb2NhdGlvbi5cclxuICAgICAgICBpZiAodGhpcy5jdXJyZW50Q2hhcmFjdGVyVG9rZW4pXHJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudENoYXJhY3RlclRva2VuLmxvY2F0aW9uLmVuZCA9IHRoaXMuY3VycmVudFRva2VuLmxvY2F0aW9uLnN0YXJ0O1xyXG5cclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5sb2NhdGlvbi5lbmQgPSB0aGlzLnByZXByb2Nlc3Nvci5wb3MgKyAxO1xyXG4gICAgICAgIHRva2VuaXplclByb3RvLl9lbWl0Q3VycmVudFRva2VuLmNhbGwodGhpcyk7XHJcbiAgICB9O1xyXG5cclxuICAgIHRva2VuaXplci5fZW1pdEN1cnJlbnRDaGFyYWN0ZXJUb2tlbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvL05PVEU6IGlmIHdlIGhhdmUgY2hhcmFjdGVyIHRva2VuIGFuZCBpdCdzIGxvY2F0aW9uIHdhc24ndCBzZXQgaW4gdGhlIF9lbWl0Q3VycmVudFRva2VuKCksXHJcbiAgICAgICAgLy90aGVuIHNldCBpdCdzIGxvY2F0aW9uIGF0IHRoZSBjdXJyZW50IHByZXByb2Nlc3NvciBwb3NpdGlvblxyXG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRDaGFyYWN0ZXJUb2tlbiAmJiB0aGlzLmN1cnJlbnRDaGFyYWN0ZXJUb2tlbi5sb2NhdGlvbi5lbmQgPT09IC0xKSB7XHJcbiAgICAgICAgICAgIC8vTk9URTogd2UgZG9uJ3QgbmVlZCB0byBpbmNyZW1lbnQgcHJlcHJvY2Vzc29yIHBvc2l0aW9uLCBzaW5jZSBjaGFyYWN0ZXIgdG9rZW5cclxuICAgICAgICAgICAgLy9lbWlzc2lvbiBpcyBhbHdheXMgZm9yY2VkIGJ5IHRoZSBzdGFydCBvZiB0aGUgbmV4dCBjaGFyYWN0ZXIgdG9rZW4gaGVyZS5cclxuICAgICAgICAgICAgLy9Tbywgd2UgYWxyZWFkeSBoYXZlIGFkdmFuY2VkIHBvc2l0aW9uLlxyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRDaGFyYWN0ZXJUb2tlbi5sb2NhdGlvbi5lbmQgPSB0aGlzLnByZXByb2Nlc3Nvci5wb3M7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0b2tlbml6ZXJQcm90by5fZW1pdEN1cnJlbnRDaGFyYWN0ZXJUb2tlbi5jYWxsKHRoaXMpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvL05PVEU6IHBhdGNoIGluaXRpYWwgc3RhdGVzIGZvciBlYWNoIG1vZGUgdG8gb2J0YWluIHRva2VuIHN0YXJ0IHBvc2l0aW9uXHJcbiAgICBPYmplY3Qua2V5cyh0b2tlbml6ZXJQcm90by5NT0RFKVxyXG5cclxuICAgICAgICAubWFwKGZ1bmN0aW9uIChtb2RlTmFtZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdG9rZW5pemVyUHJvdG8uTU9ERVttb2RlTmFtZV07XHJcbiAgICAgICAgfSlcclxuXHJcbiAgICAgICAgLmZvckVhY2goZnVuY3Rpb24gKHN0YXRlKSB7XHJcbiAgICAgICAgICAgIHRva2VuaXplcltzdGF0ZV0gPSBmdW5jdGlvbiAoY3ApIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudG9rZW5TdGFydExvYyA9IHRoaXMucHJlcHJvY2Vzc29yLnBvcztcclxuICAgICAgICAgICAgICAgIHRva2VuaXplclByb3RvW3N0YXRlXS5jYWxsKHRoaXMsIGNwKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9KTtcclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxuLy9OT1RFOiB0aGlzIGZpbGUgY29udGFpbnMgYXV0byBnZW5lcmF0ZWQgdHJpZSBzdHJ1Y3R1cmUgdGhhdCBpcyB1c2VkIGZvciBuYW1lZCBlbnRpdHkgcmVmZXJlbmNlcyBjb25zdW1wdGlvblxyXG4vLyhzZWU6IGh0dHA6Ly93d3cud2hhdHdnLm9yZy9zcGVjcy93ZWItYXBwcy9jdXJyZW50LXdvcmsvbXVsdGlwYWdlL3Rva2VuaXphdGlvbi5odG1sI3Rva2VuaXppbmctY2hhcmFjdGVyLXJlZmVyZW5jZXMgYW5kXHJcbi8vaHR0cDovL3d3dy53aGF0d2cub3JnL3NwZWNzL3dlYi1hcHBzL2N1cnJlbnQtd29yay9tdWx0aXBhZ2UvbmFtZWQtY2hhcmFjdGVyLXJlZmVyZW5jZXMuaHRtbCNuYW1lZC1jaGFyYWN0ZXItcmVmZXJlbmNlcylcclxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgICAweDQxOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzE5M119fSwgYzogWzE5M119fX19fX19fX0sIDB4NjI6IHtsOiB7MHg3Mjoge2w6IHsweDY1OiB7bDogezB4NzY6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzI1OF19fX19fX19fX19fSwgMHg2Mzoge2w6IHsweDY5OiB7bDogezB4NzI6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzE5NF19fSwgYzogWzE5NF19fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzEwNDBdfX19fX0sIDB4NDU6IHtsOiB7MHg2Qzoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHgzQjoge2M6IFsxOThdfX0sIGM6IFsxOThdfX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDY4XX19fX19LCAweDY3OiB7bDogezB4NzI6IHtsOiB7MHg2MToge2w6IHsweDc2OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsxOTJdfX0sIGM6IFsxOTJdfX19fX19fX19LCAweDZDOiB7bDogezB4NzA6IHtsOiB7MHg2ODoge2w6IHsweDYxOiB7bDogezB4M0I6IHtjOiBbOTEzXX19fX19fX19fSwgMHg2RDoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzI1Nl19fX19fX19fX0sIDB4NEQ6IHtsOiB7MHg1MDoge2w6IHsweDNCOiB7YzogWzM4XX19LCBjOiBbMzhdfX19LCAweDZFOiB7bDogezB4NjQ6IHtsOiB7MHgzQjoge2M6IFsxMDgzNV19fX19fSwgMHg2Rjoge2w6IHsweDY3OiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzI2MF19fX19fX19LCAweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxMjBdfX19fX19fSwgMHg3MDoge2w6IHsweDcwOiB7bDogezB4NkM6IHtsOiB7MHg3OToge2w6IHsweDQ2OiB7bDogezB4NzU6IHtsOiB7MHg2RToge2w6IHsweDYzOiB7bDogezB4NzQ6IHtsOiB7MHg2OToge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs4Mjg5XX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4Njc6IHtsOiB7MHgzQjoge2M6IFsxOTddfX0sIGM6IFsxOTddfX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMTk5NjRdfX19fX0sIDB4NzM6IHtsOiB7MHg2OToge2w6IHsweDY3OiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs4Nzg4XX19fX19fX19fX19LCAweDc0OiB7bDogezB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDY0OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsxOTVdfX0sIGM6IFsxOTVdfX19fX19fX19LCAweDc1OiB7bDogezB4NkQ6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzE5Nl19fSwgYzogWzE5Nl19fX19fX19LFxyXG4gICAgMHg2MToge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg3NToge2w6IHsweDc0OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsyMjVdfX0sIGM6IFsyMjVdfX19fX19fX19LCAweDYyOiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDc2OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsyNTldfX19fX19fX19fX0sIDB4NjM6IHtsOiB7MHgzQjoge2M6IFs4NzY2XX0sIDB4NjQ6IHtsOiB7MHgzQjoge2M6IFs4NzY3XX19fSwgMHg0NToge2w6IHsweDNCOiB7YzogWzg3NjYsIDgxOV19fX0sIDB4Njk6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbMjI2XX19LCBjOiBbMjI2XX19fX19LCAweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzE4MF19fSwgYzogWzE4MF19fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzEwNzJdfX19fX0sIDB4NjU6IHtsOiB7MHg2Qzoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHgzQjoge2M6IFsyMzBdfX0sIGM6IFsyMzBdfX19fX19fSwgMHg2Njoge2w6IHsweDNCOiB7YzogWzgyODldfSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDA5NF19fX19fSwgMHg2Nzoge2w6IHsweDcyOiB7bDogezB4NjE6IHtsOiB7MHg3Njoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbMjI0XX19LCBjOiBbMjI0XX19fX19fX19fSwgMHg2Qzoge2w6IHsweDY1OiB7bDogezB4NjY6IHtsOiB7MHg3Mzoge2w6IHsweDc5OiB7bDogezB4NkQ6IHtsOiB7MHgzQjoge2M6IFs4NTAxXX19fX19fX19fSwgMHg3MDoge2w6IHsweDY4OiB7bDogezB4M0I6IHtjOiBbODUwMV19fX19fX19LCAweDcwOiB7bDogezB4Njg6IHtsOiB7MHg2MToge2w6IHsweDNCOiB7YzogWzk0NV19fX19fX19fX0sIDB4NkQ6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsyNTddfX19fX0sIDB4NkM6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzEwODE1XX19fX19fX0sIDB4NzA6IHtsOiB7MHgzQjoge2M6IFszOF19fSwgYzogWzM4XX19fSwgMHg2RToge2w6IHsweDY0OiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDY0OiB7bDogezB4M0I6IHtjOiBbMTA4MzddfX19fX19fSwgMHgzQjoge2M6IFs4NzQzXX0sIDB4NjQ6IHtsOiB7MHgzQjoge2M6IFsxMDg0NF19fX0sIDB4NzM6IHtsOiB7MHg2Qzoge2w6IHsweDZGOiB7bDogezB4NzA6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzEwODQwXX19fX19fX19fX19LCAweDc2OiB7bDogezB4M0I6IHtjOiBbMTA4NDJdfX19fX0sIDB4Njc6IHtsOiB7MHgzQjoge2M6IFs4NzM2XX0sIDB4NjU6IHtsOiB7MHgzQjoge2M6IFsxMDY2MF19fX0sIDB4NkM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg3MzZdfX19fX0sIDB4NkQ6IHtsOiB7MHg3Mzoge2w6IHsweDY0OiB7bDogezB4NjE6IHtsOiB7MHg2MToge2w6IHsweDNCOiB7YzogWzEwNjY0XX19fSwgMHg2Mjoge2w6IHsweDNCOiB7YzogWzEwNjY1XX19fSwgMHg2Mzoge2w6IHsweDNCOiB7YzogWzEwNjY2XX19fSwgMHg2NDoge2w6IHsweDNCOiB7YzogWzEwNjY3XX19fSwgMHg2NToge2w6IHsweDNCOiB7YzogWzEwNjY4XX19fSwgMHg2Njoge2w6IHsweDNCOiB7YzogWzEwNjY5XX19fSwgMHg2Nzoge2w6IHsweDNCOiB7YzogWzEwNjcwXX19fSwgMHg2ODoge2w6IHsweDNCOiB7YzogWzEwNjcxXX19fX19LCAweDNCOiB7YzogWzg3MzddfX19fX19fSwgMHg3Mjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODczNV19LCAweDc2OiB7bDogezB4NjI6IHtsOiB7MHgzQjoge2M6IFs4ODk0XX0sIDB4NjQ6IHtsOiB7MHgzQjoge2M6IFsxMDY1M119fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDcwOiB7bDogezB4Njg6IHtsOiB7MHgzQjoge2M6IFs4NzM4XX19fX19LCAweDc0OiB7bDogezB4M0I6IHtjOiBbMTk3XX19fX19LCAweDdBOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbOTA4NF19fX19fX19fX19fX19LCAweDZGOiB7bDogezB4Njc6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbMjYxXX19fX19fX0sIDB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDE0Nl19fX19fX19LCAweDcwOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDY5OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDg2M119fX19fX19fX0sIDB4M0I6IHtjOiBbODc3Nl19LCAweDQ1OiB7bDogezB4M0I6IHtjOiBbMTA4NjRdfX19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbODc3OF19fX0sIDB4Njk6IHtsOiB7MHg2NDoge2w6IHsweDNCOiB7YzogWzg3NzldfX19fX0sIDB4NkY6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzM5XX19fX19LCAweDcwOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc4OiB7bDogezB4M0I6IHtjOiBbODc3Nl19LCAweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFs4Nzc4XX19fX19fX19fX19fX19fSwgMHg3Mjoge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzIyOV19fSwgYzogWzIyOV19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzExOTk5MF19fX19fSwgMHg3NDoge2w6IHsweDNCOiB7YzogWzQyXX19fSwgMHg3OToge2w6IHsweDZEOiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFs4Nzc2XX0sIDB4NjU6IHtsOiB7MHg3MToge2w6IHsweDNCOiB7YzogWzg3ODFdfX19fX19fX19fX19fSwgMHg3NDoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHg2NDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbMjI3XX19LCBjOiBbMjI3XX19fX19fX19fSwgMHg3NToge2w6IHsweDZEOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsyMjhdfX0sIGM6IFsyMjhdfX19fX0sIDB4Nzc6IHtsOiB7MHg2Mzoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4NzU1XX19fX19fX19fX19fX0sIDB4Njk6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA3NjldfX19fX19fX19fX0sXHJcbiAgICAweDYyOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDZCOiB7bDogezB4NjM6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4Njc6IHtsOiB7MHgzQjoge2M6IFs4NzgwXX19fX19fX19fSwgMHg2NToge2w6IHsweDcwOiB7bDogezB4NzM6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzEwMTRdfX19fX19fX19fX19fX19LCAweDcwOiB7bDogezB4NzI6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4MjQ1XX19fX19fX19fX19LCAweDczOiB7bDogezB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzg3NjVdfSwgMHg2NToge2w6IHsweDcxOiB7bDogezB4M0I6IHtjOiBbODkwOV19fX19fX19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg3Njoge2w6IHsweDY1OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4ODkzXX19fX19fX0sIDB4Nzc6IHtsOiB7MHg2NToge2w6IHsweDY0OiB7bDogezB4M0I6IHtjOiBbODk2NV19LCAweDY3OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4OTY1XX19fX19fX19fX19fX19fSwgMHg2Mjoge2w6IHsweDcyOiB7bDogezB4NkI6IHtsOiB7MHgzQjoge2M6IFs5MTQxXX0sIDB4NzQ6IHtsOiB7MHg2Mjoge2w6IHsweDcyOiB7bDogezB4NkI6IHtsOiB7MHgzQjoge2M6IFs5MTQyXX19fX19fX19fX19fX19fSwgMHg2Mzoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzg3ODBdfX19fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzEwNzNdfX19fX0sIDB4NjQ6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NkY6IHtsOiB7MHgzQjoge2M6IFs4MjIyXX19fX19fX19fSwgMHg2NToge2w6IHsweDYzOiB7bDogezB4NjE6IHtsOiB7MHg3NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODc1N119LCAweDY1OiB7bDogezB4M0I6IHtjOiBbODc1N119fX19fX19fX19fSwgMHg2RDoge2w6IHsweDcwOiB7bDogezB4NzQ6IHtsOiB7MHg3OToge2w6IHsweDc2OiB7bDogezB4M0I6IHtjOiBbMTA2NzJdfX19fX19fX19fX0sIDB4NzA6IHtsOiB7MHg3Mzoge2w6IHsweDY5OiB7bDogezB4M0I6IHtjOiBbMTAxNF19fX19fX19LCAweDcyOiB7bDogezB4NkU6IHtsOiB7MHg2Rjoge2w6IHsweDc1OiB7bDogezB4M0I6IHtjOiBbODQ5Ml19fX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDNCOiB7YzogWzk0Nl19fX0sIDB4Njg6IHtsOiB7MHgzQjoge2M6IFs4NTAyXX19fSwgMHg3Nzoge2w6IHsweDY1OiB7bDogezB4NjU6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzg4MTJdfX19fX19fX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDk1XX19fX19LCAweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2Mzoge2w6IHsweDYxOiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFs4ODk4XX19fX19LCAweDY5OiB7bDogezB4NzI6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzk3MTFdfX19fX19fSwgMHg3NToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbODg5OV19fX19fX19LCAweDZGOiB7bDogezB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA3NTJdfX19fX19fSwgMHg3MDoge2w6IHsweDZDOiB7bDogezB4NzU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzEwNzUzXX19fX19fX19fSwgMHg3NDoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHg2NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbMTA3NTRdfX19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDcxOiB7bDogezB4NjM6IHtsOiB7MHg3NToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbMTA3NThdfX19fX19fX19LCAweDc0OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzk3MzNdfX19fX19fX19LCAweDc0OiB7bDogezB4NzI6IHtsOiB7MHg2OToge2w6IHsweDYxOiB7bDogezB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2NDoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzk2NjFdfX19fX19fX19LCAweDc1OiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFs5NjUxXX19fX19fX19fX19fX19fX19fX19fSwgMHg3NToge2w6IHsweDcwOiB7bDogezB4NkM6IHtsOiB7MHg3NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbMTA3NTZdfX19fX19fX19fX0sIDB4NzY6IHtsOiB7MHg2NToge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODg5N119fX19fX19LCAweDc3OiB7bDogezB4NjU6IHtsOiB7MHg2NDoge2w6IHsweDY3OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4ODk2XX19fX19fX19fX19fX19fSwgMHg2Qjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbMTA1MDldfX19fX19fX19fX0sIDB4NkM6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NkI6IHtsOiB7MHg2Qzoge2w6IHsweDZGOiB7bDogezB4N0E6IHtsOiB7MHg2NToge2w6IHsweDZFOiB7bDogezB4Njc6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzEwNzMxXX19fX19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs5NjQyXX19fX19fX19fX19fX0sIDB4NzQ6IHtsOiB7MHg3Mjoge2w6IHsweDY5OiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDY3OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzk2NTJdfSwgMHg2NDoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzk2NjJdfX19fX19fX19LCAweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbOTY2Nl19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2OToge2w6IHsweDY3OiB7bDogezB4Njg6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzk2NTZdfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg2RToge2w6IHsweDZCOiB7bDogezB4M0I6IHtjOiBbOTI1MV19fX19fX19LCAweDZCOiB7bDogezB4MzE6IHtsOiB7MHgzMjoge2w6IHsweDNCOiB7YzogWzk2MThdfX19LCAweDM0OiB7bDogezB4M0I6IHtjOiBbOTYxN119fX19fSwgMHgzMzoge2w6IHsweDM0OiB7bDogezB4M0I6IHtjOiBbOTYxOV19fX19fX19LCAweDZGOiB7bDogezB4NjM6IHtsOiB7MHg2Qjoge2w6IHsweDNCOiB7YzogWzk2MDhdfX19fX19fX19LCAweDZFOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs2MSwgODQyMV19LCAweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2OToge2w6IHsweDc2OiB7bDogezB4M0I6IHtjOiBbODgwMSwgODQyMV19fX19fX19fX19fSwgMHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODk3Nl19fX19fX19LCAweDRFOiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwOTg5XX19fX19fX0sIDB4NkY6IHtsOiB7MHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbMTIwMTQ3XX19fX19LCAweDc0OiB7bDogezB4M0I6IHtjOiBbODg2OV19LCAweDc0OiB7bDogezB4NkY6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzg4NjldfX19fX19fX19LCAweDc3OiB7bDogezB4NzQ6IHtsOiB7MHg2OToge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODkwNF19fX19fX19fX0sIDB4Nzg6IHtsOiB7MHg2Mjoge2w6IHsweDZGOiB7bDogezB4Nzg6IHtsOiB7MHgzQjoge2M6IFsxMDY5N119fX19fX19LCAweDY0OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs5NDg4XX19fSwgMHg0Qzoge2w6IHsweDNCOiB7YzogWzk1NTddfX19LCAweDcyOiB7bDogezB4M0I6IHtjOiBbOTQ4NF19fX0sIDB4NTI6IHtsOiB7MHgzQjoge2M6IFs5NTU0XX19fX19LCAweDQ0OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs5NTU4XX19fSwgMHg0Qzoge2w6IHsweDNCOiB7YzogWzk1NTldfX19LCAweDcyOiB7bDogezB4M0I6IHtjOiBbOTU1NV19fX0sIDB4NTI6IHtsOiB7MHgzQjoge2M6IFs5NTU2XX19fX19LCAweDY4OiB7bDogezB4M0I6IHtjOiBbOTQ3Ml19LCAweDY0OiB7bDogezB4M0I6IHtjOiBbOTUxNl19fX0sIDB4NDQ6IHtsOiB7MHgzQjoge2M6IFs5NTczXX19fSwgMHg3NToge2w6IHsweDNCOiB7YzogWzk1MjRdfX19LCAweDU1OiB7bDogezB4M0I6IHtjOiBbOTU3Nl19fX19fSwgMHg0ODoge2w6IHsweDNCOiB7YzogWzk1NTJdfSwgMHg2NDoge2w6IHsweDNCOiB7YzogWzk1NzJdfX19LCAweDQ0OiB7bDogezB4M0I6IHtjOiBbOTU3NF19fX0sIDB4NzU6IHtsOiB7MHgzQjoge2M6IFs5NTc1XX19fSwgMHg1NToge2w6IHsweDNCOiB7YzogWzk1NzddfX19fX0sIDB4NkQ6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4NzU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzg4NjNdfX19fX19fX19fX0sIDB4NzA6IHtsOiB7MHg2Qzoge2w6IHsweDc1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4ODYyXX19fX19fX19fSwgMHg3NDoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHg2NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODg2NF19fX19fX19fX19fSwgMHg3NToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbOTQ5Nl19fX0sIDB4NEM6IHtsOiB7MHgzQjoge2M6IFs5NTYzXX19fSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzk0OTJdfX19LCAweDUyOiB7bDogezB4M0I6IHtjOiBbOTU2MF19fX19fSwgMHg1NToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbOTU2NF19fX0sIDB4NEM6IHtsOiB7MHgzQjoge2M6IFs5NTY1XX19fSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzk1NjFdfX19LCAweDUyOiB7bDogezB4M0I6IHtjOiBbOTU2Ml19fX19fSwgMHg3Njoge2w6IHsweDNCOiB7YzogWzk0NzRdfSwgMHg2ODoge2w6IHsweDNCOiB7YzogWzk1MzJdfX19LCAweDQ4OiB7bDogezB4M0I6IHtjOiBbOTU3OF19fX0sIDB4NkM6IHtsOiB7MHgzQjoge2M6IFs5NTA4XX19fSwgMHg0Qzoge2w6IHsweDNCOiB7YzogWzk1NjldfX19LCAweDcyOiB7bDogezB4M0I6IHtjOiBbOTUwMF19fX0sIDB4NTI6IHtsOiB7MHgzQjoge2M6IFs5NTY2XX19fX19LCAweDU2OiB7bDogezB4M0I6IHtjOiBbOTU1M119LCAweDY4OiB7bDogezB4M0I6IHtjOiBbOTU3OV19fX0sIDB4NDg6IHtsOiB7MHgzQjoge2M6IFs5NTgwXX19fSwgMHg2Qzoge2w6IHsweDNCOiB7YzogWzk1NzBdfX19LCAweDRDOiB7bDogezB4M0I6IHtjOiBbOTU3MV19fX0sIDB4NzI6IHtsOiB7MHgzQjoge2M6IFs5NTY3XX19fSwgMHg1Mjoge2w6IHsweDNCOiB7YzogWzk1NjhdfX19fX19fX19LCAweDcwOiB7bDogezB4NzI6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4MjQ1XX19fX19fX19fX19LCAweDcyOiB7bDogezB4NjU6IHtsOiB7MHg3Njoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbNzI4XX19fX19fX0sIDB4NzY6IHtsOiB7MHg2Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxNjZdfX0sIGM6IFsxNjZdfX19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzExOTk5MV19fX19fSwgMHg2NToge2w6IHsweDZEOiB7bDogezB4Njk6IHtsOiB7MHgzQjoge2M6IFs4MjcxXX19fX19fX0sIDB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzg3NjVdfSwgMHg2NToge2w6IHsweDNCOiB7YzogWzg5MDldfX19fX19fSwgMHg2Rjoge2w6IHsweDZDOiB7bDogezB4NjI6IHtsOiB7MHgzQjoge2M6IFsxMDY5M119fX0sIDB4M0I6IHtjOiBbOTJdfSwgMHg2ODoge2w6IHsweDczOiB7bDogezB4NzU6IHtsOiB7MHg2Mjoge2w6IHsweDNCOiB7YzogWzEwMTg0XX19fX19fX19fX19fX19fSwgMHg3NToge2w6IHsweDZDOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4MjI2XX0sIDB4NjU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzgyMjZdfX19fX19fX19LCAweDZEOiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFs4NzgyXX0sIDB4NDU6IHtsOiB7MHgzQjoge2M6IFsxMDkyNl19fX0sIDB4NjU6IHtsOiB7MHgzQjoge2M6IFs4NzgzXX0sIDB4NzE6IHtsOiB7MHgzQjoge2M6IFs4NzgzXX19fX19fX19fX19fX0sXHJcbiAgICAweDQyOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDZCOiB7bDogezB4NzM6IHtsOiB7MHg2Qzoge2w6IHsweDYxOiB7bDogezB4NzM6IHtsOiB7MHg2ODoge2w6IHsweDNCOiB7YzogWzg3MjZdfX19fX19fX19fX19fX19LCAweDcyOiB7bDogezB4NzY6IHtsOiB7MHgzQjoge2M6IFsxMDk4M119fX0sIDB4Nzc6IHtsOiB7MHg2NToge2w6IHsweDY0OiB7bDogezB4M0I6IHtjOiBbODk2Nl19fX19fX19fX19fSwgMHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTA0MV19fX19fSwgMHg2NToge2w6IHsweDYzOiB7bDogezB4NjE6IHtsOiB7MHg3NToge2w6IHsweDczOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4NzU3XX19fX19fX19fX19LCAweDcyOiB7bDogezB4NkU6IHtsOiB7MHg2Rjoge2w6IHsweDc1OiB7bDogezB4NkM6IHtsOiB7MHg2Qzoge2w6IHsweDY5OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4NDkyXX19fX19fX19fX19fX19fX19LCAweDc0OiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs5MTRdfX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDY5XX19fX19LCAweDZGOiB7bDogezB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDEyMV19fX19fX19LCAweDcyOiB7bDogezB4NjU6IHtsOiB7MHg3Njoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbNzI4XX19fX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NDkyXX19fX19fX0sIDB4NzU6IHtsOiB7MHg2RDoge2w6IHsweDcwOiB7bDogezB4NjU6IHtsOiB7MHg3MToge2w6IHsweDNCOiB7YzogWzg3ODJdfX19fX19fX19fX19fSxcclxuICAgIDB4NDM6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NzU6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbMjYyXX19fX19fX19fSwgMHg3MDoge2w6IHsweDNCOiB7YzogWzg5MTRdfSwgMHg2OToge2w6IHsweDc0OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDQ0OiB7bDogezB4Njk6IHtsOiB7MHg2Njoge2w6IHsweDY2OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDY1OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDY5OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDQ0OiB7bDogezB4M0I6IHtjOiBbODUxN119fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDc5OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDc5OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4NDkzXX19fX19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzI2OF19fX19fX19fX0sIDB4NjU6IHtsOiB7MHg2NDoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsxOTldfX0sIGM6IFsxOTldfX19fX19fSwgMHg2OToge2w6IHsweDcyOiB7bDogezB4NjM6IHtsOiB7MHgzQjoge2M6IFsyNjRdfX19fX19fSwgMHg2Rjoge2w6IHsweDZFOiB7bDogezB4Njk6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODc1Ml19fX19fX19fX19fX19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzI2Nl19fX19fX19LCAweDY1OiB7bDogezB4NjQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NkM6IHtsOiB7MHg2MToge2w6IHsweDNCOiB7YzogWzE4NF19fX19fX19fX19fSwgMHg2RToge2w6IHsweDc0OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDQ0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzE4M119fX19fX19fX19fX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODQ5M119fX19fSwgMHg0ODoge2w6IHsweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDYzXX19fX19fX0sIDB4Njg6IHtsOiB7MHg2OToge2w6IHsweDNCOiB7YzogWzkzNV19fX19fSwgMHg2OToge2w6IHsweDcyOiB7bDogezB4NjM6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4NDQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODg1N119fX19fX19LCAweDREOiB7bDogezB4Njk6IHtsOiB7MHg2RToge2w6IHsweDc1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4ODU0XX19fX19fX19fX19LCAweDUwOiB7bDogezB4NkM6IHtsOiB7MHg3NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODg1M119fX19fX19fX0sIDB4NTQ6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4NjU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzg4NTVdfX19fX19fX19fX19fX19fX19fX19LCAweDZDOiB7bDogezB4NkY6IHtsOiB7MHg2Mzoge2w6IHsweDZCOiB7bDogezB4Nzc6IHtsOiB7MHg2OToge2w6IHsweDczOiB7bDogezB4NjU6IHtsOiB7MHg0Mzoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDZGOiB7bDogezB4NzU6IHtsOiB7MHg3Mjoge2w6IHsweDQ5OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4Njc6IHtsOiB7MHg3Mjoge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4NzU0XX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2NToge2w6IHsweDQzOiB7bDogezB4NzU6IHtsOiB7MHg3Mjoge2w6IHsweDZDOiB7bDogezB4Nzk6IHtsOiB7MHg0NDoge2w6IHsweDZGOiB7bDogezB4NzU6IHtsOiB7MHg2Mjoge2w6IHsweDZDOiB7bDogezB4NjU6IHtsOiB7MHg1MToge2w6IHsweDc1OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODIyMV19fX19fX19fX19fX19fX19fX19fX19fSwgMHg1MToge2w6IHsweDc1OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODIxN119fX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg2Rjoge2w6IHsweDZDOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzg3NTldfSwgMHg2NToge2w6IHsweDNCOiB7YzogWzEwODY4XX19fX19fX19fSwgMHg2RToge2w6IHsweDY3OiB7bDogezB4NzI6IHtsOiB7MHg3NToge2w6IHsweDY1OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg4MDFdfX19fX19fX19fX19fSwgMHg2OToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4NzUxXX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2Rjoge2w6IHsweDc1OiB7bDogezB4NzI6IHtsOiB7MHg0OToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDY3OiB7bDogezB4NzI6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODc1MF19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzg0NTBdfX19LCAweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2NDoge2w6IHsweDc1OiB7bDogezB4NjM6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg3MjBdfX19fX19fX19fX19fX19LCAweDc1OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4NzI6IHtsOiB7MHg0Mzoge2w6IHsweDZDOiB7bDogezB4NkY6IHtsOiB7MHg2Mzoge2w6IHsweDZCOiB7bDogezB4Nzc6IHtsOiB7MHg2OToge2w6IHsweDczOiB7bDogezB4NjU6IHtsOiB7MHg0Mzoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDZGOiB7bDogezB4NzU6IHtsOiB7MHg3Mjoge2w6IHsweDQ5OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4Njc6IHtsOiB7MHg3Mjoge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4NzU1XX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NEY6IHtsOiB7MHg1MDoge2w6IHsweDU5OiB7bDogezB4M0I6IHtjOiBbMTY5XX19LCBjOiBbMTY5XX19fX19LCAweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Mzoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbMTA3OTldfX19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzExOTk2Nl19fX19fX19LCAweDc1OiB7bDogezB4NzA6IHtsOiB7MHg0Mzoge2w6IHsweDYxOiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFs4NzgxXX19fX19fX0sIDB4M0I6IHtjOiBbODkxNV19fX19fX19LFxyXG4gICAgMHg2Mzoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg3NToge2w6IHsweDc0OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsyNjNdfX19fX19fX19LCAweDcwOiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDY0OiB7bDogezB4M0I6IHtjOiBbMTA4MjBdfX19fX19fSwgMHg2Mjoge2w6IHsweDcyOiB7bDogezB4NjM6IHtsOiB7MHg3NToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbMTA4MjVdfX19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg2MToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbMTA4MjddfX19fX0sIDB4NzU6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzEwODIzXX19fX19fX0sIDB4M0I6IHtjOiBbODc0NV19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwODE2XX19fX19fX0sIDB4NzM6IHtsOiB7MHgzQjoge2M6IFs4NzQ1LCA2NTAyNF19fX19fSwgMHg3Mjoge2w6IHsweDY1OiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4MjU3XX19fX19LCAweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs3MTFdfX19fX19fX19LCAweDYzOiB7bDogezB4NjE6IHtsOiB7MHg3MDoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbMTA4MjldfX19fX0sIDB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbMjY5XX19fX19fX19fSwgMHg2NToge2w6IHsweDY0OiB7bDogezB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzIzMV19fSwgYzogWzIzMV19fX19fX19LCAweDY5OiB7bDogezB4NzI6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzI2NV19fX19fX19LCAweDc1OiB7bDogezB4NzA6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzEwODI4XX0sIDB4NzM6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzEwODMyXX19fX19fX19fX19fX0sIDB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMjY3XX19fX19fX0sIDB4NjU6IHtsOiB7MHg2NDoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsxODRdfX0sIGM6IFsxODRdfX19fX0sIDB4NkQ6IHtsOiB7MHg3MDoge2w6IHsweDc0OiB7bDogezB4Nzk6IHtsOiB7MHg3Njoge2w6IHsweDNCOiB7YzogWzEwNjc0XX19fX19fX19fX19LCAweDZFOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxNjJdfSwgMHg2NToge2w6IHsweDcyOiB7bDogezB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTgzXX19fX19fX19fX19fSwgYzogWzE2Ml19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDk2XX19fX19LCAweDY4OiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzEwOTVdfX19fX0sIDB4NjU6IHtsOiB7MHg2Mzoge2w6IHsweDZCOiB7bDogezB4M0I6IHtjOiBbMTAwMDNdfSwgMHg2RDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2Qjoge2w6IHsweDNCOiB7YzogWzEwMDAzXX19fX19fX19fX19fX19fSwgMHg2OToge2w6IHsweDNCOiB7YzogWzk2N119fX19fSwgMHg2OToge2w6IHsweDcyOiB7bDogezB4NjM6IHtsOiB7MHgzQjoge2M6IFs3MTBdfSwgMHg2NToge2w6IHsweDcxOiB7bDogezB4M0I6IHtjOiBbODc5MV19fX19fSwgMHg2Qzoge2w6IHsweDY1OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODYzNF19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2OToge2w6IHsweDY3OiB7bDogezB4Njg6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg2MzVdfX19fX19fX19fX19fX19fX19fX19LCAweDY0OiB7bDogezB4NjE6IHtsOiB7MHg3Mzoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODg1OV19fX19fX19LCAweDYzOiB7bDogezB4Njk6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbODg1OF19fX19fX19fX0sIDB4NjQ6IHtsOiB7MHg2MToge2w6IHsweDczOiB7bDogezB4Njg6IHtsOiB7MHgzQjoge2M6IFs4ODYxXX19fX19fX19fSwgMHg1Mjoge2w6IHsweDNCOiB7YzogWzE3NF19fX0sIDB4NTM6IHtsOiB7MHgzQjoge2M6IFs5NDE2XX19fX19fX19fX19LCAweDNCOiB7YzogWzk2NzVdfSwgMHg0NToge2w6IHsweDNCOiB7YzogWzEwNjkxXX19fSwgMHg2NToge2w6IHsweDNCOiB7YzogWzg3OTFdfX19LCAweDY2OiB7bDogezB4NkU6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxMDc2OF19fX19fX19fX19fSwgMHg2RDoge2w6IHsweDY5OiB7bDogezB4NjQ6IHtsOiB7MHgzQjoge2M6IFsxMDk5MV19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg2OToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA2OTBdfX19fX19fX19fX19fSwgMHg2Qzoge2w6IHsweDc1OiB7bDogezB4NjI6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzk4MjddfSwgMHg3NToge2w6IHsweDY5OiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs5ODI3XX19fX19fX19fX19fX19fSwgMHg2Rjoge2w6IHsweDZDOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzU4XX0sIDB4NjU6IHtsOiB7MHgzQjoge2M6IFs4Nzg4XX0sIDB4NzE6IHtsOiB7MHgzQjoge2M6IFs4Nzg4XX19fX19fX19fX19LCAweDZEOiB7bDogezB4NkQ6IHtsOiB7MHg2MToge2w6IHsweDNCOiB7YzogWzQ0XX0sIDB4NzQ6IHtsOiB7MHgzQjoge2M6IFs2NF19fX19fX19LCAweDcwOiB7bDogezB4M0I6IHtjOiBbODcwNV19LCAweDY2OiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs4NzI4XX19fX19LCAweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2RDoge2w6IHsweDY1OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg3MDVdfX19fX19fX19LCAweDc4OiB7bDogezB4NjU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzg0NTBdfX19fX19fX19fX19fX19LCAweDZFOiB7bDogezB4Njc6IHtsOiB7MHgzQjoge2M6IFs4NzczXX0sIDB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA4NjFdfX19fX19fX19LCAweDY5OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg3NTBdfX19fX19fX19LCAweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxNDhdfX19LCAweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2NDoge2w6IHsweDNCOiB7YzogWzg3MjBdfX19fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzE2OV19LCAweDczOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NDcxXX19fX19fSwgYzogWzE2OV19fX19fSwgMHg3Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg2MjldfX19fX19fSwgMHg2Rjoge2w6IHsweDczOiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFsxMDAwN119fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTE5OTkyXX19fX19LCAweDc1OiB7bDogezB4NjI6IHtsOiB7MHgzQjoge2M6IFsxMDk1OV19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbMTA5NjFdfX19fX0sIDB4NzA6IHtsOiB7MHgzQjoge2M6IFsxMDk2MF19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbMTA5NjJdfX19fX19fX19LCAweDc0OiB7bDogezB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODk0M119fX19fX19fX0sIDB4NzU6IHtsOiB7MHg2NDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMTA1NTJdfX19LCAweDcyOiB7bDogezB4M0I6IHtjOiBbMTA1NDldfX19fX19fX19fX0sIDB4NjU6IHtsOiB7MHg3MDoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODkyNl19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbODkyN119fX19fX19LCAweDZDOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODYzMF19LCAweDcwOiB7bDogezB4M0I6IHtjOiBbMTA1NTddfX19fX19fX19fX0sIDB4NzA6IHtsOiB7MHg2Mjoge2w6IHsweDcyOiB7bDogezB4NjM6IHtsOiB7MHg2MToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbMTA4MjRdfX19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg2MToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbMTA4MjJdfX19fX0sIDB4NzU6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzEwODI2XX19fX19fX0sIDB4M0I6IHtjOiBbODc0Nl19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg4NDVdfX19fX19fSwgMHg2Rjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA4MjFdfX19fX0sIDB4NzM6IHtsOiB7MHgzQjoge2M6IFs4NzQ2LCA2NTAyNF19fX19fSwgMHg3Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg2MzFdfSwgMHg2RDoge2w6IHsweDNCOiB7YzogWzEwNTU2XX19fX19fX19fSwgMHg2Qzoge2w6IHsweDc5OiB7bDogezB4NjU6IHtsOiB7MHg3MToge2w6IHsweDcwOiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbODkyNl19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg3NToge2w6IHsweDYzOiB7bDogezB4NjM6IHtsOiB7MHgzQjoge2M6IFs4OTI3XX19fX19fX19fX19fX0sIDB4NzY6IHtsOiB7MHg2NToge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODkxMF19fX19fX19LCAweDc3OiB7bDogezB4NjU6IHtsOiB7MHg2NDoge2w6IHsweDY3OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4OTExXX19fX19fX19fX19fX19fSwgMHg3Mjoge2w6IHsweDY1OiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFsxNjRdfX0sIGM6IFsxNjRdfX19fX0sIDB4NzY6IHtsOiB7MHg2NToge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4NjY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg2MzBdfX19fX19fX19LCAweDcyOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDY4OiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4NjMxXX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg3Njoge2w6IHsweDY1OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4OTEwXX19fX19fX0sIDB4Nzc6IHtsOiB7MHg2NToge2w6IHsweDY0OiB7bDogezB4M0I6IHtjOiBbODkxMV19fX19fX19fX0sIDB4Nzc6IHtsOiB7MHg2Mzoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4NzU0XX19fX19fX19fX19fX0sIDB4Njk6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODc1M119fX19fX19fX0sIDB4Nzk6IHtsOiB7MHg2Qzoge2w6IHsweDYzOiB7bDogezB4NzQ6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzkwMDVdfX19fX19fX19fX19fSxcclxuICAgIDB4NjQ6IHtsOiB7MHg2MToge2w6IHsweDY3OiB7bDogezB4Njc6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODIyNF19fX19fX19fX0sIDB4NkM6IHtsOiB7MHg2NToge2w6IHsweDc0OiB7bDogezB4Njg6IHtsOiB7MHgzQjoge2M6IFs4NTA0XX19fX19fX19fSwgMHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODU5NV19fX19fSwgMHg3Mzoge2w6IHsweDY4OiB7bDogezB4M0I6IHtjOiBbODIwOF19LCAweDc2OiB7bDogezB4M0I6IHtjOiBbODg2N119fX19fX19fX0sIDB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODY1OV19fX19fX19LCAweDYyOiB7bDogezB4NkI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzEwNTExXX19fX19fX19fX19LCAweDZDOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzczM119fX19fX19fX0sIDB4NjM6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzI3MV19fX19fX19fX0sIDB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDc2XX19fX19LCAweDY0OiB7bDogezB4NjE6IHtsOiB7MHg2Nzoge2w6IHsweDY3OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzgyMjVdfX19fX19fX19LCAweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjUwXX19fX19fX0sIDB4M0I6IHtjOiBbODUxOF19LCAweDZGOiB7bDogezB4NzQ6IHtsOiB7MHg3Mzoge2w6IHsweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFsxMDg3MV19fX19fX19fX19fX19LCAweDY1OiB7bDogezB4Njc6IHtsOiB7MHgzQjoge2M6IFsxNzZdfX0sIGM6IFsxNzZdfSwgMHg2Qzoge2w6IHsweDc0OiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs5NDhdfX19fX19fSwgMHg2RDoge2w6IHsweDcwOiB7bDogezB4NzQ6IHtsOiB7MHg3OToge2w6IHsweDc2OiB7bDogezB4M0I6IHtjOiBbMTA2NzNdfX19fX19fX19fX19fSwgMHg2Njoge2w6IHsweDY5OiB7bDogezB4NzM6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA2MjNdfX19fX19fX19LCAweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDk3XX19fX19LCAweDQ4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTk3XX19fX19fX0sIDB4Njg6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4NjQzXX19fSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzg2NDJdfX19fX19fX19LCAweDY5OiB7bDogezB4NjE6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzg5MDBdfSwgMHg2Rjoge2w6IHsweDZFOiB7bDogezB4NjQ6IHtsOiB7MHgzQjoge2M6IFs4OTAwXX0sIDB4NzM6IHtsOiB7MHg3NToge2w6IHsweDY5OiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs5ODMwXX19fX19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDNCOiB7YzogWzk4MzBdfX19fX19fSwgMHg2NToge2w6IHsweDNCOiB7YzogWzE2OF19fX0sIDB4Njc6IHtsOiB7MHg2MToge2w6IHsweDZEOiB7bDogezB4NkQ6IHtsOiB7MHg2MToge2w6IHsweDNCOiB7YzogWzk4OV19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs4OTQ2XX19fX19fX0sIDB4NzY6IHtsOiB7MHgzQjoge2M6IFsyNDddfSwgMHg2OToge2w6IHsweDY0OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsyNDddfSwgMHg2Rjoge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4NjU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzg5MDNdfX19fX19fX19fX19fX19fSwgYzogWzI0N119fX19fSwgMHg2Rjoge2w6IHsweDZFOiB7bDogezB4Nzg6IHtsOiB7MHgzQjoge2M6IFs4OTAzXX19fX19fX19fX19LCAweDZBOiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzExMDZdfX19fX19fSwgMHg2Qzoge2w6IHsweDYzOiB7bDogezB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbODk5MF19fX19fX19LCAweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzg5NzNdfX19fX19fX19fX0sIDB4NkY6IHtsOiB7MHg2Qzoge2w6IHsweDZDOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzM2XX19fX19fX19fSwgMHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbMTIwMTQ5XX19fX19LCAweDc0OiB7bDogezB4M0I6IHtjOiBbNzI5XX0sIDB4NjU6IHtsOiB7MHg3MToge2w6IHsweDNCOiB7YzogWzg3ODRdfSwgMHg2NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4Nzg1XX19fX19fX19fX19LCAweDZEOiB7bDogezB4Njk6IHtsOiB7MHg2RToge2w6IHsweDc1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4NzYwXX19fX19fX19fX19LCAweDcwOiB7bDogezB4NkM6IHtsOiB7MHg3NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODcyNF19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODg2NV19fX19fX19fX19fX19fX0sIDB4NzU6IHtsOiB7MHg2Mjoge2w6IHsweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Nzoge2w6IHsweDY1OiB7bDogezB4NjQ6IHtsOiB7MHg2Nzoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODk2Nl19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDc3OiB7bDogezB4NkU6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODU5NV19fX19fX19fX19fSwgMHg2NDoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHg2RToge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzg2NTBdfX19fX19fX19fX19fX19fX19fX19LCAweDY4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcwOiB7bDogezB4NkY6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDY2OiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4NjQzXX19fX19fX19fSwgMHg3Mjoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODY0Ml19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDcyOiB7bDogezB4NjI6IHtsOiB7MHg2Qjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbMTA1MTJdfX19fX19fX19fX19fSwgMHg2Mzoge2w6IHsweDZGOiB7bDogezB4NzI6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzg5OTFdfX19fX19fSwgMHg3Mjoge2w6IHsweDZGOiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFs4OTcyXX19fX19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzExOTk5M119fX0sIDB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMTA5XX19fX19LCAweDZGOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsxMDc0Ml19fX19fSwgMHg3NDoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2Qjoge2w6IHsweDNCOiB7YzogWzI3M119fX19fX19fX19fSwgMHg3NDoge2w6IHsweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg5NDVdfX19fX19fSwgMHg3Mjoge2w6IHsweDY5OiB7bDogezB4M0I6IHtjOiBbOTY2M119LCAweDY2OiB7bDogezB4M0I6IHtjOiBbOTY2Ml19fX19fX19fX0sIDB4NzU6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjkzXX19fX19fX0sIDB4Njg6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA2MDddfX19fX19fX19LCAweDc3OiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDY3OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzEwNjYyXX19fX19fX19fX19fX0sIDB4N0E6IHtsOiB7MHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTExOV19fX19fSwgMHg2OToge2w6IHsweDY3OiB7bDogezB4NzI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDIzOV19fX19fX19fX19fX19fX19fSxcclxuICAgIDB4NDQ6IHtsOiB7MHg2MToge2w6IHsweDY3OiB7bDogezB4Njc6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODIyNV19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg2MDldfX19fX0sIDB4NzM6IHtsOiB7MHg2ODoge2w6IHsweDc2OiB7bDogezB4M0I6IHtjOiBbMTA5ODBdfX19fX19fX19LCAweDYzOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFsyNzBdfX19fX19fX19LCAweDc5OiB7bDogezB4M0I6IHtjOiBbMTA0NF19fX19fSwgMHg0NDoge2w6IHsweDNCOiB7YzogWzg1MTddfSwgMHg2Rjoge2w6IHsweDc0OiB7bDogezB4NzI6IHtsOiB7MHg2MToge2w6IHsweDY4OiB7bDogezB4NjQ6IHtsOiB7MHgzQjoge2M6IFsxMDUxM119fX19fX19fX19fX19fX0sIDB4NjU6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzg3MTFdfSwgMHg3NDoge2w6IHsweDYxOiB7bDogezB4M0I6IHtjOiBbOTE2XX19fX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDcxXX19fX19LCAweDY5OiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4Njk6IHtsOiB7MHg3NDoge2w6IHsweDY5OiB7bDogezB4NjM6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4NDE6IHtsOiB7MHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzE4MF19fX19fX19fX19fSwgMHg0NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs3MjldfX19LCAweDc1OiB7bDogezB4NjI6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4NDE6IHtsOiB7MHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzczM119fX19fX19fX19fX19fX19fX19fX19fSwgMHg0Nzoge2w6IHsweDcyOiB7bDogezB4NjE6IHtsOiB7MHg3Njoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbOTZdfX19fX19fX19fX0sIDB4NTQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzczMl19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NkQ6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4NjQ6IHtsOiB7MHgzQjoge2M6IFs4OTAwXX19fX19fX19fX19LCAweDY2OiB7bDogezB4NjY6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4NjU6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4Njk6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4NDQ6IHtsOiB7MHgzQjoge2M6IFs4NTE4XX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NEE6IHtsOiB7MHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTAyNl19fX19fX19LCAweDZGOiB7bDogezB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDEyM119fX19fSwgMHg3NDoge2w6IHsweDNCOiB7YzogWzE2OF19LCAweDQ0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg0MTJdfX19fX19fSwgMHg0NToge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODc4NF19fX19fX19fX19fX19LCAweDc1OiB7bDogezB4NjI6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4NDM6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHg2Rjoge2w6IHsweDc1OiB7bDogezB4NzI6IHtsOiB7MHg0OToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDY3OiB7bDogezB4NzI6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODc1MV19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDQ0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzE2OF19fX0sIDB4Nzc6IHtsOiB7MHg2RToge2w6IHsweDQxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NjU5XX19fX19fX19fX19fX19fX19fX0sIDB4NEM6IHtsOiB7MHg2NToge2w6IHsweDY2OiB7bDogezB4NzQ6IHtsOiB7MHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODY1Nl19fX19fX19fX19fSwgMHg1Mjoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2NjBdfX19fX19fX19fX19fX19fX19fX19LCAweDU0OiB7bDogezB4NjU6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzEwOTgwXX19fX19fX19fX19fX0sIDB4NkY6IHtsOiB7MHg2RToge2w6IHsweDY3OiB7bDogezB4NEM6IHtsOiB7MHg2NToge2w6IHsweDY2OiB7bDogezB4NzQ6IHtsOiB7MHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbMTAyMzJdfX19fX19fX19fX0sIDB4NTI6IHtsOiB7MHg2OToge2w6IHsweDY3OiB7bDogezB4Njg6IHtsOiB7MHg3NDoge2w6IHsweDQxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFsxMDIzNF19fX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg1Mjoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzEwMjMzXX19fX19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDUyOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDY4OiB7bDogezB4NzQ6IHtsOiB7MHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODY1OF19fX19fX19fX19fSwgMHg1NDoge2w6IHsweDY1OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4ODcyXX19fX19fX19fX19fX19fX19LCAweDU1OiB7bDogezB4NzA6IHtsOiB7MHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODY1N119fX19fX19fX19fSwgMHg0NDoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHg2RToge2w6IHsweDQxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NjYxXX19fX19fX19fX19fX19fX19fX19fX19LCAweDU2OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDc0OiB7bDogezB4Njk6IHtsOiB7MHg2Mzoge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHg0Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NzQxXX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4Nzc6IHtsOiB7MHg2RToge2w6IHsweDQxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHg0Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDUxNV19fX19fX19LCAweDNCOiB7YzogWzg1OTVdfSwgMHg1NToge2w6IHsweDcwOiB7bDogezB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2OTNdfX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODY1OV19fX19fX19fX19fSwgMHg0Mjoge2w6IHsweDcyOiB7bDogezB4NjU6IHtsOiB7MHg3Njoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbNzg1XX19fX19fX19fX19LCAweDRDOiB7bDogezB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4NTI6IHtsOiB7MHg2OToge2w6IHsweDY3OiB7bDogezB4Njg6IHtsOiB7MHg3NDoge2w6IHsweDU2OiB7bDogezB4NjU6IHtsOiB7MHg2Mzoge2w6IHsweDc0OiB7bDogezB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTc2XX19fX19fX19fX19fX19fX19fX19fX19LCAweDU0OiB7bDogezB4NjU6IHtsOiB7MHg2NToge2w6IHsweDU2OiB7bDogezB4NjU6IHtsOiB7MHg2Mzoge2w6IHsweDc0OiB7bDogezB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTkwXX19fX19fX19fX19fX19fX19fX0sIDB4NTY6IHtsOiB7MHg2NToge2w6IHsweDYzOiB7bDogezB4NzQ6IHtsOiB7MHg2Rjoge2w6IHsweDcyOiB7bDogezB4NDI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA1ODJdfX19fX19fSwgMHgzQjoge2M6IFs4NjM3XX19fX19fX19fX19fX19fX19fX19fSwgMHg1Mjoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4NTQ6IHtsOiB7MHg2NToge2w6IHsweDY1OiB7bDogezB4NTY6IHtsOiB7MHg2NToge2w6IHsweDYzOiB7bDogezB4NzQ6IHtsOiB7MHg2Rjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA1OTFdfX19fX19fX19fX19fX19fX19fSwgMHg1Njoge2w6IHsweDY1OiB7bDogezB4NjM6IHtsOiB7MHg3NDoge2w6IHsweDZGOiB7bDogezB4NzI6IHtsOiB7MHg0Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDU4M119fX19fX19LCAweDNCOiB7YzogWzg2NDFdfX19fX19fX19fX19fX19fX19fX19fX0sIDB4NTQ6IHtsOiB7MHg2NToge2w6IHsweDY1OiB7bDogezB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2MTVdfX19fX19fX19fX0sIDB4M0I6IHtjOiBbODg2OF19fX19fX19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzExOTk2N119fX19fSwgMHg3NDoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2Qjoge2w6IHsweDNCOiB7YzogWzI3Ml19fX19fX19fX19fSwgMHg1Mzoge2w6IHsweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDI5XX19fX19fX0sIDB4NUE6IHtsOiB7MHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTAzOV19fX19fX19fX0sXHJcbiAgICAweDQ1OiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzIwMV19fSwgYzogWzIwMV19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzI4Ml19fX19fX19fX0sIDB4Njk6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbMjAyXX19LCBjOiBbMjAyXX19fX19LCAweDc5OiB7bDogezB4M0I6IHtjOiBbMTA2OV19fX19fSwgMHg2NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsyNzhdfX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDcyXX19fX19LCAweDY3OiB7bDogezB4NzI6IHtsOiB7MHg2MToge2w6IHsweDc2OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsyMDBdfX0sIGM6IFsyMDBdfX19fX19fX19LCAweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2RDoge2w6IHsweDY1OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg3MTJdfX19fX19fX19fX19fSwgMHg2RDoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzI3NF19fX19fX19LCAweDcwOiB7bDogezB4NzQ6IHtsOiB7MHg3OToge2w6IHsweDUzOiB7bDogezB4NkQ6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4NkM6IHtsOiB7MHg1Mzoge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs5NzIzXX19fX19fX19fX19fX19fX19fX19fX19LCAweDU2OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDc5OiB7bDogezB4NTM6IHtsOiB7MHg2RDoge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHg2Qzoge2w6IHsweDUzOiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzk2NDNdfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDRFOiB7bDogezB4NDc6IHtsOiB7MHgzQjoge2M6IFszMzBdfX19fX0sIDB4NkY6IHtsOiB7MHg2Nzoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFsyODBdfX19fX19fSwgMHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbMTIwMTI0XX19fX19fX0sIDB4NzA6IHtsOiB7MHg3Mzoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbOTE3XX19fX19fX19fX19fX0sIDB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsxMDg2OV19LCAweDU0OiB7bDogezB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDY0OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4NzcwXX19fX19fX19fX19fX19fSwgMHg2OToge2w6IHsweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2Mjoge2w6IHsweDcyOiB7bDogezB4Njk6IHtsOiB7MHg3NToge2w6IHsweDZEOiB7bDogezB4M0I6IHtjOiBbODY1Ml19fX19fX19fX19fX19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODQ5Nl19fX19fSwgMHg2OToge2w6IHsweDZEOiB7bDogezB4M0I6IHtjOiBbMTA4NjddfX19fX19fSwgMHg3NDoge2w6IHsweDYxOiB7bDogezB4M0I6IHtjOiBbOTE5XX19fX19LCAweDU0OiB7bDogezB4NDg6IHtsOiB7MHgzQjoge2M6IFsyMDhdfX0sIGM6IFsyMDhdfX19LCAweDc1OiB7bDogezB4NkQ6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzIwM119fSwgYzogWzIwM119fX19fSwgMHg3ODoge2w6IHsweDY5OiB7bDogezB4NzM6IHtsOiB7MHg3NDoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODcwN119fX19fX19fX0sIDB4NzA6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4NjU6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4Njk6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4NDU6IHtsOiB7MHgzQjoge2M6IFs4NTE5XX19fX19fX19fX19fX19fX19fX19fX19fX0sXHJcbiAgICAweDY1OiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzIzM119fSwgYzogWzIzM119fX19fX19LCAweDczOiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA4NjJdfX19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzI4M119fX19fX19fX0sIDB4Njk6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbMjM0XX19LCBjOiBbMjM0XX0sIDB4M0I6IHtjOiBbODc5MF19fX19fSwgMHg2Rjoge2w6IHsweDZDOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzg3ODldfX19fX19fX19LCAweDc5OiB7bDogezB4M0I6IHtjOiBbMTEwMV19fX19fSwgMHg0NDoge2w6IHsweDQ0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwODcxXX19fX19fX0sIDB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg3ODVdfX19fX19fSwgMHg2NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsyNzldfX19fX19fSwgMHg2NToge2w6IHsweDNCOiB7YzogWzg1MTldfX19LCAweDY2OiB7bDogezB4NDQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODc4Nl19fX19fX19LCAweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDk4XX19fX19LCAweDY3OiB7bDogezB4M0I6IHtjOiBbMTA5MDZdfSwgMHg3Mjoge2w6IHsweDYxOiB7bDogezB4NzY6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzIzMl19fSwgYzogWzIzMl19fX19fX19LCAweDczOiB7bDogezB4M0I6IHtjOiBbMTA5MDJdfSwgMHg2NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxMDkwNF19fX19fX19fX19fSwgMHg2Qzoge2w6IHsweDNCOiB7YzogWzEwOTA1XX0sIDB4Njk6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbOTE5MV19fX19fX19fX19fX19LCAweDZDOiB7bDogezB4M0I6IHtjOiBbODQ2N119fX0sIDB4NzM6IHtsOiB7MHgzQjoge2M6IFsxMDkwMV19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwOTAzXX19fX19fX19fX19LCAweDZEOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMjc1XX19fX19fX0sIDB4NzA6IHtsOiB7MHg3NDoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbODcwOV19LCAweDczOiB7bDogezB4NjU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg3MDldfX19fX19fSwgMHg3Njoge2w6IHsweDNCOiB7YzogWzg3MDldfX19fX19fX19LCAweDczOiB7bDogezB4NzA6IHtsOiB7MHgzMToge2w6IHsweDMzOiB7bDogezB4M0I6IHtjOiBbODE5Nl19fX0sIDB4MzQ6IHtsOiB7MHgzQjoge2M6IFs4MTk3XX19fX19LCAweDNCOiB7YzogWzgxOTVdfX19fX19fSwgMHg2RToge2w6IHsweDY3OiB7bDogezB4M0I6IHtjOiBbMzMxXX19fSwgMHg3Mzoge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbODE5NF19fX19fX19LCAweDZGOiB7bDogezB4Njc6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbMjgxXX19fX19fX0sIDB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDE1MF19fX19fX19LCAweDcwOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg5MTddfSwgMHg3Mzoge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMTA3MjNdfX19fX19fX19LCAweDZDOiB7bDogezB4NzU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzEwODY1XX19fX19fX0sIDB4NzM6IHtsOiB7MHg2OToge2w6IHsweDNCOiB7YzogWzk0OV19LCAweDZDOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzk0OV19fX19fX19LCAweDc2OiB7bDogezB4M0I6IHtjOiBbMTAxM119fX19fX19fX0sIDB4NzE6IHtsOiB7MHg2Mzoge2w6IHsweDY5OiB7bDogezB4NzI6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzg3OTBdfX19fX19fSwgMHg2Rjoge2w6IHsweDZDOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzg3ODldfX19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4M0I6IHtjOiBbODc3MF19fX19fSwgMHg2Qzoge2w6IHsweDYxOiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDY3OiB7bDogezB4NzQ6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwOTAyXX19fX19fX0sIDB4NkM6IHtsOiB7MHg2NToge2w6IHsweDczOiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFsxMDkwMV19fX19fX19fX19fX19fX19fX19LCAweDc1OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbNjFdfX19fX19fSwgMHg2NToge2w6IHsweDczOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4Nzk5XX19fX19fX0sIDB4Njk6IHtsOiB7MHg3Njoge2w6IHsweDNCOiB7YzogWzg4MDFdfSwgMHg0NDoge2w6IHsweDQ0OiB7bDogezB4M0I6IHtjOiBbMTA4NzJdfX19fX19fX19fX0sIDB4NzY6IHtsOiB7MHg3MDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mzoge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMTA3MjVdfX19fX19fX19fX19fX19LCAweDcyOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA2MDldfX19fX19fSwgMHg0NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4Nzg3XX19fX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NDk1XX19fX19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg3ODRdfX19fX19fSwgMHg2OToge2w6IHsweDZEOiB7bDogezB4M0I6IHtjOiBbODc3MF19fX19fX19LCAweDc0OiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs5NTFdfX19LCAweDY4OiB7bDogezB4M0I6IHtjOiBbMjQwXX19LCBjOiBbMjQwXX19fSwgMHg3NToge2w6IHsweDZEOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsyMzVdfX0sIGM6IFsyMzVdfX19LCAweDcyOiB7bDogezB4NkY6IHtsOiB7MHgzQjoge2M6IFs4MzY0XX19fX19fX0sIDB4Nzg6IHtsOiB7MHg2Mzoge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMzNdfX19fX0sIDB4Njk6IHtsOiB7MHg3Mzoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODcwN119fX19fX19LCAweDcwOiB7bDogezB4NjU6IHtsOiB7MHg2Mzoge2w6IHsweDc0OiB7bDogezB4NjE6IHtsOiB7MHg3NDoge2w6IHsweDY5OiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzg0OTZdfX19fX19fX19fX19fX19fX0sIDB4NkY6IHtsOiB7MHg2RToge2w6IHsweDY1OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDY5OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODUxOV19fX19fX19fX19fX19fX19fX19fX19fX19LFxyXG4gICAgMHg2Njoge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHg2Qzoge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDczOiB7bDogezB4NjU6IHtsOiB7MHg3MToge2w6IHsweDNCOiB7YzogWzg3ODZdfX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTA5Ml19fX19fSwgMHg2NToge2w6IHsweDZEOiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbOTc5Ml19fX19fX19fX19fSwgMHg2Njoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHg2OToge2w6IHsweDY3OiB7bDogezB4M0I6IHtjOiBbNjQyNTldfX19fX19fX19LCAweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzY0MjU2XX19fX19LCAweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzY0MjYwXX19fX19fX19fSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDA5OV19fX19fSwgMHg2OToge2w6IHsweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzY0MjU3XX19fX19fX19fSwgMHg2QToge2w6IHsweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzEwMiwgMTA2XX19fX19fX19fSwgMHg2Qzoge2w6IHsweDYxOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs5ODM3XX19fX19LCAweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzY0MjU4XX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2RToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbOTY0OV19fX19fX19fX0sIDB4NkU6IHtsOiB7MHg2Rjoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbNDAyXX19fX19fX0sIDB4NkY6IHtsOiB7MHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbMTIwMTUxXX19fX19LCAweDcyOiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODcwNF19fX19fX19LCAweDZCOiB7bDogezB4M0I6IHtjOiBbODkxNl19LCAweDc2OiB7bDogezB4M0I6IHtjOiBbMTA5NjldfX19fX19fX19LCAweDcwOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDc0OiB7bDogezB4Njk6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA3NjVdfX19fX19fX19fX19fX19LCAweDcyOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDMxOiB7bDogezB4MzI6IHtsOiB7MHgzQjoge2M6IFsxODldfX0sIGM6IFsxODldfSwgMHgzMzoge2w6IHsweDNCOiB7YzogWzg1MzFdfX19LCAweDM0OiB7bDogezB4M0I6IHtjOiBbMTg4XX19LCBjOiBbMTg4XX0sIDB4MzU6IHtsOiB7MHgzQjoge2M6IFs4NTMzXX19fSwgMHgzNjoge2w6IHsweDNCOiB7YzogWzg1MzddfX19LCAweDM4OiB7bDogezB4M0I6IHtjOiBbODUzOV19fX19fSwgMHgzMjoge2w6IHsweDMzOiB7bDogezB4M0I6IHtjOiBbODUzMl19fX0sIDB4MzU6IHtsOiB7MHgzQjoge2M6IFs4NTM0XX19fX19LCAweDMzOiB7bDogezB4MzQ6IHtsOiB7MHgzQjoge2M6IFsxOTBdfX0sIGM6IFsxOTBdfSwgMHgzNToge2w6IHsweDNCOiB7YzogWzg1MzVdfX19LCAweDM4OiB7bDogezB4M0I6IHtjOiBbODU0MF19fX19fSwgMHgzNDoge2w6IHsweDM1OiB7bDogezB4M0I6IHtjOiBbODUzNl19fX19fSwgMHgzNToge2w6IHsweDM2OiB7bDogezB4M0I6IHtjOiBbODUzOF19fX0sIDB4Mzg6IHtsOiB7MHgzQjoge2M6IFs4NTQxXX19fX19LCAweDM3OiB7bDogezB4Mzg6IHtsOiB7MHgzQjoge2M6IFs4NTQyXX19fX19fX0sIDB4NzM6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzgyNjBdfX19fX19fSwgMHg2Rjoge2w6IHsweDc3OiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs4OTk0XX19fX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMTk5OTVdfX19fX19fX19LFxyXG4gICAgMHg0Njoge2w6IHsweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDYwXX19fX19LCAweDY2OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAwNzNdfX19fX0sIDB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2NDoge2w6IHsweDUzOiB7bDogezB4NkQ6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4NkM6IHtsOiB7MHg1Mzoge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs5NzI0XX19fX19fX19fX19fX19fX19fX19fX19LCAweDU2OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDc5OiB7bDogezB4NTM6IHtsOiB7MHg2RDoge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHg2Qzoge2w6IHsweDUzOiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzk2NDJdfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NkY6IHtsOiB7MHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbMTIwMTI1XX19fX19LCAweDcyOiB7bDogezB4NDE6IHtsOiB7MHg2Qzoge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODcwNF19fX19fX19fX0sIDB4NzU6IHtsOiB7MHg3Mjoge2w6IHsweDY5OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDc0OiB7bDogezB4NzI6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzg0OTddfX19fX19fX19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NDk3XX19fX19fX19fSxcclxuICAgIDB4Njc6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NzU6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbNTAxXX19fX19fX19fSwgMHg2RDoge2w6IHsweDZEOiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs5NDddfSwgMHg2NDoge2w6IHsweDNCOiB7YzogWzk4OV19fX19fX19fX0sIDB4NzA6IHtsOiB7MHgzQjoge2M6IFsxMDg4Nl19fX19fSwgMHg2Mjoge2w6IHsweDcyOiB7bDogezB4NjU6IHtsOiB7MHg3Njoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbMjg3XX19fX19fX19fX19LCAweDYzOiB7bDogezB4Njk6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbMjg1XX19fX19fX0sIDB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDc1XX19fX19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzI4OV19fX19fX19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbODgwNV19LCAweDZDOiB7bDogezB4M0I6IHtjOiBbODkyM119fX0sIDB4NzE6IHtsOiB7MHgzQjoge2M6IFs4ODA1XX0sIDB4NzE6IHtsOiB7MHgzQjoge2M6IFs4ODA3XX19fSwgMHg3Mzoge2w6IHsweDZDOiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA4NzhdfX19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NjM6IHtsOiB7MHgzQjoge2M6IFsxMDkyMV19fX19fSwgMHgzQjoge2M6IFsxMDg3OF19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwODgwXX0sIDB4NkY6IHtsOiB7MHgzQjoge2M6IFsxMDg4Ml19LCAweDZDOiB7bDogezB4M0I6IHtjOiBbMTA4ODRdfX19fX19fX19fX0sIDB4NkM6IHtsOiB7MHgzQjoge2M6IFs4OTIzLCA2NTAyNF19LCAweDY1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFsxMDkwMF19fX19fX19fX19fSwgMHg0NToge2w6IHsweDNCOiB7YzogWzg4MDddfSwgMHg2Qzoge2w6IHsweDNCOiB7YzogWzEwODkyXX19fX19LCAweDY2OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAxMDBdfX19fX0sIDB4Njc6IHtsOiB7MHgzQjoge2M6IFs4ODExXX0sIDB4Njc6IHtsOiB7MHgzQjoge2M6IFs4OTIxXX19fX19LCAweDY5OiB7bDogezB4NkQ6IHtsOiB7MHg2NToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODUwM119fX19fX19fX0sIDB4NkE6IHtsOiB7MHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTEwN119fX19fX19LCAweDZDOiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFsxMDkxN119fX0sIDB4M0I6IHtjOiBbODgyM119LCAweDQ1OiB7bDogezB4M0I6IHtjOiBbMTA4OThdfX19LCAweDZBOiB7bDogezB4M0I6IHtjOiBbMTA5MTZdfX19fX0sIDB4NkU6IHtsOiB7MHg2MToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbMTA4OTBdfSwgMHg3MDoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3ODoge2w6IHsweDNCOiB7YzogWzEwODkwXX19fX19fX19fX19fX0sIDB4NjU6IHtsOiB7MHgzQjoge2M6IFsxMDg4OF19LCAweDcxOiB7bDogezB4M0I6IHtjOiBbMTA4ODhdfSwgMHg3MToge2w6IHsweDNCOiB7YzogWzg4MDldfX19fX19fSwgMHg0NToge2w6IHsweDNCOiB7YzogWzg4MDldfX19LCAweDczOiB7bDogezB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzg5MzVdfX19fX19fX19LCAweDZGOiB7bDogezB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDE1Ml19fX19fX19LCAweDcyOiB7bDogezB4NjE6IHtsOiB7MHg3Njoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbOTZdfX19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg0NThdfX19fX0sIDB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzg4MTldfSwgMHg2NToge2w6IHsweDNCOiB7YzogWzEwODk0XX19fSwgMHg2Qzoge2w6IHsweDNCOiB7YzogWzEwODk2XX19fX19fX19fSwgMHg3NDoge2w6IHsweDYzOiB7bDogezB4NjM6IHtsOiB7MHgzQjoge2M6IFsxMDkxOV19fX0sIDB4Njk6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwODc0XX19fX19fX0sIDB4M0I6IHtjOiBbNjJdfSwgMHg2NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4OTE5XX19fX19fX0sIDB4NkM6IHtsOiB7MHg1MDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDY0NV19fX19fX19fX0sIDB4NzE6IHtsOiB7MHg3NToge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwODc2XX19fX19fX19fX19LCAweDcyOiB7bDogezB4NjE6IHtsOiB7MHg3MDoge2w6IHsweDcwOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc4OiB7bDogezB4M0I6IHtjOiBbMTA4ODZdfX19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNjE2XX19fX19fX0sIDB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODkxOV19fX19fX19LCAweDY1OiB7bDogezB4NzE6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzg5MjNdfX19fX19fX19LCAweDcxOiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDczOiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFsxMDg5Ml19fX19fX19fX19fX19fX0sIDB4NkM6IHtsOiB7MHg2NToge2w6IHsweDczOiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4ODIzXX19fX19fX19fSwgMHg3Mzoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHgzQjoge2M6IFs4ODE5XX19fX19fX19fX0sIGM6IFs2Ml19LCAweDc2OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDc0OiB7bDogezB4NkU6IHtsOiB7MHg2NToge2w6IHsweDcxOiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFs4ODA5LCA2NTAyNF19fX19fX19fX19fX19fX0sIDB4NkU6IHtsOiB7MHg0NToge2w6IHsweDNCOiB7YzogWzg4MDksIDY1MDI0XX19fX19fX19fSxcclxuICAgIDB4NDc6IHtsOiB7MHg2MToge2w6IHsweDZEOiB7bDogezB4NkQ6IHtsOiB7MHg2MToge2w6IHsweDNCOiB7YzogWzkxNV19LCAweDY0OiB7bDogezB4M0I6IHtjOiBbOTg4XX19fX19fX19fX19LCAweDYyOiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDc2OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsyODZdfX19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg2NToge2w6IHsweDY0OiB7bDogezB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzI5MF19fX19fX19fX0sIDB4Njk6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbMjg0XX19fX19fX0sIDB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDQzXX19fX19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzI4OF19fX19fX19LCAweDY2OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAwNzRdfX19fX0sIDB4Njc6IHtsOiB7MHgzQjoge2M6IFs4OTIxXX19fSwgMHg0QToge2w6IHsweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDI3XX19fX19fX0sIDB4NkY6IHtsOiB7MHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbMTIwMTI2XX19fX19fX0sIDB4NzI6IHtsOiB7MHg2NToge2w6IHsweDYxOiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4NDU6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzg4MDVdfSwgMHg0Qzoge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzg5MjNdfX19fX19fX19fX19fX19fX19fSwgMHg0Njoge2w6IHsweDc1OiB7bDogezB4NkM6IHtsOiB7MHg2Qzoge2w6IHsweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4ODA3XX19fX19fX19fX19fX19fX19fX0sIDB4NDc6IHtsOiB7MHg3Mjoge2w6IHsweDY1OiB7bDogezB4NjE6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDkxNF19fX19fX19fX19fX19fX0sIDB4NEM6IHtsOiB7MHg2NToge2w6IHsweDczOiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4ODIzXX19fX19fX19fSwgMHg1Mzoge2w6IHsweDZDOiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4NDU6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzEwODc4XX19fX19fX19fX19fX19fX19fX19fSwgMHg1NDoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHg2NDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODgxOV19fX19fX19fX19fX19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMTk5NzBdfX19fX19fSwgMHg1NDoge2w6IHsweDNCOiB7YzogWzYyXX19LCBjOiBbNjJdfSwgMHg3NDoge2w6IHsweDNCOiB7YzogWzg4MTFdfX19fX0sXHJcbiAgICAweDQ4OiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDY1OiB7bDogezB4NkI6IHtsOiB7MHgzQjoge2M6IFs3MTFdfX19fX19fSwgMHg3NDoge2w6IHsweDNCOiB7YzogWzk0XX19fX19LCAweDQxOiB7bDogezB4NTI6IHtsOiB7MHg0NDoge2w6IHsweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDY2XX19fX19fX19fX19LCAweDYzOiB7bDogezB4Njk6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbMjkyXX19fX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODQ2MF19fX19fSwgMHg2OToge2w6IHsweDZDOiB7bDogezB4NjI6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4NzQ6IHtsOiB7MHg1Mzoge2w6IHsweDcwOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODQ1OV19fX19fX19fX19fX19fX19fX19fX19fSwgMHg2Rjoge2w6IHsweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFs4NDYxXX19fX19LCAweDcyOiB7bDogezB4Njk6IHtsOiB7MHg3QToge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHg0Qzoge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzk0NzJdfX19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg0NTldfX19fX0sIDB4NzQ6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4NkI6IHtsOiB7MHgzQjoge2M6IFsyOTRdfX19fX19fX19fX0sIDB4NzU6IHtsOiB7MHg2RDoge2w6IHsweDcwOiB7bDogezB4NDQ6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4NkU6IHtsOiB7MHg0ODoge2w6IHsweDc1OiB7bDogezB4NkQ6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzg3ODJdfX19fX19fX19fX19fX19fX0sIDB4NDU6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzg3ODNdfX19fX19fX19fX19fX19fX19fSxcclxuICAgIDB4Njg6IHtsOiB7MHg2MToge2w6IHsweDY5OiB7bDogezB4NzI6IHtsOiB7MHg3Mzoge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbODIwMl19fX19fX19fX0sIDB4NkM6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzE4OV19fX19fSwgMHg2RDoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg0NTldfX19fX19fX19LCAweDcyOiB7bDogezB4NjQ6IHtsOiB7MHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTA5OF19fX19fX19LCAweDcyOiB7bDogezB4NjM6IHtsOiB7MHg2OToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA1NjhdfX19fX19fSwgMHgzQjoge2M6IFs4NTk2XX0sIDB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NjIxXX19fX19fX19fSwgMHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjYwXX19fX19fX0sIDB4NjI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODQ2M119fX19fX19LCAweDYzOiB7bDogezB4Njk6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbMjkzXX19fX19fX19fSwgMHg2NToge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3NDoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbOTgyOV19LCAweDc1OiB7bDogezB4Njk6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzk4MjldfX19fX19fX19fX19fX19LCAweDZDOiB7bDogezB4NkM6IHtsOiB7MHg2OToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbODIzMF19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2Mzoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs4ODg5XX19fX19fX19fX19LCAweDY2OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAxMDFdfX19fX0sIDB4NkI6IHtsOiB7MHg3Mzoge2w6IHsweDY1OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFsxMDUzM119fX19fX19fX19fSwgMHg3Nzoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbMTA1MzRdfX19fX19fX19fX19fX19LCAweDZGOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODcwM119fX19fX19LCAweDZEOiB7bDogezB4NzQ6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODc2M119fX19fX19fX0sIDB4NkY6IHtsOiB7MHg2Qjoge2w6IHsweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2MTddfX19fX19fX19fX19fX19fX19fSwgMHg3Mjoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2MThdfX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbMTIwMTUzXX19fX19LCAweDcyOiB7bDogezB4NjI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODIxM119fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMTk5OTddfX19fX0sIDB4NkM6IHtsOiB7MHg2MToge2w6IHsweDczOiB7bDogezB4Njg6IHtsOiB7MHgzQjoge2M6IFs4NDYzXX19fX19fX19fSwgMHg3NDoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2Qjoge2w6IHsweDNCOiB7YzogWzI5NV19fX19fX19fX19fSwgMHg3OToge2w6IHsweDYyOiB7bDogezB4NzU6IHtsOiB7MHg2Qzoge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODI1OV19fX19fX19fX0sIDB4NzA6IHtsOiB7MHg2ODoge2w6IHsweDY1OiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs4MjA4XX19fX19fX19fX19fX0sXHJcbiAgICAweDQ5OiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzIwNV19fSwgYzogWzIwNV19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg2OToge2w6IHsweDcyOiB7bDogezB4NjM6IHtsOiB7MHgzQjoge2M6IFsyMDZdfX0sIGM6IFsyMDZdfX19fX0sIDB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDQ4XX19fX19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzMwNF19fX19fX19LCAweDQ1OiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzEwNDVdfX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODQ2NV19fX19fSwgMHg2Nzoge2w6IHsweDcyOiB7bDogezB4NjE6IHtsOiB7MHg3Njoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbMjA0XX19LCBjOiBbMjA0XX19fX19fX19fSwgMHg0QToge2w6IHsweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzMwNl19fX19fX19fX0sIDB4NkQ6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsyOThdfX19fX0sIDB4Njc6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDc5OiB7bDogezB4NDk6IHtsOiB7MHgzQjoge2M6IFs4NTIwXX19fX19fX19fX19fX19fX19LCAweDNCOiB7YzogWzg0NjVdfSwgMHg3MDoge2w6IHsweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODY1OF19fX19fX19fX19fX19LCAweDZFOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4NzQ4XX0sIDB4NjU6IHtsOiB7MHg2Nzoge2w6IHsweDcyOiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzg3NDddfX19fX19fX19LCAweDcyOiB7bDogezB4NzM6IHtsOiB7MHg2NToge2w6IHsweDYzOiB7bDogezB4NzQ6IHtsOiB7MHg2OToge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs4ODk4XX19fX19fX19fX19fX19fX19fX19fSwgMHg3Njoge2w6IHsweDY5OiB7bDogezB4NzM6IHtsOiB7MHg2OToge2w6IHsweDYyOiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDQzOiB7bDogezB4NkY6IHtsOiB7MHg2RDoge2w6IHsweDZEOiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs4MjkxXX19fX19fX19fX19LCAweDU0OiB7bDogezB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4MjkwXX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg0Rjoge2w6IHsweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDI1XX19fX19fX0sIDB4NkY6IHtsOiB7MHg2Nzoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFszMDJdfX19fX19fSwgMHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbMTIwMTI4XX19fX19LCAweDc0OiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs5MjFdfX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NDY0XX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzI5Nl19fX19fX19fX19fSwgMHg3NToge2w6IHsweDZCOiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzEwMzBdfX19fX19fSwgMHg2RDoge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMjA3XX19LCBjOiBbMjA3XX19fX19fX0sXHJcbiAgICAweDY5OiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzIzN119fSwgYzogWzIzN119fX19fX19fX0sIDB4NjM6IHtsOiB7MHgzQjoge2M6IFs4MjkxXX0sIDB4Njk6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbMjM4XX19LCBjOiBbMjM4XX19fX19LCAweDc5OiB7bDogezB4M0I6IHtjOiBbMTA4MF19fX19fSwgMHg2NToge2w6IHsweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDc3XX19fX19LCAweDc4OiB7bDogezB4NjM6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzE2MV19fSwgYzogWzE2MV19fX19fX19LCAweDY2OiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFs4NjYwXX19fSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDEwMl19fX19fSwgMHg2Nzoge2w6IHsweDcyOiB7bDogezB4NjE6IHtsOiB7MHg3Njoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbMjM2XX19LCBjOiBbMjM2XX19fX19fX19fSwgMHg2OToge2w6IHsweDNCOiB7YzogWzg1MjBdfSwgMHg2OToge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwNzY0XX19fX19fX0sIDB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg3NDldfX19fX19fSwgMHg2RToge2w6IHsweDY2OiB7bDogezB4Njk6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzEwNzE2XX19fX19fX19fSwgMHg2Rjoge2w6IHsweDc0OiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs4NDg5XX19fX19fX19fSwgMHg2QToge2w6IHsweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzMwN119fX19fX19fX0sIDB4NkQ6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsyOTldfX19fX0sIDB4Njc6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg0NjVdfX19LCAweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2RToge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODQ2NF19fX19fX19fX0sIDB4NzA6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4NDY1XX19fX19fX19fX19LCAweDc0OiB7bDogezB4Njg6IHtsOiB7MHgzQjoge2M6IFszMDVdfX19fX19fSwgMHg2Rjoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbODg4N119fX19fSwgMHg3MDoge2w6IHsweDY1OiB7bDogezB4NjQ6IHtsOiB7MHgzQjoge2M6IFs0MzddfX19fX19fX19LCAweDZFOiB7bDogezB4NjM6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4NDUzXX19fX19fX19fSwgMHgzQjoge2M6IFs4NzEyXX0sIDB4NjY6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbODczNF19LCAweDc0OiB7bDogezB4Njk6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzEwNzE3XX19fX19fX19fX19fX0sIDB4NkY6IHtsOiB7MHg2NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFszMDVdfX19fX19fX19LCAweDc0OiB7bDogezB4NjM6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODg5MF19fX19fX19LCAweDNCOiB7YzogWzg3NDddfSwgMHg2NToge2w6IHsweDY3OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODQ4NF19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2Mzoge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4ODkwXX19fX19fX19fX19LCAweDZDOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDY4OiB7bDogezB4NkI6IHtsOiB7MHgzQjoge2M6IFsxMDc3NV19fX19fX19fX19fSwgMHg3MDoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2NDoge2w6IHsweDNCOiB7YzogWzEwODEyXX19fX19fX19fX19fX0sIDB4NkY6IHtsOiB7MHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTEwNV19fX19fSwgMHg2Nzoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFszMDNdfX19fX19fSwgMHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbMTIwMTU0XX19fX19LCAweDc0OiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs5NTNdfX19fX19fSwgMHg3MDoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2NDoge2w6IHsweDNCOiB7YzogWzEwODEyXX19fX19fX19fSwgMHg3MToge2w6IHsweDc1OiB7bDogezB4NjU6IHtsOiB7MHg3Mzoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTkxXX19LCBjOiBbMTkxXX19fX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMTk5OThdfX19fX0sIDB4Njk6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzg3MTJdfSwgMHg2NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4OTQ5XX19fX19fX0sIDB4NDU6IHtsOiB7MHgzQjoge2M6IFs4OTUzXX19fSwgMHg3Mzoge2w6IHsweDNCOiB7YzogWzg5NDhdfSwgMHg3Njoge2w6IHsweDNCOiB7YzogWzg5NDddfX19fX0sIDB4NzY6IHtsOiB7MHgzQjoge2M6IFs4NzEyXX19fX19fX19fSwgMHg3NDoge2w6IHsweDNCOiB7YzogWzgyOTBdfSwgMHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzI5N119fX19fX19fX19fSwgMHg3NToge2w6IHsweDZCOiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzExMTBdfX19fX19fSwgMHg2RDoge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMjM5XX19LCBjOiBbMjM5XX19fX19fX0sXHJcbiAgICAweDRBOiB7bDogezB4NjM6IHtsOiB7MHg2OToge2w6IHsweDcyOiB7bDogezB4NjM6IHtsOiB7MHgzQjoge2M6IFszMDhdfX19fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzEwNDldfX19fX0sIDB4NjY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDA3N119fX19fSwgMHg2Rjoge2w6IHsweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxMjldfX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMTk5NzNdfX19fX0sIDB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDMyXX19fX19fX19fX19LCAweDc1OiB7bDogezB4NkI6IHtsOiB7MHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTAyOF19fX19fX19fX19fSxcclxuICAgIDB4NkE6IHtsOiB7MHg2Mzoge2w6IHsweDY5OiB7bDogezB4NzI6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzMwOV19fX19fX19LCAweDc5OiB7bDogezB4M0I6IHtjOiBbMTA4MV19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMTAzXX19fX19LCAweDZEOiB7bDogezB4NjE6IHtsOiB7MHg3NDoge2w6IHsweDY4OiB7bDogezB4M0I6IHtjOiBbNTY3XX19fX19fX19fSwgMHg2Rjoge2w6IHsweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxNTVdfX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMTk5OTldfX19fX0sIDB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMTEyXX19fX19fX19fX19LCAweDc1OiB7bDogezB4NkI6IHtsOiB7MHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTEwOF19fX19fX19fX19fSxcclxuICAgIDB4NEI6IHtsOiB7MHg2MToge2w6IHsweDcwOiB7bDogezB4NzA6IHtsOiB7MHg2MToge2w6IHsweDNCOiB7YzogWzkyMl19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg2NToge2w6IHsweDY0OiB7bDogezB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzMxMF19fX19fX19fX0sIDB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDUwXX19fX19LCAweDY2OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAwNzhdfX19fX0sIDB4NDg6IHtsOiB7MHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTA2MV19fX19fX19LCAweDRBOiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzEwMzZdfX19fX19fSwgMHg2Rjoge2w6IHsweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxMzBdfX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMTk5NzRdfX19fX19fX19LFxyXG4gICAgMHg2Qjoge2w6IHsweDYxOiB7bDogezB4NzA6IHtsOiB7MHg3MDoge2w6IHsweDYxOiB7bDogezB4M0I6IHtjOiBbOTU0XX0sIDB4NzY6IHtsOiB7MHgzQjoge2M6IFsxMDA4XX19fX19fX19fX19LCAweDYzOiB7bDogezB4NjU6IHtsOiB7MHg2NDoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFszMTFdfX19fX19fX19LCAweDc5OiB7bDogezB4M0I6IHtjOiBbMTA4Ml19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMTA0XX19fX19LCAweDY3OiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDY1OiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFszMTJdfX19fX19fX19fX0sIDB4Njg6IHtsOiB7MHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTA5M119fX19fX19LCAweDZBOiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzExMTZdfX19fX19fSwgMHg2Rjoge2w6IHsweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxNTZdfX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAwMDBdfX19fX19fX19LFxyXG4gICAgMHg2Qzoge2w6IHsweDQxOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODY2Nl19fX19fX19LCAweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjU2XX19fX19LCAweDc0OiB7bDogezB4NjE6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMTA1MjNdfX19fX19fX19fX0sIDB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzMxNF19fX19fX19fX0sIDB4NjU6IHtsOiB7MHg2RDoge2w6IHsweDcwOiB7bDogezB4NzQ6IHtsOiB7MHg3OToge2w6IHsweDc2OiB7bDogezB4M0I6IHtjOiBbMTA2NzZdfX19fX19fX19fX19fSwgMHg2Nzoge2w6IHsweDcyOiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzg0NjZdfX19fX19fX19LCAweDZEOiB7bDogezB4NjI6IHtsOiB7MHg2NDoge2w6IHsweDYxOiB7bDogezB4M0I6IHtjOiBbOTU1XX19fX19fX19fSwgMHg2RToge2w6IHsweDY3OiB7bDogezB4M0I6IHtjOiBbMTAyMTZdfSwgMHg2NDoge2w6IHsweDNCOiB7YzogWzEwNjQxXX19fSwgMHg2Qzoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbMTAyMTZdfX19fX19fX19LCAweDcwOiB7bDogezB4M0I6IHtjOiBbMTA4ODVdfX19LCAweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2Rjoge2w6IHsweDNCOiB7YzogWzE3MV19fSwgYzogWzE3MV19fX19fSwgMHg3Mjoge2w6IHsweDcyOiB7bDogezB4NjI6IHtsOiB7MHgzQjoge2M6IFs4Njc2XX0sIDB4NjY6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzEwNTI3XX19fX19fX0sIDB4M0I6IHtjOiBbODU5Ml19LCAweDY2OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFsxMDUyNV19fX19fSwgMHg2ODoge2w6IHsweDZCOiB7bDogezB4M0I6IHtjOiBbODYxN119fX19fSwgMHg2Qzoge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbODYxOV19fX19fSwgMHg3MDoge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMTA1NTNdfX19fX0sIDB4NzM6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4M0I6IHtjOiBbMTA2MTFdfX19fX19fSwgMHg3NDoge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODYxMF19fX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsxMDUyMV19fX19fX19LCAweDNCOiB7YzogWzEwOTIzXX0sIDB4NjU6IHtsOiB7MHgzQjoge2M6IFsxMDkyNV19LCAweDczOiB7bDogezB4M0I6IHtjOiBbMTA5MjUsIDY1MDI0XX19fX19fX19fSwgMHg2Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTA4XX19fX19fX0sIDB4NjI6IHtsOiB7MHg3Mjoge2w6IHsweDZCOiB7bDogezB4M0I6IHtjOiBbMTAwOThdfX19fX19fSwgMHg3Mjoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzEyM119fX0sIDB4NkI6IHtsOiB7MHgzQjoge2M6IFs5MV19fX19fX19LCAweDZCOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsxMDYzNV19fX0sIDB4NzM6IHtsOiB7MHg2Qzoge2w6IHsweDY0OiB7bDogezB4M0I6IHtjOiBbMTA2MzldfX19LCAweDc1OiB7bDogezB4M0I6IHtjOiBbMTA2MzddfX19fX19fX19fX19fSwgMHg0Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTEwXX19fX19fX19fSwgMHg2Mzoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbMzE4XX19fX19fX19fSwgMHg2NToge2w6IHsweDY0OiB7bDogezB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzMxNl19fX19fX19LCAweDY5OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4OTY4XX19fX19fX0sIDB4NzU6IHtsOiB7MHg2Mjoge2w6IHsweDNCOiB7YzogWzEyM119fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzEwODNdfX19fX0sIDB4NjQ6IHtsOiB7MHg2Mzoge2w6IHsweDYxOiB7bDogezB4M0I6IHtjOiBbMTA1NTBdfX19fX0sIDB4NzE6IHtsOiB7MHg3NToge2w6IHsweDZGOiB7bDogezB4M0I6IHtjOiBbODIyMF19LCAweDcyOiB7bDogezB4M0I6IHtjOiBbODIyMl19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2NDoge2w6IHsweDY4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTk5XX19fX19fX19fSwgMHg3NToge2w6IHsweDczOiB7bDogezB4Njg6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA1NzFdfX19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDY4OiB7bDogezB4M0I6IHtjOiBbODYyNl19fX19fX19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbODgwNF19LCAweDY2OiB7bDogezB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODU5Ml19LCAweDc0OiB7bDogezB4NjE6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODYxMF19fX19fX19fX19fX19fX19fX19LCAweDY4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcwOiB7bDogezB4NkY6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs4NjM3XX19fX19fX19fSwgMHg3NToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbODYzNl19fX19fX19fX19fX19fX19fX19LCAweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODY0N119fX19fX19fX19fX19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2OToge2w6IHsweDY3OiB7bDogezB4Njg6IHtsOiB7MHg3NDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NTk2XX0sIDB4NzM6IHtsOiB7MHgzQjoge2M6IFs4NjQ2XX19fX19fX19fX19fX0sIDB4Njg6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzA6IHtsOiB7MHg2Rjoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzg2NTFdfX19fX19fX19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NjIxXX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2ODoge2w6IHsweDcyOiB7bDogezB4NjU6IHtsOiB7MHg2NToge2w6IHsweDc0OiB7bDogezB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4OTA3XX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4Njc6IHtsOiB7MHgzQjoge2M6IFs4OTIyXX19fSwgMHg3MToge2w6IHsweDNCOiB7YzogWzg4MDRdfSwgMHg3MToge2w6IHsweDNCOiB7YzogWzg4MDZdfX19LCAweDczOiB7bDogezB4NkM6IHtsOiB7MHg2MToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxMDg3N119fX19fX19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzEwOTIwXX19fX19LCAweDNCOiB7YzogWzEwODc3XX0sIDB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA4NzldfSwgMHg2Rjoge2w6IHsweDNCOiB7YzogWzEwODgxXX0sIDB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDg4M119fX19fX19fX19fSwgMHg2Nzoge2w6IHsweDNCOiB7YzogWzg5MjIsIDY1MDI0XX0sIDB4NjU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzEwODk5XX19fX19fX0sIDB4NzM6IHtsOiB7MHg2MToge2w6IHsweDcwOiB7bDogezB4NzA6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzg6IHtsOiB7MHgzQjoge2M6IFsxMDg4NV19fX19fX19fX19fX19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg5MThdfX19fX19fSwgMHg2NToge2w6IHsweDcxOiB7bDogezB4Njc6IHtsOiB7MHg3NDoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODkyMl19fX19fX19LCAweDcxOiB7bDogezB4Njc6IHtsOiB7MHg3NDoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA4OTFdfX19fX19fX19fX19fSwgMHg2Nzoge2w6IHsweDc0OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4ODIyXX19fX19fX0sIDB4NzM6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4M0I6IHtjOiBbODgxOF19fX19fX19fX19fX19LCAweDQ1OiB7bDogezB4M0I6IHtjOiBbODgwNl19LCAweDY3OiB7bDogezB4M0I6IHtjOiBbMTA4OTFdfX19fX0sIDB4NjY6IHtsOiB7MHg2OToge2w6IHsweDczOiB7bDogezB4Njg6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwNjIwXX19fX19fX19fSwgMHg2Qzoge2w6IHsweDZGOiB7bDogezB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg5NzBdfX19fX19fX19LCAweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMTA1XX19fX19LCAweDY3OiB7bDogezB4M0I6IHtjOiBbODgyMl19LCAweDQ1OiB7bDogezB4M0I6IHtjOiBbMTA4OTddfX19fX0sIDB4NDg6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA1OTRdfX19fX19fSwgMHg2ODoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2NDoge2w6IHsweDNCOiB7YzogWzg2MzddfX19LCAweDc1OiB7bDogezB4M0I6IHtjOiBbODYzNl19LCAweDZDOiB7bDogezB4M0I6IHtjOiBbMTA2MDJdfX19fX19fX19LCAweDYyOiB7bDogezB4NkM6IHtsOiB7MHg2Qjoge2w6IHsweDNCOiB7YzogWzk2MDRdfX19fX19fX19LCAweDZBOiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzExMTNdfX19fX19fSwgMHg2Qzoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg2NDddfX19fX19fSwgMHgzQjoge2M6IFs4ODEwXX0sIDB4NjM6IHtsOiB7MHg2Rjoge2w6IHsweDcyOiB7bDogezB4NkU6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODk5MF19fX19fX19fX19fX19LCAweDY4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDY0OiB7bDogezB4M0I6IHtjOiBbMTA2MDNdfX19fX19fX19LCAweDc0OiB7bDogezB4NzI6IHtsOiB7MHg2OToge2w6IHsweDNCOiB7YzogWzk3MjJdfX19fX19fX19LCAweDZEOiB7bDogezB4Njk6IHtsOiB7MHg2NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFszMjBdfX19fX19fX19LCAweDZGOiB7bDogezB4NzU6IHtsOiB7MHg3Mzoge2w6IHsweDc0OiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDY4OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs5MTM2XX19fX19fX19fSwgMHgzQjoge2M6IFs5MTM2XX19fX19fX19fX19LCAweDZFOiB7bDogezB4NjE6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzEwODg5XX0sIDB4NzA6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzg6IHtsOiB7MHgzQjoge2M6IFsxMDg4OV19fX19fX19fX19fX19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbMTA4ODddfSwgMHg3MToge2w6IHsweDNCOiB7YzogWzEwODg3XX0sIDB4NzE6IHtsOiB7MHgzQjoge2M6IFs4ODA4XX19fX19fX0sIDB4NDU6IHtsOiB7MHgzQjoge2M6IFs4ODA4XX19fSwgMHg3Mzoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHgzQjoge2M6IFs4OTM0XX19fX19fX19fSwgMHg2Rjoge2w6IHsweDYxOiB7bDogezB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzEwMjIwXX19fX19LCAweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NzAxXX19fX19fX0sIDB4NjI6IHtsOiB7MHg3Mjoge2w6IHsweDZCOiB7bDogezB4M0I6IHtjOiBbMTAyMTRdfX19fX19fSwgMHg2RToge2w6IHsweDY3OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDY2OiB7bDogezB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbMTAyMjldfX19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2OToge2w6IHsweDY3OiB7bDogezB4Njg6IHtsOiB7MHg3NDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFsxMDIzMV19fX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg2RDoge2w6IHsweDYxOiB7bDogezB4NzA6IHtsOiB7MHg3Mzoge2w6IHsweDc0OiB7bDogezB4NkY6IHtsOiB7MHgzQjoge2M6IFsxMDIzNl19fX19fX19fX19fX19LCAweDcyOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDY4OiB7bDogezB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbMTAyMzBdfX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg2Rjoge2w6IHsweDcwOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODYxOV19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2OToge2w6IHsweDY3OiB7bDogezB4Njg6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg2MjBdfX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg3MDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDYyOV19fX19fSwgMHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDE1N119fX0sIDB4NkM6IHtsOiB7MHg3NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbMTA3OTddfX19fX19fX19LCAweDc0OiB7bDogezB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFsxMDgwNF19fX19fX19fX19fSwgMHg3Nzoge2w6IHsweDYxOiB7bDogezB4NzM6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg3MjddfX19fX19fSwgMHg2Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs5NV19fX19fX19fX0sIDB4N0E6IHtsOiB7MHgzQjoge2M6IFs5Njc0XX0sIDB4NjU6IHtsOiB7MHg2RToge2w6IHsweDY3OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs5Njc0XX19fX19fX19fSwgMHg2Njoge2w6IHsweDNCOiB7YzogWzEwNzMxXX19fX19fX0sIDB4NzA6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbNDBdfSwgMHg2Qzoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA2NDNdfX19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjQ2XX19fX19fX0sIDB4NjM6IHtsOiB7MHg2Rjoge2w6IHsweDcyOiB7bDogezB4NkU6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODk5MV19fX19fX19fX19fX19LCAweDY4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg2NTFdfSwgMHg2NDoge2w6IHsweDNCOiB7YzogWzEwNjA1XX19fX19fX19fSwgMHg2RDoge2w6IHsweDNCOiB7YzogWzgyMDZdfX19LCAweDc0OiB7bDogezB4NzI6IHtsOiB7MHg2OToge2w6IHsweDNCOiB7YzogWzg4OTVdfX19fX19fX19LCAweDczOiB7bDogezB4NjE6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NkY6IHtsOiB7MHgzQjoge2M6IFs4MjQ5XX19fX19fX19fSwgMHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDAxXX19fX19LCAweDY4OiB7bDogezB4M0I6IHtjOiBbODYyNF19fX0sIDB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzg4MThdfSwgMHg2NToge2w6IHsweDNCOiB7YzogWzEwODkzXX19fSwgMHg2Nzoge2w6IHsweDNCOiB7YzogWzEwODk1XX19fX19fX0sIDB4NzE6IHtsOiB7MHg2Mjoge2w6IHsweDNCOiB7YzogWzkxXX19fSwgMHg3NToge2w6IHsweDZGOiB7bDogezB4M0I6IHtjOiBbODIxNl19LCAweDcyOiB7bDogezB4M0I6IHtjOiBbODIxOF19fX19fX19fX0sIDB4NzQ6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4NkI6IHtsOiB7MHgzQjoge2M6IFszMjJdfX19fX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2Mzoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbMTA5MThdfX19LCAweDY5OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDg3M119fX19fX19LCAweDNCOiB7YzogWzYwXX0sIDB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODkxOF19fX19fX19LCAweDY4OiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODkwN119fX19fX19fX0sIDB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4OTA1XX19fX19fX19fSwgMHg2Qzoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNjE0XX19fX19fX19fSwgMHg3MToge2w6IHsweDc1OiB7bDogezB4NjU6IHtsOiB7MHg3Mzoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA4NzVdfX19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2OToge2w6IHsweDNCOiB7YzogWzk2NjddfSwgMHg2NToge2w6IHsweDNCOiB7YzogWzg4ODRdfX19LCAweDY2OiB7bDogezB4M0I6IHtjOiBbOTY2Nl19fX19fSwgMHg1MDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDY0Nl19fX19fX19fX19LCBjOiBbNjBdfSwgMHg3NToge2w6IHsweDcyOiB7bDogezB4NjQ6IHtsOiB7MHg3Mzoge2w6IHsweDY4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTcwXX19fX19fX19fX19LCAweDc1OiB7bDogezB4Njg6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA1OThdfX19fX19fX19fX19fSwgMHg3Njoge2w6IHsweDY1OiB7bDogezB4NzI6IHtsOiB7MHg3NDoge2w6IHsweDZFOiB7bDogezB4NjU6IHtsOiB7MHg3MToge2w6IHsweDcxOiB7bDogezB4M0I6IHtjOiBbODgwOCwgNjUwMjRdfX19fX19fX19fX19fX19LCAweDZFOiB7bDogezB4NDU6IHtsOiB7MHgzQjoge2M6IFs4ODA4LCA2NTAyNF19fX19fX19fX0sXHJcbiAgICAweDRDOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzMxM119fX19fX19fX0sIDB4NkQ6IHtsOiB7MHg2Mjoge2w6IHsweDY0OiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs5MjNdfX19fX19fX19LCAweDZFOiB7bDogezB4Njc6IHtsOiB7MHgzQjoge2M6IFsxMDIxOF19fX19fSwgMHg3MDoge2w6IHsweDZDOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDY1OiB7bDogezB4NzQ6IHtsOiB7MHg3Mjoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbODQ2Nl19fX19fX19fX19fX19fX19fSwgMHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODYwNl19fX19fX19LCAweDYzOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFszMTddfX19fX19fX19LCAweDY1OiB7bDogezB4NjQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMzE1XX19fX19fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzEwNTFdfX19fX0sIDB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4NDE6IHtsOiB7MHg2RToge2w6IHsweDY3OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDQyOiB7bDogezB4NzI6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NkI6IHtsOiB7MHg2NToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTAyMTZdfX19fX19fX19fX19fX19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHg0Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4Njc2XX19fX19fX0sIDB4M0I6IHtjOiBbODU5Ml19LCAweDUyOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDY4OiB7bDogezB4NzQ6IHtsOiB7MHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODY0Nl19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NjU2XX19fX19fX19fX19LCAweDQzOiB7bDogezB4NjU6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2RToge2w6IHsweDY3OiB7bDogezB4M0I6IHtjOiBbODk2OF19fX19fX19fX19fX19fX0sIDB4NDQ6IHtsOiB7MHg2Rjoge2w6IHsweDc1OiB7bDogezB4NjI6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4NDI6IHtsOiB7MHg3Mjoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg2Qjoge2w6IHsweDY1OiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxMDIxNF19fX19fX19fX19fX19fX19fX19fX19fSwgMHg3Nzoge2w6IHsweDZFOiB7bDogezB4NTQ6IHtsOiB7MHg2NToge2w6IHsweDY1OiB7bDogezB4NTY6IHtsOiB7MHg2NToge2w6IHsweDYzOiB7bDogezB4NzQ6IHtsOiB7MHg2Rjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA1OTNdfX19fX19fX19fX19fX19fX19fSwgMHg1Njoge2w6IHsweDY1OiB7bDogezB4NjM6IHtsOiB7MHg3NDoge2w6IHsweDZGOiB7bDogezB4NzI6IHtsOiB7MHg0Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDU4NV19fX19fX19LCAweDNCOiB7YzogWzg2NDNdfX19fX19fX19fX19fX19fX19fX19LCAweDQ2OiB7bDogezB4NkM6IHtsOiB7MHg2Rjoge2w6IHsweDZGOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4OTcwXX19fX19fX19fX19LCAweDUyOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDY4OiB7bDogezB4NzQ6IHtsOiB7MHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODU5Nl19fX19fX19fX19fSwgMHg1Njoge2w6IHsweDY1OiB7bDogezB4NjM6IHtsOiB7MHg3NDoge2w6IHsweDZGOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDU3NF19fX19fX19fX19fX19fX19fX19fX19fSwgMHg3Mjoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2NjBdfX19fX19fX19fX19fX19fX19fX19LCAweDU0OiB7bDogezB4NjU6IHtsOiB7MHg2NToge2w6IHsweDQxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NjEyXX19fX19fX19fX19LCAweDNCOiB7YzogWzg4NjddfSwgMHg1Njoge2w6IHsweDY1OiB7bDogezB4NjM6IHtsOiB7MHg3NDoge2w6IHsweDZGOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDU4Nl19fX19fX19fX19fX19fX19fSwgMHg3Mjoge2w6IHsweDY5OiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDY3OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDQyOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNzAzXX19fX19fX0sIDB4M0I6IHtjOiBbODg4Ml19LCAweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4ODg0XX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg1NToge2w6IHsweDcwOiB7bDogezB4NDQ6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4NkU6IHtsOiB7MHg1Njoge2w6IHsweDY1OiB7bDogezB4NjM6IHtsOiB7MHg3NDoge2w6IHsweDZGOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDU3N119fX19fX19fX19fX19fX19fX19fX0sIDB4NTQ6IHtsOiB7MHg2NToge2w6IHsweDY1OiB7bDogezB4NTY6IHtsOiB7MHg2NToge2w6IHsweDYzOiB7bDogezB4NzQ6IHtsOiB7MHg2Rjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA1OTJdfX19fX19fX19fX19fX19fX19fSwgMHg1Njoge2w6IHsweDY1OiB7bDogezB4NjM6IHtsOiB7MHg3NDoge2w6IHsweDZGOiB7bDogezB4NzI6IHtsOiB7MHg0Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDU4NF19fX19fX19LCAweDNCOiB7YzogWzg2MzldfX19fX19fX19fX19fX19fX0sIDB4NTY6IHtsOiB7MHg2NToge2w6IHsweDYzOiB7bDogezB4NzQ6IHtsOiB7MHg2Rjoge2w6IHsweDcyOiB7bDogezB4NDI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA1NzhdfX19fX19fSwgMHgzQjoge2M6IFs4NjM2XX19fX19fX19fX19fX19fX19LCAweDczOiB7bDogezB4NzM6IHtsOiB7MHg0NToge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4NDc6IHtsOiB7MHg3Mjoge2w6IHsweDY1OiB7bDogezB4NjE6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4OTIyXX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NDY6IHtsOiB7MHg3NToge2w6IHsweDZDOiB7bDogezB4NkM6IHtsOiB7MHg0NToge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODgwNl19fX19fX19fX19fX19fX19fX19LCAweDQ3OiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDYxOiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODgyMl19fX19fX19fX19fX19fX0sIDB4NEM6IHtsOiB7MHg2NToge2w6IHsweDczOiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFsxMDkxM119fX19fX19fX0sIDB4NTM6IHtsOiB7MHg2Qzoge2w6IHsweDYxOiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsxMDg3N119fX19fX19fX19fX19fX19fX19fX0sIDB4NTQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg4MThdfX19fX19fX19fX19fX19fX0sIDB4NjY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDA3OV19fX19fSwgMHg0QToge2w6IHsweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDMzXX19fX19fX0sIDB4NkM6IHtsOiB7MHgzQjoge2M6IFs4OTIwXX0sIDB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2NjZdfX19fX19fX19fX19fX19fX19fSwgMHg2RDoge2w6IHsweDY5OiB7bDogezB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMzE5XX19fX19fX19fX19LCAweDZGOiB7bDogezB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDRDOiB7bDogezB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzEwMjI5XX19fX19fX19fX19LCAweDUyOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDY4OiB7bDogezB4NzQ6IHtsOiB7MHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbMTAyMzFdfX19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NkM6IHtsOiB7MHg2NToge2w6IHsweDY2OiB7bDogezB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbMTAyMzJdfX19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2OToge2w6IHsweDY3OiB7bDogezB4Njg6IHtsOiB7MHg3NDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFsxMDIzNF19fX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg1Mjoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzEwMjMwXX19fX19fX19fX19fX19fX19fX19fSwgMHg3Mjoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzEwMjMzXX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDEzMV19fX19fSwgMHg3Nzoge2w6IHsweDY1OiB7bDogezB4NzI6IHtsOiB7MHg0Qzoge2w6IHsweDY1OiB7bDogezB4NjY6IHtsOiB7MHg3NDoge2w6IHsweDQxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NjAxXX19fX19fX19fX19fX19fX19fX0sIDB4NTI6IHtsOiB7MHg2OToge2w6IHsweDY3OiB7bDogezB4Njg6IHtsOiB7MHg3NDoge2w6IHsweDQxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NjAwXX19fX19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg0NjZdfX19fX0sIDB4Njg6IHtsOiB7MHgzQjoge2M6IFs4NjI0XX19fSwgMHg3NDoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2Qjoge2w6IHsweDNCOiB7YzogWzMyMV19fX19fX19fX19fSwgMHg1NDoge2w6IHsweDNCOiB7YzogWzYwXX19LCBjOiBbNjBdfSwgMHg3NDoge2w6IHsweDNCOiB7YzogWzg4MTBdfX19fX0sXHJcbiAgICAweDZEOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTc1XX19LCBjOiBbMTc1XX19fSwgMHg2Qzoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbOTc5NF19fX0sIDB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxMDAxNl19LCAweDY1OiB7bDogezB4NzM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzEwMDE2XX19fX19fX19fX19LCAweDcwOiB7bDogezB4M0I6IHtjOiBbODYxNF19LCAweDczOiB7bDogezB4NzQ6IHtsOiB7MHg2Rjoge2w6IHsweDNCOiB7YzogWzg2MTRdfSwgMHg2NDoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzg2MTVdfX19fX19fX19LCAweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODYxMl19fX19fX19fX0sIDB4NzU6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzg2MTNdfX19fX19fX19fX19fSwgMHg3Mjoge2w6IHsweDZCOiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzk2NDZdfX19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg2Rjoge2w6IHsweDZEOiB7bDogezB4NkQ6IHtsOiB7MHg2MToge2w6IHsweDNCOiB7YzogWzEwNzkzXX19fX19fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzEwODRdfX19fX0sIDB4NjQ6IHtsOiB7MHg2MToge2w6IHsweDczOiB7bDogezB4Njg6IHtsOiB7MHgzQjoge2M6IFs4MjEyXX19fX19fX19fSwgMHg0NDoge2w6IHsweDQ0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg3NjJdfX19fX19fX19LCAweDY1OiB7bDogezB4NjE6IHtsOiB7MHg3Mzoge2w6IHsweDc1OiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDY0OiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDY3OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg3MzddfX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMTA2XX19fX19LCAweDY4OiB7bDogezB4NkY6IHtsOiB7MHgzQjoge2M6IFs4NDg3XX19fX19LCAweDY5OiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4M0I6IHtjOiBbMTgxXX19LCBjOiBbMTgxXX19fX19LCAweDY0OiB7bDogezB4NjE6IHtsOiB7MHg3Mzoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbNDJdfX19fX19fSwgMHg2Mzoge2w6IHsweDY5OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDk5Ml19fX19fX19LCAweDNCOiB7YzogWzg3MzldfSwgMHg2NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxODNdfX0sIGM6IFsxODNdfX19fX19fSwgMHg2RToge2w6IHsweDc1OiB7bDogezB4NzM6IHtsOiB7MHg2Mjoge2w6IHsweDNCOiB7YzogWzg4NjNdfX19LCAweDNCOiB7YzogWzg3MjJdfSwgMHg2NDoge2w6IHsweDNCOiB7YzogWzg3NjBdfSwgMHg3NToge2w6IHsweDNCOiB7YzogWzEwNzk0XX19fX19fX19fX19fX0sIDB4NkM6IHtsOiB7MHg2Mzoge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbMTA5NzFdfX19fX0sIDB4NjQ6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzgyMzBdfX19fX19fSwgMHg2RToge2w6IHsweDcwOiB7bDogezB4NkM6IHtsOiB7MHg3NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODcyM119fX19fX19fX19fSwgMHg2Rjoge2w6IHsweDY0OiB7bDogezB4NjU6IHtsOiB7MHg2Qzoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODg3MV19fX19fX19fX0sIDB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDE1OF19fX19fX19LCAweDcwOiB7bDogezB4M0I6IHtjOiBbODcyM119fX0sIDB4NzM6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDAyXX19fX19LCAweDc0OiB7bDogezB4NzA6IHtsOiB7MHg2Rjoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODc2Nl19fX19fX19fX19fSwgMHg3NToge2w6IHsweDNCOiB7YzogWzk1Nl19LCAweDZDOiB7bDogezB4NzQ6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4NjE6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzg4ODhdfX19fX19fX19fX19fSwgMHg2RDoge2w6IHsweDYxOiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFs4ODg4XX19fX19fX19fX19LFxyXG4gICAgMHg0RDoge2w6IHsweDYxOiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFsxMDUwMV19fX19fSwgMHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTA1Ml19fX19fSwgMHg2NToge2w6IHsweDY0OiB7bDogezB4Njk6IHtsOiB7MHg3NToge2w6IHsweDZEOiB7bDogezB4NTM6IHtsOiB7MHg3MDoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzgyODddfX19fX19fX19fX19fX19fX19fSwgMHg2Qzoge2w6IHsweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4NzI6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzg0OTldfX19fX19fX19fX19fX19fX0sIDB4NjY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDA4MF19fX19fSwgMHg2OToge2w6IHsweDZFOiB7bDogezB4NzU6IHtsOiB7MHg3Mzoge2w6IHsweDUwOiB7bDogezB4NkM6IHtsOiB7MHg3NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODcyM119fX19fX19fX19fX19fX19fSwgMHg2Rjoge2w6IHsweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxMzJdfX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NDk5XX19fX19fX0sIDB4NzU6IHtsOiB7MHgzQjoge2M6IFs5MjRdfX19fX0sXHJcbiAgICAweDZFOiB7bDogezB4NjE6IHtsOiB7MHg2Mjoge2w6IHsweDZDOiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs4NzExXX19fX19fX0sIDB4NjM6IHtsOiB7MHg3NToge2w6IHsweDc0OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFszMjRdfX19fX19fX19LCAweDZFOiB7bDogezB4Njc6IHtsOiB7MHgzQjoge2M6IFs4NzM2LCA4NDAyXX19fX19LCAweDcwOiB7bDogezB4M0I6IHtjOiBbODc3N119LCAweDQ1OiB7bDogezB4M0I6IHtjOiBbMTA4NjQsIDgyNF19fX0sIDB4Njk6IHtsOiB7MHg2NDoge2w6IHsweDNCOiB7YzogWzg3NzksIDgyNF19fX19fSwgMHg2Rjoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbMzI5XX19fX19LCAweDcwOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc4OiB7bDogezB4M0I6IHtjOiBbODc3N119fX19fX19fX19fSwgMHg3NDoge2w6IHsweDc1OiB7bDogezB4NzI6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbOTgzOF19LCAweDczOiB7bDogezB4M0I6IHtjOiBbODQ2OV19fX19fX19LCAweDNCOiB7YzogWzk4MzhdfX19fX19fX19LCAweDYyOiB7bDogezB4NzM6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzE2MF19fSwgYzogWzE2MF19fX0sIDB4NzU6IHtsOiB7MHg2RDoge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbODc4MiwgODI0XX0sIDB4NjU6IHtsOiB7MHgzQjoge2M6IFs4NzgzLCA4MjRdfX19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg2MToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbMTA4MTldfX19LCAweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzMyOF19fX19fX19fX0sIDB4NjU6IHtsOiB7MHg2NDoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFszMjZdfX19fX19fX19LCAweDZGOiB7bDogezB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzg3NzVdfSwgMHg2NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxMDg2MSwgODI0XX19fX19fX19fX19fX0sIDB4NzU6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzEwODE4XX19fX19LCAweDc5OiB7bDogezB4M0I6IHtjOiBbMTA4NV19fX19fSwgMHg2NDoge2w6IHsweDYxOiB7bDogezB4NzM6IHtsOiB7MHg2ODoge2w6IHsweDNCOiB7YzogWzgyMTFdfX19fX19fX19LCAweDY1OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDY4OiB7bDogezB4NkI6IHtsOiB7MHgzQjoge2M6IFsxMDUzMl19fX19fSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzg1OTldfSwgMHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODU5OV19fX19fX19fX19fSwgMHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjYzXX19fX19fX0sIDB4M0I6IHtjOiBbODgwMF19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg3ODQsIDgyNF19fX19fX19LCAweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2OToge2w6IHsweDc2OiB7bDogezB4M0I6IHtjOiBbODgwMl19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2NToge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDUzNl19fX19fX19LCAweDY5OiB7bDogezB4NkQ6IHtsOiB7MHgzQjoge2M6IFs4NzcwLCA4MjRdfX19fX19fSwgMHg3ODoge2w6IHsweDY5OiB7bDogezB4NzM6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg3MDhdfSwgMHg3Mzoge2w6IHsweDNCOiB7YzogWzg3MDhdfX19fX19fX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMTA3XX19fX19LCAweDY3OiB7bDogezB4NDU6IHtsOiB7MHgzQjoge2M6IFs4ODA3LCA4MjRdfX19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbODgxN119LCAweDcxOiB7bDogezB4M0I6IHtjOiBbODgxN119LCAweDcxOiB7bDogezB4M0I6IHtjOiBbODgwNywgODI0XX19fSwgMHg3Mzoge2w6IHsweDZDOiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA4NzgsIDgyNF19fX19fX19fX19fX19LCAweDczOiB7bDogezB4M0I6IHtjOiBbMTA4NzgsIDgyNF19fX19fSwgMHg3Mzoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHgzQjoge2M6IFs4ODIxXX19fX19fX0sIDB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4ODE1XX0sIDB4NzI6IHtsOiB7MHgzQjoge2M6IFs4ODE1XX19fX19fX0sIDB4NDc6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzg5MjEsIDgyNF19fX0sIDB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4ODExLCA4NDAyXX0sIDB4NzY6IHtsOiB7MHgzQjoge2M6IFs4ODExLCA4MjRdfX19fX19fSwgMHg2ODoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg2MjJdfX19fX19fSwgMHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjU0XX19fX19fX0sIDB4NzA6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA5OTRdfX19fX19fX19LCAweDY5OiB7bDogezB4M0I6IHtjOiBbODcxNV19LCAweDczOiB7bDogezB4M0I6IHtjOiBbODk1Nl19LCAweDY0OiB7bDogezB4M0I6IHtjOiBbODk1NF19fX19fSwgMHg3Njoge2w6IHsweDNCOiB7YzogWzg3MTVdfX19fX0sIDB4NkE6IHtsOiB7MHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTExNF19fX19fX19LCAweDZDOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODYwMl19fX19fX19LCAweDQxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg2NTNdfX19fX19fSwgMHg2NDoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODIyOV19fX19fSwgMHg0NToge2w6IHsweDNCOiB7YzogWzg4MDYsIDgyNF19fX0sIDB4NjU6IHtsOiB7MHgzQjoge2M6IFs4ODE2XX0sIDB4NjY6IHtsOiB7MHg3NDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NjAyXX19fX19fX19fX19LCAweDcyOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDY4OiB7bDogezB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODYyMl19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDcxOiB7bDogezB4M0I6IHtjOiBbODgxNl19LCAweDcxOiB7bDogezB4M0I6IHtjOiBbODgwNiwgODI0XX19fSwgMHg3Mzoge2w6IHsweDZDOiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA4NzcsIDgyNF19fX19fX19fX19fX19LCAweDczOiB7bDogezB4M0I6IHtjOiBbMTA4NzcsIDgyNF19LCAweDczOiB7bDogezB4M0I6IHtjOiBbODgxNF19fX19fX19LCAweDczOiB7bDogezB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzg4MjBdfX19fX19fSwgMHg3NDoge2w6IHsweDNCOiB7YzogWzg4MTRdfSwgMHg3Mjoge2w6IHsweDY5OiB7bDogezB4M0I6IHtjOiBbODkzOF19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbODk0MF19fX19fX19fX19fSwgMHg0Qzoge2w6IHsweDY1OiB7bDogezB4NjY6IHtsOiB7MHg3NDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NjUzXX19fX19fX19fX19LCAweDcyOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDY4OiB7bDogezB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODY1NF19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NkM6IHtsOiB7MHgzQjoge2M6IFs4OTIwLCA4MjRdfX19LCAweDc0OiB7bDogezB4M0I6IHtjOiBbODgxMCwgODQwMl19LCAweDc2OiB7bDogezB4M0I6IHtjOiBbODgxMCwgODI0XX19fX19fX0sIDB4NkQ6IHtsOiB7MHg2OToge2w6IHsweDY0OiB7bDogezB4M0I6IHtjOiBbODc0MF19fX19fX19LCAweDZGOiB7bDogezB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDE1OV19fX19fSwgMHg3NDoge2w6IHsweDNCOiB7YzogWzE3Ml19LCAweDY5OiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs4NzEzXX0sIDB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODk0OSwgODI0XX19fX19fX0sIDB4NDU6IHtsOiB7MHgzQjoge2M6IFs4OTUzLCA4MjRdfX19LCAweDc2OiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs4NzEzXX19fSwgMHg2Mjoge2w6IHsweDNCOiB7YzogWzg5NTFdfX19LCAweDYzOiB7bDogezB4M0I6IHtjOiBbODk1MF19fX19fX19fX0sIDB4NkU6IHtsOiB7MHg2OToge2w6IHsweDNCOiB7YzogWzg3MTZdfSwgMHg3Njoge2w6IHsweDYxOiB7bDogezB4M0I6IHtjOiBbODcxNl19fX0sIDB4NjI6IHtsOiB7MHgzQjoge2M6IFs4OTU4XX19fSwgMHg2Mzoge2w6IHsweDNCOiB7YzogWzg5NTddfX19fX19fX19fSwgYzogWzE3Ml19fX0sIDB4NzA6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzg3NDJdfX19fX19fX19fX0sIDB4M0I6IHtjOiBbODc0Ml19LCAweDczOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsxMTAwNSwgODQyMV19fX19fSwgMHg3NDoge2w6IHsweDNCOiB7YzogWzg3MDYsIDgyNF19fX19fX19LCAweDZGOiB7bDogezB4NkM6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxMDc3Ml19fX19fX19fX19fSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzg4MzJdfSwgMHg2Mzoge2w6IHsweDc1OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4OTI4XX19fX19fX0sIDB4NjU6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzg4MzJdfSwgMHg2NToge2w6IHsweDcxOiB7bDogezB4M0I6IHtjOiBbMTA5MjcsIDgyNF19fX19fX19LCAweDNCOiB7YzogWzEwOTI3LCA4MjRdfX19fX19fSwgMHg3Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbMTA1NDcsIDgyNF19fX0sIDB4M0I6IHtjOiBbODYwM119LCAweDc3OiB7bDogezB4M0I6IHtjOiBbODYwNSwgODI0XX19fX19fX19fSwgMHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjU1XX19fX19fX0sIDB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDY4OiB7bDogezB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODYwM119fX19fX19fX19fX19fX19fX19LCAweDc0OiB7bDogezB4NzI6IHtsOiB7MHg2OToge2w6IHsweDNCOiB7YzogWzg5MzldfSwgMHg2NToge2w6IHsweDNCOiB7YzogWzg5NDFdfX19fX19fX19fX0sIDB4NTI6IHtsOiB7MHg2OToge2w6IHsweDY3OiB7bDogezB4Njg6IHtsOiB7MHg3NDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NjU1XX19fX19fX19fX19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbODgzM119LCAweDYzOiB7bDogezB4NzU6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg5MjldfX19fX19fSwgMHg2NToge2w6IHsweDNCOiB7YzogWzEwOTI4LCA4MjRdfX19LCAweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDAzXX19fX19LCAweDY4OiB7bDogezB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDc0OiB7bDogezB4NkQ6IHtsOiB7MHg2OToge2w6IHsweDY0OiB7bDogezB4M0I6IHtjOiBbODc0MF19fX19fX19LCAweDcwOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4NzQyXX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzg3NjldfSwgMHg2NToge2w6IHsweDNCOiB7YzogWzg3NzJdfSwgMHg3MToge2w6IHsweDNCOiB7YzogWzg3NzJdfX19fX19fX19LCAweDZEOiB7bDogezB4Njk6IHtsOiB7MHg2NDoge2w6IHsweDNCOiB7YzogWzg3NDBdfX19fX19fSwgMHg3MDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NzQyXX19fX19fX0sIDB4NzE6IHtsOiB7MHg3Mzoge2w6IHsweDc1OiB7bDogezB4NjI6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg5MzBdfX19fX0sIDB4NzA6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg5MzFdfX19fX19fX19fX0sIDB4NzU6IHtsOiB7MHg2Mjoge2w6IHsweDNCOiB7YzogWzg4MzZdfSwgMHg0NToge2w6IHsweDNCOiB7YzogWzEwOTQ5LCA4MjRdfX19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbODg0MF19fX0sIDB4NzM6IHtsOiB7MHg2NToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODgzNCwgODQwMl19LCAweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFs4ODQwXX0sIDB4NzE6IHtsOiB7MHgzQjoge2M6IFsxMDk0OSwgODI0XX19fX19fX19fX19fX19fSwgMHg2Mzoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbODgzM119LCAweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFsxMDkyOCwgODI0XX19fX19fX19fSwgMHg3MDoge2w6IHsweDNCOiB7YzogWzg4MzddfSwgMHg0NToge2w6IHsweDNCOiB7YzogWzEwOTUwLCA4MjRdfX19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbODg0MV19fX0sIDB4NzM6IHtsOiB7MHg2NToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODgzNSwgODQwMl19LCAweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFs4ODQxXX0sIDB4NzE6IHtsOiB7MHgzQjoge2M6IFsxMDk1MCwgODI0XX19fX19fX19fX19fX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2Nzoge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODgyNV19fX19fSwgMHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzI0MV19fSwgYzogWzI0MV19fX19fX19LCAweDZDOiB7bDogezB4Njc6IHtsOiB7MHgzQjoge2M6IFs4ODI0XX19fX19LCAweDcyOiB7bDogezB4Njk6IHtsOiB7MHg2MToge2w6IHsweDZFOiB7bDogezB4Njc6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDY2OiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4OTM4XX0sIDB4NjU6IHtsOiB7MHg3MToge2w6IHsweDNCOiB7YzogWzg5NDBdfX19fX19fX19fX19fSwgMHg3Mjoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODkzOV19LCAweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFs4OTQxXX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NzU6IHtsOiB7MHgzQjoge2M6IFs5NTddfSwgMHg2RDoge2w6IHsweDNCOiB7YzogWzM1XX0sIDB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4M0I6IHtjOiBbODQ3MF19fX19fX19LCAweDczOiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFs4MTk5XX19fX19fX19fSwgMHg3Njoge2w6IHsweDYxOiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFs4NzgxLCA4NDAyXX19fX19LCAweDY0OiB7bDogezB4NjE6IHtsOiB7MHg3Mzoge2w6IHsweDY4OiB7bDogezB4M0I6IHtjOiBbODg3Nl19fX19fX19fX0sIDB4NDQ6IHtsOiB7MHg2MToge2w6IHsweDczOiB7bDogezB4Njg6IHtsOiB7MHgzQjoge2M6IFs4ODc3XX19fX19fX19fSwgMHg2Nzoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODgwNSwgODQwMl19fX0sIDB4NzQ6IHtsOiB7MHgzQjoge2M6IFs2MiwgODQwMl19fX19fSwgMHg0ODoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTAwXX19fX19fX19fSwgMHg2OToge2w6IHsweDZFOiB7bDogezB4NjY6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbMTA3MThdfX19fX19fX19fX0sIDB4NkM6IHtsOiB7MHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDQ5OF19fX19fX19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbODgwNCwgODQwMl19fX0sIDB4NzQ6IHtsOiB7MHgzQjoge2M6IFs2MCwgODQwMl19LCAweDcyOiB7bDogezB4Njk6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg4ODQsIDg0MDJdfX19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDQ5OV19fX19fX19LCAweDc0OiB7bDogezB4NzI6IHtsOiB7MHg2OToge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODg4NSwgODQwMl19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHgzQjoge2M6IFs4NzY0LCA4NDAyXX19fX19fX19fSwgMHg1Njoge2w6IHsweDY0OiB7bDogezB4NjE6IHtsOiB7MHg3Mzoge2w6IHsweDY4OiB7bDogezB4M0I6IHtjOiBbODg3OF19fX19fX19fX0sIDB4NDQ6IHtsOiB7MHg2MToge2w6IHsweDczOiB7bDogezB4Njg6IHtsOiB7MHgzQjoge2M6IFs4ODc5XX19fX19fX19fX19LCAweDc3OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDY4OiB7bDogezB4NkI6IHtsOiB7MHgzQjoge2M6IFsxMDUzMV19fX19fSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzg1OThdfSwgMHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODU5OF19fX19fX19fX19fSwgMHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjYyXX19fX19fX0sIDB4NkU6IHtsOiB7MHg2NToge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDUzNV19fX19fX19fX19fX19LFxyXG4gICAgMHg0RToge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg3NToge2w6IHsweDc0OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFszMjNdfX19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzMyN119fX19fX19fX0sIDB4NjU6IHtsOiB7MHg2NDoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFszMjVdfX19fX19fX19LCAweDc5OiB7bDogezB4M0I6IHtjOiBbMTA1M119fX19fSwgMHg2NToge2w6IHsweDY3OiB7bDogezB4NjE6IHtsOiB7MHg3NDoge2w6IHsweDY5OiB7bDogezB4NzY6IHtsOiB7MHg2NToge2w6IHsweDREOiB7bDogezB4NjU6IHtsOiB7MHg2NDoge2w6IHsweDY5OiB7bDogezB4NzU6IHtsOiB7MHg2RDoge2w6IHsweDUzOiB7bDogezB4NzA6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4MjAzXX19fX19fX19fX19fX19fX19fX19fX19LCAweDU0OiB7bDogezB4Njg6IHtsOiB7MHg2OToge2w6IHsweDYzOiB7bDogezB4NkI6IHtsOiB7MHg1Mzoge2w6IHsweDcwOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODIwM119fX19fX19fX19fX19fX0sIDB4NkU6IHtsOiB7MHg1Mzoge2w6IHsweDcwOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODIwM119fX19fX19fX19fX19fX19fX19LCAweDU2OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDc5OiB7bDogezB4NTQ6IHtsOiB7MHg2ODoge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHg1Mzoge2w6IHsweDcwOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODIwM119fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4NjQ6IHtsOiB7MHg0Nzoge2w6IHsweDcyOiB7bDogezB4NjU6IHtsOiB7MHg2MToge2w6IHsweDc0OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDQ3OiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDYxOiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODgxMV19fX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg0Qzoge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHg3Mzoge2w6IHsweDRDOiB7bDogezB4NjU6IHtsOiB7MHg3Mzoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODgxMF19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDc3OiB7bDogezB4NEM6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsxMF19fX19fX19fX19fX19LCAweDY2OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAwODFdfX19fX0sIDB4NEE6IHtsOiB7MHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTAzNF19fX19fX19LCAweDZGOiB7bDogezB4NDI6IHtsOiB7MHg3Mjoge2w6IHsweDY1OiB7bDogezB4NjE6IHtsOiB7MHg2Qjoge2w6IHsweDNCOiB7YzogWzgyODhdfX19fX19fX19fX0sIDB4NkU6IHtsOiB7MHg0Mjoge2w6IHsweDcyOiB7bDogezB4NjU6IHtsOiB7MHg2MToge2w6IHsweDZCOiB7bDogezB4Njk6IHtsOiB7MHg2RToge2w6IHsweDY3OiB7bDogezB4NTM6IHtsOiB7MHg3MDoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzE2MF19fX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbODQ2OV19fX19fSwgMHg3NDoge2w6IHsweDNCOiB7YzogWzEwOTg4XX0sIDB4NDM6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4Njc6IHtsOiB7MHg3Mjoge2w6IHsweDc1OiB7bDogezB4NjU6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODgwMl19fX19fX19fX19fX19fX19fSwgMHg3NToge2w6IHsweDcwOiB7bDogezB4NDM6IHtsOiB7MHg2MToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbODgxM119fX19fX19fX19fX19LCAweDQ0OiB7bDogezB4NkY6IHtsOiB7MHg3NToge2w6IHsweDYyOiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDU2OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDc0OiB7bDogezB4Njk6IHtsOiB7MHg2Mzoge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHg0Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NzQyXX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDQ1OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDZEOiB7bDogezB4NjU6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODcxM119fX19fX19fX19fX19LCAweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODgwMF19LCAweDU0OiB7bDogezB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDY0OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4NzcwLCA4MjRdfX19fX19fX19fX19fX19fX19fSwgMHg3ODoge2w6IHsweDY5OiB7bDogezB4NzM6IHtsOiB7MHg3NDoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODcwOF19fX19fX19fX19fX19LCAweDQ3OiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDYxOiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODgxNV19LCAweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4ODE3XX19fX19fX19fX19LCAweDQ2OiB7bDogezB4NzU6IHtsOiB7MHg2Qzoge2w6IHsweDZDOiB7bDogezB4NDU6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzg4MDcsIDgyNF19fX19fX19fX19fX19fX19fX19LCAweDQ3OiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDYxOiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODgxMSwgODI0XX19fX19fX19fX19fX19fSwgMHg0Qzoge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzg4MjVdfX19fX19fX19LCAweDUzOiB7bDogezB4NkM6IHtsOiB7MHg2MToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHg0NToge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMTA4NzgsIDgyNF19fX19fX19fX19fX19fX19fX19fX0sIDB4NTQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg4MjFdfX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg0ODoge2w6IHsweDc1OiB7bDogezB4NkQ6IHtsOiB7MHg3MDoge2w6IHsweDQ0OiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDZFOiB7bDogezB4NDg6IHtsOiB7MHg3NToge2w6IHsweDZEOiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFs4NzgyLCA4MjRdfX19fX19fX19fX19fX19fX0sIDB4NDU6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzg3ODMsIDgyNF19fX19fX19fX19fX19fX19fX19LCAweDRDOiB7bDogezB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4NTQ6IHtsOiB7MHg3Mjoge2w6IHsweDY5OiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDY3OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDQyOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNzAzLCA4MjRdfX19fX19fSwgMHgzQjoge2M6IFs4OTM4XX0sIDB4NDU6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzg5NDBdfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODgxNF19LCAweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4ODE2XX19fX19fX19fX19LCAweDQ3OiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDYxOiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODgyNF19fX19fX19fX19fX19fX0sIDB4NEM6IHtsOiB7MHg2NToge2w6IHsweDczOiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4ODEwLCA4MjRdfX19fX19fX19LCAweDUzOiB7bDogezB4NkM6IHtsOiB7MHg2MToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHg0NToge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMTA4NzcsIDgyNF19fX19fX19fX19fX19fX19fX19fX0sIDB4NTQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg4MjBdfX19fX19fX19fX19fX19fX19fSwgMHg0RToge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4NjQ6IHtsOiB7MHg0Nzoge2w6IHsweDcyOiB7bDogezB4NjU6IHtsOiB7MHg2MToge2w6IHsweDc0OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDQ3OiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDYxOiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA5MTQsIDgyNF19fX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg0Qzoge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHg3Mzoge2w6IHsweDRDOiB7bDogezB4NjU6IHtsOiB7MHg3Mzoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbMTA5MTMsIDgyNF19fX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg1MDoge2w6IHsweDcyOiB7bDogezB4NjU6IHtsOiB7MHg2Mzoge2w6IHsweDY1OiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODgzMl19LCAweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsxMDkyNywgODI0XX19fX19fX19fX19LCAweDUzOiB7bDogezB4NkM6IHtsOiB7MHg2MToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHg0NToge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODkyOF19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDUyOiB7bDogezB4NjU6IHtsOiB7MHg3Njoge2w6IHsweDY1OiB7bDogezB4NzI6IHtsOiB7MHg3Mzoge2w6IHsweDY1OiB7bDogezB4NDU6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4NkQ6IHtsOiB7MHg2NToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4NzE2XX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg2OToge2w6IHsweDY3OiB7bDogezB4Njg6IHtsOiB7MHg3NDoge2w6IHsweDU0OiB7bDogezB4NzI6IHtsOiB7MHg2OToge2w6IHsweDYxOiB7bDogezB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDZDOiB7bDogezB4NjU6IHtsOiB7MHg0Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDcwNCwgODI0XX19fX19fX0sIDB4M0I6IHtjOiBbODkzOV19LCAweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4OTQxXX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NTM6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDY1OiB7bDogezB4NTM6IHtsOiB7MHg3NToge2w6IHsweDYyOiB7bDogezB4NzM6IHtsOiB7MHg2NToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODg0NywgODI0XX0sIDB4NDU6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzg5MzBdfX19fX19fX19fX19fX19fX19fSwgMHg3MDoge2w6IHsweDY1OiB7bDogezB4NzI6IHtsOiB7MHg3Mzoge2w6IHsweDY1OiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4ODQ4LCA4MjRdfSwgMHg0NToge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODkzMV19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDc1OiB7bDogezB4NjI6IHtsOiB7MHg3Mzoge2w6IHsweDY1OiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4ODM0LCA4NDAyXX0sIDB4NDU6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzg4NDBdfX19fX19fX19fX19fX19fX19fSwgMHg2Mzoge2w6IHsweDYzOiB7bDogezB4NjU6IHtsOiB7MHg2NToge2w6IHsweDY0OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4ODMzXX0sIDB4NDU6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzEwOTI4LCA4MjRdfX19fX19fX19fX0sIDB4NTM6IHtsOiB7MHg2Qzoge2w6IHsweDYxOiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4OTI5XX19fX19fX19fX19fX19fX19fX19fSwgMHg1NDoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHg2NDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODgzMSwgODI0XX19fX19fX19fX19fX19fX19fX19fX19LCAweDcwOiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDczOiB7bDogezB4NjU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg4MzUsIDg0MDJdfSwgMHg0NToge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODg0MV19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NTQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg3NjldfSwgMHg0NToge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODc3Ml19fX19fX19fX19fSwgMHg0Njoge2w6IHsweDc1OiB7bDogezB4NkM6IHtsOiB7MHg2Qzoge2w6IHsweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4Nzc1XX19fX19fX19fX19fX19fX19fX0sIDB4NTQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg3NzddfX19fX19fX19fX19fX19fX19fX19LCAweDU2OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDc0OiB7bDogezB4Njk6IHtsOiB7MHg2Mzoge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHg0Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NzQwXX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMTk5NzddfX19fX19fSwgMHg3NDoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHg2NDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbMjA5XX19LCBjOiBbMjA5XX19fX19fX19fSwgMHg3NToge2w6IHsweDNCOiB7YzogWzkyNV19fX19fSxcclxuICAgIDB4NEY6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NzU6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbMjExXX19LCBjOiBbMjExXX19fX19fX19fSwgMHg2Mzoge2w6IHsweDY5OiB7bDogezB4NzI6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzIxMl19fSwgYzogWzIxMl19fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzEwNTRdfX19fX0sIDB4NjQ6IHtsOiB7MHg2Mjoge2w6IHsweDZDOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzMzNl19fX19fX19fX19fSwgMHg0NToge2w6IHsweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzMzOF19fX19fX19fX0sIDB4NjY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDA4Ml19fX19fSwgMHg2Nzoge2w6IHsweDcyOiB7bDogezB4NjE6IHtsOiB7MHg3Njoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbMjEwXX19LCBjOiBbMjEwXX19fX19fX19fSwgMHg2RDoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzMzMl19fX19fX19LCAweDY1OiB7bDogezB4Njc6IHtsOiB7MHg2MToge2w6IHsweDNCOiB7YzogWzkzN119fX19fX19LCAweDY5OiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs5MjddfX19fX19fX19fX19fSwgMHg2Rjoge2w6IHsweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxMzRdfX19fX19fSwgMHg3MDoge2w6IHsweDY1OiB7bDogezB4NkU6IHtsOiB7MHg0Mzoge2w6IHsweDc1OiB7bDogezB4NzI6IHtsOiB7MHg2Qzoge2w6IHsweDc5OiB7bDogezB4NDQ6IHtsOiB7MHg2Rjoge2w6IHsweDc1OiB7bDogezB4NjI6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4NTE6IHtsOiB7MHg3NToge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzgyMjBdfX19fX19fX19fX19fX19fX19fX19fX0sIDB4NTE6IHtsOiB7MHg3NToge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzgyMTZdfX19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDcyOiB7bDogezB4M0I6IHtjOiBbMTA4MzZdfX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzExOTk3OF19fX19fSwgMHg2Qzoge2w6IHsweDYxOiB7bDogezB4NzM6IHtsOiB7MHg2ODoge2w6IHsweDNCOiB7YzogWzIxNl19fSwgYzogWzIxNl19fX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzIxM119fSwgYzogWzIxM119fX19fSwgMHg2RDoge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFsxMDgwN119fX19fX19fX19fSwgMHg3NToge2w6IHsweDZEOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsyMTRdfX0sIGM6IFsyMTRdfX19fX0sIDB4NzY6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4NDI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODI1NF19fX19fSwgMHg3Mjoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzkxODJdfX19LCAweDZCOiB7bDogezB4NjU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzkxNDBdfX19fX19fX19fX19fX19LCAweDUwOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDY1OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDY4OiB7bDogezB4NjU6IHtsOiB7MHg3Mzoge2w6IHsweDY5OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs5MTgwXX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX0sXHJcbiAgICAweDZGOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzI0M119fSwgYzogWzI0M119fX19fX19LCAweDczOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4ODU5XX19fX19fX0sIDB4NjM6IHtsOiB7MHg2OToge2w6IHsweDcyOiB7bDogezB4NjM6IHtsOiB7MHgzQjoge2M6IFsyNDRdfX0sIGM6IFsyNDRdfSwgMHgzQjoge2M6IFs4ODU4XX19fX19LCAweDc5OiB7bDogezB4M0I6IHtjOiBbMTA4Nl19fX19fSwgMHg2NDoge2w6IHsweDYxOiB7bDogezB4NzM6IHtsOiB7MHg2ODoge2w6IHsweDNCOiB7YzogWzg4NjFdfX19fX19fSwgMHg2Mjoge2w6IHsweDZDOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzMzN119fX19fX19fX0sIDB4Njk6IHtsOiB7MHg3Njoge2w6IHsweDNCOiB7YzogWzEwODA4XX19fX19LCAweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4ODU3XX19fX19LCAweDczOiB7bDogezB4NkY6IHtsOiB7MHg2Qzoge2w6IHsweDY0OiB7bDogezB4M0I6IHtjOiBbMTA2ODRdfX19fX19fX19fX0sIDB4NjU6IHtsOiB7MHg2Qzoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHgzQjoge2M6IFszMzldfX19fX19fX19LCAweDY2OiB7bDogezB4NjM6IHtsOiB7MHg2OToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA2ODddfX19fX19fSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDEwOF19fX19fSwgMHg2Nzoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs3MzFdfX19fX0sIDB4NzI6IHtsOiB7MHg2MToge2w6IHsweDc2OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsyNDJdfX0sIGM6IFsyNDJdfX19fX19fSwgMHg3NDoge2w6IHsweDNCOiB7YzogWzEwNjg5XX19fX19LCAweDY4OiB7bDogezB4NjI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA2NzddfX19fX19fSwgMHg2RDoge2w6IHsweDNCOiB7YzogWzkzN119fX19fSwgMHg2OToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4NzUwXX19fX19fX0sIDB4NkM6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjM0XX19fX19fX0sIDB4NjM6IHtsOiB7MHg2OToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA2ODZdfX19fX0sIDB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDczOiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFsxMDY4M119fX19fX19fX19fSwgMHg2OToge2w6IHsweDZFOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4MjU0XX19fX19fX0sIDB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxMDY4OF19fX19fSwgMHg2RDoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzMzM119fX19fX19LCAweDY1OiB7bDogezB4Njc6IHtsOiB7MHg2MToge2w6IHsweDNCOiB7YzogWzk2OV19fX19fX19LCAweDY5OiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs5NTldfX19fX19fX19LCAweDY0OiB7bDogezB4M0I6IHtjOiBbMTA2NzhdfX19LCAweDZFOiB7bDogezB4NzU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzg4NTRdfX19fX19fX19fX0sIDB4NkY6IHtsOiB7MHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbMTIwMTYwXX19fX19fX0sIDB4NzA6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA2NzldfX19fX0sIDB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbMTA2ODFdfX19fX19fSwgMHg2Qzoge2w6IHsweDc1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4ODUzXX19fX19fX19fSwgMHg3Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg2MzVdfX19fX19fSwgMHgzQjoge2M6IFs4NzQ0XX0sIDB4NjQ6IHtsOiB7MHgzQjoge2M6IFsxMDg0NV19LCAweDY1OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NTAwXX0sIDB4NkY6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzg1MDBdfX19fX19fX19LCAweDY2OiB7bDogezB4M0I6IHtjOiBbMTcwXX19LCBjOiBbMTcwXX0sIDB4NkQ6IHtsOiB7MHgzQjoge2M6IFsxODZdfX0sIGM6IFsxODZdfX19LCAweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2Rjoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbODg4Nl19fX19fX19fX0sIDB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwODM4XX19fX19LCAweDczOiB7bDogezB4NkM6IHtsOiB7MHg2Rjoge2w6IHsweDcwOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsxMDgzOV19fX19fX19fX19fSwgMHg3Njoge2w6IHsweDNCOiB7YzogWzEwODQzXX19fX19LCAweDUzOiB7bDogezB4M0I6IHtjOiBbOTQxNl19fX0sIDB4NzM6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODUwMF19fX19fSwgMHg2Qzoge2w6IHsweDYxOiB7bDogezB4NzM6IHtsOiB7MHg2ODoge2w6IHsweDNCOiB7YzogWzI0OF19fSwgYzogWzI0OF19fX19fX19LCAweDZGOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4ODU2XX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzI0NV19fSwgYzogWzI0NV19fX19fSwgMHg2RDoge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHg2MToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbMTA4MDZdfX19fX0sIDB4M0I6IHtjOiBbODg1NV19fX19fX19fX19fSwgMHg3NToge2w6IHsweDZEOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsyNDZdfX0sIGM6IFsyNDZdfX19fX0sIDB4NzY6IHtsOiB7MHg2Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs5MDIxXX19fX19fX19fX19LFxyXG4gICAgMHg3MDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2MToge2w6IHsweDNCOiB7YzogWzE4Ml19LCAweDZDOiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODc0MV19fX19fX19fX19LCBjOiBbMTgyXX0sIDB4M0I6IHtjOiBbODc0MV19LCAweDczOiB7bDogezB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzEwOTk1XX19fX19LCAweDZDOiB7bDogezB4M0I6IHtjOiBbMTEwMDVdfX19fX0sIDB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4NzA2XX19fX19fX0sIDB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzEwODddfX19fX0sIDB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzM3XX19fX19fX0sIDB4Njk6IHtsOiB7MHg2Rjoge2w6IHsweDY0OiB7bDogezB4M0I6IHtjOiBbNDZdfX19fX19fSwgMHg2RDoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4MjQwXX19fX19fX0sIDB4NzA6IHtsOiB7MHgzQjoge2M6IFs4ODY5XX19fSwgMHg3NDoge2w6IHsweDY1OiB7bDogezB4NkU6IHtsOiB7MHg2Qjoge2w6IHsweDNCOiB7YzogWzgyNDFdfX19fX19fX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMTA5XX19fX19LCAweDY4OiB7bDogezB4Njk6IHtsOiB7MHgzQjoge2M6IFs5NjZdfSwgMHg3Njoge2w6IHsweDNCOiB7YzogWzk4MV19fX19fSwgMHg2RDoge2w6IHsweDZEOiB7bDogezB4NjE6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg0OTldfX19fX19fX19LCAweDZGOiB7bDogezB4NkU6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzk3NDJdfX19fX19fX19LCAweDY5OiB7bDogezB4M0I6IHtjOiBbOTYwXX0sIDB4NzQ6IHtsOiB7MHg2Mzoge2w6IHsweDY4OiB7bDogezB4NjY6IHtsOiB7MHg2Rjoge2w6IHsweDcyOiB7bDogezB4NkI6IHtsOiB7MHgzQjoge2M6IFs4OTE2XX19fX19fX19fX19fX19fSwgMHg3Njoge2w6IHsweDNCOiB7YzogWzk4Ml19fX19fSwgMHg2Qzoge2w6IHsweDYxOiB7bDogezB4NkU6IHtsOiB7MHg2Mzoge2w6IHsweDZCOiB7bDogezB4M0I6IHtjOiBbODQ2M119LCAweDY4OiB7bDogezB4M0I6IHtjOiBbODQ2Ml19fX19fX19LCAweDZCOiB7bDogezB4NzY6IHtsOiB7MHgzQjoge2M6IFs4NDYzXX19fX19fX19fSwgMHg3NToge2w6IHsweDczOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDY5OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDc4N119fX19fX19fX0sIDB4NjI6IHtsOiB7MHgzQjoge2M6IFs4ODYyXX19fSwgMHg2Mzoge2w6IHsweDY5OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDc4Nl19fX19fX19LCAweDNCOiB7YzogWzQzXX0sIDB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDNCOiB7YzogWzg3MjRdfX19LCAweDc1OiB7bDogezB4M0I6IHtjOiBbMTA3ODldfX19fX0sIDB4NjU6IHtsOiB7MHgzQjoge2M6IFsxMDg2Nl19fX0sIDB4NkQ6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzE3N119fSwgYzogWzE3N119fX0sIDB4NzM6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4M0I6IHtjOiBbMTA3OTBdfX19fX19fSwgMHg3NDoge2w6IHsweDc3OiB7bDogezB4NkY6IHtsOiB7MHgzQjoge2M6IFsxMDc5MV19fX19fX19fX19fX19LCAweDZEOiB7bDogezB4M0I6IHtjOiBbMTc3XX19fSwgMHg2Rjoge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwNzczXX19fX19fX19fX19fX0sIDB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDE2MV19fX19fSwgMHg3NToge2w6IHsweDZFOiB7bDogezB4NjQ6IHtsOiB7MHgzQjoge2M6IFsxNjNdfX0sIGM6IFsxNjNdfX19fX19fSwgMHg3Mjoge2w6IHsweDYxOiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFsxMDkzNV19fX19fSwgMHgzQjoge2M6IFs4ODI2XX0sIDB4NjM6IHtsOiB7MHg3NToge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODgyOF19fX19fX19LCAweDY1OiB7bDogezB4NjM6IHtsOiB7MHg2MToge2w6IHsweDcwOiB7bDogezB4NzA6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzg6IHtsOiB7MHgzQjoge2M6IFsxMDkzNV19fX19fX19fX19fX19LCAweDNCOiB7YzogWzg4MjZdfSwgMHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzI6IHtsOiB7MHg2Qzoge2w6IHsweDc5OiB7bDogezB4NjU6IHtsOiB7MHg3MToge2w6IHsweDNCOiB7YzogWzg4MjhdfX19fX19fX19fX19fX19LCAweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFsxMDkyN119fX19fSwgMHg2RToge2w6IHsweDYxOiB7bDogezB4NzA6IHtsOiB7MHg3MDoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3ODoge2w6IHsweDNCOiB7YzogWzEwOTM3XX19fX19fX19fX19fX0sIDB4NjU6IHtsOiB7MHg3MToge2w6IHsweDcxOiB7bDogezB4M0I6IHtjOiBbMTA5MzNdfX19fX19fSwgMHg3Mzoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHgzQjoge2M6IFs4OTM2XX19fX19fX19fSwgMHg3Mzoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHgzQjoge2M6IFs4ODMwXX19fX19fX19fSwgMHgzQjoge2M6IFsxMDkyN119fX0sIDB4NDU6IHtsOiB7MHgzQjoge2M6IFsxMDkzMV19fX0sIDB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODI0Ml19LCAweDczOiB7bDogezB4M0I6IHtjOiBbODQ3M119fX19fX19fX0sIDB4NkU6IHtsOiB7MHg2MToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbMTA5MzddfX19fX0sIDB4NDU6IHtsOiB7MHgzQjoge2M6IFsxMDkzM119fX0sIDB4NzM6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4M0I6IHtjOiBbODkzNl19fX19fX19fX0sIDB4NkY6IHtsOiB7MHg2NDoge2w6IHsweDNCOiB7YzogWzg3MTldfX19LCAweDY2OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs5MDA2XX19fX19fX19fSwgMHg2Qzoge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg5NzhdfX19fX19fX19LCAweDczOiB7bDogezB4NzU6IHtsOiB7MHg3Mjoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbODk3OV19fX19fX19fX19fSwgMHg3MDoge2w6IHsweDNCOiB7YzogWzg3MzNdfSwgMHg3NDoge2w6IHsweDZGOiB7bDogezB4M0I6IHtjOiBbODczM119fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4M0I6IHtjOiBbODgzMF19fX19fX19LCAweDc1OiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODg4MF19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAwMDVdfX19fX0sIDB4Njk6IHtsOiB7MHgzQjoge2M6IFs5NjhdfX19fX0sIDB4NzU6IHtsOiB7MHg2RToge2w6IHsweDYzOiB7bDogezB4NzM6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzgyMDBdfX19fX19fX19fX19fSxcclxuICAgIDB4NTA6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzQ6IHtsOiB7MHg2OToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHg0NDoge2w6IHsweDNCOiB7YzogWzg3MDZdfX19fX19fX19fX19fX19LCAweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDU1XX19fX19LCAweDY2OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAwODNdfX19fX0sIDB4Njg6IHtsOiB7MHg2OToge2w6IHsweDNCOiB7YzogWzkzNF19fX19fSwgMHg2OToge2w6IHsweDNCOiB7YzogWzkyOF19fX0sIDB4NkM6IHtsOiB7MHg3NToge2w6IHsweDczOiB7bDogezB4NEQ6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4NzU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzE3N119fX19fX19fX19fX19fX19fSwgMHg2Rjoge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHg2Mzoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDcwOiB7bDogezB4NkM6IHtsOiB7MHg2MToge2w6IHsweDZFOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4NDYwXX19fX19fX19fX19fX19fX19fX19fX19LCAweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFs4NDczXX19fX19fX0sIDB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDkzOV19LCAweDY1OiB7bDogezB4NjM6IHtsOiB7MHg2NToge2w6IHsweDY0OiB7bDogezB4NjU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzg4MjZdfSwgMHg0NToge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMTA5MjddfX19fX19fX19fX0sIDB4NTM6IHtsOiB7MHg2Qzoge2w6IHsweDYxOiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4ODI4XX19fX19fX19fX19fX19fX19fX19fSwgMHg1NDoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHg2NDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODgzMF19fX19fX19fX19fX19fX19fX19fX19fSwgMHg2OToge2w6IHsweDZEOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4MjQzXX19fX19fX0sIDB4NkY6IHtsOiB7MHg2NDoge2w6IHsweDc1OiB7bDogezB4NjM6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg3MTldfX19fX19fX19LCAweDcwOiB7bDogezB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDc0OiB7bDogezB4Njk6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzg3MzNdfX19fX0sIDB4M0I6IHtjOiBbODc1OV19fX19fX19fX19fX19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzExOTk3OV19fX19fSwgMHg2OToge2w6IHsweDNCOiB7YzogWzkzNl19fX19fX19LFxyXG4gICAgMHg1MToge2w6IHsweDY2OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAwODRdfX19fX0sIDB4NkY6IHtsOiB7MHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbODQ3NF19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzExOTk4MF19fX19fX19LCAweDU1OiB7bDogezB4NEY6IHtsOiB7MHg1NDoge2w6IHsweDNCOiB7YzogWzM0XX19LCBjOiBbMzRdfX19fX19fSxcclxuICAgIDB4NzE6IHtsOiB7MHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMTEwXX19fX19LCAweDY5OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwNzY0XX19fX19fX0sIDB4NkY6IHtsOiB7MHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbMTIwMTYyXX19fX19fX0sIDB4NzA6IHtsOiB7MHg3Mjoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzgyNzldfX19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDA2XX19fX19fX0sIDB4NzU6IHtsOiB7MHg2MToge2w6IHsweDc0OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDZFOiB7bDogezB4Njk6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4NDYxXX19fX19fX19fX19fX19fSwgMHg2OToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxMDc3NF19fX19fX19fX19fSwgMHg2NToge2w6IHsweDczOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs2M119LCAweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFs4Nzk5XX19fX19fX19fX19LCAweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFszNF19fSwgYzogWzM0XX19fX19fX0sXHJcbiAgICAweDcyOiB7bDogezB4NDE6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjY3XX19fX19fX0sIDB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg2NThdfX19fX0sIDB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsxMDUyNF19fX19fX19fX19fSwgMHg2MToge2w6IHsweDYzOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4NzY1LCA4MTddfX19LCAweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzM0MV19fX19fX19fX0sIDB4NjQ6IHtsOiB7MHg2OToge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbODczMF19fX19fX19LCAweDY1OiB7bDogezB4NkQ6IHtsOiB7MHg3MDoge2w6IHsweDc0OiB7bDogezB4Nzk6IHtsOiB7MHg3Njoge2w6IHsweDNCOiB7YzogWzEwNjc1XX19fX19fX19fX19fX0sIDB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzEwMjE3XX0sIDB4NjQ6IHtsOiB7MHgzQjoge2M6IFsxMDY0Ml19fX0sIDB4NjU6IHtsOiB7MHgzQjoge2M6IFsxMDY2MV19fX0sIDB4NkM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzEwMjE3XX19fX19fX19fSwgMHg3MToge2w6IHsweDc1OiB7bDogezB4NkY6IHtsOiB7MHgzQjoge2M6IFsxODddfX0sIGM6IFsxODddfX19fX0sIDB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDYxOiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFsxMDYxM119fX19fSwgMHg2Mjoge2w6IHsweDNCOiB7YzogWzg2NzddfSwgMHg2Njoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbMTA1MjhdfX19fX19fSwgMHg2Mzoge2w6IHsweDNCOiB7YzogWzEwNTQ3XX19fSwgMHgzQjoge2M6IFs4NTk0XX0sIDB4NjY6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzEwNTI2XX19fX19LCAweDY4OiB7bDogezB4NkI6IHtsOiB7MHgzQjoge2M6IFs4NjE4XX19fX19LCAweDZDOiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFs4NjIwXX19fX19LCAweDcwOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsxMDU2NV19fX19fSwgMHg3Mzoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHgzQjoge2M6IFsxMDYxMl19fX19fX19LCAweDc0OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4NjExXX19fX19LCAweDc3OiB7bDogezB4M0I6IHtjOiBbODYwNV19fX19fX19LCAweDc0OiB7bDogezB4NjE6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMTA1MjJdfX19fX19fSwgMHg2OToge2w6IHsweDZGOiB7bDogezB4M0I6IHtjOiBbODc1OF19LCAweDZFOiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODQ3NF19fX19fX19fX19fX19fX19fSwgMHg2Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTA5XX19fX19fX0sIDB4NjI6IHtsOiB7MHg3Mjoge2w6IHsweDZCOiB7bDogezB4M0I6IHtjOiBbMTAwOTldfX19fX19fSwgMHg3Mjoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzEyNV19fX0sIDB4NkI6IHtsOiB7MHgzQjoge2M6IFs5M119fX19fX19LCAweDZCOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsxMDYzNl19fX0sIDB4NzM6IHtsOiB7MHg2Qzoge2w6IHsweDY0OiB7bDogezB4M0I6IHtjOiBbMTA2MzhdfX19LCAweDc1OiB7bDogezB4M0I6IHtjOiBbMTA2NDBdfX19fX19fX19fX19fSwgMHg0Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTExXX19fX19fX19fSwgMHg2Mzoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbMzQ1XX19fX19fX19fSwgMHg2NToge2w6IHsweDY0OiB7bDogezB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzM0M119fX19fX19LCAweDY5OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4OTY5XX19fX19fX0sIDB4NzU6IHtsOiB7MHg2Mjoge2w6IHsweDNCOiB7YzogWzEyNV19fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzEwODhdfX19fX0sIDB4NjQ6IHtsOiB7MHg2Mzoge2w6IHsweDYxOiB7bDogezB4M0I6IHtjOiBbMTA1NTFdfX19fX0sIDB4NkM6IHtsOiB7MHg2NDoge2w6IHsweDY4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNjAxXX19fX19fX19fX19LCAweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2Rjoge2w6IHsweDNCOiB7YzogWzgyMjFdfSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzgyMjFdfX19fX19fX19LCAweDczOiB7bDogezB4Njg6IHtsOiB7MHgzQjoge2M6IFs4NjI3XX19fX19fX0sIDB4NjU6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODQ3Nl19LCAweDY5OiB7bDogezB4NkU6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg0NzVdfX19fX19fSwgMHg3MDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg0NzZdfX19fX19fX19LCAweDczOiB7bDogezB4M0I6IHtjOiBbODQ3N119fX19fX19LCAweDYzOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs5NjQ1XX19fX19LCAweDY3OiB7bDogezB4M0I6IHtjOiBbMTc0XX19LCBjOiBbMTc0XX19fSwgMHg2Njoge2w6IHsweDY5OiB7bDogezB4NzM6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA2MjFdfX19fX19fX19LCAweDZDOiB7bDogezB4NkY6IHtsOiB7MHg2Rjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODk3MV19fX19fX19fX0sIDB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAxMTFdfX19fX0sIDB4NDg6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA1OTZdfX19fX19fSwgMHg2ODoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2NDoge2w6IHsweDNCOiB7YzogWzg2NDFdfX19LCAweDc1OiB7bDogezB4M0I6IHtjOiBbODY0MF19LCAweDZDOiB7bDogezB4M0I6IHtjOiBbMTA2MDRdfX19fX19fX19LCAweDZGOiB7bDogezB4M0I6IHtjOiBbOTYxXX0sIDB4NzY6IHtsOiB7MHgzQjoge2M6IFsxMDA5XX19fX19fX0sIDB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDY4OiB7bDogezB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODU5NF19LCAweDc0OiB7bDogezB4NjE6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODYxMV19fX19fX19fX19fX19fX19fX19LCAweDY4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcwOiB7bDogezB4NkY6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs4NjQxXX19fX19fX19fSwgMHg3NToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbODY0MF19fX19fX19fX19fX19fX19fX19LCAweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODY0NF19fX19fX19fX19fX19LCAweDY4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcwOiB7bDogezB4NkY6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4NjUyXX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2OToge2w6IHsweDY3OiB7bDogezB4Njg6IHtsOiB7MHg3NDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzg2NDldfX19fX19fX19fX19fX19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NjA1XX19fX19fX19fX19fX19fX19fX19fSwgMHg3NDoge2w6IHsweDY4OiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDY1OiB7bDogezB4NzQ6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4NjU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzg5MDhdfX19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDZFOiB7bDogezB4Njc6IHtsOiB7MHgzQjoge2M6IFs3MzBdfX19fX0sIDB4NzM6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4Njc6IHtsOiB7MHg2NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHg3Mzoge2w6IHsweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFs4Nzg3XX19fX19fX19fX19fX19fX19fX19fX19LCAweDZDOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODY0NF19fX19fX19LCAweDY4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg2NTJdfX19fX19fSwgMHg2RDoge2w6IHsweDNCOiB7YzogWzgyMDddfX19fX0sIDB4NkQ6IHtsOiB7MHg2Rjoge2w6IHsweDc1OiB7bDogezB4NzM6IHtsOiB7MHg3NDoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg2ODoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbOTEzN119fX19fX19fX0sIDB4M0I6IHtjOiBbOTEzN119fX19fX19fX19fSwgMHg2RToge2w6IHsweDZEOiB7bDogezB4Njk6IHtsOiB7MHg2NDoge2w6IHsweDNCOiB7YzogWzEwOTkwXX19fX19fX19fSwgMHg2Rjoge2w6IHsweDYxOiB7bDogezB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzEwMjIxXX19fX19LCAweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NzAyXX19fX19fX0sIDB4NjI6IHtsOiB7MHg3Mjoge2w6IHsweDZCOiB7bDogezB4M0I6IHtjOiBbMTAyMTVdfX19fX19fSwgMHg3MDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDYzMF19fX19fSwgMHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDE2M119fX0sIDB4NkM6IHtsOiB7MHg3NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbMTA3OThdfX19fX19fX19LCAweDc0OiB7bDogezB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFsxMDgwNV19fX19fX19fX19fX19LCAweDcwOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzQxXX0sIDB4Njc6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwNjQ0XX19fX19fX19fSwgMHg3MDoge2w6IHsweDZGOiB7bDogezB4NkM6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxMDc3MF19fX19fX19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjQ5XX19fX19fX19fSwgMHg3Mzoge2w6IHsweDYxOiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDZGOiB7bDogezB4M0I6IHtjOiBbODI1MF19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDAwN119fX19fSwgMHg2ODoge2w6IHsweDNCOiB7YzogWzg2MjVdfX19LCAweDcxOiB7bDogezB4NjI6IHtsOiB7MHgzQjoge2M6IFs5M119fX0sIDB4NzU6IHtsOiB7MHg2Rjoge2w6IHsweDNCOiB7YzogWzgyMTddfSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzgyMTddfX19fX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2ODoge2w6IHsweDcyOiB7bDogezB4NjU6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg5MDhdfX19fX19fX19LCAweDY5OiB7bDogezB4NkQ6IHtsOiB7MHg2NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODkwNl19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2OToge2w6IHsweDNCOiB7YzogWzk2NTddfSwgMHg2NToge2w6IHsweDNCOiB7YzogWzg4ODVdfX19LCAweDY2OiB7bDogezB4M0I6IHtjOiBbOTY1Nl19fX0sIDB4NkM6IHtsOiB7MHg3NDoge2w6IHsweDcyOiB7bDogezB4Njk6IHtsOiB7MHgzQjoge2M6IFsxMDcwMl19fX19fX19fX19fX19fX0sIDB4NzU6IHtsOiB7MHg2Qzoge2w6IHsweDc1OiB7bDogezB4Njg6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA2MDBdfX19fX19fX19fX19fSwgMHg3ODoge2w6IHsweDNCOiB7YzogWzg0NzhdfX19fX0sXHJcbiAgICAweDUyOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzM0MF19fX19fX19fX0sIDB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzEwMjE5XX19fX19LCAweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjA4XX0sIDB4NzQ6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzEwNTE4XX19fX19fX19fX19LCAweDQyOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA1MTJdfX19fX19fX19LCAweDYzOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFszNDRdfX19fX19fX19LCAweDY1OiB7bDogezB4NjQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMzQyXX19fX19fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzEwNTZdfX19fX0sIDB4NjU6IHtsOiB7MHgzQjoge2M6IFs4NDc2XX0sIDB4NzY6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4NzM6IHtsOiB7MHg2NToge2w6IHsweDQ1OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDZEOiB7bDogezB4NjU6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODcxNV19fX19fX19fX19fX19LCAweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2Mjoge2w6IHsweDcyOiB7bDogezB4Njk6IHtsOiB7MHg3NToge2w6IHsweDZEOiB7bDogezB4M0I6IHtjOiBbODY1MV19fX19fX19fX19fX19fX19fX19fX19fSwgMHg1NToge2w6IHsweDcwOiB7bDogezB4NDU6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDY5OiB7bDogezB4NjI6IHtsOiB7MHg3Mjoge2w6IHsweDY5OiB7bDogezB4NzU6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzEwNjA3XX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg0NToge2w6IHsweDQ3OiB7bDogezB4M0I6IHtjOiBbMTc0XX19LCBjOiBbMTc0XX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODQ3Nl19fX19fSwgMHg2ODoge2w6IHsweDZGOiB7bDogezB4M0I6IHtjOiBbOTI5XX19fX19LCAweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4NDE6IHtsOiB7MHg2RToge2w6IHsweDY3OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDQyOiB7bDogezB4NzI6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NkI6IHtsOiB7MHg2NToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTAyMTddfX19fX19fX19fX19fX19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHg0Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4Njc3XX19fX19fX0sIDB4M0I6IHtjOiBbODU5NF19LCAweDRDOiB7bDogezB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2NDRdfX19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2NThdfX19fX19fX19fX0sIDB4NDM6IHtsOiB7MHg2NToge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4Njc6IHtsOiB7MHgzQjoge2M6IFs4OTY5XX19fX19fX19fX19fX19fSwgMHg0NDoge2w6IHsweDZGOiB7bDogezB4NzU6IHtsOiB7MHg2Mjoge2w6IHsweDZDOiB7bDogezB4NjU6IHtsOiB7MHg0Mjoge2w6IHsweDcyOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDZCOiB7bDogezB4NjU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwMjE1XX19fX19fX19fX19fX19fX19fX19fX19LCAweDc3OiB7bDogezB4NkU6IHtsOiB7MHg1NDoge2w6IHsweDY1OiB7bDogezB4NjU6IHtsOiB7MHg1Njoge2w6IHsweDY1OiB7bDogezB4NjM6IHtsOiB7MHg3NDoge2w6IHsweDZGOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDU4OV19fX19fX19fX19fX19fX19fX19LCAweDU2OiB7bDogezB4NjU6IHtsOiB7MHg2Mzoge2w6IHsweDc0OiB7bDogezB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDQyOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTgxXX19fX19fX0sIDB4M0I6IHtjOiBbODY0Ml19fX19fX19fX19fX19fX19fX19fX0sIDB4NDY6IHtsOiB7MHg2Qzoge2w6IHsweDZGOiB7bDogezB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg5NzFdfX19fX19fX19fX0sIDB4NTQ6IHtsOiB7MHg2NToge2w6IHsweDY1OiB7bDogezB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2MTRdfX19fX19fX19fX0sIDB4M0I6IHtjOiBbODg2Nl19LCAweDU2OiB7bDogezB4NjU6IHtsOiB7MHg2Mzoge2w6IHsweDc0OiB7bDogezB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTg3XX19fX19fX19fX19fX19fX19LCAweDcyOiB7bDogezB4Njk6IHtsOiB7MHg2MToge2w6IHsweDZFOiB7bDogezB4Njc6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4NDI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA3MDRdfX19fX19fSwgMHgzQjoge2M6IFs4ODgzXX0sIDB4NDU6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzg4ODVdfX19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDU1OiB7bDogezB4NzA6IHtsOiB7MHg0NDoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHg2RToge2w6IHsweDU2OiB7bDogezB4NjU6IHtsOiB7MHg2Mzoge2w6IHsweDc0OiB7bDogezB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTc1XX19fX19fX19fX19fX19fX19fX19fSwgMHg1NDoge2w6IHsweDY1OiB7bDogezB4NjU6IHtsOiB7MHg1Njoge2w6IHsweDY1OiB7bDogezB4NjM6IHtsOiB7MHg3NDoge2w6IHsweDZGOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDU4OF19fX19fX19fX19fX19fX19fX19LCAweDU2OiB7bDogezB4NjU6IHtsOiB7MHg2Mzoge2w6IHsweDc0OiB7bDogezB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDQyOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTgwXX19fX19fX0sIDB4M0I6IHtjOiBbODYzOF19fX19fX19fX19fX19fX19fSwgMHg1Njoge2w6IHsweDY1OiB7bDogezB4NjM6IHtsOiB7MHg3NDoge2w6IHsweDZGOiB7bDogezB4NzI6IHtsOiB7MHg0Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDU3OV19fX19fX19LCAweDNCOiB7YzogWzg2NDBdfX19fX19fX19fX19fX19fX19fX19LCAweDZGOiB7bDogezB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzg0NzddfX19fX0sIDB4NzU6IHtsOiB7MHg2RToge2w6IHsweDY0OiB7bDogezB4NDk6IHtsOiB7MHg2RDoge2w6IHsweDcwOiB7bDogezB4NkM6IHtsOiB7MHg2OToge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFsxMDYwOF19fX19fX19fX19fX19fX19fX19fX19fSwgMHg3Mjoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2NjddfX19fX19fX19fX19fX19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg0NzVdfX19fX0sIDB4Njg6IHtsOiB7MHgzQjoge2M6IFs4NjI1XX19fX19LCAweDc1OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDQ0OiB7bDogezB4NjU6IHtsOiB7MHg2Qzoge2w6IHsweDYxOiB7bDogezB4Nzk6IHtsOiB7MHg2NToge2w6IHsweDY0OiB7bDogezB4M0I6IHtjOiBbMTA3NDBdfX19fX19fX19fX19fX19fX19fX19fX0sXHJcbiAgICAweDUzOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzM0Nl19fX19fX19fX19fSwgMHg2Mzoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbMzUyXX19fX19fX19fSwgMHgzQjoge2M6IFsxMDk0MF19LCAweDY1OiB7bDogezB4NjQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMzUwXX19fX19fX19fSwgMHg2OToge2w6IHsweDcyOiB7bDogezB4NjM6IHtsOiB7MHgzQjoge2M6IFszNDhdfX19fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzEwNTddfX19fX0sIDB4NjY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDA4Nl19fX19fSwgMHg0ODoge2w6IHsweDQzOiB7bDogezB4NDg6IHtsOiB7MHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTA2NV19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzEwNjRdfX19fX19fSwgMHg2ODoge2w6IHsweDZGOiB7bDogezB4NzI6IHtsOiB7MHg3NDoge2w6IHsweDQ0OiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDZFOiB7bDogezB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg1OTVdfX19fX19fX19fX19fX19fX19fSwgMHg0Qzoge2w6IHsweDY1OiB7bDogezB4NjY6IHtsOiB7MHg3NDoge2w6IHsweDQxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NTkyXX19fX19fX19fX19fX19fX19fX0sIDB4NTI6IHtsOiB7MHg2OToge2w6IHsweDY3OiB7bDogezB4Njg6IHtsOiB7MHg3NDoge2w6IHsweDQxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHgzQjoge2M6IFs4NTk0XX19fX19fX19fX19fX19fX19fX19fSwgMHg1NToge2w6IHsweDcwOiB7bDogezB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg1OTNdfX19fX19fX19fX19fX19fX19fX19fX0sIDB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDZEOiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs5MzFdfX19fX19fX19LCAweDZEOiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDZDOiB7bDogezB4NDM6IHtsOiB7MHg2OToge2w6IHsweDcyOiB7bDogezB4NjM6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODcyOF19fX19fX19fX19fX19fX19fX19fX0sIDB4NEY6IHtsOiB7MHg0Njoge2w6IHsweDU0OiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzEwNjhdfX19fX19fX19fX0sIDB4NkY6IHtsOiB7MHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbMTIwMTM4XX19fX19fX0sIDB4NzE6IHtsOiB7MHg3Mjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODczMF19fX19fSwgMHg3NToge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzk2MzNdfSwgMHg0OToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4NzM6IHtsOiB7MHg2NToge2w6IHsweDYzOiB7bDogezB4NzQ6IHtsOiB7MHg2OToge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs4ODUxXX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NTM6IHtsOiB7MHg3NToge2w6IHsweDYyOiB7bDogezB4NzM6IHtsOiB7MHg2NToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODg0N119LCAweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4ODQ5XX19fX19fX19fX19fX19fX19fX0sIDB4NzA6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4NzM6IHtsOiB7MHg2NToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODg0OF19LCAweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4ODUwXX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg1NToge2w6IHsweDZFOiB7bDogezB4Njk6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbODg1Ml19fX19fX19fX19fX19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTE5OTgyXX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODkwMl19fX19fX19LCAweDc1OiB7bDogezB4NjI6IHtsOiB7MHgzQjoge2M6IFs4OTEyXX0sIDB4NzM6IHtsOiB7MHg2NToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODkxMl19LCAweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4ODM4XX19fX19fX19fX19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg2Mzoge2w6IHsweDY1OiB7bDogezB4NjU6IHtsOiB7MHg2NDoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODgyN119LCAweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsxMDkyOF19fX19fX19fX19fSwgMHg1Mzoge2w6IHsweDZDOiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDc0OiB7bDogezB4NDU6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NjE6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzg4MjldfX19fX19fX19fX19fX19fX19fX19LCAweDU0OiB7bDogezB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDY0OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4ODMxXX19fX19fX19fX19fX19fX19fX19fSwgMHg2ODoge2w6IHsweDU0OiB7bDogezB4Njg6IHtsOiB7MHg2MToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODcxNV19fX19fX19fX19fX19LCAweDZEOiB7bDogezB4M0I6IHtjOiBbODcyMV19fX0sIDB4NzA6IHtsOiB7MHgzQjoge2M6IFs4OTEzXX0sIDB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDczOiB7bDogezB4NjU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg4MzVdfSwgMHg0NToge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODgzOV19fX19fX19fX19fX19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2NToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODkxM119fX19fX19fX19fX19LFxyXG4gICAgMHg3Mzoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg3NToge2w6IHsweDc0OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFszNDddfX19fX19fX19fX0sIDB4NjI6IHtsOiB7MHg3MToge2w6IHsweDc1OiB7bDogezB4NkY6IHtsOiB7MHgzQjoge2M6IFs4MjE4XX19fX19fX19fSwgMHg2Mzoge2w6IHsweDYxOiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFsxMDkzNl19fX0sIDB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbMzUzXX19fX19fX19fSwgMHgzQjoge2M6IFs4ODI3XX0sIDB4NjM6IHtsOiB7MHg3NToge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODgyOV19fX19fX19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbMTA5MjhdfSwgMHg2NDoge2w6IHsweDY5OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFszNTFdfX19fX19fX19LCAweDQ1OiB7bDogezB4M0I6IHtjOiBbMTA5MzJdfX19LCAweDY5OiB7bDogezB4NzI6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzM0OV19fX19fX19LCAweDZFOiB7bDogezB4NjE6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzEwOTM4XX19fX19LCAweDQ1OiB7bDogezB4M0I6IHtjOiBbMTA5MzRdfX19LCAweDczOiB7bDogezB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzg5MzddfX19fX19fX19LCAweDcwOiB7bDogezB4NkY6IHtsOiB7MHg2Qzoge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwNzcxXX19fX19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4M0I6IHtjOiBbODgzMV19fX19fX19LCAweDc5OiB7bDogezB4M0I6IHtjOiBbMTA4OV19fX19fSwgMHg2NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHg2Mjoge2w6IHsweDNCOiB7YzogWzg4NjVdfX19LCAweDNCOiB7YzogWzg5MDFdfSwgMHg2NToge2w6IHsweDNCOiB7YzogWzEwODU0XX19fX19fX19fSwgMHg2NToge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2ODoge2w6IHsweDZCOiB7bDogezB4M0I6IHtjOiBbMTA1MzNdfX19fX0sIDB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjAwXX0sIDB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2MDBdfX19fX19fX19fX0sIDB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODY2NF19fX19fX19LCAweDYzOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxNjddfX0sIGM6IFsxNjddfX19LCAweDZEOiB7bDogezB4Njk6IHtsOiB7MHgzQjoge2M6IFs1OV19fX19fSwgMHg3Mzoge2w6IHsweDc3OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTM3XX19fX19fX19fSwgMHg3NDoge2w6IHsweDZEOiB7bDogezB4Njk6IHtsOiB7MHg2RToge2w6IHsweDc1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4NzI2XX19fX19fX19fSwgMHg2RToge2w6IHsweDNCOiB7YzogWzg3MjZdfX19fX19fSwgMHg3ODoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTAwMzhdfX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMTEyXX0sIDB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbODk5NF19fX19fX19fX19fSwgMHg2ODoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzk4MzldfX19fX19fSwgMHg2Mzoge2w6IHsweDY4OiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzEwOTddfX19fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzEwOTZdfX19fX0sIDB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDc0OiB7bDogezB4NkQ6IHtsOiB7MHg2OToge2w6IHsweDY0OiB7bDogezB4M0I6IHtjOiBbODczOV19fX19fX19LCAweDcwOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4NzQxXX19fX19fX19fX19fX19fX19fX19fX19LCAweDc5OiB7bDogezB4M0I6IHtjOiBbMTczXX19LCBjOiBbMTczXX19fSwgMHg2OToge2w6IHsweDY3OiB7bDogezB4NkQ6IHtsOiB7MHg2MToge2w6IHsweDNCOiB7YzogWzk2M119LCAweDY2OiB7bDogezB4M0I6IHtjOiBbOTYyXX19fSwgMHg3Njoge2w6IHsweDNCOiB7YzogWzk2Ml19fX19fX19fX0sIDB4NkQ6IHtsOiB7MHgzQjoge2M6IFs4NzY0XX0sIDB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA4NThdfX19fX19fSwgMHg2NToge2w6IHsweDNCOiB7YzogWzg3NzFdfSwgMHg3MToge2w6IHsweDNCOiB7YzogWzg3NzFdfX19fX0sIDB4Njc6IHtsOiB7MHgzQjoge2M6IFsxMDkxMF19LCAweDQ1OiB7bDogezB4M0I6IHtjOiBbMTA5MTJdfX19fX0sIDB4NkM6IHtsOiB7MHgzQjoge2M6IFsxMDkwOV19LCAweDQ1OiB7bDogezB4M0I6IHtjOiBbMTA5MTFdfX19fX0sIDB4NkU6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg3NzRdfX19fX0sIDB4NzA6IHtsOiB7MHg2Qzoge2w6IHsweDc1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFsxMDc4OF19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDYxMF19fX19fX19fX19fX19LCAweDZDOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODU5Ml19fX19fX19fX0sIDB4NkQ6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4NkM6IHtsOiB7MHg3Mzoge2w6IHsweDY1OiB7bDogezB4NzQ6IHtsOiB7MHg2RDoge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHg3NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODcyNl19fX19fX19fX19fX19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2ODoge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbMTA4MDNdfX19fX19fX19LCAweDY1OiB7bDogezB4NzA6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzM6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzEwNzI0XX19fX19fX19fX19fX0sIDB4Njk6IHtsOiB7MHg2NDoge2w6IHsweDNCOiB7YzogWzg3MzldfX19LCAweDZDOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4OTk1XX19fX19fX0sIDB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxMDkyMl19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbMTA5MjRdfSwgMHg3Mzoge2w6IHsweDNCOiB7YzogWzEwOTI0LCA2NTAyNF19fX19fX19fX0sIDB4NkY6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzExMDBdfX19fX19fX19LCAweDZDOiB7bDogezB4NjI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbOTAyM119fX19fSwgMHgzQjoge2M6IFsxMDY5Ml19fX0sIDB4M0I6IHtjOiBbNDddfX19LCAweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxNjRdfX19fX19fSwgMHg3MDoge2w6IHsweDYxOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbOTgyNF19LCAweDc1OiB7bDogezB4Njk6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzk4MjRdfX19fX19fX19fX19fSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzg3NDFdfX19fX19fSwgMHg3MToge2w6IHsweDYzOiB7bDogezB4NjE6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzg4NTFdfSwgMHg3Mzoge2w6IHsweDNCOiB7YzogWzg4NTEsIDY1MDI0XX19fX19fX0sIDB4NzU6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzg4NTJdfSwgMHg3Mzoge2w6IHsweDNCOiB7YzogWzg4NTIsIDY1MDI0XX19fX19fX19fSwgMHg3Mzoge2w6IHsweDc1OiB7bDogezB4NjI6IHtsOiB7MHgzQjoge2M6IFs4ODQ3XX0sIDB4NjU6IHtsOiB7MHgzQjoge2M6IFs4ODQ5XX19fSwgMHg3Mzoge2w6IHsweDY1OiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4ODQ3XX0sIDB4NjU6IHtsOiB7MHg3MToge2w6IHsweDNCOiB7YzogWzg4NDldfX19fX19fX19fX19fSwgMHg3MDoge2w6IHsweDNCOiB7YzogWzg4NDhdfSwgMHg2NToge2w6IHsweDNCOiB7YzogWzg4NTBdfX19LCAweDczOiB7bDogezB4NjU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg4NDhdfSwgMHg2NToge2w6IHsweDcxOiB7bDogezB4M0I6IHtjOiBbODg1MF19fX19fX19fX19fX19fX19fSwgMHg3NToge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzk2MzNdfX19LCAweDY2OiB7bDogezB4M0I6IHtjOiBbOTY0Ml19fX19fX19LCAweDNCOiB7YzogWzk2MzNdfSwgMHg2Njoge2w6IHsweDNCOiB7YzogWzk2NDJdfX19fX19fSwgMHg3Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg1OTRdfX19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDAwOF19fX19fSwgMHg2NToge2w6IHsweDc0OiB7bDogezB4NkQ6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzg3MjZdfX19fX19fX19LCAweDZEOiB7bDogezB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODk5NV19fX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFs4OTAyXX19fX19fX19fX19LCAweDc0OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzk3MzRdfSwgMHg2Njoge2w6IHsweDNCOiB7YzogWzk3MzNdfX19fX19fSwgMHg3Mjoge2w6IHsweDYxOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDY4OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDcwOiB7bDogezB4NzM6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzEwMTNdfX19fX19fX19fX19fX19LCAweDcwOiB7bDogezB4Njg6IHtsOiB7MHg2OToge2w6IHsweDNCOiB7YzogWzk4MV19fX19fX19fX19fX19fX19fSwgMHg2RToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbMTc1XX19fX19fX19fSwgMHg3NToge2w6IHsweDYyOiB7bDogezB4M0I6IHtjOiBbODgzNF19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwOTQxXX19fX19fX0sIDB4NDU6IHtsOiB7MHgzQjoge2M6IFsxMDk0OV19fX0sIDB4NjU6IHtsOiB7MHgzQjoge2M6IFs4ODM4XX0sIDB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA5NDddfX19fX19fX19LCAweDZEOiB7bDogezB4NzU6IHtsOiB7MHg2Qzoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA5NDVdfX19fX19fX19LCAweDZFOiB7bDogezB4NDU6IHtsOiB7MHgzQjoge2M6IFsxMDk1NV19fX0sIDB4NjU6IHtsOiB7MHgzQjoge2M6IFs4ODQyXX19fX19LCAweDcwOiB7bDogezB4NkM6IHtsOiB7MHg3NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbMTA5NDNdfX19fX19fX19LCAweDcyOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA2MTddfX19fX19fX19LCAweDczOiB7bDogezB4NjU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg4MzRdfSwgMHg2NToge2w6IHsweDcxOiB7bDogezB4M0I6IHtjOiBbODgzOF19LCAweDcxOiB7bDogezB4M0I6IHtjOiBbMTA5NDldfX19fX19fSwgMHg2RToge2w6IHsweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFs4ODQyXX0sIDB4NzE6IHtsOiB7MHgzQjoge2M6IFsxMDk1NV19fX19fX19fX19fX19LCAweDY5OiB7bDogezB4NkQ6IHtsOiB7MHgzQjoge2M6IFsxMDk1MV19fX19fSwgMHg3NToge2w6IHsweDYyOiB7bDogezB4M0I6IHtjOiBbMTA5NjVdfX19LCAweDcwOiB7bDogezB4M0I6IHtjOiBbMTA5NjNdfX19fX19fX19LCAweDYzOiB7bDogezB4NjM6IHtsOiB7MHg2MToge2w6IHsweDcwOiB7bDogezB4NzA6IHtsOiB7MHg3Mjoge2w6IHsweDZGOiB7bDogezB4Nzg6IHtsOiB7MHgzQjoge2M6IFsxMDkzNl19fX19fX19fX19fX19LCAweDNCOiB7YzogWzg4MjddfSwgMHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzI6IHtsOiB7MHg2Qzoge2w6IHsweDc5OiB7bDogezB4NjU6IHtsOiB7MHg3MToge2w6IHsweDNCOiB7YzogWzg4MjldfX19fX19fX19fX19fX19LCAweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFsxMDkyOF19fX19fSwgMHg2RToge2w6IHsweDYxOiB7bDogezB4NzA6IHtsOiB7MHg3MDoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3ODoge2w6IHsweDNCOiB7YzogWzEwOTM4XX19fX19fX19fX19fX0sIDB4NjU6IHtsOiB7MHg3MToge2w6IHsweDcxOiB7bDogezB4M0I6IHtjOiBbMTA5MzRdfX19fX19fSwgMHg3Mzoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHgzQjoge2M6IFs4OTM3XX19fX19fX19fSwgMHg3Mzoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHgzQjoge2M6IFs4ODMxXX19fX19fX19fX19LCAweDZEOiB7bDogezB4M0I6IHtjOiBbODcyMV19fX0sIDB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzk4MzRdfX19fX0sIDB4NzA6IHtsOiB7MHgzMToge2w6IHsweDNCOiB7YzogWzE4NV19fSwgYzogWzE4NV19LCAweDMyOiB7bDogezB4M0I6IHtjOiBbMTc4XX19LCBjOiBbMTc4XX0sIDB4MzM6IHtsOiB7MHgzQjoge2M6IFsxNzldfX0sIGM6IFsxNzldfSwgMHgzQjoge2M6IFs4ODM1XX0sIDB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA5NDJdfX19fX0sIDB4NzM6IHtsOiB7MHg3NToge2w6IHsweDYyOiB7bDogezB4M0I6IHtjOiBbMTA5NjhdfX19fX19fX19LCAweDQ1OiB7bDogezB4M0I6IHtjOiBbMTA5NTBdfX19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbODgzOV19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzEwOTQ4XX19fX19fX19fSwgMHg2ODoge2w6IHsweDczOiB7bDogezB4NkY6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzEwMTg1XX19fX19LCAweDc1OiB7bDogezB4NjI6IHtsOiB7MHgzQjoge2M6IFsxMDk2N119fX19fX19fX0sIDB4NkM6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDYxOV19fX19fX19fX0sIDB4NkQ6IHtsOiB7MHg3NToge2w6IHsweDZDOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxMDk0Nl19fX19fX19fX0sIDB4NkU6IHtsOiB7MHg0NToge2w6IHsweDNCOiB7YzogWzEwOTU2XX19fSwgMHg2NToge2w6IHsweDNCOiB7YzogWzg4NDNdfX19fX0sIDB4NzA6IHtsOiB7MHg2Qzoge2w6IHsweDc1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFsxMDk0NF19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2NToge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODgzNV19LCAweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFs4ODM5XX0sIDB4NzE6IHtsOiB7MHgzQjoge2M6IFsxMDk1MF19fX19fX19LCAweDZFOiB7bDogezB4NjU6IHtsOiB7MHg3MToge2w6IHsweDNCOiB7YzogWzg4NDNdfSwgMHg3MToge2w6IHsweDNCOiB7YzogWzEwOTU2XX19fX19fX19fX19fX0sIDB4Njk6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzEwOTUyXX19fX19LCAweDc1OiB7bDogezB4NjI6IHtsOiB7MHgzQjoge2M6IFsxMDk2NF19fX0sIDB4NzA6IHtsOiB7MHgzQjoge2M6IFsxMDk2Nl19fX19fX19fX19fSwgMHg3Nzoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2ODoge2w6IHsweDZCOiB7bDogezB4M0I6IHtjOiBbMTA1MzRdfX19fX0sIDB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjAxXX0sIDB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2MDFdfX19fX19fX19fX0sIDB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODY2NV19fX19fX19LCAweDZFOiB7bDogezB4Nzc6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTA1MzhdfX19fX19fX19fX0sIDB4N0E6IHtsOiB7MHg2Qzoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHgzQjoge2M6IFsyMjNdfX0sIGM6IFsyMjNdfX19fX19fX19LFxyXG4gICAgMHg1NDoge2w6IHsweDYxOiB7bDogezB4NjI6IHtsOiB7MHgzQjoge2M6IFs5XX19fSwgMHg3NToge2w6IHsweDNCOiB7YzogWzkzMl19fX19fSwgMHg2Mzoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbMzU2XX19fX19fX19fSwgMHg2NToge2w6IHsweDY0OiB7bDogezB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzM1NF19fX19fX19fX0sIDB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDU4XX19fX19LCAweDY2OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAwODddfX19fX0sIDB4Njg6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDZGOiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg3NTZdfX19fX19fX19fX19fSwgMHg3NDoge2w6IHsweDYxOiB7bDogezB4M0I6IHtjOiBbOTIwXX19fX19fX0sIDB4Njk6IHtsOiB7MHg2Mzoge2w6IHsweDZCOiB7bDogezB4NTM6IHtsOiB7MHg3MDoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzgyODcsIDgyMDJdfX19fX19fX19fX19fX19LCAweDZFOiB7bDogezB4NTM6IHtsOiB7MHg3MDoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzgyMDFdfX19fX19fX19fX19fX19fX0sIDB4NDg6IHtsOiB7MHg0Rjoge2w6IHsweDUyOiB7bDogezB4NEU6IHtsOiB7MHgzQjoge2M6IFsyMjJdfX0sIGM6IFsyMjJdfX19fX19fSwgMHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg3NjRdfSwgMHg0NToge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2MToge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbODc3MV19fX19fX19fX19fSwgMHg0Njoge2w6IHsweDc1OiB7bDogezB4NkM6IHtsOiB7MHg2Qzoge2w6IHsweDQ1OiB7bDogezB4NzE6IHtsOiB7MHg3NToge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4NzczXX19fX19fX19fX19fX19fX19fX0sIDB4NTQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg3NzZdfX19fX19fX19fX19fX19fX19fSwgMHg2Rjoge2w6IHsweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxMzldfX19fX19fSwgMHg1Mjoge2w6IHsweDQxOiB7bDogezB4NDQ6IHtsOiB7MHg0NToge2w6IHsweDNCOiB7YzogWzg0ODJdfX19fX19fX19LCAweDcyOiB7bDogezB4Njk6IHtsOiB7MHg3MDoge2w6IHsweDZDOiB7bDogezB4NjU6IHtsOiB7MHg0NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4NDExXX19fX19fX19fX19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzExOTk4M119fX19fSwgMHg3NDoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2Qjoge2w6IHsweDNCOiB7YzogWzM1OF19fX19fX19fX19fSwgMHg1Mzoge2w6IHsweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDYyXX19fX19LCAweDQ4OiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzEwMzVdfX19fX19fX19fX0sXHJcbiAgICAweDc0OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDY3OiB7bDogezB4NjU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg5ODJdfX19fX19fX19LCAweDc1OiB7bDogezB4M0I6IHtjOiBbOTY0XX19fX19LCAweDYyOiB7bDogezB4NzI6IHtsOiB7MHg2Qjoge2w6IHsweDNCOiB7YzogWzkxNDBdfX19fX19fSwgMHg2Mzoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbMzU3XX19fX19fX19fSwgMHg2NToge2w6IHsweDY0OiB7bDogezB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzM1NV19fX19fX19fX0sIDB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDkwXX19fX19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg0MTFdfX19fX19fSwgMHg2NToge2w6IHsweDZDOiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbODk4MV19fX19fX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMTEzXX19fX19LCAweDY4OiB7bDogezB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDY1OiB7bDogezB4MzQ6IHtsOiB7MHgzQjoge2M6IFs4NzU2XX19fSwgMHg2Njoge2w6IHsweDZGOiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg3NTZdfX19fX19fX19fX19fSwgMHg3NDoge2w6IHsweDYxOiB7bDogezB4M0I6IHtjOiBbOTUyXX0sIDB4NzM6IHtsOiB7MHg3OToge2w6IHsweDZEOiB7bDogezB4M0I6IHtjOiBbOTc3XX19fX19fX0sIDB4NzY6IHtsOiB7MHgzQjoge2M6IFs5NzddfX19fX19fX19LCAweDY5OiB7bDogezB4NjM6IHtsOiB7MHg2Qjoge2w6IHsweDYxOiB7bDogezB4NzA6IHtsOiB7MHg3MDoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3ODoge2w6IHsweDNCOiB7YzogWzg3NzZdfX19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHgzQjoge2M6IFs4NzY0XX19fX19fX19fX19LCAweDZFOiB7bDogezB4NzM6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzgyMDFdfX19fX19fX19LCAweDZCOiB7bDogezB4NjE6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzg3NzZdfX19fX0sIDB4NzM6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4M0I6IHtjOiBbODc2NF19fX19fX19fX0sIDB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbMjU0XX19LCBjOiBbMjU0XX19fX19fX0sIDB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDY0OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs3MzJdfX19fX19fSwgMHg2RDoge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHg2Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDgwMV19fX19fSwgMHgzQjoge2M6IFs4ODY0XX19fSwgMHgzQjoge2M6IFsyMTVdfSwgMHg2NDoge2w6IHsweDNCOiB7YzogWzEwODAwXX19fX0sIGM6IFsyMTVdfX19fX0sIDB4NkU6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg3NDldfX19fX19fSwgMHg2Rjoge2w6IHsweDY1OiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFsxMDUzNl19fX19fSwgMHg3MDoge2w6IHsweDYyOiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzkwMTRdfX19fX19fSwgMHg2Mzoge2w6IHsweDY5OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDk5M119fX19fX19LCAweDNCOiB7YzogWzg4NjhdfSwgMHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDE2NV19LCAweDZGOiB7bDogezB4NzI6IHtsOiB7MHg2Qjoge2w6IHsweDNCOiB7YzogWzEwOTcwXX19fX19fX19fX19LCAweDczOiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFsxMDUzN119fX19fX19LCAweDcwOiB7bDogezB4NzI6IHtsOiB7MHg2OToge2w6IHsweDZEOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4MjQ0XX19fX19fX19fX19LCAweDcyOiB7bDogezB4NjE6IHtsOiB7MHg2NDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODQ4Ml19fX19fX19LCAweDY5OiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDY3OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzk2NTNdfSwgMHg2NDoge2w6IHsweDZGOiB7bDogezB4Nzc6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzk2NjNdfX19fX19fX19LCAweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2Njoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbOTY2N119LCAweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFs4ODg0XX19fX19fX19fX19fX0sIDB4NzE6IHtsOiB7MHgzQjoge2M6IFs4Nzk2XX19fSwgMHg3Mjoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbOTY1N119LCAweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFs4ODg1XX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbOTcwOF19fX19fX19LCAweDY1OiB7bDogezB4M0I6IHtjOiBbODc5Nl19fX0sIDB4NkQ6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4NzU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzEwODEwXX19fX19fX19fX19LCAweDcwOiB7bDogezB4NkM6IHtsOiB7MHg3NToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbMTA4MDldfX19fX19fX19LCAweDczOiB7bDogezB4NjI6IHtsOiB7MHgzQjoge2M6IFsxMDcwMV19fX19fSwgMHg3NDoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzEwODExXX19fX19fX19fX19LCAweDcwOiB7bDogezB4NjU6IHtsOiB7MHg3QToge2w6IHsweDY5OiB7bDogezB4NzU6IHtsOiB7MHg2RDoge2w6IHsweDNCOiB7YzogWzkxODZdfX19fX19fX19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDAwOV19fX0sIDB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDk0XX19fX19LCAweDY4OiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzExMTVdfX19fX19fSwgMHg3NDoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2Qjoge2w6IHsweDNCOiB7YzogWzM1OV19fX19fX19fX19fSwgMHg3Nzoge2w6IHsweDY5OiB7bDogezB4Nzg6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg4MTJdfX19fX19fSwgMHg2Rjoge2w6IHsweDY4OiB7bDogezB4NjU6IHtsOiB7MHg2MToge2w6IHsweDY0OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDY2OiB7bDogezB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODYwNl19fX19fX19fX19fX19fX19fX19LCAweDcyOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDY4OiB7bDogezB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODYwOF19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fSxcclxuICAgIDB4NTU6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NzU6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbMjE4XX19LCBjOiBbMjE4XX19fX19fX0sIDB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg2MDddfSwgMHg2Rjoge2w6IHsweDYzOiB7bDogezB4Njk6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTY5XX19fX19fX19fX19fX19fSwgMHg2Mjoge2w6IHsweDcyOiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzEwMzhdfX19fX0sIDB4NjU6IHtsOiB7MHg3Njoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbMzY0XX19fX19fX19fX19LCAweDYzOiB7bDogezB4Njk6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbMjE5XX19LCBjOiBbMjE5XX19fX19LCAweDc5OiB7bDogezB4M0I6IHtjOiBbMTA1OV19fX19fSwgMHg2NDoge2w6IHsweDYyOiB7bDogezB4NkM6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbMzY4XX19fX19fX19fX19LCAweDY2OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAwODhdfX19fX0sIDB4Njc6IHtsOiB7MHg3Mjoge2w6IHsweDYxOiB7bDogezB4NzY6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzIxN119fSwgYzogWzIxN119fX19fX19fX0sIDB4NkQ6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFszNjJdfX19fX19fX19LCAweDZFOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4NDI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbOTVdfX19fX0sIDB4NzI6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs5MTgzXX19fSwgMHg2Qjoge2w6IHsweDY1OiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs5MTQxXX19fX19fX19fX19fX19fSwgMHg1MDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2NToge2w6IHsweDZFOiB7bDogezB4NzQ6IHtsOiB7MHg2ODoge2w6IHsweDY1OiB7bDogezB4NzM6IHtsOiB7MHg2OToge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbOTE4MV19fX19fX19fX19fX19fX19fX19fX19fX19fX19fSwgMHg2OToge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs4ODk5XX0sIDB4NTA6IHtsOiB7MHg2Qzoge2w6IHsweDc1OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4ODQ2XX19fX19fX19fX19fX19fX19LCAweDZGOiB7bDogezB4Njc6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbMzcwXX19fX19fX0sIDB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDE0MF19fX19fX19LCAweDcwOiB7bDogezB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDQyOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTE0XX19fX19fX0sIDB4M0I6IHtjOiBbODU5M119LCAweDQ0OiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDZFOiB7bDogezB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2NDVdfX19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2NTddfX19fX19fX19fX0sIDB4NDQ6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4NkU6IHtsOiB7MHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODU5N119fX19fX19fX19fX19fX19fX19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDZFOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg2NjFdfX19fX19fX19fX19fX19fX19fSwgMHg0NToge2w6IHsweDcxOiB7bDogezB4NzU6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4Njk6IHtsOiB7MHg2Mjoge2w6IHsweDcyOiB7bDogezB4Njk6IHtsOiB7MHg3NToge2w6IHsweDZEOiB7bDogezB4M0I6IHtjOiBbMTA2MDZdfX19fX19fX19fX19fX19fX19fX19fX0sIDB4NzA6IHtsOiB7MHg2NToge2w6IHsweDcyOiB7bDogezB4NEM6IHtsOiB7MHg2NToge2w6IHsweDY2OiB7bDogezB4NzQ6IHtsOiB7MHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODU5OF19fX19fX19fX19fX19fX19fX19LCAweDUyOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDY4OiB7bDogezB4NzQ6IHtsOiB7MHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODU5OV19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2OToge2w6IHsweDNCOiB7YzogWzk3OF19LCAweDZDOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzkzM119fX19fX19fX19fSwgMHg1NDoge2w6IHsweDY1OiB7bDogezB4NjU6IHtsOiB7MHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODYxM119fX19fX19fX19fSwgMHgzQjoge2M6IFs4ODY5XX19fX19fX19fSwgMHg3Mjoge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzM2Nl19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTE5OTg0XX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzM2MF19fX19fX19fX19fSwgMHg3NToge2w6IHsweDZEOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFsyMjBdfX0sIGM6IFsyMjBdfX19fX19fSxcclxuICAgIDB4NzU6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NzU6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbMjUwXX19LCBjOiBbMjUwXX19fX19fX0sIDB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg1OTNdfX19fX19fSwgMHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjU3XX19fX19fX0sIDB4NjI6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMTE4XX19fX19LCAweDY1OiB7bDogezB4NzY6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzM2NV19fX19fX19fX19fSwgMHg2Mzoge2w6IHsweDY5OiB7bDogezB4NzI6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzI1MV19fSwgYzogWzI1MV19fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzEwOTFdfX19fX0sIDB4NjQ6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjQ1XX19fX19fX0sIDB4NjI6IHtsOiB7MHg2Qzoge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHgzQjoge2M6IFszNjldfX19fX19fX19LCAweDY4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNjA2XX19fX19fX19fSwgMHg2Njoge2w6IHsweDY5OiB7bDogezB4NzM6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA2MjJdfX19fX19fX19LCAweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMTE0XX19fX19LCAweDY3OiB7bDogezB4NzI6IHtsOiB7MHg2MToge2w6IHsweDc2OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsyNDldfX0sIGM6IFsyNDldfX19fX19fX19LCAweDQ4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwNTk1XX19fX19fX0sIDB4Njg6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NkM6IHtsOiB7MHgzQjoge2M6IFs4NjM5XX19fSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzg2MzhdfX19fX19fSwgMHg2Mjoge2w6IHsweDZDOiB7bDogezB4NkI6IHtsOiB7MHgzQjoge2M6IFs5NjAwXX19fX19fX19fSwgMHg2Qzoge2w6IHsweDYzOiB7bDogezB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbODk4OF19LCAweDY1OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4OTg4XX19fX19fX19fX19LCAweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzg5NzVdfX19fX19fX19LCAweDc0OiB7bDogezB4NzI6IHtsOiB7MHg2OToge2w6IHsweDNCOiB7YzogWzk3MjBdfX19fX19fX19LCAweDZEOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMzYzXX19fX19fX0sIDB4NkM6IHtsOiB7MHgzQjoge2M6IFsxNjhdfX0sIGM6IFsxNjhdfX19LCAweDZGOiB7bDogezB4Njc6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbMzcxXX19fX19fX0sIDB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDE2Nl19fX19fX19LCAweDcwOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDNCOiB7YzogWzg1OTNdfX19fX19fX19fX0sIDB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4NkU6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDc3OiB7bDogezB4M0I6IHtjOiBbODU5N119fX19fX19fX19fX19fX19fX19LCAweDY4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcwOiB7bDogezB4NkY6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDY2OiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4NjM5XX19fX19fX19fSwgMHg3Mjoge2w6IHsweDY5OiB7bDogezB4Njc6IHtsOiB7MHg2ODoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbODYzOF19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDZDOiB7bDogezB4NzU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzg4NDZdfX19fX19fSwgMHg3Mzoge2w6IHsweDY5OiB7bDogezB4M0I6IHtjOiBbOTY1XX0sIDB4Njg6IHtsOiB7MHgzQjoge2M6IFs5NzhdfX19LCAweDZDOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzk2NV19fX19fX19fX19fSwgMHg3NToge2w6IHsweDcwOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3Nzoge2w6IHsweDczOiB7bDogezB4M0I6IHtjOiBbODY0OF19fX19fX19fX19fX19fX19fX19LCAweDcyOiB7bDogezB4NjM6IHtsOiB7MHg2Rjoge2w6IHsweDcyOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFs4OTg5XX0sIDB4NjU6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg5ODldfX19fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbODk3NF19fX19fX19fX0sIDB4Njk6IHtsOiB7MHg2RToge2w6IHsweDY3OiB7bDogezB4M0I6IHtjOiBbMzY3XX19fX19fX0sIDB4NzQ6IHtsOiB7MHg3Mjoge2w6IHsweDY5OiB7bDogezB4M0I6IHtjOiBbOTcyMV19fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDEwXX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4OTQ0XX19fX19fX0sIDB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDY0OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFszNjFdfX19fX19fX19LCAweDcyOiB7bDogezB4Njk6IHtsOiB7MHgzQjoge2M6IFs5NjUzXX0sIDB4NjY6IHtsOiB7MHgzQjoge2M6IFs5NjUyXX19fX19fX19fSwgMHg3NToge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzg2NDhdfX19fX19fSwgMHg2RDoge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMjUyXX19LCBjOiBbMjUyXX19fX19LCAweDc3OiB7bDogezB4NjE6IHtsOiB7MHg2RToge2w6IHsweDY3OiB7bDogezB4NkM6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzEwNjYzXX19fX19fX19fX19fX19fSxcclxuICAgIDB4NzY6IHtsOiB7MHg2MToge2w6IHsweDZFOiB7bDogezB4Njc6IHtsOiB7MHg3Mjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMTA2NTJdfX19fX19fX19LCAweDcyOiB7bDogezB4NjU6IHtsOiB7MHg3MDoge2w6IHsweDczOiB7bDogezB4Njk6IHtsOiB7MHg2Qzoge2w6IHsweDZGOiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFsxMDEzXX19fX19fX19fX19fX19fSwgMHg2Qjoge2w6IHsweDYxOiB7bDogezB4NzA6IHtsOiB7MHg3MDoge2w6IHsweDYxOiB7bDogezB4M0I6IHtjOiBbMTAwOF19fX19fX19fX19fSwgMHg2RToge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHg2ODoge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzg3MDldfX19fX19fX19fX19fX19LCAweDcwOiB7bDogezB4Njg6IHtsOiB7MHg2OToge2w6IHsweDNCOiB7YzogWzk4MV19fX19fSwgMHg2OToge2w6IHsweDNCOiB7YzogWzk4Ml19fX0sIDB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDcwOiB7bDogezB4NzQ6IHtsOiB7MHg2Rjoge2w6IHsweDNCOiB7YzogWzg3MzNdfX19fX19fX19fX19fSwgMHg3Mjoge2w6IHsweDNCOiB7YzogWzg1OTddfSwgMHg2ODoge2w6IHsweDZGOiB7bDogezB4M0I6IHtjOiBbMTAwOV19fX19fX19LCAweDczOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDZEOiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs5NjJdfX19fX19fX19LCAweDc1OiB7bDogezB4NjI6IHtsOiB7MHg3Mzoge2w6IHsweDY1OiB7bDogezB4NzQ6IHtsOiB7MHg2RToge2w6IHsweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFs4ODQyLCA2NTAyNF19LCAweDcxOiB7bDogezB4M0I6IHtjOiBbMTA5NTUsIDY1MDI0XX19fX19fX19fX19fX19fX19LCAweDcwOiB7bDogezB4NzM6IHtsOiB7MHg2NToge2w6IHsweDc0OiB7bDogezB4NkU6IHtsOiB7MHg2NToge2w6IHsweDcxOiB7bDogezB4M0I6IHtjOiBbODg0MywgNjUwMjRdfSwgMHg3MToge2w6IHsweDNCOiB7YzogWzEwOTU2LCA2NTAyNF19fX19fX19fX19fX19fX19fX19fX0sIDB4NzQ6IHtsOiB7MHg2ODoge2w6IHsweDY1OiB7bDogezB4NzQ6IHtsOiB7MHg2MToge2w6IHsweDNCOiB7YzogWzk3N119fX19fX19fX0sIDB4NzI6IHtsOiB7MHg2OToge2w6IHsweDYxOiB7bDogezB4NkU6IHtsOiB7MHg2Nzoge2w6IHsweDZDOiB7bDogezB4NjU6IHtsOiB7MHg2Qzoge2w6IHsweDY1OiB7bDogezB4NjY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzg4ODJdfX19fX19fX19LCAweDcyOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDY4OiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4ODgzXX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX0sIDB4NDE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODY2MV19fX19fX19LCAweDQyOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwOTg0XX0sIDB4NzY6IHtsOiB7MHgzQjoge2M6IFsxMDk4NV19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzEwNzRdfX19fX0sIDB4NjQ6IHtsOiB7MHg2MToge2w6IHsweDczOiB7bDogezB4Njg6IHtsOiB7MHgzQjoge2M6IFs4ODY2XX19fX19fX19fSwgMHg0NDoge2w6IHsweDYxOiB7bDogezB4NzM6IHtsOiB7MHg2ODoge2w6IHsweDNCOiB7YzogWzg4NzJdfX19fX19fX19LCAweDY1OiB7bDogezB4NjU6IHtsOiB7MHg2Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4ODkxXX19fX19fX0sIDB4M0I6IHtjOiBbODc0NF19LCAweDY1OiB7bDogezB4NzE6IHtsOiB7MHgzQjoge2M6IFs4Nzk0XX19fX19fX0sIDB4NkM6IHtsOiB7MHg2Qzoge2w6IHsweDY5OiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFs4OTQyXX19fX19fX19fSwgMHg3Mjoge2w6IHsweDYyOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEyNF19fX19fX19LCAweDc0OiB7bDogezB4M0I6IHtjOiBbMTI0XX19fX19fX0sIDB4NjY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDExNV19fX19fSwgMHg2Qzoge2w6IHsweDc0OiB7bDogezB4NzI6IHtsOiB7MHg2OToge2w6IHsweDNCOiB7YzogWzg4ODJdfX19fX19fX19LCAweDZFOiB7bDogezB4NzM6IHtsOiB7MHg3NToge2w6IHsweDYyOiB7bDogezB4M0I6IHtjOiBbODgzNCwgODQwMl19fX0sIDB4NzA6IHtsOiB7MHgzQjoge2M6IFs4ODM1LCA4NDAyXX19fX19fX19fSwgMHg2Rjoge2w6IHsweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxNjddfX19fX19fSwgMHg3MDoge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzg3MzNdfX19fX19fX19LCAweDcyOiB7bDogezB4NzQ6IHtsOiB7MHg3Mjoge2w6IHsweDY5OiB7bDogezB4M0I6IHtjOiBbODg4M119fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDExXX19fX19LCAweDc1OiB7bDogezB4NjI6IHtsOiB7MHg2RToge2w6IHsweDQ1OiB7bDogezB4M0I6IHtjOiBbMTA5NTUsIDY1MDI0XX19fSwgMHg2NToge2w6IHsweDNCOiB7YzogWzg4NDIsIDY1MDI0XX19fX19fX0sIDB4NzA6IHtsOiB7MHg2RToge2w6IHsweDQ1OiB7bDogezB4M0I6IHtjOiBbMTA5NTYsIDY1MDI0XX19fSwgMHg2NToge2w6IHsweDNCOiB7YzogWzg4NDMsIDY1MDI0XX19fX19fX19fX19LCAweDdBOiB7bDogezB4Njk6IHtsOiB7MHg2Nzoge2w6IHsweDdBOiB7bDogezB4NjE6IHtsOiB7MHg2Nzoge2w6IHsweDNCOiB7YzogWzEwNjUwXX19fX19fX19fX19fX19fSxcclxuICAgIDB4NTY6IHtsOiB7MHg2Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDk4N119fX19fX19LCAweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDQyXX19fX19LCAweDY0OiB7bDogezB4NjE6IHtsOiB7MHg3Mzoge2w6IHsweDY4OiB7bDogezB4M0I6IHtjOiBbODg3M119LCAweDZDOiB7bDogezB4M0I6IHtjOiBbMTA5ODJdfX19fX19fX19fX0sIDB4NDQ6IHtsOiB7MHg2MToge2w6IHsweDczOiB7bDogezB4Njg6IHtsOiB7MHgzQjoge2M6IFs4ODc1XX19fX19fX19fSwgMHg2NToge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODg5N119fX0sIDB4NzI6IHtsOiB7MHg2Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4MjE0XX19fX19fX0sIDB4NzQ6IHtsOiB7MHgzQjoge2M6IFs4MjE0XX0sIDB4Njk6IHtsOiB7MHg2Mzoge2w6IHsweDYxOiB7bDogezB4NkM6IHtsOiB7MHg0Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NzM5XX19fX19fX0sIDB4NEM6IHtsOiB7MHg2OToge2w6IHsweDZFOiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsxMjRdfX19fX19fX19LCAweDUzOiB7bDogezB4NjU6IHtsOiB7MHg3MDoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2MToge2w6IHsweDc0OiB7bDogezB4NkY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEwMDcyXX19fX19fX19fX19fX19fX19fX0sIDB4NTQ6IHtsOiB7MHg2OToge2w6IHsweDZDOiB7bDogezB4NjQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg3NjhdfX19fX19fX19fX19fX19fX19fX19LCAweDc5OiB7bDogezB4NTQ6IHtsOiB7MHg2ODoge2w6IHsweDY5OiB7bDogezB4NkU6IHtsOiB7MHg1Mzoge2w6IHsweDcwOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODIwMl19fX19fX19fX19fX19fX19fX19fX19fX19LCAweDY2OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAwODldfX19fX0sIDB4NkY6IHtsOiB7MHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbMTIwMTQxXX19fX19fX0sIDB4NzM6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTE5OTg1XX19fX19fX0sIDB4NzY6IHtsOiB7MHg2NDoge2w6IHsweDYxOiB7bDogezB4NzM6IHtsOiB7MHg2ODoge2w6IHsweDNCOiB7YzogWzg4NzRdfX19fX19fX19fX19fSxcclxuICAgIDB4NTc6IHtsOiB7MHg2Mzoge2w6IHsweDY5OiB7bDogezB4NzI6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzM3Ml19fX19fX19fX0sIDB4NjU6IHtsOiB7MHg2NDoge2w6IHsweDY3OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4ODk2XX19fX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDkwXX19fX19LCAweDZGOiB7bDogezB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDE0Ml19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzExOTk4Nl19fX19fX19fX0sXHJcbiAgICAweDc3OiB7bDogezB4NjM6IHtsOiB7MHg2OToge2w6IHsweDcyOiB7bDogezB4NjM6IHtsOiB7MHgzQjoge2M6IFszNzNdfX19fX19fX19LCAweDY1OiB7bDogezB4NjQ6IHtsOiB7MHg2Mjoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDg0N119fX19fX19LCAweDY3OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4NzQzXX0sIDB4NzE6IHtsOiB7MHgzQjoge2M6IFs4NzkzXX19fX19fX19fSwgMHg2OToge2w6IHsweDY1OiB7bDogezB4NzI6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzg0NzJdfX19fX19fX19fX0sIDB4NjY6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDExNl19fX19fSwgMHg2Rjoge2w6IHsweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxNjhdfX19fX19fSwgMHg3MDoge2w6IHsweDNCOiB7YzogWzg0NzJdfX19LCAweDcyOiB7bDogezB4M0I6IHtjOiBbODc2OF19LCAweDY1OiB7bDogezB4NjE6IHtsOiB7MHg3NDoge2w6IHsweDY4OiB7bDogezB4M0I6IHtjOiBbODc2OF19fX19fX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAwMTJdfX19fX19fX19LFxyXG4gICAgMHg3ODoge2w6IHsweDYzOiB7bDogezB4NjE6IHtsOiB7MHg3MDoge2w6IHsweDNCOiB7YzogWzg4OThdfX19fX0sIDB4Njk6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbOTcxMV19fX19fX19LCAweDc1OiB7bDogezB4NzA6IHtsOiB7MHgzQjoge2M6IFs4ODk5XX19fX19fX0sIDB4NjQ6IHtsOiB7MHg3NDoge2w6IHsweDcyOiB7bDogezB4Njk6IHtsOiB7MHgzQjoge2M6IFs5NjYxXX19fX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMTE3XX19fX19LCAweDY4OiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTAyMzFdfX19fX19fSwgMHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDIzNF19fX19fX19fX0sIDB4Njk6IHtsOiB7MHgzQjoge2M6IFs5NThdfX19LCAweDZDOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTAyMjldfX19fX19fSwgMHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDIzMl19fX19fX19fX0sIDB4NkQ6IHtsOiB7MHg2MToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbMTAyMzZdfX19fX19fSwgMHg2RToge2w6IHsweDY5OiB7bDogezB4NzM6IHtsOiB7MHgzQjoge2M6IFs4OTU1XX19fX19fX0sIDB4NkY6IHtsOiB7MHg2NDoge2w6IHsweDZGOiB7bDogezB4NzQ6IHtsOiB7MHgzQjoge2M6IFsxMDc1Ml19fX19fX19LCAweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxNjldfX19LCAweDZDOiB7bDogezB4NzU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzEwNzUzXX19fX19fX19fSwgMHg3NDoge2w6IHsweDY5OiB7bDogezB4NkQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzEwNzU0XX19fX19fX19fX19LCAweDcyOiB7bDogezB4NjE6IHtsOiB7MHg3Mjoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTAyMzBdfX19fX19fSwgMHg0MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMDIzM119fX19fX19fX0sIDB4NzM6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDEzXX19fX19LCAweDcxOiB7bDogezB4NjM6IHtsOiB7MHg3NToge2w6IHsweDcwOiB7bDogezB4M0I6IHtjOiBbMTA3NThdfX19fX19fX19fX0sIDB4NzU6IHtsOiB7MHg3MDoge2w6IHsweDZDOiB7bDogezB4NzU6IHtsOiB7MHg3Mzoge2w6IHsweDNCOiB7YzogWzEwNzU2XX19fX19fX19fSwgMHg3NDoge2w6IHsweDcyOiB7bDogezB4Njk6IHtsOiB7MHgzQjoge2M6IFs5NjUxXX19fX19fX19fSwgMHg3Njoge2w6IHsweDY1OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFs4ODk3XX19fX19fX0sIDB4Nzc6IHtsOiB7MHg2NToge2w6IHsweDY0OiB7bDogezB4Njc6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzg4OTZdfX19fX19fX19fX19fSxcclxuICAgIDB4NTg6IHtsOiB7MHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDkxXX19fX19LCAweDY5OiB7bDogezB4M0I6IHtjOiBbOTI2XX19fSwgMHg2Rjoge2w6IHsweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxNDNdfX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMTk5ODddfX19fX19fX19LFxyXG4gICAgMHg1OToge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg3NToge2w6IHsweDc0OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFsyMjFdfX0sIGM6IFsyMjFdfX19fX19fX19LCAweDQxOiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzEwNzFdfX19fX19fSwgMHg2Mzoge2w6IHsweDY5OiB7bDogezB4NzI6IHtsOiB7MHg2Mzoge2w6IHsweDNCOiB7YzogWzM3NF19fX19fX19LCAweDc5OiB7bDogezB4M0I6IHtjOiBbMTA2N119fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDkyXX19fX19LCAweDQ5OiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzEwMzFdfX19fX19fSwgMHg2Rjoge2w6IHsweDcwOiB7bDogezB4NjY6IHtsOiB7MHgzQjoge2M6IFsxMjAxNDRdfX19fX19fSwgMHg3Mzoge2w6IHsweDYzOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMTk5ODhdfX19fX19fSwgMHg1NToge2w6IHsweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDcwXX19fX19fX0sIDB4NzU6IHtsOiB7MHg2RDoge2w6IHsweDZDOiB7bDogezB4M0I6IHtjOiBbMzc2XX19fX19fX19fSxcclxuICAgIDB4Nzk6IHtsOiB7MHg2MToge2w6IHsweDYzOiB7bDogezB4NzU6IHtsOiB7MHg3NDoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbMjUzXX19LCBjOiBbMjUzXX19fX19LCAweDc5OiB7bDogezB4M0I6IHtjOiBbMTEwM119fX19fX19LCAweDYzOiB7bDogezB4Njk6IHtsOiB7MHg3Mjoge2w6IHsweDYzOiB7bDogezB4M0I6IHtjOiBbMzc1XX19fX19fX0sIDB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDk5XX19fX19LCAweDY1OiB7bDogezB4NkU6IHtsOiB7MHgzQjoge2M6IFsxNjVdfX0sIGM6IFsxNjVdfX19LCAweDY2OiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFsxMjAxMThdfX19fX0sIDB4Njk6IHtsOiB7MHg2Mzoge2w6IHsweDc5OiB7bDogezB4M0I6IHtjOiBbMTExMV19fX19fX19LCAweDZGOiB7bDogezB4NzA6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzEyMDE3MF19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzEyMDAxNF19fX19fX19LCAweDc1OiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzExMDJdfX19fX0sIDB4NkQ6IHtsOiB7MHg2Qzoge2w6IHsweDNCOiB7YzogWzI1NV19fSwgYzogWzI1NV19fX19fX19LFxyXG4gICAgMHg1QToge2w6IHsweDYxOiB7bDogezB4NjM6IHtsOiB7MHg3NToge2w6IHsweDc0OiB7bDogezB4NjU6IHtsOiB7MHgzQjoge2M6IFszNzddfX19fX19fX19fX0sIDB4NjM6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NkY6IHtsOiB7MHg2RToge2w6IHsweDNCOiB7YzogWzM4MV19fX19fX19fX0sIDB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDQ3XX19fX19LCAweDY0OiB7bDogezB4NkY6IHtsOiB7MHg3NDoge2w6IHsweDNCOiB7YzogWzM3OV19fX19fX19LCAweDY1OiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDU3OiB7bDogezB4Njk6IHtsOiB7MHg2NDoge2w6IHsweDc0OiB7bDogezB4Njg6IHtsOiB7MHg1Mzoge2w6IHsweDcwOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDY1OiB7bDogezB4M0I6IHtjOiBbODIwM119fX19fX19fX19fX19fX19fX19fX19fX19LCAweDc0OiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs5MThdfX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbODQ4OF19fX19fSwgMHg0ODoge2w6IHsweDYzOiB7bDogezB4Nzk6IHtsOiB7MHgzQjoge2M6IFsxMDQ2XX19fX19fX0sIDB4NkY6IHtsOiB7MHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbODQ4NF19fX19fX19LCAweDczOiB7bDogezB4NjM6IHtsOiB7MHg3Mjoge2w6IHsweDNCOiB7YzogWzExOTk4OV19fX19fX19fX0sXHJcbiAgICAweDdBOiB7bDogezB4NjE6IHtsOiB7MHg2Mzoge2w6IHsweDc1OiB7bDogezB4NzQ6IHtsOiB7MHg2NToge2w6IHsweDNCOiB7YzogWzM3OF19fX19fX19fX19fSwgMHg2Mzoge2w6IHsweDYxOiB7bDogezB4NzI6IHtsOiB7MHg2Rjoge2w6IHsweDZFOiB7bDogezB4M0I6IHtjOiBbMzgyXX19fX19fX19fSwgMHg3OToge2w6IHsweDNCOiB7YzogWzEwNzldfX19fX0sIDB4NjQ6IHtsOiB7MHg2Rjoge2w6IHsweDc0OiB7bDogezB4M0I6IHtjOiBbMzgwXX19fX19fX0sIDB4NjU6IHtsOiB7MHg2NToge2w6IHsweDc0OiB7bDogezB4NzI6IHtsOiB7MHg2Njoge2w6IHsweDNCOiB7YzogWzg0ODhdfX19fX19fX19LCAweDc0OiB7bDogezB4NjE6IHtsOiB7MHgzQjoge2M6IFs5NTBdfX19fX19fSwgMHg2Njoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMTE5XX19fX19LCAweDY4OiB7bDogezB4NjM6IHtsOiB7MHg3OToge2w6IHsweDNCOiB7YzogWzEwNzhdfX19fX19fSwgMHg2OToge2w6IHsweDY3OiB7bDogezB4NzI6IHtsOiB7MHg2MToge2w6IHsweDcyOiB7bDogezB4NzI6IHtsOiB7MHgzQjoge2M6IFs4NjY5XX19fX19fX19fX19fX0sIDB4NkY6IHtsOiB7MHg3MDoge2w6IHsweDY2OiB7bDogezB4M0I6IHtjOiBbMTIwMTcxXX19fX19fX0sIDB4NzM6IHtsOiB7MHg2Mzoge2w6IHsweDcyOiB7bDogezB4M0I6IHtjOiBbMTIwMDE1XX19fX19fX0sIDB4Nzc6IHtsOiB7MHg2QToge2w6IHsweDNCOiB7YzogWzgyMDVdfX19LCAweDZFOiB7bDogezB4NkE6IHtsOiB7MHgzQjoge2M6IFs4MjA0XX19fX19fX19fVxyXG59OyIsIid1c2Ugc3RyaWN0JztcblxudmFyIFVOSUNPREUgPSByZXF1aXJlKCcuLi9jb21tb24vdW5pY29kZScpO1xuXG4vL0FsaWFzZXNcbnZhciAkID0gVU5JQ09ERS5DT0RFX1BPSU5UUztcblxuLy9VdGlsc1xuXG4vL09QVElNSVpBVElPTjogdGhlc2UgdXRpbGl0eSBmdW5jdGlvbnMgc2hvdWxkIG5vdCBiZSBtb3ZlZCBvdXQgb2YgdGhpcyBtb2R1bGUuIFY4IENyYW5rc2hhZnQgd2lsbCBub3QgaW5saW5lXG4vL3RoaXMgZnVuY3Rpb25zIGlmIHRoZXkgd2lsbCBiZSBzaXR1YXRlZCBpbiBhbm90aGVyIG1vZHVsZSBkdWUgdG8gY29udGV4dCBzd2l0Y2guXG4vL0Fsd2F5cyBwZXJmb3JtIGlubGluaW5nIGNoZWNrIGJlZm9yZSBtb2RpZnlpbmcgdGhpcyBmdW5jdGlvbnMgKCdub2RlIC0tdHJhY2UtaW5saW5pbmcnKS5cbmZ1bmN0aW9uIGlzUmVzZXJ2ZWRDb2RlUG9pbnQoY3ApIHtcbiAgICByZXR1cm4gY3AgPj0gMHhEODAwICYmIGNwIDw9IDB4REZGRiB8fCBjcCA+IDB4MTBGRkZGO1xufVxuXG5mdW5jdGlvbiBpc1N1cnJvZ2F0ZVBhaXIoY3AxLCBjcDIpIHtcbiAgICByZXR1cm4gY3AxID49IDB4RDgwMCAmJiBjcDEgPD0gMHhEQkZGICYmIGNwMiA+PSAweERDMDAgJiYgY3AyIDw9IDB4REZGRjtcbn1cblxuZnVuY3Rpb24gZ2V0U3Vycm9nYXRlUGFpckNvZGVQb2ludChjcDEsIGNwMikge1xuICAgIHJldHVybiAoY3AxIC0gMHhEODAwKSAqIDB4NDAwICsgMHgyNDAwICsgY3AyO1xufVxuXG4vL1ByZXByb2Nlc3NvclxuLy9OT1RFOiBIVE1MIGlucHV0IHByZXByb2Nlc3Npbmdcbi8vKHNlZTogaHR0cDovL3d3dy53aGF0d2cub3JnL3NwZWNzL3dlYi1hcHBzL2N1cnJlbnQtd29yay9tdWx0aXBhZ2UvcGFyc2luZy5odG1sI3ByZXByb2Nlc3NpbmctdGhlLWlucHV0LXN0cmVhbSlcbnZhciBQcmVwcm9jZXNzb3IgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChodG1sKSB7XG4gICAgdGhpcy53cml0ZShodG1sKTtcblxuICAgIC8vTk9URTogb25lIGxlYWRpbmcgVStGRUZGIEJZVEUgT1JERVIgTUFSSyBjaGFyYWN0ZXIgbXVzdCBiZSBpZ25vcmVkIGlmIGFueSBhcmUgcHJlc2VudCBpbiB0aGUgaW5wdXQgc3RyZWFtLlxuICAgIHRoaXMucG9zID0gdGhpcy5odG1sLmNoYXJDb2RlQXQoMCkgPT09ICQuQk9NID8gMCA6IC0xO1xuXG4gICAgdGhpcy5nYXBTdGFjayA9IFtdO1xuICAgIHRoaXMubGFzdEdhcFBvcyA9IC0xO1xuICAgIHRoaXMuc2tpcE5leHROZXdMaW5lID0gZmFsc2U7XG59O1xuXG5QcmVwcm9jZXNzb3IucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKGh0bWwpIHtcbiAgICBpZiAodGhpcy5odG1sKSB7XG4gICAgICAgIHRoaXMuaHRtbCA9IHRoaXMuaHRtbC5zdWJzdHJpbmcoMCwgdGhpcy5wb3MgKyAxKSArXG4gICAgICAgICAgICAgICAgICAgIGh0bWwgK1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmh0bWwuc3Vic3RyaW5nKHRoaXMucG9zICsgMSwgdGhpcy5odG1sLmxlbmd0aCk7XG5cbiAgICB9XG4gICAgZWxzZVxuICAgICAgICB0aGlzLmh0bWwgPSBodG1sO1xuXG5cbiAgICB0aGlzLmxhc3RDaGFyUG9zID0gdGhpcy5odG1sLmxlbmd0aCAtIDE7XG59O1xuXG5QcmVwcm9jZXNzb3IucHJvdG90eXBlLmFkdmFuY2VBbmRQZWVrQ29kZVBvaW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucG9zKys7XG5cbiAgICBpZiAodGhpcy5wb3MgPiB0aGlzLmxhc3RDaGFyUG9zKVxuICAgICAgICByZXR1cm4gJC5FT0Y7XG5cbiAgICB2YXIgY3AgPSB0aGlzLmh0bWwuY2hhckNvZGVBdCh0aGlzLnBvcyk7XG5cbiAgICAvL05PVEU6IGFueSBVKzAwMEEgTElORSBGRUVEIChMRikgY2hhcmFjdGVycyB0aGF0IGltbWVkaWF0ZWx5IGZvbGxvdyBhIFUrMDAwRCBDQVJSSUFHRSBSRVRVUk4gKENSKSBjaGFyYWN0ZXJcbiAgICAvL211c3QgYmUgaWdub3JlZC5cbiAgICBpZiAodGhpcy5za2lwTmV4dE5ld0xpbmUgJiYgY3AgPT09ICQuTElORV9GRUVEKSB7XG4gICAgICAgIHRoaXMuc2tpcE5leHROZXdMaW5lID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX2FkZEdhcCgpO1xuICAgICAgICByZXR1cm4gdGhpcy5hZHZhbmNlQW5kUGVla0NvZGVQb2ludCgpO1xuICAgIH1cblxuICAgIC8vTk9URTogYWxsIFUrMDAwRCBDQVJSSUFHRSBSRVRVUk4gKENSKSBjaGFyYWN0ZXJzIG11c3QgYmUgY29udmVydGVkIHRvIFUrMDAwQSBMSU5FIEZFRUQgKExGKSBjaGFyYWN0ZXJzXG4gICAgaWYgKGNwID09PSAkLkNBUlJJQUdFX1JFVFVSTikge1xuICAgICAgICB0aGlzLnNraXBOZXh0TmV3TGluZSA9IHRydWU7XG4gICAgICAgIHJldHVybiAkLkxJTkVfRkVFRDtcbiAgICB9XG5cbiAgICB0aGlzLnNraXBOZXh0TmV3TGluZSA9IGZhbHNlO1xuXG4gICAgLy9PUFRJTUlaQVRJT046IGZpcnN0IHBlcmZvcm0gY2hlY2sgaWYgdGhlIGNvZGUgcG9pbnQgaW4gdGhlIGFsbG93ZWQgcmFuZ2UgdGhhdCBjb3ZlcnMgbW9zdCBjb21tb25cbiAgICAvL0hUTUwgaW5wdXQgKGUuZy4gQVNDSUkgY29kZXMpIHRvIGF2b2lkIHBlcmZvcm1hbmNlLWNvc3Qgb3BlcmF0aW9ucyBmb3IgaGlnaC1yYW5nZSBjb2RlIHBvaW50cy5cbiAgICByZXR1cm4gY3AgPj0gMHhEODAwID8gdGhpcy5fcHJvY2Vzc0hpZ2hSYW5nZUNvZGVQb2ludChjcCkgOiBjcDtcbn07XG5cblByZXByb2Nlc3Nvci5wcm90b3R5cGUuX3Byb2Nlc3NIaWdoUmFuZ2VDb2RlUG9pbnQgPSBmdW5jdGlvbiAoY3ApIHtcbiAgICAvL05PVEU6IHRyeSB0byBwZWVrIGEgc3Vycm9nYXRlIHBhaXJcbiAgICBpZiAodGhpcy5wb3MgIT09IHRoaXMubGFzdENoYXJQb3MpIHtcbiAgICAgICAgdmFyIG5leHRDcCA9IHRoaXMuaHRtbC5jaGFyQ29kZUF0KHRoaXMucG9zICsgMSk7XG5cbiAgICAgICAgaWYgKGlzU3Vycm9nYXRlUGFpcihjcCwgbmV4dENwKSkge1xuICAgICAgICAgICAgLy9OT1RFOiB3ZSBoYXZlIGEgc3Vycm9nYXRlIHBhaXIuIFBlZWsgcGFpciBjaGFyYWN0ZXIgYW5kIHJlY2FsY3VsYXRlIGNvZGUgcG9pbnQuXG4gICAgICAgICAgICB0aGlzLnBvcysrO1xuICAgICAgICAgICAgY3AgPSBnZXRTdXJyb2dhdGVQYWlyQ29kZVBvaW50KGNwLCBuZXh0Q3ApO1xuXG4gICAgICAgICAgICAvL05PVEU6IGFkZCBnYXAgdGhhdCBzaG91bGQgYmUgYXZvaWRlZCBkdXJpbmcgcmV0cmVhdFxuICAgICAgICAgICAgdGhpcy5fYWRkR2FwKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNSZXNlcnZlZENvZGVQb2ludChjcCkpXG4gICAgICAgIGNwID0gJC5SRVBMQUNFTUVOVF9DSEFSQUNURVI7XG5cbiAgICByZXR1cm4gY3A7XG59O1xuXG5QcmVwcm9jZXNzb3IucHJvdG90eXBlLl9hZGRHYXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5nYXBTdGFjay5wdXNoKHRoaXMubGFzdEdhcFBvcyk7XG4gICAgdGhpcy5sYXN0R2FwUG9zID0gdGhpcy5wb3M7XG59O1xuXG5QcmVwcm9jZXNzb3IucHJvdG90eXBlLnJldHJlYXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMucG9zID09PSB0aGlzLmxhc3RHYXBQb3MpIHtcbiAgICAgICAgdGhpcy5sYXN0R2FwUG9zID0gdGhpcy5nYXBTdGFjay5wb3AoKTtcbiAgICAgICAgdGhpcy5wb3MtLTtcbiAgICB9XG5cbiAgICB0aGlzLnBvcy0tO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBQcmVwcm9jZXNzb3IgPSByZXF1aXJlKCcuL3ByZXByb2Nlc3NvcicpLFxyXG4gICAgTG9jYXRpb25JbmZvTWl4aW4gPSByZXF1aXJlKCcuL2xvY2F0aW9uX2luZm9fbWl4aW4nKSxcclxuICAgIFVOSUNPREUgPSByZXF1aXJlKCcuLi9jb21tb24vdW5pY29kZScpLFxyXG4gICAgTkFNRURfRU5USVRZX1RSSUUgPSByZXF1aXJlKCcuL25hbWVkX2VudGl0eV90cmllJyk7XHJcblxyXG4vL0FsaWFzZXNcclxudmFyICQgPSBVTklDT0RFLkNPREVfUE9JTlRTLFxyXG4gICAgJCQgPSBVTklDT0RFLkNPREVfUE9JTlRfU0VRVUVOQ0VTO1xyXG5cclxuLy9SZXBsYWNlbWVudCBjb2RlIHBvaW50cyBmb3IgbnVtZXJpYyBlbnRpdGllc1xyXG52YXIgTlVNRVJJQ19FTlRJVFlfUkVQTEFDRU1FTlRTID0ge1xyXG4gICAgMHgwMDogMHhGRkZELCAweDBEOiAweDAwMEQsIDB4ODA6IDB4MjBBQywgMHg4MTogMHgwMDgxLCAweDgyOiAweDIwMUEsIDB4ODM6IDB4MDE5MiwgMHg4NDogMHgyMDFFLFxyXG4gICAgMHg4NTogMHgyMDI2LCAweDg2OiAweDIwMjAsIDB4ODc6IDB4MjAyMSwgMHg4ODogMHgwMkM2LCAweDg5OiAweDIwMzAsIDB4OEE6IDB4MDE2MCwgMHg4QjogMHgyMDM5LFxyXG4gICAgMHg4QzogMHgwMTUyLCAweDhEOiAweDAwOEQsIDB4OEU6IDB4MDE3RCwgMHg4RjogMHgwMDhGLCAweDkwOiAweDAwOTAsIDB4OTE6IDB4MjAxOCwgMHg5MjogMHgyMDE5LFxyXG4gICAgMHg5MzogMHgyMDFDLCAweDk0OiAweDIwMUQsIDB4OTU6IDB4MjAyMiwgMHg5NjogMHgyMDEzLCAweDk3OiAweDIwMTQsIDB4OTg6IDB4MDJEQywgMHg5OTogMHgyMTIyLFxyXG4gICAgMHg5QTogMHgwMTYxLCAweDlCOiAweDIwM0EsIDB4OUM6IDB4MDE1MywgMHg5RDogMHgwMDlELCAweDlFOiAweDAxN0UsIDB4OUY6IDB4MDE3OFxyXG59O1xyXG5cclxuLy9TdGF0ZXNcclxudmFyIERBVEFfU1RBVEUgPSAnREFUQV9TVEFURScsXHJcbiAgICBDSEFSQUNURVJfUkVGRVJFTkNFX0lOX0RBVEFfU1RBVEUgPSAnQ0hBUkFDVEVSX1JFRkVSRU5DRV9JTl9EQVRBX1NUQVRFJyxcclxuICAgIFJDREFUQV9TVEFURSA9ICdSQ0RBVEFfU1RBVEUnLFxyXG4gICAgQ0hBUkFDVEVSX1JFRkVSRU5DRV9JTl9SQ0RBVEFfU1RBVEUgPSAnQ0hBUkFDVEVSX1JFRkVSRU5DRV9JTl9SQ0RBVEFfU1RBVEUnLFxyXG4gICAgUkFXVEVYVF9TVEFURSA9ICdSQVdURVhUX1NUQVRFJyxcclxuICAgIFNDUklQVF9EQVRBX1NUQVRFID0gJ1NDUklQVF9EQVRBX1NUQVRFJyxcclxuICAgIFBMQUlOVEVYVF9TVEFURSA9ICdQTEFJTlRFWFRfU1RBVEUnLFxyXG4gICAgVEFHX09QRU5fU1RBVEUgPSAnVEFHX09QRU5fU1RBVEUnLFxyXG4gICAgRU5EX1RBR19PUEVOX1NUQVRFID0gJ0VORF9UQUdfT1BFTl9TVEFURScsXHJcbiAgICBUQUdfTkFNRV9TVEFURSA9ICdUQUdfTkFNRV9TVEFURScsXHJcbiAgICBSQ0RBVEFfTEVTU19USEFOX1NJR05fU1RBVEUgPSAnUkNEQVRBX0xFU1NfVEhBTl9TSUdOX1NUQVRFJyxcclxuICAgIFJDREFUQV9FTkRfVEFHX09QRU5fU1RBVEUgPSAnUkNEQVRBX0VORF9UQUdfT1BFTl9TVEFURScsXHJcbiAgICBSQ0RBVEFfRU5EX1RBR19OQU1FX1NUQVRFID0gJ1JDREFUQV9FTkRfVEFHX05BTUVfU1RBVEUnLFxyXG4gICAgUkFXVEVYVF9MRVNTX1RIQU5fU0lHTl9TVEFURSA9ICdSQVdURVhUX0xFU1NfVEhBTl9TSUdOX1NUQVRFJyxcclxuICAgIFJBV1RFWFRfRU5EX1RBR19PUEVOX1NUQVRFID0gJ1JBV1RFWFRfRU5EX1RBR19PUEVOX1NUQVRFJyxcclxuICAgIFJBV1RFWFRfRU5EX1RBR19OQU1FX1NUQVRFID0gJ1JBV1RFWFRfRU5EX1RBR19OQU1FX1NUQVRFJyxcclxuICAgIFNDUklQVF9EQVRBX0xFU1NfVEhBTl9TSUdOX1NUQVRFID0gJ1NDUklQVF9EQVRBX0xFU1NfVEhBTl9TSUdOX1NUQVRFJyxcclxuICAgIFNDUklQVF9EQVRBX0VORF9UQUdfT1BFTl9TVEFURSA9ICdTQ1JJUFRfREFUQV9FTkRfVEFHX09QRU5fU1RBVEUnLFxyXG4gICAgU0NSSVBUX0RBVEFfRU5EX1RBR19OQU1FX1NUQVRFID0gJ1NDUklQVF9EQVRBX0VORF9UQUdfTkFNRV9TVEFURScsXHJcbiAgICBTQ1JJUFRfREFUQV9FU0NBUEVfU1RBUlRfU1RBVEUgPSAnU0NSSVBUX0RBVEFfRVNDQVBFX1NUQVJUX1NUQVRFJyxcclxuICAgIFNDUklQVF9EQVRBX0VTQ0FQRV9TVEFSVF9EQVNIX1NUQVRFID0gJ1NDUklQVF9EQVRBX0VTQ0FQRV9TVEFSVF9EQVNIX1NUQVRFJyxcclxuICAgIFNDUklQVF9EQVRBX0VTQ0FQRURfU1RBVEUgPSAnU0NSSVBUX0RBVEFfRVNDQVBFRF9TVEFURScsXHJcbiAgICBTQ1JJUFRfREFUQV9FU0NBUEVEX0RBU0hfU1RBVEUgPSAnU0NSSVBUX0RBVEFfRVNDQVBFRF9EQVNIX1NUQVRFJyxcclxuICAgIFNDUklQVF9EQVRBX0VTQ0FQRURfREFTSF9EQVNIX1NUQVRFID0gJ1NDUklQVF9EQVRBX0VTQ0FQRURfREFTSF9EQVNIX1NUQVRFJyxcclxuICAgIFNDUklQVF9EQVRBX0VTQ0FQRURfTEVTU19USEFOX1NJR05fU1RBVEUgPSAnU0NSSVBUX0RBVEFfRVNDQVBFRF9MRVNTX1RIQU5fU0lHTl9TVEFURScsXHJcbiAgICBTQ1JJUFRfREFUQV9FU0NBUEVEX0VORF9UQUdfT1BFTl9TVEFURSA9ICdTQ1JJUFRfREFUQV9FU0NBUEVEX0VORF9UQUdfT1BFTl9TVEFURScsXHJcbiAgICBTQ1JJUFRfREFUQV9FU0NBUEVEX0VORF9UQUdfTkFNRV9TVEFURSA9ICdTQ1JJUFRfREFUQV9FU0NBUEVEX0VORF9UQUdfTkFNRV9TVEFURScsXHJcbiAgICBTQ1JJUFRfREFUQV9ET1VCTEVfRVNDQVBFX1NUQVJUX1NUQVRFID0gJ1NDUklQVF9EQVRBX0RPVUJMRV9FU0NBUEVfU1RBUlRfU1RBVEUnLFxyXG4gICAgU0NSSVBUX0RBVEFfRE9VQkxFX0VTQ0FQRURfU1RBVEUgPSAnU0NSSVBUX0RBVEFfRE9VQkxFX0VTQ0FQRURfU1RBVEUnLFxyXG4gICAgU0NSSVBUX0RBVEFfRE9VQkxFX0VTQ0FQRURfREFTSF9TVEFURSA9ICdTQ1JJUFRfREFUQV9ET1VCTEVfRVNDQVBFRF9EQVNIX1NUQVRFJyxcclxuICAgIFNDUklQVF9EQVRBX0RPVUJMRV9FU0NBUEVEX0RBU0hfREFTSF9TVEFURSA9ICdTQ1JJUFRfREFUQV9ET1VCTEVfRVNDQVBFRF9EQVNIX0RBU0hfU1RBVEUnLFxyXG4gICAgU0NSSVBUX0RBVEFfRE9VQkxFX0VTQ0FQRURfTEVTU19USEFOX1NJR05fU1RBVEUgPSAnU0NSSVBUX0RBVEFfRE9VQkxFX0VTQ0FQRURfTEVTU19USEFOX1NJR05fU1RBVEUnLFxyXG4gICAgU0NSSVBUX0RBVEFfRE9VQkxFX0VTQ0FQRV9FTkRfU1RBVEUgPSAnU0NSSVBUX0RBVEFfRE9VQkxFX0VTQ0FQRV9FTkRfU1RBVEUnLFxyXG4gICAgQkVGT1JFX0FUVFJJQlVURV9OQU1FX1NUQVRFID0gJ0JFRk9SRV9BVFRSSUJVVEVfTkFNRV9TVEFURScsXHJcbiAgICBBVFRSSUJVVEVfTkFNRV9TVEFURSA9ICdBVFRSSUJVVEVfTkFNRV9TVEFURScsXHJcbiAgICBBRlRFUl9BVFRSSUJVVEVfTkFNRV9TVEFURSA9ICdBRlRFUl9BVFRSSUJVVEVfTkFNRV9TVEFURScsXHJcbiAgICBCRUZPUkVfQVRUUklCVVRFX1ZBTFVFX1NUQVRFID0gJ0JFRk9SRV9BVFRSSUJVVEVfVkFMVUVfU1RBVEUnLFxyXG4gICAgQVRUUklCVVRFX1ZBTFVFX0RPVUJMRV9RVU9URURfU1RBVEUgPSAnQVRUUklCVVRFX1ZBTFVFX0RPVUJMRV9RVU9URURfU1RBVEUnLFxyXG4gICAgQVRUUklCVVRFX1ZBTFVFX1NJTkdMRV9RVU9URURfU1RBVEUgPSAnQVRUUklCVVRFX1ZBTFVFX1NJTkdMRV9RVU9URURfU1RBVEUnLFxyXG4gICAgQVRUUklCVVRFX1ZBTFVFX1VOUVVPVEVEX1NUQVRFID0gJ0FUVFJJQlVURV9WQUxVRV9VTlFVT1RFRF9TVEFURScsXHJcbiAgICBDSEFSQUNURVJfUkVGRVJFTkNFX0lOX0FUVFJJQlVURV9WQUxVRV9TVEFURSA9ICdDSEFSQUNURVJfUkVGRVJFTkNFX0lOX0FUVFJJQlVURV9WQUxVRV9TVEFURScsXHJcbiAgICBBRlRFUl9BVFRSSUJVVEVfVkFMVUVfUVVPVEVEX1NUQVRFID0gJ0FGVEVSX0FUVFJJQlVURV9WQUxVRV9RVU9URURfU1RBVEUnLFxyXG4gICAgU0VMRl9DTE9TSU5HX1NUQVJUX1RBR19TVEFURSA9ICdTRUxGX0NMT1NJTkdfU1RBUlRfVEFHX1NUQVRFJyxcclxuICAgIEJPR1VTX0NPTU1FTlRfU1RBVEUgPSAnQk9HVVNfQ09NTUVOVF9TVEFURScsXHJcbiAgICBNQVJLVVBfREVDTEFSQVRJT05fT1BFTl9TVEFURSA9ICdNQVJLVVBfREVDTEFSQVRJT05fT1BFTl9TVEFURScsXHJcbiAgICBDT01NRU5UX1NUQVJUX1NUQVRFID0gJ0NPTU1FTlRfU1RBUlRfU1RBVEUnLFxyXG4gICAgQ09NTUVOVF9TVEFSVF9EQVNIX1NUQVRFID0gJ0NPTU1FTlRfU1RBUlRfREFTSF9TVEFURScsXHJcbiAgICBDT01NRU5UX1NUQVRFID0gJ0NPTU1FTlRfU1RBVEUnLFxyXG4gICAgQ09NTUVOVF9FTkRfREFTSF9TVEFURSA9ICdDT01NRU5UX0VORF9EQVNIX1NUQVRFJyxcclxuICAgIENPTU1FTlRfRU5EX1NUQVRFID0gJ0NPTU1FTlRfRU5EX1NUQVRFJyxcclxuICAgIENPTU1FTlRfRU5EX0JBTkdfU1RBVEUgPSAnQ09NTUVOVF9FTkRfQkFOR19TVEFURScsXHJcbiAgICBET0NUWVBFX1NUQVRFID0gJ0RPQ1RZUEVfU1RBVEUnLFxyXG4gICAgQkVGT1JFX0RPQ1RZUEVfTkFNRV9TVEFURSA9ICdCRUZPUkVfRE9DVFlQRV9OQU1FX1NUQVRFJyxcclxuICAgIERPQ1RZUEVfTkFNRV9TVEFURSA9ICdET0NUWVBFX05BTUVfU1RBVEUnLFxyXG4gICAgQUZURVJfRE9DVFlQRV9OQU1FX1NUQVRFID0gJ0FGVEVSX0RPQ1RZUEVfTkFNRV9TVEFURScsXHJcbiAgICBBRlRFUl9ET0NUWVBFX1BVQkxJQ19LRVlXT1JEX1NUQVRFID0gJ0FGVEVSX0RPQ1RZUEVfUFVCTElDX0tFWVdPUkRfU1RBVEUnLFxyXG4gICAgQkVGT1JFX0RPQ1RZUEVfUFVCTElDX0lERU5USUZJRVJfU1RBVEUgPSAnQkVGT1JFX0RPQ1RZUEVfUFVCTElDX0lERU5USUZJRVJfU1RBVEUnLFxyXG4gICAgRE9DVFlQRV9QVUJMSUNfSURFTlRJRklFUl9ET1VCTEVfUVVPVEVEX1NUQVRFID0gJ0RPQ1RZUEVfUFVCTElDX0lERU5USUZJRVJfRE9VQkxFX1FVT1RFRF9TVEFURScsXHJcbiAgICBET0NUWVBFX1BVQkxJQ19JREVOVElGSUVSX1NJTkdMRV9RVU9URURfU1RBVEUgPSAnRE9DVFlQRV9QVUJMSUNfSURFTlRJRklFUl9TSU5HTEVfUVVPVEVEX1NUQVRFJyxcclxuICAgIEFGVEVSX0RPQ1RZUEVfUFVCTElDX0lERU5USUZJRVJfU1RBVEUgPSAnQUZURVJfRE9DVFlQRV9QVUJMSUNfSURFTlRJRklFUl9TVEFURScsXHJcbiAgICBCRVRXRUVOX0RPQ1RZUEVfUFVCTElDX0FORF9TWVNURU1fSURFTlRJRklFUlNfU1RBVEUgPSAnQkVUV0VFTl9ET0NUWVBFX1BVQkxJQ19BTkRfU1lTVEVNX0lERU5USUZJRVJTX1NUQVRFJyxcclxuICAgIEFGVEVSX0RPQ1RZUEVfU1lTVEVNX0tFWVdPUkRfU1RBVEUgPSAnQUZURVJfRE9DVFlQRV9TWVNURU1fS0VZV09SRF9TVEFURScsXHJcbiAgICBCRUZPUkVfRE9DVFlQRV9TWVNURU1fSURFTlRJRklFUl9TVEFURSA9ICdCRUZPUkVfRE9DVFlQRV9TWVNURU1fSURFTlRJRklFUl9TVEFURScsXHJcbiAgICBET0NUWVBFX1NZU1RFTV9JREVOVElGSUVSX0RPVUJMRV9RVU9URURfU1RBVEUgPSAnRE9DVFlQRV9TWVNURU1fSURFTlRJRklFUl9ET1VCTEVfUVVPVEVEX1NUQVRFJyxcclxuICAgIERPQ1RZUEVfU1lTVEVNX0lERU5USUZJRVJfU0lOR0xFX1FVT1RFRF9TVEFURSA9ICdET0NUWVBFX1NZU1RFTV9JREVOVElGSUVSX1NJTkdMRV9RVU9URURfU1RBVEUnLFxyXG4gICAgQUZURVJfRE9DVFlQRV9TWVNURU1fSURFTlRJRklFUl9TVEFURSA9ICdBRlRFUl9ET0NUWVBFX1NZU1RFTV9JREVOVElGSUVSX1NUQVRFJyxcclxuICAgIEJPR1VTX0RPQ1RZUEVfU1RBVEUgPSAnQk9HVVNfRE9DVFlQRV9TVEFURScsXHJcbiAgICBDREFUQV9TRUNUSU9OX1NUQVRFID0gJ0NEQVRBX1NFQ1RJT05fU1RBVEUnO1xyXG5cclxuLy9VdGlsc1xyXG5cclxuLy9PUFRJTUlaQVRJT046IHRoZXNlIHV0aWxpdHkgZnVuY3Rpb25zIHNob3VsZCBub3QgYmUgbW92ZWQgb3V0IG9mIHRoaXMgbW9kdWxlLiBWOCBDcmFua3NoYWZ0IHdpbGwgbm90IGlubGluZVxyXG4vL3RoaXMgZnVuY3Rpb25zIGlmIHRoZXkgd2lsbCBiZSBzaXR1YXRlZCBpbiBhbm90aGVyIG1vZHVsZSBkdWUgdG8gY29udGV4dCBzd2l0Y2guXHJcbi8vQWx3YXlzIHBlcmZvcm0gaW5saW5pbmcgY2hlY2sgYmVmb3JlIG1vZGlmeWluZyB0aGlzIGZ1bmN0aW9ucyAoJ25vZGUgLS10cmFjZS1pbmxpbmluZycpLlxyXG5mdW5jdGlvbiBpc1doaXRlc3BhY2UoY3ApIHtcclxuICAgIHJldHVybiBjcCA9PT0gJC5TUEFDRSB8fCBjcCA9PT0gJC5MSU5FX0ZFRUQgfHwgY3AgPT09ICQuVEFCVUxBVElPTiB8fCBjcCA9PT0gJC5GT1JNX0ZFRUQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzQXNjaWlEaWdpdChjcCkge1xyXG4gICAgcmV0dXJuIGNwID49ICQuRElHSVRfMCAmJiBjcCA8PSAkLkRJR0lUXzk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzQXNjaWlVcHBlcihjcCkge1xyXG4gICAgcmV0dXJuIGNwID49ICQuTEFUSU5fQ0FQSVRBTF9BICYmIGNwIDw9ICQuTEFUSU5fQ0FQSVRBTF9aO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0FzY2lpTG93ZXIoY3ApIHtcclxuICAgIHJldHVybiBjcCA+PSAkLkxBVElOX1NNQUxMX0EgJiYgY3AgPD0gJC5MQVRJTl9TTUFMTF9aO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0FzY2lpQWxwaGFOdW1lcmljKGNwKSB7XHJcbiAgICByZXR1cm4gaXNBc2NpaURpZ2l0KGNwKSB8fCBpc0FzY2lpVXBwZXIoY3ApIHx8IGlzQXNjaWlMb3dlcihjcCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzRGlnaXQoY3AsIGlzSGV4KSB7XHJcbiAgICByZXR1cm4gaXNBc2NpaURpZ2l0KGNwKSB8fCAoaXNIZXggJiYgKChjcCA+PSAkLkxBVElOX0NBUElUQUxfQSAmJiBjcCA8PSAkLkxBVElOX0NBUElUQUxfRikgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNwID49ICQuTEFUSU5fU01BTExfQSAmJiBjcCA8PSAkLkxBVElOX1NNQUxMX0YpKSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzUmVzZXJ2ZWRDb2RlUG9pbnQoY3ApIHtcclxuICAgIHJldHVybiBjcCA+PSAweEQ4MDAgJiYgY3AgPD0gMHhERkZGIHx8IGNwID4gMHgxMEZGRkY7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHRvQXNjaWlMb3dlckNvZGVQb2ludChjcCkge1xyXG4gICAgcmV0dXJuIGNwICsgMHgwMDIwO1xyXG59XHJcblxyXG4vL05PVEU6IFN0cmluZy5mcm9tQ2hhckNvZGUoKSBmdW5jdGlvbiBjYW4gaGFuZGxlIG9ubHkgY2hhcmFjdGVycyBmcm9tIEJNUCBzdWJzZXQuXHJcbi8vU28sIHdlIG5lZWQgdG8gd29ya2Fyb3VuZCB0aGlzIG1hbnVhbGx5LlxyXG4vLyhzZWU6IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvU3RyaW5nL2Zyb21DaGFyQ29kZSNHZXR0aW5nX2l0X3RvX3dvcmtfd2l0aF9oaWdoZXJfdmFsdWVzKVxyXG5mdW5jdGlvbiB0b0NoYXIoY3ApIHtcclxuICAgIGlmIChjcCA8PSAweEZGRkYpXHJcbiAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoY3ApO1xyXG5cclxuICAgIGNwIC09IDB4MTAwMDA7XHJcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShjcCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMCkgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4REMwMCB8IGNwICYgMHgzRkYpO1xyXG59XHJcblxyXG5mdW5jdGlvbiB0b0FzY2lpTG93ZXJDaGFyKGNwKSB7XHJcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSh0b0FzY2lpTG93ZXJDb2RlUG9pbnQoY3ApKTtcclxufVxyXG5cclxuLy9Ub2tlbml6ZXJcclxudmFyIFRva2VuaXplciA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGh0bWwsIG9wdGlvbnMpIHtcclxuICAgIHRoaXMuZGlzYWJsZUVudGl0aWVzRGVjb2RpbmcgPSBmYWxzZTtcclxuXHJcbiAgICB0aGlzLnByZXByb2Nlc3NvciA9IG5ldyBQcmVwcm9jZXNzb3IoaHRtbCk7XHJcblxyXG4gICAgdGhpcy50b2tlblF1ZXVlID0gW107XHJcblxyXG4gICAgdGhpcy5hbGxvd0NEQVRBID0gZmFsc2U7XHJcblxyXG4gICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICB0aGlzLnJldHVyblN0YXRlID0gJyc7XHJcblxyXG4gICAgdGhpcy5jb25zdW1wdGlvblBvcyA9IDA7XHJcblxyXG4gICAgdGhpcy50ZW1wQnVmZiA9IFtdO1xyXG4gICAgdGhpcy5hZGRpdGlvbmFsQWxsb3dlZENwID0gdm9pZCAwO1xyXG4gICAgdGhpcy5sYXN0U3RhcnRUYWdOYW1lID0gJyc7XHJcblxyXG4gICAgdGhpcy5jdXJyZW50Q2hhcmFjdGVyVG9rZW4gPSBudWxsO1xyXG4gICAgdGhpcy5jdXJyZW50VG9rZW4gPSBudWxsO1xyXG4gICAgdGhpcy5jdXJyZW50QXR0ciA9IG51bGw7XHJcblxyXG4gICAgaWYgKG9wdGlvbnMpIHtcclxuICAgICAgICB0aGlzLmRpc2FibGVFbnRpdGllc0RlY29kaW5nID0gIW9wdGlvbnMuZGVjb2RlSHRtbEVudGl0aWVzO1xyXG5cclxuICAgICAgICBpZiAob3B0aW9ucy5sb2NhdGlvbkluZm8pXHJcbiAgICAgICAgICAgIExvY2F0aW9uSW5mb01peGluLmFzc2lnbih0aGlzKTtcclxuICAgIH1cclxufTtcclxuXHJcbi8vVG9rZW4gdHlwZXNcclxuVG9rZW5pemVyLkNIQVJBQ1RFUl9UT0tFTiA9ICdDSEFSQUNURVJfVE9LRU4nO1xyXG5Ub2tlbml6ZXIuTlVMTF9DSEFSQUNURVJfVE9LRU4gPSAnTlVMTF9DSEFSQUNURVJfVE9LRU4nO1xyXG5Ub2tlbml6ZXIuV0hJVEVTUEFDRV9DSEFSQUNURVJfVE9LRU4gPSAnV0hJVEVTUEFDRV9DSEFSQUNURVJfVE9LRU4nO1xyXG5Ub2tlbml6ZXIuU1RBUlRfVEFHX1RPS0VOID0gJ1NUQVJUX1RBR19UT0tFTic7XHJcblRva2VuaXplci5FTkRfVEFHX1RPS0VOID0gJ0VORF9UQUdfVE9LRU4nO1xyXG5Ub2tlbml6ZXIuQ09NTUVOVF9UT0tFTiA9ICdDT01NRU5UX1RPS0VOJztcclxuVG9rZW5pemVyLkRPQ1RZUEVfVE9LRU4gPSAnRE9DVFlQRV9UT0tFTic7XHJcblRva2VuaXplci5FT0ZfVE9LRU4gPSAnRU9GX1RPS0VOJztcclxuXHJcbi8vVG9rZW5pemVyIGluaXRpYWwgc3RhdGVzIGZvciBkaWZmZXJlbnQgbW9kZXNcclxuVG9rZW5pemVyLk1PREUgPSBUb2tlbml6ZXIucHJvdG90eXBlLk1PREUgPSB7XHJcbiAgICBEQVRBOiBEQVRBX1NUQVRFLFxyXG4gICAgUkNEQVRBOiBSQ0RBVEFfU1RBVEUsXHJcbiAgICBSQVdURVhUOiBSQVdURVhUX1NUQVRFLFxyXG4gICAgU0NSSVBUX0RBVEE6IFNDUklQVF9EQVRBX1NUQVRFLFxyXG4gICAgUExBSU5URVhUOiBQTEFJTlRFWFRfU1RBVEVcclxufTtcclxuXHJcbi8vU3RhdGljXHJcblRva2VuaXplci5nZXRUb2tlbkF0dHIgPSBmdW5jdGlvbiAodG9rZW4sIGF0dHJOYW1lKSB7XHJcbiAgICBmb3IgKHZhciBpID0gdG9rZW4uYXR0cnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICBpZiAodG9rZW4uYXR0cnNbaV0ubmFtZSA9PT0gYXR0ck5hbWUpXHJcbiAgICAgICAgICAgIHJldHVybiB0b2tlbi5hdHRyc1tpXS52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxufTtcclxuXHJcbi8vR2V0IHRva2VuXHJcblRva2VuaXplci5wcm90b3R5cGUuZ2V0TmV4dFRva2VuID0gZnVuY3Rpb24gKCkge1xyXG4gICAgd2hpbGUgKCF0aGlzLnRva2VuUXVldWUubGVuZ3RoKVxyXG4gICAgICAgIHRoaXNbdGhpcy5zdGF0ZV0odGhpcy5fY29uc3VtZSgpKTtcclxuXHJcbiAgICByZXR1cm4gdGhpcy50b2tlblF1ZXVlLnNoaWZ0KCk7XHJcbn07XHJcblxyXG4vL0NvbnN1bXB0aW9uXHJcblRva2VuaXplci5wcm90b3R5cGUuX2NvbnN1bWUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB0aGlzLmNvbnN1bXB0aW9uUG9zKys7XHJcbiAgICByZXR1cm4gdGhpcy5wcmVwcm9jZXNzb3IuYWR2YW5jZUFuZFBlZWtDb2RlUG9pbnQoKTtcclxufTtcclxuXHJcblRva2VuaXplci5wcm90b3R5cGUuX3VuY29uc3VtZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHRoaXMuY29uc3VtcHRpb25Qb3MtLTtcclxuICAgIHRoaXMucHJlcHJvY2Vzc29yLnJldHJlYXQoKTtcclxufTtcclxuXHJcblRva2VuaXplci5wcm90b3R5cGUuX3VuY29uc3VtZVNldmVyYWwgPSBmdW5jdGlvbiAoY291bnQpIHtcclxuICAgIHdoaWxlIChjb3VudC0tKVxyXG4gICAgICAgIHRoaXMuX3VuY29uc3VtZSgpO1xyXG59O1xyXG5cclxuVG9rZW5pemVyLnByb3RvdHlwZS5fcmVjb25zdW1lSW5TdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZSkge1xyXG4gICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xyXG4gICAgdGhpcy5fdW5jb25zdW1lKCk7XHJcbn07XHJcblxyXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9jb25zdW1lU3Vic2VxdWVudElmTWF0Y2ggPSBmdW5jdGlvbiAocGF0dGVybiwgc3RhcnRDcCwgY2FzZVNlbnNpdGl2ZSkge1xyXG4gICAgdmFyIHJvbGxiYWNrUG9zID0gdGhpcy5jb25zdW1wdGlvblBvcyxcclxuICAgICAgICBpc01hdGNoID0gdHJ1ZSxcclxuICAgICAgICBwYXR0ZXJuTGVuZ3RoID0gcGF0dGVybi5sZW5ndGgsXHJcbiAgICAgICAgcGF0dGVyblBvcyA9IDAsXHJcbiAgICAgICAgY3AgPSBzdGFydENwLFxyXG4gICAgICAgIHBhdHRlcm5DcCA9IHZvaWQgMDtcclxuXHJcbiAgICBmb3IgKDsgcGF0dGVyblBvcyA8IHBhdHRlcm5MZW5ndGg7IHBhdHRlcm5Qb3MrKykge1xyXG4gICAgICAgIGlmIChwYXR0ZXJuUG9zID4gMClcclxuICAgICAgICAgICAgY3AgPSB0aGlzLl9jb25zdW1lKCk7XHJcblxyXG4gICAgICAgIGlmIChjcCA9PT0gJC5FT0YpIHtcclxuICAgICAgICAgICAgaXNNYXRjaCA9IGZhbHNlO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHBhdHRlcm5DcCA9IHBhdHRlcm5bcGF0dGVyblBvc107XHJcblxyXG4gICAgICAgIGlmIChjcCAhPT0gcGF0dGVybkNwICYmIChjYXNlU2Vuc2l0aXZlIHx8IGNwICE9PSB0b0FzY2lpTG93ZXJDb2RlUG9pbnQocGF0dGVybkNwKSkpIHtcclxuICAgICAgICAgICAgaXNNYXRjaCA9IGZhbHNlO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFpc01hdGNoKVxyXG4gICAgICAgIHRoaXMuX3VuY29uc3VtZVNldmVyYWwodGhpcy5jb25zdW1wdGlvblBvcyAtIHJvbGxiYWNrUG9zKTtcclxuXHJcbiAgICByZXR1cm4gaXNNYXRjaDtcclxufTtcclxuXHJcbi8vTG9va2FoZWFkXHJcblRva2VuaXplci5wcm90b3R5cGUuX2xvb2thaGVhZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBjcCA9IHRoaXMucHJlcHJvY2Vzc29yLmFkdmFuY2VBbmRQZWVrQ29kZVBvaW50KCk7XHJcbiAgICB0aGlzLnByZXByb2Nlc3Nvci5yZXRyZWF0KCk7XHJcblxyXG4gICAgcmV0dXJuIGNwO1xyXG59O1xyXG5cclxuLy9UZW1wIGJ1ZmZlclxyXG5Ub2tlbml6ZXIucHJvdG90eXBlLmlzVGVtcEJ1ZmZlckVxdWFsVG9TY3JpcHRTdHJpbmcgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICBpZiAodGhpcy50ZW1wQnVmZi5sZW5ndGggIT09ICQkLlNDUklQVF9TVFJJTkcubGVuZ3RoKVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudGVtcEJ1ZmYubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBpZiAodGhpcy50ZW1wQnVmZltpXSAhPT0gJCQuU0NSSVBUX1NUUklOR1tpXSlcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0cnVlO1xyXG59O1xyXG5cclxuLy9Ub2tlbiBjcmVhdGlvblxyXG5Ub2tlbml6ZXIucHJvdG90eXBlLmJ1aWxkU3RhcnRUYWdUb2tlbiA9IGZ1bmN0aW9uICh0YWdOYW1lKSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIHR5cGU6IFRva2VuaXplci5TVEFSVF9UQUdfVE9LRU4sXHJcbiAgICAgICAgdGFnTmFtZTogdGFnTmFtZSxcclxuICAgICAgICBzZWxmQ2xvc2luZzogZmFsc2UsXHJcbiAgICAgICAgYXR0cnM6IFtdXHJcbiAgICB9O1xyXG59O1xyXG5cclxuVG9rZW5pemVyLnByb3RvdHlwZS5idWlsZEVuZFRhZ1Rva2VuID0gZnVuY3Rpb24gKHRhZ05hbWUpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgdHlwZTogVG9rZW5pemVyLkVORF9UQUdfVE9LRU4sXHJcbiAgICAgICAgdGFnTmFtZTogdGFnTmFtZSxcclxuICAgICAgICBpZ25vcmVkOiBmYWxzZSxcclxuICAgICAgICBhdHRyczogW11cclxuICAgIH07XHJcbn07XHJcblxyXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9jcmVhdGVTdGFydFRhZ1Rva2VuID0gZnVuY3Rpb24gKHRhZ05hbWVGaXJzdENoKSB7XHJcbiAgICB0aGlzLmN1cnJlbnRUb2tlbiA9IHRoaXMuYnVpbGRTdGFydFRhZ1Rva2VuKHRhZ05hbWVGaXJzdENoKTtcclxufTtcclxuXHJcblRva2VuaXplci5wcm90b3R5cGUuX2NyZWF0ZUVuZFRhZ1Rva2VuID0gZnVuY3Rpb24gKHRhZ05hbWVGaXJzdENoKSB7XHJcbiAgICB0aGlzLmN1cnJlbnRUb2tlbiA9IHRoaXMuYnVpbGRFbmRUYWdUb2tlbih0YWdOYW1lRmlyc3RDaCk7XHJcbn07XHJcblxyXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9jcmVhdGVDb21tZW50VG9rZW4gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB0aGlzLmN1cnJlbnRUb2tlbiA9IHtcclxuICAgICAgICB0eXBlOiBUb2tlbml6ZXIuQ09NTUVOVF9UT0tFTixcclxuICAgICAgICBkYXRhOiAnJ1xyXG4gICAgfTtcclxufTtcclxuXHJcblRva2VuaXplci5wcm90b3R5cGUuX2NyZWF0ZURvY3R5cGVUb2tlbiA9IGZ1bmN0aW9uIChkb2N0eXBlTmFtZUZpcnN0Q2gpIHtcclxuICAgIHRoaXMuY3VycmVudFRva2VuID0ge1xyXG4gICAgICAgIHR5cGU6IFRva2VuaXplci5ET0NUWVBFX1RPS0VOLFxyXG4gICAgICAgIG5hbWU6IGRvY3R5cGVOYW1lRmlyc3RDaCB8fCAnJyxcclxuICAgICAgICBmb3JjZVF1aXJrczogZmFsc2UsXHJcbiAgICAgICAgcHVibGljSWQ6IG51bGwsXHJcbiAgICAgICAgc3lzdGVtSWQ6IG51bGxcclxuICAgIH07XHJcbn07XHJcblxyXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9jcmVhdGVDaGFyYWN0ZXJUb2tlbiA9IGZ1bmN0aW9uICh0eXBlLCBjaCkge1xyXG4gICAgdGhpcy5jdXJyZW50Q2hhcmFjdGVyVG9rZW4gPSB7XHJcbiAgICAgICAgdHlwZTogdHlwZSxcclxuICAgICAgICBjaGFyczogY2hcclxuICAgIH07XHJcbn07XHJcblxyXG4vL1RhZyBhdHRyaWJ1dGVzXHJcblRva2VuaXplci5wcm90b3R5cGUuX2NyZWF0ZUF0dHIgPSBmdW5jdGlvbiAoYXR0ck5hbWVGaXJzdENoKSB7XHJcbiAgICB0aGlzLmN1cnJlbnRBdHRyID0ge1xyXG4gICAgICAgIG5hbWU6IGF0dHJOYW1lRmlyc3RDaCxcclxuICAgICAgICB2YWx1ZTogJydcclxuICAgIH07XHJcbn07XHJcblxyXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9pc0R1cGxpY2F0ZUF0dHIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICByZXR1cm4gVG9rZW5pemVyLmdldFRva2VuQXR0cih0aGlzLmN1cnJlbnRUb2tlbiwgdGhpcy5jdXJyZW50QXR0ci5uYW1lKSAhPT0gbnVsbDtcclxufTtcclxuXHJcblRva2VuaXplci5wcm90b3R5cGUuX2xlYXZlQXR0ck5hbWUgPSBmdW5jdGlvbiAodG9TdGF0ZSkge1xyXG4gICAgdGhpcy5zdGF0ZSA9IHRvU3RhdGU7XHJcblxyXG4gICAgaWYgKCF0aGlzLl9pc0R1cGxpY2F0ZUF0dHIoKSlcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5hdHRycy5wdXNoKHRoaXMuY3VycmVudEF0dHIpO1xyXG59O1xyXG5cclxuLy9BcHByb3ByaWF0ZSBlbmQgdGFnIHRva2VuXHJcbi8vKHNlZTogaHR0cDovL3d3dy53aGF0d2cub3JnL3NwZWNzL3dlYi1hcHBzL2N1cnJlbnQtd29yay9tdWx0aXBhZ2UvdG9rZW5pemF0aW9uLmh0bWwjYXBwcm9wcmlhdGUtZW5kLXRhZy10b2tlbilcclxuVG9rZW5pemVyLnByb3RvdHlwZS5faXNBcHByb3ByaWF0ZUVuZFRhZ1Rva2VuID0gZnVuY3Rpb24gKCkge1xyXG4gICAgcmV0dXJuIHRoaXMubGFzdFN0YXJ0VGFnTmFtZSA9PT0gdGhpcy5jdXJyZW50VG9rZW4udGFnTmFtZTtcclxufTtcclxuXHJcbi8vVG9rZW4gZW1pc3Npb25cclxuVG9rZW5pemVyLnByb3RvdHlwZS5fZW1pdEN1cnJlbnRUb2tlbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHRoaXMuX2VtaXRDdXJyZW50Q2hhcmFjdGVyVG9rZW4oKTtcclxuXHJcbiAgICAvL05PVEU6IHN0b3JlIGVtaXRlZCBzdGFydCB0YWcncyB0YWdOYW1lIHRvIGRldGVybWluZSBpcyB0aGUgZm9sbG93aW5nIGVuZCB0YWcgdG9rZW4gaXMgYXBwcm9wcmlhdGUuXHJcbiAgICBpZiAodGhpcy5jdXJyZW50VG9rZW4udHlwZSA9PT0gVG9rZW5pemVyLlNUQVJUX1RBR19UT0tFTilcclxuICAgICAgICB0aGlzLmxhc3RTdGFydFRhZ05hbWUgPSB0aGlzLmN1cnJlbnRUb2tlbi50YWdOYW1lO1xyXG5cclxuICAgIHRoaXMudG9rZW5RdWV1ZS5wdXNoKHRoaXMuY3VycmVudFRva2VuKTtcclxuICAgIHRoaXMuY3VycmVudFRva2VuID0gbnVsbDtcclxufTtcclxuXHJcblRva2VuaXplci5wcm90b3R5cGUuX2VtaXRDdXJyZW50Q2hhcmFjdGVyVG9rZW4gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICBpZiAodGhpcy5jdXJyZW50Q2hhcmFjdGVyVG9rZW4pIHtcclxuICAgICAgICB0aGlzLnRva2VuUXVldWUucHVzaCh0aGlzLmN1cnJlbnRDaGFyYWN0ZXJUb2tlbik7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50Q2hhcmFjdGVyVG9rZW4gPSBudWxsO1xyXG4gICAgfVxyXG59O1xyXG5cclxuVG9rZW5pemVyLnByb3RvdHlwZS5fZW1pdEVPRlRva2VuID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdGhpcy5fZW1pdEN1cnJlbnRDaGFyYWN0ZXJUb2tlbigpO1xyXG4gICAgdGhpcy50b2tlblF1ZXVlLnB1c2goe3R5cGU6IFRva2VuaXplci5FT0ZfVE9LRU59KTtcclxufTtcclxuXHJcbi8vQ2hhcmFjdGVycyBlbWlzc2lvblxyXG5cclxuLy9PUFRJTUlaQVRJT046IHNwZWNpZmljYXRpb24gdXNlcyBvbmx5IG9uZSB0eXBlIG9mIGNoYXJhY3RlciB0b2tlbnMgKG9uZSB0b2tlbiBwZXIgY2hhcmFjdGVyKS5cclxuLy9UaGlzIGNhdXNlcyBhIGh1Z2UgbWVtb3J5IG92ZXJoZWFkIGFuZCBhIGxvdCBvZiB1bm5lY2Vzc2FyeSBwYXJzZXIgbG9vcHMuIHBhcnNlNSB1c2VzIDMgZ3JvdXBzIG9mIGNoYXJhY3RlcnMuXHJcbi8vSWYgd2UgaGF2ZSBhIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgdGhhdCBiZWxvbmcgdG8gdGhlIHNhbWUgZ3JvdXAsIHBhcnNlciBjYW4gcHJvY2VzcyBpdFxyXG4vL2FzIGEgc2luZ2xlIHNvbGlkIGNoYXJhY3RlciB0b2tlbi5cclxuLy9TbywgdGhlcmUgYXJlIDMgdHlwZXMgb2YgY2hhcmFjdGVyIHRva2VucyBpbiBwYXJzZTU6XHJcbi8vMSlOVUxMX0NIQVJBQ1RFUl9UT0tFTiAtIFxcdTAwMDAtY2hhcmFjdGVyIHNlcXVlbmNlcyAoZS5nLiAnXFx1MDAwMFxcdTAwMDBcXHUwMDAwJylcclxuLy8yKVdISVRFU1BBQ0VfQ0hBUkFDVEVSX1RPS0VOIC0gYW55IHdoaXRlc3BhY2UvbmV3LWxpbmUgY2hhcmFjdGVyIHNlcXVlbmNlcyAoZS5nLiAnXFxuICBcXHJcXHQgICBcXGYnKVxyXG4vLzMpQ0hBUkFDVEVSX1RPS0VOIC0gYW55IGNoYXJhY3RlciBzZXF1ZW5jZSB3aGljaCBkb24ndCBiZWxvbmcgdG8gZ3JvdXBzIDEgYW5kIDIgKGUuZy4gJ2FiY2RlZjEyMzRAQCMkJV4nKVxyXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9hcHBlbmRDaGFyVG9DdXJyZW50Q2hhcmFjdGVyVG9rZW4gPSBmdW5jdGlvbiAodHlwZSwgY2gpIHtcclxuICAgIGlmICh0aGlzLmN1cnJlbnRDaGFyYWN0ZXJUb2tlbiAmJiB0aGlzLmN1cnJlbnRDaGFyYWN0ZXJUb2tlbi50eXBlICE9PSB0eXBlKVxyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50Q2hhcmFjdGVyVG9rZW4oKTtcclxuXHJcbiAgICBpZiAodGhpcy5jdXJyZW50Q2hhcmFjdGVyVG9rZW4pXHJcbiAgICAgICAgdGhpcy5jdXJyZW50Q2hhcmFjdGVyVG9rZW4uY2hhcnMgKz0gY2g7XHJcblxyXG4gICAgZWxzZVxyXG4gICAgICAgIHRoaXMuX2NyZWF0ZUNoYXJhY3RlclRva2VuKHR5cGUsIGNoKTtcclxufTtcclxuXHJcblRva2VuaXplci5wcm90b3R5cGUuX2VtaXRDb2RlUG9pbnQgPSBmdW5jdGlvbiAoY3ApIHtcclxuICAgIHZhciB0eXBlID0gVG9rZW5pemVyLkNIQVJBQ1RFUl9UT0tFTjtcclxuXHJcbiAgICBpZiAoaXNXaGl0ZXNwYWNlKGNwKSlcclxuICAgICAgICB0eXBlID0gVG9rZW5pemVyLldISVRFU1BBQ0VfQ0hBUkFDVEVSX1RPS0VOO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLk5VTEwpXHJcbiAgICAgICAgdHlwZSA9IFRva2VuaXplci5OVUxMX0NIQVJBQ1RFUl9UT0tFTjtcclxuXHJcbiAgICB0aGlzLl9hcHBlbmRDaGFyVG9DdXJyZW50Q2hhcmFjdGVyVG9rZW4odHlwZSwgdG9DaGFyKGNwKSk7XHJcbn07XHJcblxyXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9lbWl0U2V2ZXJhbENvZGVQb2ludHMgPSBmdW5jdGlvbiAoY29kZVBvaW50cykge1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb2RlUG9pbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIHRoaXMuX2VtaXRDb2RlUG9pbnQoY29kZVBvaW50c1tpXSk7XHJcbn07XHJcblxyXG4vL05PVEU6IHVzZWQgdGhlbiB3ZSBlbWl0IGNoYXJhY3RlciBleHBsaWNpdGx5LiBUaGlzIGlzIGFsd2F5cyBhIG5vbi13aGl0ZXNwYWNlIGFuZCBhIG5vbi1udWxsIGNoYXJhY3Rlci5cclxuLy9TbyB3ZSBjYW4gYXZvaWQgYWRkaXRpb25hbCBjaGVja3MgaGVyZS5cclxuVG9rZW5pemVyLnByb3RvdHlwZS5fZW1pdENoYXIgPSBmdW5jdGlvbiAoY2gpIHtcclxuICAgIHRoaXMuX2FwcGVuZENoYXJUb0N1cnJlbnRDaGFyYWN0ZXJUb2tlbihUb2tlbml6ZXIuQ0hBUkFDVEVSX1RPS0VOLCBjaCk7XHJcbn07XHJcblxyXG4vL0NoYXJhY3RlciByZWZlcmVuY2UgdG9rZW5pemF0aW9uXHJcblRva2VuaXplci5wcm90b3R5cGUuX2NvbnN1bWVOdW1lcmljRW50aXR5ID0gZnVuY3Rpb24gKGlzSGV4KSB7XHJcbiAgICB2YXIgZGlnaXRzID0gJycsXHJcbiAgICAgICAgbmV4dENwID0gdm9pZCAwO1xyXG5cclxuICAgIGRvIHtcclxuICAgICAgICBkaWdpdHMgKz0gdG9DaGFyKHRoaXMuX2NvbnN1bWUoKSk7XHJcbiAgICAgICAgbmV4dENwID0gdGhpcy5fbG9va2FoZWFkKCk7XHJcbiAgICB9IHdoaWxlIChuZXh0Q3AgIT09ICQuRU9GICYmIGlzRGlnaXQobmV4dENwLCBpc0hleCkpO1xyXG5cclxuICAgIGlmICh0aGlzLl9sb29rYWhlYWQoKSA9PT0gJC5TRU1JQ09MT04pXHJcbiAgICAgICAgdGhpcy5fY29uc3VtZSgpO1xyXG5cclxuICAgIHZhciByZWZlcmVuY2VkQ3AgPSBwYXJzZUludChkaWdpdHMsIGlzSGV4ID8gMTYgOiAxMCksXHJcbiAgICAgICAgcmVwbGFjZW1lbnQgPSBOVU1FUklDX0VOVElUWV9SRVBMQUNFTUVOVFNbcmVmZXJlbmNlZENwXTtcclxuXHJcbiAgICBpZiAocmVwbGFjZW1lbnQpXHJcbiAgICAgICAgcmV0dXJuIHJlcGxhY2VtZW50O1xyXG5cclxuICAgIGlmIChpc1Jlc2VydmVkQ29kZVBvaW50KHJlZmVyZW5jZWRDcCkpXHJcbiAgICAgICAgcmV0dXJuICQuUkVQTEFDRU1FTlRfQ0hBUkFDVEVSO1xyXG5cclxuICAgIHJldHVybiByZWZlcmVuY2VkQ3A7XHJcbn07XHJcblxyXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9jb25zdW1lTmFtZWRFbnRpdHkgPSBmdW5jdGlvbiAoc3RhcnRDcCwgaW5BdHRyKSB7XHJcbiAgICB2YXIgcmVmZXJlbmNlZENvZGVQb2ludHMgPSBudWxsLFxyXG4gICAgICAgIGVudGl0eUNvZGVQb2ludHNDb3VudCA9IDAsXHJcbiAgICAgICAgY3AgPSBzdGFydENwLFxyXG4gICAgICAgIGxlYWYgPSBOQU1FRF9FTlRJVFlfVFJJRVtjcF0sXHJcbiAgICAgICAgY29uc3VtZWRDb3VudCA9IDEsXHJcbiAgICAgICAgc2VtaWNvbG9uVGVybWluYXRlZCA9IGZhbHNlO1xyXG5cclxuICAgIGZvciAoOyBsZWFmICYmIGNwICE9PSAkLkVPRjsgY3AgPSB0aGlzLl9jb25zdW1lKCksIGNvbnN1bWVkQ291bnQrKywgbGVhZiA9IGxlYWYubCAmJiBsZWFmLmxbY3BdKSB7XHJcbiAgICAgICAgaWYgKGxlYWYuYykge1xyXG4gICAgICAgICAgICAvL05PVEU6IHdlIGhhdmUgYXQgbGVhc3Qgb25lIG5hbWVkIHJlZmVyZW5jZSBtYXRjaC4gQnV0IHdlIGRvbid0IHN0b3AgbG9va3VwIGF0IHRoaXMgcG9pbnQsXHJcbiAgICAgICAgICAgIC8vYmVjYXVzZSBsb25nZXIgbWF0Y2hlcyBzdGlsbCBjYW4gYmUgZm91bmQgKGUuZy4gJyZub3QnIGFuZCAnJm5vdGluOycpIGV4Y2VwdCB0aGUgY2FzZVxyXG4gICAgICAgICAgICAvL3RoZW4gZm91bmQgbWF0Y2ggaXMgdGVybWluYXRlZCBieSBzZW1pY29sb24uXHJcbiAgICAgICAgICAgIHJlZmVyZW5jZWRDb2RlUG9pbnRzID0gbGVhZi5jO1xyXG4gICAgICAgICAgICBlbnRpdHlDb2RlUG9pbnRzQ291bnQgPSBjb25zdW1lZENvdW50O1xyXG5cclxuICAgICAgICAgICAgaWYgKGNwID09PSAkLlNFTUlDT0xPTikge1xyXG4gICAgICAgICAgICAgICAgc2VtaWNvbG9uVGVybWluYXRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAocmVmZXJlbmNlZENvZGVQb2ludHMpIHtcclxuICAgICAgICBpZiAoIXNlbWljb2xvblRlcm1pbmF0ZWQpIHtcclxuICAgICAgICAgICAgLy9OT1RFOiB1bmNvbnN1bWUgZXhjZXNzIChlLmcuICdpdCcgaW4gJyZub3RpdCcpXHJcbiAgICAgICAgICAgIHRoaXMuX3VuY29uc3VtZVNldmVyYWwoY29uc3VtZWRDb3VudCAtIGVudGl0eUNvZGVQb2ludHNDb3VudCk7XHJcblxyXG4gICAgICAgICAgICAvL05PVEU6IElmIHRoZSBjaGFyYWN0ZXIgcmVmZXJlbmNlIGlzIGJlaW5nIGNvbnN1bWVkIGFzIHBhcnQgb2YgYW4gYXR0cmlidXRlIGFuZCB0aGUgbmV4dCBjaGFyYWN0ZXJcclxuICAgICAgICAgICAgLy9pcyBlaXRoZXIgYSBVKzAwM0QgRVFVQUxTIFNJR04gY2hhcmFjdGVyICg9KSBvciBhbiBhbHBoYW51bWVyaWMgQVNDSUkgY2hhcmFjdGVyLCB0aGVuLCBmb3IgaGlzdG9yaWNhbFxyXG4gICAgICAgICAgICAvL3JlYXNvbnMsIGFsbCB0aGUgY2hhcmFjdGVycyB0aGF0IHdlcmUgbWF0Y2hlZCBhZnRlciB0aGUgVSswMDI2IEFNUEVSU0FORCBjaGFyYWN0ZXIgKCYpIG11c3QgYmVcclxuICAgICAgICAgICAgLy91bmNvbnN1bWVkLCBhbmQgbm90aGluZyBpcyByZXR1cm5lZC5cclxuICAgICAgICAgICAgLy9Ib3dldmVyLCBpZiB0aGlzIG5leHQgY2hhcmFjdGVyIGlzIGluIGZhY3QgYSBVKzAwM0QgRVFVQUxTIFNJR04gY2hhcmFjdGVyICg9KSwgdGhlbiB0aGlzIGlzIGFcclxuICAgICAgICAgICAgLy9wYXJzZSBlcnJvciwgYmVjYXVzZSBzb21lIGxlZ2FjeSB1c2VyIGFnZW50cyB3aWxsIG1pc2ludGVycHJldCB0aGUgbWFya3VwIGluIHRob3NlIGNhc2VzLlxyXG4gICAgICAgICAgICAvLyhzZWU6IGh0dHA6Ly93d3cud2hhdHdnLm9yZy9zcGVjcy93ZWItYXBwcy9jdXJyZW50LXdvcmsvbXVsdGlwYWdlL3Rva2VuaXphdGlvbi5odG1sI3Rva2VuaXppbmctY2hhcmFjdGVyLXJlZmVyZW5jZXMpXHJcbiAgICAgICAgICAgIGlmIChpbkF0dHIpIHtcclxuICAgICAgICAgICAgICAgIHZhciBuZXh0Q3AgPSB0aGlzLl9sb29rYWhlYWQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAobmV4dENwID09PSAkLkVRVUFMU19TSUdOIHx8IGlzQXNjaWlBbHBoYU51bWVyaWMobmV4dENwKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3VuY29uc3VtZVNldmVyYWwoZW50aXR5Q29kZVBvaW50c0NvdW50KTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHJlZmVyZW5jZWRDb2RlUG9pbnRzO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX3VuY29uc3VtZVNldmVyYWwoY29uc3VtZWRDb3VudCk7XHJcblxyXG4gICAgcmV0dXJuIG51bGw7XHJcbn07XHJcblxyXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9jb25zdW1lQ2hhcmFjdGVyUmVmZXJlbmNlID0gZnVuY3Rpb24gKHN0YXJ0Q3AsIGluQXR0cikge1xyXG4gICAgaWYgKHRoaXMuZGlzYWJsZUVudGl0aWVzRGVjb2RpbmcgfHwgaXNXaGl0ZXNwYWNlKHN0YXJ0Q3ApIHx8IHN0YXJ0Q3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04gfHxcclxuICAgICAgICBzdGFydENwID09PSAkLkFNUEVSU0FORCB8fCBzdGFydENwID09PSB0aGlzLmFkZGl0aW9uYWxBbGxvd2VkQ3AgfHwgc3RhcnRDcCA9PT0gJC5FT0YpIHtcclxuICAgICAgICAvL05PVEU6IG5vdCBhIGNoYXJhY3RlciByZWZlcmVuY2UuIE5vIGNoYXJhY3RlcnMgYXJlIGNvbnN1bWVkLCBhbmQgbm90aGluZyBpcyByZXR1cm5lZC5cclxuICAgICAgICB0aGlzLl91bmNvbnN1bWUoKTtcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChzdGFydENwID09PSAkLk5VTUJFUl9TSUdOKSB7XHJcbiAgICAgICAgLy9OT1RFOiB3ZSBoYXZlIGEgbnVtZXJpYyBlbnRpdHkgY2FuZGlkYXRlLCBub3cgd2Ugc2hvdWxkIGRldGVybWluZSBpZiBpdCdzIGhleCBvciBkZWNpbWFsXHJcbiAgICAgICAgdmFyIGlzSGV4ID0gZmFsc2UsXHJcbiAgICAgICAgICAgIG5leHRDcCA9IHRoaXMuX2xvb2thaGVhZCgpO1xyXG5cclxuICAgICAgICBpZiAobmV4dENwID09PSAkLkxBVElOX1NNQUxMX1ggfHwgbmV4dENwID09PSAkLkxBVElOX0NBUElUQUxfWCkge1xyXG4gICAgICAgICAgICB0aGlzLl9jb25zdW1lKCk7XHJcbiAgICAgICAgICAgIGlzSGV4ID0gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIG5leHRDcCA9IHRoaXMuX2xvb2thaGVhZCgpO1xyXG5cclxuICAgICAgICAvL05PVEU6IGlmIHdlIGhhdmUgYXQgbGVhc3Qgb25lIGRpZ2l0IHRoaXMgaXMgYSBudW1lcmljIGVudGl0eSBmb3Igc3VyZSwgc28gd2UgY29uc3VtZSBpdFxyXG4gICAgICAgIGlmIChuZXh0Q3AgIT09ICQuRU9GICYmIGlzRGlnaXQobmV4dENwLCBpc0hleCkpXHJcbiAgICAgICAgICAgIHJldHVybiBbdGhpcy5fY29uc3VtZU51bWVyaWNFbnRpdHkoaXNIZXgpXTtcclxuXHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vTk9URTogb3RoZXJ3aXNlIHRoaXMgaXMgYSBib2d1cyBudW1iZXIgZW50aXR5IGFuZCBhIHBhcnNlIGVycm9yLiBVbmNvbnN1bWUgdGhlIG51bWJlciBzaWduXHJcbiAgICAgICAgICAgIC8vYW5kIHRoZSAneCctY2hhcmFjdGVyIGlmIGFwcHJvcHJpYXRlLlxyXG4gICAgICAgICAgICB0aGlzLl91bmNvbnN1bWVTZXZlcmFsKGlzSGV4ID8gMiA6IDEpO1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZVxyXG4gICAgICAgIHJldHVybiB0aGlzLl9jb25zdW1lTmFtZWRFbnRpdHkoc3RhcnRDcCwgaW5BdHRyKTtcclxufTtcclxuXHJcbi8vU3RhdGUgbWFjaGluZVxyXG52YXIgXyA9IFRva2VuaXplci5wcm90b3R5cGU7XHJcblxyXG4vLzEyLjIuNC4xIERhdGEgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tEQVRBX1NUQVRFXSA9IGZ1bmN0aW9uIGRhdGFTdGF0ZShjcCkge1xyXG4gICAgaWYgKGNwID09PSAkLkFNUEVSU0FORClcclxuICAgICAgICB0aGlzLnN0YXRlID0gQ0hBUkFDVEVSX1JFRkVSRU5DRV9JTl9EQVRBX1NUQVRFO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkxFU1NfVEhBTl9TSUdOKVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBUQUdfT1BFTl9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5OVUxMKVxyXG4gICAgICAgIHRoaXMuX2VtaXRDb2RlUG9pbnQoY3ApO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkVPRilcclxuICAgICAgICB0aGlzLl9lbWl0RU9GVG9rZW4oKTtcclxuXHJcbiAgICBlbHNlXHJcbiAgICAgICAgdGhpcy5fZW1pdENvZGVQb2ludChjcCk7XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuMiBDaGFyYWN0ZXIgcmVmZXJlbmNlIGluIGRhdGEgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tDSEFSQUNURVJfUkVGRVJFTkNFX0lOX0RBVEFfU1RBVEVdID0gZnVuY3Rpb24gY2hhcmFjdGVyUmVmZXJlbmNlSW5EYXRhU3RhdGUoY3ApIHtcclxuICAgIHRoaXMuc3RhdGUgPSBEQVRBX1NUQVRFO1xyXG4gICAgdGhpcy5hZGRpdGlvbmFsQWxsb3dlZENwID0gdm9pZCAwO1xyXG5cclxuICAgIHZhciByZWZlcmVuY2VkQ29kZVBvaW50cyA9IHRoaXMuX2NvbnN1bWVDaGFyYWN0ZXJSZWZlcmVuY2UoY3AsIGZhbHNlKTtcclxuXHJcbiAgICBpZiAocmVmZXJlbmNlZENvZGVQb2ludHMpXHJcbiAgICAgICAgdGhpcy5fZW1pdFNldmVyYWxDb2RlUG9pbnRzKHJlZmVyZW5jZWRDb2RlUG9pbnRzKTtcclxuICAgIGVsc2VcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignJicpO1xyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjMgUkNEQVRBIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bUkNEQVRBX1NUQVRFXSA9IGZ1bmN0aW9uIHJjZGF0YVN0YXRlKGNwKSB7XHJcbiAgICBpZiAoY3AgPT09ICQuQU1QRVJTQU5EKVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBDSEFSQUNURVJfUkVGRVJFTkNFX0lOX1JDREFUQV9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5MRVNTX1RIQU5fU0lHTilcclxuICAgICAgICB0aGlzLnN0YXRlID0gUkNEQVRBX0xFU1NfVEhBTl9TSUdOX1NUQVRFO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLk5VTEwpXHJcbiAgICAgICAgdGhpcy5fZW1pdENoYXIoVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVIpO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkVPRilcclxuICAgICAgICB0aGlzLl9lbWl0RU9GVG9rZW4oKTtcclxuXHJcbiAgICBlbHNlXHJcbiAgICAgICAgdGhpcy5fZW1pdENvZGVQb2ludChjcCk7XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuNCBDaGFyYWN0ZXIgcmVmZXJlbmNlIGluIFJDREFUQSBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW0NIQVJBQ1RFUl9SRUZFUkVOQ0VfSU5fUkNEQVRBX1NUQVRFXSA9IGZ1bmN0aW9uIGNoYXJhY3RlclJlZmVyZW5jZUluUmNkYXRhU3RhdGUoY3ApIHtcclxuICAgIHRoaXMuc3RhdGUgPSBSQ0RBVEFfU1RBVEU7XHJcbiAgICB0aGlzLmFkZGl0aW9uYWxBbGxvd2VkQ3AgPSB2b2lkIDA7XHJcblxyXG4gICAgdmFyIHJlZmVyZW5jZWRDb2RlUG9pbnRzID0gdGhpcy5fY29uc3VtZUNoYXJhY3RlclJlZmVyZW5jZShjcCwgZmFsc2UpO1xyXG5cclxuICAgIGlmIChyZWZlcmVuY2VkQ29kZVBvaW50cylcclxuICAgICAgICB0aGlzLl9lbWl0U2V2ZXJhbENvZGVQb2ludHMocmVmZXJlbmNlZENvZGVQb2ludHMpO1xyXG4gICAgZWxzZVxyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCcmJyk7XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuNSBSQVdURVhUIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bUkFXVEVYVF9TVEFURV0gPSBmdW5jdGlvbiByYXd0ZXh0U3RhdGUoY3ApIHtcclxuICAgIGlmIChjcCA9PT0gJC5MRVNTX1RIQU5fU0lHTilcclxuICAgICAgICB0aGlzLnN0YXRlID0gUkFXVEVYVF9MRVNTX1RIQU5fU0lHTl9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5OVUxMKVxyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKFVOSUNPREUuUkVQTEFDRU1FTlRfQ0hBUkFDVEVSKTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5FT0YpXHJcbiAgICAgICAgdGhpcy5fZW1pdEVPRlRva2VuKCk7XHJcblxyXG4gICAgZWxzZVxyXG4gICAgICAgIHRoaXMuX2VtaXRDb2RlUG9pbnQoY3ApO1xyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjYgU2NyaXB0IGRhdGEgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tTQ1JJUFRfREFUQV9TVEFURV0gPSBmdW5jdGlvbiBzY3JpcHREYXRhU3RhdGUoY3ApIHtcclxuICAgIGlmIChjcCA9PT0gJC5MRVNTX1RIQU5fU0lHTilcclxuICAgICAgICB0aGlzLnN0YXRlID0gU0NSSVBUX0RBVEFfTEVTU19USEFOX1NJR05fU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuTlVMTClcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcihVTklDT0RFLlJFUExBQ0VNRU5UX0NIQVJBQ1RFUik7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKVxyXG4gICAgICAgIHRoaXMuX2VtaXRFT0ZUb2tlbigpO1xyXG5cclxuICAgIGVsc2VcclxuICAgICAgICB0aGlzLl9lbWl0Q29kZVBvaW50KGNwKTtcclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC43IFBMQUlOVEVYVCBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW1BMQUlOVEVYVF9TVEFURV0gPSBmdW5jdGlvbiBwbGFpbnRleHRTdGF0ZShjcCkge1xyXG4gICAgaWYgKGNwID09PSAkLk5VTEwpXHJcbiAgICAgICAgdGhpcy5fZW1pdENoYXIoVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVIpO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkVPRilcclxuICAgICAgICB0aGlzLl9lbWl0RU9GVG9rZW4oKTtcclxuXHJcbiAgICBlbHNlXHJcbiAgICAgICAgdGhpcy5fZW1pdENvZGVQb2ludChjcCk7XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuOCBUYWcgb3BlbiBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW1RBR19PUEVOX1NUQVRFXSA9IGZ1bmN0aW9uIHRhZ09wZW5TdGF0ZShjcCkge1xyXG4gICAgaWYgKGNwID09PSAkLkVYQ0xBTUFUSU9OX01BUkspXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IE1BUktVUF9ERUNMQVJBVElPTl9PUEVOX1NUQVRFO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLlNPTElEVVMpXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IEVORF9UQUdfT1BFTl9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmIChpc0FzY2lpVXBwZXIoY3ApKSB7XHJcbiAgICAgICAgdGhpcy5fY3JlYXRlU3RhcnRUYWdUb2tlbih0b0FzY2lpTG93ZXJDaGFyKGNwKSk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFRBR19OQU1FX1NUQVRFO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGlzQXNjaWlMb3dlcihjcCkpIHtcclxuICAgICAgICB0aGlzLl9jcmVhdGVTdGFydFRhZ1Rva2VuKHRvQ2hhcihjcCkpO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBUQUdfTkFNRV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5RVUVTVElPTl9NQVJLKSB7XHJcbiAgICAgICAgLy9OT1RFOiBjYWxsIGJvZ3VzIGNvbW1lbnQgc3RhdGUgZGlyZWN0bHkgd2l0aCBjdXJyZW50IGNvbnN1bWVkIGNoYXJhY3RlciB0byBhdm9pZCB1bm5lY2Vzc2FyeSByZWNvbnN1bXB0aW9uLlxyXG4gICAgICAgIHRoaXNbQk9HVVNfQ09NTUVOVF9TVEFURV0oY3ApO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCc8Jyk7XHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShEQVRBX1NUQVRFKTtcclxuICAgIH1cclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC45IEVuZCB0YWcgb3BlbiBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW0VORF9UQUdfT1BFTl9TVEFURV0gPSBmdW5jdGlvbiBlbmRUYWdPcGVuU3RhdGUoY3ApIHtcclxuICAgIGlmIChpc0FzY2lpVXBwZXIoY3ApKSB7XHJcbiAgICAgICAgdGhpcy5fY3JlYXRlRW5kVGFnVG9rZW4odG9Bc2NpaUxvd2VyQ2hhcihjcCkpO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBUQUdfTkFNRV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChpc0FzY2lpTG93ZXIoY3ApKSB7XHJcbiAgICAgICAgdGhpcy5fY3JlYXRlRW5kVGFnVG9rZW4odG9DaGFyKGNwKSk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFRBR19OQU1FX1NUQVRFO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkdSRUFURVJfVEhBTl9TSUdOKVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBEQVRBX1NUQVRFO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkVPRikge1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcbiAgICAgICAgdGhpcy5fZW1pdENoYXIoJzwnKTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignLycpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIC8vTk9URTogY2FsbCBib2d1cyBjb21tZW50IHN0YXRlIGRpcmVjdGx5IHdpdGggY3VycmVudCBjb25zdW1lZCBjaGFyYWN0ZXIgdG8gYXZvaWQgdW5uZWNlc3NhcnkgcmVjb25zdW1wdGlvbi5cclxuICAgICAgICB0aGlzW0JPR1VTX0NPTU1FTlRfU1RBVEVdKGNwKTtcclxuICAgIH1cclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4xMCBUYWcgbmFtZSBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW1RBR19OQU1FX1NUQVRFXSA9IGZ1bmN0aW9uIHRhZ05hbWVTdGF0ZShjcCkge1xyXG4gICAgaWYgKGlzV2hpdGVzcGFjZShjcCkpXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IEJFRk9SRV9BVFRSSUJVVEVfTkFNRV9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5TT0xJRFVTKVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTRUxGX0NMT1NJTkdfU1RBUlRfVEFHX1NUQVRFO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkdSRUFURVJfVEhBTl9TSUdOKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGlzQXNjaWlVcHBlcihjcCkpXHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4udGFnTmFtZSArPSB0b0FzY2lpTG93ZXJDaGFyKGNwKTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5OVUxMKVxyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLnRhZ05hbWUgKz0gVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVI7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKVxyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcblxyXG4gICAgZWxzZVxyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLnRhZ05hbWUgKz0gdG9DaGFyKGNwKTtcclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4xMSBSQ0RBVEEgbGVzcy10aGFuIHNpZ24gc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tSQ0RBVEFfTEVTU19USEFOX1NJR05fU1RBVEVdID0gZnVuY3Rpb24gcmNkYXRhTGVzc1RoYW5TaWduU3RhdGUoY3ApIHtcclxuICAgIGlmIChjcCA9PT0gJC5TT0xJRFVTKSB7XHJcbiAgICAgICAgdGhpcy50ZW1wQnVmZiA9IFtdO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBSQ0RBVEFfRU5EX1RBR19PUEVOX1NUQVRFO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCc8Jyk7XHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShSQ0RBVEFfU1RBVEUpO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjEyIFJDREFUQSBlbmQgdGFnIG9wZW4gc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tSQ0RBVEFfRU5EX1RBR19PUEVOX1NUQVRFXSA9IGZ1bmN0aW9uIHJjZGF0YUVuZFRhZ09wZW5TdGF0ZShjcCkge1xyXG4gICAgaWYgKGlzQXNjaWlVcHBlcihjcCkpIHtcclxuICAgICAgICB0aGlzLl9jcmVhdGVFbmRUYWdUb2tlbih0b0FzY2lpTG93ZXJDaGFyKGNwKSk7XHJcbiAgICAgICAgdGhpcy50ZW1wQnVmZi5wdXNoKGNwKTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gUkNEQVRBX0VORF9UQUdfTkFNRV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChpc0FzY2lpTG93ZXIoY3ApKSB7XHJcbiAgICAgICAgdGhpcy5fY3JlYXRlRW5kVGFnVG9rZW4odG9DaGFyKGNwKSk7XHJcbiAgICAgICAgdGhpcy50ZW1wQnVmZi5wdXNoKGNwKTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gUkNEQVRBX0VORF9UQUdfTkFNRV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIHtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignPCcpO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCcvJyk7XHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShSQ0RBVEFfU1RBVEUpO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjEzIFJDREFUQSBlbmQgdGFnIG5hbWUgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tSQ0RBVEFfRU5EX1RBR19OQU1FX1NUQVRFXSA9IGZ1bmN0aW9uIHJjZGF0YUVuZFRhZ05hbWVTdGF0ZShjcCkge1xyXG4gICAgaWYgKGlzQXNjaWlVcHBlcihjcCkpIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi50YWdOYW1lICs9IHRvQXNjaWlMb3dlckNoYXIoY3ApO1xyXG4gICAgICAgIHRoaXMudGVtcEJ1ZmYucHVzaChjcCk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoaXNBc2NpaUxvd2VyKGNwKSkge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLnRhZ05hbWUgKz0gdG9DaGFyKGNwKTtcclxuICAgICAgICB0aGlzLnRlbXBCdWZmLnB1c2goY3ApO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGlmICh0aGlzLl9pc0FwcHJvcHJpYXRlRW5kVGFnVG9rZW4oKSkge1xyXG4gICAgICAgICAgICBpZiAoaXNXaGl0ZXNwYWNlKGNwKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IEJFRk9SRV9BVFRSSUJVVEVfTkFNRV9TVEFURTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGNwID09PSAkLlNPTElEVVMpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTRUxGX0NMT1NJTkdfU1RBUlRfVEFHX1NUQVRFO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBEQVRBX1NUQVRFO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignPCcpO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCcvJyk7XHJcbiAgICAgICAgdGhpcy5fZW1pdFNldmVyYWxDb2RlUG9pbnRzKHRoaXMudGVtcEJ1ZmYpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoUkNEQVRBX1NUQVRFKTtcclxuICAgIH1cclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4xNCBSQVdURVhUIGxlc3MtdGhhbiBzaWduIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bUkFXVEVYVF9MRVNTX1RIQU5fU0lHTl9TVEFURV0gPSBmdW5jdGlvbiByYXd0ZXh0TGVzc1RoYW5TaWduU3RhdGUoY3ApIHtcclxuICAgIGlmIChjcCA9PT0gJC5TT0xJRFVTKSB7XHJcbiAgICAgICAgdGhpcy50ZW1wQnVmZiA9IFtdO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBSQVdURVhUX0VORF9UQUdfT1BFTl9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIHtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignPCcpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoUkFXVEVYVF9TVEFURSk7XHJcbiAgICB9XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuMTUgUkFXVEVYVCBlbmQgdGFnIG9wZW4gc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tSQVdURVhUX0VORF9UQUdfT1BFTl9TVEFURV0gPSBmdW5jdGlvbiByYXd0ZXh0RW5kVGFnT3BlblN0YXRlKGNwKSB7XHJcbiAgICBpZiAoaXNBc2NpaVVwcGVyKGNwKSkge1xyXG4gICAgICAgIHRoaXMuX2NyZWF0ZUVuZFRhZ1Rva2VuKHRvQXNjaWlMb3dlckNoYXIoY3ApKTtcclxuICAgICAgICB0aGlzLnRlbXBCdWZmLnB1c2goY3ApO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBSQVdURVhUX0VORF9UQUdfTkFNRV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChpc0FzY2lpTG93ZXIoY3ApKSB7XHJcbiAgICAgICAgdGhpcy5fY3JlYXRlRW5kVGFnVG9rZW4odG9DaGFyKGNwKSk7XHJcbiAgICAgICAgdGhpcy50ZW1wQnVmZi5wdXNoKGNwKTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gUkFXVEVYVF9FTkRfVEFHX05BTUVfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdGhpcy5fZW1pdENoYXIoJzwnKTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignLycpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoUkFXVEVYVF9TVEFURSk7XHJcbiAgICB9XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuMTYgUkFXVEVYVCBlbmQgdGFnIG5hbWUgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tSQVdURVhUX0VORF9UQUdfTkFNRV9TVEFURV0gPSBmdW5jdGlvbiByYXd0ZXh0RW5kVGFnTmFtZVN0YXRlKGNwKSB7XHJcbiAgICBpZiAoaXNBc2NpaVVwcGVyKGNwKSkge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLnRhZ05hbWUgKz0gdG9Bc2NpaUxvd2VyQ2hhcihjcCk7XHJcbiAgICAgICAgdGhpcy50ZW1wQnVmZi5wdXNoKGNwKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChpc0FzY2lpTG93ZXIoY3ApKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4udGFnTmFtZSArPSB0b0NoYXIoY3ApO1xyXG4gICAgICAgIHRoaXMudGVtcEJ1ZmYucHVzaChjcCk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2lzQXBwcm9wcmlhdGVFbmRUYWdUb2tlbigpKSB7XHJcbiAgICAgICAgICAgIGlmIChpc1doaXRlc3BhY2UoY3ApKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gQkVGT1JFX0FUVFJJQlVURV9OQU1FX1NUQVRFO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoY3AgPT09ICQuU09MSURVUykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNFTEZfQ0xPU0lOR19TVEFSVF9UQUdfU1RBVEU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChjcCA9PT0gJC5HUkVBVEVSX1RIQU5fU0lHTikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCc8Jyk7XHJcbiAgICAgICAgdGhpcy5fZW1pdENoYXIoJy8nKTtcclxuICAgICAgICB0aGlzLl9lbWl0U2V2ZXJhbENvZGVQb2ludHModGhpcy50ZW1wQnVmZik7XHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShSQVdURVhUX1NUQVRFKTtcclxuICAgIH1cclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4xNyBTY3JpcHQgZGF0YSBsZXNzLXRoYW4gc2lnbiBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW1NDUklQVF9EQVRBX0xFU1NfVEhBTl9TSUdOX1NUQVRFXSA9IGZ1bmN0aW9uIHNjcmlwdERhdGFMZXNzVGhhblNpZ25TdGF0ZShjcCkge1xyXG4gICAgaWYgKGNwID09PSAkLlNPTElEVVMpIHtcclxuICAgICAgICB0aGlzLnRlbXBCdWZmID0gW107XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNDUklQVF9EQVRBX0VORF9UQUdfT1BFTl9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5FWENMQU1BVElPTl9NQVJLKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNDUklQVF9EQVRBX0VTQ0FQRV9TVEFSVF9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignPCcpO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCchJyk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdGhpcy5fZW1pdENoYXIoJzwnKTtcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKFNDUklQVF9EQVRBX1NUQVRFKTtcclxuICAgIH1cclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4xOCBTY3JpcHQgZGF0YSBlbmQgdGFnIG9wZW4gc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tTQ1JJUFRfREFUQV9FTkRfVEFHX09QRU5fU1RBVEVdID0gZnVuY3Rpb24gc2NyaXB0RGF0YUVuZFRhZ09wZW5TdGF0ZShjcCkge1xyXG4gICAgaWYgKGlzQXNjaWlVcHBlcihjcCkpIHtcclxuICAgICAgICB0aGlzLl9jcmVhdGVFbmRUYWdUb2tlbih0b0FzY2lpTG93ZXJDaGFyKGNwKSk7XHJcbiAgICAgICAgdGhpcy50ZW1wQnVmZi5wdXNoKGNwKTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gU0NSSVBUX0RBVEFfRU5EX1RBR19OQU1FX1NUQVRFO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGlzQXNjaWlMb3dlcihjcCkpIHtcclxuICAgICAgICB0aGlzLl9jcmVhdGVFbmRUYWdUb2tlbih0b0NoYXIoY3ApKTtcclxuICAgICAgICB0aGlzLnRlbXBCdWZmLnB1c2goY3ApO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTQ1JJUFRfREFUQV9FTkRfVEFHX05BTUVfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdGhpcy5fZW1pdENoYXIoJzwnKTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignLycpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoU0NSSVBUX0RBVEFfU1RBVEUpO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjE5IFNjcmlwdCBkYXRhIGVuZCB0YWcgbmFtZSBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW1NDUklQVF9EQVRBX0VORF9UQUdfTkFNRV9TVEFURV0gPSBmdW5jdGlvbiBzY3JpcHREYXRhRW5kVGFnTmFtZVN0YXRlKGNwKSB7XHJcbiAgICBpZiAoaXNBc2NpaVVwcGVyKGNwKSkge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLnRhZ05hbWUgKz0gdG9Bc2NpaUxvd2VyQ2hhcihjcCk7XHJcbiAgICAgICAgdGhpcy50ZW1wQnVmZi5wdXNoKGNwKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChpc0FzY2lpTG93ZXIoY3ApKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4udGFnTmFtZSArPSB0b0NoYXIoY3ApO1xyXG4gICAgICAgIHRoaXMudGVtcEJ1ZmYucHVzaChjcCk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2lzQXBwcm9wcmlhdGVFbmRUYWdUb2tlbigpKSB7XHJcbiAgICAgICAgICAgIGlmIChpc1doaXRlc3BhY2UoY3ApKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gQkVGT1JFX0FUVFJJQlVURV9OQU1FX1NUQVRFO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBlbHNlIGlmIChjcCA9PT0gJC5TT0xJRFVTKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gU0VMRl9DTE9TSU5HX1NUQVJUX1RBR19TVEFURTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZWxzZSBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBEQVRBX1NUQVRFO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignPCcpO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCcvJyk7XHJcbiAgICAgICAgdGhpcy5fZW1pdFNldmVyYWxDb2RlUG9pbnRzKHRoaXMudGVtcEJ1ZmYpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoU0NSSVBUX0RBVEFfU1RBVEUpO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjIwIFNjcmlwdCBkYXRhIGVzY2FwZSBzdGFydCBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW1NDUklQVF9EQVRBX0VTQ0FQRV9TVEFSVF9TVEFURV0gPSBmdW5jdGlvbiBzY3JpcHREYXRhRXNjYXBlU3RhcnRTdGF0ZShjcCkge1xyXG4gICAgaWYgKGNwID09PSAkLkhZUEhFTl9NSU5VUykge1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTQ1JJUFRfREFUQV9FU0NBUEVfU1RBUlRfREFTSF9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignLScpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2VcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKFNDUklQVF9EQVRBX1NUQVRFKTtcclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4yMSBTY3JpcHQgZGF0YSBlc2NhcGUgc3RhcnQgZGFzaCBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW1NDUklQVF9EQVRBX0VTQ0FQRV9TVEFSVF9EQVNIX1NUQVRFXSA9IGZ1bmN0aW9uIHNjcmlwdERhdGFFc2NhcGVTdGFydERhc2hTdGF0ZShjcCkge1xyXG4gICAgaWYgKGNwID09PSAkLkhZUEhFTl9NSU5VUykge1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTQ1JJUFRfREFUQV9FU0NBUEVEX0RBU0hfREFTSF9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignLScpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2VcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKFNDUklQVF9EQVRBX1NUQVRFKTtcclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4yMiBTY3JpcHQgZGF0YSBlc2NhcGVkIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bU0NSSVBUX0RBVEFfRVNDQVBFRF9TVEFURV0gPSBmdW5jdGlvbiBzY3JpcHREYXRhRXNjYXBlZFN0YXRlKGNwKSB7XHJcbiAgICBpZiAoY3AgPT09ICQuSFlQSEVOX01JTlVTKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNDUklQVF9EQVRBX0VTQ0FQRURfREFTSF9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignLScpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkxFU1NfVEhBTl9TSUdOKVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTQ1JJUFRfREFUQV9FU0NBUEVEX0xFU1NfVEhBTl9TSUdOX1NUQVRFO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLk5VTEwpXHJcbiAgICAgICAgdGhpcy5fZW1pdENoYXIoVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVIpO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkVPRilcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG5cclxuICAgIGVsc2VcclxuICAgICAgICB0aGlzLl9lbWl0Q29kZVBvaW50KGNwKTtcclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4yMyBTY3JpcHQgZGF0YSBlc2NhcGVkIGRhc2ggc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tTQ1JJUFRfREFUQV9FU0NBUEVEX0RBU0hfU1RBVEVdID0gZnVuY3Rpb24gc2NyaXB0RGF0YUVzY2FwZWREYXNoU3RhdGUoY3ApIHtcclxuICAgIGlmIChjcCA9PT0gJC5IWVBIRU5fTUlOVVMpIHtcclxuICAgICAgICB0aGlzLnN0YXRlID0gU0NSSVBUX0RBVEFfRVNDQVBFRF9EQVNIX0RBU0hfU1RBVEU7XHJcbiAgICAgICAgdGhpcy5fZW1pdENoYXIoJy0nKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5MRVNTX1RIQU5fU0lHTilcclxuICAgICAgICB0aGlzLnN0YXRlID0gU0NSSVBUX0RBVEFfRVNDQVBFRF9MRVNTX1RIQU5fU0lHTl9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5OVUxMKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNDUklQVF9EQVRBX0VTQ0FQRURfU1RBVEU7XHJcbiAgICAgICAgdGhpcy5fZW1pdENoYXIoVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVIpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkVPRilcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG5cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTQ1JJUFRfREFUQV9FU0NBUEVEX1NUQVRFO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDb2RlUG9pbnQoY3ApO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjI0IFNjcmlwdCBkYXRhIGVzY2FwZWQgZGFzaCBkYXNoIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bU0NSSVBUX0RBVEFfRVNDQVBFRF9EQVNIX0RBU0hfU1RBVEVdID0gZnVuY3Rpb24gc2NyaXB0RGF0YUVzY2FwZWREYXNoRGFzaFN0YXRlKGNwKSB7XHJcbiAgICBpZiAoY3AgPT09ICQuSFlQSEVOX01JTlVTKVxyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCctJyk7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuTEVTU19USEFOX1NJR04pXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNDUklQVF9EQVRBX0VTQ0FQRURfTEVTU19USEFOX1NJR05fU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLnN0YXRlID0gU0NSSVBUX0RBVEFfU1RBVEU7XHJcbiAgICAgICAgdGhpcy5fZW1pdENoYXIoJz4nKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5OVUxMKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNDUklQVF9EQVRBX0VTQ0FQRURfU1RBVEU7XHJcbiAgICAgICAgdGhpcy5fZW1pdENoYXIoVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVIpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkVPRilcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG5cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTQ1JJUFRfREFUQV9FU0NBUEVEX1NUQVRFO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDb2RlUG9pbnQoY3ApO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjI1IFNjcmlwdCBkYXRhIGVzY2FwZWQgbGVzcy10aGFuIHNpZ24gc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tTQ1JJUFRfREFUQV9FU0NBUEVEX0xFU1NfVEhBTl9TSUdOX1NUQVRFXSA9IGZ1bmN0aW9uIHNjcmlwdERhdGFFc2NhcGVkTGVzc1RoYW5TaWduU3RhdGUoY3ApIHtcclxuICAgIGlmIChjcCA9PT0gJC5TT0xJRFVTKSB7XHJcbiAgICAgICAgdGhpcy50ZW1wQnVmZiA9IFtdO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTQ1JJUFRfREFUQV9FU0NBUEVEX0VORF9UQUdfT1BFTl9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChpc0FzY2lpVXBwZXIoY3ApKSB7XHJcbiAgICAgICAgdGhpcy50ZW1wQnVmZiA9IFtdO1xyXG4gICAgICAgIHRoaXMudGVtcEJ1ZmYucHVzaCh0b0FzY2lpTG93ZXJDb2RlUG9pbnQoY3ApKTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gU0NSSVBUX0RBVEFfRE9VQkxFX0VTQ0FQRV9TVEFSVF9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignPCcpO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDb2RlUG9pbnQoY3ApO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGlzQXNjaWlMb3dlcihjcCkpIHtcclxuICAgICAgICB0aGlzLnRlbXBCdWZmID0gW107XHJcbiAgICAgICAgdGhpcy50ZW1wQnVmZi5wdXNoKGNwKTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gU0NSSVBUX0RBVEFfRE9VQkxFX0VTQ0FQRV9TVEFSVF9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignPCcpO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDb2RlUG9pbnQoY3ApO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCc8Jyk7XHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShTQ1JJUFRfREFUQV9FU0NBUEVEX1NUQVRFKTtcclxuICAgIH1cclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4yNiBTY3JpcHQgZGF0YSBlc2NhcGVkIGVuZCB0YWcgb3BlbiBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW1NDUklQVF9EQVRBX0VTQ0FQRURfRU5EX1RBR19PUEVOX1NUQVRFXSA9IGZ1bmN0aW9uIHNjcmlwdERhdGFFc2NhcGVkRW5kVGFnT3BlblN0YXRlKGNwKSB7XHJcbiAgICBpZiAoaXNBc2NpaVVwcGVyKGNwKSkge1xyXG4gICAgICAgIHRoaXMuX2NyZWF0ZUVuZFRhZ1Rva2VuKHRvQXNjaWlMb3dlckNoYXIoY3ApKTtcclxuICAgICAgICB0aGlzLnRlbXBCdWZmLnB1c2goY3ApO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTQ1JJUFRfREFUQV9FU0NBUEVEX0VORF9UQUdfTkFNRV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChpc0FzY2lpTG93ZXIoY3ApKSB7XHJcbiAgICAgICAgdGhpcy5fY3JlYXRlRW5kVGFnVG9rZW4odG9DaGFyKGNwKSk7XHJcbiAgICAgICAgdGhpcy50ZW1wQnVmZi5wdXNoKGNwKTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gU0NSSVBUX0RBVEFfRVNDQVBFRF9FTkRfVEFHX05BTUVfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdGhpcy5fZW1pdENoYXIoJzwnKTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignLycpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoU0NSSVBUX0RBVEFfRVNDQVBFRF9TVEFURSk7XHJcbiAgICB9XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuMjcgU2NyaXB0IGRhdGEgZXNjYXBlZCBlbmQgdGFnIG5hbWUgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tTQ1JJUFRfREFUQV9FU0NBUEVEX0VORF9UQUdfTkFNRV9TVEFURV0gPSBmdW5jdGlvbiBzY3JpcHREYXRhRXNjYXBlZEVuZFRhZ05hbWVTdGF0ZShjcCkge1xyXG4gICAgaWYgKGlzQXNjaWlVcHBlcihjcCkpIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi50YWdOYW1lICs9IHRvQXNjaWlMb3dlckNoYXIoY3ApO1xyXG4gICAgICAgIHRoaXMudGVtcEJ1ZmYucHVzaChjcCk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoaXNBc2NpaUxvd2VyKGNwKSkge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLnRhZ05hbWUgKz0gdG9DaGFyKGNwKTtcclxuICAgICAgICB0aGlzLnRlbXBCdWZmLnB1c2goY3ApO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGlmICh0aGlzLl9pc0FwcHJvcHJpYXRlRW5kVGFnVG9rZW4oKSkge1xyXG4gICAgICAgICAgICBpZiAoaXNXaGl0ZXNwYWNlKGNwKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IEJFRk9SRV9BVFRSSUJVVEVfTkFNRV9TVEFURTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGNwID09PSAkLlNPTElEVVMpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTRUxGX0NMT1NJTkdfU1RBUlRfVEFHX1NUQVRFO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBEQVRBX1NUQVRFO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignPCcpO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCcvJyk7XHJcbiAgICAgICAgdGhpcy5fZW1pdFNldmVyYWxDb2RlUG9pbnRzKHRoaXMudGVtcEJ1ZmYpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoU0NSSVBUX0RBVEFfRVNDQVBFRF9TVEFURSk7XHJcbiAgICB9XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuMjggU2NyaXB0IGRhdGEgZG91YmxlIGVzY2FwZSBzdGFydCBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW1NDUklQVF9EQVRBX0RPVUJMRV9FU0NBUEVfU1RBUlRfU1RBVEVdID0gZnVuY3Rpb24gc2NyaXB0RGF0YURvdWJsZUVzY2FwZVN0YXJ0U3RhdGUoY3ApIHtcclxuICAgIGlmIChpc1doaXRlc3BhY2UoY3ApIHx8IGNwID09PSAkLlNPTElEVVMgfHwgY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLnN0YXRlID0gdGhpcy5pc1RlbXBCdWZmZXJFcXVhbFRvU2NyaXB0U3RyaW5nKCkgPyBTQ1JJUFRfREFUQV9ET1VCTEVfRVNDQVBFRF9TVEFURSA6IFNDUklQVF9EQVRBX0VTQ0FQRURfU1RBVEU7XHJcbiAgICAgICAgdGhpcy5fZW1pdENvZGVQb2ludChjcCk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoaXNBc2NpaVVwcGVyKGNwKSkge1xyXG4gICAgICAgIHRoaXMudGVtcEJ1ZmYucHVzaCh0b0FzY2lpTG93ZXJDb2RlUG9pbnQoY3ApKTtcclxuICAgICAgICB0aGlzLl9lbWl0Q29kZVBvaW50KGNwKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChpc0FzY2lpTG93ZXIoY3ApKSB7XHJcbiAgICAgICAgdGhpcy50ZW1wQnVmZi5wdXNoKGNwKTtcclxuICAgICAgICB0aGlzLl9lbWl0Q29kZVBvaW50KGNwKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlXHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShTQ1JJUFRfREFUQV9FU0NBUEVEX1NUQVRFKTtcclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4yOSBTY3JpcHQgZGF0YSBkb3VibGUgZXNjYXBlZCBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW1NDUklQVF9EQVRBX0RPVUJMRV9FU0NBUEVEX1NUQVRFXSA9IGZ1bmN0aW9uIHNjcmlwdERhdGFEb3VibGVFc2NhcGVkU3RhdGUoY3ApIHtcclxuICAgIGlmIChjcCA9PT0gJC5IWVBIRU5fTUlOVVMpIHtcclxuICAgICAgICB0aGlzLnN0YXRlID0gU0NSSVBUX0RBVEFfRE9VQkxFX0VTQ0FQRURfREFTSF9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignLScpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkxFU1NfVEhBTl9TSUdOKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNDUklQVF9EQVRBX0RPVUJMRV9FU0NBUEVEX0xFU1NfVEhBTl9TSUdOX1NUQVRFO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCc8Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuTlVMTClcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcihVTklDT0RFLlJFUExBQ0VNRU5UX0NIQVJBQ1RFUik7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKVxyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcblxyXG4gICAgZWxzZVxyXG4gICAgICAgIHRoaXMuX2VtaXRDb2RlUG9pbnQoY3ApO1xyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjMwIFNjcmlwdCBkYXRhIGRvdWJsZSBlc2NhcGVkIGRhc2ggc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tTQ1JJUFRfREFUQV9ET1VCTEVfRVNDQVBFRF9EQVNIX1NUQVRFXSA9IGZ1bmN0aW9uIHNjcmlwdERhdGFEb3VibGVFc2NhcGVkRGFzaFN0YXRlKGNwKSB7XHJcbiAgICBpZiAoY3AgPT09ICQuSFlQSEVOX01JTlVTKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNDUklQVF9EQVRBX0RPVUJMRV9FU0NBUEVEX0RBU0hfREFTSF9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignLScpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkxFU1NfVEhBTl9TSUdOKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNDUklQVF9EQVRBX0RPVUJMRV9FU0NBUEVEX0xFU1NfVEhBTl9TSUdOX1NUQVRFO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCc8Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuTlVMTCkge1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTQ1JJUFRfREFUQV9ET1VCTEVfRVNDQVBFRF9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcihVTklDT0RFLlJFUExBQ0VNRU5UX0NIQVJBQ1RFUik7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKVxyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNDUklQVF9EQVRBX0RPVUJMRV9FU0NBUEVEX1NUQVRFO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDb2RlUG9pbnQoY3ApO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjMxIFNjcmlwdCBkYXRhIGRvdWJsZSBlc2NhcGVkIGRhc2ggZGFzaCBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW1NDUklQVF9EQVRBX0RPVUJMRV9FU0NBUEVEX0RBU0hfREFTSF9TVEFURV0gPSBmdW5jdGlvbiBzY3JpcHREYXRhRG91YmxlRXNjYXBlZERhc2hEYXNoU3RhdGUoY3ApIHtcclxuICAgIGlmIChjcCA9PT0gJC5IWVBIRU5fTUlOVVMpXHJcbiAgICAgICAgdGhpcy5fZW1pdENoYXIoJy0nKTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5MRVNTX1RIQU5fU0lHTikge1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTQ1JJUFRfREFUQV9ET1VCTEVfRVNDQVBFRF9MRVNTX1RIQU5fU0lHTl9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcignPCcpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkdSRUFURVJfVEhBTl9TSUdOKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNDUklQVF9EQVRBX1NUQVRFO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCc+Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuTlVMTCkge1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTQ1JJUFRfREFUQV9ET1VCTEVfRVNDQVBFRF9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q2hhcihVTklDT0RFLlJFUExBQ0VNRU5UX0NIQVJBQ1RFUik7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKVxyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNDUklQVF9EQVRBX0RPVUJMRV9FU0NBUEVEX1NUQVRFO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDb2RlUG9pbnQoY3ApO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjMyIFNjcmlwdCBkYXRhIGRvdWJsZSBlc2NhcGVkIGxlc3MtdGhhbiBzaWduIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bU0NSSVBUX0RBVEFfRE9VQkxFX0VTQ0FQRURfTEVTU19USEFOX1NJR05fU1RBVEVdID0gZnVuY3Rpb24gc2NyaXB0RGF0YURvdWJsZUVzY2FwZWRMZXNzVGhhblNpZ25TdGF0ZShjcCkge1xyXG4gICAgaWYgKGNwID09PSAkLlNPTElEVVMpIHtcclxuICAgICAgICB0aGlzLnRlbXBCdWZmID0gW107XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNDUklQVF9EQVRBX0RPVUJMRV9FU0NBUEVfRU5EX1NUQVRFO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDaGFyKCcvJyk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZVxyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoU0NSSVBUX0RBVEFfRE9VQkxFX0VTQ0FQRURfU1RBVEUpO1xyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjMzIFNjcmlwdCBkYXRhIGRvdWJsZSBlc2NhcGUgZW5kIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bU0NSSVBUX0RBVEFfRE9VQkxFX0VTQ0FQRV9FTkRfU1RBVEVdID0gZnVuY3Rpb24gc2NyaXB0RGF0YURvdWJsZUVzY2FwZUVuZFN0YXRlKGNwKSB7XHJcbiAgICBpZiAoaXNXaGl0ZXNwYWNlKGNwKSB8fCBjcCA9PT0gJC5TT0xJRFVTIHx8IGNwID09PSAkLkdSRUFURVJfVEhBTl9TSUdOKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHRoaXMuaXNUZW1wQnVmZmVyRXF1YWxUb1NjcmlwdFN0cmluZygpID8gU0NSSVBUX0RBVEFfRVNDQVBFRF9TVEFURSA6IFNDUklQVF9EQVRBX0RPVUJMRV9FU0NBUEVEX1NUQVRFO1xyXG5cclxuICAgICAgICB0aGlzLl9lbWl0Q29kZVBvaW50KGNwKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChpc0FzY2lpVXBwZXIoY3ApKSB7XHJcbiAgICAgICAgdGhpcy50ZW1wQnVmZi5wdXNoKHRvQXNjaWlMb3dlckNvZGVQb2ludChjcCkpO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDb2RlUG9pbnQoY3ApO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGlzQXNjaWlMb3dlcihjcCkpIHtcclxuICAgICAgICB0aGlzLnRlbXBCdWZmLnB1c2goY3ApO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDb2RlUG9pbnQoY3ApO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2VcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKFNDUklQVF9EQVRBX0RPVUJMRV9FU0NBUEVEX1NUQVRFKTtcclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4zNCBCZWZvcmUgYXR0cmlidXRlIG5hbWUgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tCRUZPUkVfQVRUUklCVVRFX05BTUVfU1RBVEVdID0gZnVuY3Rpb24gYmVmb3JlQXR0cmlidXRlTmFtZVN0YXRlKGNwKSB7XHJcbiAgICBpZiAoaXNXaGl0ZXNwYWNlKGNwKSlcclxuICAgICAgICByZXR1cm47XHJcblxyXG4gICAgaWYgKGNwID09PSAkLlNPTElEVVMpXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNFTEZfQ0xPU0lOR19TVEFSVF9UQUdfU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLnN0YXRlID0gREFUQV9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoaXNBc2NpaVVwcGVyKGNwKSkge1xyXG4gICAgICAgIHRoaXMuX2NyZWF0ZUF0dHIodG9Bc2NpaUxvd2VyQ2hhcihjcCkpO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBBVFRSSUJVVEVfTkFNRV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5OVUxMKSB7XHJcbiAgICAgICAgdGhpcy5fY3JlYXRlQXR0cihVTklDT0RFLlJFUExBQ0VNRU5UX0NIQVJBQ1RFUik7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IEFUVFJJQlVURV9OQU1FX1NUQVRFO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLlFVT1RBVElPTl9NQVJLIHx8IGNwID09PSAkLkFQT1NUUk9QSEUgfHwgY3AgPT09ICQuTEVTU19USEFOX1NJR04gfHwgY3AgPT09ICQuRVFVQUxTX1NJR04pIHtcclxuICAgICAgICB0aGlzLl9jcmVhdGVBdHRyKHRvQ2hhcihjcCkpO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBBVFRSSUJVVEVfTkFNRV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5FT0YpXHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShEQVRBX1NUQVRFKTtcclxuXHJcbiAgICBlbHNlIHtcclxuICAgICAgICB0aGlzLl9jcmVhdGVBdHRyKHRvQ2hhcihjcCkpO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBBVFRSSUJVVEVfTkFNRV9TVEFURTtcclxuICAgIH1cclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4zNSBBdHRyaWJ1dGUgbmFtZSBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW0FUVFJJQlVURV9OQU1FX1NUQVRFXSA9IGZ1bmN0aW9uIGF0dHJpYnV0ZU5hbWVTdGF0ZShjcCkge1xyXG4gICAgaWYgKGlzV2hpdGVzcGFjZShjcCkpXHJcbiAgICAgICAgdGhpcy5fbGVhdmVBdHRyTmFtZShBRlRFUl9BVFRSSUJVVEVfTkFNRV9TVEFURSk7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuU09MSURVUylcclxuICAgICAgICB0aGlzLl9sZWF2ZUF0dHJOYW1lKFNFTEZfQ0xPU0lOR19TVEFSVF9UQUdfU1RBVEUpO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkVRVUFMU19TSUdOKVxyXG4gICAgICAgIHRoaXMuX2xlYXZlQXR0ck5hbWUoQkVGT1JFX0FUVFJJQlVURV9WQUxVRV9TVEFURSk7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLl9sZWF2ZUF0dHJOYW1lKERBVEFfU1RBVEUpO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChpc0FzY2lpVXBwZXIoY3ApKVxyXG4gICAgICAgIHRoaXMuY3VycmVudEF0dHIubmFtZSArPSB0b0FzY2lpTG93ZXJDaGFyKGNwKTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5RVU9UQVRJT05fTUFSSyB8fCBjcCA9PT0gJC5BUE9TVFJPUEhFIHx8IGNwID09PSAkLkxFU1NfVEhBTl9TSUdOKVxyXG4gICAgICAgIHRoaXMuY3VycmVudEF0dHIubmFtZSArPSB0b0NoYXIoY3ApO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLk5VTEwpXHJcbiAgICAgICAgdGhpcy5jdXJyZW50QXR0ci5uYW1lICs9IFVOSUNPREUuUkVQTEFDRU1FTlRfQ0hBUkFDVEVSO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkVPRilcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG5cclxuICAgIGVsc2VcclxuICAgICAgICB0aGlzLmN1cnJlbnRBdHRyLm5hbWUgKz0gdG9DaGFyKGNwKTtcclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4zNiBBZnRlciBhdHRyaWJ1dGUgbmFtZSBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW0FGVEVSX0FUVFJJQlVURV9OQU1FX1NUQVRFXSA9IGZ1bmN0aW9uIGFmdGVyQXR0cmlidXRlTmFtZVN0YXRlKGNwKSB7XHJcbiAgICBpZiAoaXNXaGl0ZXNwYWNlKGNwKSlcclxuICAgICAgICByZXR1cm47XHJcblxyXG4gICAgaWYgKGNwID09PSAkLlNPTElEVVMpXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNFTEZfQ0xPU0lOR19TVEFSVF9UQUdfU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRVFVQUxTX1NJR04pXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IEJFRk9SRV9BVFRSSUJVVEVfVkFMVUVfU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLnN0YXRlID0gREFUQV9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoaXNBc2NpaVVwcGVyKGNwKSkge1xyXG4gICAgICAgIHRoaXMuX2NyZWF0ZUF0dHIodG9Bc2NpaUxvd2VyQ2hhcihjcCkpO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBBVFRSSUJVVEVfTkFNRV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5OVUxMKSB7XHJcbiAgICAgICAgdGhpcy5fY3JlYXRlQXR0cihVTklDT0RFLlJFUExBQ0VNRU5UX0NIQVJBQ1RFUik7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IEFUVFJJQlVURV9OQU1FX1NUQVRFO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLlFVT1RBVElPTl9NQVJLIHx8IGNwID09PSAkLkFQT1NUUk9QSEUgfHwgY3AgPT09ICQuTEVTU19USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLl9jcmVhdGVBdHRyKHRvQ2hhcihjcCkpO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBBVFRSSUJVVEVfTkFNRV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5FT0YpXHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShEQVRBX1NUQVRFKTtcclxuXHJcbiAgICBlbHNlIHtcclxuICAgICAgICB0aGlzLl9jcmVhdGVBdHRyKHRvQ2hhcihjcCkpO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBBVFRSSUJVVEVfTkFNRV9TVEFURTtcclxuICAgIH1cclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4zNyBCZWZvcmUgYXR0cmlidXRlIHZhbHVlIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bQkVGT1JFX0FUVFJJQlVURV9WQUxVRV9TVEFURV0gPSBmdW5jdGlvbiBiZWZvcmVBdHRyaWJ1dGVWYWx1ZVN0YXRlKGNwKSB7XHJcbiAgICBpZiAoaXNXaGl0ZXNwYWNlKGNwKSlcclxuICAgICAgICByZXR1cm47XHJcblxyXG4gICAgaWYgKGNwID09PSAkLlFVT1RBVElPTl9NQVJLKVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBBVFRSSUJVVEVfVkFMVUVfRE9VQkxFX1FVT1RFRF9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5BTVBFUlNBTkQpXHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShBVFRSSUJVVEVfVkFMVUVfVU5RVU9URURfU1RBVEUpO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkFQT1NUUk9QSEUpXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IEFUVFJJQlVURV9WQUxVRV9TSU5HTEVfUVVPVEVEX1NUQVRFO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLk5VTEwpIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRBdHRyLnZhbHVlICs9IFVOSUNPREUuUkVQTEFDRU1FTlRfQ0hBUkFDVEVSO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBBVFRSSUJVVEVfVkFMVUVfVU5RVU9URURfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLnN0YXRlID0gREFUQV9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuTEVTU19USEFOX1NJR04gfHwgY3AgPT09ICQuRVFVQUxTX1NJR04gfHwgY3AgPT09ICQuR1JBVkVfQUNDRU5UKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50QXR0ci52YWx1ZSArPSB0b0NoYXIoY3ApO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBBVFRSSUJVVEVfVkFMVUVfVU5RVU9URURfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKVxyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50QXR0ci52YWx1ZSArPSB0b0NoYXIoY3ApO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBBVFRSSUJVVEVfVkFMVUVfVU5RVU9URURfU1RBVEU7XHJcbiAgICB9XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuMzggQXR0cmlidXRlIHZhbHVlIChkb3VibGUtcXVvdGVkKSBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW0FUVFJJQlVURV9WQUxVRV9ET1VCTEVfUVVPVEVEX1NUQVRFXSA9IGZ1bmN0aW9uIGF0dHJpYnV0ZVZhbHVlRG91YmxlUXVvdGVkU3RhdGUoY3ApIHtcclxuICAgIGlmIChjcCA9PT0gJC5RVU9UQVRJT05fTUFSSylcclxuICAgICAgICB0aGlzLnN0YXRlID0gQUZURVJfQVRUUklCVVRFX1ZBTFVFX1FVT1RFRF9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5BTVBFUlNBTkQpIHtcclxuICAgICAgICB0aGlzLmFkZGl0aW9uYWxBbGxvd2VkQ3AgPSAkLlFVT1RBVElPTl9NQVJLO1xyXG4gICAgICAgIHRoaXMucmV0dXJuU3RhdGUgPSB0aGlzLnN0YXRlO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBDSEFSQUNURVJfUkVGRVJFTkNFX0lOX0FUVFJJQlVURV9WQUxVRV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5OVUxMKVxyXG4gICAgICAgIHRoaXMuY3VycmVudEF0dHIudmFsdWUgKz0gVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVI7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKVxyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcblxyXG4gICAgZWxzZVxyXG4gICAgICAgIHRoaXMuY3VycmVudEF0dHIudmFsdWUgKz0gdG9DaGFyKGNwKTtcclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC4zOSBBdHRyaWJ1dGUgdmFsdWUgKHNpbmdsZS1xdW90ZWQpIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bQVRUUklCVVRFX1ZBTFVFX1NJTkdMRV9RVU9URURfU1RBVEVdID0gZnVuY3Rpb24gYXR0cmlidXRlVmFsdWVTaW5nbGVRdW90ZWRTdGF0ZShjcCkge1xyXG4gICAgaWYgKGNwID09PSAkLkFQT1NUUk9QSEUpXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IEFGVEVSX0FUVFJJQlVURV9WQUxVRV9RVU9URURfU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuQU1QRVJTQU5EKSB7XHJcbiAgICAgICAgdGhpcy5hZGRpdGlvbmFsQWxsb3dlZENwID0gJC5BUE9TVFJPUEhFO1xyXG4gICAgICAgIHRoaXMucmV0dXJuU3RhdGUgPSB0aGlzLnN0YXRlO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBDSEFSQUNURVJfUkVGRVJFTkNFX0lOX0FUVFJJQlVURV9WQUxVRV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5OVUxMKVxyXG4gICAgICAgIHRoaXMuY3VycmVudEF0dHIudmFsdWUgKz0gVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVI7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKVxyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcblxyXG4gICAgZWxzZVxyXG4gICAgICAgIHRoaXMuY3VycmVudEF0dHIudmFsdWUgKz0gdG9DaGFyKGNwKTtcclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC40MCBBdHRyaWJ1dGUgdmFsdWUgKHVucXVvdGVkKSBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW0FUVFJJQlVURV9WQUxVRV9VTlFVT1RFRF9TVEFURV0gPSBmdW5jdGlvbiBhdHRyaWJ1dGVWYWx1ZVVucXVvdGVkU3RhdGUoY3ApIHtcclxuICAgIGlmIChpc1doaXRlc3BhY2UoY3ApKVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBCRUZPUkVfQVRUUklCVVRFX05BTUVfU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuQU1QRVJTQU5EKSB7XHJcbiAgICAgICAgdGhpcy5hZGRpdGlvbmFsQWxsb3dlZENwID0gJC5HUkVBVEVSX1RIQU5fU0lHTjtcclxuICAgICAgICB0aGlzLnJldHVyblN0YXRlID0gdGhpcy5zdGF0ZTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gQ0hBUkFDVEVSX1JFRkVSRU5DRV9JTl9BVFRSSUJVVEVfVkFMVUVfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLnN0YXRlID0gREFUQV9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuTlVMTClcclxuICAgICAgICB0aGlzLmN1cnJlbnRBdHRyLnZhbHVlICs9IFVOSUNPREUuUkVQTEFDRU1FTlRfQ0hBUkFDVEVSO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLlFVT1RBVElPTl9NQVJLIHx8IGNwID09PSAkLkFQT1NUUk9QSEUgfHwgY3AgPT09ICQuTEVTU19USEFOX1NJR04gfHxcclxuICAgICAgICAgICAgIGNwID09PSAkLkVRVUFMU19TSUdOIHx8IGNwID09PSAkLkdSQVZFX0FDQ0VOVCkge1xyXG4gICAgICAgIHRoaXMuY3VycmVudEF0dHIudmFsdWUgKz0gdG9DaGFyKGNwKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5FT0YpXHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShEQVRBX1NUQVRFKTtcclxuXHJcbiAgICBlbHNlXHJcbiAgICAgICAgdGhpcy5jdXJyZW50QXR0ci52YWx1ZSArPSB0b0NoYXIoY3ApO1xyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjQxIENoYXJhY3RlciByZWZlcmVuY2UgaW4gYXR0cmlidXRlIHZhbHVlIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bQ0hBUkFDVEVSX1JFRkVSRU5DRV9JTl9BVFRSSUJVVEVfVkFMVUVfU1RBVEVdID0gZnVuY3Rpb24gY2hhcmFjdGVyUmVmZXJlbmNlSW5BdHRyaWJ1dGVWYWx1ZVN0YXRlKGNwKSB7XHJcbiAgICB2YXIgcmVmZXJlbmNlZENvZGVQb2ludHMgPSB0aGlzLl9jb25zdW1lQ2hhcmFjdGVyUmVmZXJlbmNlKGNwLCB0cnVlKTtcclxuXHJcbiAgICBpZiAocmVmZXJlbmNlZENvZGVQb2ludHMpIHtcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlZmVyZW5jZWRDb2RlUG9pbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRBdHRyLnZhbHVlICs9IHRvQ2hhcihyZWZlcmVuY2VkQ29kZVBvaW50c1tpXSk7XHJcbiAgICB9IGVsc2VcclxuICAgICAgICB0aGlzLmN1cnJlbnRBdHRyLnZhbHVlICs9ICcmJztcclxuXHJcbiAgICB0aGlzLnN0YXRlID0gdGhpcy5yZXR1cm5TdGF0ZTtcclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC40MiBBZnRlciBhdHRyaWJ1dGUgdmFsdWUgKHF1b3RlZCkgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tBRlRFUl9BVFRSSUJVVEVfVkFMVUVfUVVPVEVEX1NUQVRFXSA9IGZ1bmN0aW9uIGFmdGVyQXR0cmlidXRlVmFsdWVRdW90ZWRTdGF0ZShjcCkge1xyXG4gICAgaWYgKGlzV2hpdGVzcGFjZShjcCkpXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IEJFRk9SRV9BVFRSSUJVVEVfTkFNRV9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5TT0xJRFVTKVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTRUxGX0NMT1NJTkdfU1RBUlRfVEFHX1NUQVRFO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkdSRUFURVJfVEhBTl9TSUdOKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkVPRilcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG5cclxuICAgIGVsc2VcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKEJFRk9SRV9BVFRSSUJVVEVfTkFNRV9TVEFURSk7XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuNDMgU2VsZi1jbG9zaW5nIHN0YXJ0IHRhZyBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW1NFTEZfQ0xPU0lOR19TVEFSVF9UQUdfU1RBVEVdID0gZnVuY3Rpb24gc2VsZkNsb3NpbmdTdGFydFRhZ1N0YXRlKGNwKSB7XHJcbiAgICBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5zZWxmQ2xvc2luZyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkVPRilcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG5cclxuICAgIGVsc2VcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKEJFRk9SRV9BVFRSSUJVVEVfTkFNRV9TVEFURSk7XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuNDQgQm9ndXMgY29tbWVudCBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW0JPR1VTX0NPTU1FTlRfU1RBVEVdID0gZnVuY3Rpb24gYm9ndXNDb21tZW50U3RhdGUoY3ApIHtcclxuICAgIHRoaXMuX2NyZWF0ZUNvbW1lbnRUb2tlbigpO1xyXG5cclxuICAgIHdoaWxlICh0cnVlKSB7XHJcbiAgICAgICAgaWYgKGNwID09PSAkLkdSRUFURVJfVEhBTl9TSUdOKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBEQVRBX1NUQVRFO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGVsc2UgaWYgKGNwID09PSAkLkVPRikge1xyXG4gICAgICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5kYXRhICs9IGNwID09PSAkLk5VTEwgPyBVTklDT0RFLlJFUExBQ0VNRU5UX0NIQVJBQ1RFUiA6IHRvQ2hhcihjcCk7XHJcbiAgICAgICAgICAgIGNwID0gdGhpcy5fY29uc3VtZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuNDUgTWFya3VwIGRlY2xhcmF0aW9uIG9wZW4gc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tNQVJLVVBfREVDTEFSQVRJT05fT1BFTl9TVEFURV0gPSBmdW5jdGlvbiBtYXJrdXBEZWNsYXJhdGlvbk9wZW5TdGF0ZShjcCkge1xyXG4gICAgaWYgKHRoaXMuX2NvbnN1bWVTdWJzZXF1ZW50SWZNYXRjaCgkJC5EQVNIX0RBU0hfU1RSSU5HLCBjcCwgdHJ1ZSkpIHtcclxuICAgICAgICB0aGlzLl9jcmVhdGVDb21tZW50VG9rZW4oKTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gQ09NTUVOVF9TVEFSVF9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmICh0aGlzLl9jb25zdW1lU3Vic2VxdWVudElmTWF0Y2goJCQuRE9DVFlQRV9TVFJJTkcsIGNwLCBmYWxzZSkpXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERPQ1RZUEVfU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAodGhpcy5hbGxvd0NEQVRBICYmIHRoaXMuX2NvbnN1bWVTdWJzZXF1ZW50SWZNYXRjaCgkJC5DREFUQV9TVEFSVF9TVFJJTkcsIGNwLCB0cnVlKSlcclxuICAgICAgICB0aGlzLnN0YXRlID0gQ0RBVEFfU0VDVElPTl9TVEFURTtcclxuXHJcbiAgICBlbHNlIHtcclxuICAgICAgICAvL05PVEU6IGNhbGwgYm9ndXMgY29tbWVudCBzdGF0ZSBkaXJlY3RseSB3aXRoIGN1cnJlbnQgY29uc3VtZWQgY2hhcmFjdGVyIHRvIGF2b2lkIHVubmVjZXNzYXJ5IHJlY29uc3VtcHRpb24uXHJcbiAgICAgICAgdGhpc1tCT0dVU19DT01NRU5UX1NUQVRFXShjcCk7XHJcbiAgICB9XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuNDYgQ29tbWVudCBzdGFydCBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW0NPTU1FTlRfU1RBUlRfU1RBVEVdID0gZnVuY3Rpb24gY29tbWVudFN0YXJ0U3RhdGUoY3ApIHtcclxuICAgIGlmIChjcCA9PT0gJC5IWVBIRU5fTUlOVVMpXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IENPTU1FTlRfU1RBUlRfREFTSF9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5OVUxMKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZGF0YSArPSBVTklDT0RFLlJFUExBQ0VNRU5UX0NIQVJBQ1RFUjtcclxuICAgICAgICB0aGlzLnN0YXRlID0gQ09NTUVOVF9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5HUkVBVEVSX1RIQU5fU0lHTikge1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBEQVRBX1NUQVRFO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5FT0YpIHtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShEQVRBX1NUQVRFKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5kYXRhICs9IHRvQ2hhcihjcCk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IENPTU1FTlRfU1RBVEU7XHJcbiAgICB9XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuNDcgQ29tbWVudCBzdGFydCBkYXNoIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bQ09NTUVOVF9TVEFSVF9EQVNIX1NUQVRFXSA9IGZ1bmN0aW9uIGNvbW1lbnRTdGFydERhc2hTdGF0ZShjcCkge1xyXG4gICAgaWYgKGNwID09PSAkLkhZUEhFTl9NSU5VUylcclxuICAgICAgICB0aGlzLnN0YXRlID0gQ09NTUVOVF9FTkRfU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuTlVMTCkge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmRhdGEgKz0gJy0nO1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmRhdGEgKz0gVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVI7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IENPTU1FTlRfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLnN0YXRlID0gREFUQV9TVEFURTtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKSB7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZGF0YSArPSAnLSc7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZGF0YSArPSB0b0NoYXIoY3ApO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBDT01NRU5UX1NUQVRFO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjQ4IENvbW1lbnQgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tDT01NRU5UX1NUQVRFXSA9IGZ1bmN0aW9uIGNvbW1lbnRTdGF0ZShjcCkge1xyXG4gICAgaWYgKGNwID09PSAkLkhZUEhFTl9NSU5VUylcclxuICAgICAgICB0aGlzLnN0YXRlID0gQ09NTUVOVF9FTkRfREFTSF9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5OVUxMKVxyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmRhdGEgKz0gVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVI7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKSB7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZVxyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmRhdGEgKz0gdG9DaGFyKGNwKTtcclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC40OSBDb21tZW50IGVuZCBkYXNoIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bQ09NTUVOVF9FTkRfREFTSF9TVEFURV0gPSBmdW5jdGlvbiBjb21tZW50RW5kRGFzaFN0YXRlKGNwKSB7XHJcbiAgICBpZiAoY3AgPT09ICQuSFlQSEVOX01JTlVTKVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBDT01NRU5UX0VORF9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5OVUxMKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZGF0YSArPSAnLSc7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZGF0YSArPSBVTklDT0RFLlJFUExBQ0VNRU5UX0NIQVJBQ1RFUjtcclxuICAgICAgICB0aGlzLnN0YXRlID0gQ09NTUVOVF9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5FT0YpIHtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShEQVRBX1NUQVRFKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5kYXRhICs9ICctJztcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5kYXRhICs9IHRvQ2hhcihjcCk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IENPTU1FTlRfU1RBVEU7XHJcbiAgICB9XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuNTAgQ29tbWVudCBlbmQgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tDT01NRU5UX0VORF9TVEFURV0gPSBmdW5jdGlvbiBjb21tZW50RW5kU3RhdGUoY3ApIHtcclxuICAgIGlmIChjcCA9PT0gJC5HUkVBVEVSX1RIQU5fU0lHTikge1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBEQVRBX1NUQVRFO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5FWENMQU1BVElPTl9NQVJLKVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBDT01NRU5UX0VORF9CQU5HX1NUQVRFO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkhZUEhFTl9NSU5VUylcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5kYXRhICs9ICctJztcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5OVUxMKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZGF0YSArPSAnLS0nO1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmRhdGEgKz0gVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVI7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IENPTU1FTlRfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKSB7XHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShEQVRBX1NUQVRFKTtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZGF0YSArPSAnLS0nO1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmRhdGEgKz0gdG9DaGFyKGNwKTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gQ09NTUVOVF9TVEFURTtcclxuICAgIH1cclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC41MSBDb21tZW50IGVuZCBiYW5nIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bQ09NTUVOVF9FTkRfQkFOR19TVEFURV0gPSBmdW5jdGlvbiBjb21tZW50RW5kQmFuZ1N0YXRlKGNwKSB7XHJcbiAgICBpZiAoY3AgPT09ICQuSFlQSEVOX01JTlVTKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZGF0YSArPSAnLS0hJztcclxuICAgICAgICB0aGlzLnN0YXRlID0gQ09NTUVOVF9FTkRfREFTSF9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5HUkVBVEVSX1RIQU5fU0lHTikge1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBEQVRBX1NUQVRFO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5OVUxMKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZGF0YSArPSAnLS0hJztcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5kYXRhICs9IFVOSUNPREUuUkVQTEFDRU1FTlRfQ0hBUkFDVEVSO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBDT01NRU5UX1NUQVRFO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkVPRikge1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmRhdGEgKz0gJy0tISc7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZGF0YSArPSB0b0NoYXIoY3ApO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBDT01NRU5UX1NUQVRFO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjUyIERPQ1RZUEUgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tET0NUWVBFX1NUQVRFXSA9IGZ1bmN0aW9uIGRvY3R5cGVTdGF0ZShjcCkge1xyXG4gICAgaWYgKGlzV2hpdGVzcGFjZShjcCkpXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IEJFRk9SRV9ET0NUWVBFX05BTUVfU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKSB7XHJcbiAgICAgICAgdGhpcy5fY3JlYXRlRG9jdHlwZVRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZm9yY2VRdWlya3MgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2VcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKEJFRk9SRV9ET0NUWVBFX05BTUVfU1RBVEUpO1xyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjUzIEJlZm9yZSBET0NUWVBFIG5hbWUgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tCRUZPUkVfRE9DVFlQRV9OQU1FX1NUQVRFXSA9IGZ1bmN0aW9uIGJlZm9yZURvY3R5cGVOYW1lU3RhdGUoY3ApIHtcclxuICAgIGlmIChpc1doaXRlc3BhY2UoY3ApKVxyXG4gICAgICAgIHJldHVybjtcclxuXHJcbiAgICBpZiAoaXNBc2NpaVVwcGVyKGNwKSkge1xyXG4gICAgICAgIHRoaXMuX2NyZWF0ZURvY3R5cGVUb2tlbih0b0FzY2lpTG93ZXJDaGFyKGNwKSk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERPQ1RZUEVfTkFNRV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5HUkVBVEVSX1RIQU5fU0lHTikge1xyXG4gICAgICAgIHRoaXMuX2NyZWF0ZURvY3R5cGVUb2tlbigpO1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmZvcmNlUXVpcmtzID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKSB7XHJcbiAgICAgICAgdGhpcy5fY3JlYXRlRG9jdHlwZVRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZm9yY2VRdWlya3MgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLk5VTEwpIHtcclxuICAgICAgICB0aGlzLl9jcmVhdGVEb2N0eXBlVG9rZW4oVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVIpO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBET0NUWVBFX05BTUVfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdGhpcy5fY3JlYXRlRG9jdHlwZVRva2VuKHRvQ2hhcihjcCkpO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBET0NUWVBFX05BTUVfU1RBVEU7XHJcbiAgICB9XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuNTQgRE9DVFlQRSBuYW1lIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bRE9DVFlQRV9OQU1FX1NUQVRFXSA9IGZ1bmN0aW9uIGRvY3R5cGVOYW1lU3RhdGUoY3ApIHtcclxuICAgIGlmIChpc1doaXRlc3BhY2UoY3ApKVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBBRlRFUl9ET0NUWVBFX05BTUVfU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoaXNBc2NpaVVwcGVyKGNwKSlcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5uYW1lICs9IHRvQXNjaWlMb3dlckNoYXIoY3ApO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLk5VTEwpXHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4ubmFtZSArPSBVTklDT0RFLlJFUExBQ0VNRU5UX0NIQVJBQ1RFUjtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5FT0YpIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5mb3JjZVF1aXJrcyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZVxyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLm5hbWUgKz0gdG9DaGFyKGNwKTtcclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC41NSBBZnRlciBET0NUWVBFIG5hbWUgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tBRlRFUl9ET0NUWVBFX05BTUVfU1RBVEVdID0gZnVuY3Rpb24gYWZ0ZXJEb2N0eXBlTmFtZVN0YXRlKGNwKSB7XHJcbiAgICBpZiAoaXNXaGl0ZXNwYWNlKGNwKSlcclxuICAgICAgICByZXR1cm47XHJcblxyXG4gICAgaWYgKGNwID09PSAkLkdSRUFURVJfVEhBTl9TSUdOKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkVPRikge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmZvcmNlUXVpcmtzID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShEQVRBX1NUQVRFKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmICh0aGlzLl9jb25zdW1lU3Vic2VxdWVudElmTWF0Y2goJCQuUFVCTElDX1NUUklORywgY3AsIGZhbHNlKSlcclxuICAgICAgICB0aGlzLnN0YXRlID0gQUZURVJfRE9DVFlQRV9QVUJMSUNfS0VZV09SRF9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmICh0aGlzLl9jb25zdW1lU3Vic2VxdWVudElmTWF0Y2goJCQuU1lTVEVNX1NUUklORywgY3AsIGZhbHNlKSlcclxuICAgICAgICB0aGlzLnN0YXRlID0gQUZURVJfRE9DVFlQRV9TWVNURU1fS0VZV09SRF9TVEFURTtcclxuXHJcbiAgICBlbHNlIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5mb3JjZVF1aXJrcyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IEJPR1VTX0RPQ1RZUEVfU1RBVEU7XHJcbiAgICB9XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuNTYgQWZ0ZXIgRE9DVFlQRSBwdWJsaWMga2V5d29yZCBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW0FGVEVSX0RPQ1RZUEVfUFVCTElDX0tFWVdPUkRfU1RBVEVdID0gZnVuY3Rpb24gYWZ0ZXJEb2N0eXBlUHVibGljS2V5d29yZFN0YXRlKGNwKSB7XHJcbiAgICBpZiAoaXNXaGl0ZXNwYWNlKGNwKSlcclxuICAgICAgICB0aGlzLnN0YXRlID0gQkVGT1JFX0RPQ1RZUEVfUFVCTElDX0lERU5USUZJRVJfU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuUVVPVEFUSU9OX01BUkspIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5wdWJsaWNJZCA9ICcnO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBET0NUWVBFX1BVQkxJQ19JREVOVElGSUVSX0RPVUJMRV9RVU9URURfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuQVBPU1RST1BIRSkge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLnB1YmxpY0lkID0gJyc7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERPQ1RZUEVfUFVCTElDX0lERU5USUZJRVJfU0lOR0xFX1FVT1RFRF9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5HUkVBVEVSX1RIQU5fU0lHTikge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmZvcmNlUXVpcmtzID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZm9yY2VRdWlya3MgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmZvcmNlUXVpcmtzID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gQk9HVVNfRE9DVFlQRV9TVEFURTtcclxuICAgIH1cclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC41NyBCZWZvcmUgRE9DVFlQRSBwdWJsaWMgaWRlbnRpZmllciBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW0JFRk9SRV9ET0NUWVBFX1BVQkxJQ19JREVOVElGSUVSX1NUQVRFXSA9IGZ1bmN0aW9uIGJlZm9yZURvY3R5cGVQdWJsaWNJZGVudGlmaWVyU3RhdGUoY3ApIHtcclxuICAgIGlmIChpc1doaXRlc3BhY2UoY3ApKVxyXG4gICAgICAgIHJldHVybjtcclxuXHJcbiAgICBpZiAoY3AgPT09ICQuUVVPVEFUSU9OX01BUkspIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5wdWJsaWNJZCA9ICcnO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBET0NUWVBFX1BVQkxJQ19JREVOVElGSUVSX0RPVUJMRV9RVU9URURfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuQVBPU1RST1BIRSkge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLnB1YmxpY0lkID0gJyc7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERPQ1RZUEVfUFVCTElDX0lERU5USUZJRVJfU0lOR0xFX1FVT1RFRF9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5HUkVBVEVSX1RIQU5fU0lHTikge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmZvcmNlUXVpcmtzID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZm9yY2VRdWlya3MgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmZvcmNlUXVpcmtzID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gQk9HVVNfRE9DVFlQRV9TVEFURTtcclxuICAgIH1cclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC41OCBET0NUWVBFIHB1YmxpYyBpZGVudGlmaWVyIChkb3VibGUtcXVvdGVkKSBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW0RPQ1RZUEVfUFVCTElDX0lERU5USUZJRVJfRE9VQkxFX1FVT1RFRF9TVEFURV0gPSBmdW5jdGlvbiBkb2N0eXBlUHVibGljSWRlbnRpZmllckRvdWJsZVF1b3RlZFN0YXRlKGNwKSB7XHJcbiAgICBpZiAoY3AgPT09ICQuUVVPVEFUSU9OX01BUkspXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IEFGVEVSX0RPQ1RZUEVfUFVCTElDX0lERU5USUZJRVJfU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuTlVMTClcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5wdWJsaWNJZCArPSBVTklDT0RFLlJFUExBQ0VNRU5UX0NIQVJBQ1RFUjtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5HUkVBVEVSX1RIQU5fU0lHTikge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmZvcmNlUXVpcmtzID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZm9yY2VRdWlya3MgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2VcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5wdWJsaWNJZCArPSB0b0NoYXIoY3ApO1xyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjU5IERPQ1RZUEUgcHVibGljIGlkZW50aWZpZXIgKHNpbmdsZS1xdW90ZWQpIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bRE9DVFlQRV9QVUJMSUNfSURFTlRJRklFUl9TSU5HTEVfUVVPVEVEX1NUQVRFXSA9IGZ1bmN0aW9uIGRvY3R5cGVQdWJsaWNJZGVudGlmaWVyU2luZ2xlUXVvdGVkU3RhdGUoY3ApIHtcclxuICAgIGlmIChjcCA9PT0gJC5BUE9TVFJPUEhFKVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBBRlRFUl9ET0NUWVBFX1BVQkxJQ19JREVOVElGSUVSX1NUQVRFO1xyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLk5VTEwpXHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4ucHVibGljSWQgKz0gVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVI7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5mb3JjZVF1aXJrcyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBEQVRBX1NUQVRFO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkVPRikge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmZvcmNlUXVpcmtzID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5fcmVjb25zdW1lSW5TdGF0ZShEQVRBX1NUQVRFKTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlXHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4ucHVibGljSWQgKz0gdG9DaGFyKGNwKTtcclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC42MCBBZnRlciBET0NUWVBFIHB1YmxpYyBpZGVudGlmaWVyIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bQUZURVJfRE9DVFlQRV9QVUJMSUNfSURFTlRJRklFUl9TVEFURV0gPSBmdW5jdGlvbiBhZnRlckRvY3R5cGVQdWJsaWNJZGVudGlmaWVyU3RhdGUoY3ApIHtcclxuICAgIGlmIChpc1doaXRlc3BhY2UoY3ApKVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBCRVRXRUVOX0RPQ1RZUEVfUFVCTElDX0FORF9TWVNURU1fSURFTlRJRklFUlNfU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuUVVPVEFUSU9OX01BUkspIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5zeXN0ZW1JZCA9ICcnO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBET0NUWVBFX1NZU1RFTV9JREVOVElGSUVSX0RPVUJMRV9RVU9URURfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuQVBPU1RST1BIRSkge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLnN5c3RlbUlkID0gJyc7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERPQ1RZUEVfU1lTVEVNX0lERU5USUZJRVJfU0lOR0xFX1FVT1RFRF9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5FT0YpIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5mb3JjZVF1aXJrcyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZm9yY2VRdWlya3MgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBCT0dVU19ET0NUWVBFX1NUQVRFO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjYxIEJldHdlZW4gRE9DVFlQRSBwdWJsaWMgYW5kIHN5c3RlbSBpZGVudGlmaWVycyBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW0JFVFdFRU5fRE9DVFlQRV9QVUJMSUNfQU5EX1NZU1RFTV9JREVOVElGSUVSU19TVEFURV0gPSBmdW5jdGlvbiBiZXR3ZWVuRG9jdHlwZVB1YmxpY0FuZFN5c3RlbUlkZW50aWZpZXJzU3RhdGUoY3ApIHtcclxuICAgIGlmIChpc1doaXRlc3BhY2UoY3ApKVxyXG4gICAgICAgIHJldHVybjtcclxuXHJcbiAgICBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuUVVPVEFUSU9OX01BUkspIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5zeXN0ZW1JZCA9ICcnO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBET0NUWVBFX1NZU1RFTV9JREVOVElGSUVSX0RPVUJMRV9RVU9URURfU1RBVEU7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkFQT1NUUk9QSEUpIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5zeXN0ZW1JZCA9ICcnO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBET0NUWVBFX1NZU1RFTV9JREVOVElGSUVSX1NJTkdMRV9RVU9URURfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZm9yY2VRdWlya3MgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmZvcmNlUXVpcmtzID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gQk9HVVNfRE9DVFlQRV9TVEFURTtcclxuICAgIH1cclxufTtcclxuXHJcblxyXG4vLzEyLjIuNC42MiBBZnRlciBET0NUWVBFIHN5c3RlbSBrZXl3b3JkIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bQUZURVJfRE9DVFlQRV9TWVNURU1fS0VZV09SRF9TVEFURV0gPSBmdW5jdGlvbiBhZnRlckRvY3R5cGVTeXN0ZW1LZXl3b3JkU3RhdGUoY3ApIHtcclxuICAgIGlmIChpc1doaXRlc3BhY2UoY3ApKVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBCRUZPUkVfRE9DVFlQRV9TWVNURU1fSURFTlRJRklFUl9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5RVU9UQVRJT05fTUFSSykge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLnN5c3RlbUlkID0gJyc7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERPQ1RZUEVfU1lTVEVNX0lERU5USUZJRVJfRE9VQkxFX1FVT1RFRF9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5BUE9TVFJPUEhFKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uc3lzdGVtSWQgPSAnJztcclxuICAgICAgICB0aGlzLnN0YXRlID0gRE9DVFlQRV9TWVNURU1fSURFTlRJRklFUl9TSU5HTEVfUVVPVEVEX1NUQVRFO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkdSRUFURVJfVEhBTl9TSUdOKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZm9yY2VRdWlya3MgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gREFUQV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5FT0YpIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5mb3JjZVF1aXJrcyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZm9yY2VRdWlya3MgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBCT0dVU19ET0NUWVBFX1NUQVRFO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjYzIEJlZm9yZSBET0NUWVBFIHN5c3RlbSBpZGVudGlmaWVyIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bQkVGT1JFX0RPQ1RZUEVfU1lTVEVNX0lERU5USUZJRVJfU1RBVEVdID0gZnVuY3Rpb24gYmVmb3JlRG9jdHlwZVN5c3RlbUlkZW50aWZpZXJTdGF0ZShjcCkge1xyXG4gICAgaWYgKGlzV2hpdGVzcGFjZShjcCkpXHJcbiAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgIGlmIChjcCA9PT0gJC5RVU9UQVRJT05fTUFSSykge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLnN5c3RlbUlkID0gJyc7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERPQ1RZUEVfU1lTVEVNX0lERU5USUZJRVJfRE9VQkxFX1FVT1RFRF9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5BUE9TVFJPUEhFKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uc3lzdGVtSWQgPSAnJztcclxuICAgICAgICB0aGlzLnN0YXRlID0gRE9DVFlQRV9TWVNURU1fSURFTlRJRklFUl9TSU5HTEVfUVVPVEVEX1NUQVRFO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLkdSRUFURVJfVEhBTl9TSUdOKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZm9yY2VRdWlya3MgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gREFUQV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5FT0YpIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5mb3JjZVF1aXJrcyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZm9yY2VRdWlya3MgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBCT0dVU19ET0NUWVBFX1NUQVRFO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjY0IERPQ1RZUEUgc3lzdGVtIGlkZW50aWZpZXIgKGRvdWJsZS1xdW90ZWQpIHN0YXRlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbl9bRE9DVFlQRV9TWVNURU1fSURFTlRJRklFUl9ET1VCTEVfUVVPVEVEX1NUQVRFXSA9IGZ1bmN0aW9uIGRvY3R5cGVTeXN0ZW1JZGVudGlmaWVyRG91YmxlUXVvdGVkU3RhdGUoY3ApIHtcclxuICAgIGlmIChjcCA9PT0gJC5RVU9UQVRJT05fTUFSSylcclxuICAgICAgICB0aGlzLnN0YXRlID0gQUZURVJfRE9DVFlQRV9TWVNURU1fSURFTlRJRklFUl9TVEFURTtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5HUkVBVEVSX1RIQU5fU0lHTikge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLmZvcmNlUXVpcmtzID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuTlVMTClcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5zeXN0ZW1JZCArPSBVTklDT0RFLlJFUExBQ0VNRU5UX0NIQVJBQ1RFUjtcclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5FT0YpIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5mb3JjZVF1aXJrcyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZVxyXG4gICAgICAgIHRoaXMuY3VycmVudFRva2VuLnN5c3RlbUlkICs9IHRvQ2hhcihjcCk7XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuNjUgRE9DVFlQRSBzeXN0ZW0gaWRlbnRpZmllciAoc2luZ2xlLXF1b3RlZCkgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tET0NUWVBFX1NZU1RFTV9JREVOVElGSUVSX1NJTkdMRV9RVU9URURfU1RBVEVdID0gZnVuY3Rpb24gZG9jdHlwZVN5c3RlbUlkZW50aWZpZXJTaW5nbGVRdW90ZWRTdGF0ZShjcCkge1xyXG4gICAgaWYgKGNwID09PSAkLkFQT1NUUk9QSEUpXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IEFGVEVSX0RPQ1RZUEVfU1lTVEVNX0lERU5USUZJRVJfU1RBVEU7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5mb3JjZVF1aXJrcyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBEQVRBX1NUQVRFO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2UgaWYgKGNwID09PSAkLk5VTEwpXHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uc3lzdGVtSWQgKz0gVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVI7XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4uZm9yY2VRdWlya3MgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2VcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5zeXN0ZW1JZCArPSB0b0NoYXIoY3ApO1xyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjY2IEFmdGVyIERPQ1RZUEUgc3lzdGVtIGlkZW50aWZpZXIgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tBRlRFUl9ET0NUWVBFX1NZU1RFTV9JREVOVElGSUVSX1NUQVRFXSA9IGZ1bmN0aW9uIGFmdGVyRG9jdHlwZVN5c3RlbUlkZW50aWZpZXJTdGF0ZShjcCkge1xyXG4gICAgaWYgKGlzV2hpdGVzcGFjZShjcCkpXHJcbiAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgIGlmIChjcCA9PT0gJC5HUkVBVEVSX1RIQU5fU0lHTikge1xyXG4gICAgICAgIHRoaXMuX2VtaXRDdXJyZW50VG9rZW4oKTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gREFUQV9TVEFURTtcclxuICAgIH1cclxuXHJcbiAgICBlbHNlIGlmIChjcCA9PT0gJC5FT0YpIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbi5mb3JjZVF1aXJrcyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZVxyXG4gICAgICAgIHRoaXMuc3RhdGUgPSBCT0dVU19ET0NUWVBFX1NUQVRFO1xyXG59O1xyXG5cclxuXHJcbi8vMTIuMi40LjY3IEJvZ3VzIERPQ1RZUEUgc3RhdGVcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuX1tCT0dVU19ET0NUWVBFX1NUQVRFXSA9IGZ1bmN0aW9uIGJvZ3VzRG9jdHlwZVN0YXRlKGNwKSB7XHJcbiAgICBpZiAoY3AgPT09ICQuR1JFQVRFUl9USEFOX1NJR04pIHtcclxuICAgICAgICB0aGlzLl9lbWl0Q3VycmVudFRva2VuKCk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICB9XHJcblxyXG4gICAgZWxzZSBpZiAoY3AgPT09ICQuRU9GKSB7XHJcbiAgICAgICAgdGhpcy5fZW1pdEN1cnJlbnRUb2tlbigpO1xyXG4gICAgICAgIHRoaXMuX3JlY29uc3VtZUluU3RhdGUoREFUQV9TVEFURSk7XHJcbiAgICB9XHJcbn07XHJcblxyXG5cclxuLy8xMi4yLjQuNjggQ0RBVEEgc2VjdGlvbiBzdGF0ZVxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5fW0NEQVRBX1NFQ1RJT05fU1RBVEVdID0gZnVuY3Rpb24gY2RhdGFTZWN0aW9uU3RhdGUoY3ApIHtcclxuICAgIHdoaWxlICh0cnVlKSB7XHJcbiAgICAgICAgaWYgKGNwID09PSAkLkVPRikge1xyXG4gICAgICAgICAgICB0aGlzLl9yZWNvbnN1bWVJblN0YXRlKERBVEFfU1RBVEUpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX2NvbnN1bWVTdWJzZXF1ZW50SWZNYXRjaCgkJC5DREFUQV9FTkRfU1RSSU5HLCBjcCwgdHJ1ZSkpIHtcclxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IERBVEFfU1RBVEU7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2VtaXRDb2RlUG9pbnQoY3ApO1xyXG4gICAgICAgICAgICBjcCA9IHRoaXMuX2NvbnN1bWUoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbi8vTm9kZSBjb25zdHJ1Y3Rpb25cclxuZXhwb3J0cy5jcmVhdGVEb2N1bWVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgbm9kZU5hbWU6ICcjZG9jdW1lbnQnLFxyXG4gICAgICAgIHF1aXJrc01vZGU6IGZhbHNlLFxyXG4gICAgICAgIGNoaWxkTm9kZXM6IFtdXHJcbiAgICB9O1xyXG59O1xyXG5cclxuZXhwb3J0cy5jcmVhdGVEb2N1bWVudEZyYWdtZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBub2RlTmFtZTogJyNkb2N1bWVudC1mcmFnbWVudCcsXHJcbiAgICAgICAgcXVpcmtzTW9kZTogZmFsc2UsXHJcbiAgICAgICAgY2hpbGROb2RlczogW11cclxuICAgIH07XHJcbn07XHJcblxyXG5leHBvcnRzLmNyZWF0ZUVsZW1lbnQgPSBmdW5jdGlvbiAodGFnTmFtZSwgbmFtZXNwYWNlVVJJLCBhdHRycykge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBub2RlTmFtZTogdGFnTmFtZSxcclxuICAgICAgICB0YWdOYW1lOiB0YWdOYW1lLFxyXG4gICAgICAgIGF0dHJzOiBhdHRycyxcclxuICAgICAgICBuYW1lc3BhY2VVUkk6IG5hbWVzcGFjZVVSSSxcclxuICAgICAgICBjaGlsZE5vZGVzOiBbXSxcclxuICAgICAgICBwYXJlbnROb2RlOiBudWxsXHJcbiAgICB9O1xyXG59O1xyXG5cclxuZXhwb3J0cy5jcmVhdGVDb21tZW50Tm9kZSA9IGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIG5vZGVOYW1lOiAnI2NvbW1lbnQnLFxyXG4gICAgICAgIGRhdGE6IGRhdGEsXHJcbiAgICAgICAgcGFyZW50Tm9kZTogbnVsbFxyXG4gICAgfTtcclxufTtcclxuXHJcbnZhciBjcmVhdGVUZXh0Tm9kZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBub2RlTmFtZTogJyN0ZXh0JyxcclxuICAgICAgICB2YWx1ZTogdmFsdWUsXHJcbiAgICAgICAgcGFyZW50Tm9kZTogbnVsbFxyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vVHJlZSBtdXRhdGlvblxyXG5leHBvcnRzLnNldERvY3VtZW50VHlwZSA9IGZ1bmN0aW9uIChkb2N1bWVudCwgbmFtZSwgcHVibGljSWQsIHN5c3RlbUlkKSB7XHJcbiAgICB2YXIgZG9jdHlwZU5vZGUgPSBudWxsO1xyXG5cclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZG9jdW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGlmIChkb2N1bWVudC5jaGlsZE5vZGVzW2ldLm5vZGVOYW1lID09PSAnI2RvY3VtZW50VHlwZScpIHtcclxuICAgICAgICAgICAgZG9jdHlwZU5vZGUgPSBkb2N1bWVudC5jaGlsZE5vZGVzW2ldO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGRvY3R5cGVOb2RlKSB7XHJcbiAgICAgICAgZG9jdHlwZU5vZGUubmFtZSA9IG5hbWU7XHJcbiAgICAgICAgZG9jdHlwZU5vZGUucHVibGljSWQgPSBwdWJsaWNJZDtcclxuICAgICAgICBkb2N0eXBlTm9kZS5zeXN0ZW1JZCA9IHN5c3RlbUlkO1xyXG4gICAgfVxyXG5cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGFwcGVuZENoaWxkKGRvY3VtZW50LCB7XHJcbiAgICAgICAgICAgIG5vZGVOYW1lOiAnI2RvY3VtZW50VHlwZScsXHJcbiAgICAgICAgICAgIG5hbWU6IG5hbWUsXHJcbiAgICAgICAgICAgIHB1YmxpY0lkOiBwdWJsaWNJZCxcclxuICAgICAgICAgICAgc3lzdGVtSWQ6IHN5c3RlbUlkXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnRzLnNldFF1aXJrc01vZGUgPSBmdW5jdGlvbiAoZG9jdW1lbnQpIHtcclxuICAgIGRvY3VtZW50LnF1aXJrc01vZGUgPSB0cnVlO1xyXG59O1xyXG5cclxuZXhwb3J0cy5pc1F1aXJrc01vZGUgPSBmdW5jdGlvbiAoZG9jdW1lbnQpIHtcclxuICAgIHJldHVybiBkb2N1bWVudC5xdWlya3NNb2RlO1xyXG59O1xyXG5cclxudmFyIGFwcGVuZENoaWxkID0gZXhwb3J0cy5hcHBlbmRDaGlsZCA9IGZ1bmN0aW9uIChwYXJlbnROb2RlLCBuZXdOb2RlKSB7XHJcbiAgICBwYXJlbnROb2RlLmNoaWxkTm9kZXMucHVzaChuZXdOb2RlKTtcclxuICAgIG5ld05vZGUucGFyZW50Tm9kZSA9IHBhcmVudE5vZGU7XHJcbn07XHJcblxyXG52YXIgaW5zZXJ0QmVmb3JlID0gZXhwb3J0cy5pbnNlcnRCZWZvcmUgPSBmdW5jdGlvbiAocGFyZW50Tm9kZSwgbmV3Tm9kZSwgcmVmZXJlbmNlTm9kZSkge1xyXG4gICAgdmFyIGluc2VydGlvbklkeCA9IHBhcmVudE5vZGUuY2hpbGROb2Rlcy5pbmRleE9mKHJlZmVyZW5jZU5vZGUpO1xyXG5cclxuICAgIHBhcmVudE5vZGUuY2hpbGROb2Rlcy5zcGxpY2UoaW5zZXJ0aW9uSWR4LCAwLCBuZXdOb2RlKTtcclxuICAgIG5ld05vZGUucGFyZW50Tm9kZSA9IHBhcmVudE5vZGU7XHJcbn07XHJcblxyXG5leHBvcnRzLmRldGFjaE5vZGUgPSBmdW5jdGlvbiAobm9kZSkge1xyXG4gICAgaWYgKG5vZGUucGFyZW50Tm9kZSkge1xyXG4gICAgICAgIHZhciBpZHggPSBub2RlLnBhcmVudE5vZGUuY2hpbGROb2Rlcy5pbmRleE9mKG5vZGUpO1xyXG5cclxuICAgICAgICBub2RlLnBhcmVudE5vZGUuY2hpbGROb2Rlcy5zcGxpY2UoaWR4LCAxKTtcclxuICAgICAgICBub2RlLnBhcmVudE5vZGUgPSBudWxsO1xyXG4gICAgfVxyXG59O1xyXG5cclxuZXhwb3J0cy5pbnNlcnRUZXh0ID0gZnVuY3Rpb24gKHBhcmVudE5vZGUsIHRleHQpIHtcclxuICAgIGlmIChwYXJlbnROb2RlLmNoaWxkTm9kZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgdmFyIHByZXZOb2RlID0gcGFyZW50Tm9kZS5jaGlsZE5vZGVzW3BhcmVudE5vZGUuY2hpbGROb2Rlcy5sZW5ndGggLSAxXTtcclxuXHJcbiAgICAgICAgaWYgKHByZXZOb2RlLm5vZGVOYW1lID09PSAnI3RleHQnKSB7XHJcbiAgICAgICAgICAgIHByZXZOb2RlLnZhbHVlICs9IHRleHQ7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgYXBwZW5kQ2hpbGQocGFyZW50Tm9kZSwgY3JlYXRlVGV4dE5vZGUodGV4dCkpO1xyXG59O1xyXG5cclxuZXhwb3J0cy5pbnNlcnRUZXh0QmVmb3JlID0gZnVuY3Rpb24gKHBhcmVudE5vZGUsIHRleHQsIHJlZmVyZW5jZU5vZGUpIHtcclxuICAgIHZhciBwcmV2Tm9kZSA9IHBhcmVudE5vZGUuY2hpbGROb2Rlc1twYXJlbnROb2RlLmNoaWxkTm9kZXMuaW5kZXhPZihyZWZlcmVuY2VOb2RlKSAtIDFdO1xyXG5cclxuICAgIGlmIChwcmV2Tm9kZSAmJiBwcmV2Tm9kZS5ub2RlTmFtZSA9PT0gJyN0ZXh0JylcclxuICAgICAgICBwcmV2Tm9kZS52YWx1ZSArPSB0ZXh0O1xyXG4gICAgZWxzZVxyXG4gICAgICAgIGluc2VydEJlZm9yZShwYXJlbnROb2RlLCBjcmVhdGVUZXh0Tm9kZSh0ZXh0KSwgcmVmZXJlbmNlTm9kZSk7XHJcbn07XHJcblxyXG5leHBvcnRzLmFkb3B0QXR0cmlidXRlcyA9IGZ1bmN0aW9uIChyZWNpcGllbnROb2RlLCBhdHRycykge1xyXG4gICAgdmFyIHJlY2lwaWVudEF0dHJzTWFwID0gW107XHJcblxyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZWNpcGllbnROb2RlLmF0dHJzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIHJlY2lwaWVudEF0dHJzTWFwLnB1c2gocmVjaXBpZW50Tm9kZS5hdHRyc1tpXS5uYW1lKTtcclxuXHJcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGF0dHJzLmxlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgaWYgKHJlY2lwaWVudEF0dHJzTWFwLmluZGV4T2YoYXR0cnNbal0ubmFtZSkgPT09IC0xKVxyXG4gICAgICAgICAgICByZWNpcGllbnROb2RlLmF0dHJzLnB1c2goYXR0cnNbal0pO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbi8vVHJlZSB0cmF2ZXJzaW5nXHJcbmV4cG9ydHMuZ2V0Rmlyc3RDaGlsZCA9IGZ1bmN0aW9uIChub2RlKSB7XHJcbiAgICByZXR1cm4gbm9kZS5jaGlsZE5vZGVzWzBdO1xyXG59O1xyXG5cclxuZXhwb3J0cy5nZXRDaGlsZE5vZGVzID0gZnVuY3Rpb24gKG5vZGUpIHtcclxuICAgIHJldHVybiBub2RlLmNoaWxkTm9kZXM7XHJcbn07XHJcblxyXG5leHBvcnRzLmdldFBhcmVudE5vZGUgPSBmdW5jdGlvbiAobm9kZSkge1xyXG4gICAgcmV0dXJuIG5vZGUucGFyZW50Tm9kZTtcclxufTtcclxuXHJcbmV4cG9ydHMuZ2V0QXR0ckxpc3QgPSBmdW5jdGlvbiAobm9kZSkge1xyXG4gICAgcmV0dXJuIG5vZGUuYXR0cnM7XHJcbn07XHJcblxyXG4vL05vZGUgZGF0YVxyXG5leHBvcnRzLmdldFRhZ05hbWUgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgcmV0dXJuIGVsZW1lbnQudGFnTmFtZTtcclxufTtcclxuXHJcbmV4cG9ydHMuZ2V0TmFtZXNwYWNlVVJJID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgIHJldHVybiBlbGVtZW50Lm5hbWVzcGFjZVVSSTtcclxufTtcclxuXHJcbmV4cG9ydHMuZ2V0VGV4dE5vZGVDb250ZW50ID0gZnVuY3Rpb24gKHRleHROb2RlKSB7XHJcbiAgICByZXR1cm4gdGV4dE5vZGUudmFsdWU7XHJcbn07XHJcblxyXG5leHBvcnRzLmdldENvbW1lbnROb2RlQ29udGVudCA9IGZ1bmN0aW9uIChjb21tZW50Tm9kZSkge1xyXG4gICAgcmV0dXJuIGNvbW1lbnROb2RlLmRhdGE7XHJcbn07XHJcblxyXG5leHBvcnRzLmdldERvY3VtZW50VHlwZU5vZGVOYW1lID0gZnVuY3Rpb24gKGRvY3R5cGVOb2RlKSB7XHJcbiAgICByZXR1cm4gZG9jdHlwZU5vZGUubmFtZTtcclxufTtcclxuXHJcbmV4cG9ydHMuZ2V0RG9jdW1lbnRUeXBlTm9kZVB1YmxpY0lkID0gZnVuY3Rpb24gKGRvY3R5cGVOb2RlKSB7XHJcbiAgICByZXR1cm4gZG9jdHlwZU5vZGUucHVibGljSWQ7XHJcbn07XHJcblxyXG5leHBvcnRzLmdldERvY3VtZW50VHlwZU5vZGVTeXN0ZW1JZCA9IGZ1bmN0aW9uIChkb2N0eXBlTm9kZSkge1xyXG4gICAgcmV0dXJuIGRvY3R5cGVOb2RlLnN5c3RlbUlkO1xyXG59O1xyXG5cclxuLy9Ob2RlIHR5cGVzXHJcbmV4cG9ydHMuaXNUZXh0Tm9kZSA9IGZ1bmN0aW9uIChub2RlKSB7XHJcbiAgICByZXR1cm4gbm9kZS5ub2RlTmFtZSA9PT0gJyN0ZXh0JztcclxufTtcclxuXHJcbmV4cG9ydHMuaXNDb21tZW50Tm9kZSA9IGZ1bmN0aW9uIChub2RlKSB7XHJcbiAgICByZXR1cm4gbm9kZS5ub2RlTmFtZSA9PT0gJyNjb21tZW50JztcclxufTtcclxuXHJcbmV4cG9ydHMuaXNEb2N1bWVudFR5cGVOb2RlID0gZnVuY3Rpb24gKG5vZGUpIHtcclxuICAgIHJldHVybiBub2RlLm5vZGVOYW1lID09PSAnI2RvY3VtZW50VHlwZSc7XHJcbn07XHJcblxyXG5leHBvcnRzLmlzRWxlbWVudE5vZGUgPSBmdW5jdGlvbiAobm9kZSkge1xyXG4gICAgcmV0dXJuICEhbm9kZS50YWdOYW1lO1xyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBEb2N0eXBlID0gcmVxdWlyZSgnLi4vY29tbW9uL2RvY3R5cGUnKTtcblxuLy9Db252ZXJzaW9uIHRhYmxlcyBmb3IgRE9NIExldmVsMSBzdHJ1Y3R1cmUgZW11bGF0aW9uXG52YXIgbm9kZVR5cGVzID0ge1xuICAgIGVsZW1lbnQ6IDEsXG4gICAgdGV4dDogMyxcbiAgICBjZGF0YTogNCxcbiAgICBjb21tZW50OiA4XG59O1xuXG52YXIgbm9kZVByb3BlcnR5U2hvcnRoYW5kcyA9IHtcbiAgICB0YWdOYW1lOiAnbmFtZScsXG4gICAgY2hpbGROb2RlczogJ2NoaWxkcmVuJyxcbiAgICBwYXJlbnROb2RlOiAncGFyZW50JyxcbiAgICBwcmV2aW91c1NpYmxpbmc6ICdwcmV2JyxcbiAgICBuZXh0U2libGluZzogJ25leHQnLFxuICAgIG5vZGVWYWx1ZTogJ2RhdGEnXG59O1xuXG4vL05vZGVcbnZhciBOb2RlID0gZnVuY3Rpb24gKHByb3BzKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHByb3BzKSB7XG4gICAgICAgIGlmIChwcm9wcy5oYXNPd25Qcm9wZXJ0eShrZXkpKVxuICAgICAgICAgICAgdGhpc1trZXldID0gcHJvcHNba2V5XTtcbiAgICB9XG59O1xuXG5Ob2RlLnByb3RvdHlwZSA9IHtcbiAgICBnZXQgZmlyc3RDaGlsZCgpIHtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlbjtcbiAgICAgICAgcmV0dXJuIGNoaWxkcmVuICYmIGNoaWxkcmVuWzBdIHx8IG51bGw7XG4gICAgfSxcblxuICAgIGdldCBsYXN0Q2hpbGQoKSB7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW47XG4gICAgICAgIHJldHVybiBjaGlsZHJlbiAmJiBjaGlsZHJlbltjaGlsZHJlbi5sZW5ndGggLSAxXSB8fCBudWxsO1xuICAgIH0sXG5cbiAgICBnZXQgbm9kZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiBub2RlVHlwZXNbdGhpcy50eXBlXSB8fCBub2RlVHlwZXMuZWxlbWVudDtcbiAgICB9XG59O1xuXG5PYmplY3Qua2V5cyhub2RlUHJvcGVydHlTaG9ydGhhbmRzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICB2YXIgc2hvcnRoYW5kID0gbm9kZVByb3BlcnR5U2hvcnRoYW5kc1trZXldO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KE5vZGUucHJvdG90eXBlLCBrZXksIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1tzaG9ydGhhbmRdIHx8IG51bGw7XG4gICAgICAgIH0sXG4gICAgICAgIHNldDogZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICAgICAgdGhpc1tzaG9ydGhhbmRdID0gdmFsO1xuICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgfVxuICAgIH0pO1xufSk7XG5cblxuLy9Ob2RlIGNvbnN0cnVjdGlvblxuZXhwb3J0cy5jcmVhdGVEb2N1bWVudCA9XG5leHBvcnRzLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIG5ldyBOb2RlKHtcbiAgICAgICAgdHlwZTogJ3Jvb3QnLFxuICAgICAgICBuYW1lOiAncm9vdCcsXG4gICAgICAgIHBhcmVudDogbnVsbCxcbiAgICAgICAgcHJldjogbnVsbCxcbiAgICAgICAgbmV4dDogbnVsbCxcbiAgICAgICAgY2hpbGRyZW46IFtdXG4gICAgfSk7XG59O1xuXG5leHBvcnRzLmNyZWF0ZUVsZW1lbnQgPSBmdW5jdGlvbiAodGFnTmFtZSwgbmFtZXNwYWNlVVJJLCBhdHRycykge1xuICAgIHZhciBhdHRyaWJzID0ge30sXG4gICAgICAgIGF0dHJpYnNOYW1lc3BhY2UgPSB7fSxcbiAgICAgICAgYXR0cmlic1ByZWZpeCA9IHt9O1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhdHRycy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgYXR0ck5hbWUgPSBhdHRyc1tpXS5uYW1lO1xuXG4gICAgICAgIGF0dHJpYnNbYXR0ck5hbWVdID0gYXR0cnNbaV0udmFsdWU7XG4gICAgICAgIGF0dHJpYnNOYW1lc3BhY2VbYXR0ck5hbWVdID0gYXR0cnNbaV0ubmFtZXNwYWNlO1xuICAgICAgICBhdHRyaWJzUHJlZml4W2F0dHJOYW1lXSA9IGF0dHJzW2ldLnByZWZpeDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IE5vZGUoe1xuICAgICAgICB0eXBlOiB0YWdOYW1lID09PSAnc2NyaXB0JyB8fCB0YWdOYW1lID09PSAnc3R5bGUnID8gdGFnTmFtZSA6ICd0YWcnLFxuICAgICAgICBuYW1lOiB0YWdOYW1lLFxuICAgICAgICBuYW1lc3BhY2U6IG5hbWVzcGFjZVVSSSxcbiAgICAgICAgYXR0cmliczogYXR0cmlicyxcbiAgICAgICAgJ3gtYXR0cmlic05hbWVzcGFjZSc6IGF0dHJpYnNOYW1lc3BhY2UsXG4gICAgICAgICd4LWF0dHJpYnNQcmVmaXgnOiBhdHRyaWJzUHJlZml4LFxuICAgICAgICBjaGlsZHJlbjogW10sXG4gICAgICAgIHBhcmVudDogbnVsbCxcbiAgICAgICAgcHJldjogbnVsbCxcbiAgICAgICAgbmV4dDogbnVsbFxuICAgIH0pO1xufTtcblxuZXhwb3J0cy5jcmVhdGVDb21tZW50Tm9kZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgcmV0dXJuIG5ldyBOb2RlKHtcbiAgICAgICAgdHlwZTogJ2NvbW1lbnQnLFxuICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICBwYXJlbnQ6IG51bGwsXG4gICAgICAgIHByZXY6IG51bGwsXG4gICAgICAgIG5leHQ6IG51bGxcbiAgICB9KTtcbn07XG5cbnZhciBjcmVhdGVUZXh0Tm9kZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgTm9kZSh7XG4gICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgZGF0YTogdmFsdWUsXG4gICAgICAgIHBhcmVudDogbnVsbCxcbiAgICAgICAgcHJldjogbnVsbCxcbiAgICAgICAgbmV4dDogbnVsbFxuICAgIH0pO1xufTtcblxuXG4vL1RyZWUgbXV0YXRpb25cbmV4cG9ydHMuc2V0RG9jdW1lbnRUeXBlID0gZnVuY3Rpb24gKGRvY3VtZW50LCBuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpIHtcbiAgICB2YXIgZGF0YSA9IERvY3R5cGUuc2VyaWFsaXplQ29udGVudChuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpLFxuICAgICAgICBkb2N0eXBlTm9kZSA9IG51bGw7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRvY3VtZW50LmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChkb2N1bWVudC5jaGlsZHJlbltpXS50eXBlID09PSAnZGlyZWN0aXZlJyAmJiBkb2N1bWVudC5jaGlsZHJlbltpXS5uYW1lID09PSAnIWRvY3R5cGUnKSB7XG4gICAgICAgICAgICBkb2N0eXBlTm9kZSA9IGRvY3VtZW50LmNoaWxkcmVuW2ldO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZG9jdHlwZU5vZGUpIHtcbiAgICAgICAgZG9jdHlwZU5vZGUuZGF0YSA9IGRhdGE7XG4gICAgICAgIGRvY3R5cGVOb2RlWyd4LW5hbWUnXSA9IG5hbWU7XG4gICAgICAgIGRvY3R5cGVOb2RlWyd4LXB1YmxpY0lkJ10gPSBwdWJsaWNJZDtcbiAgICAgICAgZG9jdHlwZU5vZGVbJ3gtc3lzdGVtSWQnXSA9IHN5c3RlbUlkO1xuICAgIH1cblxuICAgIGVsc2Uge1xuICAgICAgICBhcHBlbmRDaGlsZChkb2N1bWVudCwgbmV3IE5vZGUoe1xuICAgICAgICAgICAgdHlwZTogJ2RpcmVjdGl2ZScsXG4gICAgICAgICAgICBuYW1lOiAnIWRvY3R5cGUnLFxuICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgICd4LW5hbWUnOiBuYW1lLFxuICAgICAgICAgICAgJ3gtcHVibGljSWQnOiBwdWJsaWNJZCxcbiAgICAgICAgICAgICd4LXN5c3RlbUlkJzogc3lzdGVtSWRcbiAgICAgICAgfSkpO1xuICAgIH1cblxufTtcblxuZXhwb3J0cy5zZXRRdWlya3NNb2RlID0gZnVuY3Rpb24gKGRvY3VtZW50KSB7XG4gICAgZG9jdW1lbnQucXVpcmtzTW9kZSA9IHRydWU7XG59O1xuXG5leHBvcnRzLmlzUXVpcmtzTW9kZSA9IGZ1bmN0aW9uIChkb2N1bWVudCkge1xuICAgIHJldHVybiBkb2N1bWVudC5xdWlya3NNb2RlO1xufTtcblxudmFyIGFwcGVuZENoaWxkID0gZXhwb3J0cy5hcHBlbmRDaGlsZCA9IGZ1bmN0aW9uIChwYXJlbnROb2RlLCBuZXdOb2RlKSB7XG4gICAgdmFyIHByZXYgPSBwYXJlbnROb2RlLmNoaWxkcmVuW3BhcmVudE5vZGUuY2hpbGRyZW4ubGVuZ3RoIC0gMV07XG5cbiAgICBpZiAocHJldikge1xuICAgICAgICBwcmV2Lm5leHQgPSBuZXdOb2RlO1xuICAgICAgICBuZXdOb2RlLnByZXYgPSBwcmV2O1xuICAgIH1cblxuICAgIHBhcmVudE5vZGUuY2hpbGRyZW4ucHVzaChuZXdOb2RlKTtcbiAgICBuZXdOb2RlLnBhcmVudCA9IHBhcmVudE5vZGU7XG59O1xuXG52YXIgaW5zZXJ0QmVmb3JlID0gZXhwb3J0cy5pbnNlcnRCZWZvcmUgPSBmdW5jdGlvbiAocGFyZW50Tm9kZSwgbmV3Tm9kZSwgcmVmZXJlbmNlTm9kZSkge1xuICAgIHZhciBpbnNlcnRpb25JZHggPSBwYXJlbnROb2RlLmNoaWxkcmVuLmluZGV4T2YocmVmZXJlbmNlTm9kZSksXG4gICAgICAgIHByZXYgPSByZWZlcmVuY2VOb2RlLnByZXY7XG5cbiAgICBpZiAocHJldikge1xuICAgICAgICBwcmV2Lm5leHQgPSBuZXdOb2RlO1xuICAgICAgICBuZXdOb2RlLnByZXYgPSBwcmV2O1xuICAgIH1cblxuICAgIHJlZmVyZW5jZU5vZGUucHJldiA9IG5ld05vZGU7XG4gICAgbmV3Tm9kZS5uZXh0ID0gcmVmZXJlbmNlTm9kZTtcblxuICAgIHBhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKGluc2VydGlvbklkeCwgMCwgbmV3Tm9kZSk7XG4gICAgbmV3Tm9kZS5wYXJlbnQgPSBwYXJlbnROb2RlO1xufTtcblxuZXhwb3J0cy5kZXRhY2hOb2RlID0gZnVuY3Rpb24gKG5vZGUpIHtcbiAgICBpZiAobm9kZS5wYXJlbnQpIHtcbiAgICAgICAgdmFyIGlkeCA9IG5vZGUucGFyZW50LmNoaWxkcmVuLmluZGV4T2Yobm9kZSksXG4gICAgICAgICAgICBwcmV2ID0gbm9kZS5wcmV2LFxuICAgICAgICAgICAgbmV4dCA9IG5vZGUubmV4dDtcblxuICAgICAgICBub2RlLnByZXYgPSBudWxsO1xuICAgICAgICBub2RlLm5leHQgPSBudWxsO1xuXG4gICAgICAgIGlmIChwcmV2KVxuICAgICAgICAgICAgcHJldi5uZXh0ID0gbmV4dDtcblxuICAgICAgICBpZiAobmV4dClcbiAgICAgICAgICAgIG5leHQucHJldiA9IHByZXY7XG5cbiAgICAgICAgbm9kZS5wYXJlbnQuY2hpbGRyZW4uc3BsaWNlKGlkeCwgMSk7XG4gICAgICAgIG5vZGUucGFyZW50ID0gbnVsbDtcbiAgICB9XG59O1xuXG5leHBvcnRzLmluc2VydFRleHQgPSBmdW5jdGlvbiAocGFyZW50Tm9kZSwgdGV4dCkge1xuICAgIHZhciBsYXN0Q2hpbGQgPSBwYXJlbnROb2RlLmNoaWxkcmVuW3BhcmVudE5vZGUuY2hpbGRyZW4ubGVuZ3RoIC0gMV07XG5cbiAgICBpZiAobGFzdENoaWxkICYmIGxhc3RDaGlsZC50eXBlID09PSAndGV4dCcpXG4gICAgICAgIGxhc3RDaGlsZC5kYXRhICs9IHRleHQ7XG4gICAgZWxzZVxuICAgICAgICBhcHBlbmRDaGlsZChwYXJlbnROb2RlLCBjcmVhdGVUZXh0Tm9kZSh0ZXh0KSk7XG59O1xuXG5leHBvcnRzLmluc2VydFRleHRCZWZvcmUgPSBmdW5jdGlvbiAocGFyZW50Tm9kZSwgdGV4dCwgcmVmZXJlbmNlTm9kZSkge1xuICAgIHZhciBwcmV2Tm9kZSA9IHBhcmVudE5vZGUuY2hpbGRyZW5bcGFyZW50Tm9kZS5jaGlsZHJlbi5pbmRleE9mKHJlZmVyZW5jZU5vZGUpIC0gMV07XG5cbiAgICBpZiAocHJldk5vZGUgJiYgcHJldk5vZGUudHlwZSA9PT0gJ3RleHQnKVxuICAgICAgICBwcmV2Tm9kZS5kYXRhICs9IHRleHQ7XG4gICAgZWxzZVxuICAgICAgICBpbnNlcnRCZWZvcmUocGFyZW50Tm9kZSwgY3JlYXRlVGV4dE5vZGUodGV4dCksIHJlZmVyZW5jZU5vZGUpO1xufTtcblxuZXhwb3J0cy5hZG9wdEF0dHJpYnV0ZXMgPSBmdW5jdGlvbiAocmVjaXBpZW50Tm9kZSwgYXR0cnMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBhdHRyTmFtZSA9IGF0dHJzW2ldLm5hbWU7XG5cbiAgICAgICAgaWYgKHR5cGVvZiByZWNpcGllbnROb2RlLmF0dHJpYnNbYXR0ck5hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcmVjaXBpZW50Tm9kZS5hdHRyaWJzW2F0dHJOYW1lXSA9IGF0dHJzW2ldLnZhbHVlO1xuICAgICAgICAgICAgcmVjaXBpZW50Tm9kZVsneC1hdHRyaWJzTmFtZXNwYWNlJ11bYXR0ck5hbWVdID0gYXR0cnNbaV0ubmFtZXNwYWNlO1xuICAgICAgICAgICAgcmVjaXBpZW50Tm9kZVsneC1hdHRyaWJzUHJlZml4J11bYXR0ck5hbWVdID0gYXR0cnNbaV0ucHJlZml4O1xuICAgICAgICB9XG4gICAgfVxufTtcblxuXG4vL1RyZWUgdHJhdmVyc2luZ1xuZXhwb3J0cy5nZXRGaXJzdENoaWxkID0gZnVuY3Rpb24gKG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5jaGlsZHJlblswXTtcbn07XG5cbmV4cG9ydHMuZ2V0Q2hpbGROb2RlcyA9IGZ1bmN0aW9uIChub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUuY2hpbGRyZW47XG59O1xuXG5leHBvcnRzLmdldFBhcmVudE5vZGUgPSBmdW5jdGlvbiAobm9kZSkge1xuICAgIHJldHVybiBub2RlLnBhcmVudDtcbn07XG5cbmV4cG9ydHMuZ2V0QXR0ckxpc3QgPSBmdW5jdGlvbiAobm9kZSkge1xuICAgIHZhciBhdHRyTGlzdCA9IFtdO1xuXG4gICAgZm9yICh2YXIgbmFtZSBpbiBub2RlLmF0dHJpYnMpIHtcbiAgICAgICAgaWYgKG5vZGUuYXR0cmlicy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICAgICAgYXR0ckxpc3QucHVzaCh7XG4gICAgICAgICAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogbm9kZS5hdHRyaWJzW25hbWVdLFxuICAgICAgICAgICAgICAgIG5hbWVzcGFjZTogbm9kZVsneC1hdHRyaWJzTmFtZXNwYWNlJ11bbmFtZV0sXG4gICAgICAgICAgICAgICAgcHJlZml4OiBub2RlWyd4LWF0dHJpYnNQcmVmaXgnXVtuYW1lXVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYXR0ckxpc3Q7XG59O1xuXG5cbi8vTm9kZSBkYXRhXG5leHBvcnRzLmdldFRhZ05hbWUgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgIHJldHVybiBlbGVtZW50Lm5hbWU7XG59O1xuXG5leHBvcnRzLmdldE5hbWVzcGFjZVVSSSA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgcmV0dXJuIGVsZW1lbnQubmFtZXNwYWNlO1xufTtcblxuZXhwb3J0cy5nZXRUZXh0Tm9kZUNvbnRlbnQgPSBmdW5jdGlvbiAodGV4dE5vZGUpIHtcbiAgICByZXR1cm4gdGV4dE5vZGUuZGF0YTtcbn07XG5cbmV4cG9ydHMuZ2V0Q29tbWVudE5vZGVDb250ZW50ID0gZnVuY3Rpb24gKGNvbW1lbnROb2RlKSB7XG4gICAgcmV0dXJuIGNvbW1lbnROb2RlLmRhdGE7XG59O1xuXG5leHBvcnRzLmdldERvY3VtZW50VHlwZU5vZGVOYW1lID0gZnVuY3Rpb24gKGRvY3R5cGVOb2RlKSB7XG4gICAgcmV0dXJuIGRvY3R5cGVOb2RlWyd4LW5hbWUnXTtcbn07XG5cbmV4cG9ydHMuZ2V0RG9jdW1lbnRUeXBlTm9kZVB1YmxpY0lkID0gZnVuY3Rpb24gKGRvY3R5cGVOb2RlKSB7XG4gICAgcmV0dXJuIGRvY3R5cGVOb2RlWyd4LXB1YmxpY0lkJ107XG59O1xuXG5leHBvcnRzLmdldERvY3VtZW50VHlwZU5vZGVTeXN0ZW1JZCA9IGZ1bmN0aW9uIChkb2N0eXBlTm9kZSkge1xuICAgIHJldHVybiBkb2N0eXBlTm9kZVsneC1zeXN0ZW1JZCddO1xufTtcblxuXG4vL05vZGUgdHlwZXNcbmV4cG9ydHMuaXNUZXh0Tm9kZSA9IGZ1bmN0aW9uIChub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUudHlwZSA9PT0gJ3RleHQnO1xufTtcblxuZXhwb3J0cy5pc0NvbW1lbnROb2RlID0gZnVuY3Rpb24gKG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS50eXBlID09PSAnY29tbWVudCc7XG59O1xuXG5leHBvcnRzLmlzRG9jdW1lbnRUeXBlTm9kZSA9IGZ1bmN0aW9uIChub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUudHlwZSA9PT0gJ2RpcmVjdGl2ZScgJiYgbm9kZS5uYW1lID09PSAnIWRvY3R5cGUnO1xufTtcblxuZXhwb3J0cy5pc0VsZW1lbnROb2RlID0gZnVuY3Rpb24gKG5vZGUpIHtcbiAgICByZXR1cm4gISFub2RlLmF0dHJpYnM7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxuLy9Db25zdFxyXG52YXIgTk9BSF9BUktfQ0FQQUNJVFkgPSAzO1xyXG5cclxuLy9MaXN0IG9mIGZvcm1hdHRpbmcgZWxlbWVudHNcclxudmFyIEZvcm1hdHRpbmdFbGVtZW50TGlzdCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRyZWVBZGFwdGVyKSB7XHJcbiAgICB0aGlzLmxlbmd0aCA9IDA7XHJcbiAgICB0aGlzLmVudHJpZXMgPSBbXTtcclxuICAgIHRoaXMudHJlZUFkYXB0ZXIgPSB0cmVlQWRhcHRlcjtcclxuICAgIHRoaXMuYm9va21hcmsgPSBudWxsO1xyXG59O1xyXG5cclxuLy9FbnRyeSB0eXBlc1xyXG5Gb3JtYXR0aW5nRWxlbWVudExpc3QuTUFSS0VSX0VOVFJZID0gJ01BUktFUl9FTlRSWSc7XHJcbkZvcm1hdHRpbmdFbGVtZW50TGlzdC5FTEVNRU5UX0VOVFJZID0gJ0VMRU1FTlRfRU5UUlknO1xyXG5cclxuLy9Ob2FoIEFyaydzIGNvbmRpdGlvblxyXG4vL09QVElNSVpBVElPTjogYXQgZmlyc3Qgd2UgdHJ5IHRvIGZpbmQgcG9zc2libGUgY2FuZGlkYXRlcyBmb3IgZXhjbHVzaW9uIHVzaW5nXHJcbi8vbGlnaHR3ZWlnaHQgaGV1cmlzdGljcyB3aXRob3V0IHRob3JvdWdoIGF0dHJpYnV0ZXMgY2hlY2suXHJcbkZvcm1hdHRpbmdFbGVtZW50TGlzdC5wcm90b3R5cGUuX2dldE5vYWhBcmtDb25kaXRpb25DYW5kaWRhdGVzID0gZnVuY3Rpb24gKG5ld0VsZW1lbnQpIHtcclxuICAgIHZhciBjYW5kaWRhdGVzID0gW107XHJcblxyXG4gICAgaWYgKHRoaXMubGVuZ3RoID49IE5PQUhfQVJLX0NBUEFDSVRZKSB7XHJcbiAgICAgICAgdmFyIG5lQXR0cnNMZW5ndGggPSB0aGlzLnRyZWVBZGFwdGVyLmdldEF0dHJMaXN0KG5ld0VsZW1lbnQpLmxlbmd0aCxcclxuICAgICAgICAgICAgbmVUYWdOYW1lID0gdGhpcy50cmVlQWRhcHRlci5nZXRUYWdOYW1lKG5ld0VsZW1lbnQpLFxyXG4gICAgICAgICAgICBuZU5hbWVzcGFjZVVSSSA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0TmFtZXNwYWNlVVJJKG5ld0VsZW1lbnQpO1xyXG5cclxuICAgICAgICBmb3IgKHZhciBpID0gdGhpcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgICAgICB2YXIgZW50cnkgPSB0aGlzLmVudHJpZXNbaV07XHJcblxyXG4gICAgICAgICAgICBpZiAoZW50cnkudHlwZSA9PT0gRm9ybWF0dGluZ0VsZW1lbnRMaXN0Lk1BUktFUl9FTlRSWSlcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBlbnRyeS5lbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgZWxlbWVudEF0dHJzID0gdGhpcy50cmVlQWRhcHRlci5nZXRBdHRyTGlzdChlbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnRyZWVBZGFwdGVyLmdldFRhZ05hbWUoZWxlbWVudCkgPT09IG5lVGFnTmFtZSAmJlxyXG4gICAgICAgICAgICAgICAgdGhpcy50cmVlQWRhcHRlci5nZXROYW1lc3BhY2VVUkkoZWxlbWVudCkgPT09IG5lTmFtZXNwYWNlVVJJICYmXHJcbiAgICAgICAgICAgICAgICBlbGVtZW50QXR0cnMubGVuZ3RoID09PSBuZUF0dHJzTGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICBjYW5kaWRhdGVzLnB1c2goe2lkeDogaSwgYXR0cnM6IGVsZW1lbnRBdHRyc30pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBjYW5kaWRhdGVzLmxlbmd0aCA8IE5PQUhfQVJLX0NBUEFDSVRZID8gW10gOiBjYW5kaWRhdGVzO1xyXG59O1xyXG5cclxuRm9ybWF0dGluZ0VsZW1lbnRMaXN0LnByb3RvdHlwZS5fZW5zdXJlTm9haEFya0NvbmRpdGlvbiA9IGZ1bmN0aW9uIChuZXdFbGVtZW50KSB7XHJcbiAgICB2YXIgY2FuZGlkYXRlcyA9IHRoaXMuX2dldE5vYWhBcmtDb25kaXRpb25DYW5kaWRhdGVzKG5ld0VsZW1lbnQpLFxyXG4gICAgICAgIGNMZW5ndGggPSBjYW5kaWRhdGVzLmxlbmd0aDtcclxuXHJcbiAgICBpZiAoY0xlbmd0aCkge1xyXG4gICAgICAgIHZhciBuZUF0dHJzID0gdGhpcy50cmVlQWRhcHRlci5nZXRBdHRyTGlzdChuZXdFbGVtZW50KSxcclxuICAgICAgICAgICAgbmVBdHRyc0xlbmd0aCA9IG5lQXR0cnMubGVuZ3RoLFxyXG4gICAgICAgICAgICBuZUF0dHJzTWFwID0ge307XHJcblxyXG4gICAgICAgIC8vTk9URTogYnVpbGQgYXR0cnMgbWFwIGZvciB0aGUgbmV3IGVsZW1lbnQgc28gd2UgY2FuIHBlcmZvcm0gZmFzdCBsb29rdXBzXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuZUF0dHJzTGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgdmFyIG5lQXR0ciA9IG5lQXR0cnNbaV07XHJcblxyXG4gICAgICAgICAgICBuZUF0dHJzTWFwW25lQXR0ci5uYW1lXSA9IG5lQXR0ci52YWx1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbmVBdHRyc0xlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgY0xlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgY0F0dHIgPSBjYW5kaWRhdGVzW2pdLmF0dHJzW2ldO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChuZUF0dHJzTWFwW2NBdHRyLm5hbWVdICE9PSBjQXR0ci52YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhbmRpZGF0ZXMuc3BsaWNlKGosIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNMZW5ndGgtLTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoY2FuZGlkYXRlcy5sZW5ndGggPCBOT0FIX0FSS19DQVBBQ0lUWSlcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vTk9URTogcmVtb3ZlIGJvdHRvbW1vc3QgY2FuZGlkYXRlcyB1bnRpbCBOb2FoJ3MgQXJrIGNvbmRpdGlvbiB3aWxsIG5vdCBiZSBtZXRcclxuICAgICAgICBmb3IgKHZhciBpID0gY0xlbmd0aCAtIDE7IGkgPj0gTk9BSF9BUktfQ0FQQUNJVFkgLSAxOyBpLS0pIHtcclxuICAgICAgICAgICAgdGhpcy5lbnRyaWVzLnNwbGljZShjYW5kaWRhdGVzW2ldLmlkeCwgMSk7XHJcbiAgICAgICAgICAgIHRoaXMubGVuZ3RoLS07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59O1xyXG5cclxuLy9NdXRhdGlvbnNcclxuRm9ybWF0dGluZ0VsZW1lbnRMaXN0LnByb3RvdHlwZS5pbnNlcnRNYXJrZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB0aGlzLmVudHJpZXMucHVzaCh7dHlwZTogRm9ybWF0dGluZ0VsZW1lbnRMaXN0Lk1BUktFUl9FTlRSWX0pO1xyXG4gICAgdGhpcy5sZW5ndGgrKztcclxufTtcclxuXHJcbkZvcm1hdHRpbmdFbGVtZW50TGlzdC5wcm90b3R5cGUucHVzaEVsZW1lbnQgPSBmdW5jdGlvbiAoZWxlbWVudCwgdG9rZW4pIHtcclxuICAgIHRoaXMuX2Vuc3VyZU5vYWhBcmtDb25kaXRpb24oZWxlbWVudCk7XHJcblxyXG4gICAgdGhpcy5lbnRyaWVzLnB1c2goe1xyXG4gICAgICAgIHR5cGU6IEZvcm1hdHRpbmdFbGVtZW50TGlzdC5FTEVNRU5UX0VOVFJZLFxyXG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgICAgdG9rZW46IHRva2VuXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmxlbmd0aCsrO1xyXG59O1xyXG5cclxuRm9ybWF0dGluZ0VsZW1lbnRMaXN0LnByb3RvdHlwZS5pbnNlcnRFbGVtZW50QWZ0ZXJCb29rbWFyayA9IGZ1bmN0aW9uIChlbGVtZW50LCB0b2tlbikge1xyXG4gICAgdmFyIGJvb2ttYXJrSWR4ID0gdGhpcy5sZW5ndGggLSAxO1xyXG5cclxuICAgIGZvciAoOyBib29rbWFya0lkeCA+PSAwOyBib29rbWFya0lkeC0tKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZW50cmllc1tib29rbWFya0lkeF0gPT09IHRoaXMuYm9va21hcmspXHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuZW50cmllcy5zcGxpY2UoYm9va21hcmtJZHggKyAxLCAwLCB7XHJcbiAgICAgICAgdHlwZTogRm9ybWF0dGluZ0VsZW1lbnRMaXN0LkVMRU1FTlRfRU5UUlksXHJcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgICB0b2tlbjogdG9rZW5cclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMubGVuZ3RoKys7XHJcbn07XHJcblxyXG5Gb3JtYXR0aW5nRWxlbWVudExpc3QucHJvdG90eXBlLnJlbW92ZUVudHJ5ID0gZnVuY3Rpb24gKGVudHJ5KSB7XHJcbiAgICBmb3IgKHZhciBpID0gdGhpcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgIGlmICh0aGlzLmVudHJpZXNbaV0gPT09IGVudHJ5KSB7XHJcbiAgICAgICAgICAgIHRoaXMuZW50cmllcy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgICAgIHRoaXMubGVuZ3RoLS07XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufTtcclxuXHJcbkZvcm1hdHRpbmdFbGVtZW50TGlzdC5wcm90b3R5cGUuY2xlYXJUb0xhc3RNYXJrZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB3aGlsZSAodGhpcy5sZW5ndGgpIHtcclxuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLmVudHJpZXMucG9wKCk7XHJcblxyXG4gICAgICAgIHRoaXMubGVuZ3RoLS07XHJcblxyXG4gICAgICAgIGlmIChlbnRyeS50eXBlID09PSBGb3JtYXR0aW5nRWxlbWVudExpc3QuTUFSS0VSX0VOVFJZKVxyXG4gICAgICAgICAgICBicmVhaztcclxuICAgIH1cclxufTtcclxuXHJcbi8vU2VhcmNoXHJcbkZvcm1hdHRpbmdFbGVtZW50TGlzdC5wcm90b3R5cGUuZ2V0RWxlbWVudEVudHJ5SW5TY29wZVdpdGhUYWdOYW1lID0gZnVuY3Rpb24gKHRhZ05hbWUpIHtcclxuICAgIGZvciAodmFyIGkgPSB0aGlzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy5lbnRyaWVzW2ldO1xyXG5cclxuICAgICAgICBpZiAoZW50cnkudHlwZSA9PT0gRm9ybWF0dGluZ0VsZW1lbnRMaXN0Lk1BUktFUl9FTlRSWSlcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLnRyZWVBZGFwdGVyLmdldFRhZ05hbWUoZW50cnkuZWxlbWVudCkgPT09IHRhZ05hbWUpXHJcbiAgICAgICAgICAgIHJldHVybiBlbnRyeTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxufTtcclxuXHJcbkZvcm1hdHRpbmdFbGVtZW50TGlzdC5wcm90b3R5cGUuZ2V0RWxlbWVudEVudHJ5ID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgIGZvciAodmFyIGkgPSB0aGlzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy5lbnRyaWVzW2ldO1xyXG5cclxuICAgICAgICBpZiAoZW50cnkudHlwZSA9PT0gRm9ybWF0dGluZ0VsZW1lbnRMaXN0LkVMRU1FTlRfRU5UUlkgJiYgZW50cnkuZWxlbWVudCA9PSBlbGVtZW50KVxyXG4gICAgICAgICAgICByZXR1cm4gZW50cnk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG51bGw7XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIE9wZW5FbGVtZW50U3RhY2sgPSByZXF1aXJlKCcuL29wZW5fZWxlbWVudF9zdGFjaycpLFxuICAgIFRva2VuaXplciA9IHJlcXVpcmUoJy4uL3Rva2VuaXphdGlvbi90b2tlbml6ZXInKSxcbiAgICBIVE1MID0gcmVxdWlyZSgnLi4vY29tbW9uL2h0bWwnKTtcblxuXG4vL0FsaWFzZXNcbnZhciAkID0gSFRNTC5UQUdfTkFNRVM7XG5cblxuZnVuY3Rpb24gc2V0RW5kTG9jYXRpb24oZWxlbWVudCwgZW5kVGFnVG9rZW4pIHtcbiAgICBpZiAoZWxlbWVudC5fX2xvY2F0aW9uKVxuICAgICAgICBlbGVtZW50Ll9fbG9jYXRpb24uZW5kID0gZW5kVGFnVG9rZW4ubG9jYXRpb24uZW5kO1xufVxuXG4vL05PVEU6IHBhdGNoIG9wZW4gZWxlbWVudHMgc3RhY2ssIHNvIHdlIGNhbiBhc3NpZ24gZW5kIGxvY2F0aW9uIGZvciB0aGUgZWxlbWVudHNcbmZ1bmN0aW9uIHBhdGNoT3BlbkVsZW1lbnRzU3RhY2soc3RhY2ssIHBhcnNlcikge1xuICAgIHN0YWNrLnBvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2V0RW5kTG9jYXRpb24odGhpcy5jdXJyZW50LCBwYXJzZXIuY3VycmVudFRva2VuKTtcbiAgICAgICAgT3BlbkVsZW1lbnRTdGFjay5wcm90b3R5cGUucG9wLmNhbGwodGhpcyk7XG4gICAgfTtcblxuICAgIHN0YWNrLnBvcEFsbFVwVG9IdG1sRWxlbWVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IHRoaXMuc3RhY2tUb3A7IGkgPiAwOyBpLS0pXG4gICAgICAgICAgICBzZXRFbmRMb2NhdGlvbih0aGlzLml0ZW1zW2ldLCBwYXJzZXIuY3VycmVudFRva2VuKTtcblxuICAgICAgICBPcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS5wb3BBbGxVcFRvSHRtbEVsZW1lbnQuY2FsbCh0aGlzKTtcbiAgICB9O1xuXG4gICAgc3RhY2sucmVtb3ZlID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgc2V0RW5kTG9jYXRpb24oZWxlbWVudCwgcGFyc2VyLmN1cnJlbnRUb2tlbik7XG4gICAgICAgIE9wZW5FbGVtZW50U3RhY2sucHJvdG90eXBlLnJlbW92ZS5jYWxsKHRoaXMsIGVsZW1lbnQpO1xuICAgIH07XG59XG5cbmV4cG9ydHMuYXNzaWduID0gZnVuY3Rpb24gKHBhcnNlcikge1xuICAgIC8vTk9URTogb2J0YWluIFBhcnNlciBwcm90byB0aGlzIHdheSB0byBhdm9pZCBtb2R1bGUgY2lyY3VsYXIgcmVmZXJlbmNlc1xuICAgIHZhciBwYXJzZXJQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwYXJzZXIpO1xuXG4gICAgLy9OT1RFOiBwYXRjaCBfcmVzZXQgbWV0aG9kXG4gICAgcGFyc2VyLl9yZXNldCA9IGZ1bmN0aW9uIChodG1sLCBkb2N1bWVudCwgZnJhZ21lbnRDb250ZXh0KSB7XG4gICAgICAgIHBhcnNlclByb3RvLl9yZXNldC5jYWxsKHRoaXMsIGh0bWwsIGRvY3VtZW50LCBmcmFnbWVudENvbnRleHQpO1xuXG4gICAgICAgIHRoaXMuYXR0YWNoYWJsZUVsZW1lbnRMb2NhdGlvbiA9IG51bGw7XG4gICAgICAgIHRoaXMubGFzdEZvc3RlclBhcmVudGluZ0xvY2F0aW9uID0gbnVsbDtcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4gPSBudWxsO1xuXG4gICAgICAgIHBhdGNoT3BlbkVsZW1lbnRzU3RhY2sodGhpcy5vcGVuRWxlbWVudHMsIHBhcnNlcik7XG4gICAgfTtcblxuICAgIHBhcnNlci5fcHJvY2Vzc1Rva2VuSW5Gb3JlaWduQ29udGVudCA9IGZ1bmN0aW9uICh0b2tlbikge1xuICAgICAgICB0aGlzLmN1cnJlbnRUb2tlbiA9IHRva2VuO1xuICAgICAgICBwYXJzZXJQcm90by5fcHJvY2Vzc1Rva2VuSW5Gb3JlaWduQ29udGVudC5jYWxsKHRoaXMsIHRva2VuKTtcbiAgICB9O1xuXG4gICAgcGFyc2VyLl9wcm9jZXNzVG9rZW4gPSBmdW5jdGlvbiAodG9rZW4pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4gPSB0b2tlbjtcbiAgICAgICAgcGFyc2VyUHJvdG8uX3Byb2Nlc3NUb2tlbi5jYWxsKHRoaXMsIHRva2VuKTtcblxuICAgICAgICAvL05PVEU6IDxib2R5PiBhbmQgPGh0bWw+IGFyZSBuZXZlciBwb3BwZWQgZnJvbSB0aGUgc3RhY2ssIHNvIHdlIG5lZWQgdG8gdXBkYXRlZFxuICAgICAgICAvL3RoZWlyIGVuZCBsb2NhdGlvbiBleHBsaWNpdGx5LlxuICAgICAgICBpZiAodG9rZW4udHlwZSA9PT0gVG9rZW5pemVyLkVORF9UQUdfVE9LRU4gJiZcbiAgICAgICAgICAgICh0b2tlbi50YWdOYW1lID09PSAkLkhUTUwgfHxcbiAgICAgICAgICAgICAodG9rZW4udGFnTmFtZSA9PT0gJC5CT0RZICYmIHRoaXMub3BlbkVsZW1lbnRzLmhhc0luU2NvcGUoJC5CT0RZKSkpKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gdGhpcy5vcGVuRWxlbWVudHMuc3RhY2tUb3A7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSB0aGlzLm9wZW5FbGVtZW50cy5pdGVtc1tpXTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRyZWVBZGFwdGVyLmdldFRhZ05hbWUoZWxlbWVudCkgPT09IHRva2VuLnRhZ05hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0RW5kTG9jYXRpb24oZWxlbWVudCwgdG9rZW4pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLy9Eb2N0eXBlXG4gICAgcGFyc2VyLl9zZXREb2N1bWVudFR5cGUgPSBmdW5jdGlvbiAodG9rZW4pIHtcbiAgICAgICAgcGFyc2VyUHJvdG8uX3NldERvY3VtZW50VHlwZS5jYWxsKHRoaXMsIHRva2VuKTtcblxuICAgICAgICB2YXIgZG9jdW1lbnRDaGlsZHJlbiA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0Q2hpbGROb2Rlcyh0aGlzLmRvY3VtZW50KSxcbiAgICAgICAgICAgIGNuTGVuZ3RoID0gZG9jdW1lbnRDaGlsZHJlbi5sZW5ndGg7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjbkxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgbm9kZSA9IGRvY3VtZW50Q2hpbGRyZW5baV07XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnRyZWVBZGFwdGVyLmlzRG9jdW1lbnRUeXBlTm9kZShub2RlKSkge1xuICAgICAgICAgICAgICAgIG5vZGUuX19sb2NhdGlvbiA9IHRva2VuLmxvY2F0aW9uO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8vRWxlbWVudHNcbiAgICBwYXJzZXIuX2F0dGFjaEVsZW1lbnRUb1RyZWUgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICAvL05PVEU6IF9hdHRhY2hFbGVtZW50VG9UcmVlIGlzIGNhbGxlZCBmcm9tIF9hcHBlbmRFbGVtZW50LCBfaW5zZXJ0RWxlbWVudCBhbmQgX2luc2VydFRlbXBsYXRlIG1ldGhvZHMuXG4gICAgICAgIC8vU28gd2Ugd2lsbCB1c2UgdG9rZW4gbG9jYXRpb24gc3RvcmVkIGluIHRoaXMgbWV0aG9kcyBmb3IgdGhlIGVsZW1lbnQuXG4gICAgICAgIGVsZW1lbnQuX19sb2NhdGlvbiA9IHRoaXMuYXR0YWNoYWJsZUVsZW1lbnRMb2NhdGlvbiB8fCBudWxsO1xuICAgICAgICB0aGlzLmF0dGFjaGFibGVFbGVtZW50TG9jYXRpb24gPSBudWxsO1xuICAgICAgICBwYXJzZXJQcm90by5fYXR0YWNoRWxlbWVudFRvVHJlZS5jYWxsKHRoaXMsIGVsZW1lbnQpO1xuICAgIH07XG5cbiAgICBwYXJzZXIuX2FwcGVuZEVsZW1lbnQgPSBmdW5jdGlvbiAodG9rZW4sIG5hbWVzcGFjZVVSSSkge1xuICAgICAgICB0aGlzLmF0dGFjaGFibGVFbGVtZW50TG9jYXRpb24gPSB0b2tlbi5sb2NhdGlvbjtcbiAgICAgICAgcGFyc2VyUHJvdG8uX2FwcGVuZEVsZW1lbnQuY2FsbCh0aGlzLCB0b2tlbiwgbmFtZXNwYWNlVVJJKTtcbiAgICB9O1xuXG4gICAgcGFyc2VyLl9pbnNlcnRFbGVtZW50ID0gZnVuY3Rpb24gKHRva2VuLCBuYW1lc3BhY2VVUkkpIHtcbiAgICAgICAgdGhpcy5hdHRhY2hhYmxlRWxlbWVudExvY2F0aW9uID0gdG9rZW4ubG9jYXRpb247XG4gICAgICAgIHBhcnNlclByb3RvLl9pbnNlcnRFbGVtZW50LmNhbGwodGhpcywgdG9rZW4sIG5hbWVzcGFjZVVSSSk7XG4gICAgfTtcblxuICAgIHBhcnNlci5faW5zZXJ0VGVtcGxhdGUgPSBmdW5jdGlvbiAodG9rZW4pIHtcbiAgICAgICAgdGhpcy5hdHRhY2hhYmxlRWxlbWVudExvY2F0aW9uID0gdG9rZW4ubG9jYXRpb247XG4gICAgICAgIHBhcnNlclByb3RvLl9pbnNlcnRUZW1wbGF0ZS5jYWxsKHRoaXMsIHRva2VuKTtcblxuICAgICAgICB2YXIgdG1wbENvbnRlbnQgPSB0aGlzLnRyZWVBZGFwdGVyLmdldENoaWxkTm9kZXModGhpcy5vcGVuRWxlbWVudHMuY3VycmVudClbMF07XG5cbiAgICAgICAgdG1wbENvbnRlbnQuX19sb2NhdGlvbiA9IG51bGw7XG4gICAgfTtcblxuICAgIHBhcnNlci5faW5zZXJ0RmFrZVJvb3RFbGVtZW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBwYXJzZXJQcm90by5faW5zZXJ0RmFrZVJvb3RFbGVtZW50LmNhbGwodGhpcyk7XG4gICAgICAgIHRoaXMub3BlbkVsZW1lbnRzLmN1cnJlbnQuX19sb2NhdGlvbiA9IG51bGw7XG4gICAgfTtcblxuICAgIC8vQ29tbWVudHNcbiAgICBwYXJzZXIuX2FwcGVuZENvbW1lbnROb2RlID0gZnVuY3Rpb24gKHRva2VuLCBwYXJlbnQpIHtcbiAgICAgICAgcGFyc2VyUHJvdG8uX2FwcGVuZENvbW1lbnROb2RlLmNhbGwodGhpcywgdG9rZW4sIHBhcmVudCk7XG5cbiAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy50cmVlQWRhcHRlci5nZXRDaGlsZE5vZGVzKHBhcmVudCksXG4gICAgICAgICAgICBjb21tZW50Tm9kZSA9IGNoaWxkcmVuW2NoaWxkcmVuLmxlbmd0aCAtIDFdO1xuXG4gICAgICAgIGNvbW1lbnROb2RlLl9fbG9jYXRpb24gPSB0b2tlbi5sb2NhdGlvbjtcbiAgICB9O1xuXG4gICAgLy9UZXh0XG4gICAgcGFyc2VyLl9maW5kRm9zdGVyUGFyZW50aW5nTG9jYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vTk9URTogc3RvcmUgbGFzdCBmb3N0ZXIgcGFyZW50aW5nIGxvY2F0aW9uLCBzbyB3ZSB3aWxsIGJlIGFibGUgdG8gZmluZCBpbnNlcnRlZCB0ZXh0XG4gICAgICAgIC8vaW4gY2FzZSBvZiBmb3N0ZXIgcGFyZW50aW5nXG4gICAgICAgIHRoaXMubGFzdEZvc3RlclBhcmVudGluZ0xvY2F0aW9uID0gcGFyc2VyUHJvdG8uX2ZpbmRGb3N0ZXJQYXJlbnRpbmdMb2NhdGlvbi5jYWxsKHRoaXMpO1xuICAgICAgICByZXR1cm4gdGhpcy5sYXN0Rm9zdGVyUGFyZW50aW5nTG9jYXRpb247XG4gICAgfTtcblxuICAgIHBhcnNlci5faW5zZXJ0Q2hhcmFjdGVycyA9IGZ1bmN0aW9uICh0b2tlbikge1xuICAgICAgICBwYXJzZXJQcm90by5faW5zZXJ0Q2hhcmFjdGVycy5jYWxsKHRoaXMsIHRva2VuKTtcblxuICAgICAgICB2YXIgaGFzRm9zdGVyUGFyZW50ID0gdGhpcy5fc2hvdWxkRm9zdGVyUGFyZW50T25JbnNlcnRpb24oKSxcbiAgICAgICAgICAgIHBhcmVudGluZ0xvY2F0aW9uID0gdGhpcy5sYXN0Rm9zdGVyUGFyZW50aW5nTG9jYXRpb24sXG4gICAgICAgICAgICBwYXJlbnQgPSAoaGFzRm9zdGVyUGFyZW50ICYmIHBhcmVudGluZ0xvY2F0aW9uLnBhcmVudCkgfHxcbiAgICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbkVsZW1lbnRzLmN1cnJlbnRUbXBsQ29udGVudCB8fFxuICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVuRWxlbWVudHMuY3VycmVudCxcbiAgICAgICAgICAgIHNpYmxpbmdzID0gdGhpcy50cmVlQWRhcHRlci5nZXRDaGlsZE5vZGVzKHBhcmVudCksXG4gICAgICAgICAgICB0ZXh0Tm9kZUlkeCA9IGhhc0Zvc3RlclBhcmVudCAmJiBwYXJlbnRpbmdMb2NhdGlvbi5iZWZvcmVFbGVtZW50ID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgc2libGluZ3MuaW5kZXhPZihwYXJlbnRpbmdMb2NhdGlvbi5iZWZvcmVFbGVtZW50KSAtIDEgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICBzaWJsaW5ncy5sZW5ndGggLSAxLFxuICAgICAgICAgICAgdGV4dE5vZGUgPSBzaWJsaW5nc1t0ZXh0Tm9kZUlkeF07XG5cbiAgICAgICAgLy9OT1RFOiBpZiB3ZSBoYXZlIGxvY2F0aW9uIGFzc2lnbmVkIGJ5IGFub3RoZXIgdG9rZW4sIHRoZW4ganVzdCB1cGRhdGUgZW5kIHBvc2l0aW9uXG4gICAgICAgIGlmICh0ZXh0Tm9kZS5fX2xvY2F0aW9uKVxuICAgICAgICAgICAgdGV4dE5vZGUuX19sb2NhdGlvbi5lbmQgPSB0b2tlbi5sb2NhdGlvbi5lbmQ7XG5cbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGV4dE5vZGUuX19sb2NhdGlvbiA9IHRva2VuLmxvY2F0aW9uO1xuICAgIH07XG59O1xuXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgSFRNTCA9IHJlcXVpcmUoJy4uL2NvbW1vbi9odG1sJyk7XHJcblxyXG4vL0FsaWFzZXNcclxudmFyICQgPSBIVE1MLlRBR19OQU1FUyxcclxuICAgIE5TID0gSFRNTC5OQU1FU1BBQ0VTO1xyXG5cclxuLy9FbGVtZW50IHV0aWxzXHJcblxyXG4vL09QVElNSVpBVElPTjogSW50ZWdlciBjb21wYXJpc29ucyBhcmUgbG93LWNvc3QsIHNvIHdlIGNhbiB1c2UgdmVyeSBmYXN0IHRhZyBuYW1lIGxlbmd0aCBmaWx0ZXJzIGhlcmUuXHJcbi8vSXQncyBmYXN0ZXIgdGhhbiB1c2luZyBkaWN0aW9uYXJ5LlxyXG5mdW5jdGlvbiBpc0ltcGxpZWRFbmRUYWdSZXF1aXJlZCh0bikge1xyXG4gICAgc3dpdGNoICh0bi5sZW5ndGgpIHtcclxuICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgIHJldHVybiB0biA9PT0gJC5QO1xyXG5cclxuICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgIHJldHVybiB0biA9PT0gJC5SUCB8fCB0biA9PT0gJC5SVCB8fCB0biA9PT0gJC5ERCB8fCB0biA9PT0gJC5EVCB8fCB0biA9PT0gJC5MSTtcclxuXHJcbiAgICAgICAgY2FzZSA2OlxyXG4gICAgICAgICAgICByZXR1cm4gdG4gPT09ICQuT1BUSU9OO1xyXG5cclxuICAgICAgICBjYXNlIDg6XHJcbiAgICAgICAgICAgIHJldHVybiB0biA9PT0gJC5PUFRHUk9VUDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzU2NvcGluZ0VsZW1lbnQodG4sIG5zKSB7XHJcbiAgICBzd2l0Y2ggKHRuLmxlbmd0aCkge1xyXG4gICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgaWYgKHRuID09PSAkLlREIHx8IHRuID09PSAkLlRIKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5zID09PSBOUy5IVE1MO1xyXG5cclxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuTUkgfHwgdG4gPT09ICQuTU8gfHwgdG4gPT0gJC5NTiB8fCB0biA9PT0gJC5NUylcclxuICAgICAgICAgICAgICAgIHJldHVybiBucyA9PT0gTlMuTUFUSE1MO1xyXG5cclxuICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgIGNhc2UgNDpcclxuICAgICAgICAgICAgaWYgKHRuID09PSAkLkhUTUwpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnMgPT09IE5TLkhUTUw7XHJcblxyXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5ERVNDKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5zID09PSBOUy5TVkc7XHJcblxyXG4gICAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgY2FzZSA1OlxyXG4gICAgICAgICAgICBpZiAodG4gPT09ICQuVEFCTEUpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnMgPT09IE5TLkhUTUw7XHJcblxyXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5NVEVYVClcclxuICAgICAgICAgICAgICAgIHJldHVybiBucyA9PT0gTlMuTUFUSE1MO1xyXG5cclxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuVElUTEUpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnMgPT09IE5TLlNWRztcclxuXHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBjYXNlIDY6XHJcbiAgICAgICAgICAgIHJldHVybiAodG4gPT09ICQuQVBQTEVUIHx8IHRuID09PSAkLk9CSkVDVCkgJiYgbnMgPT09IE5TLkhUTUw7XHJcblxyXG4gICAgICAgIGNhc2UgNzpcclxuICAgICAgICAgICAgcmV0dXJuICh0biA9PT0gJC5DQVBUSU9OIHx8IHRuID09PSAkLk1BUlFVRUUpICYmIG5zID09PSBOUy5IVE1MO1xyXG5cclxuICAgICAgICBjYXNlIDg6XHJcbiAgICAgICAgICAgIHJldHVybiB0biA9PT0gJC5URU1QTEFURSAmJiBucyA9PT0gTlMuSFRNTDtcclxuXHJcbiAgICAgICAgY2FzZSAxMzpcclxuICAgICAgICAgICAgcmV0dXJuIHRuID09PSAkLkZPUkVJR05fT0JKRUNUICYmIG5zID09PSBOUy5TVkc7XHJcblxyXG4gICAgICAgIGNhc2UgMTQ6XHJcbiAgICAgICAgICAgIHJldHVybiB0biA9PT0gJC5BTk5PVEFUSU9OX1hNTCAmJiBucyA9PT0gTlMuTUFUSE1MO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuLy9TdGFjayBvZiBvcGVuIGVsZW1lbnRzXHJcbnZhciBPcGVuRWxlbWVudFN0YWNrID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZG9jdW1lbnQsIHRyZWVBZGFwdGVyKSB7XHJcbiAgICB0aGlzLnN0YWNrVG9wID0gLTE7XHJcbiAgICB0aGlzLml0ZW1zID0gW107XHJcbiAgICB0aGlzLmN1cnJlbnQgPSBkb2N1bWVudDtcclxuICAgIHRoaXMuY3VycmVudFRhZ05hbWUgPSBudWxsO1xyXG4gICAgdGhpcy5jdXJyZW50VG1wbENvbnRlbnQgPSBudWxsO1xyXG4gICAgdGhpcy50bXBsQ291bnQgPSAwO1xyXG4gICAgdGhpcy50cmVlQWRhcHRlciA9IHRyZWVBZGFwdGVyO1xyXG59O1xyXG5cclxuLy9JbmRleCBvZiBlbGVtZW50XHJcbk9wZW5FbGVtZW50U3RhY2sucHJvdG90eXBlLl9pbmRleE9mID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgIHZhciBpZHggPSAtMTtcclxuXHJcbiAgICBmb3IgKHZhciBpID0gdGhpcy5zdGFja1RvcDsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICBpZiAodGhpcy5pdGVtc1tpXSA9PT0gZWxlbWVudCkge1xyXG4gICAgICAgICAgICBpZHggPSBpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gaWR4O1xyXG59O1xyXG5cclxuLy9VcGRhdGUgY3VycmVudCBlbGVtZW50XHJcbk9wZW5FbGVtZW50U3RhY2sucHJvdG90eXBlLl9pc0luVGVtcGxhdGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICBpZiAodGhpcy5jdXJyZW50VGFnTmFtZSAhPT0gJC5URU1QTEFURSlcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMudHJlZUFkYXB0ZXIuZ2V0TmFtZXNwYWNlVVJJKHRoaXMuY3VycmVudCkgPT09IE5TLkhUTUw7XHJcbn07XHJcblxyXG5PcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS5fdXBkYXRlQ3VycmVudEVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB0aGlzLmN1cnJlbnQgPSB0aGlzLml0ZW1zW3RoaXMuc3RhY2tUb3BdO1xyXG4gICAgdGhpcy5jdXJyZW50VGFnTmFtZSA9IHRoaXMuY3VycmVudCAmJiB0aGlzLnRyZWVBZGFwdGVyLmdldFRhZ05hbWUodGhpcy5jdXJyZW50KTtcclxuXHJcbiAgICB0aGlzLmN1cnJlbnRUbXBsQ29udGVudCA9IHRoaXMuX2lzSW5UZW1wbGF0ZSgpID8gdGhpcy50cmVlQWRhcHRlci5nZXRDaGlsZE5vZGVzKHRoaXMuY3VycmVudClbMF0gOiBudWxsO1xyXG59O1xyXG5cclxuLy9NdXRhdGlvbnNcclxuT3BlbkVsZW1lbnRTdGFjay5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICB0aGlzLml0ZW1zWysrdGhpcy5zdGFja1RvcF0gPSBlbGVtZW50O1xyXG4gICAgdGhpcy5fdXBkYXRlQ3VycmVudEVsZW1lbnQoKTtcclxuXHJcbiAgICBpZiAodGhpcy5faXNJblRlbXBsYXRlKCkpXHJcbiAgICAgICAgdGhpcy50bXBsQ291bnQrKztcclxuXHJcbn07XHJcblxyXG5PcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB0aGlzLnN0YWNrVG9wLS07XHJcblxyXG4gICAgaWYgKHRoaXMudG1wbENvdW50ID4gMCAmJiB0aGlzLl9pc0luVGVtcGxhdGUoKSlcclxuICAgICAgICB0aGlzLnRtcGxDb3VudC0tO1xyXG5cclxuICAgIHRoaXMuX3VwZGF0ZUN1cnJlbnRFbGVtZW50KCk7XHJcbn07XHJcblxyXG5PcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS5yZXBsYWNlID0gZnVuY3Rpb24gKG9sZEVsZW1lbnQsIG5ld0VsZW1lbnQpIHtcclxuICAgIHZhciBpZHggPSB0aGlzLl9pbmRleE9mKG9sZEVsZW1lbnQpO1xyXG4gICAgdGhpcy5pdGVtc1tpZHhdID0gbmV3RWxlbWVudDtcclxuXHJcbiAgICBpZiAoaWR4ID09PSB0aGlzLnN0YWNrVG9wKVxyXG4gICAgICAgIHRoaXMuX3VwZGF0ZUN1cnJlbnRFbGVtZW50KCk7XHJcbn07XHJcblxyXG5PcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS5pbnNlcnRBZnRlciA9IGZ1bmN0aW9uIChyZWZlcmVuY2VFbGVtZW50LCBuZXdFbGVtZW50KSB7XHJcbiAgICB2YXIgaW5zZXJ0aW9uSWR4ID0gdGhpcy5faW5kZXhPZihyZWZlcmVuY2VFbGVtZW50KSArIDE7XHJcblxyXG4gICAgdGhpcy5pdGVtcy5zcGxpY2UoaW5zZXJ0aW9uSWR4LCAwLCBuZXdFbGVtZW50KTtcclxuXHJcbiAgICBpZiAoaW5zZXJ0aW9uSWR4ID09ICsrdGhpcy5zdGFja1RvcClcclxuICAgICAgICB0aGlzLl91cGRhdGVDdXJyZW50RWxlbWVudCgpO1xyXG59O1xyXG5cclxuT3BlbkVsZW1lbnRTdGFjay5wcm90b3R5cGUucG9wVW50aWxUYWdOYW1lUG9wcGVkID0gZnVuY3Rpb24gKHRhZ05hbWUpIHtcclxuICAgIHdoaWxlICh0aGlzLnN0YWNrVG9wID4gLTEpIHtcclxuICAgICAgICB2YXIgdG4gPSB0aGlzLmN1cnJlbnRUYWdOYW1lO1xyXG5cclxuICAgICAgICB0aGlzLnBvcCgpO1xyXG5cclxuICAgICAgICBpZiAodG4gPT09IHRhZ05hbWUpXHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG59O1xyXG5cclxuT3BlbkVsZW1lbnRTdGFjay5wcm90b3R5cGUucG9wVW50aWxUZW1wbGF0ZVBvcHBlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHdoaWxlICh0aGlzLnN0YWNrVG9wID4gLTEpIHtcclxuICAgICAgICB2YXIgdG4gPSB0aGlzLmN1cnJlbnRUYWdOYW1lLFxyXG4gICAgICAgICAgICBucyA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0TmFtZXNwYWNlVVJJKHRoaXMuY3VycmVudCk7XHJcblxyXG4gICAgICAgIHRoaXMucG9wKCk7XHJcblxyXG4gICAgICAgIGlmICh0biA9PT0gJC5URU1QTEFURSAmJiBucyA9PT0gTlMuSFRNTClcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbn07XHJcblxyXG5PcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS5wb3BVbnRpbEVsZW1lbnRQb3BwZWQgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgd2hpbGUgKHRoaXMuc3RhY2tUb3AgPiAtMSkge1xyXG4gICAgICAgIHZhciBwb3BwZWRFbGVtZW50ID0gdGhpcy5jdXJyZW50O1xyXG5cclxuICAgICAgICB0aGlzLnBvcCgpO1xyXG5cclxuICAgICAgICBpZiAocG9wcGVkRWxlbWVudCA9PT0gZWxlbWVudClcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbn07XHJcblxyXG5PcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS5wb3BVbnRpbE51bWJlcmVkSGVhZGVyUG9wcGVkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgd2hpbGUgKHRoaXMuc3RhY2tUb3AgPiAtMSkge1xyXG4gICAgICAgIHZhciB0biA9IHRoaXMuY3VycmVudFRhZ05hbWU7XHJcblxyXG4gICAgICAgIHRoaXMucG9wKCk7XHJcblxyXG4gICAgICAgIGlmICh0biA9PT0gJC5IMSB8fCB0biA9PT0gJC5IMiB8fCB0biA9PT0gJC5IMyB8fCB0biA9PT0gJC5INCB8fCB0biA9PT0gJC5INSB8fCB0biA9PT0gJC5INilcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbn07XHJcblxyXG5PcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS5wb3BBbGxVcFRvSHRtbEVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAvL05PVEU6IGhlcmUgd2UgYXNzdW1lIHRoYXQgcm9vdCA8aHRtbD4gZWxlbWVudCBpcyBhbHdheXMgZmlyc3QgaW4gdGhlIG9wZW4gZWxlbWVudCBzdGFjaywgc29cclxuICAgIC8vd2UgcGVyZm9ybSB0aGlzIGZhc3Qgc3RhY2sgY2xlYW4gdXAuXHJcbiAgICB0aGlzLnN0YWNrVG9wID0gMDtcclxuICAgIHRoaXMuX3VwZGF0ZUN1cnJlbnRFbGVtZW50KCk7XHJcbn07XHJcblxyXG5PcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS5jbGVhckJhY2tUb1RhYmxlQ29udGV4dCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHdoaWxlICh0aGlzLmN1cnJlbnRUYWdOYW1lICE9PSAkLlRBQkxFICYmIHRoaXMuY3VycmVudFRhZ05hbWUgIT09ICQuVEVNUExBVEUgJiYgdGhpcy5jdXJyZW50VGFnTmFtZSAhPT0gJC5IVE1MKVxyXG4gICAgICAgIHRoaXMucG9wKCk7XHJcbn07XHJcblxyXG5PcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS5jbGVhckJhY2tUb1RhYmxlQm9keUNvbnRleHQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB3aGlsZSAodGhpcy5jdXJyZW50VGFnTmFtZSAhPT0gJC5UQk9EWSAmJiB0aGlzLmN1cnJlbnRUYWdOYW1lICE9PSAkLlRGT09UICYmXHJcbiAgICAgICAgICAgdGhpcy5jdXJyZW50VGFnTmFtZSAhPT0gJC5USEVBRCAmJiB0aGlzLmN1cnJlbnRUYWdOYW1lICE9PSAkLlRFTVBMQVRFICYmXHJcbiAgICAgICAgICAgdGhpcy5jdXJyZW50VGFnTmFtZSAhPT0gJC5IVE1MKSB7XHJcbiAgICAgICAgdGhpcy5wb3AoKTtcclxuICAgIH1cclxufTtcclxuXHJcbk9wZW5FbGVtZW50U3RhY2sucHJvdG90eXBlLmNsZWFyQmFja1RvVGFibGVSb3dDb250ZXh0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgd2hpbGUgKHRoaXMuY3VycmVudFRhZ05hbWUgIT09ICQuVFIgJiYgdGhpcy5jdXJyZW50VGFnTmFtZSAhPT0gJC5URU1QTEFURSAmJiB0aGlzLmN1cnJlbnRUYWdOYW1lICE9PSAkLkhUTUwpXHJcbiAgICAgICAgdGhpcy5wb3AoKTtcclxufTtcclxuXHJcbk9wZW5FbGVtZW50U3RhY2sucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICBmb3IgKHZhciBpID0gdGhpcy5zdGFja1RvcDsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICBpZiAodGhpcy5pdGVtc1tpXSA9PT0gZWxlbWVudCkge1xyXG4gICAgICAgICAgICB0aGlzLml0ZW1zLnNwbGljZShpLCAxKTtcclxuICAgICAgICAgICAgdGhpcy5zdGFja1RvcC0tO1xyXG4gICAgICAgICAgICB0aGlzLl91cGRhdGVDdXJyZW50RWxlbWVudCgpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn07XHJcblxyXG4vL1NlYXJjaFxyXG5PcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS50cnlQZWVrUHJvcGVybHlOZXN0ZWRCb2R5RWxlbWVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIC8vUHJvcGVybHkgbmVzdGVkIDxib2R5PiBlbGVtZW50IChzaG91bGQgYmUgc2Vjb25kIGVsZW1lbnQgaW4gc3RhY2spLlxyXG4gICAgdmFyIGVsZW1lbnQgPSB0aGlzLml0ZW1zWzFdO1xyXG4gICAgcmV0dXJuIGVsZW1lbnQgJiYgdGhpcy50cmVlQWRhcHRlci5nZXRUYWdOYW1lKGVsZW1lbnQpID09PSAkLkJPRFkgPyBlbGVtZW50IDogbnVsbDtcclxufTtcclxuXHJcbk9wZW5FbGVtZW50U3RhY2sucHJvdG90eXBlLmNvbnRhaW5zID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgIHJldHVybiB0aGlzLl9pbmRleE9mKGVsZW1lbnQpID4gLTE7XHJcbn07XHJcblxyXG5PcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS5nZXRDb21tb25BbmNlc3RvciA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICB2YXIgZWxlbWVudElkeCA9IHRoaXMuX2luZGV4T2YoZWxlbWVudCk7XHJcblxyXG4gICAgcmV0dXJuIC0tZWxlbWVudElkeCA+PSAwID8gdGhpcy5pdGVtc1tlbGVtZW50SWR4XSA6IG51bGw7XHJcbn07XHJcblxyXG5PcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS5pc1Jvb3RIdG1sRWxlbWVudEN1cnJlbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zdGFja1RvcCA9PT0gMCAmJiB0aGlzLmN1cnJlbnRUYWdOYW1lID09PSAkLkhUTUw7XHJcbn07XHJcblxyXG4vL0VsZW1lbnQgaW4gc2NvcGVcclxuT3BlbkVsZW1lbnRTdGFjay5wcm90b3R5cGUuaGFzSW5TY29wZSA9IGZ1bmN0aW9uICh0YWdOYW1lKSB7XHJcbiAgICBmb3IgKHZhciBpID0gdGhpcy5zdGFja1RvcDsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICB2YXIgdG4gPSB0aGlzLnRyZWVBZGFwdGVyLmdldFRhZ05hbWUodGhpcy5pdGVtc1tpXSk7XHJcblxyXG4gICAgICAgIGlmICh0biA9PT0gdGFnTmFtZSlcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcblxyXG4gICAgICAgIHZhciBucyA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0TmFtZXNwYWNlVVJJKHRoaXMuaXRlbXNbaV0pO1xyXG5cclxuICAgICAgICBpZiAoaXNTY29waW5nRWxlbWVudCh0biwgbnMpKVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRydWU7XHJcbn07XHJcblxyXG5PcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS5oYXNOdW1iZXJlZEhlYWRlckluU2NvcGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICBmb3IgKHZhciBpID0gdGhpcy5zdGFja1RvcDsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICB2YXIgdG4gPSB0aGlzLnRyZWVBZGFwdGVyLmdldFRhZ05hbWUodGhpcy5pdGVtc1tpXSk7XHJcblxyXG4gICAgICAgIGlmICh0biA9PT0gJC5IMSB8fCB0biA9PT0gJC5IMiB8fCB0biA9PT0gJC5IMyB8fCB0biA9PT0gJC5INCB8fCB0biA9PT0gJC5INSB8fCB0biA9PT0gJC5INilcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcblxyXG4gICAgICAgIGlmIChpc1Njb3BpbmdFbGVtZW50KHRuLCB0aGlzLnRyZWVBZGFwdGVyLmdldE5hbWVzcGFjZVVSSSh0aGlzLml0ZW1zW2ldKSkpXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdHJ1ZTtcclxufTtcclxuXHJcbk9wZW5FbGVtZW50U3RhY2sucHJvdG90eXBlLmhhc0luTGlzdEl0ZW1TY29wZSA9IGZ1bmN0aW9uICh0YWdOYW1lKSB7XHJcbiAgICBmb3IgKHZhciBpID0gdGhpcy5zdGFja1RvcDsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICB2YXIgdG4gPSB0aGlzLnRyZWVBZGFwdGVyLmdldFRhZ05hbWUodGhpcy5pdGVtc1tpXSk7XHJcblxyXG4gICAgICAgIGlmICh0biA9PT0gdGFnTmFtZSlcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcblxyXG4gICAgICAgIHZhciBucyA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0TmFtZXNwYWNlVVJJKHRoaXMuaXRlbXNbaV0pO1xyXG5cclxuICAgICAgICBpZiAoKCh0biA9PT0gJC5VTCB8fCB0biA9PT0gJC5PTCkgJiYgbnMgPT09IE5TLkhUTUwpIHx8IGlzU2NvcGluZ0VsZW1lbnQodG4sIG5zKSlcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0cnVlO1xyXG59O1xyXG5cclxuT3BlbkVsZW1lbnRTdGFjay5wcm90b3R5cGUuaGFzSW5CdXR0b25TY29wZSA9IGZ1bmN0aW9uICh0YWdOYW1lKSB7XHJcbiAgICBmb3IgKHZhciBpID0gdGhpcy5zdGFja1RvcDsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICB2YXIgdG4gPSB0aGlzLnRyZWVBZGFwdGVyLmdldFRhZ05hbWUodGhpcy5pdGVtc1tpXSk7XHJcblxyXG4gICAgICAgIGlmICh0biA9PT0gdGFnTmFtZSlcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcblxyXG4gICAgICAgIHZhciBucyA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0TmFtZXNwYWNlVVJJKHRoaXMuaXRlbXNbaV0pO1xyXG5cclxuICAgICAgICBpZiAoKHRuID09PSAkLkJVVFRPTiAmJiBucyA9PT0gTlMuSFRNTCkgfHwgaXNTY29waW5nRWxlbWVudCh0biwgbnMpKVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRydWU7XHJcbn07XHJcblxyXG5PcGVuRWxlbWVudFN0YWNrLnByb3RvdHlwZS5oYXNJblRhYmxlU2NvcGUgPSBmdW5jdGlvbiAodGFnTmFtZSkge1xyXG4gICAgZm9yICh2YXIgaSA9IHRoaXMuc3RhY2tUb3A7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgdmFyIHRuID0gdGhpcy50cmVlQWRhcHRlci5nZXRUYWdOYW1lKHRoaXMuaXRlbXNbaV0pO1xyXG5cclxuICAgICAgICBpZiAodG4gPT09IHRhZ05hbWUpXHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG5cclxuICAgICAgICB2YXIgbnMgPSB0aGlzLnRyZWVBZGFwdGVyLmdldE5hbWVzcGFjZVVSSSh0aGlzLml0ZW1zW2ldKTtcclxuXHJcbiAgICAgICAgaWYgKCh0biA9PT0gJC5UQUJMRSB8fCB0biA9PT0gJC5URU1QTEFURSB8fCB0biA9PT0gJC5IVE1MKSAmJiBucyA9PT0gTlMuSFRNTClcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0cnVlO1xyXG59O1xyXG5cclxuT3BlbkVsZW1lbnRTdGFjay5wcm90b3R5cGUuaGFzVGFibGVCb2R5Q29udGV4dEluVGFibGVTY29wZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIGZvciAodmFyIGkgPSB0aGlzLnN0YWNrVG9wOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgIHZhciB0biA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0VGFnTmFtZSh0aGlzLml0ZW1zW2ldKTtcclxuXHJcbiAgICAgICAgaWYgKHRuID09PSAkLlRCT0RZIHx8IHRuID09PSAkLlRIRUFEIHx8IHRuID09PSAkLlRGT09UKVxyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuXHJcbiAgICAgICAgdmFyIG5zID0gdGhpcy50cmVlQWRhcHRlci5nZXROYW1lc3BhY2VVUkkodGhpcy5pdGVtc1tpXSk7XHJcblxyXG4gICAgICAgIGlmICgodG4gPT09ICQuVEFCTEUgfHwgdG4gPT09ICQuSFRNTCkgJiYgbnMgPT09IE5TLkhUTUwpXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdHJ1ZTtcclxufTtcclxuXHJcbk9wZW5FbGVtZW50U3RhY2sucHJvdG90eXBlLmhhc0luU2VsZWN0U2NvcGUgPSBmdW5jdGlvbiAodGFnTmFtZSkge1xyXG4gICAgZm9yICh2YXIgaSA9IHRoaXMuc3RhY2tUb3A7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgdmFyIHRuID0gdGhpcy50cmVlQWRhcHRlci5nZXRUYWdOYW1lKHRoaXMuaXRlbXNbaV0pO1xyXG5cclxuICAgICAgICBpZiAodG4gPT09IHRhZ05hbWUpXHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG5cclxuICAgICAgICB2YXIgbnMgPSB0aGlzLnRyZWVBZGFwdGVyLmdldE5hbWVzcGFjZVVSSSh0aGlzLml0ZW1zW2ldKTtcclxuXHJcbiAgICAgICAgaWYgKHRuICE9PSAkLk9QVElPTiAmJiB0biAhPT0gJC5PUFRHUk9VUCAmJiBucyA9PT0gTlMuSFRNTClcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0cnVlO1xyXG59O1xyXG5cclxuLy9JbXBsaWVkIGVuZCB0YWdzXHJcbk9wZW5FbGVtZW50U3RhY2sucHJvdG90eXBlLmdlbmVyYXRlSW1wbGllZEVuZFRhZ3MgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB3aGlsZSAoaXNJbXBsaWVkRW5kVGFnUmVxdWlyZWQodGhpcy5jdXJyZW50VGFnTmFtZSkpXHJcbiAgICAgICAgdGhpcy5wb3AoKTtcclxufTtcclxuXHJcbk9wZW5FbGVtZW50U3RhY2sucHJvdG90eXBlLmdlbmVyYXRlSW1wbGllZEVuZFRhZ3NXaXRoRXhjbHVzaW9uID0gZnVuY3Rpb24gKGV4Y2x1c2lvblRhZ05hbWUpIHtcclxuICAgIHdoaWxlIChpc0ltcGxpZWRFbmRUYWdSZXF1aXJlZCh0aGlzLmN1cnJlbnRUYWdOYW1lKSAmJiB0aGlzLmN1cnJlbnRUYWdOYW1lICE9PSBleGNsdXNpb25UYWdOYW1lKVxyXG4gICAgICAgIHRoaXMucG9wKCk7XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFRva2VuaXplciA9IHJlcXVpcmUoJy4uL3Rva2VuaXphdGlvbi90b2tlbml6ZXInKSxcbiAgICBPcGVuRWxlbWVudFN0YWNrID0gcmVxdWlyZSgnLi9vcGVuX2VsZW1lbnRfc3RhY2snKSxcbiAgICBGb3JtYXR0aW5nRWxlbWVudExpc3QgPSByZXF1aXJlKCcuL2Zvcm1hdHRpbmdfZWxlbWVudF9saXN0JyksXG4gICAgTG9jYXRpb25JbmZvTWl4aW4gPSByZXF1aXJlKCcuL2xvY2F0aW9uX2luZm9fbWl4aW4nKSxcbiAgICBEZWZhdWx0VHJlZUFkYXB0ZXIgPSByZXF1aXJlKCcuLi90cmVlX2FkYXB0ZXJzL2RlZmF1bHQnKSxcbiAgICBEb2N0eXBlID0gcmVxdWlyZSgnLi4vY29tbW9uL2RvY3R5cGUnKSxcbiAgICBGb3JlaWduQ29udGVudCA9IHJlcXVpcmUoJy4uL2NvbW1vbi9mb3JlaWduX2NvbnRlbnQnKSxcbiAgICBVdGlscyA9IHJlcXVpcmUoJy4uL2NvbW1vbi91dGlscycpLFxuICAgIFVOSUNPREUgPSByZXF1aXJlKCcuLi9jb21tb24vdW5pY29kZScpLFxuICAgIEhUTUwgPSByZXF1aXJlKCcuLi9jb21tb24vaHRtbCcpO1xuXG4vL0FsaWFzZXNcbnZhciAkID0gSFRNTC5UQUdfTkFNRVMsXG4gICAgTlMgPSBIVE1MLk5BTUVTUEFDRVMsXG4gICAgQVRUUlMgPSBIVE1MLkFUVFJTO1xuXG4vL0RlZmF1bHQgb3B0aW9uc1xudmFyIERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBkZWNvZGVIdG1sRW50aXRpZXM6IHRydWUsXG4gICAgbG9jYXRpb25JbmZvOiBmYWxzZVxufTtcblxuLy9NaXNjIGNvbnN0YW50c1xudmFyIFNFQVJDSEFCTEVfSU5ERVhfREVGQVVMVF9QUk9NUFQgPSAnVGhpcyBpcyBhIHNlYXJjaGFibGUgaW5kZXguIEVudGVyIHNlYXJjaCBrZXl3b3JkczogJyxcbiAgICBTRUFSQ0hBQkxFX0lOREVYX0lOUFVUX05BTUUgPSAnaXNpbmRleCcsXG4gICAgSElEREVOX0lOUFVUX1RZUEUgPSAnaGlkZGVuJztcblxuLy9BZG9wdGlvbiBhZ2VuY3kgbG9vcHMgaXRlcmF0aW9uIGNvdW50XG52YXIgQUFfT1VURVJfTE9PUF9JVEVSID0gOCxcbiAgICBBQV9JTk5FUl9MT09QX0lURVIgPSAzO1xuXG4vL0luc2VydGlvbiBtb2Rlc1xudmFyIElOSVRJQUxfTU9ERSA9ICdJTklUSUFMX01PREUnLFxuICAgIEJFRk9SRV9IVE1MX01PREUgPSAnQkVGT1JFX0hUTUxfTU9ERScsXG4gICAgQkVGT1JFX0hFQURfTU9ERSA9ICdCRUZPUkVfSEVBRF9NT0RFJyxcbiAgICBJTl9IRUFEX01PREUgPSAnSU5fSEVBRF9NT0RFJyxcbiAgICBBRlRFUl9IRUFEX01PREUgPSAnQUZURVJfSEVBRF9NT0RFJyxcbiAgICBJTl9CT0RZX01PREUgPSAnSU5fQk9EWV9NT0RFJyxcbiAgICBURVhUX01PREUgPSAnVEVYVF9NT0RFJyxcbiAgICBJTl9UQUJMRV9NT0RFID0gJ0lOX1RBQkxFX01PREUnLFxuICAgIElOX1RBQkxFX1RFWFRfTU9ERSA9ICdJTl9UQUJMRV9URVhUX01PREUnLFxuICAgIElOX0NBUFRJT05fTU9ERSA9ICdJTl9DQVBUSU9OX01PREUnLFxuICAgIElOX0NPTFVNTl9HUk9VUF9NT0RFID0gJ0lOX0NPTFVNTl9HUk9VUF9NT0RFJyxcbiAgICBJTl9UQUJMRV9CT0RZX01PREUgPSAnSU5fVEFCTEVfQk9EWV9NT0RFJyxcbiAgICBJTl9ST1dfTU9ERSA9ICdJTl9ST1dfTU9ERScsXG4gICAgSU5fQ0VMTF9NT0RFID0gJ0lOX0NFTExfTU9ERScsXG4gICAgSU5fU0VMRUNUX01PREUgPSAnSU5fU0VMRUNUX01PREUnLFxuICAgIElOX1NFTEVDVF9JTl9UQUJMRV9NT0RFID0gJ0lOX1NFTEVDVF9JTl9UQUJMRV9NT0RFJyxcbiAgICBJTl9URU1QTEFURV9NT0RFID0gJ0lOX1RFTVBMQVRFX01PREUnLFxuICAgIEFGVEVSX0JPRFlfTU9ERSA9ICdBRlRFUl9CT0RZX01PREUnLFxuICAgIElOX0ZSQU1FU0VUX01PREUgPSAnSU5fRlJBTUVTRVRfTU9ERScsXG4gICAgQUZURVJfRlJBTUVTRVRfTU9ERSA9ICdBRlRFUl9GUkFNRVNFVF9NT0RFJyxcbiAgICBBRlRFUl9BRlRFUl9CT0RZX01PREUgPSAnQUZURVJfQUZURVJfQk9EWV9NT0RFJyxcbiAgICBBRlRFUl9BRlRFUl9GUkFNRVNFVF9NT0RFID0gJ0FGVEVSX0FGVEVSX0ZSQU1FU0VUX01PREUnO1xuXG4vL0luc2VydGlvbiBtb2RlIHJlc2V0IG1hcFxudmFyIElOU0VSVElPTl9NT0RFX1JFU0VUX01BUCA9IHt9O1xuXG5JTlNFUlRJT05fTU9ERV9SRVNFVF9NQVBbJC5UUl0gPSBJTl9ST1dfTU9ERTtcbklOU0VSVElPTl9NT0RFX1JFU0VUX01BUFskLlRCT0RZXSA9XG5JTlNFUlRJT05fTU9ERV9SRVNFVF9NQVBbJC5USEVBRF0gPVxuSU5TRVJUSU9OX01PREVfUkVTRVRfTUFQWyQuVEZPT1RdID0gSU5fVEFCTEVfQk9EWV9NT0RFO1xuSU5TRVJUSU9OX01PREVfUkVTRVRfTUFQWyQuQ0FQVElPTl0gPSBJTl9DQVBUSU9OX01PREU7XG5JTlNFUlRJT05fTU9ERV9SRVNFVF9NQVBbJC5DT0xHUk9VUF0gPSBJTl9DT0xVTU5fR1JPVVBfTU9ERTtcbklOU0VSVElPTl9NT0RFX1JFU0VUX01BUFskLlRBQkxFXSA9IElOX1RBQkxFX01PREU7XG5JTlNFUlRJT05fTU9ERV9SRVNFVF9NQVBbJC5CT0RZXSA9IElOX0JPRFlfTU9ERTtcbklOU0VSVElPTl9NT0RFX1JFU0VUX01BUFskLkZSQU1FU0VUXSA9IElOX0ZSQU1FU0VUX01PREU7XG5cbi8vVGVtcGxhdGUgaW5zZXJ0aW9uIG1vZGUgc3dpdGNoIG1hcFxudmFyIFRFTVBMQVRFX0lOU0VSVElPTl9NT0RFX1NXSVRDSF9NQVAgPSB7fTtcblxuVEVNUExBVEVfSU5TRVJUSU9OX01PREVfU1dJVENIX01BUFskLkNBUFRJT05dID1cblRFTVBMQVRFX0lOU0VSVElPTl9NT0RFX1NXSVRDSF9NQVBbJC5DT0xHUk9VUF0gPVxuVEVNUExBVEVfSU5TRVJUSU9OX01PREVfU1dJVENIX01BUFskLlRCT0RZXSA9XG5URU1QTEFURV9JTlNFUlRJT05fTU9ERV9TV0lUQ0hfTUFQWyQuVEZPT1RdID1cblRFTVBMQVRFX0lOU0VSVElPTl9NT0RFX1NXSVRDSF9NQVBbJC5USEVBRF0gPSBJTl9UQUJMRV9NT0RFO1xuVEVNUExBVEVfSU5TRVJUSU9OX01PREVfU1dJVENIX01BUFskLkNPTF0gPSBJTl9DT0xVTU5fR1JPVVBfTU9ERTtcblRFTVBMQVRFX0lOU0VSVElPTl9NT0RFX1NXSVRDSF9NQVBbJC5UUl0gPSBJTl9UQUJMRV9CT0RZX01PREU7XG5URU1QTEFURV9JTlNFUlRJT05fTU9ERV9TV0lUQ0hfTUFQWyQuVERdID1cblRFTVBMQVRFX0lOU0VSVElPTl9NT0RFX1NXSVRDSF9NQVBbJC5USF0gPSBJTl9ST1dfTU9ERTtcblxuLy9Ub2tlbiBoYW5kbGVycyBtYXAgZm9yIGluc2VydGlvbiBtb2Rlc1xudmFyIF8gPSB7fTtcblxuX1tJTklUSUFMX01PREVdID0ge307XG5fW0lOSVRJQUxfTU9ERV1bVG9rZW5pemVyLkNIQVJBQ1RFUl9UT0tFTl0gPVxuX1tJTklUSUFMX01PREVdW1Rva2VuaXplci5OVUxMX0NIQVJBQ1RFUl9UT0tFTl0gPSB0b2tlbkluSW5pdGlhbE1vZGU7XG5fW0lOSVRJQUxfTU9ERV1bVG9rZW5pemVyLldISVRFU1BBQ0VfQ0hBUkFDVEVSX1RPS0VOXSA9IGlnbm9yZVRva2VuO1xuX1tJTklUSUFMX01PREVdW1Rva2VuaXplci5DT01NRU5UX1RPS0VOXSA9IGFwcGVuZENvbW1lbnQ7XG5fW0lOSVRJQUxfTU9ERV1bVG9rZW5pemVyLkRPQ1RZUEVfVE9LRU5dID0gZG9jdHlwZUluSW5pdGlhbE1vZGU7XG5fW0lOSVRJQUxfTU9ERV1bVG9rZW5pemVyLlNUQVJUX1RBR19UT0tFTl0gPVxuX1tJTklUSUFMX01PREVdW1Rva2VuaXplci5FTkRfVEFHX1RPS0VOXSA9XG5fW0lOSVRJQUxfTU9ERV1bVG9rZW5pemVyLkVPRl9UT0tFTl0gPSB0b2tlbkluSW5pdGlhbE1vZGU7XG5cbl9bQkVGT1JFX0hUTUxfTU9ERV0gPSB7fTtcbl9bQkVGT1JFX0hUTUxfTU9ERV1bVG9rZW5pemVyLkNIQVJBQ1RFUl9UT0tFTl0gPVxuX1tCRUZPUkVfSFRNTF9NT0RFXVtUb2tlbml6ZXIuTlVMTF9DSEFSQUNURVJfVE9LRU5dID0gdG9rZW5CZWZvcmVIdG1sO1xuX1tCRUZPUkVfSFRNTF9NT0RFXVtUb2tlbml6ZXIuV0hJVEVTUEFDRV9DSEFSQUNURVJfVE9LRU5dID0gaWdub3JlVG9rZW47XG5fW0JFRk9SRV9IVE1MX01PREVdW1Rva2VuaXplci5DT01NRU5UX1RPS0VOXSA9IGFwcGVuZENvbW1lbnQ7XG5fW0JFRk9SRV9IVE1MX01PREVdW1Rva2VuaXplci5ET0NUWVBFX1RPS0VOXSA9IGlnbm9yZVRva2VuO1xuX1tCRUZPUkVfSFRNTF9NT0RFXVtUb2tlbml6ZXIuU1RBUlRfVEFHX1RPS0VOXSA9IHN0YXJ0VGFnQmVmb3JlSHRtbDtcbl9bQkVGT1JFX0hUTUxfTU9ERV1bVG9rZW5pemVyLkVORF9UQUdfVE9LRU5dID0gZW5kVGFnQmVmb3JlSHRtbDtcbl9bQkVGT1JFX0hUTUxfTU9ERV1bVG9rZW5pemVyLkVPRl9UT0tFTl0gPSB0b2tlbkJlZm9yZUh0bWw7XG5cbl9bQkVGT1JFX0hFQURfTU9ERV0gPSB7fTtcbl9bQkVGT1JFX0hFQURfTU9ERV1bVG9rZW5pemVyLkNIQVJBQ1RFUl9UT0tFTl0gPVxuX1tCRUZPUkVfSEVBRF9NT0RFXVtUb2tlbml6ZXIuTlVMTF9DSEFSQUNURVJfVE9LRU5dID0gdG9rZW5CZWZvcmVIZWFkO1xuX1tCRUZPUkVfSEVBRF9NT0RFXVtUb2tlbml6ZXIuV0hJVEVTUEFDRV9DSEFSQUNURVJfVE9LRU5dID0gaWdub3JlVG9rZW47XG5fW0JFRk9SRV9IRUFEX01PREVdW1Rva2VuaXplci5DT01NRU5UX1RPS0VOXSA9IGFwcGVuZENvbW1lbnQ7XG5fW0JFRk9SRV9IRUFEX01PREVdW1Rva2VuaXplci5ET0NUWVBFX1RPS0VOXSA9IGlnbm9yZVRva2VuO1xuX1tCRUZPUkVfSEVBRF9NT0RFXVtUb2tlbml6ZXIuU1RBUlRfVEFHX1RPS0VOXSA9IHN0YXJ0VGFnQmVmb3JlSGVhZDtcbl9bQkVGT1JFX0hFQURfTU9ERV1bVG9rZW5pemVyLkVORF9UQUdfVE9LRU5dID0gZW5kVGFnQmVmb3JlSGVhZDtcbl9bQkVGT1JFX0hFQURfTU9ERV1bVG9rZW5pemVyLkVPRl9UT0tFTl0gPSB0b2tlbkJlZm9yZUhlYWQ7XG5cbl9bSU5fSEVBRF9NT0RFXSA9IHt9O1xuX1tJTl9IRUFEX01PREVdW1Rva2VuaXplci5DSEFSQUNURVJfVE9LRU5dID1cbl9bSU5fSEVBRF9NT0RFXVtUb2tlbml6ZXIuTlVMTF9DSEFSQUNURVJfVE9LRU5dID0gdG9rZW5JbkhlYWQ7XG5fW0lOX0hFQURfTU9ERV1bVG9rZW5pemVyLldISVRFU1BBQ0VfQ0hBUkFDVEVSX1RPS0VOXSA9IGluc2VydENoYXJhY3RlcnM7XG5fW0lOX0hFQURfTU9ERV1bVG9rZW5pemVyLkNPTU1FTlRfVE9LRU5dID0gYXBwZW5kQ29tbWVudDtcbl9bSU5fSEVBRF9NT0RFXVtUb2tlbml6ZXIuRE9DVFlQRV9UT0tFTl0gPSBpZ25vcmVUb2tlbjtcbl9bSU5fSEVBRF9NT0RFXVtUb2tlbml6ZXIuU1RBUlRfVEFHX1RPS0VOXSA9IHN0YXJ0VGFnSW5IZWFkO1xuX1tJTl9IRUFEX01PREVdW1Rva2VuaXplci5FTkRfVEFHX1RPS0VOXSA9IGVuZFRhZ0luSGVhZDtcbl9bSU5fSEVBRF9NT0RFXVtUb2tlbml6ZXIuRU9GX1RPS0VOXSA9IHRva2VuSW5IZWFkO1xuXG5fW0FGVEVSX0hFQURfTU9ERV0gPSB7fTtcbl9bQUZURVJfSEVBRF9NT0RFXVtUb2tlbml6ZXIuQ0hBUkFDVEVSX1RPS0VOXSA9XG5fW0FGVEVSX0hFQURfTU9ERV1bVG9rZW5pemVyLk5VTExfQ0hBUkFDVEVSX1RPS0VOXSA9IHRva2VuQWZ0ZXJIZWFkO1xuX1tBRlRFUl9IRUFEX01PREVdW1Rva2VuaXplci5XSElURVNQQUNFX0NIQVJBQ1RFUl9UT0tFTl0gPSBpbnNlcnRDaGFyYWN0ZXJzO1xuX1tBRlRFUl9IRUFEX01PREVdW1Rva2VuaXplci5DT01NRU5UX1RPS0VOXSA9IGFwcGVuZENvbW1lbnQ7XG5fW0FGVEVSX0hFQURfTU9ERV1bVG9rZW5pemVyLkRPQ1RZUEVfVE9LRU5dID0gaWdub3JlVG9rZW47XG5fW0FGVEVSX0hFQURfTU9ERV1bVG9rZW5pemVyLlNUQVJUX1RBR19UT0tFTl0gPSBzdGFydFRhZ0FmdGVySGVhZDtcbl9bQUZURVJfSEVBRF9NT0RFXVtUb2tlbml6ZXIuRU5EX1RBR19UT0tFTl0gPSBlbmRUYWdBZnRlckhlYWQ7XG5fW0FGVEVSX0hFQURfTU9ERV1bVG9rZW5pemVyLkVPRl9UT0tFTl0gPSB0b2tlbkFmdGVySGVhZDtcblxuX1tJTl9CT0RZX01PREVdID0ge307XG5fW0lOX0JPRFlfTU9ERV1bVG9rZW5pemVyLkNIQVJBQ1RFUl9UT0tFTl0gPSBjaGFyYWN0ZXJJbkJvZHk7XG5fW0lOX0JPRFlfTU9ERV1bVG9rZW5pemVyLk5VTExfQ0hBUkFDVEVSX1RPS0VOXSA9IGlnbm9yZVRva2VuO1xuX1tJTl9CT0RZX01PREVdW1Rva2VuaXplci5XSElURVNQQUNFX0NIQVJBQ1RFUl9UT0tFTl0gPSB3aGl0ZXNwYWNlQ2hhcmFjdGVySW5Cb2R5O1xuX1tJTl9CT0RZX01PREVdW1Rva2VuaXplci5DT01NRU5UX1RPS0VOXSA9IGFwcGVuZENvbW1lbnQ7XG5fW0lOX0JPRFlfTU9ERV1bVG9rZW5pemVyLkRPQ1RZUEVfVE9LRU5dID0gaWdub3JlVG9rZW47XG5fW0lOX0JPRFlfTU9ERV1bVG9rZW5pemVyLlNUQVJUX1RBR19UT0tFTl0gPSBzdGFydFRhZ0luQm9keTtcbl9bSU5fQk9EWV9NT0RFXVtUb2tlbml6ZXIuRU5EX1RBR19UT0tFTl0gPSBlbmRUYWdJbkJvZHk7XG5fW0lOX0JPRFlfTU9ERV1bVG9rZW5pemVyLkVPRl9UT0tFTl0gPSBlb2ZJbkJvZHk7XG5cbl9bVEVYVF9NT0RFXSA9IHt9O1xuX1tURVhUX01PREVdW1Rva2VuaXplci5DSEFSQUNURVJfVE9LRU5dID1cbl9bVEVYVF9NT0RFXVtUb2tlbml6ZXIuTlVMTF9DSEFSQUNURVJfVE9LRU5dID1cbl9bVEVYVF9NT0RFXVtUb2tlbml6ZXIuV0hJVEVTUEFDRV9DSEFSQUNURVJfVE9LRU5dID0gaW5zZXJ0Q2hhcmFjdGVycztcbl9bVEVYVF9NT0RFXVtUb2tlbml6ZXIuQ09NTUVOVF9UT0tFTl0gPVxuX1tURVhUX01PREVdW1Rva2VuaXplci5ET0NUWVBFX1RPS0VOXSA9XG5fW1RFWFRfTU9ERV1bVG9rZW5pemVyLlNUQVJUX1RBR19UT0tFTl0gPSBpZ25vcmVUb2tlbjtcbl9bVEVYVF9NT0RFXVtUb2tlbml6ZXIuRU5EX1RBR19UT0tFTl0gPSBlbmRUYWdJblRleHQ7XG5fW1RFWFRfTU9ERV1bVG9rZW5pemVyLkVPRl9UT0tFTl0gPSBlb2ZJblRleHQ7XG5cbl9bSU5fVEFCTEVfTU9ERV0gPSB7fTtcbl9bSU5fVEFCTEVfTU9ERV1bVG9rZW5pemVyLkNIQVJBQ1RFUl9UT0tFTl0gPVxuX1tJTl9UQUJMRV9NT0RFXVtUb2tlbml6ZXIuTlVMTF9DSEFSQUNURVJfVE9LRU5dID1cbl9bSU5fVEFCTEVfTU9ERV1bVG9rZW5pemVyLldISVRFU1BBQ0VfQ0hBUkFDVEVSX1RPS0VOXSA9IGNoYXJhY3RlckluVGFibGU7XG5fW0lOX1RBQkxFX01PREVdW1Rva2VuaXplci5DT01NRU5UX1RPS0VOXSA9IGFwcGVuZENvbW1lbnQ7XG5fW0lOX1RBQkxFX01PREVdW1Rva2VuaXplci5ET0NUWVBFX1RPS0VOXSA9IGlnbm9yZVRva2VuO1xuX1tJTl9UQUJMRV9NT0RFXVtUb2tlbml6ZXIuU1RBUlRfVEFHX1RPS0VOXSA9IHN0YXJ0VGFnSW5UYWJsZTtcbl9bSU5fVEFCTEVfTU9ERV1bVG9rZW5pemVyLkVORF9UQUdfVE9LRU5dID0gZW5kVGFnSW5UYWJsZTtcbl9bSU5fVEFCTEVfTU9ERV1bVG9rZW5pemVyLkVPRl9UT0tFTl0gPSBlb2ZJbkJvZHk7XG5cbl9bSU5fVEFCTEVfVEVYVF9NT0RFXSA9IHt9O1xuX1tJTl9UQUJMRV9URVhUX01PREVdW1Rva2VuaXplci5DSEFSQUNURVJfVE9LRU5dID0gY2hhcmFjdGVySW5UYWJsZVRleHQ7XG5fW0lOX1RBQkxFX1RFWFRfTU9ERV1bVG9rZW5pemVyLk5VTExfQ0hBUkFDVEVSX1RPS0VOXSA9IGlnbm9yZVRva2VuO1xuX1tJTl9UQUJMRV9URVhUX01PREVdW1Rva2VuaXplci5XSElURVNQQUNFX0NIQVJBQ1RFUl9UT0tFTl0gPSB3aGl0ZXNwYWNlQ2hhcmFjdGVySW5UYWJsZVRleHQ7XG5fW0lOX1RBQkxFX1RFWFRfTU9ERV1bVG9rZW5pemVyLkNPTU1FTlRfVE9LRU5dID1cbl9bSU5fVEFCTEVfVEVYVF9NT0RFXVtUb2tlbml6ZXIuRE9DVFlQRV9UT0tFTl0gPVxuX1tJTl9UQUJMRV9URVhUX01PREVdW1Rva2VuaXplci5TVEFSVF9UQUdfVE9LRU5dID1cbl9bSU5fVEFCTEVfVEVYVF9NT0RFXVtUb2tlbml6ZXIuRU5EX1RBR19UT0tFTl0gPVxuX1tJTl9UQUJMRV9URVhUX01PREVdW1Rva2VuaXplci5FT0ZfVE9LRU5dID0gdG9rZW5JblRhYmxlVGV4dDtcblxuX1tJTl9DQVBUSU9OX01PREVdID0ge307XG5fW0lOX0NBUFRJT05fTU9ERV1bVG9rZW5pemVyLkNIQVJBQ1RFUl9UT0tFTl0gPSBjaGFyYWN0ZXJJbkJvZHk7XG5fW0lOX0NBUFRJT05fTU9ERV1bVG9rZW5pemVyLk5VTExfQ0hBUkFDVEVSX1RPS0VOXSA9IGlnbm9yZVRva2VuO1xuX1tJTl9DQVBUSU9OX01PREVdW1Rva2VuaXplci5XSElURVNQQUNFX0NIQVJBQ1RFUl9UT0tFTl0gPSB3aGl0ZXNwYWNlQ2hhcmFjdGVySW5Cb2R5O1xuX1tJTl9DQVBUSU9OX01PREVdW1Rva2VuaXplci5DT01NRU5UX1RPS0VOXSA9IGFwcGVuZENvbW1lbnQ7XG5fW0lOX0NBUFRJT05fTU9ERV1bVG9rZW5pemVyLkRPQ1RZUEVfVE9LRU5dID0gaWdub3JlVG9rZW47XG5fW0lOX0NBUFRJT05fTU9ERV1bVG9rZW5pemVyLlNUQVJUX1RBR19UT0tFTl0gPSBzdGFydFRhZ0luQ2FwdGlvbjtcbl9bSU5fQ0FQVElPTl9NT0RFXVtUb2tlbml6ZXIuRU5EX1RBR19UT0tFTl0gPSBlbmRUYWdJbkNhcHRpb247XG5fW0lOX0NBUFRJT05fTU9ERV1bVG9rZW5pemVyLkVPRl9UT0tFTl0gPSBlb2ZJbkJvZHk7XG5cbl9bSU5fQ09MVU1OX0dST1VQX01PREVdID0ge307XG5fW0lOX0NPTFVNTl9HUk9VUF9NT0RFXVtUb2tlbml6ZXIuQ0hBUkFDVEVSX1RPS0VOXSA9XG5fW0lOX0NPTFVNTl9HUk9VUF9NT0RFXVtUb2tlbml6ZXIuTlVMTF9DSEFSQUNURVJfVE9LRU5dID0gdG9rZW5JbkNvbHVtbkdyb3VwO1xuX1tJTl9DT0xVTU5fR1JPVVBfTU9ERV1bVG9rZW5pemVyLldISVRFU1BBQ0VfQ0hBUkFDVEVSX1RPS0VOXSA9IGluc2VydENoYXJhY3RlcnM7XG5fW0lOX0NPTFVNTl9HUk9VUF9NT0RFXVtUb2tlbml6ZXIuQ09NTUVOVF9UT0tFTl0gPSBhcHBlbmRDb21tZW50O1xuX1tJTl9DT0xVTU5fR1JPVVBfTU9ERV1bVG9rZW5pemVyLkRPQ1RZUEVfVE9LRU5dID0gaWdub3JlVG9rZW47XG5fW0lOX0NPTFVNTl9HUk9VUF9NT0RFXVtUb2tlbml6ZXIuU1RBUlRfVEFHX1RPS0VOXSA9IHN0YXJ0VGFnSW5Db2x1bW5Hcm91cDtcbl9bSU5fQ09MVU1OX0dST1VQX01PREVdW1Rva2VuaXplci5FTkRfVEFHX1RPS0VOXSA9IGVuZFRhZ0luQ29sdW1uR3JvdXA7XG5fW0lOX0NPTFVNTl9HUk9VUF9NT0RFXVtUb2tlbml6ZXIuRU9GX1RPS0VOXSA9IGVvZkluQm9keTtcblxuX1tJTl9UQUJMRV9CT0RZX01PREVdID0ge307XG5fW0lOX1RBQkxFX0JPRFlfTU9ERV1bVG9rZW5pemVyLkNIQVJBQ1RFUl9UT0tFTl0gPVxuX1tJTl9UQUJMRV9CT0RZX01PREVdW1Rva2VuaXplci5OVUxMX0NIQVJBQ1RFUl9UT0tFTl0gPVxuX1tJTl9UQUJMRV9CT0RZX01PREVdW1Rva2VuaXplci5XSElURVNQQUNFX0NIQVJBQ1RFUl9UT0tFTl0gPSBjaGFyYWN0ZXJJblRhYmxlO1xuX1tJTl9UQUJMRV9CT0RZX01PREVdW1Rva2VuaXplci5DT01NRU5UX1RPS0VOXSA9IGFwcGVuZENvbW1lbnQ7XG5fW0lOX1RBQkxFX0JPRFlfTU9ERV1bVG9rZW5pemVyLkRPQ1RZUEVfVE9LRU5dID0gaWdub3JlVG9rZW47XG5fW0lOX1RBQkxFX0JPRFlfTU9ERV1bVG9rZW5pemVyLlNUQVJUX1RBR19UT0tFTl0gPSBzdGFydFRhZ0luVGFibGVCb2R5O1xuX1tJTl9UQUJMRV9CT0RZX01PREVdW1Rva2VuaXplci5FTkRfVEFHX1RPS0VOXSA9IGVuZFRhZ0luVGFibGVCb2R5O1xuX1tJTl9UQUJMRV9CT0RZX01PREVdW1Rva2VuaXplci5FT0ZfVE9LRU5dID0gZW9mSW5Cb2R5O1xuXG5fW0lOX1JPV19NT0RFXSA9IHt9O1xuX1tJTl9ST1dfTU9ERV1bVG9rZW5pemVyLkNIQVJBQ1RFUl9UT0tFTl0gPVxuX1tJTl9ST1dfTU9ERV1bVG9rZW5pemVyLk5VTExfQ0hBUkFDVEVSX1RPS0VOXSA9XG5fW0lOX1JPV19NT0RFXVtUb2tlbml6ZXIuV0hJVEVTUEFDRV9DSEFSQUNURVJfVE9LRU5dID0gY2hhcmFjdGVySW5UYWJsZTtcbl9bSU5fUk9XX01PREVdW1Rva2VuaXplci5DT01NRU5UX1RPS0VOXSA9IGFwcGVuZENvbW1lbnQ7XG5fW0lOX1JPV19NT0RFXVtUb2tlbml6ZXIuRE9DVFlQRV9UT0tFTl0gPSBpZ25vcmVUb2tlbjtcbl9bSU5fUk9XX01PREVdW1Rva2VuaXplci5TVEFSVF9UQUdfVE9LRU5dID0gc3RhcnRUYWdJblJvdztcbl9bSU5fUk9XX01PREVdW1Rva2VuaXplci5FTkRfVEFHX1RPS0VOXSA9IGVuZFRhZ0luUm93O1xuX1tJTl9ST1dfTU9ERV1bVG9rZW5pemVyLkVPRl9UT0tFTl0gPSBlb2ZJbkJvZHk7XG5cbl9bSU5fQ0VMTF9NT0RFXSA9IHt9O1xuX1tJTl9DRUxMX01PREVdW1Rva2VuaXplci5DSEFSQUNURVJfVE9LRU5dID0gY2hhcmFjdGVySW5Cb2R5O1xuX1tJTl9DRUxMX01PREVdW1Rva2VuaXplci5OVUxMX0NIQVJBQ1RFUl9UT0tFTl0gPSBpZ25vcmVUb2tlbjtcbl9bSU5fQ0VMTF9NT0RFXVtUb2tlbml6ZXIuV0hJVEVTUEFDRV9DSEFSQUNURVJfVE9LRU5dID0gd2hpdGVzcGFjZUNoYXJhY3RlckluQm9keTtcbl9bSU5fQ0VMTF9NT0RFXVtUb2tlbml6ZXIuQ09NTUVOVF9UT0tFTl0gPSBhcHBlbmRDb21tZW50O1xuX1tJTl9DRUxMX01PREVdW1Rva2VuaXplci5ET0NUWVBFX1RPS0VOXSA9IGlnbm9yZVRva2VuO1xuX1tJTl9DRUxMX01PREVdW1Rva2VuaXplci5TVEFSVF9UQUdfVE9LRU5dID0gc3RhcnRUYWdJbkNlbGw7XG5fW0lOX0NFTExfTU9ERV1bVG9rZW5pemVyLkVORF9UQUdfVE9LRU5dID0gZW5kVGFnSW5DZWxsO1xuX1tJTl9DRUxMX01PREVdW1Rva2VuaXplci5FT0ZfVE9LRU5dID0gZW9mSW5Cb2R5O1xuXG5fW0lOX1NFTEVDVF9NT0RFXSA9IHt9O1xuX1tJTl9TRUxFQ1RfTU9ERV1bVG9rZW5pemVyLkNIQVJBQ1RFUl9UT0tFTl0gPSBpbnNlcnRDaGFyYWN0ZXJzO1xuX1tJTl9TRUxFQ1RfTU9ERV1bVG9rZW5pemVyLk5VTExfQ0hBUkFDVEVSX1RPS0VOXSA9IGlnbm9yZVRva2VuO1xuX1tJTl9TRUxFQ1RfTU9ERV1bVG9rZW5pemVyLldISVRFU1BBQ0VfQ0hBUkFDVEVSX1RPS0VOXSA9IGluc2VydENoYXJhY3RlcnM7XG5fW0lOX1NFTEVDVF9NT0RFXVtUb2tlbml6ZXIuQ09NTUVOVF9UT0tFTl0gPSBhcHBlbmRDb21tZW50O1xuX1tJTl9TRUxFQ1RfTU9ERV1bVG9rZW5pemVyLkRPQ1RZUEVfVE9LRU5dID0gaWdub3JlVG9rZW47XG5fW0lOX1NFTEVDVF9NT0RFXVtUb2tlbml6ZXIuU1RBUlRfVEFHX1RPS0VOXSA9IHN0YXJ0VGFnSW5TZWxlY3Q7XG5fW0lOX1NFTEVDVF9NT0RFXVtUb2tlbml6ZXIuRU5EX1RBR19UT0tFTl0gPSBlbmRUYWdJblNlbGVjdDtcbl9bSU5fU0VMRUNUX01PREVdW1Rva2VuaXplci5FT0ZfVE9LRU5dID0gZW9mSW5Cb2R5O1xuXG5fW0lOX1NFTEVDVF9JTl9UQUJMRV9NT0RFXSA9IHt9O1xuX1tJTl9TRUxFQ1RfSU5fVEFCTEVfTU9ERV1bVG9rZW5pemVyLkNIQVJBQ1RFUl9UT0tFTl0gPSBpbnNlcnRDaGFyYWN0ZXJzO1xuX1tJTl9TRUxFQ1RfSU5fVEFCTEVfTU9ERV1bVG9rZW5pemVyLk5VTExfQ0hBUkFDVEVSX1RPS0VOXSA9IGlnbm9yZVRva2VuO1xuX1tJTl9TRUxFQ1RfSU5fVEFCTEVfTU9ERV1bVG9rZW5pemVyLldISVRFU1BBQ0VfQ0hBUkFDVEVSX1RPS0VOXSA9IGluc2VydENoYXJhY3RlcnM7XG5fW0lOX1NFTEVDVF9JTl9UQUJMRV9NT0RFXVtUb2tlbml6ZXIuQ09NTUVOVF9UT0tFTl0gPSBhcHBlbmRDb21tZW50O1xuX1tJTl9TRUxFQ1RfSU5fVEFCTEVfTU9ERV1bVG9rZW5pemVyLkRPQ1RZUEVfVE9LRU5dID0gaWdub3JlVG9rZW47XG5fW0lOX1NFTEVDVF9JTl9UQUJMRV9NT0RFXVtUb2tlbml6ZXIuU1RBUlRfVEFHX1RPS0VOXSA9IHN0YXJ0VGFnSW5TZWxlY3RJblRhYmxlO1xuX1tJTl9TRUxFQ1RfSU5fVEFCTEVfTU9ERV1bVG9rZW5pemVyLkVORF9UQUdfVE9LRU5dID0gZW5kVGFnSW5TZWxlY3RJblRhYmxlO1xuX1tJTl9TRUxFQ1RfSU5fVEFCTEVfTU9ERV1bVG9rZW5pemVyLkVPRl9UT0tFTl0gPSBlb2ZJbkJvZHk7XG5cbl9bSU5fVEVNUExBVEVfTU9ERV0gPSB7fTtcbl9bSU5fVEVNUExBVEVfTU9ERV1bVG9rZW5pemVyLkNIQVJBQ1RFUl9UT0tFTl0gPSBjaGFyYWN0ZXJJbkJvZHk7XG5fW0lOX1RFTVBMQVRFX01PREVdW1Rva2VuaXplci5OVUxMX0NIQVJBQ1RFUl9UT0tFTl0gPSBpZ25vcmVUb2tlbjtcbl9bSU5fVEVNUExBVEVfTU9ERV1bVG9rZW5pemVyLldISVRFU1BBQ0VfQ0hBUkFDVEVSX1RPS0VOXSA9IHdoaXRlc3BhY2VDaGFyYWN0ZXJJbkJvZHk7XG5fW0lOX1RFTVBMQVRFX01PREVdW1Rva2VuaXplci5DT01NRU5UX1RPS0VOXSA9IGFwcGVuZENvbW1lbnQ7XG5fW0lOX1RFTVBMQVRFX01PREVdW1Rva2VuaXplci5ET0NUWVBFX1RPS0VOXSA9IGlnbm9yZVRva2VuO1xuX1tJTl9URU1QTEFURV9NT0RFXVtUb2tlbml6ZXIuU1RBUlRfVEFHX1RPS0VOXSA9IHN0YXJ0VGFnSW5UZW1wbGF0ZTtcbl9bSU5fVEVNUExBVEVfTU9ERV1bVG9rZW5pemVyLkVORF9UQUdfVE9LRU5dID0gZW5kVGFnSW5UZW1wbGF0ZTtcbl9bSU5fVEVNUExBVEVfTU9ERV1bVG9rZW5pemVyLkVPRl9UT0tFTl0gPSBlb2ZJblRlbXBsYXRlO1xuXG5fW0FGVEVSX0JPRFlfTU9ERV0gPSB7fTtcbl9bQUZURVJfQk9EWV9NT0RFXVtUb2tlbml6ZXIuQ0hBUkFDVEVSX1RPS0VOXSA9XG5fW0FGVEVSX0JPRFlfTU9ERV1bVG9rZW5pemVyLk5VTExfQ0hBUkFDVEVSX1RPS0VOXSA9IHRva2VuQWZ0ZXJCb2R5O1xuX1tBRlRFUl9CT0RZX01PREVdW1Rva2VuaXplci5XSElURVNQQUNFX0NIQVJBQ1RFUl9UT0tFTl0gPSB3aGl0ZXNwYWNlQ2hhcmFjdGVySW5Cb2R5O1xuX1tBRlRFUl9CT0RZX01PREVdW1Rva2VuaXplci5DT01NRU5UX1RPS0VOXSA9IGFwcGVuZENvbW1lbnRUb1Jvb3RIdG1sRWxlbWVudDtcbl9bQUZURVJfQk9EWV9NT0RFXVtUb2tlbml6ZXIuRE9DVFlQRV9UT0tFTl0gPSBpZ25vcmVUb2tlbjtcbl9bQUZURVJfQk9EWV9NT0RFXVtUb2tlbml6ZXIuU1RBUlRfVEFHX1RPS0VOXSA9IHN0YXJ0VGFnQWZ0ZXJCb2R5O1xuX1tBRlRFUl9CT0RZX01PREVdW1Rva2VuaXplci5FTkRfVEFHX1RPS0VOXSA9IGVuZFRhZ0FmdGVyQm9keTtcbl9bQUZURVJfQk9EWV9NT0RFXVtUb2tlbml6ZXIuRU9GX1RPS0VOXSA9IHN0b3BQYXJzaW5nO1xuXG5fW0lOX0ZSQU1FU0VUX01PREVdID0ge307XG5fW0lOX0ZSQU1FU0VUX01PREVdW1Rva2VuaXplci5DSEFSQUNURVJfVE9LRU5dID1cbl9bSU5fRlJBTUVTRVRfTU9ERV1bVG9rZW5pemVyLk5VTExfQ0hBUkFDVEVSX1RPS0VOXSA9IGlnbm9yZVRva2VuO1xuX1tJTl9GUkFNRVNFVF9NT0RFXVtUb2tlbml6ZXIuV0hJVEVTUEFDRV9DSEFSQUNURVJfVE9LRU5dID0gaW5zZXJ0Q2hhcmFjdGVycztcbl9bSU5fRlJBTUVTRVRfTU9ERV1bVG9rZW5pemVyLkNPTU1FTlRfVE9LRU5dID0gYXBwZW5kQ29tbWVudDtcbl9bSU5fRlJBTUVTRVRfTU9ERV1bVG9rZW5pemVyLkRPQ1RZUEVfVE9LRU5dID0gaWdub3JlVG9rZW47XG5fW0lOX0ZSQU1FU0VUX01PREVdW1Rva2VuaXplci5TVEFSVF9UQUdfVE9LRU5dID0gc3RhcnRUYWdJbkZyYW1lc2V0O1xuX1tJTl9GUkFNRVNFVF9NT0RFXVtUb2tlbml6ZXIuRU5EX1RBR19UT0tFTl0gPSBlbmRUYWdJbkZyYW1lc2V0O1xuX1tJTl9GUkFNRVNFVF9NT0RFXVtUb2tlbml6ZXIuRU9GX1RPS0VOXSA9IHN0b3BQYXJzaW5nO1xuXG5fW0FGVEVSX0ZSQU1FU0VUX01PREVdID0ge307XG5fW0FGVEVSX0ZSQU1FU0VUX01PREVdW1Rva2VuaXplci5DSEFSQUNURVJfVE9LRU5dID1cbl9bQUZURVJfRlJBTUVTRVRfTU9ERV1bVG9rZW5pemVyLk5VTExfQ0hBUkFDVEVSX1RPS0VOXSA9IGlnbm9yZVRva2VuO1xuX1tBRlRFUl9GUkFNRVNFVF9NT0RFXVtUb2tlbml6ZXIuV0hJVEVTUEFDRV9DSEFSQUNURVJfVE9LRU5dID0gaW5zZXJ0Q2hhcmFjdGVycztcbl9bQUZURVJfRlJBTUVTRVRfTU9ERV1bVG9rZW5pemVyLkNPTU1FTlRfVE9LRU5dID0gYXBwZW5kQ29tbWVudDtcbl9bQUZURVJfRlJBTUVTRVRfTU9ERV1bVG9rZW5pemVyLkRPQ1RZUEVfVE9LRU5dID0gaWdub3JlVG9rZW47XG5fW0FGVEVSX0ZSQU1FU0VUX01PREVdW1Rva2VuaXplci5TVEFSVF9UQUdfVE9LRU5dID0gc3RhcnRUYWdBZnRlckZyYW1lc2V0O1xuX1tBRlRFUl9GUkFNRVNFVF9NT0RFXVtUb2tlbml6ZXIuRU5EX1RBR19UT0tFTl0gPSBlbmRUYWdBZnRlckZyYW1lc2V0O1xuX1tBRlRFUl9GUkFNRVNFVF9NT0RFXVtUb2tlbml6ZXIuRU9GX1RPS0VOXSA9IHN0b3BQYXJzaW5nO1xuXG5fW0FGVEVSX0FGVEVSX0JPRFlfTU9ERV0gPSB7fTtcbl9bQUZURVJfQUZURVJfQk9EWV9NT0RFXVtUb2tlbml6ZXIuQ0hBUkFDVEVSX1RPS0VOXSA9IHRva2VuQWZ0ZXJBZnRlckJvZHk7XG5fW0FGVEVSX0FGVEVSX0JPRFlfTU9ERV1bVG9rZW5pemVyLk5VTExfQ0hBUkFDVEVSX1RPS0VOXSA9IHRva2VuQWZ0ZXJBZnRlckJvZHk7XG5fW0FGVEVSX0FGVEVSX0JPRFlfTU9ERV1bVG9rZW5pemVyLldISVRFU1BBQ0VfQ0hBUkFDVEVSX1RPS0VOXSA9IHdoaXRlc3BhY2VDaGFyYWN0ZXJJbkJvZHk7XG5fW0FGVEVSX0FGVEVSX0JPRFlfTU9ERV1bVG9rZW5pemVyLkNPTU1FTlRfVE9LRU5dID0gYXBwZW5kQ29tbWVudFRvRG9jdW1lbnQ7XG5fW0FGVEVSX0FGVEVSX0JPRFlfTU9ERV1bVG9rZW5pemVyLkRPQ1RZUEVfVE9LRU5dID0gaWdub3JlVG9rZW47XG5fW0FGVEVSX0FGVEVSX0JPRFlfTU9ERV1bVG9rZW5pemVyLlNUQVJUX1RBR19UT0tFTl0gPSBzdGFydFRhZ0FmdGVyQWZ0ZXJCb2R5O1xuX1tBRlRFUl9BRlRFUl9CT0RZX01PREVdW1Rva2VuaXplci5FTkRfVEFHX1RPS0VOXSA9IHRva2VuQWZ0ZXJBZnRlckJvZHk7XG5fW0FGVEVSX0FGVEVSX0JPRFlfTU9ERV1bVG9rZW5pemVyLkVPRl9UT0tFTl0gPSBzdG9wUGFyc2luZztcblxuX1tBRlRFUl9BRlRFUl9GUkFNRVNFVF9NT0RFXSA9IHt9O1xuX1tBRlRFUl9BRlRFUl9GUkFNRVNFVF9NT0RFXVtUb2tlbml6ZXIuQ0hBUkFDVEVSX1RPS0VOXSA9XG5fW0FGVEVSX0FGVEVSX0ZSQU1FU0VUX01PREVdW1Rva2VuaXplci5OVUxMX0NIQVJBQ1RFUl9UT0tFTl0gPSBpZ25vcmVUb2tlbjtcbl9bQUZURVJfQUZURVJfRlJBTUVTRVRfTU9ERV1bVG9rZW5pemVyLldISVRFU1BBQ0VfQ0hBUkFDVEVSX1RPS0VOXSA9IHdoaXRlc3BhY2VDaGFyYWN0ZXJJbkJvZHk7XG5fW0FGVEVSX0FGVEVSX0ZSQU1FU0VUX01PREVdW1Rva2VuaXplci5DT01NRU5UX1RPS0VOXSA9IGFwcGVuZENvbW1lbnRUb0RvY3VtZW50O1xuX1tBRlRFUl9BRlRFUl9GUkFNRVNFVF9NT0RFXVtUb2tlbml6ZXIuRE9DVFlQRV9UT0tFTl0gPSBpZ25vcmVUb2tlbjtcbl9bQUZURVJfQUZURVJfRlJBTUVTRVRfTU9ERV1bVG9rZW5pemVyLlNUQVJUX1RBR19UT0tFTl0gPSBzdGFydFRhZ0FmdGVyQWZ0ZXJGcmFtZXNldDtcbl9bQUZURVJfQUZURVJfRlJBTUVTRVRfTU9ERV1bVG9rZW5pemVyLkVORF9UQUdfVE9LRU5dID0gaWdub3JlVG9rZW47XG5fW0FGVEVSX0FGVEVSX0ZSQU1FU0VUX01PREVdW1Rva2VuaXplci5FT0ZfVE9LRU5dID0gc3RvcFBhcnNpbmc7XG5cbi8vU2VhcmNoYWJsZSBpbmRleCBidWlsZGluZyB1dGlscyAoPGlzaW5kZXg+IHRhZylcbmZ1bmN0aW9uIGdldFNlYXJjaGFibGVJbmRleEZvcm1BdHRycyhpc2luZGV4U3RhcnRUYWdUb2tlbikge1xuICAgIHZhciBpbmRleEFjdGlvbiA9IFRva2VuaXplci5nZXRUb2tlbkF0dHIoaXNpbmRleFN0YXJ0VGFnVG9rZW4sIEFUVFJTLkFDVElPTiksXG4gICAgICAgIGF0dHJzID0gW107XG5cbiAgICBpZiAoaW5kZXhBY3Rpb24gIT09IG51bGwpIHtcbiAgICAgICAgYXR0cnMucHVzaCh7XG4gICAgICAgICAgICBuYW1lOiBBVFRSUy5BQ1RJT04sXG4gICAgICAgICAgICB2YWx1ZTogaW5kZXhBY3Rpb25cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF0dHJzO1xufVxuXG5mdW5jdGlvbiBnZXRTZWFyY2hhYmxlSW5kZXhMYWJlbFRleHQoaXNpbmRleFN0YXJ0VGFnVG9rZW4pIHtcbiAgICB2YXIgaW5kZXhQcm9tcHQgPSBUb2tlbml6ZXIuZ2V0VG9rZW5BdHRyKGlzaW5kZXhTdGFydFRhZ1Rva2VuLCBBVFRSUy5QUk9NUFQpO1xuXG4gICAgcmV0dXJuIGluZGV4UHJvbXB0ID09PSBudWxsID8gU0VBUkNIQUJMRV9JTkRFWF9ERUZBVUxUX1BST01QVCA6IGluZGV4UHJvbXB0O1xufVxuXG5mdW5jdGlvbiBnZXRTZWFyY2hhYmxlSW5kZXhJbnB1dEF0dHJzKGlzaW5kZXhTdGFydFRhZ1Rva2VuKSB7XG4gICAgdmFyIGlzaW5kZXhBdHRycyA9IGlzaW5kZXhTdGFydFRhZ1Rva2VuLmF0dHJzLFxuICAgICAgICBpbnB1dEF0dHJzID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGlzaW5kZXhBdHRycy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgbmFtZSA9IGlzaW5kZXhBdHRyc1tpXS5uYW1lO1xuXG4gICAgICAgIGlmIChuYW1lICE9PSBBVFRSUy5OQU1FICYmIG5hbWUgIT09IEFUVFJTLkFDVElPTiAmJiBuYW1lICE9PSBBVFRSUy5QUk9NUFQpXG4gICAgICAgICAgICBpbnB1dEF0dHJzLnB1c2goaXNpbmRleEF0dHJzW2ldKTtcbiAgICB9XG5cbiAgICBpbnB1dEF0dHJzLnB1c2goe1xuICAgICAgICBuYW1lOiBBVFRSUy5OQU1FLFxuICAgICAgICB2YWx1ZTogU0VBUkNIQUJMRV9JTkRFWF9JTlBVVF9OQU1FXG4gICAgfSk7XG5cbiAgICByZXR1cm4gaW5wdXRBdHRycztcbn1cblxuLy9QYXJzZXJcbnZhciBQYXJzZXIgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0cmVlQWRhcHRlciwgb3B0aW9ucykge1xuICAgIHRoaXMudHJlZUFkYXB0ZXIgPSB0cmVlQWRhcHRlciB8fCBEZWZhdWx0VHJlZUFkYXB0ZXI7XG4gICAgdGhpcy5vcHRpb25zID0gVXRpbHMubWVyZ2VPcHRpb25zKERFRkFVTFRfT1BUSU9OUywgb3B0aW9ucyk7XG4gICAgdGhpcy5zY3JpcHRIYW5kbGVyID0gbnVsbDtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMubG9jYXRpb25JbmZvKVxuICAgICAgICBMb2NhdGlvbkluZm9NaXhpbi5hc3NpZ24odGhpcyk7XG59O1xuXG4vL0FQSVxuUGFyc2VyLnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uIChodG1sKSB7XG4gICAgdmFyIGRvY3VtZW50ID0gdGhpcy50cmVlQWRhcHRlci5jcmVhdGVEb2N1bWVudCgpO1xuXG4gICAgdGhpcy5fcmVzZXQoaHRtbCwgZG9jdW1lbnQsIG51bGwpO1xuICAgIHRoaXMuX3J1blBhcnNpbmdMb29wKCk7XG5cbiAgICByZXR1cm4gZG9jdW1lbnQ7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLnBhcnNlRnJhZ21lbnQgPSBmdW5jdGlvbiAoaHRtbCwgZnJhZ21lbnRDb250ZXh0KSB7XG4gICAgLy9OT1RFOiB1c2UgPHRlbXBsYXRlPiBlbGVtZW50IGFzIGEgZnJhZ21lbnQgY29udGV4dCBpZiBjb250ZXh0IGVsZW1lbnQgd2FzIG5vdCBwcm92aWRlZCxcbiAgICAvL3NvIHdlIHdpbGwgcGFyc2UgaW4gXCJmb3JnaXZpbmdcIiBtYW5uZXJcbiAgICBpZiAoIWZyYWdtZW50Q29udGV4dClcbiAgICAgICAgZnJhZ21lbnRDb250ZXh0ID0gdGhpcy50cmVlQWRhcHRlci5jcmVhdGVFbGVtZW50KCQuVEVNUExBVEUsIE5TLkhUTUwsIFtdKTtcblxuICAgIC8vTk9URTogY3JlYXRlIGZha2UgZWxlbWVudCB3aGljaCB3aWxsIGJlIHVzZWQgYXMgJ2RvY3VtZW50JyBmb3IgZnJhZ21lbnQgcGFyc2luZy5cbiAgICAvL1RoaXMgaXMgaW1wb3J0YW50IGZvciBqc2RvbSB0aGVyZSAnZG9jdW1lbnQnIGNhbid0IGJlIHJlY3JlYXRlZCwgdGhlcmVmb3JlXG4gICAgLy9mcmFnbWVudCBwYXJzaW5nIGNhdXNlcyBtZXNzaW5nIG9mIHRoZSBtYWluIGBkb2N1bWVudGAuXG4gICAgdmFyIGRvY3VtZW50TW9jayA9IHRoaXMudHJlZUFkYXB0ZXIuY3JlYXRlRWxlbWVudCgnZG9jdW1lbnRtb2NrJywgTlMuSFRNTCwgW10pO1xuXG4gICAgdGhpcy5fcmVzZXQoaHRtbCwgZG9jdW1lbnRNb2NrLCBmcmFnbWVudENvbnRleHQpO1xuXG4gICAgaWYgKHRoaXMudHJlZUFkYXB0ZXIuZ2V0VGFnTmFtZShmcmFnbWVudENvbnRleHQpID09PSAkLlRFTVBMQVRFKVxuICAgICAgICB0aGlzLl9wdXNoVG1wbEluc2VydGlvbk1vZGUoSU5fVEVNUExBVEVfTU9ERSk7XG5cbiAgICB0aGlzLl9pbml0VG9rZW5pemVyRm9yRnJhZ21lbnRQYXJzaW5nKCk7XG4gICAgdGhpcy5faW5zZXJ0RmFrZVJvb3RFbGVtZW50KCk7XG4gICAgdGhpcy5fcmVzZXRJbnNlcnRpb25Nb2RlKCk7XG4gICAgdGhpcy5fZmluZEZvcm1JbkZyYWdtZW50Q29udGV4dCgpO1xuICAgIHRoaXMuX3J1blBhcnNpbmdMb29wKCk7XG5cbiAgICB2YXIgcm9vdEVsZW1lbnQgPSB0aGlzLnRyZWVBZGFwdGVyLmdldEZpcnN0Q2hpbGQoZG9jdW1lbnRNb2NrKSxcbiAgICAgICAgZnJhZ21lbnQgPSB0aGlzLnRyZWVBZGFwdGVyLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcblxuICAgIHRoaXMuX2Fkb3B0Tm9kZXMocm9vdEVsZW1lbnQsIGZyYWdtZW50KTtcblxuICAgIHJldHVybiBmcmFnbWVudDtcbn07XG5cbi8vUmVzZXQgc3RhdGVcblBhcnNlci5wcm90b3R5cGUuX3Jlc2V0ID0gZnVuY3Rpb24gKGh0bWwsIGRvY3VtZW50LCBmcmFnbWVudENvbnRleHQpIHtcbiAgICB0aGlzLnRva2VuaXplciA9IG5ldyBUb2tlbml6ZXIoaHRtbCwgdGhpcy5vcHRpb25zKTtcblxuICAgIHRoaXMuc3RvcHBlZCA9IGZhbHNlO1xuXG4gICAgdGhpcy5pbnNlcnRpb25Nb2RlID0gSU5JVElBTF9NT0RFO1xuICAgIHRoaXMub3JpZ2luYWxJbnNlcnRpb25Nb2RlID0gJyc7XG5cbiAgICB0aGlzLmRvY3VtZW50ID0gZG9jdW1lbnQ7XG4gICAgdGhpcy5mcmFnbWVudENvbnRleHQgPSBmcmFnbWVudENvbnRleHQ7XG5cbiAgICB0aGlzLmhlYWRFbGVtZW50ID0gbnVsbDtcbiAgICB0aGlzLmZvcm1FbGVtZW50ID0gbnVsbDtcblxuICAgIHRoaXMub3BlbkVsZW1lbnRzID0gbmV3IE9wZW5FbGVtZW50U3RhY2sodGhpcy5kb2N1bWVudCwgdGhpcy50cmVlQWRhcHRlcik7XG4gICAgdGhpcy5hY3RpdmVGb3JtYXR0aW5nRWxlbWVudHMgPSBuZXcgRm9ybWF0dGluZ0VsZW1lbnRMaXN0KHRoaXMudHJlZUFkYXB0ZXIpO1xuXG4gICAgdGhpcy50bXBsSW5zZXJ0aW9uTW9kZVN0YWNrID0gW107XG4gICAgdGhpcy50bXBsSW5zZXJ0aW9uTW9kZVN0YWNrVG9wID0gLTE7XG4gICAgdGhpcy5jdXJyZW50VG1wbEluc2VydGlvbk1vZGUgPSBudWxsO1xuXG4gICAgdGhpcy5wZW5kaW5nQ2hhcmFjdGVyVG9rZW5zID0gW107XG4gICAgdGhpcy5oYXNOb25XaGl0ZXNwYWNlUGVuZGluZ0NoYXJhY3RlclRva2VuID0gZmFsc2U7XG5cbiAgICB0aGlzLmZyYW1lc2V0T2sgPSB0cnVlO1xuICAgIHRoaXMuc2tpcE5leHROZXdMaW5lID0gZmFsc2U7XG4gICAgdGhpcy5mb3N0ZXJQYXJlbnRpbmdFbmFibGVkID0gZmFsc2U7XG59O1xuXG4vL1BhcnNpbmcgbG9vcFxuUGFyc2VyLnByb3RvdHlwZS5faXRlcmF0ZVBhcnNpbmdMb29wID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuX3NldHVwVG9rZW5pemVyQ0RBVEFNb2RlKCk7XG5cbiAgICB2YXIgdG9rZW4gPSB0aGlzLnRva2VuaXplci5nZXROZXh0VG9rZW4oKTtcblxuICAgIGlmICh0aGlzLnNraXBOZXh0TmV3TGluZSkge1xuICAgICAgICB0aGlzLnNraXBOZXh0TmV3TGluZSA9IGZhbHNlO1xuXG4gICAgICAgIGlmICh0b2tlbi50eXBlID09PSBUb2tlbml6ZXIuV0hJVEVTUEFDRV9DSEFSQUNURVJfVE9LRU4gJiYgdG9rZW4uY2hhcnNbMF0gPT09ICdcXG4nKSB7XG4gICAgICAgICAgICBpZiAodG9rZW4uY2hhcnMubGVuZ3RoID09PSAxKVxuICAgICAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICAgICAgdG9rZW4uY2hhcnMgPSB0b2tlbi5jaGFycy5zdWJzdHIoMSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5fc2hvdWxkUHJvY2Vzc1Rva2VuSW5Gb3JlaWduQ29udGVudCh0b2tlbikpXG4gICAgICAgIHRoaXMuX3Byb2Nlc3NUb2tlbkluRm9yZWlnbkNvbnRlbnQodG9rZW4pO1xuXG4gICAgZWxzZVxuICAgICAgICB0aGlzLl9wcm9jZXNzVG9rZW4odG9rZW4pO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5fcnVuUGFyc2luZ0xvb3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgd2hpbGUgKCF0aGlzLnN0b3BwZWQpXG4gICAgICAgIHRoaXMuX2l0ZXJhdGVQYXJzaW5nTG9vcCgpO1xufTtcblxuLy9UZXh0IHBhcnNpbmdcblBhcnNlci5wcm90b3R5cGUuX3NldHVwVG9rZW5pemVyQ0RBVEFNb2RlID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBjdXJyZW50ID0gdGhpcy5fZ2V0QWRqdXN0ZWRDdXJyZW50RWxlbWVudCgpO1xuXG4gICAgdGhpcy50b2tlbml6ZXIuYWxsb3dDREFUQSA9IGN1cnJlbnQgJiYgY3VycmVudCAhPT0gdGhpcy5kb2N1bWVudCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyZWVBZGFwdGVyLmdldE5hbWVzcGFjZVVSSShjdXJyZW50KSAhPT0gTlMuSFRNTCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoIXRoaXMuX2lzSHRtbEludGVncmF0aW9uUG9pbnQoY3VycmVudCkpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICghdGhpcy5faXNNYXRoTUxUZXh0SW50ZWdyYXRpb25Qb2ludChjdXJyZW50KSk7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLl9zd2l0Y2hUb1RleHRQYXJzaW5nID0gZnVuY3Rpb24gKGN1cnJlbnRUb2tlbiwgbmV4dFRva2VuaXplclN0YXRlKSB7XG4gICAgdGhpcy5faW5zZXJ0RWxlbWVudChjdXJyZW50VG9rZW4sIE5TLkhUTUwpO1xuICAgIHRoaXMudG9rZW5pemVyLnN0YXRlID0gbmV4dFRva2VuaXplclN0YXRlO1xuICAgIHRoaXMub3JpZ2luYWxJbnNlcnRpb25Nb2RlID0gdGhpcy5pbnNlcnRpb25Nb2RlO1xuICAgIHRoaXMuaW5zZXJ0aW9uTW9kZSA9IFRFWFRfTU9ERTtcbn07XG5cbi8vRnJhZ21lbnQgcGFyc2luZ1xuUGFyc2VyLnByb3RvdHlwZS5fZ2V0QWRqdXN0ZWRDdXJyZW50RWxlbWVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5vcGVuRWxlbWVudHMuc3RhY2tUb3AgPT09IDAgJiYgdGhpcy5mcmFnbWVudENvbnRleHQgP1xuICAgICAgICAgICB0aGlzLmZyYWdtZW50Q29udGV4dCA6XG4gICAgICAgICAgIHRoaXMub3BlbkVsZW1lbnRzLmN1cnJlbnQ7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLl9maW5kRm9ybUluRnJhZ21lbnRDb250ZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBub2RlID0gdGhpcy5mcmFnbWVudENvbnRleHQ7XG5cbiAgICBkbyB7XG4gICAgICAgIGlmICh0aGlzLnRyZWVBZGFwdGVyLmdldFRhZ05hbWUobm9kZSkgPT09ICQuRk9STSkge1xuICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudCA9IG5vZGU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIG5vZGUgPSB0aGlzLnRyZWVBZGFwdGVyLmdldFBhcmVudE5vZGUobm9kZSk7XG4gICAgfSB3aGlsZSAobm9kZSk7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLl9pbml0VG9rZW5pemVyRm9yRnJhZ21lbnRQYXJzaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB0biA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0VGFnTmFtZSh0aGlzLmZyYWdtZW50Q29udGV4dCk7XG5cbiAgICBpZiAodG4gPT09ICQuVElUTEUgfHwgdG4gPT09ICQuVEVYVEFSRUEpXG4gICAgICAgIHRoaXMudG9rZW5pemVyLnN0YXRlID0gVG9rZW5pemVyLk1PREUuUkNEQVRBO1xuXG4gICAgZWxzZSBpZiAodG4gPT09ICQuU1RZTEUgfHwgdG4gPT09ICQuWE1QIHx8IHRuID09PSAkLklGUkFNRSB8fFxuICAgICAgICAgICAgIHRuID09PSAkLk5PRU1CRUQgfHwgdG4gPT09ICQuTk9GUkFNRVMgfHwgdG4gPT09ICQuTk9TQ1JJUFQpIHtcbiAgICAgICAgdGhpcy50b2tlbml6ZXIuc3RhdGUgPSBUb2tlbml6ZXIuTU9ERS5SQVdURVhUO1xuICAgIH1cblxuICAgIGVsc2UgaWYgKHRuID09PSAkLlNDUklQVClcbiAgICAgICAgdGhpcy50b2tlbml6ZXIuc3RhdGUgPSBUb2tlbml6ZXIuTU9ERS5TQ1JJUFRfREFUQTtcblxuICAgIGVsc2UgaWYgKHRuID09PSAkLlBMQUlOVEVYVClcbiAgICAgICAgdGhpcy50b2tlbml6ZXIuc3RhdGUgPSBUb2tlbml6ZXIuTU9ERS5QTEFJTlRFWFQ7XG59O1xuXG4vL1RyZWUgbXV0YXRpb25cblBhcnNlci5wcm90b3R5cGUuX3NldERvY3VtZW50VHlwZSA9IGZ1bmN0aW9uICh0b2tlbikge1xuICAgIHRoaXMudHJlZUFkYXB0ZXIuc2V0RG9jdW1lbnRUeXBlKHRoaXMuZG9jdW1lbnQsIHRva2VuLm5hbWUsIHRva2VuLnB1YmxpY0lkLCB0b2tlbi5zeXN0ZW1JZCk7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLl9hdHRhY2hFbGVtZW50VG9UcmVlID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICBpZiAodGhpcy5fc2hvdWxkRm9zdGVyUGFyZW50T25JbnNlcnRpb24oKSlcbiAgICAgICAgdGhpcy5fZm9zdGVyUGFyZW50RWxlbWVudChlbGVtZW50KTtcblxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgcGFyZW50ID0gdGhpcy5vcGVuRWxlbWVudHMuY3VycmVudFRtcGxDb250ZW50IHx8IHRoaXMub3BlbkVsZW1lbnRzLmN1cnJlbnQ7XG5cbiAgICAgICAgdGhpcy50cmVlQWRhcHRlci5hcHBlbmRDaGlsZChwYXJlbnQsIGVsZW1lbnQpO1xuICAgIH1cbn07XG5cblBhcnNlci5wcm90b3R5cGUuX2FwcGVuZEVsZW1lbnQgPSBmdW5jdGlvbiAodG9rZW4sIG5hbWVzcGFjZVVSSSkge1xuICAgIHZhciBlbGVtZW50ID0gdGhpcy50cmVlQWRhcHRlci5jcmVhdGVFbGVtZW50KHRva2VuLnRhZ05hbWUsIG5hbWVzcGFjZVVSSSwgdG9rZW4uYXR0cnMpO1xuXG4gICAgdGhpcy5fYXR0YWNoRWxlbWVudFRvVHJlZShlbGVtZW50KTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUuX2luc2VydEVsZW1lbnQgPSBmdW5jdGlvbiAodG9rZW4sIG5hbWVzcGFjZVVSSSkge1xuICAgIHZhciBlbGVtZW50ID0gdGhpcy50cmVlQWRhcHRlci5jcmVhdGVFbGVtZW50KHRva2VuLnRhZ05hbWUsIG5hbWVzcGFjZVVSSSwgdG9rZW4uYXR0cnMpO1xuXG4gICAgdGhpcy5fYXR0YWNoRWxlbWVudFRvVHJlZShlbGVtZW50KTtcbiAgICB0aGlzLm9wZW5FbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5faW5zZXJ0VGVtcGxhdGUgPSBmdW5jdGlvbiAodG9rZW4pIHtcbiAgICB2YXIgdG1wbCA9IHRoaXMudHJlZUFkYXB0ZXIuY3JlYXRlRWxlbWVudCh0b2tlbi50YWdOYW1lLCBOUy5IVE1MLCB0b2tlbi5hdHRycyksXG4gICAgICAgIGNvbnRlbnQgPSB0aGlzLnRyZWVBZGFwdGVyLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcblxuICAgIHRoaXMudHJlZUFkYXB0ZXIuYXBwZW5kQ2hpbGQodG1wbCwgY29udGVudCk7XG4gICAgdGhpcy5fYXR0YWNoRWxlbWVudFRvVHJlZSh0bXBsKTtcbiAgICB0aGlzLm9wZW5FbGVtZW50cy5wdXNoKHRtcGwpO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5faW5zZXJ0RmFrZVJvb3RFbGVtZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBlbGVtZW50ID0gdGhpcy50cmVlQWRhcHRlci5jcmVhdGVFbGVtZW50KCQuSFRNTCwgTlMuSFRNTCwgW10pO1xuXG4gICAgdGhpcy50cmVlQWRhcHRlci5hcHBlbmRDaGlsZCh0aGlzLm9wZW5FbGVtZW50cy5jdXJyZW50LCBlbGVtZW50KTtcbiAgICB0aGlzLm9wZW5FbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5fYXBwZW5kQ29tbWVudE5vZGUgPSBmdW5jdGlvbiAodG9rZW4sIHBhcmVudCkge1xuICAgIHZhciBjb21tZW50Tm9kZSA9IHRoaXMudHJlZUFkYXB0ZXIuY3JlYXRlQ29tbWVudE5vZGUodG9rZW4uZGF0YSk7XG5cbiAgICB0aGlzLnRyZWVBZGFwdGVyLmFwcGVuZENoaWxkKHBhcmVudCwgY29tbWVudE5vZGUpO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5faW5zZXJ0Q2hhcmFjdGVycyA9IGZ1bmN0aW9uICh0b2tlbikge1xuICAgIGlmICh0aGlzLl9zaG91bGRGb3N0ZXJQYXJlbnRPbkluc2VydGlvbigpKVxuICAgICAgICB0aGlzLl9mb3N0ZXJQYXJlbnRUZXh0KHRva2VuLmNoYXJzKTtcblxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgcGFyZW50ID0gdGhpcy5vcGVuRWxlbWVudHMuY3VycmVudFRtcGxDb250ZW50IHx8IHRoaXMub3BlbkVsZW1lbnRzLmN1cnJlbnQ7XG5cbiAgICAgICAgdGhpcy50cmVlQWRhcHRlci5pbnNlcnRUZXh0KHBhcmVudCwgdG9rZW4uY2hhcnMpO1xuICAgIH1cbn07XG5cblBhcnNlci5wcm90b3R5cGUuX2Fkb3B0Tm9kZXMgPSBmdW5jdGlvbiAoZG9ub3IsIHJlY2lwaWVudCkge1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIHZhciBjaGlsZCA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0Rmlyc3RDaGlsZChkb25vcik7XG5cbiAgICAgICAgaWYgKCFjaGlsZClcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIHRoaXMudHJlZUFkYXB0ZXIuZGV0YWNoTm9kZShjaGlsZCk7XG4gICAgICAgIHRoaXMudHJlZUFkYXB0ZXIuYXBwZW5kQ2hpbGQocmVjaXBpZW50LCBjaGlsZCk7XG4gICAgfVxufTtcblxuLy9Ub2tlbiBwcm9jZXNzaW5nXG5QYXJzZXIucHJvdG90eXBlLl9zaG91bGRQcm9jZXNzVG9rZW5JbkZvcmVpZ25Db250ZW50ID0gZnVuY3Rpb24gKHRva2VuKSB7XG4gICAgdmFyIGN1cnJlbnQgPSB0aGlzLl9nZXRBZGp1c3RlZEN1cnJlbnRFbGVtZW50KCk7XG5cbiAgICBpZiAoIWN1cnJlbnQgfHwgY3VycmVudCA9PT0gdGhpcy5kb2N1bWVudClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgdmFyIG5zID0gdGhpcy50cmVlQWRhcHRlci5nZXROYW1lc3BhY2VVUkkoY3VycmVudCk7XG5cbiAgICBpZiAobnMgPT09IE5TLkhUTUwpXG4gICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgIGlmICh0aGlzLnRyZWVBZGFwdGVyLmdldFRhZ05hbWUoY3VycmVudCkgPT09ICQuQU5OT1RBVElPTl9YTUwgJiYgbnMgPT09IE5TLk1BVEhNTCAmJlxuICAgICAgICB0b2tlbi50eXBlID09PSBUb2tlbml6ZXIuU1RBUlRfVEFHX1RPS0VOICYmIHRva2VuLnRhZ05hbWUgPT09ICQuU1ZHKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgaXNDaGFyYWN0ZXJUb2tlbiA9IHRva2VuLnR5cGUgPT09IFRva2VuaXplci5DSEFSQUNURVJfVE9LRU4gfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuLnR5cGUgPT09IFRva2VuaXplci5OVUxMX0NIQVJBQ1RFUl9UT0tFTiB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW4udHlwZSA9PT0gVG9rZW5pemVyLldISVRFU1BBQ0VfQ0hBUkFDVEVSX1RPS0VOLFxuICAgICAgICBpc01hdGhNTFRleHRTdGFydFRhZyA9IHRva2VuLnR5cGUgPT09IFRva2VuaXplci5TVEFSVF9UQUdfVE9LRU4gJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b2tlbi50YWdOYW1lICE9PSAkLk1HTFlQSCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuLnRhZ05hbWUgIT09ICQuTUFMSUdOTUFSSztcblxuICAgIGlmICgoaXNNYXRoTUxUZXh0U3RhcnRUYWcgfHwgaXNDaGFyYWN0ZXJUb2tlbikgJiYgdGhpcy5faXNNYXRoTUxUZXh0SW50ZWdyYXRpb25Qb2ludChjdXJyZW50KSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKCh0b2tlbi50eXBlID09PSBUb2tlbml6ZXIuU1RBUlRfVEFHX1RPS0VOIHx8IGlzQ2hhcmFjdGVyVG9rZW4pICYmIHRoaXMuX2lzSHRtbEludGVncmF0aW9uUG9pbnQoY3VycmVudCkpXG4gICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgIHJldHVybiB0b2tlbi50eXBlICE9PSBUb2tlbml6ZXIuRU9GX1RPS0VOO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5fcHJvY2Vzc1Rva2VuID0gZnVuY3Rpb24gKHRva2VuKSB7XG4gICAgX1t0aGlzLmluc2VydGlvbk1vZGVdW3Rva2VuLnR5cGVdKHRoaXMsIHRva2VuKTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUuX3Byb2Nlc3NUb2tlbkluQm9keU1vZGUgPSBmdW5jdGlvbiAodG9rZW4pIHtcbiAgICBfW0lOX0JPRFlfTU9ERV1bdG9rZW4udHlwZV0odGhpcywgdG9rZW4pO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5fcHJvY2Vzc1Rva2VuSW5Gb3JlaWduQ29udGVudCA9IGZ1bmN0aW9uICh0b2tlbikge1xuICAgIGlmICh0b2tlbi50eXBlID09PSBUb2tlbml6ZXIuQ0hBUkFDVEVSX1RPS0VOKVxuICAgICAgICBjaGFyYWN0ZXJJbkZvcmVpZ25Db250ZW50KHRoaXMsIHRva2VuKTtcblxuICAgIGVsc2UgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuaXplci5OVUxMX0NIQVJBQ1RFUl9UT0tFTilcbiAgICAgICAgbnVsbENoYXJhY3RlckluRm9yZWlnbkNvbnRlbnQodGhpcywgdG9rZW4pO1xuXG4gICAgZWxzZSBpZiAodG9rZW4udHlwZSA9PT0gVG9rZW5pemVyLldISVRFU1BBQ0VfQ0hBUkFDVEVSX1RPS0VOKVxuICAgICAgICBpbnNlcnRDaGFyYWN0ZXJzKHRoaXMsIHRva2VuKTtcblxuICAgIGVsc2UgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuaXplci5DT01NRU5UX1RPS0VOKVxuICAgICAgICBhcHBlbmRDb21tZW50KHRoaXMsIHRva2VuKTtcblxuICAgIGVsc2UgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuaXplci5TVEFSVF9UQUdfVE9LRU4pXG4gICAgICAgIHN0YXJ0VGFnSW5Gb3JlaWduQ29udGVudCh0aGlzLCB0b2tlbik7XG5cbiAgICBlbHNlIGlmICh0b2tlbi50eXBlID09PSBUb2tlbml6ZXIuRU5EX1RBR19UT0tFTilcbiAgICAgICAgZW5kVGFnSW5Gb3JlaWduQ29udGVudCh0aGlzLCB0b2tlbik7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLl9wcm9jZXNzRmFrZVN0YXJ0VGFnV2l0aEF0dHJzID0gZnVuY3Rpb24gKHRhZ05hbWUsIGF0dHJzKSB7XG4gICAgdmFyIGZha2VUb2tlbiA9IHRoaXMudG9rZW5pemVyLmJ1aWxkU3RhcnRUYWdUb2tlbih0YWdOYW1lKTtcblxuICAgIGZha2VUb2tlbi5hdHRycyA9IGF0dHJzO1xuICAgIHRoaXMuX3Byb2Nlc3NUb2tlbihmYWtlVG9rZW4pO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5fcHJvY2Vzc0Zha2VTdGFydFRhZyA9IGZ1bmN0aW9uICh0YWdOYW1lKSB7XG4gICAgdmFyIGZha2VUb2tlbiA9IHRoaXMudG9rZW5pemVyLmJ1aWxkU3RhcnRUYWdUb2tlbih0YWdOYW1lKTtcblxuICAgIHRoaXMuX3Byb2Nlc3NUb2tlbihmYWtlVG9rZW4pO1xuICAgIHJldHVybiBmYWtlVG9rZW47XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLl9wcm9jZXNzRmFrZUVuZFRhZyA9IGZ1bmN0aW9uICh0YWdOYW1lKSB7XG4gICAgdmFyIGZha2VUb2tlbiA9IHRoaXMudG9rZW5pemVyLmJ1aWxkRW5kVGFnVG9rZW4odGFnTmFtZSk7XG5cbiAgICB0aGlzLl9wcm9jZXNzVG9rZW4oZmFrZVRva2VuKTtcbiAgICByZXR1cm4gZmFrZVRva2VuO1xufTtcblxuLy9JbnRlZ3JhdGlvbiBwb2ludHNcblBhcnNlci5wcm90b3R5cGUuX2lzTWF0aE1MVGV4dEludGVncmF0aW9uUG9pbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgIHZhciB0biA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0VGFnTmFtZShlbGVtZW50KSxcbiAgICAgICAgbnMgPSB0aGlzLnRyZWVBZGFwdGVyLmdldE5hbWVzcGFjZVVSSShlbGVtZW50KTtcblxuICAgIHJldHVybiBGb3JlaWduQ29udGVudC5pc01hdGhNTFRleHRJbnRlZ3JhdGlvblBvaW50KHRuLCBucyk7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLl9pc0h0bWxJbnRlZ3JhdGlvblBvaW50ID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICB2YXIgdG4gPSB0aGlzLnRyZWVBZGFwdGVyLmdldFRhZ05hbWUoZWxlbWVudCksXG4gICAgICAgIG5zID0gdGhpcy50cmVlQWRhcHRlci5nZXROYW1lc3BhY2VVUkkoZWxlbWVudCksXG4gICAgICAgIGF0dHJzID0gdGhpcy50cmVlQWRhcHRlci5nZXRBdHRyTGlzdChlbGVtZW50KTtcblxuICAgIHJldHVybiBGb3JlaWduQ29udGVudC5pc0h0bWxJbnRlZ3JhdGlvblBvaW50KHRuLCBucywgYXR0cnMpO1xufTtcblxuLy9BY3RpdmUgZm9ybWF0dGluZyBlbGVtZW50cyByZWNvbnN0cnVjdGlvblxuUGFyc2VyLnByb3RvdHlwZS5fcmVjb25zdHJ1Y3RBY3RpdmVGb3JtYXR0aW5nRWxlbWVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGxpc3RMZW5ndGggPSB0aGlzLmFjdGl2ZUZvcm1hdHRpbmdFbGVtZW50cy5sZW5ndGg7XG5cbiAgICBpZiAobGlzdExlbmd0aCkge1xuICAgICAgICB2YXIgdW5vcGVuSWR4ID0gbGlzdExlbmd0aCxcbiAgICAgICAgICAgIGVudHJ5ID0gbnVsbDtcblxuICAgICAgICBkbyB7XG4gICAgICAgICAgICB1bm9wZW5JZHgtLTtcbiAgICAgICAgICAgIGVudHJ5ID0gdGhpcy5hY3RpdmVGb3JtYXR0aW5nRWxlbWVudHMuZW50cmllc1t1bm9wZW5JZHhdO1xuXG4gICAgICAgICAgICBpZiAoZW50cnkudHlwZSA9PT0gRm9ybWF0dGluZ0VsZW1lbnRMaXN0Lk1BUktFUl9FTlRSWSB8fCB0aGlzLm9wZW5FbGVtZW50cy5jb250YWlucyhlbnRyeS5lbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIHVub3BlbklkeCsrO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IHdoaWxlICh1bm9wZW5JZHggPiAwKTtcblxuICAgICAgICBmb3IgKHZhciBpID0gdW5vcGVuSWR4OyBpIDwgbGlzdExlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBlbnRyeSA9IHRoaXMuYWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzLmVudHJpZXNbaV07XG4gICAgICAgICAgICB0aGlzLl9pbnNlcnRFbGVtZW50KGVudHJ5LnRva2VuLCB0aGlzLnRyZWVBZGFwdGVyLmdldE5hbWVzcGFjZVVSSShlbnRyeS5lbGVtZW50KSk7XG4gICAgICAgICAgICBlbnRyeS5lbGVtZW50ID0gdGhpcy5vcGVuRWxlbWVudHMuY3VycmVudDtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbi8vQ2xvc2UgZWxlbWVudHNcblBhcnNlci5wcm90b3R5cGUuX2Nsb3NlVGFibGVDZWxsID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLm9wZW5FbGVtZW50cy5oYXNJblRhYmxlU2NvcGUoJC5URCkpXG4gICAgICAgIHRoaXMuX3Byb2Nlc3NGYWtlRW5kVGFnKCQuVEQpO1xuXG4gICAgZWxzZVxuICAgICAgICB0aGlzLl9wcm9jZXNzRmFrZUVuZFRhZygkLlRIKTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUuX2Nsb3NlUEVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5vcGVuRWxlbWVudHMuZ2VuZXJhdGVJbXBsaWVkRW5kVGFnc1dpdGhFeGNsdXNpb24oJC5QKTtcbiAgICB0aGlzLm9wZW5FbGVtZW50cy5wb3BVbnRpbFRhZ05hbWVQb3BwZWQoJC5QKTtcbn07XG5cbi8vSW5zZXJ0aW9uIG1vZGVzXG5QYXJzZXIucHJvdG90eXBlLl9yZXNldEluc2VydGlvbk1vZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgZm9yICh2YXIgaSA9IHRoaXMub3BlbkVsZW1lbnRzLnN0YWNrVG9wLCBsYXN0ID0gZmFsc2U7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIHZhciBlbGVtZW50ID0gdGhpcy5vcGVuRWxlbWVudHMuaXRlbXNbaV07XG5cbiAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAgIGxhc3QgPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5mcmFnbWVudENvbnRleHQpXG4gICAgICAgICAgICAgICAgZWxlbWVudCA9IHRoaXMuZnJhZ21lbnRDb250ZXh0O1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHRuID0gdGhpcy50cmVlQWRhcHRlci5nZXRUYWdOYW1lKGVsZW1lbnQpLFxuICAgICAgICAgICAgbmV3SW5zZXJ0aW9uTW9kZSA9IElOU0VSVElPTl9NT0RFX1JFU0VUX01BUFt0bl07XG5cbiAgICAgICAgaWYgKG5ld0luc2VydGlvbk1vZGUpIHtcbiAgICAgICAgICAgIHRoaXMuaW5zZXJ0aW9uTW9kZSA9IG5ld0luc2VydGlvbk1vZGU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGVsc2UgaWYgKCFsYXN0ICYmICh0biA9PT0gJC5URCB8fCB0biA9PT0gJC5USCkpIHtcbiAgICAgICAgICAgIHRoaXMuaW5zZXJ0aW9uTW9kZSA9IElOX0NFTExfTU9ERTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgZWxzZSBpZiAoIWxhc3QgJiYgdG4gPT09ICQuSEVBRCkge1xuICAgICAgICAgICAgdGhpcy5pbnNlcnRpb25Nb2RlID0gSU5fSEVBRF9NT0RFO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5TRUxFQ1QpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc2V0SW5zZXJ0aW9uTW9kZUZvclNlbGVjdChpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuVEVNUExBVEUpIHtcbiAgICAgICAgICAgIHRoaXMuaW5zZXJ0aW9uTW9kZSA9IHRoaXMuY3VycmVudFRtcGxJbnNlcnRpb25Nb2RlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5IVE1MKSB7XG4gICAgICAgICAgICB0aGlzLmluc2VydGlvbk1vZGUgPSB0aGlzLmhlYWRFbGVtZW50ID8gQUZURVJfSEVBRF9NT0RFIDogQkVGT1JFX0hFQURfTU9ERTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgZWxzZSBpZiAobGFzdCkge1xuICAgICAgICAgICAgdGhpcy5pbnNlcnRpb25Nb2RlID0gSU5fQk9EWV9NT0RFO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLl9yZXNldEluc2VydGlvbk1vZGVGb3JTZWxlY3QgPSBmdW5jdGlvbiAoc2VsZWN0SWR4KSB7XG4gICAgaWYgKHNlbGVjdElkeCA+IDApIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IHNlbGVjdElkeCAtIDE7IGkgPiAwOyBpLS0pIHtcbiAgICAgICAgICAgIHZhciBhbmNlc3RvciA9IHRoaXMub3BlbkVsZW1lbnRzLml0ZW1zW2ldLFxuICAgICAgICAgICAgICAgIHRuID0gdGhpcy50cmVlQWRhcHRlci5nZXRUYWdOYW1lKGFuY2VzdG9yKTtcblxuICAgICAgICAgICAgaWYgKHRuID09PSAkLlRFTVBMQVRFKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5UQUJMRSkge1xuICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0aW9uTW9kZSA9IElOX1NFTEVDVF9JTl9UQUJMRV9NT0RFO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuaW5zZXJ0aW9uTW9kZSA9IElOX1NFTEVDVF9NT0RFO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5fcHVzaFRtcGxJbnNlcnRpb25Nb2RlID0gZnVuY3Rpb24gKG1vZGUpIHtcbiAgICB0aGlzLnRtcGxJbnNlcnRpb25Nb2RlU3RhY2sucHVzaChtb2RlKTtcbiAgICB0aGlzLnRtcGxJbnNlcnRpb25Nb2RlU3RhY2tUb3ArKztcbiAgICB0aGlzLmN1cnJlbnRUbXBsSW5zZXJ0aW9uTW9kZSA9IG1vZGU7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLl9wb3BUbXBsSW5zZXJ0aW9uTW9kZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnRtcGxJbnNlcnRpb25Nb2RlU3RhY2sucG9wKCk7XG4gICAgdGhpcy50bXBsSW5zZXJ0aW9uTW9kZVN0YWNrVG9wLS07XG4gICAgdGhpcy5jdXJyZW50VG1wbEluc2VydGlvbk1vZGUgPSB0aGlzLnRtcGxJbnNlcnRpb25Nb2RlU3RhY2tbdGhpcy50bXBsSW5zZXJ0aW9uTW9kZVN0YWNrVG9wXTtcbn07XG5cbi8vRm9zdGVyIHBhcmVudGluZ1xuUGFyc2VyLnByb3RvdHlwZS5faXNFbGVtZW50Q2F1c2VzRm9zdGVyUGFyZW50aW5nID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICB2YXIgdG4gPSB0aGlzLnRyZWVBZGFwdGVyLmdldFRhZ05hbWUoZWxlbWVudCk7XG5cbiAgICByZXR1cm4gdG4gPT09ICQuVEFCTEUgfHwgdG4gPT09ICQuVEJPRFkgfHwgdG4gPT09ICQuVEZPT1QgfHwgdG4gPT0gJC5USEVBRCB8fCB0biA9PT0gJC5UUjtcbn07XG5cblBhcnNlci5wcm90b3R5cGUuX3Nob3VsZEZvc3RlclBhcmVudE9uSW5zZXJ0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZvc3RlclBhcmVudGluZ0VuYWJsZWQgJiYgdGhpcy5faXNFbGVtZW50Q2F1c2VzRm9zdGVyUGFyZW50aW5nKHRoaXMub3BlbkVsZW1lbnRzLmN1cnJlbnQpO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5fZmluZEZvc3RlclBhcmVudGluZ0xvY2F0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBsb2NhdGlvbiA9IHtcbiAgICAgICAgcGFyZW50OiBudWxsLFxuICAgICAgICBiZWZvcmVFbGVtZW50OiBudWxsXG4gICAgfTtcblxuICAgIGZvciAodmFyIGkgPSB0aGlzLm9wZW5FbGVtZW50cy5zdGFja1RvcDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgdmFyIG9wZW5FbGVtZW50ID0gdGhpcy5vcGVuRWxlbWVudHMuaXRlbXNbaV0sXG4gICAgICAgICAgICB0biA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0VGFnTmFtZShvcGVuRWxlbWVudCksXG4gICAgICAgICAgICBucyA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0TmFtZXNwYWNlVVJJKG9wZW5FbGVtZW50KTtcblxuICAgICAgICBpZiAodG4gPT09ICQuVEVNUExBVEUgJiYgbnMgPT09IE5TLkhUTUwpIHtcbiAgICAgICAgICAgIGxvY2F0aW9uLnBhcmVudCA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0Q2hpbGROb2RlcyhvcGVuRWxlbWVudClbMF07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGVsc2UgaWYgKHRuID09PSAkLlRBQkxFKSB7XG4gICAgICAgICAgICBsb2NhdGlvbi5wYXJlbnQgPSB0aGlzLnRyZWVBZGFwdGVyLmdldFBhcmVudE5vZGUob3BlbkVsZW1lbnQpO1xuXG4gICAgICAgICAgICBpZiAobG9jYXRpb24ucGFyZW50KVxuICAgICAgICAgICAgICAgIGxvY2F0aW9uLmJlZm9yZUVsZW1lbnQgPSBvcGVuRWxlbWVudDtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBsb2NhdGlvbi5wYXJlbnQgPSB0aGlzLm9wZW5FbGVtZW50cy5pdGVtc1tpIC0gMV07XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFsb2NhdGlvbi5wYXJlbnQpXG4gICAgICAgIGxvY2F0aW9uLnBhcmVudCA9IHRoaXMub3BlbkVsZW1lbnRzLml0ZW1zWzBdO1xuXG4gICAgcmV0dXJuIGxvY2F0aW9uO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5fZm9zdGVyUGFyZW50RWxlbWVudCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgdmFyIGxvY2F0aW9uID0gdGhpcy5fZmluZEZvc3RlclBhcmVudGluZ0xvY2F0aW9uKCk7XG5cbiAgICBpZiAobG9jYXRpb24uYmVmb3JlRWxlbWVudClcbiAgICAgICAgdGhpcy50cmVlQWRhcHRlci5pbnNlcnRCZWZvcmUobG9jYXRpb24ucGFyZW50LCBlbGVtZW50LCBsb2NhdGlvbi5iZWZvcmVFbGVtZW50KTtcbiAgICBlbHNlXG4gICAgICAgIHRoaXMudHJlZUFkYXB0ZXIuYXBwZW5kQ2hpbGQobG9jYXRpb24ucGFyZW50LCBlbGVtZW50KTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUuX2Zvc3RlclBhcmVudFRleHQgPSBmdW5jdGlvbiAoY2hhcnMpIHtcbiAgICB2YXIgbG9jYXRpb24gPSB0aGlzLl9maW5kRm9zdGVyUGFyZW50aW5nTG9jYXRpb24oKTtcblxuICAgIGlmIChsb2NhdGlvbi5iZWZvcmVFbGVtZW50KVxuICAgICAgICB0aGlzLnRyZWVBZGFwdGVyLmluc2VydFRleHRCZWZvcmUobG9jYXRpb24ucGFyZW50LCBjaGFycywgbG9jYXRpb24uYmVmb3JlRWxlbWVudCk7XG4gICAgZWxzZVxuICAgICAgICB0aGlzLnRyZWVBZGFwdGVyLmluc2VydFRleHQobG9jYXRpb24ucGFyZW50LCBjaGFycyk7XG59O1xuXG4vL1NwZWNpYWwgZWxlbWVudHNcblBhcnNlci5wcm90b3R5cGUuX2lzU3BlY2lhbEVsZW1lbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgIHZhciB0biA9IHRoaXMudHJlZUFkYXB0ZXIuZ2V0VGFnTmFtZShlbGVtZW50KSxcbiAgICAgICAgbnMgPSB0aGlzLnRyZWVBZGFwdGVyLmdldE5hbWVzcGFjZVVSSShlbGVtZW50KTtcblxuICAgIHJldHVybiBIVE1MLlNQRUNJQUxfRUxFTUVOVFNbbnNdW3RuXTtcbn07XG5cbi8vQWRvcHRpb24gYWdlbmN5IGFsZ29yaXRobVxuLy8oc2VlOiBodHRwOi8vd3d3LndoYXR3Zy5vcmcvc3BlY3Mvd2ViLWFwcHMvY3VycmVudC13b3JrL211bHRpcGFnZS90cmVlLWNvbnN0cnVjdGlvbi5odG1sI2Fkb3B0aW9uQWdlbmN5KVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy9TdGVwcyA1LTggb2YgdGhlIGFsZ29yaXRobVxuZnVuY3Rpb24gYWFPYnRhaW5Gb3JtYXR0aW5nRWxlbWVudEVudHJ5KHAsIHRva2VuKSB7XG4gICAgdmFyIGZvcm1hdHRpbmdFbGVtZW50RW50cnkgPSBwLmFjdGl2ZUZvcm1hdHRpbmdFbGVtZW50cy5nZXRFbGVtZW50RW50cnlJblNjb3BlV2l0aFRhZ05hbWUodG9rZW4udGFnTmFtZSk7XG5cbiAgICBpZiAoZm9ybWF0dGluZ0VsZW1lbnRFbnRyeSkge1xuICAgICAgICBpZiAoIXAub3BlbkVsZW1lbnRzLmNvbnRhaW5zKGZvcm1hdHRpbmdFbGVtZW50RW50cnkuZWxlbWVudCkpIHtcbiAgICAgICAgICAgIHAuYWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzLnJlbW92ZUVudHJ5KGZvcm1hdHRpbmdFbGVtZW50RW50cnkpO1xuICAgICAgICAgICAgZm9ybWF0dGluZ0VsZW1lbnRFbnRyeSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBlbHNlIGlmICghcC5vcGVuRWxlbWVudHMuaGFzSW5TY29wZSh0b2tlbi50YWdOYW1lKSlcbiAgICAgICAgICAgIGZvcm1hdHRpbmdFbGVtZW50RW50cnkgPSBudWxsO1xuICAgIH1cblxuICAgIGVsc2VcbiAgICAgICAgZ2VuZXJpY0VuZFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICByZXR1cm4gZm9ybWF0dGluZ0VsZW1lbnRFbnRyeTtcbn1cblxuLy9TdGVwcyA5IGFuZCAxMCBvZiB0aGUgYWxnb3JpdGhtXG5mdW5jdGlvbiBhYU9idGFpbkZ1cnRoZXN0QmxvY2socCwgZm9ybWF0dGluZ0VsZW1lbnRFbnRyeSkge1xuICAgIHZhciBmdXJ0aGVzdEJsb2NrID0gbnVsbDtcblxuICAgIGZvciAodmFyIGkgPSBwLm9wZW5FbGVtZW50cy5zdGFja1RvcDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgdmFyIGVsZW1lbnQgPSBwLm9wZW5FbGVtZW50cy5pdGVtc1tpXTtcblxuICAgICAgICBpZiAoZWxlbWVudCA9PT0gZm9ybWF0dGluZ0VsZW1lbnRFbnRyeS5lbGVtZW50KVxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgaWYgKHAuX2lzU3BlY2lhbEVsZW1lbnQoZWxlbWVudCkpXG4gICAgICAgICAgICBmdXJ0aGVzdEJsb2NrID0gZWxlbWVudDtcbiAgICB9XG5cbiAgICBpZiAoIWZ1cnRoZXN0QmxvY2spIHtcbiAgICAgICAgcC5vcGVuRWxlbWVudHMucG9wVW50aWxFbGVtZW50UG9wcGVkKGZvcm1hdHRpbmdFbGVtZW50RW50cnkuZWxlbWVudCk7XG4gICAgICAgIHAuYWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzLnJlbW92ZUVudHJ5KGZvcm1hdHRpbmdFbGVtZW50RW50cnkpO1xuICAgIH1cblxuICAgIHJldHVybiBmdXJ0aGVzdEJsb2NrO1xufVxuXG4vL1N0ZXAgMTMgb2YgdGhlIGFsZ29yaXRobVxuZnVuY3Rpb24gYWFJbm5lckxvb3AocCwgZnVydGhlc3RCbG9jaywgZm9ybWF0dGluZ0VsZW1lbnQpIHtcbiAgICB2YXIgZWxlbWVudCA9IG51bGwsXG4gICAgICAgIGxhc3RFbGVtZW50ID0gZnVydGhlc3RCbG9jayxcbiAgICAgICAgbmV4dEVsZW1lbnQgPSBwLm9wZW5FbGVtZW50cy5nZXRDb21tb25BbmNlc3RvcihmdXJ0aGVzdEJsb2NrKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgQUFfSU5ORVJfTE9PUF9JVEVSOyBpKyspIHtcbiAgICAgICAgZWxlbWVudCA9IG5leHRFbGVtZW50O1xuXG4gICAgICAgIC8vTk9URTogc3RvcmUgbmV4dCBlbGVtZW50IGZvciB0aGUgbmV4dCBsb29wIGl0ZXJhdGlvbiAoaXQgbWF5IGJlIGRlbGV0ZWQgZnJvbSB0aGUgc3RhY2sgYnkgc3RlcCA5LjUpXG4gICAgICAgIG5leHRFbGVtZW50ID0gcC5vcGVuRWxlbWVudHMuZ2V0Q29tbW9uQW5jZXN0b3IoZWxlbWVudCk7XG5cbiAgICAgICAgdmFyIGVsZW1lbnRFbnRyeSA9IHAuYWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzLmdldEVsZW1lbnRFbnRyeShlbGVtZW50KTtcblxuICAgICAgICBpZiAoIWVsZW1lbnRFbnRyeSkge1xuICAgICAgICAgICAgcC5vcGVuRWxlbWVudHMucmVtb3ZlKGVsZW1lbnQpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZWxlbWVudCA9PT0gZm9ybWF0dGluZ0VsZW1lbnQpXG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBlbGVtZW50ID0gYWFSZWNyZWF0ZUVsZW1lbnRGcm9tRW50cnkocCwgZWxlbWVudEVudHJ5KTtcblxuICAgICAgICBpZiAobGFzdEVsZW1lbnQgPT09IGZ1cnRoZXN0QmxvY2spXG4gICAgICAgICAgICBwLmFjdGl2ZUZvcm1hdHRpbmdFbGVtZW50cy5ib29rbWFyayA9IGVsZW1lbnRFbnRyeTtcblxuICAgICAgICBwLnRyZWVBZGFwdGVyLmRldGFjaE5vZGUobGFzdEVsZW1lbnQpO1xuICAgICAgICBwLnRyZWVBZGFwdGVyLmFwcGVuZENoaWxkKGVsZW1lbnQsIGxhc3RFbGVtZW50KTtcbiAgICAgICAgbGFzdEVsZW1lbnQgPSBlbGVtZW50O1xuICAgIH1cblxuICAgIHJldHVybiBsYXN0RWxlbWVudDtcbn1cblxuLy9TdGVwIDEzLjcgb2YgdGhlIGFsZ29yaXRobVxuZnVuY3Rpb24gYWFSZWNyZWF0ZUVsZW1lbnRGcm9tRW50cnkocCwgZWxlbWVudEVudHJ5KSB7XG4gICAgdmFyIG5zID0gcC50cmVlQWRhcHRlci5nZXROYW1lc3BhY2VVUkkoZWxlbWVudEVudHJ5LmVsZW1lbnQpLFxuICAgICAgICBuZXdFbGVtZW50ID0gcC50cmVlQWRhcHRlci5jcmVhdGVFbGVtZW50KGVsZW1lbnRFbnRyeS50b2tlbi50YWdOYW1lLCBucywgZWxlbWVudEVudHJ5LnRva2VuLmF0dHJzKTtcblxuICAgIHAub3BlbkVsZW1lbnRzLnJlcGxhY2UoZWxlbWVudEVudHJ5LmVsZW1lbnQsIG5ld0VsZW1lbnQpO1xuICAgIGVsZW1lbnRFbnRyeS5lbGVtZW50ID0gbmV3RWxlbWVudDtcblxuICAgIHJldHVybiBuZXdFbGVtZW50O1xufVxuXG4vL1N0ZXAgMTQgb2YgdGhlIGFsZ29yaXRobVxuZnVuY3Rpb24gYWFJbnNlcnRMYXN0Tm9kZUluQ29tbW9uQW5jZXN0b3IocCwgY29tbW9uQW5jZXN0b3IsIGxhc3RFbGVtZW50KSB7XG4gICAgaWYgKHAuX2lzRWxlbWVudENhdXNlc0Zvc3RlclBhcmVudGluZyhjb21tb25BbmNlc3RvcikpXG4gICAgICAgIHAuX2Zvc3RlclBhcmVudEVsZW1lbnQobGFzdEVsZW1lbnQpO1xuXG4gICAgZWxzZSB7XG4gICAgICAgIHZhciB0biA9IHAudHJlZUFkYXB0ZXIuZ2V0VGFnTmFtZShjb21tb25BbmNlc3RvciksXG4gICAgICAgICAgICBucyA9IHAudHJlZUFkYXB0ZXIuZ2V0TmFtZXNwYWNlVVJJKGNvbW1vbkFuY2VzdG9yKTtcblxuICAgICAgICBpZiAodG4gPT09ICQuVEVNUExBVEUgJiYgbnMgPT09IE5TLkhUTUwpXG4gICAgICAgICAgICBjb21tb25BbmNlc3RvciA9IHAudHJlZUFkYXB0ZXIuZ2V0Q2hpbGROb2Rlcyhjb21tb25BbmNlc3RvcilbMF07XG5cbiAgICAgICAgcC50cmVlQWRhcHRlci5hcHBlbmRDaGlsZChjb21tb25BbmNlc3RvciwgbGFzdEVsZW1lbnQpO1xuICAgIH1cbn1cblxuLy9TdGVwcyAxNS0xOSBvZiB0aGUgYWxnb3JpdGhtXG5mdW5jdGlvbiBhYVJlcGxhY2VGb3JtYXR0aW5nRWxlbWVudChwLCBmdXJ0aGVzdEJsb2NrLCBmb3JtYXR0aW5nRWxlbWVudEVudHJ5KSB7XG4gICAgdmFyIG5zID0gcC50cmVlQWRhcHRlci5nZXROYW1lc3BhY2VVUkkoZm9ybWF0dGluZ0VsZW1lbnRFbnRyeS5lbGVtZW50KSxcbiAgICAgICAgdG9rZW4gPSBmb3JtYXR0aW5nRWxlbWVudEVudHJ5LnRva2VuLFxuICAgICAgICBuZXdFbGVtZW50ID0gcC50cmVlQWRhcHRlci5jcmVhdGVFbGVtZW50KHRva2VuLnRhZ05hbWUsIG5zLCB0b2tlbi5hdHRycyk7XG5cbiAgICBwLl9hZG9wdE5vZGVzKGZ1cnRoZXN0QmxvY2ssIG5ld0VsZW1lbnQpO1xuICAgIHAudHJlZUFkYXB0ZXIuYXBwZW5kQ2hpbGQoZnVydGhlc3RCbG9jaywgbmV3RWxlbWVudCk7XG5cbiAgICBwLmFjdGl2ZUZvcm1hdHRpbmdFbGVtZW50cy5pbnNlcnRFbGVtZW50QWZ0ZXJCb29rbWFyayhuZXdFbGVtZW50LCBmb3JtYXR0aW5nRWxlbWVudEVudHJ5LnRva2VuKTtcbiAgICBwLmFjdGl2ZUZvcm1hdHRpbmdFbGVtZW50cy5yZW1vdmVFbnRyeShmb3JtYXR0aW5nRWxlbWVudEVudHJ5KTtcblxuICAgIHAub3BlbkVsZW1lbnRzLnJlbW92ZShmb3JtYXR0aW5nRWxlbWVudEVudHJ5LmVsZW1lbnQpO1xuICAgIHAub3BlbkVsZW1lbnRzLmluc2VydEFmdGVyKGZ1cnRoZXN0QmxvY2ssIG5ld0VsZW1lbnQpO1xufVxuXG4vL0FsZ29yaXRobSBlbnRyeSBwb2ludFxuZnVuY3Rpb24gY2FsbEFkb3B0aW9uQWdlbmN5KHAsIHRva2VuKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBBQV9PVVRFUl9MT09QX0lURVI7IGkrKykge1xuICAgICAgICB2YXIgZm9ybWF0dGluZ0VsZW1lbnRFbnRyeSA9IGFhT2J0YWluRm9ybWF0dGluZ0VsZW1lbnRFbnRyeShwLCB0b2tlbiwgZm9ybWF0dGluZ0VsZW1lbnRFbnRyeSk7XG5cbiAgICAgICAgaWYgKCFmb3JtYXR0aW5nRWxlbWVudEVudHJ5KVxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgdmFyIGZ1cnRoZXN0QmxvY2sgPSBhYU9idGFpbkZ1cnRoZXN0QmxvY2socCwgZm9ybWF0dGluZ0VsZW1lbnRFbnRyeSk7XG5cbiAgICAgICAgaWYgKCFmdXJ0aGVzdEJsb2NrKVxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgcC5hY3RpdmVGb3JtYXR0aW5nRWxlbWVudHMuYm9va21hcmsgPSBmb3JtYXR0aW5nRWxlbWVudEVudHJ5O1xuXG4gICAgICAgIHZhciBsYXN0RWxlbWVudCA9IGFhSW5uZXJMb29wKHAsIGZ1cnRoZXN0QmxvY2ssIGZvcm1hdHRpbmdFbGVtZW50RW50cnkuZWxlbWVudCksXG4gICAgICAgICAgICBjb21tb25BbmNlc3RvciA9IHAub3BlbkVsZW1lbnRzLmdldENvbW1vbkFuY2VzdG9yKGZvcm1hdHRpbmdFbGVtZW50RW50cnkuZWxlbWVudCk7XG5cbiAgICAgICAgcC50cmVlQWRhcHRlci5kZXRhY2hOb2RlKGxhc3RFbGVtZW50KTtcbiAgICAgICAgYWFJbnNlcnRMYXN0Tm9kZUluQ29tbW9uQW5jZXN0b3IocCwgY29tbW9uQW5jZXN0b3IsIGxhc3RFbGVtZW50KTtcbiAgICAgICAgYWFSZXBsYWNlRm9ybWF0dGluZ0VsZW1lbnQocCwgZnVydGhlc3RCbG9jaywgZm9ybWF0dGluZ0VsZW1lbnRFbnRyeSk7XG4gICAgfVxufVxuXG5cbi8vR2VuZXJpYyB0b2tlbiBoYW5kbGVyc1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIGlnbm9yZVRva2VuKHAsIHRva2VuKSB7XG4gICAgLy9OT1RFOiBkbyBub3RoaW5nID0pXG59XG5cbmZ1bmN0aW9uIGFwcGVuZENvbW1lbnQocCwgdG9rZW4pIHtcbiAgICBwLl9hcHBlbmRDb21tZW50Tm9kZSh0b2tlbiwgcC5vcGVuRWxlbWVudHMuY3VycmVudFRtcGxDb250ZW50IHx8IHAub3BlbkVsZW1lbnRzLmN1cnJlbnQpXG59XG5cbmZ1bmN0aW9uIGFwcGVuZENvbW1lbnRUb1Jvb3RIdG1sRWxlbWVudChwLCB0b2tlbikge1xuICAgIHAuX2FwcGVuZENvbW1lbnROb2RlKHRva2VuLCBwLm9wZW5FbGVtZW50cy5pdGVtc1swXSk7XG59XG5cbmZ1bmN0aW9uIGFwcGVuZENvbW1lbnRUb0RvY3VtZW50KHAsIHRva2VuKSB7XG4gICAgcC5fYXBwZW5kQ29tbWVudE5vZGUodG9rZW4sIHAuZG9jdW1lbnQpO1xufVxuXG5mdW5jdGlvbiBpbnNlcnRDaGFyYWN0ZXJzKHAsIHRva2VuKSB7XG4gICAgcC5faW5zZXJ0Q2hhcmFjdGVycyh0b2tlbik7XG59XG5cbmZ1bmN0aW9uIHN0b3BQYXJzaW5nKHAsIHRva2VuKSB7XG4gICAgcC5zdG9wcGVkID0gdHJ1ZTtcbn1cblxuLy8xMi4yLjUuNC4xIFRoZSBcImluaXRpYWxcIiBpbnNlcnRpb24gbW9kZVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIGRvY3R5cGVJbkluaXRpYWxNb2RlKHAsIHRva2VuKSB7XG4gICAgcC5fc2V0RG9jdW1lbnRUeXBlKHRva2VuKTtcblxuICAgIGlmICh0b2tlbi5mb3JjZVF1aXJrcyB8fCBEb2N0eXBlLmlzUXVpcmtzKHRva2VuLm5hbWUsIHRva2VuLnB1YmxpY0lkLCB0b2tlbi5zeXN0ZW1JZCkpXG4gICAgICAgIHAudHJlZUFkYXB0ZXIuc2V0UXVpcmtzTW9kZShwLmRvY3VtZW50KTtcblxuICAgIHAuaW5zZXJ0aW9uTW9kZSA9IEJFRk9SRV9IVE1MX01PREU7XG59XG5cbmZ1bmN0aW9uIHRva2VuSW5Jbml0aWFsTW9kZShwLCB0b2tlbikge1xuICAgIHAudHJlZUFkYXB0ZXIuc2V0UXVpcmtzTW9kZShwLmRvY3VtZW50KTtcbiAgICBwLmluc2VydGlvbk1vZGUgPSBCRUZPUkVfSFRNTF9NT0RFO1xuICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG59XG5cblxuLy8xMi4yLjUuNC4yIFRoZSBcImJlZm9yZSBodG1sXCIgaW5zZXJ0aW9uIG1vZGVcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBzdGFydFRhZ0JlZm9yZUh0bWwocCwgdG9rZW4pIHtcbiAgICBpZiAodG9rZW4udGFnTmFtZSA9PT0gJC5IVE1MKSB7XG4gICAgICAgIHAuX2luc2VydEVsZW1lbnQodG9rZW4sIE5TLkhUTUwpO1xuICAgICAgICBwLmluc2VydGlvbk1vZGUgPSBCRUZPUkVfSEVBRF9NT0RFO1xuICAgIH1cblxuICAgIGVsc2VcbiAgICAgICAgdG9rZW5CZWZvcmVIdG1sKHAsIHRva2VuKTtcbn1cblxuZnVuY3Rpb24gZW5kVGFnQmVmb3JlSHRtbChwLCB0b2tlbikge1xuICAgIHZhciB0biA9IHRva2VuLnRhZ05hbWU7XG5cbiAgICBpZiAodG4gPT09ICQuSFRNTCB8fCB0biA9PT0gJC5IRUFEIHx8IHRuID09PSAkLkJPRFkgfHwgdG4gPT09ICQuQlIpXG4gICAgICAgIHRva2VuQmVmb3JlSHRtbChwLCB0b2tlbik7XG59XG5cbmZ1bmN0aW9uIHRva2VuQmVmb3JlSHRtbChwLCB0b2tlbikge1xuICAgIHAuX2luc2VydEZha2VSb290RWxlbWVudCgpO1xuICAgIHAuaW5zZXJ0aW9uTW9kZSA9IEJFRk9SRV9IRUFEX01PREU7XG4gICAgcC5fcHJvY2Vzc1Rva2VuKHRva2VuKTtcbn1cblxuXG4vLzEyLjIuNS40LjMgVGhlIFwiYmVmb3JlIGhlYWRcIiBpbnNlcnRpb24gbW9kZVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIHN0YXJ0VGFnQmVmb3JlSGVhZChwLCB0b2tlbikge1xuICAgIHZhciB0biA9IHRva2VuLnRhZ05hbWU7XG5cbiAgICBpZiAodG4gPT09ICQuSFRNTClcbiAgICAgICAgc3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgZWxzZSBpZiAodG4gPT09ICQuSEVBRCkge1xuICAgICAgICBwLl9pbnNlcnRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcbiAgICAgICAgcC5oZWFkRWxlbWVudCA9IHAub3BlbkVsZW1lbnRzLmN1cnJlbnQ7XG4gICAgICAgIHAuaW5zZXJ0aW9uTW9kZSA9IElOX0hFQURfTU9ERTtcbiAgICB9XG5cbiAgICBlbHNlXG4gICAgICAgIHRva2VuQmVmb3JlSGVhZChwLCB0b2tlbik7XG59XG5cbmZ1bmN0aW9uIGVuZFRhZ0JlZm9yZUhlYWQocCwgdG9rZW4pIHtcbiAgICB2YXIgdG4gPSB0b2tlbi50YWdOYW1lO1xuXG4gICAgaWYgKHRuID09PSAkLkhFQUQgfHwgdG4gPT09ICQuQk9EWSB8fCB0biA9PT0gJC5IVE1MIHx8IHRuID09PSAkLkJSKVxuICAgICAgICB0b2tlbkJlZm9yZUhlYWQocCwgdG9rZW4pO1xufVxuXG5mdW5jdGlvbiB0b2tlbkJlZm9yZUhlYWQocCwgdG9rZW4pIHtcbiAgICBwLl9wcm9jZXNzRmFrZVN0YXJ0VGFnKCQuSEVBRCk7XG4gICAgcC5fcHJvY2Vzc1Rva2VuKHRva2VuKTtcbn1cblxuXG4vLzEyLjIuNS40LjQgVGhlIFwiaW4gaGVhZFwiIGluc2VydGlvbiBtb2RlXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZnVuY3Rpb24gc3RhcnRUYWdJbkhlYWQocCwgdG9rZW4pIHtcbiAgICB2YXIgdG4gPSB0b2tlbi50YWdOYW1lO1xuXG4gICAgaWYgKHRuID09PSAkLkhUTUwpXG4gICAgICAgIHN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgIGVsc2UgaWYgKHRuID09PSAkLkJBU0UgfHwgdG4gPT09ICQuQkFTRUZPTlQgfHwgdG4gPT09ICQuQkdTT1VORCB8fFxuICAgICAgICAgICAgIHRuID09PSAkLkNPTU1BTkQgfHwgdG4gPT09ICQuTElOSyB8fCB0biA9PT0gJC5NRVRBKSB7XG4gICAgICAgIHAuX2FwcGVuZEVsZW1lbnQodG9rZW4sIE5TLkhUTUwpO1xuICAgIH1cblxuICAgIGVsc2UgaWYgKHRuID09PSAkLlRJVExFKVxuICAgICAgICBwLl9zd2l0Y2hUb1RleHRQYXJzaW5nKHRva2VuLCBUb2tlbml6ZXIuTU9ERS5SQ0RBVEEpO1xuXG4gICAgLy9OT1RFOiBoZXJlIHdlIGFzc3VtZSB0aGF0IHdlIGFsd2F5cyBhY3QgYXMgYW4gaW50ZXJhY3RpdmUgdXNlciBhZ2VudCB3aXRoIGVuYWJsZWQgc2NyaXB0aW5nLCBzbyB3ZSBwYXJzZVxuICAgIC8vPG5vc2NyaXB0PiBhcyBhIHJhd3RleHQuXG4gICAgZWxzZSBpZiAodG4gPT09ICQuTk9TQ1JJUFQgfHwgdG4gPT09ICQuTk9GUkFNRVMgfHwgdG4gPT09ICQuU1RZTEUpXG4gICAgICAgIHAuX3N3aXRjaFRvVGV4dFBhcnNpbmcodG9rZW4sIFRva2VuaXplci5NT0RFLlJBV1RFWFQpO1xuXG4gICAgZWxzZSBpZiAodG4gPT09ICQuU0NSSVBUKVxuICAgICAgICBwLl9zd2l0Y2hUb1RleHRQYXJzaW5nKHRva2VuLCBUb2tlbml6ZXIuTU9ERS5TQ1JJUFRfREFUQSk7XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5URU1QTEFURSkge1xuICAgICAgICBwLl9pbnNlcnRUZW1wbGF0ZSh0b2tlbiwgTlMuSFRNTCk7XG4gICAgICAgIHAuYWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzLmluc2VydE1hcmtlcigpO1xuICAgICAgICBwLmZyYW1lc2V0T2sgPSBmYWxzZTtcbiAgICAgICAgcC5pbnNlcnRpb25Nb2RlID0gSU5fVEVNUExBVEVfTU9ERTtcbiAgICAgICAgcC5fcHVzaFRtcGxJbnNlcnRpb25Nb2RlKElOX1RFTVBMQVRFX01PREUpO1xuICAgIH1cblxuICAgIGVsc2UgaWYgKHRuICE9PSAkLkhFQUQpXG4gICAgICAgIHRva2VuSW5IZWFkKHAsIHRva2VuKTtcbn1cblxuZnVuY3Rpb24gZW5kVGFnSW5IZWFkKHAsIHRva2VuKSB7XG4gICAgdmFyIHRuID0gdG9rZW4udGFnTmFtZTtcblxuICAgIGlmICh0biA9PT0gJC5IRUFEKSB7XG4gICAgICAgIHAub3BlbkVsZW1lbnRzLnBvcCgpO1xuICAgICAgICBwLmluc2VydGlvbk1vZGUgPSBBRlRFUl9IRUFEX01PREU7XG4gICAgfVxuXG4gICAgZWxzZSBpZiAodG4gPT09ICQuQk9EWSB8fCB0biA9PT0gJC5CUiB8fCB0biA9PT0gJC5IVE1MKVxuICAgICAgICB0b2tlbkluSGVhZChwLCB0b2tlbik7XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5URU1QTEFURSAmJiBwLm9wZW5FbGVtZW50cy50bXBsQ291bnQgPiAwKSB7XG4gICAgICAgIHAub3BlbkVsZW1lbnRzLmdlbmVyYXRlSW1wbGllZEVuZFRhZ3MoKTtcbiAgICAgICAgcC5vcGVuRWxlbWVudHMucG9wVW50aWxUZW1wbGF0ZVBvcHBlZCgpO1xuICAgICAgICBwLmFjdGl2ZUZvcm1hdHRpbmdFbGVtZW50cy5jbGVhclRvTGFzdE1hcmtlcigpO1xuICAgICAgICBwLl9wb3BUbXBsSW5zZXJ0aW9uTW9kZSgpO1xuICAgICAgICBwLl9yZXNldEluc2VydGlvbk1vZGUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRva2VuSW5IZWFkKHAsIHRva2VuKSB7XG4gICAgcC5fcHJvY2Vzc0Zha2VFbmRUYWcoJC5IRUFEKTtcbiAgICBwLl9wcm9jZXNzVG9rZW4odG9rZW4pO1xufVxuXG5cbi8vMTIuMi41LjQuNiBUaGUgXCJhZnRlciBoZWFkXCIgaW5zZXJ0aW9uIG1vZGVcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBzdGFydFRhZ0FmdGVySGVhZChwLCB0b2tlbikge1xuICAgIHZhciB0biA9IHRva2VuLnRhZ05hbWU7XG5cbiAgICBpZiAodG4gPT09ICQuSFRNTClcbiAgICAgICAgc3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgZWxzZSBpZiAodG4gPT09ICQuQk9EWSkge1xuICAgICAgICBwLl9pbnNlcnRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcbiAgICAgICAgcC5mcmFtZXNldE9rID0gZmFsc2U7XG4gICAgICAgIHAuaW5zZXJ0aW9uTW9kZSA9IElOX0JPRFlfTU9ERTtcbiAgICB9XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5GUkFNRVNFVCkge1xuICAgICAgICBwLl9pbnNlcnRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcbiAgICAgICAgcC5pbnNlcnRpb25Nb2RlID0gSU5fRlJBTUVTRVRfTU9ERTtcbiAgICB9XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5CQVNFIHx8IHRuID09PSAkLkJBU0VGT05UIHx8IHRuID09PSAkLkJHU09VTkQgfHwgdG4gPT09ICQuTElOSyB8fCB0biA9PT0gJC5NRVRBIHx8XG4gICAgICAgICAgICAgdG4gPT09ICQuTk9GUkFNRVMgfHwgdG4gPT09ICQuU0NSSVBUIHx8IHRuID09PSAkLlNUWUxFIHx8IHRuID09PSAkLlRFTVBMQVRFIHx8IHRuID09PSAkLlRJVExFKSB7XG4gICAgICAgIHAub3BlbkVsZW1lbnRzLnB1c2gocC5oZWFkRWxlbWVudCk7XG4gICAgICAgIHN0YXJ0VGFnSW5IZWFkKHAsIHRva2VuKTtcbiAgICAgICAgcC5vcGVuRWxlbWVudHMucmVtb3ZlKHAuaGVhZEVsZW1lbnQpO1xuICAgIH1cblxuICAgIGVsc2UgaWYgKHRuICE9PSAkLkhFQUQpXG4gICAgICAgIHRva2VuQWZ0ZXJIZWFkKHAsIHRva2VuKTtcbn1cblxuZnVuY3Rpb24gZW5kVGFnQWZ0ZXJIZWFkKHAsIHRva2VuKSB7XG4gICAgdmFyIHRuID0gdG9rZW4udGFnTmFtZTtcblxuICAgIGlmICh0biA9PT0gJC5CT0RZIHx8IHRuID09PSAkLkhUTUwgfHwgdG4gPT09ICQuQlIpXG4gICAgICAgIHRva2VuQWZ0ZXJIZWFkKHAsIHRva2VuKTtcblxuICAgIGVsc2UgaWYgKHRuID09PSAkLlRFTVBMQVRFKVxuICAgICAgICBlbmRUYWdJbkhlYWQocCwgdG9rZW4pO1xufVxuXG5mdW5jdGlvbiB0b2tlbkFmdGVySGVhZChwLCB0b2tlbikge1xuICAgIHAuX3Byb2Nlc3NGYWtlU3RhcnRUYWcoJC5CT0RZKTtcbiAgICBwLmZyYW1lc2V0T2sgPSB0cnVlO1xuICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG59XG5cblxuLy8xMi4yLjUuNC43IFRoZSBcImluIGJvZHlcIiBpbnNlcnRpb24gbW9kZVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIHdoaXRlc3BhY2VDaGFyYWN0ZXJJbkJvZHkocCwgdG9rZW4pIHtcbiAgICBwLl9yZWNvbnN0cnVjdEFjdGl2ZUZvcm1hdHRpbmdFbGVtZW50cygpO1xuICAgIHAuX2luc2VydENoYXJhY3RlcnModG9rZW4pO1xufVxuXG5mdW5jdGlvbiBjaGFyYWN0ZXJJbkJvZHkocCwgdG9rZW4pIHtcbiAgICBwLl9yZWNvbnN0cnVjdEFjdGl2ZUZvcm1hdHRpbmdFbGVtZW50cygpO1xuICAgIHAuX2luc2VydENoYXJhY3RlcnModG9rZW4pO1xuICAgIHAuZnJhbWVzZXRPayA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBodG1sU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICBpZiAocC5vcGVuRWxlbWVudHMudG1wbENvdW50ID09PSAwKVxuICAgICAgICBwLnRyZWVBZGFwdGVyLmFkb3B0QXR0cmlidXRlcyhwLm9wZW5FbGVtZW50cy5pdGVtc1swXSwgdG9rZW4uYXR0cnMpO1xufVxuXG5mdW5jdGlvbiBib2R5U3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICB2YXIgYm9keUVsZW1lbnQgPSBwLm9wZW5FbGVtZW50cy50cnlQZWVrUHJvcGVybHlOZXN0ZWRCb2R5RWxlbWVudCgpO1xuXG4gICAgaWYgKGJvZHlFbGVtZW50ICYmIHAub3BlbkVsZW1lbnRzLnRtcGxDb3VudCA9PT0gMCkge1xuICAgICAgICBwLmZyYW1lc2V0T2sgPSBmYWxzZTtcbiAgICAgICAgcC50cmVlQWRhcHRlci5hZG9wdEF0dHJpYnV0ZXMoYm9keUVsZW1lbnQsIHRva2VuLmF0dHJzKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGZyYW1lc2V0U3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICB2YXIgYm9keUVsZW1lbnQgPSBwLm9wZW5FbGVtZW50cy50cnlQZWVrUHJvcGVybHlOZXN0ZWRCb2R5RWxlbWVudCgpO1xuXG4gICAgaWYgKHAuZnJhbWVzZXRPayAmJiBib2R5RWxlbWVudCkge1xuICAgICAgICBwLnRyZWVBZGFwdGVyLmRldGFjaE5vZGUoYm9keUVsZW1lbnQpO1xuICAgICAgICBwLm9wZW5FbGVtZW50cy5wb3BBbGxVcFRvSHRtbEVsZW1lbnQoKTtcbiAgICAgICAgcC5faW5zZXJ0RWxlbWVudCh0b2tlbiwgTlMuSFRNTCk7XG4gICAgICAgIHAuaW5zZXJ0aW9uTW9kZSA9IElOX0ZSQU1FU0VUX01PREU7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBhZGRyZXNzU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICBpZiAocC5vcGVuRWxlbWVudHMuaGFzSW5CdXR0b25TY29wZSgkLlApKVxuICAgICAgICBwLl9jbG9zZVBFbGVtZW50KCk7XG5cbiAgICBwLl9pbnNlcnRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcbn1cblxuZnVuY3Rpb24gbnVtYmVyZWRIZWFkZXJTdGFydFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIGlmIChwLm9wZW5FbGVtZW50cy5oYXNJbkJ1dHRvblNjb3BlKCQuUCkpXG4gICAgICAgIHAuX2Nsb3NlUEVsZW1lbnQoKTtcblxuICAgIHZhciB0biA9IHAub3BlbkVsZW1lbnRzLmN1cnJlbnRUYWdOYW1lO1xuXG4gICAgaWYgKHRuID09PSAkLkgxIHx8IHRuID09PSAkLkgyIHx8IHRuID09PSAkLkgzIHx8IHRuID09PSAkLkg0IHx8IHRuID09PSAkLkg1IHx8IHRuID09PSAkLkg2KVxuICAgICAgICBwLm9wZW5FbGVtZW50cy5wb3AoKTtcblxuICAgIHAuX2luc2VydEVsZW1lbnQodG9rZW4sIE5TLkhUTUwpO1xufVxuXG5mdW5jdGlvbiBwcmVTdGFydFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIGlmIChwLm9wZW5FbGVtZW50cy5oYXNJbkJ1dHRvblNjb3BlKCQuUCkpXG4gICAgICAgIHAuX2Nsb3NlUEVsZW1lbnQoKTtcblxuICAgIHAuX2luc2VydEVsZW1lbnQodG9rZW4sIE5TLkhUTUwpO1xuICAgIC8vTk9URTogSWYgdGhlIG5leHQgdG9rZW4gaXMgYSBVKzAwMEEgTElORSBGRUVEIChMRikgY2hhcmFjdGVyIHRva2VuLCB0aGVuIGlnbm9yZSB0aGF0IHRva2VuIGFuZCBtb3ZlXG4gICAgLy9vbiB0byB0aGUgbmV4dCBvbmUuIChOZXdsaW5lcyBhdCB0aGUgc3RhcnQgb2YgcHJlIGJsb2NrcyBhcmUgaWdub3JlZCBhcyBhbiBhdXRob3JpbmcgY29udmVuaWVuY2UuKVxuICAgIHAuc2tpcE5leHROZXdMaW5lID0gdHJ1ZTtcbiAgICBwLmZyYW1lc2V0T2sgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gZm9ybVN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKSB7XG4gICAgdmFyIGluVGVtcGxhdGUgPSBwLm9wZW5FbGVtZW50cy50bXBsQ291bnQgPiAwO1xuXG4gICAgaWYgKCFwLmZvcm1FbGVtZW50IHx8IGluVGVtcGxhdGUpIHtcbiAgICAgICAgaWYgKHAub3BlbkVsZW1lbnRzLmhhc0luQnV0dG9uU2NvcGUoJC5QKSlcbiAgICAgICAgICAgIHAuX2Nsb3NlUEVsZW1lbnQoKTtcblxuICAgICAgICBwLl9pbnNlcnRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcblxuICAgICAgICBpZiAoIWluVGVtcGxhdGUpXG4gICAgICAgICAgICBwLmZvcm1FbGVtZW50ID0gcC5vcGVuRWxlbWVudHMuY3VycmVudDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGxpc3RJdGVtU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICBwLmZyYW1lc2V0T2sgPSBmYWxzZTtcblxuICAgIGZvciAodmFyIGkgPSBwLm9wZW5FbGVtZW50cy5zdGFja1RvcDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgdmFyIGVsZW1lbnQgPSBwLm9wZW5FbGVtZW50cy5pdGVtc1tpXSxcbiAgICAgICAgICAgIHRuID0gcC50cmVlQWRhcHRlci5nZXRUYWdOYW1lKGVsZW1lbnQpO1xuXG4gICAgICAgIGlmICgodG9rZW4udGFnTmFtZSA9PT0gJC5MSSAmJiB0biA9PT0gJC5MSSkgfHxcbiAgICAgICAgICAgICgodG9rZW4udGFnTmFtZSA9PT0gJC5ERCB8fCB0b2tlbi50YWdOYW1lID09PSAkLkRUKSAmJiAodG4gPT09ICQuREQgfHwgdG4gPT0gJC5EVCkpKSB7XG4gICAgICAgICAgICBwLl9wcm9jZXNzRmFrZUVuZFRhZyh0bik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0biAhPT0gJC5BRERSRVNTICYmIHRuICE9PSAkLkRJViAmJiB0biAhPT0gJC5QICYmIHAuX2lzU3BlY2lhbEVsZW1lbnQoZWxlbWVudCkpXG4gICAgICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAocC5vcGVuRWxlbWVudHMuaGFzSW5CdXR0b25TY29wZSgkLlApKVxuICAgICAgICBwLl9jbG9zZVBFbGVtZW50KCk7XG5cbiAgICBwLl9pbnNlcnRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcbn1cblxuZnVuY3Rpb24gcGxhaW50ZXh0U3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICBpZiAocC5vcGVuRWxlbWVudHMuaGFzSW5CdXR0b25TY29wZSgkLlApKVxuICAgICAgICBwLl9jbG9zZVBFbGVtZW50KCk7XG5cbiAgICBwLl9pbnNlcnRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcbiAgICBwLnRva2VuaXplci5zdGF0ZSA9IFRva2VuaXplci5NT0RFLlBMQUlOVEVYVDtcbn1cblxuZnVuY3Rpb24gYnV0dG9uU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICBpZiAocC5vcGVuRWxlbWVudHMuaGFzSW5TY29wZSgkLkJVVFRPTikpIHtcbiAgICAgICAgcC5fcHJvY2Vzc0Zha2VFbmRUYWcoJC5CVVRUT04pO1xuICAgICAgICBidXR0b25TdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG4gICAgfVxuXG4gICAgZWxzZSB7XG4gICAgICAgIHAuX3JlY29uc3RydWN0QWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzKCk7XG4gICAgICAgIHAuX2luc2VydEVsZW1lbnQodG9rZW4sIE5TLkhUTUwpO1xuICAgICAgICBwLmZyYW1lc2V0T2sgPSBmYWxzZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGFTdGFydFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIHZhciBhY3RpdmVFbGVtZW50RW50cnkgPSBwLmFjdGl2ZUZvcm1hdHRpbmdFbGVtZW50cy5nZXRFbGVtZW50RW50cnlJblNjb3BlV2l0aFRhZ05hbWUoJC5BKTtcblxuICAgIGlmIChhY3RpdmVFbGVtZW50RW50cnkpIHtcbiAgICAgICAgcC5fcHJvY2Vzc0Zha2VFbmRUYWcoJC5BKTtcbiAgICAgICAgcC5vcGVuRWxlbWVudHMucmVtb3ZlKGFjdGl2ZUVsZW1lbnRFbnRyeS5lbGVtZW50KTtcbiAgICAgICAgcC5hY3RpdmVGb3JtYXR0aW5nRWxlbWVudHMucmVtb3ZlRW50cnkoYWN0aXZlRWxlbWVudEVudHJ5KTtcbiAgICB9XG5cbiAgICBwLl9yZWNvbnN0cnVjdEFjdGl2ZUZvcm1hdHRpbmdFbGVtZW50cygpO1xuICAgIHAuX2luc2VydEVsZW1lbnQodG9rZW4sIE5TLkhUTUwpO1xuICAgIHAuYWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzLnB1c2hFbGVtZW50KHAub3BlbkVsZW1lbnRzLmN1cnJlbnQsIHRva2VuKTtcbn1cblxuZnVuY3Rpb24gYlN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKSB7XG4gICAgcC5fcmVjb25zdHJ1Y3RBY3RpdmVGb3JtYXR0aW5nRWxlbWVudHMoKTtcbiAgICBwLl9pbnNlcnRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcbiAgICBwLmFjdGl2ZUZvcm1hdHRpbmdFbGVtZW50cy5wdXNoRWxlbWVudChwLm9wZW5FbGVtZW50cy5jdXJyZW50LCB0b2tlbik7XG59XG5cbmZ1bmN0aW9uIG5vYnJTdGFydFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIHAuX3JlY29uc3RydWN0QWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzKCk7XG5cbiAgICBpZiAocC5vcGVuRWxlbWVudHMuaGFzSW5TY29wZSgkLk5PQlIpKSB7XG4gICAgICAgIHAuX3Byb2Nlc3NGYWtlRW5kVGFnKCQuTk9CUik7XG4gICAgICAgIHAuX3JlY29uc3RydWN0QWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzKCk7XG4gICAgfVxuXG4gICAgcC5faW5zZXJ0RWxlbWVudCh0b2tlbiwgTlMuSFRNTCk7XG4gICAgcC5hY3RpdmVGb3JtYXR0aW5nRWxlbWVudHMucHVzaEVsZW1lbnQocC5vcGVuRWxlbWVudHMuY3VycmVudCwgdG9rZW4pO1xufVxuXG5mdW5jdGlvbiBhcHBsZXRTdGFydFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIHAuX3JlY29uc3RydWN0QWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzKCk7XG4gICAgcC5faW5zZXJ0RWxlbWVudCh0b2tlbiwgTlMuSFRNTCk7XG4gICAgcC5hY3RpdmVGb3JtYXR0aW5nRWxlbWVudHMuaW5zZXJ0TWFya2VyKCk7XG4gICAgcC5mcmFtZXNldE9rID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHRhYmxlU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICBpZiAoIXAudHJlZUFkYXB0ZXIuaXNRdWlya3NNb2RlKHAuZG9jdW1lbnQpICYmIHAub3BlbkVsZW1lbnRzLmhhc0luQnV0dG9uU2NvcGUoJC5QKSlcbiAgICAgICAgcC5fY2xvc2VQRWxlbWVudCgpO1xuXG4gICAgcC5faW5zZXJ0RWxlbWVudCh0b2tlbiwgTlMuSFRNTCk7XG4gICAgcC5mcmFtZXNldE9rID0gZmFsc2U7XG4gICAgcC5pbnNlcnRpb25Nb2RlID0gSU5fVEFCTEVfTU9ERTtcbn1cblxuZnVuY3Rpb24gYXJlYVN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKSB7XG4gICAgcC5fcmVjb25zdHJ1Y3RBY3RpdmVGb3JtYXR0aW5nRWxlbWVudHMoKTtcbiAgICBwLl9hcHBlbmRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcbiAgICBwLmZyYW1lc2V0T2sgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaW5wdXRTdGFydFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIHAuX3JlY29uc3RydWN0QWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzKCk7XG4gICAgcC5fYXBwZW5kRWxlbWVudCh0b2tlbiwgTlMuSFRNTCk7XG5cbiAgICB2YXIgaW5wdXRUeXBlID0gVG9rZW5pemVyLmdldFRva2VuQXR0cih0b2tlbiwgQVRUUlMuVFlQRSk7XG5cbiAgICBpZiAoIWlucHV0VHlwZSB8fCBpbnB1dFR5cGUudG9Mb3dlckNhc2UoKSAhPT0gSElEREVOX0lOUFVUX1RZUEUpXG4gICAgICAgIHAuZnJhbWVzZXRPayA9IGZhbHNlO1xuXG59XG5cbmZ1bmN0aW9uIHBhcmFtU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICBwLl9hcHBlbmRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcbn1cblxuZnVuY3Rpb24gaHJTdGFydFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIGlmIChwLm9wZW5FbGVtZW50cy5oYXNJbkJ1dHRvblNjb3BlKCQuUCkpXG4gICAgICAgIHAuX2Nsb3NlUEVsZW1lbnQoKTtcblxuICAgIHAuX2FwcGVuZEVsZW1lbnQodG9rZW4sIE5TLkhUTUwpO1xuICAgIHAuZnJhbWVzZXRPayA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBpbWFnZVN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKSB7XG4gICAgdG9rZW4udGFnTmFtZSA9ICQuSU1HO1xuICAgIGFyZWFTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG59XG5cbmZ1bmN0aW9uIGlzaW5kZXhTdGFydFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIGlmICghcC5mb3JtRWxlbWVudCB8fCBwLm9wZW5FbGVtZW50cy50bXBsQ291bnQgPiAwKSB7XG4gICAgICAgIHAuX3Byb2Nlc3NGYWtlU3RhcnRUYWdXaXRoQXR0cnMoJC5GT1JNLCBnZXRTZWFyY2hhYmxlSW5kZXhGb3JtQXR0cnModG9rZW4pKTtcbiAgICAgICAgcC5fcHJvY2Vzc0Zha2VTdGFydFRhZygkLkhSKTtcbiAgICAgICAgcC5fcHJvY2Vzc0Zha2VTdGFydFRhZygkLkxBQkVMKTtcbiAgICAgICAgcC50cmVlQWRhcHRlci5pbnNlcnRUZXh0KHAub3BlbkVsZW1lbnRzLmN1cnJlbnQsIGdldFNlYXJjaGFibGVJbmRleExhYmVsVGV4dCh0b2tlbikpO1xuICAgICAgICBwLl9wcm9jZXNzRmFrZVN0YXJ0VGFnV2l0aEF0dHJzKCQuSU5QVVQsIGdldFNlYXJjaGFibGVJbmRleElucHV0QXR0cnModG9rZW4pKTtcbiAgICAgICAgcC5fcHJvY2Vzc0Zha2VFbmRUYWcoJC5MQUJFTCk7XG4gICAgICAgIHAuX3Byb2Nlc3NGYWtlU3RhcnRUYWcoJC5IUik7XG4gICAgICAgIHAuX3Byb2Nlc3NGYWtlRW5kVGFnKCQuRk9STSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiB0ZXh0YXJlYVN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKSB7XG4gICAgcC5faW5zZXJ0RWxlbWVudCh0b2tlbiwgTlMuSFRNTCk7XG4gICAgLy9OT1RFOiBJZiB0aGUgbmV4dCB0b2tlbiBpcyBhIFUrMDAwQSBMSU5FIEZFRUQgKExGKSBjaGFyYWN0ZXIgdG9rZW4sIHRoZW4gaWdub3JlIHRoYXQgdG9rZW4gYW5kIG1vdmVcbiAgICAvL29uIHRvIHRoZSBuZXh0IG9uZS4gKE5ld2xpbmVzIGF0IHRoZSBzdGFydCBvZiB0ZXh0YXJlYSBlbGVtZW50cyBhcmUgaWdub3JlZCBhcyBhbiBhdXRob3JpbmcgY29udmVuaWVuY2UuKVxuICAgIHAuc2tpcE5leHROZXdMaW5lID0gdHJ1ZTtcbiAgICBwLnRva2VuaXplci5zdGF0ZSA9IFRva2VuaXplci5NT0RFLlJDREFUQTtcbiAgICBwLm9yaWdpbmFsSW5zZXJ0aW9uTW9kZSA9IHAuaW5zZXJ0aW9uTW9kZTtcbiAgICBwLmZyYW1lc2V0T2sgPSBmYWxzZTtcbiAgICBwLmluc2VydGlvbk1vZGUgPSBURVhUX01PREU7XG59XG5cbmZ1bmN0aW9uIHhtcFN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKSB7XG4gICAgaWYgKHAub3BlbkVsZW1lbnRzLmhhc0luQnV0dG9uU2NvcGUoJC5QKSlcbiAgICAgICAgcC5fY2xvc2VQRWxlbWVudCgpO1xuXG4gICAgcC5fcmVjb25zdHJ1Y3RBY3RpdmVGb3JtYXR0aW5nRWxlbWVudHMoKTtcbiAgICBwLmZyYW1lc2V0T2sgPSBmYWxzZTtcbiAgICBwLl9zd2l0Y2hUb1RleHRQYXJzaW5nKHRva2VuLCBUb2tlbml6ZXIuTU9ERS5SQVdURVhUKTtcbn1cblxuZnVuY3Rpb24gaWZyYW1lU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICBwLmZyYW1lc2V0T2sgPSBmYWxzZTtcbiAgICBwLl9zd2l0Y2hUb1RleHRQYXJzaW5nKHRva2VuLCBUb2tlbml6ZXIuTU9ERS5SQVdURVhUKTtcbn1cblxuLy9OT1RFOiBoZXJlIHdlIGFzc3VtZSB0aGF0IHdlIGFsd2F5cyBhY3QgYXMgYW4gdXNlciBhZ2VudCB3aXRoIGVuYWJsZWQgcGx1Z2lucywgc28gd2UgcGFyc2Vcbi8vPG5vZW1iZWQ+IGFzIGEgcmF3dGV4dC5cbmZ1bmN0aW9uIG5vZW1iZWRTdGFydFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIHAuX3N3aXRjaFRvVGV4dFBhcnNpbmcodG9rZW4sIFRva2VuaXplci5NT0RFLlJBV1RFWFQpO1xufVxuXG5mdW5jdGlvbiBzZWxlY3RTdGFydFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIHAuX3JlY29uc3RydWN0QWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzKCk7XG4gICAgcC5faW5zZXJ0RWxlbWVudCh0b2tlbiwgTlMuSFRNTCk7XG4gICAgcC5mcmFtZXNldE9rID0gZmFsc2U7XG5cbiAgICBpZiAocC5pbnNlcnRpb25Nb2RlID09PSBJTl9UQUJMRV9NT0RFIHx8IHAuaW5zZXJ0aW9uTW9kZSA9PT0gSU5fQ0FQVElPTl9NT0RFIHx8XG4gICAgICAgIHAuaW5zZXJ0aW9uTW9kZSA9PT0gSU5fVEFCTEVfQk9EWV9NT0RFIHx8IHAuaW5zZXJ0aW9uTW9kZSA9PT0gSU5fUk9XX01PREUgfHxcbiAgICAgICAgcC5pbnNlcnRpb25Nb2RlID09PSBJTl9DRUxMX01PREUpIHtcbiAgICAgICAgcC5pbnNlcnRpb25Nb2RlID0gSU5fU0VMRUNUX0lOX1RBQkxFX01PREU7XG4gICAgfVxuXG4gICAgZWxzZVxuICAgICAgICBwLmluc2VydGlvbk1vZGUgPSBJTl9TRUxFQ1RfTU9ERTtcbn1cblxuZnVuY3Rpb24gb3B0Z3JvdXBTdGFydFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIGlmIChwLm9wZW5FbGVtZW50cy5jdXJyZW50VGFnTmFtZSA9PT0gJC5PUFRJT04pXG4gICAgICAgIHAuX3Byb2Nlc3NGYWtlRW5kVGFnKCQuT1BUSU9OKTtcblxuICAgIHAuX3JlY29uc3RydWN0QWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzKCk7XG4gICAgcC5faW5zZXJ0RWxlbWVudCh0b2tlbiwgTlMuSFRNTCk7XG59XG5cbmZ1bmN0aW9uIHJwU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICBpZiAocC5vcGVuRWxlbWVudHMuaGFzSW5TY29wZSgkLlJVQlkpKVxuICAgICAgICBwLm9wZW5FbGVtZW50cy5nZW5lcmF0ZUltcGxpZWRFbmRUYWdzKCk7XG5cbiAgICBwLl9pbnNlcnRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcbn1cblxuZnVuY3Rpb24gbWVudWl0ZW1TdGFydFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIHAuX2FwcGVuZEVsZW1lbnQodG9rZW4sIE5TLkhUTUwpO1xufVxuXG5mdW5jdGlvbiBtYXRoU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICBwLl9yZWNvbnN0cnVjdEFjdGl2ZUZvcm1hdHRpbmdFbGVtZW50cygpO1xuXG4gICAgRm9yZWlnbkNvbnRlbnQuYWRqdXN0VG9rZW5NYXRoTUxBdHRycyh0b2tlbik7XG4gICAgRm9yZWlnbkNvbnRlbnQuYWRqdXN0VG9rZW5YTUxBdHRycyh0b2tlbik7XG5cbiAgICBpZiAodG9rZW4uc2VsZkNsb3NpbmcpXG4gICAgICAgIHAuX2FwcGVuZEVsZW1lbnQodG9rZW4sIE5TLk1BVEhNTCk7XG4gICAgZWxzZVxuICAgICAgICBwLl9pbnNlcnRFbGVtZW50KHRva2VuLCBOUy5NQVRITUwpO1xufVxuXG5mdW5jdGlvbiBzdmdTdGFydFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIHAuX3JlY29uc3RydWN0QWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzKCk7XG5cbiAgICBGb3JlaWduQ29udGVudC5hZGp1c3RUb2tlblNWR0F0dHJzKHRva2VuKTtcbiAgICBGb3JlaWduQ29udGVudC5hZGp1c3RUb2tlblhNTEF0dHJzKHRva2VuKTtcblxuICAgIGlmICh0b2tlbi5zZWxmQ2xvc2luZylcbiAgICAgICAgcC5fYXBwZW5kRWxlbWVudCh0b2tlbiwgTlMuU1ZHKTtcbiAgICBlbHNlXG4gICAgICAgIHAuX2luc2VydEVsZW1lbnQodG9rZW4sIE5TLlNWRyk7XG59XG5cbmZ1bmN0aW9uIGdlbmVyaWNTdGFydFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIHAuX3JlY29uc3RydWN0QWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzKCk7XG4gICAgcC5faW5zZXJ0RWxlbWVudCh0b2tlbiwgTlMuSFRNTCk7XG59XG5cbi8vT1BUSU1JWkFUSU9OOiBJbnRlZ2VyIGNvbXBhcmlzb25zIGFyZSBsb3ctY29zdCwgc28gd2UgY2FuIHVzZSB2ZXJ5IGZhc3QgdGFnIG5hbWUgbGVuZ3RoIGZpbHRlcnMgaGVyZS5cbi8vSXQncyBmYXN0ZXIgdGhhbiB1c2luZyBkaWN0aW9uYXJ5LlxuZnVuY3Rpb24gc3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICB2YXIgdG4gPSB0b2tlbi50YWdOYW1lO1xuXG4gICAgc3dpdGNoICh0bi5sZW5ndGgpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgaWYgKHRuID09PSAkLkkgfHwgdG4gPT09ICQuUyB8fCB0biA9PT0gJC5CIHx8IHRuID09PSAkLlUpXG4gICAgICAgICAgICAgICAgYlN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuUClcbiAgICAgICAgICAgICAgICBhZGRyZXNzU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5BKVxuICAgICAgICAgICAgICAgIGFTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBnZW5lcmljU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICBpZiAodG4gPT09ICQuREwgfHwgdG4gPT09ICQuT0wgfHwgdG4gPT09ICQuVUwpXG4gICAgICAgICAgICAgICAgYWRkcmVzc1N0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuSDEgfHwgdG4gPT09ICQuSDIgfHwgdG4gPT09ICQuSDMgfHwgdG4gPT09ICQuSDQgfHwgdG4gPT09ICQuSDUgfHwgdG4gPT09ICQuSDYpXG4gICAgICAgICAgICAgICAgbnVtYmVyZWRIZWFkZXJTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLkxJIHx8IHRuID09PSAkLkREIHx8IHRuID09PSAkLkRUKVxuICAgICAgICAgICAgICAgIGxpc3RJdGVtU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5FTSB8fCB0biA9PT0gJC5UVClcbiAgICAgICAgICAgICAgICBiU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5CUilcbiAgICAgICAgICAgICAgICBhcmVhU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5IUilcbiAgICAgICAgICAgICAgICBoclN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuUlAgfHwgdG4gPT09ICQuUlQpXG4gICAgICAgICAgICAgICAgcnBTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuICE9PSAkLlRIICYmIHRuICE9PSAkLlREICYmIHRuICE9PSAkLlRSKVxuICAgICAgICAgICAgICAgIGdlbmVyaWNTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgIGlmICh0biA9PT0gJC5ESVYgfHwgdG4gPT09ICQuRElSIHx8IHRuID09PSAkLk5BVilcbiAgICAgICAgICAgICAgICBhZGRyZXNzU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5QUkUpXG4gICAgICAgICAgICAgICAgcHJlU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5CSUcpXG4gICAgICAgICAgICAgICAgYlN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuSU1HIHx8IHRuID09PSAkLldCUilcbiAgICAgICAgICAgICAgICBhcmVhU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5YTVApXG4gICAgICAgICAgICAgICAgeG1wU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5TVkcpXG4gICAgICAgICAgICAgICAgc3ZnU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biAhPT0gJC5DT0wpXG4gICAgICAgICAgICAgICAgZ2VuZXJpY1N0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgaWYgKHRuID09PSAkLkhUTUwpXG4gICAgICAgICAgICAgICAgaHRtbFN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuQkFTRSB8fCB0biA9PT0gJC5MSU5LIHx8IHRuID09PSAkLk1FVEEpXG4gICAgICAgICAgICAgICAgc3RhcnRUYWdJbkhlYWQocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5CT0RZKVxuICAgICAgICAgICAgICAgIGJvZHlTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLk1BSU4gfHwgdG4gPT09ICQuTUVOVSlcbiAgICAgICAgICAgICAgICBhZGRyZXNzU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5GT1JNKVxuICAgICAgICAgICAgICAgIGZvcm1TdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLkNPREUgfHwgdG4gPT09ICQuRk9OVClcbiAgICAgICAgICAgICAgICBiU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5OT0JSKVxuICAgICAgICAgICAgICAgIG5vYnJTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLkFSRUEpXG4gICAgICAgICAgICAgICAgYXJlYVN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuTUFUSClcbiAgICAgICAgICAgICAgICBtYXRoU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biAhPT0gJC5IRUFEKVxuICAgICAgICAgICAgICAgIGdlbmVyaWNTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgIGlmICh0biA9PT0gJC5TVFlMRSB8fCB0biA9PT0gJC5USVRMRSlcbiAgICAgICAgICAgICAgICBzdGFydFRhZ0luSGVhZChwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLkFTSURFKVxuICAgICAgICAgICAgICAgIGFkZHJlc3NTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLlNNQUxMKVxuICAgICAgICAgICAgICAgIGJTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLlRBQkxFKVxuICAgICAgICAgICAgICAgIHRhYmxlU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5FTUJFRClcbiAgICAgICAgICAgICAgICBhcmVhU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5JTlBVVClcbiAgICAgICAgICAgICAgICBpbnB1dFN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuUEFSQU0gfHwgdG4gPT09ICQuVFJBQ0spXG4gICAgICAgICAgICAgICAgcGFyYW1TdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLklNQUdFKVxuICAgICAgICAgICAgICAgIGltYWdlU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biAhPT0gJC5GUkFNRSAmJiB0biAhPT0gJC5UQk9EWSAmJiB0biAhPT0gJC5URk9PVCAmJiB0biAhPT0gJC5USEVBRClcbiAgICAgICAgICAgICAgICBnZW5lcmljU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICBpZiAodG4gPT09ICQuU0NSSVBUKVxuICAgICAgICAgICAgICAgIHN0YXJ0VGFnSW5IZWFkKHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuQ0VOVEVSIHx8IHRuID09PSAkLkZJR1VSRSB8fCB0biA9PT0gJC5GT09URVIgfHwgdG4gPT09ICQuSEVBREVSIHx8IHRuID09PSAkLkhHUk9VUClcbiAgICAgICAgICAgICAgICBhZGRyZXNzU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5CVVRUT04pXG4gICAgICAgICAgICAgICAgYnV0dG9uU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5TVFJJS0UgfHwgdG4gPT09ICQuU1RST05HKVxuICAgICAgICAgICAgICAgIGJTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLkFQUExFVCB8fCB0biA9PT0gJC5PQkpFQ1QpXG4gICAgICAgICAgICAgICAgYXBwbGV0U3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5LRVlHRU4pXG4gICAgICAgICAgICAgICAgYXJlYVN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuU09VUkNFKVxuICAgICAgICAgICAgICAgIHBhcmFtU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5JRlJBTUUpXG4gICAgICAgICAgICAgICAgaWZyYW1lU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5TRUxFQ1QpXG4gICAgICAgICAgICAgICAgc2VsZWN0U3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5PUFRJT04pXG4gICAgICAgICAgICAgICAgb3B0Z3JvdXBTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBnZW5lcmljU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICBpZiAodG4gPT09ICQuQkdTT1VORCB8fCB0biA9PT0gJC5DT01NQU5EKVxuICAgICAgICAgICAgICAgIHN0YXJ0VGFnSW5IZWFkKHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuREVUQUlMUyB8fCB0biA9PT0gJC5BRERSRVNTIHx8IHRuID09PSAkLkFSVElDTEUgfHwgdG4gPT09ICQuU0VDVElPTiB8fCB0biA9PT0gJC5TVU1NQVJZKVxuICAgICAgICAgICAgICAgIGFkZHJlc3NTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLkxJU1RJTkcpXG4gICAgICAgICAgICAgICAgcHJlU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5NQVJRVUVFKVxuICAgICAgICAgICAgICAgIGFwcGxldFN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuSVNJTkRFWClcbiAgICAgICAgICAgICAgICBpc2luZGV4U3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5OT0VNQkVEKVxuICAgICAgICAgICAgICAgIG5vZW1iZWRTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuICE9PSAkLkNBUFRJT04pXG4gICAgICAgICAgICAgICAgZ2VuZXJpY1N0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSA4OlxuICAgICAgICAgICAgaWYgKHRuID09PSAkLkJBU0VGT05UIHx8IHRuID09PSAkLk1FTlVJVEVNKVxuICAgICAgICAgICAgICAgIG1lbnVpdGVtU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5GUkFNRVNFVClcbiAgICAgICAgICAgICAgICBmcmFtZXNldFN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuRklFTERTRVQpXG4gICAgICAgICAgICAgICAgYWRkcmVzc1N0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuVEVYVEFSRUEpXG4gICAgICAgICAgICAgICAgdGV4dGFyZWFTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLlRFTVBMQVRFKVxuICAgICAgICAgICAgICAgIHN0YXJ0VGFnSW5IZWFkKHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuTk9TQ1JJUFQpXG4gICAgICAgICAgICAgICAgbm9lbWJlZFN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuT1BUR1JPVVApXG4gICAgICAgICAgICAgICAgb3B0Z3JvdXBTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuICE9PSAkLkNPTEdST1VQKVxuICAgICAgICAgICAgICAgIGdlbmVyaWNTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgOTpcbiAgICAgICAgICAgIGlmICh0biA9PT0gJC5QTEFJTlRFWFQpXG4gICAgICAgICAgICAgICAgcGxhaW50ZXh0U3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgZ2VuZXJpY1N0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAxMDpcbiAgICAgICAgICAgIGlmICh0biA9PT0gJC5CTE9DS1FVT1RFIHx8IHRuID09PSAkLkZJR0NBUFRJT04pXG4gICAgICAgICAgICAgICAgYWRkcmVzc1N0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGdlbmVyaWNTdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBnZW5lcmljU3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gYm9keUVuZFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIGlmIChwLm9wZW5FbGVtZW50cy5oYXNJblNjb3BlKCQuQk9EWSkpXG4gICAgICAgIHAuaW5zZXJ0aW9uTW9kZSA9IEFGVEVSX0JPRFlfTU9ERTtcblxuICAgIGVsc2VcbiAgICAgICAgdG9rZW4uaWdub3JlZCA9IHRydWU7XG59XG5cbmZ1bmN0aW9uIGh0bWxFbmRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICB2YXIgZmFrZVRva2VuID0gcC5fcHJvY2Vzc0Zha2VFbmRUYWcoJC5CT0RZKTtcblxuICAgIGlmICghZmFrZVRva2VuLmlnbm9yZWQpXG4gICAgICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG59XG5cbmZ1bmN0aW9uIGFkZHJlc3NFbmRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICB2YXIgdG4gPSB0b2tlbi50YWdOYW1lO1xuXG4gICAgaWYgKHAub3BlbkVsZW1lbnRzLmhhc0luU2NvcGUodG4pKSB7XG4gICAgICAgIHAub3BlbkVsZW1lbnRzLmdlbmVyYXRlSW1wbGllZEVuZFRhZ3MoKTtcbiAgICAgICAgcC5vcGVuRWxlbWVudHMucG9wVW50aWxUYWdOYW1lUG9wcGVkKHRuKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGZvcm1FbmRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICB2YXIgaW5UZW1wbGF0ZSA9IHAub3BlbkVsZW1lbnRzLnRtcGxDb3VudCA+IDAsXG4gICAgICAgIGZvcm1FbGVtZW50ID0gcC5mb3JtRWxlbWVudDtcblxuICAgIGlmICghaW5UZW1wbGF0ZSlcbiAgICAgICAgcC5mb3JtRWxlbWVudCA9IG51bGw7XG5cbiAgICBpZiAoKGZvcm1FbGVtZW50IHx8IGluVGVtcGxhdGUpICYmIHAub3BlbkVsZW1lbnRzLmhhc0luU2NvcGUoJC5GT1JNKSkge1xuICAgICAgICBwLm9wZW5FbGVtZW50cy5nZW5lcmF0ZUltcGxpZWRFbmRUYWdzKCk7XG5cbiAgICAgICAgaWYgKGluVGVtcGxhdGUpXG4gICAgICAgICAgICBwLm9wZW5FbGVtZW50cy5wb3BVbnRpbFRhZ05hbWVQb3BwZWQoJC5GT1JNKTtcblxuICAgICAgICBlbHNlXG4gICAgICAgICAgICBwLm9wZW5FbGVtZW50cy5yZW1vdmUoZm9ybUVsZW1lbnQpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcEVuZFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIGlmIChwLm9wZW5FbGVtZW50cy5oYXNJbkJ1dHRvblNjb3BlKCQuUCkpIHtcbiAgICAgICAgcC5vcGVuRWxlbWVudHMuZ2VuZXJhdGVJbXBsaWVkRW5kVGFnc1dpdGhFeGNsdXNpb24oJC5QKTtcbiAgICAgICAgcC5vcGVuRWxlbWVudHMucG9wVW50aWxUYWdOYW1lUG9wcGVkKCQuUCk7XG4gICAgfVxuXG4gICAgZWxzZSB7XG4gICAgICAgIHAuX3Byb2Nlc3NGYWtlU3RhcnRUYWcoJC5QKTtcbiAgICAgICAgcC5fcHJvY2Vzc1Rva2VuKHRva2VuKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGxpRW5kVGFnSW5Cb2R5KHAsIHRva2VuKSB7XG4gICAgaWYgKHAub3BlbkVsZW1lbnRzLmhhc0luTGlzdEl0ZW1TY29wZSgkLkxJKSkge1xuICAgICAgICBwLm9wZW5FbGVtZW50cy5nZW5lcmF0ZUltcGxpZWRFbmRUYWdzV2l0aEV4Y2x1c2lvbigkLkxJKTtcbiAgICAgICAgcC5vcGVuRWxlbWVudHMucG9wVW50aWxUYWdOYW1lUG9wcGVkKCQuTEkpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZGRFbmRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICB2YXIgdG4gPSB0b2tlbi50YWdOYW1lO1xuXG4gICAgaWYgKHAub3BlbkVsZW1lbnRzLmhhc0luU2NvcGUodG4pKSB7XG4gICAgICAgIHAub3BlbkVsZW1lbnRzLmdlbmVyYXRlSW1wbGllZEVuZFRhZ3NXaXRoRXhjbHVzaW9uKHRuKTtcbiAgICAgICAgcC5vcGVuRWxlbWVudHMucG9wVW50aWxUYWdOYW1lUG9wcGVkKHRuKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIG51bWJlcmVkSGVhZGVyRW5kVGFnSW5Cb2R5KHAsIHRva2VuKSB7XG4gICAgaWYgKHAub3BlbkVsZW1lbnRzLmhhc051bWJlcmVkSGVhZGVySW5TY29wZSgpKSB7XG4gICAgICAgIHAub3BlbkVsZW1lbnRzLmdlbmVyYXRlSW1wbGllZEVuZFRhZ3MoKTtcbiAgICAgICAgcC5vcGVuRWxlbWVudHMucG9wVW50aWxOdW1iZXJlZEhlYWRlclBvcHBlZCgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gYXBwbGV0RW5kVGFnSW5Cb2R5KHAsIHRva2VuKSB7XG4gICAgdmFyIHRuID0gdG9rZW4udGFnTmFtZTtcblxuICAgIGlmIChwLm9wZW5FbGVtZW50cy5oYXNJblNjb3BlKHRuKSkge1xuICAgICAgICBwLm9wZW5FbGVtZW50cy5nZW5lcmF0ZUltcGxpZWRFbmRUYWdzKCk7XG4gICAgICAgIHAub3BlbkVsZW1lbnRzLnBvcFVudGlsVGFnTmFtZVBvcHBlZCh0bik7XG4gICAgICAgIHAuYWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzLmNsZWFyVG9MYXN0TWFya2VyKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBickVuZFRhZ0luQm9keShwLCB0b2tlbikge1xuICAgIHAuX3Byb2Nlc3NGYWtlU3RhcnRUYWcoJC5CUik7XG59XG5cbmZ1bmN0aW9uIGdlbmVyaWNFbmRUYWdJbkJvZHkocCwgdG9rZW4pIHtcbiAgICB2YXIgdG4gPSB0b2tlbi50YWdOYW1lO1xuXG4gICAgZm9yICh2YXIgaSA9IHAub3BlbkVsZW1lbnRzLnN0YWNrVG9wOyBpID4gMDsgaS0tKSB7XG4gICAgICAgIHZhciBlbGVtZW50ID0gcC5vcGVuRWxlbWVudHMuaXRlbXNbaV07XG5cbiAgICAgICAgaWYgKHAudHJlZUFkYXB0ZXIuZ2V0VGFnTmFtZShlbGVtZW50KSA9PT0gdG4pIHtcbiAgICAgICAgICAgIHAub3BlbkVsZW1lbnRzLmdlbmVyYXRlSW1wbGllZEVuZFRhZ3NXaXRoRXhjbHVzaW9uKHRuKTtcbiAgICAgICAgICAgIHAub3BlbkVsZW1lbnRzLnBvcFVudGlsRWxlbWVudFBvcHBlZChlbGVtZW50KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHAuX2lzU3BlY2lhbEVsZW1lbnQoZWxlbWVudCkpXG4gICAgICAgICAgICBicmVhaztcbiAgICB9XG59XG5cbi8vT1BUSU1JWkFUSU9OOiBJbnRlZ2VyIGNvbXBhcmlzb25zIGFyZSBsb3ctY29zdCwgc28gd2UgY2FuIHVzZSB2ZXJ5IGZhc3QgdGFnIG5hbWUgbGVuZ3RoIGZpbHRlcnMgaGVyZS5cbi8vSXQncyBmYXN0ZXIgdGhhbiB1c2luZyBkaWN0aW9uYXJ5LlxuZnVuY3Rpb24gZW5kVGFnSW5Cb2R5KHAsIHRva2VuKSB7XG4gICAgdmFyIHRuID0gdG9rZW4udGFnTmFtZTtcblxuICAgIHN3aXRjaCAodG4ubGVuZ3RoKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgIGlmICh0biA9PT0gJC5BIHx8IHRuID09PSAkLkIgfHwgdG4gPT09ICQuSSB8fCB0biA9PT0gJC5TIHx8IHRuID09ICQuVSlcbiAgICAgICAgICAgICAgICBjYWxsQWRvcHRpb25BZ2VuY3kocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5QKVxuICAgICAgICAgICAgICAgIHBFbmRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgZ2VuZXJpY0VuZFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgIGlmICh0biA9PSAkLkRMIHx8IHRuID09PSAkLlVMIHx8IHRuID09PSAkLk9MKVxuICAgICAgICAgICAgICAgIGFkZHJlc3NFbmRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5MSSlcbiAgICAgICAgICAgICAgICBsaUVuZFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLkREIHx8IHRuID09PSAkLkRUKVxuICAgICAgICAgICAgICAgIGRkRW5kVGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuSDEgfHwgdG4gPT09ICQuSDIgfHwgdG4gPT09ICQuSDMgfHwgdG4gPT09ICQuSDQgfHwgdG4gPT09ICQuSDUgfHwgdG4gPT09ICQuSDYpXG4gICAgICAgICAgICAgICAgbnVtYmVyZWRIZWFkZXJFbmRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5CUilcbiAgICAgICAgICAgICAgICBickVuZFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLkVNIHx8IHRuID09PSAkLlRUKVxuICAgICAgICAgICAgICAgIGNhbGxBZG9wdGlvbkFnZW5jeShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBnZW5lcmljRW5kVGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgaWYgKHRuID09PSAkLkJJRylcbiAgICAgICAgICAgICAgICBjYWxsQWRvcHRpb25BZ2VuY3kocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5ESVIgfHwgdG4gPT09ICQuRElWIHx8IHRuID09PSAkLk5BVilcbiAgICAgICAgICAgICAgICBhZGRyZXNzRW5kVGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGdlbmVyaWNFbmRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICBpZiAodG4gPT09ICQuQk9EWSlcbiAgICAgICAgICAgICAgICBib2R5RW5kVGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuSFRNTClcbiAgICAgICAgICAgICAgICBodG1sRW5kVGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuRk9STSlcbiAgICAgICAgICAgICAgICBmb3JtRW5kVGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuQ09ERSB8fCB0biA9PT0gJC5GT05UIHx8IHRuID09PSAkLk5PQlIpXG4gICAgICAgICAgICAgICAgY2FsbEFkb3B0aW9uQWdlbmN5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuTUFJTiB8fCB0biA9PT0gJC5NRU5VKVxuICAgICAgICAgICAgICAgIGFkZHJlc3NFbmRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgZ2VuZXJpY0VuZFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgIGlmICh0biA9PT0gJC5BU0lERSlcbiAgICAgICAgICAgICAgICBhZGRyZXNzRW5kVGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuU01BTEwpXG4gICAgICAgICAgICAgICAgY2FsbEFkb3B0aW9uQWdlbmN5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGdlbmVyaWNFbmRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICBpZiAodG4gPT09ICQuQ0VOVEVSIHx8IHRuID09PSAkLkZJR1VSRSB8fCB0biA9PT0gJC5GT09URVIgfHwgdG4gPT09ICQuSEVBREVSIHx8IHRuID09PSAkLkhHUk9VUClcbiAgICAgICAgICAgICAgICBhZGRyZXNzRW5kVGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuQVBQTEVUIHx8IHRuID09PSAkLk9CSkVDVClcbiAgICAgICAgICAgICAgICBhcHBsZXRFbmRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PSAkLlNUUklLRSB8fCB0biA9PT0gJC5TVFJPTkcpXG4gICAgICAgICAgICAgICAgY2FsbEFkb3B0aW9uQWdlbmN5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGdlbmVyaWNFbmRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICBpZiAodG4gPT09ICQuQUREUkVTUyB8fCB0biA9PT0gJC5BUlRJQ0xFIHx8IHRuID09PSAkLkRFVEFJTFMgfHwgdG4gPT09ICQuU0VDVElPTiB8fCB0biA9PT0gJC5TVU1NQVJZKVxuICAgICAgICAgICAgICAgIGFkZHJlc3NFbmRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5NQVJRVUVFKVxuICAgICAgICAgICAgICAgIGFwcGxldEVuZFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBnZW5lcmljRW5kVGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSA4OlxuICAgICAgICAgICAgaWYgKHRuID09PSAkLkZJRUxEU0VUKVxuICAgICAgICAgICAgICAgIGFkZHJlc3NFbmRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5URU1QTEFURSlcbiAgICAgICAgICAgICAgICBlbmRUYWdJbkhlYWQocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgZ2VuZXJpY0VuZFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgMTA6XG4gICAgICAgICAgICBpZiAodG4gPT09ICQuQkxPQ0tRVU9URSB8fCB0biA9PT0gJC5GSUdDQVBUSU9OKVxuICAgICAgICAgICAgICAgIGFkZHJlc3NFbmRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgZ2VuZXJpY0VuZFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQgOlxuICAgICAgICAgICAgZ2VuZXJpY0VuZFRhZ0luQm9keShwLCB0b2tlbik7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBlb2ZJbkJvZHkocCwgdG9rZW4pIHtcbiAgICBpZiAocC50bXBsSW5zZXJ0aW9uTW9kZVN0YWNrVG9wID4gLTEpXG4gICAgICAgIGVvZkluVGVtcGxhdGUocCwgdG9rZW4pO1xuXG4gICAgZWxzZVxuICAgICAgICBwLnN0b3BwZWQgPSB0cnVlO1xufVxuXG4vLzEyLjIuNS40LjggVGhlIFwidGV4dFwiIGluc2VydGlvbiBtb2RlXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZnVuY3Rpb24gZW5kVGFnSW5UZXh0KHAsIHRva2VuKSB7XG4gICAgaWYgKCFwLmZyYWdtZW50Q29udGV4dCAmJiBwLnNjcmlwdEhhbmRsZXIgJiYgdG9rZW4udGFnTmFtZSA9PT0gJC5TQ1JJUFQpXG4gICAgICAgIHAuc2NyaXB0SGFuZGxlcihwLmRvY3VtZW50LCBwLm9wZW5FbGVtZW50cy5jdXJyZW50KTtcblxuICAgIHAub3BlbkVsZW1lbnRzLnBvcCgpO1xuICAgIHAuaW5zZXJ0aW9uTW9kZSA9IHAub3JpZ2luYWxJbnNlcnRpb25Nb2RlO1xufVxuXG5cbmZ1bmN0aW9uIGVvZkluVGV4dChwLCB0b2tlbikge1xuICAgIHAub3BlbkVsZW1lbnRzLnBvcCgpO1xuICAgIHAuaW5zZXJ0aW9uTW9kZSA9IHAub3JpZ2luYWxJbnNlcnRpb25Nb2RlO1xuICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG59XG5cblxuLy8xMi4yLjUuNC45IFRoZSBcImluIHRhYmxlXCIgaW5zZXJ0aW9uIG1vZGVcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBjaGFyYWN0ZXJJblRhYmxlKHAsIHRva2VuKSB7XG4gICAgdmFyIGN1clRuID0gcC5vcGVuRWxlbWVudHMuY3VycmVudFRhZ05hbWU7XG5cbiAgICBpZiAoY3VyVG4gPT09ICQuVEFCTEUgfHwgY3VyVG4gPT09ICQuVEJPRFkgfHwgY3VyVG4gPT09ICQuVEZPT1QgfHwgY3VyVG4gPT09ICQuVEhFQUQgfHwgY3VyVG4gPT09ICQuVFIpIHtcbiAgICAgICAgcC5wZW5kaW5nQ2hhcmFjdGVyVG9rZW5zID0gW107XG4gICAgICAgIHAuaGFzTm9uV2hpdGVzcGFjZVBlbmRpbmdDaGFyYWN0ZXJUb2tlbiA9IGZhbHNlO1xuICAgICAgICBwLm9yaWdpbmFsSW5zZXJ0aW9uTW9kZSA9IHAuaW5zZXJ0aW9uTW9kZTtcbiAgICAgICAgcC5pbnNlcnRpb25Nb2RlID0gSU5fVEFCTEVfVEVYVF9NT0RFO1xuICAgICAgICBwLl9wcm9jZXNzVG9rZW4odG9rZW4pO1xuICAgIH1cblxuICAgIGVsc2VcbiAgICAgICAgdG9rZW5JblRhYmxlKHAsIHRva2VuKTtcbn1cblxuZnVuY3Rpb24gY2FwdGlvblN0YXJ0VGFnSW5UYWJsZShwLCB0b2tlbikge1xuICAgIHAub3BlbkVsZW1lbnRzLmNsZWFyQmFja1RvVGFibGVDb250ZXh0KCk7XG4gICAgcC5hY3RpdmVGb3JtYXR0aW5nRWxlbWVudHMuaW5zZXJ0TWFya2VyKCk7XG4gICAgcC5faW5zZXJ0RWxlbWVudCh0b2tlbiwgTlMuSFRNTCk7XG4gICAgcC5pbnNlcnRpb25Nb2RlID0gSU5fQ0FQVElPTl9NT0RFO1xufVxuXG5mdW5jdGlvbiBjb2xncm91cFN0YXJ0VGFnSW5UYWJsZShwLCB0b2tlbikge1xuICAgIHAub3BlbkVsZW1lbnRzLmNsZWFyQmFja1RvVGFibGVDb250ZXh0KCk7XG4gICAgcC5faW5zZXJ0RWxlbWVudCh0b2tlbiwgTlMuSFRNTCk7XG4gICAgcC5pbnNlcnRpb25Nb2RlID0gSU5fQ09MVU1OX0dST1VQX01PREU7XG59XG5cbmZ1bmN0aW9uIGNvbFN0YXJ0VGFnSW5UYWJsZShwLCB0b2tlbikge1xuICAgIHAuX3Byb2Nlc3NGYWtlU3RhcnRUYWcoJC5DT0xHUk9VUCk7XG4gICAgcC5fcHJvY2Vzc1Rva2VuKHRva2VuKTtcbn1cblxuZnVuY3Rpb24gdGJvZHlTdGFydFRhZ0luVGFibGUocCwgdG9rZW4pIHtcbiAgICBwLm9wZW5FbGVtZW50cy5jbGVhckJhY2tUb1RhYmxlQ29udGV4dCgpO1xuICAgIHAuX2luc2VydEVsZW1lbnQodG9rZW4sIE5TLkhUTUwpO1xuICAgIHAuaW5zZXJ0aW9uTW9kZSA9IElOX1RBQkxFX0JPRFlfTU9ERTtcbn1cblxuZnVuY3Rpb24gdGRTdGFydFRhZ0luVGFibGUocCwgdG9rZW4pIHtcbiAgICBwLl9wcm9jZXNzRmFrZVN0YXJ0VGFnKCQuVEJPRFkpO1xuICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG59XG5cbmZ1bmN0aW9uIHRhYmxlU3RhcnRUYWdJblRhYmxlKHAsIHRva2VuKSB7XG4gICAgdmFyIGZha2VUb2tlbiA9IHAuX3Byb2Nlc3NGYWtlRW5kVGFnKCQuVEFCTEUpO1xuXG4gICAgLy9OT1RFOiBUaGUgZmFrZSBlbmQgdGFnIHRva2VuIGhlcmUgY2FuIG9ubHkgYmUgaWdub3JlZCBpbiB0aGUgZnJhZ21lbnQgY2FzZS5cbiAgICBpZiAoIWZha2VUb2tlbi5pZ25vcmVkKVxuICAgICAgICBwLl9wcm9jZXNzVG9rZW4odG9rZW4pO1xufVxuXG5mdW5jdGlvbiBpbnB1dFN0YXJ0VGFnSW5UYWJsZShwLCB0b2tlbikge1xuICAgIHZhciBpbnB1dFR5cGUgPSBUb2tlbml6ZXIuZ2V0VG9rZW5BdHRyKHRva2VuLCBBVFRSUy5UWVBFKTtcblxuICAgIGlmIChpbnB1dFR5cGUgJiYgaW5wdXRUeXBlLnRvTG93ZXJDYXNlKCkgPT09IEhJRERFTl9JTlBVVF9UWVBFKVxuICAgICAgICBwLl9hcHBlbmRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcblxuICAgIGVsc2VcbiAgICAgICAgdG9rZW5JblRhYmxlKHAsIHRva2VuKTtcbn1cblxuZnVuY3Rpb24gZm9ybVN0YXJ0VGFnSW5UYWJsZShwLCB0b2tlbikge1xuICAgIGlmICghcC5mb3JtRWxlbWVudCAmJiBwLm9wZW5FbGVtZW50cy50bXBsQ291bnQgPT09IDApIHtcbiAgICAgICAgcC5faW5zZXJ0RWxlbWVudCh0b2tlbiwgTlMuSFRNTCk7XG4gICAgICAgIHAuZm9ybUVsZW1lbnQgPSBwLm9wZW5FbGVtZW50cy5jdXJyZW50O1xuICAgICAgICBwLm9wZW5FbGVtZW50cy5wb3AoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHN0YXJ0VGFnSW5UYWJsZShwLCB0b2tlbikge1xuICAgIHZhciB0biA9IHRva2VuLnRhZ05hbWU7XG5cbiAgICBzd2l0Y2ggKHRuLmxlbmd0aCkge1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICBpZiAodG4gPT09ICQuVEQgfHwgdG4gPT09ICQuVEggfHwgdG4gPT09ICQuVFIpXG4gICAgICAgICAgICAgICAgdGRTdGFydFRhZ0luVGFibGUocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdG9rZW5JblRhYmxlKHAsIHRva2VuKTtcblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgaWYgKHRuID09PSAkLkNPTClcbiAgICAgICAgICAgICAgICBjb2xTdGFydFRhZ0luVGFibGUocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdG9rZW5JblRhYmxlKHAsIHRva2VuKTtcblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgaWYgKHRuID09PSAkLkZPUk0pXG4gICAgICAgICAgICAgICAgZm9ybVN0YXJ0VGFnSW5UYWJsZShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICB0b2tlbkluVGFibGUocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICBpZiAodG4gPT09ICQuVEFCTEUpXG4gICAgICAgICAgICAgICAgdGFibGVTdGFydFRhZ0luVGFibGUocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlIGlmICh0biA9PT0gJC5TVFlMRSlcbiAgICAgICAgICAgICAgICBzdGFydFRhZ0luSGVhZChwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLlRCT0RZIHx8IHRuID09PSAkLlRGT09UIHx8IHRuID09PSAkLlRIRUFEKVxuICAgICAgICAgICAgICAgIHRib2R5U3RhcnRUYWdJblRhYmxlKHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZSBpZiAodG4gPT09ICQuSU5QVVQpXG4gICAgICAgICAgICAgICAgaW5wdXRTdGFydFRhZ0luVGFibGUocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdG9rZW5JblRhYmxlKHAsIHRva2VuKTtcblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgaWYgKHRuID09PSAkLlNDUklQVClcbiAgICAgICAgICAgICAgICBzdGFydFRhZ0luSGVhZChwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICB0b2tlbkluVGFibGUocCwgdG9rZW4pO1xuXG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICBpZiAodG4gPT09ICQuQ0FQVElPTilcbiAgICAgICAgICAgICAgICBjYXB0aW9uU3RhcnRUYWdJblRhYmxlKHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHRva2VuSW5UYWJsZShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgODpcbiAgICAgICAgICAgIGlmICh0biA9PT0gJC5DT0xHUk9VUClcbiAgICAgICAgICAgICAgICBjb2xncm91cFN0YXJ0VGFnSW5UYWJsZShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKHRuID09PSAkLlRFTVBMQVRFKVxuICAgICAgICAgICAgICAgIHN0YXJ0VGFnSW5IZWFkKHAsIHRva2VuKTtcblxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHRva2VuSW5UYWJsZShwLCB0b2tlbik7XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0b2tlbkluVGFibGUocCwgdG9rZW4pO1xuICAgIH1cblxufVxuXG5mdW5jdGlvbiBlbmRUYWdJblRhYmxlKHAsIHRva2VuKSB7XG4gICAgdmFyIHRuID0gdG9rZW4udGFnTmFtZTtcblxuICAgIGlmICh0biA9PT0gJC5UQUJMRSkge1xuICAgICAgICBpZiAocC5vcGVuRWxlbWVudHMuaGFzSW5UYWJsZVNjb3BlKCQuVEFCTEUpKSB7XG4gICAgICAgICAgICBwLm9wZW5FbGVtZW50cy5wb3BVbnRpbFRhZ05hbWVQb3BwZWQoJC5UQUJMRSk7XG4gICAgICAgICAgICBwLl9yZXNldEluc2VydGlvbk1vZGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRva2VuLmlnbm9yZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGVsc2UgaWYgKHRuID09PSAkLlRFTVBMQVRFKVxuICAgICAgICBlbmRUYWdJbkhlYWQocCwgdG9rZW4pO1xuXG4gICAgZWxzZSBpZiAodG4gIT09ICQuQk9EWSAmJiB0biAhPT0gJC5DQVBUSU9OICYmIHRuICE9PSAkLkNPTCAmJiB0biAhPT0gJC5DT0xHUk9VUCAmJiB0biAhPT0gJC5IVE1MICYmXG4gICAgICAgICAgICAgdG4gIT09ICQuVEJPRFkgJiYgdG4gIT09ICQuVEQgJiYgdG4gIT09ICQuVEZPT1QgJiYgdG4gIT09ICQuVEggJiYgdG4gIT09ICQuVEhFQUQgJiYgdG4gIT09ICQuVFIpIHtcbiAgICAgICAgdG9rZW5JblRhYmxlKHAsIHRva2VuKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRva2VuSW5UYWJsZShwLCB0b2tlbikge1xuICAgIHZhciBzYXZlZEZvc3RlclBhcmVudGluZ1N0YXRlID0gcC5mb3N0ZXJQYXJlbnRpbmdFbmFibGVkO1xuXG4gICAgcC5mb3N0ZXJQYXJlbnRpbmdFbmFibGVkID0gdHJ1ZTtcbiAgICBwLl9wcm9jZXNzVG9rZW5JbkJvZHlNb2RlKHRva2VuKTtcbiAgICBwLmZvc3RlclBhcmVudGluZ0VuYWJsZWQgPSBzYXZlZEZvc3RlclBhcmVudGluZ1N0YXRlO1xufVxuXG5cbi8vMTIuMi41LjQuMTAgVGhlIFwiaW4gdGFibGUgdGV4dFwiIGluc2VydGlvbiBtb2RlXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZnVuY3Rpb24gd2hpdGVzcGFjZUNoYXJhY3RlckluVGFibGVUZXh0KHAsIHRva2VuKSB7XG4gICAgcC5wZW5kaW5nQ2hhcmFjdGVyVG9rZW5zLnB1c2godG9rZW4pO1xufVxuXG5mdW5jdGlvbiBjaGFyYWN0ZXJJblRhYmxlVGV4dChwLCB0b2tlbikge1xuICAgIHAucGVuZGluZ0NoYXJhY3RlclRva2Vucy5wdXNoKHRva2VuKTtcbiAgICBwLmhhc05vbldoaXRlc3BhY2VQZW5kaW5nQ2hhcmFjdGVyVG9rZW4gPSB0cnVlO1xufVxuXG5mdW5jdGlvbiB0b2tlbkluVGFibGVUZXh0KHAsIHRva2VuKSB7XG4gICAgaWYgKHAuaGFzTm9uV2hpdGVzcGFjZVBlbmRpbmdDaGFyYWN0ZXJUb2tlbikge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHAucGVuZGluZ0NoYXJhY3RlclRva2Vucy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIHRva2VuSW5UYWJsZShwLCBwLnBlbmRpbmdDaGFyYWN0ZXJUb2tlbnNbaV0pO1xuICAgIH1cblxuICAgIGVsc2Uge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHAucGVuZGluZ0NoYXJhY3RlclRva2Vucy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIHAuX2luc2VydENoYXJhY3RlcnMocC5wZW5kaW5nQ2hhcmFjdGVyVG9rZW5zW2ldKTtcbiAgICB9XG5cbiAgICBwLmluc2VydGlvbk1vZGUgPSBwLm9yaWdpbmFsSW5zZXJ0aW9uTW9kZTtcbiAgICBwLl9wcm9jZXNzVG9rZW4odG9rZW4pO1xufVxuXG5cbi8vMTIuMi41LjQuMTEgVGhlIFwiaW4gY2FwdGlvblwiIGluc2VydGlvbiBtb2RlXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZnVuY3Rpb24gc3RhcnRUYWdJbkNhcHRpb24ocCwgdG9rZW4pIHtcbiAgICB2YXIgdG4gPSB0b2tlbi50YWdOYW1lO1xuXG4gICAgaWYgKHRuID09PSAkLkNBUFRJT04gfHwgdG4gPT09ICQuQ09MIHx8IHRuID09PSAkLkNPTEdST1VQIHx8IHRuID09PSAkLlRCT0RZIHx8XG4gICAgICAgIHRuID09PSAkLlREIHx8IHRuID09PSAkLlRGT09UIHx8IHRuID09PSAkLlRIIHx8IHRuID09PSAkLlRIRUFEIHx8IHRuID09PSAkLlRSKSB7XG4gICAgICAgIHZhciBmYWtlVG9rZW4gPSBwLl9wcm9jZXNzRmFrZUVuZFRhZygkLkNBUFRJT04pO1xuXG4gICAgICAgIC8vTk9URTogVGhlIGZha2UgZW5kIHRhZyB0b2tlbiBoZXJlIGNhbiBvbmx5IGJlIGlnbm9yZWQgaW4gdGhlIGZyYWdtZW50IGNhc2UuXG4gICAgICAgIGlmICghZmFrZVRva2VuLmlnbm9yZWQpXG4gICAgICAgICAgICBwLl9wcm9jZXNzVG9rZW4odG9rZW4pO1xuICAgIH1cblxuICAgIGVsc2VcbiAgICAgICAgc3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xufVxuXG5mdW5jdGlvbiBlbmRUYWdJbkNhcHRpb24ocCwgdG9rZW4pIHtcbiAgICB2YXIgdG4gPSB0b2tlbi50YWdOYW1lO1xuXG4gICAgaWYgKHRuID09PSAkLkNBUFRJT04pIHtcbiAgICAgICAgaWYgKHAub3BlbkVsZW1lbnRzLmhhc0luVGFibGVTY29wZSgkLkNBUFRJT04pKSB7XG4gICAgICAgICAgICBwLm9wZW5FbGVtZW50cy5nZW5lcmF0ZUltcGxpZWRFbmRUYWdzKCk7XG4gICAgICAgICAgICBwLm9wZW5FbGVtZW50cy5wb3BVbnRpbFRhZ05hbWVQb3BwZWQoJC5DQVBUSU9OKTtcbiAgICAgICAgICAgIHAuYWN0aXZlRm9ybWF0dGluZ0VsZW1lbnRzLmNsZWFyVG9MYXN0TWFya2VyKCk7XG4gICAgICAgICAgICBwLmluc2VydGlvbk1vZGUgPSBJTl9UQUJMRV9NT0RFO1xuICAgICAgICB9XG5cbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdG9rZW4uaWdub3JlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgZWxzZSBpZiAodG4gPT09ICQuVEFCTEUpIHtcbiAgICAgICAgdmFyIGZha2VUb2tlbiA9IHAuX3Byb2Nlc3NGYWtlRW5kVGFnKCQuQ0FQVElPTik7XG5cbiAgICAgICAgLy9OT1RFOiBUaGUgZmFrZSBlbmQgdGFnIHRva2VuIGhlcmUgY2FuIG9ubHkgYmUgaWdub3JlZCBpbiB0aGUgZnJhZ21lbnQgY2FzZS5cbiAgICAgICAgaWYgKCFmYWtlVG9rZW4uaWdub3JlZClcbiAgICAgICAgICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG4gICAgfVxuXG4gICAgZWxzZSBpZiAodG4gIT09ICQuQk9EWSAmJiB0biAhPT0gJC5DT0wgJiYgdG4gIT09ICQuQ09MR1JPVVAgJiYgdG4gIT09ICQuSFRNTCAmJiB0biAhPT0gJC5UQk9EWSAmJlxuICAgICAgICAgICAgIHRuICE9PSAkLlREICYmIHRuICE9PSAkLlRGT09UICYmIHRuICE9PSAkLlRIICYmIHRuICE9PSAkLlRIRUFEICYmIHRuICE9PSAkLlRSKSB7XG4gICAgICAgIGVuZFRhZ0luQm9keShwLCB0b2tlbik7XG4gICAgfVxufVxuXG5cbi8vMTIuMi41LjQuMTIgVGhlIFwiaW4gY29sdW1uIGdyb3VwXCIgaW5zZXJ0aW9uIG1vZGVcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBzdGFydFRhZ0luQ29sdW1uR3JvdXAocCwgdG9rZW4pIHtcbiAgICB2YXIgdG4gPSB0b2tlbi50YWdOYW1lO1xuXG4gICAgaWYgKHRuID09PSAkLkhUTUwpXG4gICAgICAgIHN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgIGVsc2UgaWYgKHRuID09PSAkLkNPTClcbiAgICAgICAgcC5fYXBwZW5kRWxlbWVudCh0b2tlbiwgTlMuSFRNTCk7XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5URU1QTEFURSlcbiAgICAgICAgc3RhcnRUYWdJbkhlYWQocCwgdG9rZW4pO1xuXG4gICAgZWxzZVxuICAgICAgICB0b2tlbkluQ29sdW1uR3JvdXAocCwgdG9rZW4pO1xufVxuXG5mdW5jdGlvbiBlbmRUYWdJbkNvbHVtbkdyb3VwKHAsIHRva2VuKSB7XG4gICAgdmFyIHRuID0gdG9rZW4udGFnTmFtZTtcblxuICAgIGlmICh0biA9PT0gJC5DT0xHUk9VUCkge1xuICAgICAgICBpZiAocC5vcGVuRWxlbWVudHMuY3VycmVudFRhZ05hbWUgIT09ICQuQ09MR1JPVVApXG4gICAgICAgICAgICB0b2tlbi5pZ25vcmVkID0gdHJ1ZTtcblxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHAub3BlbkVsZW1lbnRzLnBvcCgpO1xuICAgICAgICAgICAgcC5pbnNlcnRpb25Nb2RlID0gSU5fVEFCTEVfTU9ERTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGVsc2UgaWYgKHRuID09PSAkLlRFTVBMQVRFKVxuICAgICAgICBlbmRUYWdJbkhlYWQocCwgdG9rZW4pO1xuXG4gICAgZWxzZSBpZiAodG4gIT09ICQuQ09MKVxuICAgICAgICB0b2tlbkluQ29sdW1uR3JvdXAocCwgdG9rZW4pO1xufVxuXG5mdW5jdGlvbiB0b2tlbkluQ29sdW1uR3JvdXAocCwgdG9rZW4pIHtcbiAgICB2YXIgZmFrZVRva2VuID0gcC5fcHJvY2Vzc0Zha2VFbmRUYWcoJC5DT0xHUk9VUCk7XG5cbiAgICAvL05PVEU6IFRoZSBmYWtlIGVuZCB0YWcgdG9rZW4gaGVyZSBjYW4gb25seSBiZSBpZ25vcmVkIGluIHRoZSBmcmFnbWVudCBjYXNlLlxuICAgIGlmICghZmFrZVRva2VuLmlnbm9yZWQpXG4gICAgICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG59XG5cbi8vMTIuMi41LjQuMTMgVGhlIFwiaW4gdGFibGUgYm9keVwiIGluc2VydGlvbiBtb2RlXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZnVuY3Rpb24gc3RhcnRUYWdJblRhYmxlQm9keShwLCB0b2tlbikge1xuICAgIHZhciB0biA9IHRva2VuLnRhZ05hbWU7XG5cbiAgICBpZiAodG4gPT09ICQuVFIpIHtcbiAgICAgICAgcC5vcGVuRWxlbWVudHMuY2xlYXJCYWNrVG9UYWJsZUJvZHlDb250ZXh0KCk7XG4gICAgICAgIHAuX2luc2VydEVsZW1lbnQodG9rZW4sIE5TLkhUTUwpO1xuICAgICAgICBwLmluc2VydGlvbk1vZGUgPSBJTl9ST1dfTU9ERTtcbiAgICB9XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5USCB8fCB0biA9PT0gJC5URCkge1xuICAgICAgICBwLl9wcm9jZXNzRmFrZVN0YXJ0VGFnKCQuVFIpO1xuICAgICAgICBwLl9wcm9jZXNzVG9rZW4odG9rZW4pO1xuICAgIH1cblxuICAgIGVsc2UgaWYgKHRuID09PSAkLkNBUFRJT04gfHwgdG4gPT09ICQuQ09MIHx8IHRuID09PSAkLkNPTEdST1VQIHx8XG4gICAgICAgICAgICAgdG4gPT09ICQuVEJPRFkgfHwgdG4gPT09ICQuVEZPT1QgfHwgdG4gPT09ICQuVEhFQUQpIHtcblxuICAgICAgICBpZiAocC5vcGVuRWxlbWVudHMuaGFzVGFibGVCb2R5Q29udGV4dEluVGFibGVTY29wZSgpKSB7XG4gICAgICAgICAgICBwLm9wZW5FbGVtZW50cy5jbGVhckJhY2tUb1RhYmxlQm9keUNvbnRleHQoKTtcbiAgICAgICAgICAgIHAuX3Byb2Nlc3NGYWtlRW5kVGFnKHAub3BlbkVsZW1lbnRzLmN1cnJlbnRUYWdOYW1lKTtcbiAgICAgICAgICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbHNlXG4gICAgICAgIHN0YXJ0VGFnSW5UYWJsZShwLCB0b2tlbik7XG59XG5cbmZ1bmN0aW9uIGVuZFRhZ0luVGFibGVCb2R5KHAsIHRva2VuKSB7XG4gICAgdmFyIHRuID0gdG9rZW4udGFnTmFtZTtcblxuICAgIGlmICh0biA9PT0gJC5UQk9EWSB8fCB0biA9PT0gJC5URk9PVCB8fCB0biA9PT0gJC5USEVBRCkge1xuICAgICAgICBpZiAocC5vcGVuRWxlbWVudHMuaGFzSW5UYWJsZVNjb3BlKHRuKSkge1xuICAgICAgICAgICAgcC5vcGVuRWxlbWVudHMuY2xlYXJCYWNrVG9UYWJsZUJvZHlDb250ZXh0KCk7XG4gICAgICAgICAgICBwLm9wZW5FbGVtZW50cy5wb3AoKTtcbiAgICAgICAgICAgIHAuaW5zZXJ0aW9uTW9kZSA9IElOX1RBQkxFX01PREU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5UQUJMRSkge1xuICAgICAgICBpZiAocC5vcGVuRWxlbWVudHMuaGFzVGFibGVCb2R5Q29udGV4dEluVGFibGVTY29wZSgpKSB7XG4gICAgICAgICAgICBwLm9wZW5FbGVtZW50cy5jbGVhckJhY2tUb1RhYmxlQm9keUNvbnRleHQoKTtcbiAgICAgICAgICAgIHAuX3Byb2Nlc3NGYWtlRW5kVGFnKHAub3BlbkVsZW1lbnRzLmN1cnJlbnRUYWdOYW1lKTtcbiAgICAgICAgICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbHNlIGlmICh0biAhPT0gJC5CT0RZICYmIHRuICE9PSAkLkNBUFRJT04gJiYgdG4gIT09ICQuQ09MICYmIHRuICE9PSAkLkNPTEdST1VQIHx8XG4gICAgICAgICAgICAgdG4gIT09ICQuSFRNTCAmJiB0biAhPT0gJC5URCAmJiB0biAhPT0gJC5USCAmJiB0biAhPT0gJC5UUikge1xuICAgICAgICBlbmRUYWdJblRhYmxlKHAsIHRva2VuKTtcbiAgICB9XG59XG5cbi8vMTIuMi41LjQuMTQgVGhlIFwiaW4gcm93XCIgaW5zZXJ0aW9uIG1vZGVcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBzdGFydFRhZ0luUm93KHAsIHRva2VuKSB7XG4gICAgdmFyIHRuID0gdG9rZW4udGFnTmFtZTtcblxuICAgIGlmICh0biA9PT0gJC5USCB8fCB0biA9PT0gJC5URCkge1xuICAgICAgICBwLm9wZW5FbGVtZW50cy5jbGVhckJhY2tUb1RhYmxlUm93Q29udGV4dCgpO1xuICAgICAgICBwLl9pbnNlcnRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcbiAgICAgICAgcC5pbnNlcnRpb25Nb2RlID0gSU5fQ0VMTF9NT0RFO1xuICAgICAgICBwLmFjdGl2ZUZvcm1hdHRpbmdFbGVtZW50cy5pbnNlcnRNYXJrZXIoKTtcbiAgICB9XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5DQVBUSU9OIHx8IHRuID09PSAkLkNPTCB8fCB0biA9PT0gJC5DT0xHUk9VUCB8fCB0biA9PT0gJC5UQk9EWSB8fFxuICAgICAgICAgICAgIHRuID09PSAkLlRGT09UIHx8IHRuID09PSAkLlRIRUFEIHx8IHRuID09PSAkLlRSKSB7XG4gICAgICAgIHZhciBmYWtlVG9rZW4gPSBwLl9wcm9jZXNzRmFrZUVuZFRhZygkLlRSKTtcblxuICAgICAgICAvL05PVEU6IFRoZSBmYWtlIGVuZCB0YWcgdG9rZW4gaGVyZSBjYW4gb25seSBiZSBpZ25vcmVkIGluIHRoZSBmcmFnbWVudCBjYXNlLlxuICAgICAgICBpZiAoIWZha2VUb2tlbi5pZ25vcmVkKVxuICAgICAgICAgICAgcC5fcHJvY2Vzc1Rva2VuKHRva2VuKTtcbiAgICB9XG5cbiAgICBlbHNlXG4gICAgICAgIHN0YXJ0VGFnSW5UYWJsZShwLCB0b2tlbik7XG59XG5cbmZ1bmN0aW9uIGVuZFRhZ0luUm93KHAsIHRva2VuKSB7XG4gICAgdmFyIHRuID0gdG9rZW4udGFnTmFtZTtcblxuICAgIGlmICh0biA9PT0gJC5UUikge1xuICAgICAgICBpZiAocC5vcGVuRWxlbWVudHMuaGFzSW5UYWJsZVNjb3BlKCQuVFIpKSB7XG4gICAgICAgICAgICBwLm9wZW5FbGVtZW50cy5jbGVhckJhY2tUb1RhYmxlUm93Q29udGV4dCgpO1xuICAgICAgICAgICAgcC5vcGVuRWxlbWVudHMucG9wKCk7XG4gICAgICAgICAgICBwLmluc2VydGlvbk1vZGUgPSBJTl9UQUJMRV9CT0RZX01PREU7XG4gICAgICAgIH1cblxuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0b2tlbi5pZ25vcmVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5UQUJMRSkge1xuICAgICAgICB2YXIgZmFrZVRva2VuID0gcC5fcHJvY2Vzc0Zha2VFbmRUYWcoJC5UUik7XG5cbiAgICAgICAgLy9OT1RFOiBUaGUgZmFrZSBlbmQgdGFnIHRva2VuIGhlcmUgY2FuIG9ubHkgYmUgaWdub3JlZCBpbiB0aGUgZnJhZ21lbnQgY2FzZS5cbiAgICAgICAgaWYgKCFmYWtlVG9rZW4uaWdub3JlZClcbiAgICAgICAgICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG4gICAgfVxuXG4gICAgZWxzZSBpZiAodG4gPT09ICQuVEJPRFkgfHwgdG4gPT09ICQuVEZPT1QgfHwgdG4gPT09ICQuVEhFQUQpIHtcbiAgICAgICAgaWYgKHAub3BlbkVsZW1lbnRzLmhhc0luVGFibGVTY29wZSh0bikpIHtcbiAgICAgICAgICAgIHAuX3Byb2Nlc3NGYWtlRW5kVGFnKCQuVFIpO1xuICAgICAgICAgICAgcC5fcHJvY2Vzc1Rva2VuKHRva2VuKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGVsc2UgaWYgKHRuICE9PSAkLkJPRFkgJiYgdG4gIT09ICQuQ0FQVElPTiAmJiB0biAhPT0gJC5DT0wgJiYgdG4gIT09ICQuQ09MR1JPVVAgfHxcbiAgICAgICAgICAgICB0biAhPT0gJC5IVE1MICYmIHRuICE9PSAkLlREICYmIHRuICE9PSAkLlRIKSB7XG4gICAgICAgIGVuZFRhZ0luVGFibGUocCwgdG9rZW4pO1xuICAgIH1cbn1cblxuXG4vLzEyLjIuNS40LjE1IFRoZSBcImluIGNlbGxcIiBpbnNlcnRpb24gbW9kZVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIHN0YXJ0VGFnSW5DZWxsKHAsIHRva2VuKSB7XG4gICAgdmFyIHRuID0gdG9rZW4udGFnTmFtZTtcblxuICAgIGlmICh0biA9PT0gJC5DQVBUSU9OIHx8IHRuID09PSAkLkNPTCB8fCB0biA9PT0gJC5DT0xHUk9VUCB8fCB0biA9PT0gJC5UQk9EWSB8fFxuICAgICAgICB0biA9PT0gJC5URCB8fCB0biA9PT0gJC5URk9PVCB8fCB0biA9PT0gJC5USCB8fCB0biA9PT0gJC5USEVBRCB8fCB0biA9PT0gJC5UUikge1xuXG4gICAgICAgIGlmIChwLm9wZW5FbGVtZW50cy5oYXNJblRhYmxlU2NvcGUoJC5URCkgfHwgcC5vcGVuRWxlbWVudHMuaGFzSW5UYWJsZVNjb3BlKCQuVEgpKSB7XG4gICAgICAgICAgICBwLl9jbG9zZVRhYmxlQ2VsbCgpO1xuICAgICAgICAgICAgcC5fcHJvY2Vzc1Rva2VuKHRva2VuKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGVsc2VcbiAgICAgICAgc3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xufVxuXG5mdW5jdGlvbiBlbmRUYWdJbkNlbGwocCwgdG9rZW4pIHtcbiAgICB2YXIgdG4gPSB0b2tlbi50YWdOYW1lO1xuXG4gICAgaWYgKHRuID09PSAkLlREIHx8IHRuID09PSAkLlRIKSB7XG4gICAgICAgIGlmIChwLm9wZW5FbGVtZW50cy5oYXNJblRhYmxlU2NvcGUodG4pKSB7XG4gICAgICAgICAgICBwLm9wZW5FbGVtZW50cy5nZW5lcmF0ZUltcGxpZWRFbmRUYWdzKCk7XG4gICAgICAgICAgICBwLm9wZW5FbGVtZW50cy5wb3BVbnRpbFRhZ05hbWVQb3BwZWQodG4pO1xuICAgICAgICAgICAgcC5hY3RpdmVGb3JtYXR0aW5nRWxlbWVudHMuY2xlYXJUb0xhc3RNYXJrZXIoKTtcbiAgICAgICAgICAgIHAuaW5zZXJ0aW9uTW9kZSA9IElOX1JPV19NT0RFO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZWxzZSBpZiAodG4gPT09ICQuVEFCTEUgfHwgdG4gPT09ICQuVEJPRFkgfHwgdG4gPT09ICQuVEZPT1QgfHwgdG4gPT09ICQuVEhFQUQgfHwgdG4gPT09ICQuVFIpIHtcbiAgICAgICAgaWYgKHAub3BlbkVsZW1lbnRzLmhhc0luVGFibGVTY29wZSh0bikpIHtcbiAgICAgICAgICAgIHAuX2Nsb3NlVGFibGVDZWxsKCk7XG4gICAgICAgICAgICBwLl9wcm9jZXNzVG9rZW4odG9rZW4pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZWxzZSBpZiAodG4gIT09ICQuQk9EWSAmJiB0biAhPT0gJC5DQVBUSU9OICYmIHRuICE9PSAkLkNPTCAmJiB0biAhPT0gJC5DT0xHUk9VUCAmJiB0biAhPT0gJC5IVE1MKVxuICAgICAgICBlbmRUYWdJbkJvZHkocCwgdG9rZW4pO1xufVxuXG4vLzEyLjIuNS40LjE2IFRoZSBcImluIHNlbGVjdFwiIGluc2VydGlvbiBtb2RlXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZnVuY3Rpb24gc3RhcnRUYWdJblNlbGVjdChwLCB0b2tlbikge1xuICAgIHZhciB0biA9IHRva2VuLnRhZ05hbWU7XG5cbiAgICBpZiAodG4gPT09ICQuSFRNTClcbiAgICAgICAgc3RhcnRUYWdJbkJvZHkocCwgdG9rZW4pO1xuXG4gICAgZWxzZSBpZiAodG4gPT09ICQuT1BUSU9OKSB7XG4gICAgICAgIGlmIChwLm9wZW5FbGVtZW50cy5jdXJyZW50VGFnTmFtZSA9PT0gJC5PUFRJT04pXG4gICAgICAgICAgICBwLl9wcm9jZXNzRmFrZUVuZFRhZygkLk9QVElPTik7XG5cbiAgICAgICAgcC5faW5zZXJ0RWxlbWVudCh0b2tlbiwgTlMuSFRNTCk7XG4gICAgfVxuXG4gICAgZWxzZSBpZiAodG4gPT09ICQuT1BUR1JPVVApIHtcbiAgICAgICAgaWYgKHAub3BlbkVsZW1lbnRzLmN1cnJlbnRUYWdOYW1lID09PSAkLk9QVElPTilcbiAgICAgICAgICAgIHAuX3Byb2Nlc3NGYWtlRW5kVGFnKCQuT1BUSU9OKTtcblxuICAgICAgICBpZiAocC5vcGVuRWxlbWVudHMuY3VycmVudFRhZ05hbWUgPT09ICQuT1BUR1JPVVApXG4gICAgICAgICAgICBwLl9wcm9jZXNzRmFrZUVuZFRhZygkLk9QVEdST1VQKTtcblxuICAgICAgICBwLl9pbnNlcnRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcbiAgICB9XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5TRUxFQ1QpXG4gICAgICAgIHAuX3Byb2Nlc3NGYWtlRW5kVGFnKCQuU0VMRUNUKTtcblxuICAgIGVsc2UgaWYgKHRuID09PSAkLklOUFVUIHx8IHRuID09PSAkLktFWUdFTiB8fCB0biA9PT0gJC5URVhUQVJFQSkge1xuICAgICAgICBpZiAocC5vcGVuRWxlbWVudHMuaGFzSW5TZWxlY3RTY29wZSgkLlNFTEVDVCkpIHtcbiAgICAgICAgICAgIHAuX3Byb2Nlc3NGYWtlRW5kVGFnKCQuU0VMRUNUKTtcbiAgICAgICAgICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5TQ1JJUFQgfHwgdG4gPT09ICQuVEVNUExBVEUpXG4gICAgICAgIHN0YXJ0VGFnSW5IZWFkKHAsIHRva2VuKTtcbn1cblxuZnVuY3Rpb24gZW5kVGFnSW5TZWxlY3QocCwgdG9rZW4pIHtcbiAgICB2YXIgdG4gPSB0b2tlbi50YWdOYW1lO1xuXG4gICAgaWYgKHRuID09PSAkLk9QVEdST1VQKSB7XG4gICAgICAgIHZhciBwcmV2T3BlbkVsZW1lbnQgPSBwLm9wZW5FbGVtZW50cy5pdGVtc1twLm9wZW5FbGVtZW50cy5zdGFja1RvcCAtIDFdLFxuICAgICAgICAgICAgcHJldk9wZW5FbGVtZW50VG4gPSBwcmV2T3BlbkVsZW1lbnQgJiYgcC50cmVlQWRhcHRlci5nZXRUYWdOYW1lKHByZXZPcGVuRWxlbWVudCk7XG5cbiAgICAgICAgaWYgKHAub3BlbkVsZW1lbnRzLmN1cnJlbnRUYWdOYW1lID09PSAkLk9QVElPTiAmJiBwcmV2T3BlbkVsZW1lbnRUbiA9PT0gJC5PUFRHUk9VUClcbiAgICAgICAgICAgIHAuX3Byb2Nlc3NGYWtlRW5kVGFnKCQuT1BUSU9OKTtcblxuICAgICAgICBpZiAocC5vcGVuRWxlbWVudHMuY3VycmVudFRhZ05hbWUgPT09ICQuT1BUR1JPVVApXG4gICAgICAgICAgICBwLm9wZW5FbGVtZW50cy5wb3AoKTtcbiAgICB9XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5PUFRJT04pIHtcbiAgICAgICAgaWYgKHAub3BlbkVsZW1lbnRzLmN1cnJlbnRUYWdOYW1lID09PSAkLk9QVElPTilcbiAgICAgICAgICAgIHAub3BlbkVsZW1lbnRzLnBvcCgpO1xuICAgIH1cblxuICAgIGVsc2UgaWYgKHRuID09PSAkLlNFTEVDVCAmJiBwLm9wZW5FbGVtZW50cy5oYXNJblNlbGVjdFNjb3BlKCQuU0VMRUNUKSkge1xuICAgICAgICBwLm9wZW5FbGVtZW50cy5wb3BVbnRpbFRhZ05hbWVQb3BwZWQoJC5TRUxFQ1QpO1xuICAgICAgICBwLl9yZXNldEluc2VydGlvbk1vZGUoKTtcbiAgICB9XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5URU1QTEFURSlcbiAgICAgICAgZW5kVGFnSW5IZWFkKHAsIHRva2VuKTtcbn1cblxuLy8xMi4yLjUuNC4xNyBUaGUgXCJpbiBzZWxlY3QgaW4gdGFibGVcIiBpbnNlcnRpb24gbW9kZVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIHN0YXJ0VGFnSW5TZWxlY3RJblRhYmxlKHAsIHRva2VuKSB7XG4gICAgdmFyIHRuID0gdG9rZW4udGFnTmFtZTtcblxuICAgIGlmICh0biA9PT0gJC5DQVBUSU9OIHx8IHRuID09PSAkLlRBQkxFIHx8IHRuID09PSAkLlRCT0RZIHx8IHRuID09PSAkLlRGT09UIHx8XG4gICAgICAgIHRuID09PSAkLlRIRUFEIHx8IHRuID09PSAkLlRSIHx8IHRuID09PSAkLlREIHx8IHRuID09PSAkLlRIKSB7XG4gICAgICAgIHAuX3Byb2Nlc3NGYWtlRW5kVGFnKCQuU0VMRUNUKTtcbiAgICAgICAgcC5fcHJvY2Vzc1Rva2VuKHRva2VuKTtcbiAgICB9XG5cbiAgICBlbHNlXG4gICAgICAgIHN0YXJ0VGFnSW5TZWxlY3QocCwgdG9rZW4pO1xufVxuXG5mdW5jdGlvbiBlbmRUYWdJblNlbGVjdEluVGFibGUocCwgdG9rZW4pIHtcbiAgICB2YXIgdG4gPSB0b2tlbi50YWdOYW1lO1xuXG4gICAgaWYgKHRuID09PSAkLkNBUFRJT04gfHwgdG4gPT09ICQuVEFCTEUgfHwgdG4gPT09ICQuVEJPRFkgfHwgdG4gPT09ICQuVEZPT1QgfHxcbiAgICAgICAgdG4gPT09ICQuVEhFQUQgfHwgdG4gPT09ICQuVFIgfHwgdG4gPT09ICQuVEQgfHwgdG4gPT09ICQuVEgpIHtcbiAgICAgICAgaWYgKHAub3BlbkVsZW1lbnRzLmhhc0luVGFibGVTY29wZSh0bikpIHtcbiAgICAgICAgICAgIHAuX3Byb2Nlc3NGYWtlRW5kVGFnKCQuU0VMRUNUKTtcbiAgICAgICAgICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbHNlXG4gICAgICAgIGVuZFRhZ0luU2VsZWN0KHAsIHRva2VuKTtcbn1cblxuLy8xMi4yLjUuNC4xOCBUaGUgXCJpbiB0ZW1wbGF0ZVwiIGluc2VydGlvbiBtb2RlXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZnVuY3Rpb24gc3RhcnRUYWdJblRlbXBsYXRlKHAsIHRva2VuKSB7XG4gICAgdmFyIHRuID0gdG9rZW4udGFnTmFtZTtcblxuICAgIGlmICh0biA9PT0gJC5CQVNFIHx8IHRuID09PSAkLkJBU0VGT05UIHx8IHRuID09PSAkLkJHU09VTkQgfHwgdG4gPT09ICQuTElOSyB8fCB0biA9PT0gJC5NRVRBIHx8XG4gICAgICAgIHRuID09PSAkLk5PRlJBTUVTIHx8IHRuID09PSAkLlNDUklQVCB8fCB0biA9PT0gJC5TVFlMRSB8fCB0biA9PT0gJC5URU1QTEFURSB8fCB0biA9PT0gJC5USVRMRSkge1xuICAgICAgICBzdGFydFRhZ0luSGVhZChwLCB0b2tlbik7XG4gICAgfVxuXG4gICAgZWxzZSB7XG4gICAgICAgIHZhciBuZXdJbnNlcnRpb25Nb2RlID0gVEVNUExBVEVfSU5TRVJUSU9OX01PREVfU1dJVENIX01BUFt0bl0gfHwgSU5fQk9EWV9NT0RFO1xuXG4gICAgICAgIHAuX3BvcFRtcGxJbnNlcnRpb25Nb2RlKCk7XG4gICAgICAgIHAuX3B1c2hUbXBsSW5zZXJ0aW9uTW9kZShuZXdJbnNlcnRpb25Nb2RlKTtcbiAgICAgICAgcC5pbnNlcnRpb25Nb2RlID0gbmV3SW5zZXJ0aW9uTW9kZTtcbiAgICAgICAgcC5fcHJvY2Vzc1Rva2VuKHRva2VuKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGVuZFRhZ0luVGVtcGxhdGUocCwgdG9rZW4pIHtcbiAgICBpZiAodG9rZW4udGFnTmFtZSA9PT0gJC5URU1QTEFURSlcbiAgICAgICAgZW5kVGFnSW5IZWFkKHAsIHRva2VuKTtcbn1cblxuZnVuY3Rpb24gZW9mSW5UZW1wbGF0ZShwLCB0b2tlbikge1xuICAgIGlmIChwLm9wZW5FbGVtZW50cy50bXBsQ291bnQgPiAwKSB7XG4gICAgICAgIHAub3BlbkVsZW1lbnRzLnBvcFVudGlsVGVtcGxhdGVQb3BwZWQoKTtcbiAgICAgICAgcC5hY3RpdmVGb3JtYXR0aW5nRWxlbWVudHMuY2xlYXJUb0xhc3RNYXJrZXIoKTtcbiAgICAgICAgcC5fcG9wVG1wbEluc2VydGlvbk1vZGUoKTtcbiAgICAgICAgcC5fcmVzZXRJbnNlcnRpb25Nb2RlKCk7XG4gICAgICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG4gICAgfVxuXG4gICAgZWxzZVxuICAgICAgICBwLnN0b3BwZWQgPSB0cnVlO1xufVxuXG5cbi8vMTIuMi41LjQuMTkgVGhlIFwiYWZ0ZXIgYm9keVwiIGluc2VydGlvbiBtb2RlXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZnVuY3Rpb24gc3RhcnRUYWdBZnRlckJvZHkocCwgdG9rZW4pIHtcbiAgICBpZiAodG9rZW4udGFnTmFtZSA9PT0gJC5IVE1MKVxuICAgICAgICBzdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICBlbHNlXG4gICAgICAgIHRva2VuQWZ0ZXJCb2R5KHAsIHRva2VuKTtcbn1cblxuZnVuY3Rpb24gZW5kVGFnQWZ0ZXJCb2R5KHAsIHRva2VuKSB7XG4gICAgaWYgKHRva2VuLnRhZ05hbWUgPT09ICQuSFRNTCkge1xuICAgICAgICBpZiAoIXAuZnJhZ21lbnRDb250ZXh0KVxuICAgICAgICAgICAgcC5pbnNlcnRpb25Nb2RlID0gQUZURVJfQUZURVJfQk9EWV9NT0RFO1xuICAgIH1cblxuICAgIGVsc2VcbiAgICAgICAgdG9rZW5BZnRlckJvZHkocCwgdG9rZW4pO1xufVxuXG5mdW5jdGlvbiB0b2tlbkFmdGVyQm9keShwLCB0b2tlbikge1xuICAgIHAuaW5zZXJ0aW9uTW9kZSA9IElOX0JPRFlfTU9ERTtcbiAgICBwLl9wcm9jZXNzVG9rZW4odG9rZW4pO1xufVxuXG4vLzEyLjIuNS40LjIwIFRoZSBcImluIGZyYW1lc2V0XCIgaW5zZXJ0aW9uIG1vZGVcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBzdGFydFRhZ0luRnJhbWVzZXQocCwgdG9rZW4pIHtcbiAgICB2YXIgdG4gPSB0b2tlbi50YWdOYW1lO1xuXG4gICAgaWYgKHRuID09PSAkLkhUTUwpXG4gICAgICAgIHN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgIGVsc2UgaWYgKHRuID09PSAkLkZSQU1FU0VUKVxuICAgICAgICBwLl9pbnNlcnRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcblxuICAgIGVsc2UgaWYgKHRuID09PSAkLkZSQU1FKVxuICAgICAgICBwLl9hcHBlbmRFbGVtZW50KHRva2VuLCBOUy5IVE1MKTtcblxuICAgIGVsc2UgaWYgKHRuID09PSAkLk5PRlJBTUVTKVxuICAgICAgICBzdGFydFRhZ0luSGVhZChwLCB0b2tlbik7XG59XG5cbmZ1bmN0aW9uIGVuZFRhZ0luRnJhbWVzZXQocCwgdG9rZW4pIHtcbiAgICBpZiAodG9rZW4udGFnTmFtZSA9PT0gJC5GUkFNRVNFVCAmJiAhcC5vcGVuRWxlbWVudHMuaXNSb290SHRtbEVsZW1lbnRDdXJyZW50KCkpIHtcbiAgICAgICAgcC5vcGVuRWxlbWVudHMucG9wKCk7XG5cbiAgICAgICAgaWYgKCFwLmZyYWdtZW50Q29udGV4dCAmJiBwLm9wZW5FbGVtZW50cy5jdXJyZW50VGFnTmFtZSAhPT0gJC5GUkFNRVNFVClcbiAgICAgICAgICAgIHAuaW5zZXJ0aW9uTW9kZSA9IEFGVEVSX0ZSQU1FU0VUX01PREU7XG4gICAgfVxufVxuXG4vLzEyLjIuNS40LjIxIFRoZSBcImFmdGVyIGZyYW1lc2V0XCIgaW5zZXJ0aW9uIG1vZGVcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBzdGFydFRhZ0FmdGVyRnJhbWVzZXQocCwgdG9rZW4pIHtcbiAgICB2YXIgdG4gPSB0b2tlbi50YWdOYW1lO1xuXG4gICAgaWYgKHRuID09PSAkLkhUTUwpXG4gICAgICAgIHN0YXJ0VGFnSW5Cb2R5KHAsIHRva2VuKTtcblxuICAgIGVsc2UgaWYgKHRuID09PSAkLk5PRlJBTUVTKVxuICAgICAgICBzdGFydFRhZ0luSGVhZChwLCB0b2tlbik7XG59XG5cbmZ1bmN0aW9uIGVuZFRhZ0FmdGVyRnJhbWVzZXQocCwgdG9rZW4pIHtcbiAgICBpZiAodG9rZW4udGFnTmFtZSA9PT0gJC5IVE1MKVxuICAgICAgICBwLmluc2VydGlvbk1vZGUgPSBBRlRFUl9BRlRFUl9GUkFNRVNFVF9NT0RFO1xufVxuXG4vLzEyLjIuNS40LjIyIFRoZSBcImFmdGVyIGFmdGVyIGJvZHlcIiBpbnNlcnRpb24gbW9kZVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIHN0YXJ0VGFnQWZ0ZXJBZnRlckJvZHkocCwgdG9rZW4pIHtcbiAgICBpZiAodG9rZW4udGFnTmFtZSA9PT0gJC5IVE1MKVxuICAgICAgICBzdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICBlbHNlXG4gICAgICAgIHRva2VuQWZ0ZXJBZnRlckJvZHkocCwgdG9rZW4pO1xufVxuXG5mdW5jdGlvbiB0b2tlbkFmdGVyQWZ0ZXJCb2R5KHAsIHRva2VuKSB7XG4gICAgcC5pbnNlcnRpb25Nb2RlID0gSU5fQk9EWV9NT0RFO1xuICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG59XG5cbi8vMTIuMi41LjQuMjMgVGhlIFwiYWZ0ZXIgYWZ0ZXIgZnJhbWVzZXRcIiBpbnNlcnRpb24gbW9kZVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIHN0YXJ0VGFnQWZ0ZXJBZnRlckZyYW1lc2V0KHAsIHRva2VuKSB7XG4gICAgdmFyIHRuID0gdG9rZW4udGFnTmFtZTtcblxuICAgIGlmICh0biA9PT0gJC5IVE1MKVxuICAgICAgICBzdGFydFRhZ0luQm9keShwLCB0b2tlbik7XG5cbiAgICBlbHNlIGlmICh0biA9PT0gJC5OT0ZSQU1FUylcbiAgICAgICAgc3RhcnRUYWdJbkhlYWQocCwgdG9rZW4pO1xufVxuXG5cbi8vMTIuMi41LjUgVGhlIHJ1bGVzIGZvciBwYXJzaW5nIHRva2VucyBpbiBmb3JlaWduIGNvbnRlbnRcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBudWxsQ2hhcmFjdGVySW5Gb3JlaWduQ29udGVudChwLCB0b2tlbikge1xuICAgIHRva2VuLmNoYXJzID0gVU5JQ09ERS5SRVBMQUNFTUVOVF9DSEFSQUNURVI7XG4gICAgcC5faW5zZXJ0Q2hhcmFjdGVycyh0b2tlbik7XG59XG5cbmZ1bmN0aW9uIGNoYXJhY3RlckluRm9yZWlnbkNvbnRlbnQocCwgdG9rZW4pIHtcbiAgICBwLl9pbnNlcnRDaGFyYWN0ZXJzKHRva2VuKTtcbiAgICBwLmZyYW1lc2V0T2sgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gc3RhcnRUYWdJbkZvcmVpZ25Db250ZW50KHAsIHRva2VuKSB7XG4gICAgaWYgKEZvcmVpZ25Db250ZW50LmNhdXNlc0V4aXQodG9rZW4pICYmICFwLmZyYWdtZW50Q29udGV4dCkge1xuICAgICAgICB3aGlsZSAocC50cmVlQWRhcHRlci5nZXROYW1lc3BhY2VVUkkocC5vcGVuRWxlbWVudHMuY3VycmVudCkgIT09IE5TLkhUTUwgJiZcbiAgICAgICAgICAgICAgICghcC5faXNNYXRoTUxUZXh0SW50ZWdyYXRpb25Qb2ludChwLm9wZW5FbGVtZW50cy5jdXJyZW50KSkgJiZcbiAgICAgICAgICAgICAgICghcC5faXNIdG1sSW50ZWdyYXRpb25Qb2ludChwLm9wZW5FbGVtZW50cy5jdXJyZW50KSkpIHtcbiAgICAgICAgICAgIHAub3BlbkVsZW1lbnRzLnBvcCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcC5fcHJvY2Vzc1Rva2VuKHRva2VuKTtcbiAgICB9XG5cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIGN1cnJlbnQgPSBwLl9nZXRBZGp1c3RlZEN1cnJlbnRFbGVtZW50KCksXG4gICAgICAgICAgICBjdXJyZW50TnMgPSBwLnRyZWVBZGFwdGVyLmdldE5hbWVzcGFjZVVSSShjdXJyZW50KTtcblxuICAgICAgICBpZiAoY3VycmVudE5zID09PSBOUy5NQVRITUwpXG4gICAgICAgICAgICBGb3JlaWduQ29udGVudC5hZGp1c3RUb2tlbk1hdGhNTEF0dHJzKHRva2VuKTtcblxuICAgICAgICBlbHNlIGlmIChjdXJyZW50TnMgPT09IE5TLlNWRykge1xuICAgICAgICAgICAgRm9yZWlnbkNvbnRlbnQuYWRqdXN0VG9rZW5TVkdUYWdOYW1lKHRva2VuKTtcbiAgICAgICAgICAgIEZvcmVpZ25Db250ZW50LmFkanVzdFRva2VuU1ZHQXR0cnModG9rZW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgRm9yZWlnbkNvbnRlbnQuYWRqdXN0VG9rZW5YTUxBdHRycyh0b2tlbik7XG5cbiAgICAgICAgaWYgKHRva2VuLnNlbGZDbG9zaW5nKVxuICAgICAgICAgICAgcC5fYXBwZW5kRWxlbWVudCh0b2tlbiwgY3VycmVudE5zKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgcC5faW5zZXJ0RWxlbWVudCh0b2tlbiwgY3VycmVudE5zKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGVuZFRhZ0luRm9yZWlnbkNvbnRlbnQocCwgdG9rZW4pIHtcbiAgICBmb3IgKHZhciBpID0gcC5vcGVuRWxlbWVudHMuc3RhY2tUb3A7IGkgPiAwOyBpLS0pIHtcbiAgICAgICAgdmFyIGVsZW1lbnQgPSBwLm9wZW5FbGVtZW50cy5pdGVtc1tpXTtcblxuICAgICAgICBpZiAocC50cmVlQWRhcHRlci5nZXROYW1lc3BhY2VVUkkoZWxlbWVudCkgPT09IE5TLkhUTUwpIHtcbiAgICAgICAgICAgIHAuX3Byb2Nlc3NUb2tlbih0b2tlbik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwLnRyZWVBZGFwdGVyLmdldFRhZ05hbWUoZWxlbWVudCkudG9Mb3dlckNhc2UoKSA9PT0gdG9rZW4udGFnTmFtZSkge1xuICAgICAgICAgICAgcC5vcGVuRWxlbWVudHMucG9wVW50aWxFbGVtZW50UG9wcGVkKGVsZW1lbnQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKiFcbiAqIEBvdmVydmlldyBlczYtcHJvbWlzZSAtIGEgdGlueSBpbXBsZW1lbnRhdGlvbiBvZiBQcm9taXNlcy9BKy5cbiAqIEBjb3B5cmlnaHQgQ29weXJpZ2h0IChjKSAyMDE0IFllaHVkYSBLYXR6LCBUb20gRGFsZSwgU3RlZmFuIFBlbm5lciBhbmQgY29udHJpYnV0b3JzIChDb252ZXJzaW9uIHRvIEVTNiBBUEkgYnkgSmFrZSBBcmNoaWJhbGQpXG4gKiBAbGljZW5zZSAgIExpY2Vuc2VkIHVuZGVyIE1JVCBsaWNlbnNlXG4gKiAgICAgICAgICAgIFNlZSBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vamFrZWFyY2hpYmFsZC9lczYtcHJvbWlzZS9tYXN0ZXIvTElDRU5TRVxuICogQHZlcnNpb24gICAyLjMuMFxuICovXG5cbihmdW5jdGlvbigpIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcbiAgICBmdW5jdGlvbiBsaWIkZXM2JHByb21pc2UkdXRpbHMkJG9iamVjdE9yRnVuY3Rpb24oeCkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB4ID09PSAnZnVuY3Rpb24nIHx8ICh0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgeCAhPT0gbnVsbCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJHV0aWxzJCRpc0Z1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgeCA9PT0gJ2Z1bmN0aW9uJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkZXM2JHByb21pc2UkdXRpbHMkJGlzTWF5YmVUaGVuYWJsZSh4KSB7XG4gICAgICByZXR1cm4gdHlwZW9mIHggPT09ICdvYmplY3QnICYmIHggIT09IG51bGw7XG4gICAgfVxuXG4gICAgdmFyIGxpYiRlczYkcHJvbWlzZSR1dGlscyQkX2lzQXJyYXk7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KSB7XG4gICAgICBsaWIkZXM2JHByb21pc2UkdXRpbHMkJF9pc0FycmF5ID0gZnVuY3Rpb24gKHgpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh4KSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpYiRlczYkcHJvbWlzZSR1dGlscyQkX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuICAgIH1cblxuICAgIHZhciBsaWIkZXM2JHByb21pc2UkdXRpbHMkJGlzQXJyYXkgPSBsaWIkZXM2JHByb21pc2UkdXRpbHMkJF9pc0FycmF5O1xuICAgIHZhciBsaWIkZXM2JHByb21pc2UkYXNhcCQkbGVuID0gMDtcbiAgICB2YXIgbGliJGVzNiRwcm9taXNlJGFzYXAkJHRvU3RyaW5nID0ge30udG9TdHJpbmc7XG4gICAgdmFyIGxpYiRlczYkcHJvbWlzZSRhc2FwJCR2ZXJ0eE5leHQ7XG4gICAgdmFyIGxpYiRlczYkcHJvbWlzZSRhc2FwJCRjdXN0b21TY2hlZHVsZXJGbjtcblxuICAgIHZhciBsaWIkZXM2JHByb21pc2UkYXNhcCQkYXNhcCA9IGZ1bmN0aW9uIGFzYXAoY2FsbGJhY2ssIGFyZykge1xuICAgICAgbGliJGVzNiRwcm9taXNlJGFzYXAkJHF1ZXVlW2xpYiRlczYkcHJvbWlzZSRhc2FwJCRsZW5dID0gY2FsbGJhY2s7XG4gICAgICBsaWIkZXM2JHByb21pc2UkYXNhcCQkcXVldWVbbGliJGVzNiRwcm9taXNlJGFzYXAkJGxlbiArIDFdID0gYXJnO1xuICAgICAgbGliJGVzNiRwcm9taXNlJGFzYXAkJGxlbiArPSAyO1xuICAgICAgaWYgKGxpYiRlczYkcHJvbWlzZSRhc2FwJCRsZW4gPT09IDIpIHtcbiAgICAgICAgLy8gSWYgbGVuIGlzIDIsIHRoYXQgbWVhbnMgdGhhdCB3ZSBuZWVkIHRvIHNjaGVkdWxlIGFuIGFzeW5jIGZsdXNoLlxuICAgICAgICAvLyBJZiBhZGRpdGlvbmFsIGNhbGxiYWNrcyBhcmUgcXVldWVkIGJlZm9yZSB0aGUgcXVldWUgaXMgZmx1c2hlZCwgdGhleVxuICAgICAgICAvLyB3aWxsIGJlIHByb2Nlc3NlZCBieSB0aGlzIGZsdXNoIHRoYXQgd2UgYXJlIHNjaGVkdWxpbmcuXG4gICAgICAgIGlmIChsaWIkZXM2JHByb21pc2UkYXNhcCQkY3VzdG9tU2NoZWR1bGVyRm4pIHtcbiAgICAgICAgICBsaWIkZXM2JHByb21pc2UkYXNhcCQkY3VzdG9tU2NoZWR1bGVyRm4obGliJGVzNiRwcm9taXNlJGFzYXAkJGZsdXNoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsaWIkZXM2JHByb21pc2UkYXNhcCQkc2NoZWR1bGVGbHVzaCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJGFzYXAkJHNldFNjaGVkdWxlcihzY2hlZHVsZUZuKSB7XG4gICAgICBsaWIkZXM2JHByb21pc2UkYXNhcCQkY3VzdG9tU2NoZWR1bGVyRm4gPSBzY2hlZHVsZUZuO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRlczYkcHJvbWlzZSRhc2FwJCRzZXRBc2FwKGFzYXBGbikge1xuICAgICAgbGliJGVzNiRwcm9taXNlJGFzYXAkJGFzYXAgPSBhc2FwRm47XG4gICAgfVxuXG4gICAgdmFyIGxpYiRlczYkcHJvbWlzZSRhc2FwJCRicm93c2VyV2luZG93ID0gKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSA/IHdpbmRvdyA6IHVuZGVmaW5lZDtcbiAgICB2YXIgbGliJGVzNiRwcm9taXNlJGFzYXAkJGJyb3dzZXJHbG9iYWwgPSBsaWIkZXM2JHByb21pc2UkYXNhcCQkYnJvd3NlcldpbmRvdyB8fCB7fTtcbiAgICB2YXIgbGliJGVzNiRwcm9taXNlJGFzYXAkJEJyb3dzZXJNdXRhdGlvbk9ic2VydmVyID0gbGliJGVzNiRwcm9taXNlJGFzYXAkJGJyb3dzZXJHbG9iYWwuTXV0YXRpb25PYnNlcnZlciB8fCBsaWIkZXM2JHByb21pc2UkYXNhcCQkYnJvd3Nlckdsb2JhbC5XZWJLaXRNdXRhdGlvbk9ic2VydmVyO1xuICAgIHZhciBsaWIkZXM2JHByb21pc2UkYXNhcCQkaXNOb2RlID0gdHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIHt9LnRvU3RyaW5nLmNhbGwocHJvY2VzcykgPT09ICdbb2JqZWN0IHByb2Nlc3NdJztcblxuICAgIC8vIHRlc3QgZm9yIHdlYiB3b3JrZXIgYnV0IG5vdCBpbiBJRTEwXG4gICAgdmFyIGxpYiRlczYkcHJvbWlzZSRhc2FwJCRpc1dvcmtlciA9IHR5cGVvZiBVaW50OENsYW1wZWRBcnJheSAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgIHR5cGVvZiBpbXBvcnRTY3JpcHRzICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgdHlwZW9mIE1lc3NhZ2VDaGFubmVsICE9PSAndW5kZWZpbmVkJztcblxuICAgIC8vIG5vZGVcbiAgICBmdW5jdGlvbiBsaWIkZXM2JHByb21pc2UkYXNhcCQkdXNlTmV4dFRpY2soKSB7XG4gICAgICB2YXIgbmV4dFRpY2sgPSBwcm9jZXNzLm5leHRUaWNrO1xuICAgICAgLy8gbm9kZSB2ZXJzaW9uIDAuMTAueCBkaXNwbGF5cyBhIGRlcHJlY2F0aW9uIHdhcm5pbmcgd2hlbiBuZXh0VGljayBpcyB1c2VkIHJlY3Vyc2l2ZWx5XG4gICAgICAvLyBzZXRJbW1lZGlhdGUgc2hvdWxkIGJlIHVzZWQgaW5zdGVhZCBpbnN0ZWFkXG4gICAgICB2YXIgdmVyc2lvbiA9IHByb2Nlc3MudmVyc2lvbnMubm9kZS5tYXRjaCgvXig/OihcXGQrKVxcLik/KD86KFxcZCspXFwuKT8oXFwqfFxcZCspJC8pO1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmVyc2lvbikgJiYgdmVyc2lvblsxXSA9PT0gJzAnICYmIHZlcnNpb25bMl0gPT09ICcxMCcpIHtcbiAgICAgICAgbmV4dFRpY2sgPSBzZXRJbW1lZGlhdGU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIG5leHRUaWNrKGxpYiRlczYkcHJvbWlzZSRhc2FwJCRmbHVzaCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIHZlcnR4XG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJGFzYXAkJHVzZVZlcnR4VGltZXIoKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIGxpYiRlczYkcHJvbWlzZSRhc2FwJCR2ZXJ0eE5leHQobGliJGVzNiRwcm9taXNlJGFzYXAkJGZsdXNoKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJGFzYXAkJHVzZU11dGF0aW9uT2JzZXJ2ZXIoKSB7XG4gICAgICB2YXIgaXRlcmF0aW9ucyA9IDA7XG4gICAgICB2YXIgb2JzZXJ2ZXIgPSBuZXcgbGliJGVzNiRwcm9taXNlJGFzYXAkJEJyb3dzZXJNdXRhdGlvbk9ic2VydmVyKGxpYiRlczYkcHJvbWlzZSRhc2FwJCRmbHVzaCk7XG4gICAgICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcnKTtcbiAgICAgIG9ic2VydmVyLm9ic2VydmUobm9kZSwgeyBjaGFyYWN0ZXJEYXRhOiB0cnVlIH0pO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIG5vZGUuZGF0YSA9IChpdGVyYXRpb25zID0gKytpdGVyYXRpb25zICUgMik7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIHdlYiB3b3JrZXJcbiAgICBmdW5jdGlvbiBsaWIkZXM2JHByb21pc2UkYXNhcCQkdXNlTWVzc2FnZUNoYW5uZWwoKSB7XG4gICAgICB2YXIgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBsaWIkZXM2JHByb21pc2UkYXNhcCQkZmx1c2g7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICBjaGFubmVsLnBvcnQyLnBvc3RNZXNzYWdlKDApO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkZXM2JHByb21pc2UkYXNhcCQkdXNlU2V0VGltZW91dCgpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgc2V0VGltZW91dChsaWIkZXM2JHByb21pc2UkYXNhcCQkZmx1c2gsIDEpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgbGliJGVzNiRwcm9taXNlJGFzYXAkJHF1ZXVlID0gbmV3IEFycmF5KDEwMDApO1xuICAgIGZ1bmN0aW9uIGxpYiRlczYkcHJvbWlzZSRhc2FwJCRmbHVzaCgpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGliJGVzNiRwcm9taXNlJGFzYXAkJGxlbjsgaSs9Mikge1xuICAgICAgICB2YXIgY2FsbGJhY2sgPSBsaWIkZXM2JHByb21pc2UkYXNhcCQkcXVldWVbaV07XG4gICAgICAgIHZhciBhcmcgPSBsaWIkZXM2JHByb21pc2UkYXNhcCQkcXVldWVbaSsxXTtcblxuICAgICAgICBjYWxsYmFjayhhcmcpO1xuXG4gICAgICAgIGxpYiRlczYkcHJvbWlzZSRhc2FwJCRxdWV1ZVtpXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgbGliJGVzNiRwcm9taXNlJGFzYXAkJHF1ZXVlW2krMV0gPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGxpYiRlczYkcHJvbWlzZSRhc2FwJCRsZW4gPSAwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRlczYkcHJvbWlzZSRhc2FwJCRhdHRlbXB0VmVydGV4KCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIHIgPSByZXF1aXJlO1xuICAgICAgICB2YXIgdmVydHggPSByKCd2ZXJ0eCcpO1xuICAgICAgICBsaWIkZXM2JHByb21pc2UkYXNhcCQkdmVydHhOZXh0ID0gdmVydHgucnVuT25Mb29wIHx8IHZlcnR4LnJ1bk9uQ29udGV4dDtcbiAgICAgICAgcmV0dXJuIGxpYiRlczYkcHJvbWlzZSRhc2FwJCR1c2VWZXJ0eFRpbWVyKCk7XG4gICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgcmV0dXJuIGxpYiRlczYkcHJvbWlzZSRhc2FwJCR1c2VTZXRUaW1lb3V0KCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGxpYiRlczYkcHJvbWlzZSRhc2FwJCRzY2hlZHVsZUZsdXNoO1xuICAgIC8vIERlY2lkZSB3aGF0IGFzeW5jIG1ldGhvZCB0byB1c2UgdG8gdHJpZ2dlcmluZyBwcm9jZXNzaW5nIG9mIHF1ZXVlZCBjYWxsYmFja3M6XG4gICAgaWYgKGxpYiRlczYkcHJvbWlzZSRhc2FwJCRpc05vZGUpIHtcbiAgICAgIGxpYiRlczYkcHJvbWlzZSRhc2FwJCRzY2hlZHVsZUZsdXNoID0gbGliJGVzNiRwcm9taXNlJGFzYXAkJHVzZU5leHRUaWNrKCk7XG4gICAgfSBlbHNlIGlmIChsaWIkZXM2JHByb21pc2UkYXNhcCQkQnJvd3Nlck11dGF0aW9uT2JzZXJ2ZXIpIHtcbiAgICAgIGxpYiRlczYkcHJvbWlzZSRhc2FwJCRzY2hlZHVsZUZsdXNoID0gbGliJGVzNiRwcm9taXNlJGFzYXAkJHVzZU11dGF0aW9uT2JzZXJ2ZXIoKTtcbiAgICB9IGVsc2UgaWYgKGxpYiRlczYkcHJvbWlzZSRhc2FwJCRpc1dvcmtlcikge1xuICAgICAgbGliJGVzNiRwcm9taXNlJGFzYXAkJHNjaGVkdWxlRmx1c2ggPSBsaWIkZXM2JHByb21pc2UkYXNhcCQkdXNlTWVzc2FnZUNoYW5uZWwoKTtcbiAgICB9IGVsc2UgaWYgKGxpYiRlczYkcHJvbWlzZSRhc2FwJCRicm93c2VyV2luZG93ID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIHJlcXVpcmUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGxpYiRlczYkcHJvbWlzZSRhc2FwJCRzY2hlZHVsZUZsdXNoID0gbGliJGVzNiRwcm9taXNlJGFzYXAkJGF0dGVtcHRWZXJ0ZXgoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGliJGVzNiRwcm9taXNlJGFzYXAkJHNjaGVkdWxlRmx1c2ggPSBsaWIkZXM2JHByb21pc2UkYXNhcCQkdXNlU2V0VGltZW91dCgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJG5vb3AoKSB7fVxuXG4gICAgdmFyIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJFBFTkRJTkcgICA9IHZvaWQgMDtcbiAgICB2YXIgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkRlVMRklMTEVEID0gMTtcbiAgICB2YXIgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkUkVKRUNURUQgID0gMjtcblxuICAgIHZhciBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRHRVRfVEhFTl9FUlJPUiA9IG5ldyBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRFcnJvck9iamVjdCgpO1xuXG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkc2VsZkZ1bGxmaWxsbWVudCgpIHtcbiAgICAgIHJldHVybiBuZXcgVHlwZUVycm9yKFwiWW91IGNhbm5vdCByZXNvbHZlIGEgcHJvbWlzZSB3aXRoIGl0c2VsZlwiKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRjYW5ub3RSZXR1cm5Pd24oKSB7XG4gICAgICByZXR1cm4gbmV3IFR5cGVFcnJvcignQSBwcm9taXNlcyBjYWxsYmFjayBjYW5ub3QgcmV0dXJuIHRoYXQgc2FtZSBwcm9taXNlLicpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJGdldFRoZW4ocHJvbWlzZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbjtcbiAgICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkR0VUX1RIRU5fRVJST1IuZXJyb3IgPSBlcnJvcjtcbiAgICAgICAgcmV0dXJuIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJEdFVF9USEVOX0VSUk9SO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJHRyeVRoZW4odGhlbiwgdmFsdWUsIGZ1bGZpbGxtZW50SGFuZGxlciwgcmVqZWN0aW9uSGFuZGxlcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdGhlbi5jYWxsKHZhbHVlLCBmdWxmaWxsbWVudEhhbmRsZXIsIHJlamVjdGlvbkhhbmRsZXIpO1xuICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgIHJldHVybiBlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJGhhbmRsZUZvcmVpZ25UaGVuYWJsZShwcm9taXNlLCB0aGVuYWJsZSwgdGhlbikge1xuICAgICAgIGxpYiRlczYkcHJvbWlzZSRhc2FwJCRhc2FwKGZ1bmN0aW9uKHByb21pc2UpIHtcbiAgICAgICAgdmFyIHNlYWxlZCA9IGZhbHNlO1xuICAgICAgICB2YXIgZXJyb3IgPSBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCR0cnlUaGVuKHRoZW4sIHRoZW5hYmxlLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgIGlmIChzZWFsZWQpIHsgcmV0dXJuOyB9XG4gICAgICAgICAgc2VhbGVkID0gdHJ1ZTtcbiAgICAgICAgICBpZiAodGhlbmFibGUgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRyZXNvbHZlKHByb21pc2UsIHZhbHVlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkZnVsZmlsbChwcm9taXNlLCB2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LCBmdW5jdGlvbihyZWFzb24pIHtcbiAgICAgICAgICBpZiAoc2VhbGVkKSB7IHJldHVybjsgfVxuICAgICAgICAgIHNlYWxlZCA9IHRydWU7XG5cbiAgICAgICAgICBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRyZWplY3QocHJvbWlzZSwgcmVhc29uKTtcbiAgICAgICAgfSwgJ1NldHRsZTogJyArIChwcm9taXNlLl9sYWJlbCB8fCAnIHVua25vd24gcHJvbWlzZScpKTtcblxuICAgICAgICBpZiAoIXNlYWxlZCAmJiBlcnJvcikge1xuICAgICAgICAgIHNlYWxlZCA9IHRydWU7XG4gICAgICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkcmVqZWN0KHByb21pc2UsIGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfSwgcHJvbWlzZSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkaGFuZGxlT3duVGhlbmFibGUocHJvbWlzZSwgdGhlbmFibGUpIHtcbiAgICAgIGlmICh0aGVuYWJsZS5fc3RhdGUgPT09IGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJEZVTEZJTExFRCkge1xuICAgICAgICBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRmdWxmaWxsKHByb21pc2UsIHRoZW5hYmxlLl9yZXN1bHQpO1xuICAgICAgfSBlbHNlIGlmICh0aGVuYWJsZS5fc3RhdGUgPT09IGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJFJFSkVDVEVEKSB7XG4gICAgICAgIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJHJlamVjdChwcm9taXNlLCB0aGVuYWJsZS5fcmVzdWx0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJHN1YnNjcmliZSh0aGVuYWJsZSwgdW5kZWZpbmVkLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJHJlc29sdmUocHJvbWlzZSwgdmFsdWUpO1xuICAgICAgICB9LCBmdW5jdGlvbihyZWFzb24pIHtcbiAgICAgICAgICBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRyZWplY3QocHJvbWlzZSwgcmVhc29uKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkaGFuZGxlTWF5YmVUaGVuYWJsZShwcm9taXNlLCBtYXliZVRoZW5hYmxlKSB7XG4gICAgICBpZiAobWF5YmVUaGVuYWJsZS5jb25zdHJ1Y3RvciA9PT0gcHJvbWlzZS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRoYW5kbGVPd25UaGVuYWJsZShwcm9taXNlLCBtYXliZVRoZW5hYmxlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciB0aGVuID0gbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkZ2V0VGhlbihtYXliZVRoZW5hYmxlKTtcblxuICAgICAgICBpZiAodGhlbiA9PT0gbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkR0VUX1RIRU5fRVJST1IpIHtcbiAgICAgICAgICBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRyZWplY3QocHJvbWlzZSwgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkR0VUX1RIRU5fRVJST1IuZXJyb3IpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoZW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJGZ1bGZpbGwocHJvbWlzZSwgbWF5YmVUaGVuYWJsZSk7XG4gICAgICAgIH0gZWxzZSBpZiAobGliJGVzNiRwcm9taXNlJHV0aWxzJCRpc0Z1bmN0aW9uKHRoZW4pKSB7XG4gICAgICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkaGFuZGxlRm9yZWlnblRoZW5hYmxlKHByb21pc2UsIG1heWJlVGhlbmFibGUsIHRoZW4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJGZ1bGZpbGwocHJvbWlzZSwgbWF5YmVUaGVuYWJsZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRyZXNvbHZlKHByb21pc2UsIHZhbHVlKSB7XG4gICAgICBpZiAocHJvbWlzZSA9PT0gdmFsdWUpIHtcbiAgICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkcmVqZWN0KHByb21pc2UsIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJHNlbGZGdWxsZmlsbG1lbnQoKSk7XG4gICAgICB9IGVsc2UgaWYgKGxpYiRlczYkcHJvbWlzZSR1dGlscyQkb2JqZWN0T3JGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkaGFuZGxlTWF5YmVUaGVuYWJsZShwcm9taXNlLCB2YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRmdWxmaWxsKHByb21pc2UsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRwdWJsaXNoUmVqZWN0aW9uKHByb21pc2UpIHtcbiAgICAgIGlmIChwcm9taXNlLl9vbmVycm9yKSB7XG4gICAgICAgIHByb21pc2UuX29uZXJyb3IocHJvbWlzZS5fcmVzdWx0KTtcbiAgICAgIH1cblxuICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkcHVibGlzaChwcm9taXNlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRmdWxmaWxsKHByb21pc2UsIHZhbHVlKSB7XG4gICAgICBpZiAocHJvbWlzZS5fc3RhdGUgIT09IGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJFBFTkRJTkcpIHsgcmV0dXJuOyB9XG5cbiAgICAgIHByb21pc2UuX3Jlc3VsdCA9IHZhbHVlO1xuICAgICAgcHJvbWlzZS5fc3RhdGUgPSBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRGVUxGSUxMRUQ7XG5cbiAgICAgIGlmIChwcm9taXNlLl9zdWJzY3JpYmVycy5sZW5ndGggIT09IDApIHtcbiAgICAgICAgbGliJGVzNiRwcm9taXNlJGFzYXAkJGFzYXAobGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkcHVibGlzaCwgcHJvbWlzZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkcmVqZWN0KHByb21pc2UsIHJlYXNvbikge1xuICAgICAgaWYgKHByb21pc2UuX3N0YXRlICE9PSBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRQRU5ESU5HKSB7IHJldHVybjsgfVxuICAgICAgcHJvbWlzZS5fc3RhdGUgPSBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRSRUpFQ1RFRDtcbiAgICAgIHByb21pc2UuX3Jlc3VsdCA9IHJlYXNvbjtcblxuICAgICAgbGliJGVzNiRwcm9taXNlJGFzYXAkJGFzYXAobGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkcHVibGlzaFJlamVjdGlvbiwgcHJvbWlzZSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkc3Vic2NyaWJlKHBhcmVudCwgY2hpbGQsIG9uRnVsZmlsbG1lbnQsIG9uUmVqZWN0aW9uKSB7XG4gICAgICB2YXIgc3Vic2NyaWJlcnMgPSBwYXJlbnQuX3N1YnNjcmliZXJzO1xuICAgICAgdmFyIGxlbmd0aCA9IHN1YnNjcmliZXJzLmxlbmd0aDtcblxuICAgICAgcGFyZW50Ll9vbmVycm9yID0gbnVsbDtcblxuICAgICAgc3Vic2NyaWJlcnNbbGVuZ3RoXSA9IGNoaWxkO1xuICAgICAgc3Vic2NyaWJlcnNbbGVuZ3RoICsgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkRlVMRklMTEVEXSA9IG9uRnVsZmlsbG1lbnQ7XG4gICAgICBzdWJzY3JpYmVyc1tsZW5ndGggKyBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRSRUpFQ1RFRF0gID0gb25SZWplY3Rpb247XG5cbiAgICAgIGlmIChsZW5ndGggPT09IDAgJiYgcGFyZW50Ll9zdGF0ZSkge1xuICAgICAgICBsaWIkZXM2JHByb21pc2UkYXNhcCQkYXNhcChsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRwdWJsaXNoLCBwYXJlbnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJHB1Ymxpc2gocHJvbWlzZSkge1xuICAgICAgdmFyIHN1YnNjcmliZXJzID0gcHJvbWlzZS5fc3Vic2NyaWJlcnM7XG4gICAgICB2YXIgc2V0dGxlZCA9IHByb21pc2UuX3N0YXRlO1xuXG4gICAgICBpZiAoc3Vic2NyaWJlcnMubGVuZ3RoID09PSAwKSB7IHJldHVybjsgfVxuXG4gICAgICB2YXIgY2hpbGQsIGNhbGxiYWNrLCBkZXRhaWwgPSBwcm9taXNlLl9yZXN1bHQ7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3Vic2NyaWJlcnMubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgY2hpbGQgPSBzdWJzY3JpYmVyc1tpXTtcbiAgICAgICAgY2FsbGJhY2sgPSBzdWJzY3JpYmVyc1tpICsgc2V0dGxlZF07XG5cbiAgICAgICAgaWYgKGNoaWxkKSB7XG4gICAgICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkaW52b2tlQ2FsbGJhY2soc2V0dGxlZCwgY2hpbGQsIGNhbGxiYWNrLCBkZXRhaWwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNhbGxiYWNrKGRldGFpbCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcHJvbWlzZS5fc3Vic2NyaWJlcnMubGVuZ3RoID0gMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRFcnJvck9iamVjdCgpIHtcbiAgICAgIHRoaXMuZXJyb3IgPSBudWxsO1xuICAgIH1cblxuICAgIHZhciBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRUUllfQ0FUQ0hfRVJST1IgPSBuZXcgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkRXJyb3JPYmplY3QoKTtcblxuICAgIGZ1bmN0aW9uIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJHRyeUNhdGNoKGNhbGxiYWNrLCBkZXRhaWwpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhkZXRhaWwpO1xuICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJFRSWV9DQVRDSF9FUlJPUi5lcnJvciA9IGU7XG4gICAgICAgIHJldHVybiBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRUUllfQ0FUQ0hfRVJST1I7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkaW52b2tlQ2FsbGJhY2soc2V0dGxlZCwgcHJvbWlzZSwgY2FsbGJhY2ssIGRldGFpbCkge1xuICAgICAgdmFyIGhhc0NhbGxiYWNrID0gbGliJGVzNiRwcm9taXNlJHV0aWxzJCRpc0Z1bmN0aW9uKGNhbGxiYWNrKSxcbiAgICAgICAgICB2YWx1ZSwgZXJyb3IsIHN1Y2NlZWRlZCwgZmFpbGVkO1xuXG4gICAgICBpZiAoaGFzQ2FsbGJhY2spIHtcbiAgICAgICAgdmFsdWUgPSBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCR0cnlDYXRjaChjYWxsYmFjaywgZGV0YWlsKTtcblxuICAgICAgICBpZiAodmFsdWUgPT09IGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJFRSWV9DQVRDSF9FUlJPUikge1xuICAgICAgICAgIGZhaWxlZCA9IHRydWU7XG4gICAgICAgICAgZXJyb3IgPSB2YWx1ZS5lcnJvcjtcbiAgICAgICAgICB2YWx1ZSA9IG51bGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3VjY2VlZGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcm9taXNlID09PSB2YWx1ZSkge1xuICAgICAgICAgIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJHJlamVjdChwcm9taXNlLCBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRjYW5ub3RSZXR1cm5Pd24oKSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbHVlID0gZGV0YWlsO1xuICAgICAgICBzdWNjZWVkZWQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAocHJvbWlzZS5fc3RhdGUgIT09IGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJFBFTkRJTkcpIHtcbiAgICAgICAgLy8gbm9vcFxuICAgICAgfSBlbHNlIGlmIChoYXNDYWxsYmFjayAmJiBzdWNjZWVkZWQpIHtcbiAgICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkcmVzb2x2ZShwcm9taXNlLCB2YWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKGZhaWxlZCkge1xuICAgICAgICBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRyZWplY3QocHJvbWlzZSwgZXJyb3IpO1xuICAgICAgfSBlbHNlIGlmIChzZXR0bGVkID09PSBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRGVUxGSUxMRUQpIHtcbiAgICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkZnVsZmlsbChwcm9taXNlLCB2YWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKHNldHRsZWQgPT09IGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJFJFSkVDVEVEKSB7XG4gICAgICAgIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJHJlamVjdChwcm9taXNlLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkaW5pdGlhbGl6ZVByb21pc2UocHJvbWlzZSwgcmVzb2x2ZXIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlc29sdmVyKGZ1bmN0aW9uIHJlc29sdmVQcm9taXNlKHZhbHVlKXtcbiAgICAgICAgICBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRyZXNvbHZlKHByb21pc2UsIHZhbHVlKTtcbiAgICAgICAgfSwgZnVuY3Rpb24gcmVqZWN0UHJvbWlzZShyZWFzb24pIHtcbiAgICAgICAgICBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRyZWplY3QocHJvbWlzZSwgcmVhc29uKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkcmVqZWN0KHByb21pc2UsIGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpYiRlczYkcHJvbWlzZSRlbnVtZXJhdG9yJCRFbnVtZXJhdG9yKENvbnN0cnVjdG9yLCBpbnB1dCkge1xuICAgICAgdmFyIGVudW1lcmF0b3IgPSB0aGlzO1xuXG4gICAgICBlbnVtZXJhdG9yLl9pbnN0YW5jZUNvbnN0cnVjdG9yID0gQ29uc3RydWN0b3I7XG4gICAgICBlbnVtZXJhdG9yLnByb21pc2UgPSBuZXcgQ29uc3RydWN0b3IobGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkbm9vcCk7XG5cbiAgICAgIGlmIChlbnVtZXJhdG9yLl92YWxpZGF0ZUlucHV0KGlucHV0KSkge1xuICAgICAgICBlbnVtZXJhdG9yLl9pbnB1dCAgICAgPSBpbnB1dDtcbiAgICAgICAgZW51bWVyYXRvci5sZW5ndGggICAgID0gaW5wdXQubGVuZ3RoO1xuICAgICAgICBlbnVtZXJhdG9yLl9yZW1haW5pbmcgPSBpbnB1dC5sZW5ndGg7XG5cbiAgICAgICAgZW51bWVyYXRvci5faW5pdCgpO1xuXG4gICAgICAgIGlmIChlbnVtZXJhdG9yLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJGZ1bGZpbGwoZW51bWVyYXRvci5wcm9taXNlLCBlbnVtZXJhdG9yLl9yZXN1bHQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVudW1lcmF0b3IubGVuZ3RoID0gZW51bWVyYXRvci5sZW5ndGggfHwgMDtcbiAgICAgICAgICBlbnVtZXJhdG9yLl9lbnVtZXJhdGUoKTtcbiAgICAgICAgICBpZiAoZW51bWVyYXRvci5fcmVtYWluaW5nID09PSAwKSB7XG4gICAgICAgICAgICBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRmdWxmaWxsKGVudW1lcmF0b3IucHJvbWlzZSwgZW51bWVyYXRvci5fcmVzdWx0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJHJlamVjdChlbnVtZXJhdG9yLnByb21pc2UsIGVudW1lcmF0b3IuX3ZhbGlkYXRpb25FcnJvcigpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsaWIkZXM2JHByb21pc2UkZW51bWVyYXRvciQkRW51bWVyYXRvci5wcm90b3R5cGUuX3ZhbGlkYXRlSW5wdXQgPSBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgcmV0dXJuIGxpYiRlczYkcHJvbWlzZSR1dGlscyQkaXNBcnJheShpbnB1dCk7XG4gICAgfTtcblxuICAgIGxpYiRlczYkcHJvbWlzZSRlbnVtZXJhdG9yJCRFbnVtZXJhdG9yLnByb3RvdHlwZS5fdmFsaWRhdGlvbkVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKCdBcnJheSBNZXRob2RzIG11c3QgYmUgcHJvdmlkZWQgYW4gQXJyYXknKTtcbiAgICB9O1xuXG4gICAgbGliJGVzNiRwcm9taXNlJGVudW1lcmF0b3IkJEVudW1lcmF0b3IucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLl9yZXN1bHQgPSBuZXcgQXJyYXkodGhpcy5sZW5ndGgpO1xuICAgIH07XG5cbiAgICB2YXIgbGliJGVzNiRwcm9taXNlJGVudW1lcmF0b3IkJGRlZmF1bHQgPSBsaWIkZXM2JHByb21pc2UkZW51bWVyYXRvciQkRW51bWVyYXRvcjtcblxuICAgIGxpYiRlczYkcHJvbWlzZSRlbnVtZXJhdG9yJCRFbnVtZXJhdG9yLnByb3RvdHlwZS5fZW51bWVyYXRlID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZW51bWVyYXRvciA9IHRoaXM7XG5cbiAgICAgIHZhciBsZW5ndGggID0gZW51bWVyYXRvci5sZW5ndGg7XG4gICAgICB2YXIgcHJvbWlzZSA9IGVudW1lcmF0b3IucHJvbWlzZTtcbiAgICAgIHZhciBpbnB1dCAgID0gZW51bWVyYXRvci5faW5wdXQ7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBwcm9taXNlLl9zdGF0ZSA9PT0gbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkUEVORElORyAmJiBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZW51bWVyYXRvci5fZWFjaEVudHJ5KGlucHV0W2ldLCBpKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgbGliJGVzNiRwcm9taXNlJGVudW1lcmF0b3IkJEVudW1lcmF0b3IucHJvdG90eXBlLl9lYWNoRW50cnkgPSBmdW5jdGlvbihlbnRyeSwgaSkge1xuICAgICAgdmFyIGVudW1lcmF0b3IgPSB0aGlzO1xuICAgICAgdmFyIGMgPSBlbnVtZXJhdG9yLl9pbnN0YW5jZUNvbnN0cnVjdG9yO1xuXG4gICAgICBpZiAobGliJGVzNiRwcm9taXNlJHV0aWxzJCRpc01heWJlVGhlbmFibGUoZW50cnkpKSB7XG4gICAgICAgIGlmIChlbnRyeS5jb25zdHJ1Y3RvciA9PT0gYyAmJiBlbnRyeS5fc3RhdGUgIT09IGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJFBFTkRJTkcpIHtcbiAgICAgICAgICBlbnRyeS5fb25lcnJvciA9IG51bGw7XG4gICAgICAgICAgZW51bWVyYXRvci5fc2V0dGxlZEF0KGVudHJ5Ll9zdGF0ZSwgaSwgZW50cnkuX3Jlc3VsdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW51bWVyYXRvci5fd2lsbFNldHRsZUF0KGMucmVzb2x2ZShlbnRyeSksIGkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbnVtZXJhdG9yLl9yZW1haW5pbmctLTtcbiAgICAgICAgZW51bWVyYXRvci5fcmVzdWx0W2ldID0gZW50cnk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGxpYiRlczYkcHJvbWlzZSRlbnVtZXJhdG9yJCRFbnVtZXJhdG9yLnByb3RvdHlwZS5fc2V0dGxlZEF0ID0gZnVuY3Rpb24oc3RhdGUsIGksIHZhbHVlKSB7XG4gICAgICB2YXIgZW51bWVyYXRvciA9IHRoaXM7XG4gICAgICB2YXIgcHJvbWlzZSA9IGVudW1lcmF0b3IucHJvbWlzZTtcblxuICAgICAgaWYgKHByb21pc2UuX3N0YXRlID09PSBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRQRU5ESU5HKSB7XG4gICAgICAgIGVudW1lcmF0b3IuX3JlbWFpbmluZy0tO1xuXG4gICAgICAgIGlmIChzdGF0ZSA9PT0gbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkUkVKRUNURUQpIHtcbiAgICAgICAgICBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRyZWplY3QocHJvbWlzZSwgdmFsdWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVudW1lcmF0b3IuX3Jlc3VsdFtpXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChlbnVtZXJhdG9yLl9yZW1haW5pbmcgPT09IDApIHtcbiAgICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkZnVsZmlsbChwcm9taXNlLCBlbnVtZXJhdG9yLl9yZXN1bHQpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBsaWIkZXM2JHByb21pc2UkZW51bWVyYXRvciQkRW51bWVyYXRvci5wcm90b3R5cGUuX3dpbGxTZXR0bGVBdCA9IGZ1bmN0aW9uKHByb21pc2UsIGkpIHtcbiAgICAgIHZhciBlbnVtZXJhdG9yID0gdGhpcztcblxuICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkc3Vic2NyaWJlKHByb21pc2UsIHVuZGVmaW5lZCwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgZW51bWVyYXRvci5fc2V0dGxlZEF0KGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJEZVTEZJTExFRCwgaSwgdmFsdWUpO1xuICAgICAgfSwgZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgICAgIGVudW1lcmF0b3IuX3NldHRsZWRBdChsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRSRUpFQ1RFRCwgaSwgcmVhc29uKTtcbiAgICAgIH0pO1xuICAgIH07XG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJHByb21pc2UkYWxsJCRhbGwoZW50cmllcykge1xuICAgICAgcmV0dXJuIG5ldyBsaWIkZXM2JHByb21pc2UkZW51bWVyYXRvciQkZGVmYXVsdCh0aGlzLCBlbnRyaWVzKS5wcm9taXNlO1xuICAgIH1cbiAgICB2YXIgbGliJGVzNiRwcm9taXNlJHByb21pc2UkYWxsJCRkZWZhdWx0ID0gbGliJGVzNiRwcm9taXNlJHByb21pc2UkYWxsJCRhbGw7XG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJHByb21pc2UkcmFjZSQkcmFjZShlbnRyaWVzKSB7XG4gICAgICAvKmpzaGludCB2YWxpZHRoaXM6dHJ1ZSAqL1xuICAgICAgdmFyIENvbnN0cnVjdG9yID0gdGhpcztcblxuICAgICAgdmFyIHByb21pc2UgPSBuZXcgQ29uc3RydWN0b3IobGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkbm9vcCk7XG5cbiAgICAgIGlmICghbGliJGVzNiRwcm9taXNlJHV0aWxzJCRpc0FycmF5KGVudHJpZXMpKSB7XG4gICAgICAgIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJHJlamVjdChwcm9taXNlLCBuZXcgVHlwZUVycm9yKCdZb3UgbXVzdCBwYXNzIGFuIGFycmF5IHRvIHJhY2UuJykpO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgIH1cblxuICAgICAgdmFyIGxlbmd0aCA9IGVudHJpZXMubGVuZ3RoO1xuXG4gICAgICBmdW5jdGlvbiBvbkZ1bGZpbGxtZW50KHZhbHVlKSB7XG4gICAgICAgIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJHJlc29sdmUocHJvbWlzZSwgdmFsdWUpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBvblJlamVjdGlvbihyZWFzb24pIHtcbiAgICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkcmVqZWN0KHByb21pc2UsIHJlYXNvbik7XG4gICAgICB9XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBwcm9taXNlLl9zdGF0ZSA9PT0gbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkUEVORElORyAmJiBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkc3Vic2NyaWJlKENvbnN0cnVjdG9yLnJlc29sdmUoZW50cmllc1tpXSksIHVuZGVmaW5lZCwgb25GdWxmaWxsbWVudCwgb25SZWplY3Rpb24pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9XG4gICAgdmFyIGxpYiRlczYkcHJvbWlzZSRwcm9taXNlJHJhY2UkJGRlZmF1bHQgPSBsaWIkZXM2JHByb21pc2UkcHJvbWlzZSRyYWNlJCRyYWNlO1xuICAgIGZ1bmN0aW9uIGxpYiRlczYkcHJvbWlzZSRwcm9taXNlJHJlc29sdmUkJHJlc29sdmUob2JqZWN0KSB7XG4gICAgICAvKmpzaGludCB2YWxpZHRoaXM6dHJ1ZSAqL1xuICAgICAgdmFyIENvbnN0cnVjdG9yID0gdGhpcztcblxuICAgICAgaWYgKG9iamVjdCAmJiB0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJiBvYmplY3QuY29uc3RydWN0b3IgPT09IENvbnN0cnVjdG9yKSB7XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9XG5cbiAgICAgIHZhciBwcm9taXNlID0gbmV3IENvbnN0cnVjdG9yKGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJG5vb3ApO1xuICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkcmVzb2x2ZShwcm9taXNlLCBvYmplY3QpO1xuICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgfVxuICAgIHZhciBsaWIkZXM2JHByb21pc2UkcHJvbWlzZSRyZXNvbHZlJCRkZWZhdWx0ID0gbGliJGVzNiRwcm9taXNlJHByb21pc2UkcmVzb2x2ZSQkcmVzb2x2ZTtcbiAgICBmdW5jdGlvbiBsaWIkZXM2JHByb21pc2UkcHJvbWlzZSRyZWplY3QkJHJlamVjdChyZWFzb24pIHtcbiAgICAgIC8qanNoaW50IHZhbGlkdGhpczp0cnVlICovXG4gICAgICB2YXIgQ29uc3RydWN0b3IgPSB0aGlzO1xuICAgICAgdmFyIHByb21pc2UgPSBuZXcgQ29uc3RydWN0b3IobGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkbm9vcCk7XG4gICAgICBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRyZWplY3QocHJvbWlzZSwgcmVhc29uKTtcbiAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cbiAgICB2YXIgbGliJGVzNiRwcm9taXNlJHByb21pc2UkcmVqZWN0JCRkZWZhdWx0ID0gbGliJGVzNiRwcm9taXNlJHByb21pc2UkcmVqZWN0JCRyZWplY3Q7XG5cbiAgICB2YXIgbGliJGVzNiRwcm9taXNlJHByb21pc2UkJGNvdW50ZXIgPSAwO1xuXG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJHByb21pc2UkJG5lZWRzUmVzb2x2ZXIoKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdZb3UgbXVzdCBwYXNzIGEgcmVzb2x2ZXIgZnVuY3Rpb24gYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHRvIHRoZSBwcm9taXNlIGNvbnN0cnVjdG9yJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJHByb21pc2UkJG5lZWRzTmV3KCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZhaWxlZCB0byBjb25zdHJ1Y3QgJ1Byb21pc2UnOiBQbGVhc2UgdXNlIHRoZSAnbmV3JyBvcGVyYXRvciwgdGhpcyBvYmplY3QgY29uc3RydWN0b3IgY2Fubm90IGJlIGNhbGxlZCBhcyBhIGZ1bmN0aW9uLlwiKTtcbiAgICB9XG5cbiAgICB2YXIgbGliJGVzNiRwcm9taXNlJHByb21pc2UkJGRlZmF1bHQgPSBsaWIkZXM2JHByb21pc2UkcHJvbWlzZSQkUHJvbWlzZTtcbiAgICAvKipcbiAgICAgIFByb21pc2Ugb2JqZWN0cyByZXByZXNlbnQgdGhlIGV2ZW50dWFsIHJlc3VsdCBvZiBhbiBhc3luY2hyb25vdXMgb3BlcmF0aW9uLiBUaGVcbiAgICAgIHByaW1hcnkgd2F5IG9mIGludGVyYWN0aW5nIHdpdGggYSBwcm9taXNlIGlzIHRocm91Z2ggaXRzIGB0aGVuYCBtZXRob2QsIHdoaWNoXG4gICAgICByZWdpc3RlcnMgY2FsbGJhY2tzIHRvIHJlY2VpdmUgZWl0aGVyIGEgcHJvbWlzZSdzIGV2ZW50dWFsIHZhbHVlIG9yIHRoZSByZWFzb25cbiAgICAgIHdoeSB0aGUgcHJvbWlzZSBjYW5ub3QgYmUgZnVsZmlsbGVkLlxuXG4gICAgICBUZXJtaW5vbG9neVxuICAgICAgLS0tLS0tLS0tLS1cblxuICAgICAgLSBgcHJvbWlzZWAgaXMgYW4gb2JqZWN0IG9yIGZ1bmN0aW9uIHdpdGggYSBgdGhlbmAgbWV0aG9kIHdob3NlIGJlaGF2aW9yIGNvbmZvcm1zIHRvIHRoaXMgc3BlY2lmaWNhdGlvbi5cbiAgICAgIC0gYHRoZW5hYmxlYCBpcyBhbiBvYmplY3Qgb3IgZnVuY3Rpb24gdGhhdCBkZWZpbmVzIGEgYHRoZW5gIG1ldGhvZC5cbiAgICAgIC0gYHZhbHVlYCBpcyBhbnkgbGVnYWwgSmF2YVNjcmlwdCB2YWx1ZSAoaW5jbHVkaW5nIHVuZGVmaW5lZCwgYSB0aGVuYWJsZSwgb3IgYSBwcm9taXNlKS5cbiAgICAgIC0gYGV4Y2VwdGlvbmAgaXMgYSB2YWx1ZSB0aGF0IGlzIHRocm93biB1c2luZyB0aGUgdGhyb3cgc3RhdGVtZW50LlxuICAgICAgLSBgcmVhc29uYCBpcyBhIHZhbHVlIHRoYXQgaW5kaWNhdGVzIHdoeSBhIHByb21pc2Ugd2FzIHJlamVjdGVkLlxuICAgICAgLSBgc2V0dGxlZGAgdGhlIGZpbmFsIHJlc3Rpbmcgc3RhdGUgb2YgYSBwcm9taXNlLCBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuXG5cbiAgICAgIEEgcHJvbWlzZSBjYW4gYmUgaW4gb25lIG9mIHRocmVlIHN0YXRlczogcGVuZGluZywgZnVsZmlsbGVkLCBvciByZWplY3RlZC5cblxuICAgICAgUHJvbWlzZXMgdGhhdCBhcmUgZnVsZmlsbGVkIGhhdmUgYSBmdWxmaWxsbWVudCB2YWx1ZSBhbmQgYXJlIGluIHRoZSBmdWxmaWxsZWRcbiAgICAgIHN0YXRlLiAgUHJvbWlzZXMgdGhhdCBhcmUgcmVqZWN0ZWQgaGF2ZSBhIHJlamVjdGlvbiByZWFzb24gYW5kIGFyZSBpbiB0aGVcbiAgICAgIHJlamVjdGVkIHN0YXRlLiAgQSBmdWxmaWxsbWVudCB2YWx1ZSBpcyBuZXZlciBhIHRoZW5hYmxlLlxuXG4gICAgICBQcm9taXNlcyBjYW4gYWxzbyBiZSBzYWlkIHRvICpyZXNvbHZlKiBhIHZhbHVlLiAgSWYgdGhpcyB2YWx1ZSBpcyBhbHNvIGFcbiAgICAgIHByb21pc2UsIHRoZW4gdGhlIG9yaWdpbmFsIHByb21pc2UncyBzZXR0bGVkIHN0YXRlIHdpbGwgbWF0Y2ggdGhlIHZhbHVlJ3NcbiAgICAgIHNldHRsZWQgc3RhdGUuICBTbyBhIHByb21pc2UgdGhhdCAqcmVzb2x2ZXMqIGEgcHJvbWlzZSB0aGF0IHJlamVjdHMgd2lsbFxuICAgICAgaXRzZWxmIHJlamVjdCwgYW5kIGEgcHJvbWlzZSB0aGF0ICpyZXNvbHZlcyogYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgd2lsbFxuICAgICAgaXRzZWxmIGZ1bGZpbGwuXG5cblxuICAgICAgQmFzaWMgVXNhZ2U6XG4gICAgICAtLS0tLS0tLS0tLS1cblxuICAgICAgYGBganNcbiAgICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIC8vIG9uIHN1Y2Nlc3NcbiAgICAgICAgcmVzb2x2ZSh2YWx1ZSk7XG5cbiAgICAgICAgLy8gb24gZmFpbHVyZVxuICAgICAgICByZWplY3QocmVhc29uKTtcbiAgICAgIH0pO1xuXG4gICAgICBwcm9taXNlLnRoZW4oZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgLy8gb24gZnVsZmlsbG1lbnRcbiAgICAgIH0sIGZ1bmN0aW9uKHJlYXNvbikge1xuICAgICAgICAvLyBvbiByZWplY3Rpb25cbiAgICAgIH0pO1xuICAgICAgYGBgXG5cbiAgICAgIEFkdmFuY2VkIFVzYWdlOlxuICAgICAgLS0tLS0tLS0tLS0tLS0tXG5cbiAgICAgIFByb21pc2VzIHNoaW5lIHdoZW4gYWJzdHJhY3RpbmcgYXdheSBhc3luY2hyb25vdXMgaW50ZXJhY3Rpb25zIHN1Y2ggYXNcbiAgICAgIGBYTUxIdHRwUmVxdWVzdGBzLlxuXG4gICAgICBgYGBqc1xuICAgICAgZnVuY3Rpb24gZ2V0SlNPTih1cmwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCl7XG4gICAgICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuXG4gICAgICAgICAgeGhyLm9wZW4oJ0dFVCcsIHVybCk7XG4gICAgICAgICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGhhbmRsZXI7XG4gICAgICAgICAgeGhyLnJlc3BvbnNlVHlwZSA9ICdqc29uJztcbiAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgICB4aHIuc2VuZCgpO1xuXG4gICAgICAgICAgZnVuY3Rpb24gaGFuZGxlcigpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnJlYWR5U3RhdGUgPT09IHRoaXMuRE9ORSkge1xuICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgICAgICAgICAgIHJlc29sdmUodGhpcy5yZXNwb25zZSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignZ2V0SlNPTjogYCcgKyB1cmwgKyAnYCBmYWlsZWQgd2l0aCBzdGF0dXM6IFsnICsgdGhpcy5zdGF0dXMgKyAnXScpKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBnZXRKU09OKCcvcG9zdHMuanNvbicpLnRoZW4oZnVuY3Rpb24oanNvbikge1xuICAgICAgICAvLyBvbiBmdWxmaWxsbWVudFxuICAgICAgfSwgZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgICAgIC8vIG9uIHJlamVjdGlvblxuICAgICAgfSk7XG4gICAgICBgYGBcblxuICAgICAgVW5saWtlIGNhbGxiYWNrcywgcHJvbWlzZXMgYXJlIGdyZWF0IGNvbXBvc2FibGUgcHJpbWl0aXZlcy5cblxuICAgICAgYGBganNcbiAgICAgIFByb21pc2UuYWxsKFtcbiAgICAgICAgZ2V0SlNPTignL3Bvc3RzJyksXG4gICAgICAgIGdldEpTT04oJy9jb21tZW50cycpXG4gICAgICBdKS50aGVuKGZ1bmN0aW9uKHZhbHVlcyl7XG4gICAgICAgIHZhbHVlc1swXSAvLyA9PiBwb3N0c0pTT05cbiAgICAgICAgdmFsdWVzWzFdIC8vID0+IGNvbW1lbnRzSlNPTlxuXG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgICB9KTtcbiAgICAgIGBgYFxuXG4gICAgICBAY2xhc3MgUHJvbWlzZVxuICAgICAgQHBhcmFtIHtmdW5jdGlvbn0gcmVzb2x2ZXJcbiAgICAgIFVzZWZ1bCBmb3IgdG9vbGluZy5cbiAgICAgIEBjb25zdHJ1Y3RvclxuICAgICovXG4gICAgZnVuY3Rpb24gbGliJGVzNiRwcm9taXNlJHByb21pc2UkJFByb21pc2UocmVzb2x2ZXIpIHtcbiAgICAgIHRoaXMuX2lkID0gbGliJGVzNiRwcm9taXNlJHByb21pc2UkJGNvdW50ZXIrKztcbiAgICAgIHRoaXMuX3N0YXRlID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5fcmVzdWx0ID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5fc3Vic2NyaWJlcnMgPSBbXTtcblxuICAgICAgaWYgKGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJG5vb3AgIT09IHJlc29sdmVyKSB7XG4gICAgICAgIGlmICghbGliJGVzNiRwcm9taXNlJHV0aWxzJCRpc0Z1bmN0aW9uKHJlc29sdmVyKSkge1xuICAgICAgICAgIGxpYiRlczYkcHJvbWlzZSRwcm9taXNlJCRuZWVkc1Jlc29sdmVyKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgbGliJGVzNiRwcm9taXNlJHByb21pc2UkJFByb21pc2UpKSB7XG4gICAgICAgICAgbGliJGVzNiRwcm9taXNlJHByb21pc2UkJG5lZWRzTmV3KCk7XG4gICAgICAgIH1cblxuICAgICAgICBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRpbml0aWFsaXplUHJvbWlzZSh0aGlzLCByZXNvbHZlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGliJGVzNiRwcm9taXNlJHByb21pc2UkJFByb21pc2UuYWxsID0gbGliJGVzNiRwcm9taXNlJHByb21pc2UkYWxsJCRkZWZhdWx0O1xuICAgIGxpYiRlczYkcHJvbWlzZSRwcm9taXNlJCRQcm9taXNlLnJhY2UgPSBsaWIkZXM2JHByb21pc2UkcHJvbWlzZSRyYWNlJCRkZWZhdWx0O1xuICAgIGxpYiRlczYkcHJvbWlzZSRwcm9taXNlJCRQcm9taXNlLnJlc29sdmUgPSBsaWIkZXM2JHByb21pc2UkcHJvbWlzZSRyZXNvbHZlJCRkZWZhdWx0O1xuICAgIGxpYiRlczYkcHJvbWlzZSRwcm9taXNlJCRQcm9taXNlLnJlamVjdCA9IGxpYiRlczYkcHJvbWlzZSRwcm9taXNlJHJlamVjdCQkZGVmYXVsdDtcbiAgICBsaWIkZXM2JHByb21pc2UkcHJvbWlzZSQkUHJvbWlzZS5fc2V0U2NoZWR1bGVyID0gbGliJGVzNiRwcm9taXNlJGFzYXAkJHNldFNjaGVkdWxlcjtcbiAgICBsaWIkZXM2JHByb21pc2UkcHJvbWlzZSQkUHJvbWlzZS5fc2V0QXNhcCA9IGxpYiRlczYkcHJvbWlzZSRhc2FwJCRzZXRBc2FwO1xuICAgIGxpYiRlczYkcHJvbWlzZSRwcm9taXNlJCRQcm9taXNlLl9hc2FwID0gbGliJGVzNiRwcm9taXNlJGFzYXAkJGFzYXA7XG5cbiAgICBsaWIkZXM2JHByb21pc2UkcHJvbWlzZSQkUHJvbWlzZS5wcm90b3R5cGUgPSB7XG4gICAgICBjb25zdHJ1Y3RvcjogbGliJGVzNiRwcm9taXNlJHByb21pc2UkJFByb21pc2UsXG5cbiAgICAvKipcbiAgICAgIFRoZSBwcmltYXJ5IHdheSBvZiBpbnRlcmFjdGluZyB3aXRoIGEgcHJvbWlzZSBpcyB0aHJvdWdoIGl0cyBgdGhlbmAgbWV0aG9kLFxuICAgICAgd2hpY2ggcmVnaXN0ZXJzIGNhbGxiYWNrcyB0byByZWNlaXZlIGVpdGhlciBhIHByb21pc2UncyBldmVudHVhbCB2YWx1ZSBvciB0aGVcbiAgICAgIHJlYXNvbiB3aHkgdGhlIHByb21pc2UgY2Fubm90IGJlIGZ1bGZpbGxlZC5cblxuICAgICAgYGBganNcbiAgICAgIGZpbmRVc2VyKCkudGhlbihmdW5jdGlvbih1c2VyKXtcbiAgICAgICAgLy8gdXNlciBpcyBhdmFpbGFibGVcbiAgICAgIH0sIGZ1bmN0aW9uKHJlYXNvbil7XG4gICAgICAgIC8vIHVzZXIgaXMgdW5hdmFpbGFibGUsIGFuZCB5b3UgYXJlIGdpdmVuIHRoZSByZWFzb24gd2h5XG4gICAgICB9KTtcbiAgICAgIGBgYFxuXG4gICAgICBDaGFpbmluZ1xuICAgICAgLS0tLS0tLS1cblxuICAgICAgVGhlIHJldHVybiB2YWx1ZSBvZiBgdGhlbmAgaXMgaXRzZWxmIGEgcHJvbWlzZS4gIFRoaXMgc2Vjb25kLCAnZG93bnN0cmVhbSdcbiAgICAgIHByb21pc2UgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBmaXJzdCBwcm9taXNlJ3MgZnVsZmlsbG1lbnRcbiAgICAgIG9yIHJlamVjdGlvbiBoYW5kbGVyLCBvciByZWplY3RlZCBpZiB0aGUgaGFuZGxlciB0aHJvd3MgYW4gZXhjZXB0aW9uLlxuXG4gICAgICBgYGBqc1xuICAgICAgZmluZFVzZXIoKS50aGVuKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICAgIHJldHVybiB1c2VyLm5hbWU7XG4gICAgICB9LCBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICAgIHJldHVybiAnZGVmYXVsdCBuYW1lJztcbiAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHVzZXJOYW1lKSB7XG4gICAgICAgIC8vIElmIGBmaW5kVXNlcmAgZnVsZmlsbGVkLCBgdXNlck5hbWVgIHdpbGwgYmUgdGhlIHVzZXIncyBuYW1lLCBvdGhlcndpc2UgaXRcbiAgICAgICAgLy8gd2lsbCBiZSBgJ2RlZmF1bHQgbmFtZSdgXG4gICAgICB9KTtcblxuICAgICAgZmluZFVzZXIoKS50aGVuKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRm91bmQgdXNlciwgYnV0IHN0aWxsIHVuaGFwcHknKTtcbiAgICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdgZmluZFVzZXJgIHJlamVjdGVkIGFuZCB3ZSdyZSB1bmhhcHB5Jyk7XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAvLyBuZXZlciByZWFjaGVkXG4gICAgICB9LCBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICAgIC8vIGlmIGBmaW5kVXNlcmAgZnVsZmlsbGVkLCBgcmVhc29uYCB3aWxsIGJlICdGb3VuZCB1c2VyLCBidXQgc3RpbGwgdW5oYXBweScuXG4gICAgICAgIC8vIElmIGBmaW5kVXNlcmAgcmVqZWN0ZWQsIGByZWFzb25gIHdpbGwgYmUgJ2BmaW5kVXNlcmAgcmVqZWN0ZWQgYW5kIHdlJ3JlIHVuaGFwcHknLlxuICAgICAgfSk7XG4gICAgICBgYGBcbiAgICAgIElmIHRoZSBkb3duc3RyZWFtIHByb21pc2UgZG9lcyBub3Qgc3BlY2lmeSBhIHJlamVjdGlvbiBoYW5kbGVyLCByZWplY3Rpb24gcmVhc29ucyB3aWxsIGJlIHByb3BhZ2F0ZWQgZnVydGhlciBkb3duc3RyZWFtLlxuXG4gICAgICBgYGBqc1xuICAgICAgZmluZFVzZXIoKS50aGVuKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICAgIHRocm93IG5ldyBQZWRhZ29naWNhbEV4Y2VwdGlvbignVXBzdHJlYW0gZXJyb3InKTtcbiAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIC8vIG5ldmVyIHJlYWNoZWRcbiAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIC8vIG5ldmVyIHJlYWNoZWRcbiAgICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgLy8gVGhlIGBQZWRnYWdvY2lhbEV4Y2VwdGlvbmAgaXMgcHJvcGFnYXRlZCBhbGwgdGhlIHdheSBkb3duIHRvIGhlcmVcbiAgICAgIH0pO1xuICAgICAgYGBgXG5cbiAgICAgIEFzc2ltaWxhdGlvblxuICAgICAgLS0tLS0tLS0tLS0tXG5cbiAgICAgIFNvbWV0aW1lcyB0aGUgdmFsdWUgeW91IHdhbnQgdG8gcHJvcGFnYXRlIHRvIGEgZG93bnN0cmVhbSBwcm9taXNlIGNhbiBvbmx5IGJlXG4gICAgICByZXRyaWV2ZWQgYXN5bmNocm9ub3VzbHkuIFRoaXMgY2FuIGJlIGFjaGlldmVkIGJ5IHJldHVybmluZyBhIHByb21pc2UgaW4gdGhlXG4gICAgICBmdWxmaWxsbWVudCBvciByZWplY3Rpb24gaGFuZGxlci4gVGhlIGRvd25zdHJlYW0gcHJvbWlzZSB3aWxsIHRoZW4gYmUgcGVuZGluZ1xuICAgICAgdW50aWwgdGhlIHJldHVybmVkIHByb21pc2UgaXMgc2V0dGxlZC4gVGhpcyBpcyBjYWxsZWQgKmFzc2ltaWxhdGlvbiouXG5cbiAgICAgIGBgYGpzXG4gICAgICBmaW5kVXNlcigpLnRoZW4oZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgICAgcmV0dXJuIGZpbmRDb21tZW50c0J5QXV0aG9yKHVzZXIpO1xuICAgICAgfSkudGhlbihmdW5jdGlvbiAoY29tbWVudHMpIHtcbiAgICAgICAgLy8gVGhlIHVzZXIncyBjb21tZW50cyBhcmUgbm93IGF2YWlsYWJsZVxuICAgICAgfSk7XG4gICAgICBgYGBcblxuICAgICAgSWYgdGhlIGFzc2ltbGlhdGVkIHByb21pc2UgcmVqZWN0cywgdGhlbiB0aGUgZG93bnN0cmVhbSBwcm9taXNlIHdpbGwgYWxzbyByZWplY3QuXG5cbiAgICAgIGBgYGpzXG4gICAgICBmaW5kVXNlcigpLnRoZW4oZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgICAgcmV0dXJuIGZpbmRDb21tZW50c0J5QXV0aG9yKHVzZXIpO1xuICAgICAgfSkudGhlbihmdW5jdGlvbiAoY29tbWVudHMpIHtcbiAgICAgICAgLy8gSWYgYGZpbmRDb21tZW50c0J5QXV0aG9yYCBmdWxmaWxscywgd2UnbGwgaGF2ZSB0aGUgdmFsdWUgaGVyZVxuICAgICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICAvLyBJZiBgZmluZENvbW1lbnRzQnlBdXRob3JgIHJlamVjdHMsIHdlJ2xsIGhhdmUgdGhlIHJlYXNvbiBoZXJlXG4gICAgICB9KTtcbiAgICAgIGBgYFxuXG4gICAgICBTaW1wbGUgRXhhbXBsZVxuICAgICAgLS0tLS0tLS0tLS0tLS1cblxuICAgICAgU3luY2hyb25vdXMgRXhhbXBsZVxuXG4gICAgICBgYGBqYXZhc2NyaXB0XG4gICAgICB2YXIgcmVzdWx0O1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXN1bHQgPSBmaW5kUmVzdWx0KCk7XG4gICAgICAgIC8vIHN1Y2Nlc3NcbiAgICAgIH0gY2F0Y2gocmVhc29uKSB7XG4gICAgICAgIC8vIGZhaWx1cmVcbiAgICAgIH1cbiAgICAgIGBgYFxuXG4gICAgICBFcnJiYWNrIEV4YW1wbGVcblxuICAgICAgYGBganNcbiAgICAgIGZpbmRSZXN1bHQoZnVuY3Rpb24ocmVzdWx0LCBlcnIpe1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgLy8gZmFpbHVyZVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIHN1Y2Nlc3NcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBgYGBcblxuICAgICAgUHJvbWlzZSBFeGFtcGxlO1xuXG4gICAgICBgYGBqYXZhc2NyaXB0XG4gICAgICBmaW5kUmVzdWx0KCkudGhlbihmdW5jdGlvbihyZXN1bHQpe1xuICAgICAgICAvLyBzdWNjZXNzXG4gICAgICB9LCBmdW5jdGlvbihyZWFzb24pe1xuICAgICAgICAvLyBmYWlsdXJlXG4gICAgICB9KTtcbiAgICAgIGBgYFxuXG4gICAgICBBZHZhbmNlZCBFeGFtcGxlXG4gICAgICAtLS0tLS0tLS0tLS0tLVxuXG4gICAgICBTeW5jaHJvbm91cyBFeGFtcGxlXG5cbiAgICAgIGBgYGphdmFzY3JpcHRcbiAgICAgIHZhciBhdXRob3IsIGJvb2tzO1xuXG4gICAgICB0cnkge1xuICAgICAgICBhdXRob3IgPSBmaW5kQXV0aG9yKCk7XG4gICAgICAgIGJvb2tzICA9IGZpbmRCb29rc0J5QXV0aG9yKGF1dGhvcik7XG4gICAgICAgIC8vIHN1Y2Nlc3NcbiAgICAgIH0gY2F0Y2gocmVhc29uKSB7XG4gICAgICAgIC8vIGZhaWx1cmVcbiAgICAgIH1cbiAgICAgIGBgYFxuXG4gICAgICBFcnJiYWNrIEV4YW1wbGVcblxuICAgICAgYGBganNcblxuICAgICAgZnVuY3Rpb24gZm91bmRCb29rcyhib29rcykge1xuXG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGZhaWx1cmUocmVhc29uKSB7XG5cbiAgICAgIH1cblxuICAgICAgZmluZEF1dGhvcihmdW5jdGlvbihhdXRob3IsIGVycil7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICBmYWlsdXJlKGVycik7XG4gICAgICAgICAgLy8gZmFpbHVyZVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBmaW5kQm9vb2tzQnlBdXRob3IoYXV0aG9yLCBmdW5jdGlvbihib29rcywgZXJyKSB7XG4gICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICBmYWlsdXJlKGVycik7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIGZvdW5kQm9va3MoYm9va3MpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2gocmVhc29uKSB7XG4gICAgICAgICAgICAgICAgICBmYWlsdXJlKHJlYXNvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICAgICAgICBmYWlsdXJlKGVycik7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIHN1Y2Nlc3NcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBgYGBcblxuICAgICAgUHJvbWlzZSBFeGFtcGxlO1xuXG4gICAgICBgYGBqYXZhc2NyaXB0XG4gICAgICBmaW5kQXV0aG9yKCkuXG4gICAgICAgIHRoZW4oZmluZEJvb2tzQnlBdXRob3IpLlxuICAgICAgICB0aGVuKGZ1bmN0aW9uKGJvb2tzKXtcbiAgICAgICAgICAvLyBmb3VuZCBib29rc1xuICAgICAgfSkuY2F0Y2goZnVuY3Rpb24ocmVhc29uKXtcbiAgICAgICAgLy8gc29tZXRoaW5nIHdlbnQgd3JvbmdcbiAgICAgIH0pO1xuICAgICAgYGBgXG5cbiAgICAgIEBtZXRob2QgdGhlblxuICAgICAgQHBhcmFtIHtGdW5jdGlvbn0gb25GdWxmaWxsZWRcbiAgICAgIEBwYXJhbSB7RnVuY3Rpb259IG9uUmVqZWN0ZWRcbiAgICAgIFVzZWZ1bCBmb3IgdG9vbGluZy5cbiAgICAgIEByZXR1cm4ge1Byb21pc2V9XG4gICAgKi9cbiAgICAgIHRoZW46IGZ1bmN0aW9uKG9uRnVsZmlsbG1lbnQsIG9uUmVqZWN0aW9uKSB7XG4gICAgICAgIHZhciBwYXJlbnQgPSB0aGlzO1xuICAgICAgICB2YXIgc3RhdGUgPSBwYXJlbnQuX3N0YXRlO1xuXG4gICAgICAgIGlmIChzdGF0ZSA9PT0gbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkRlVMRklMTEVEICYmICFvbkZ1bGZpbGxtZW50IHx8IHN0YXRlID09PSBsaWIkZXM2JHByb21pc2UkJGludGVybmFsJCRSRUpFQ1RFRCAmJiAhb25SZWplY3Rpb24pIHtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjaGlsZCA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJG5vb3ApO1xuICAgICAgICB2YXIgcmVzdWx0ID0gcGFyZW50Ll9yZXN1bHQ7XG5cbiAgICAgICAgaWYgKHN0YXRlKSB7XG4gICAgICAgICAgdmFyIGNhbGxiYWNrID0gYXJndW1lbnRzW3N0YXRlIC0gMV07XG4gICAgICAgICAgbGliJGVzNiRwcm9taXNlJGFzYXAkJGFzYXAoZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIGxpYiRlczYkcHJvbWlzZSQkaW50ZXJuYWwkJGludm9rZUNhbGxiYWNrKHN0YXRlLCBjaGlsZCwgY2FsbGJhY2ssIHJlc3VsdCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGliJGVzNiRwcm9taXNlJCRpbnRlcm5hbCQkc3Vic2NyaWJlKHBhcmVudCwgY2hpbGQsIG9uRnVsZmlsbG1lbnQsIG9uUmVqZWN0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjaGlsZDtcbiAgICAgIH0sXG5cbiAgICAvKipcbiAgICAgIGBjYXRjaGAgaXMgc2ltcGx5IHN1Z2FyIGZvciBgdGhlbih1bmRlZmluZWQsIG9uUmVqZWN0aW9uKWAgd2hpY2ggbWFrZXMgaXQgdGhlIHNhbWVcbiAgICAgIGFzIHRoZSBjYXRjaCBibG9jayBvZiBhIHRyeS9jYXRjaCBzdGF0ZW1lbnQuXG5cbiAgICAgIGBgYGpzXG4gICAgICBmdW5jdGlvbiBmaW5kQXV0aG9yKCl7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY291bGRuJ3QgZmluZCB0aGF0IGF1dGhvcicpO1xuICAgICAgfVxuXG4gICAgICAvLyBzeW5jaHJvbm91c1xuICAgICAgdHJ5IHtcbiAgICAgICAgZmluZEF1dGhvcigpO1xuICAgICAgfSBjYXRjaChyZWFzb24pIHtcbiAgICAgICAgLy8gc29tZXRoaW5nIHdlbnQgd3JvbmdcbiAgICAgIH1cblxuICAgICAgLy8gYXN5bmMgd2l0aCBwcm9taXNlc1xuICAgICAgZmluZEF1dGhvcigpLmNhdGNoKGZ1bmN0aW9uKHJlYXNvbil7XG4gICAgICAgIC8vIHNvbWV0aGluZyB3ZW50IHdyb25nXG4gICAgICB9KTtcbiAgICAgIGBgYFxuXG4gICAgICBAbWV0aG9kIGNhdGNoXG4gICAgICBAcGFyYW0ge0Z1bmN0aW9ufSBvblJlamVjdGlvblxuICAgICAgVXNlZnVsIGZvciB0b29saW5nLlxuICAgICAgQHJldHVybiB7UHJvbWlzZX1cbiAgICAqL1xuICAgICAgJ2NhdGNoJzogZnVuY3Rpb24ob25SZWplY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGhlbihudWxsLCBvblJlamVjdGlvbik7XG4gICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBsaWIkZXM2JHByb21pc2UkcG9seWZpbGwkJHBvbHlmaWxsKCkge1xuICAgICAgdmFyIGxvY2FsO1xuXG4gICAgICBpZiAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBsb2NhbCA9IGdsb2JhbDtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgbG9jYWwgPSBzZWxmO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBsb2NhbCA9IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BvbHlmaWxsIGZhaWxlZCBiZWNhdXNlIGdsb2JhbCBvYmplY3QgaXMgdW5hdmFpbGFibGUgaW4gdGhpcyBlbnZpcm9ubWVudCcpO1xuICAgICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIFAgPSBsb2NhbC5Qcm9taXNlO1xuXG4gICAgICBpZiAoUCAmJiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoUC5yZXNvbHZlKCkpID09PSAnW29iamVjdCBQcm9taXNlXScgJiYgIVAuY2FzdCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGxvY2FsLlByb21pc2UgPSBsaWIkZXM2JHByb21pc2UkcHJvbWlzZSQkZGVmYXVsdDtcbiAgICB9XG4gICAgdmFyIGxpYiRlczYkcHJvbWlzZSRwb2x5ZmlsbCQkZGVmYXVsdCA9IGxpYiRlczYkcHJvbWlzZSRwb2x5ZmlsbCQkcG9seWZpbGw7XG5cbiAgICB2YXIgbGliJGVzNiRwcm9taXNlJHVtZCQkRVM2UHJvbWlzZSA9IHtcbiAgICAgICdQcm9taXNlJzogbGliJGVzNiRwcm9taXNlJHByb21pc2UkJGRlZmF1bHQsXG4gICAgICAncG9seWZpbGwnOiBsaWIkZXM2JHByb21pc2UkcG9seWZpbGwkJGRlZmF1bHRcbiAgICB9O1xuXG4gICAgLyogZ2xvYmFsIGRlZmluZTp0cnVlIG1vZHVsZTp0cnVlIHdpbmRvdzogdHJ1ZSAqL1xuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZVsnYW1kJ10pIHtcbiAgICAgIGRlZmluZShmdW5jdGlvbigpIHsgcmV0dXJuIGxpYiRlczYkcHJvbWlzZSR1bWQkJEVTNlByb21pc2U7IH0pO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlWydleHBvcnRzJ10pIHtcbiAgICAgIG1vZHVsZVsnZXhwb3J0cyddID0gbGliJGVzNiRwcm9taXNlJHVtZCQkRVM2UHJvbWlzZTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpc1snRVM2UHJvbWlzZSddID0gbGliJGVzNiRwcm9taXNlJHVtZCQkRVM2UHJvbWlzZTtcbiAgICB9XG5cbiAgICBsaWIkZXM2JHByb21pc2UkcG9seWZpbGwkJGRlZmF1bHQoKTtcbn0pLmNhbGwodGhpcyk7XG5cbiIsIi8qXG5Db3B5cmlnaHQgKEMpIDIwMTUgRnJlZCBLLiBTY2hvdHQgPGZrc2Nob3R0QGdtYWlsLmNvbT5cbkNvcHlyaWdodCAoQykgMjAxMyBBcml5YSBIaWRheWF0IDxhcml5YS5oaWRheWF0QGdtYWlsLmNvbT5cbkNvcHlyaWdodCAoQykgMjAxMyBUaGFkZGVlIFR5bCA8dGhhZGRlZS50eWxAZ21haWwuY29tPlxuQ29weXJpZ2h0IChDKSAyMDEzIE1hdGhpYXMgQnluZW5zIDxtYXRoaWFzQHFpd2kuYmU+XG5Db3B5cmlnaHQgKEMpIDIwMTIgQXJpeWEgSGlkYXlhdCA8YXJpeWEuaGlkYXlhdEBnbWFpbC5jb20+XG5Db3B5cmlnaHQgKEMpIDIwMTIgTWF0aGlhcyBCeW5lbnMgPG1hdGhpYXNAcWl3aS5iZT5cbkNvcHlyaWdodCAoQykgMjAxMiBKb29zdC1XaW0gQm9la2VzdGVpam4gPGpvb3N0LXdpbUBib2VrZXN0ZWlqbi5ubD5cbkNvcHlyaWdodCAoQykgMjAxMiBLcmlzIEtvd2FsIDxrcmlzLmtvd2FsQGNpeGFyLmNvbT5cbkNvcHlyaWdodCAoQykgMjAxMiBZdXN1a2UgU3V6dWtpIDx1dGF0YW5lLnRlYUBnbWFpbC5jb20+XG5Db3B5cmlnaHQgKEMpIDIwMTIgQXJwYWQgQm9yc29zIDxhcnBhZC5ib3Jzb3NAZ29vZ2xlbWFpbC5jb20+XG5Db3B5cmlnaHQgKEMpIDIwMTEgQXJpeWEgSGlkYXlhdCA8YXJpeWEuaGlkYXlhdEBnbWFpbC5jb20+XG5cblJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxubW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG5cbiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4gIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG5cblRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG5BTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG5JTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxuRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbihJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcbkxPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxuT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbihJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG4vKmVzbGludCBuby11bmRlZmluZWQ6MCwgbm8tdXNlLWJlZm9yZS1kZWZpbmU6IDAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIHN5bnRheCA9IHJlcXVpcmUoXCIuL2xpYi9zeW50YXhcIiksXG4gICAgdG9rZW5JbmZvID0gcmVxdWlyZShcIi4vbGliL3Rva2VuLWluZm9cIiksXG4gICAgYXN0Tm9kZVR5cGVzID0gcmVxdWlyZShcIi4vbGliL2FzdC1ub2RlLXR5cGVzXCIpLFxuICAgIGFzdE5vZGVGYWN0b3J5ID0gcmVxdWlyZShcIi4vbGliL2FzdC1ub2RlLWZhY3RvcnlcIiksXG4gICAgZGVmYXVsdEZlYXR1cmVzID0gcmVxdWlyZShcIi4vbGliL2ZlYXR1cmVzXCIpLFxuICAgIE1lc3NhZ2VzID0gcmVxdWlyZShcIi4vbGliL21lc3NhZ2VzXCIpLFxuICAgIFhIVE1MRW50aXRpZXMgPSByZXF1aXJlKFwiLi9saWIveGh0bWwtZW50aXRpZXNcIiksXG4gICAgU3RyaW5nTWFwID0gcmVxdWlyZShcIi4vbGliL3N0cmluZy1tYXBcIiksXG4gICAgY29tbWVudEF0dGFjaG1lbnQgPSByZXF1aXJlKFwiLi9saWIvY29tbWVudC1hdHRhY2htZW50XCIpO1xuXG52YXIgVG9rZW4gPSB0b2tlbkluZm8uVG9rZW4sXG4gICAgVG9rZW5OYW1lID0gdG9rZW5JbmZvLlRva2VuTmFtZSxcbiAgICBGbkV4cHJUb2tlbnMgPSB0b2tlbkluZm8uRm5FeHByVG9rZW5zLFxuICAgIFJlZ2V4ID0gc3ludGF4LlJlZ2V4LFxuICAgIFByb3BlcnR5S2luZCxcbiAgICBzb3VyY2UsXG4gICAgc3RyaWN0LFxuICAgIGluZGV4LFxuICAgIGxpbmVOdW1iZXIsXG4gICAgbGluZVN0YXJ0LFxuICAgIGxlbmd0aCxcbiAgICBsb29rYWhlYWQsXG4gICAgc3RhdGUsXG4gICAgZXh0cmE7XG5cblByb3BlcnR5S2luZCA9IHtcbiAgICBEYXRhOiAxLFxuICAgIEdldDogMixcbiAgICBTZXQ6IDRcbn07XG5cblxuLy8gRW5zdXJlIHRoZSBjb25kaXRpb24gaXMgdHJ1ZSwgb3RoZXJ3aXNlIHRocm93IGFuIGVycm9yLlxuLy8gVGhpcyBpcyBvbmx5IHRvIGhhdmUgYSBiZXR0ZXIgY29udHJhY3Qgc2VtYW50aWMsIGkuZS4gYW5vdGhlciBzYWZldHkgbmV0XG4vLyB0byBjYXRjaCBhIGxvZ2ljIGVycm9yLiBUaGUgY29uZGl0aW9uIHNoYWxsIGJlIGZ1bGZpbGxlZCBpbiBub3JtYWwgY2FzZS5cbi8vIERvIE5PVCB1c2UgdGhpcyB0byBlbmZvcmNlIGEgY2VydGFpbiBjb25kaXRpb24gb24gYW55IHVzZXIgaW5wdXQuXG5cbmZ1bmN0aW9uIGFzc2VydChjb25kaXRpb24sIG1lc3NhZ2UpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAoIWNvbmRpdGlvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBU1NFUlQ6IFwiICsgbWVzc2FnZSk7XG4gICAgfVxufVxuXG4vLyA3LjQgQ29tbWVudHNcblxuZnVuY3Rpb24gYWRkQ29tbWVudCh0eXBlLCB2YWx1ZSwgc3RhcnQsIGVuZCwgbG9jKSB7XG4gICAgdmFyIGNvbW1lbnQ7XG5cbiAgICBhc3NlcnQodHlwZW9mIHN0YXJ0ID09PSBcIm51bWJlclwiLCBcIkNvbW1lbnQgbXVzdCBoYXZlIHZhbGlkIHBvc2l0aW9uXCIpO1xuXG4gICAgLy8gQmVjYXVzZSB0aGUgd2F5IHRoZSBhY3R1YWwgdG9rZW4gaXMgc2Nhbm5lZCwgb2Z0ZW4gdGhlIGNvbW1lbnRzXG4gICAgLy8gKGlmIGFueSkgYXJlIHNraXBwZWQgdHdpY2UgZHVyaW5nIHRoZSBsZXhpY2FsIGFuYWx5c2lzLlxuICAgIC8vIFRodXMsIHdlIG5lZWQgdG8gc2tpcCBhZGRpbmcgYSBjb21tZW50IGlmIHRoZSBjb21tZW50IGFycmF5IGFscmVhZHlcbiAgICAvLyBoYW5kbGVkIGl0LlxuICAgIGlmIChzdGF0ZS5sYXN0Q29tbWVudFN0YXJ0ID49IHN0YXJ0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc3RhdGUubGFzdENvbW1lbnRTdGFydCA9IHN0YXJ0O1xuXG4gICAgY29tbWVudCA9IHtcbiAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgfTtcbiAgICBpZiAoZXh0cmEucmFuZ2UpIHtcbiAgICAgICAgY29tbWVudC5yYW5nZSA9IFtzdGFydCwgZW5kXTtcbiAgICB9XG4gICAgaWYgKGV4dHJhLmxvYykge1xuICAgICAgICBjb21tZW50LmxvYyA9IGxvYztcbiAgICB9XG4gICAgZXh0cmEuY29tbWVudHMucHVzaChjb21tZW50KTtcblxuICAgIGlmIChleHRyYS5hdHRhY2hDb21tZW50KSB7XG4gICAgICAgIGNvbW1lbnRBdHRhY2htZW50LmFkZENvbW1lbnQoY29tbWVudCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBza2lwU2luZ2xlTGluZUNvbW1lbnQob2Zmc2V0KSB7XG4gICAgdmFyIHN0YXJ0LCBsb2MsIGNoLCBjb21tZW50O1xuXG4gICAgc3RhcnQgPSBpbmRleCAtIG9mZnNldDtcbiAgICBsb2MgPSB7XG4gICAgICAgIHN0YXJ0OiB7XG4gICAgICAgICAgICBsaW5lOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgY29sdW1uOiBpbmRleCAtIGxpbmVTdGFydCAtIG9mZnNldFxuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgKytpbmRleDtcbiAgICAgICAgaWYgKHN5bnRheC5pc0xpbmVUZXJtaW5hdG9yKGNoKSkge1xuICAgICAgICAgICAgaWYgKGV4dHJhLmNvbW1lbnRzKSB7XG4gICAgICAgICAgICAgICAgY29tbWVudCA9IHNvdXJjZS5zbGljZShzdGFydCArIG9mZnNldCwgaW5kZXggLSAxKTtcbiAgICAgICAgICAgICAgICBsb2MuZW5kID0ge1xuICAgICAgICAgICAgICAgICAgICBsaW5lOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICBjb2x1bW46IGluZGV4IC0gbGluZVN0YXJ0IC0gMVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgYWRkQ29tbWVudChcIkxpbmVcIiwgY29tbWVudCwgc3RhcnQsIGluZGV4IC0gMSwgbG9jKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjaCA9PT0gMTMgJiYgc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpID09PSAxMCkge1xuICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICArK2xpbmVOdW1iZXI7XG4gICAgICAgICAgICBsaW5lU3RhcnQgPSBpbmRleDtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChleHRyYS5jb21tZW50cykge1xuICAgICAgICBjb21tZW50ID0gc291cmNlLnNsaWNlKHN0YXJ0ICsgb2Zmc2V0LCBpbmRleCk7XG4gICAgICAgIGxvYy5lbmQgPSB7XG4gICAgICAgICAgICBsaW5lOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgY29sdW1uOiBpbmRleCAtIGxpbmVTdGFydFxuICAgICAgICB9O1xuICAgICAgICBhZGRDb21tZW50KFwiTGluZVwiLCBjb21tZW50LCBzdGFydCwgaW5kZXgsIGxvYyk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBza2lwTXVsdGlMaW5lQ29tbWVudCgpIHtcbiAgICB2YXIgc3RhcnQsIGxvYywgY2gsIGNvbW1lbnQ7XG5cbiAgICBpZiAoZXh0cmEuY29tbWVudHMpIHtcbiAgICAgICAgc3RhcnQgPSBpbmRleCAtIDI7XG4gICAgICAgIGxvYyA9IHtcbiAgICAgICAgICAgIHN0YXJ0OiB7XG4gICAgICAgICAgICAgICAgbGluZTogbGluZU51bWJlcixcbiAgICAgICAgICAgICAgICBjb2x1bW46IGluZGV4IC0gbGluZVN0YXJ0IC0gMlxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgaWYgKHN5bnRheC5pc0xpbmVUZXJtaW5hdG9yKGNoKSkge1xuICAgICAgICAgICAgaWYgKGNoID09PSAweDBEICYmIHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4ICsgMSkgPT09IDB4MEEpIHtcbiAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgKytsaW5lTnVtYmVyO1xuICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgIGxpbmVTdGFydCA9IGluZGV4O1xuICAgICAgICAgICAgaWYgKGluZGV4ID49IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCJJTExFR0FMXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGNoID09PSAweDJBKSB7XG4gICAgICAgICAgICAvLyBCbG9jayBjb21tZW50IGVuZHMgd2l0aCBcIiovXCIuXG4gICAgICAgICAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQoaW5kZXggKyAxKSA9PT0gMHgyRikge1xuICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgICAgICBpZiAoZXh0cmEuY29tbWVudHMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IHNvdXJjZS5zbGljZShzdGFydCArIDIsIGluZGV4IC0gMik7XG4gICAgICAgICAgICAgICAgICAgIGxvYy5lbmQgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsaW5lOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uOiBpbmRleCAtIGxpbmVTdGFydFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBhZGRDb21tZW50KFwiQmxvY2tcIiwgY29tbWVudCwgc3RhcnQsIGluZGV4LCBsb2MpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICArK2luZGV4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCJJTExFR0FMXCIpO1xufVxuXG5mdW5jdGlvbiBza2lwQ29tbWVudCgpIHtcbiAgICB2YXIgY2gsIHN0YXJ0O1xuXG4gICAgc3RhcnQgPSAoaW5kZXggPT09IDApO1xuICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcblxuICAgICAgICBpZiAoc3ludGF4LmlzV2hpdGVTcGFjZShjaCkpIHtcbiAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgIH0gZWxzZSBpZiAoc3ludGF4LmlzTGluZVRlcm1pbmF0b3IoY2gpKSB7XG4gICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgaWYgKGNoID09PSAweDBEICYmIHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSA9PT0gMHgwQSkge1xuICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICArK2xpbmVOdW1iZXI7XG4gICAgICAgICAgICBsaW5lU3RhcnQgPSBpbmRleDtcbiAgICAgICAgICAgIHN0YXJ0ID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChjaCA9PT0gMHgyRikgeyAvLyBVKzAwMkYgaXMgXCIvXCJcbiAgICAgICAgICAgIGNoID0gc291cmNlLmNoYXJDb2RlQXQoaW5kZXggKyAxKTtcbiAgICAgICAgICAgIGlmIChjaCA9PT0gMHgyRikge1xuICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgICAgICBza2lwU2luZ2xlTGluZUNvbW1lbnQoMik7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PT0gMHgyQSkgeyAgLy8gVSswMDJBIGlzIFwiKlwiXG4gICAgICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgICAgIHNraXBNdWx0aUxpbmVDb21tZW50KCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHN0YXJ0ICYmIGNoID09PSAweDJEKSB7IC8vIFUrMDAyRCBpcyBcIi1cIlxuICAgICAgICAgICAgLy8gVSswMDNFIGlzIFwiPlwiXG4gICAgICAgICAgICBpZiAoKHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4ICsgMSkgPT09IDB4MkQpICYmIChzb3VyY2UuY2hhckNvZGVBdChpbmRleCArIDIpID09PSAweDNFKSkge1xuICAgICAgICAgICAgICAgIC8vIFwiLS0+XCIgaXMgYSBzaW5nbGUtbGluZSBjb21tZW50XG4gICAgICAgICAgICAgICAgaW5kZXggKz0gMztcbiAgICAgICAgICAgICAgICBza2lwU2luZ2xlTGluZUNvbW1lbnQoMyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGNoID09PSAweDNDKSB7IC8vIFUrMDAzQyBpcyBcIjxcIlxuICAgICAgICAgICAgaWYgKHNvdXJjZS5zbGljZShpbmRleCArIDEsIGluZGV4ICsgNCkgPT09IFwiIS0tXCIpIHtcbiAgICAgICAgICAgICAgICArK2luZGV4OyAvLyBgPGBcbiAgICAgICAgICAgICAgICArK2luZGV4OyAvLyBgIWBcbiAgICAgICAgICAgICAgICArK2luZGV4OyAvLyBgLWBcbiAgICAgICAgICAgICAgICArK2luZGV4OyAvLyBgLWBcbiAgICAgICAgICAgICAgICBza2lwU2luZ2xlTGluZUNvbW1lbnQoNCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIHNjYW5IZXhFc2NhcGUocHJlZml4KSB7XG4gICAgdmFyIGksIGxlbiwgY2gsIGNvZGUgPSAwO1xuXG4gICAgbGVuID0gKHByZWZpeCA9PT0gXCJ1XCIpID8gNCA6IDI7XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgIGlmIChpbmRleCA8IGxlbmd0aCAmJiBzeW50YXguaXNIZXhEaWdpdChzb3VyY2VbaW5kZXhdKSkge1xuICAgICAgICAgICAgY2ggPSBzb3VyY2VbaW5kZXgrK107XG4gICAgICAgICAgICBjb2RlID0gY29kZSAqIDE2ICsgXCIwMTIzNDU2Nzg5YWJjZGVmXCIuaW5kZXhPZihjaC50b0xvd2VyQ2FzZSgpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGUpO1xufVxuXG4vKipcbiAqIFNjYW5zIGFuIGV4dGVuZGVkIHVuaWNvZGUgY29kZSBwb2ludCBlc2NhcGUgc2VxdWVuY2UgZnJvbSBzb3VyY2UuIFRocm93cyBhblxuICogZXJyb3IgaWYgdGhlIHNlcXVlbmNlIGlzIGVtcHR5IG9yIGlmIHRoZSBjb2RlIHBvaW50IHZhbHVlIGlzIHRvbyBsYXJnZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBzdHJpbmcgY3JlYXRlZCBieSB0aGUgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2UuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBzY2FuVW5pY29kZUNvZGVQb2ludEVzY2FwZSgpIHtcbiAgICB2YXIgY2gsIGNvZGUsIGN1MSwgY3UyO1xuXG4gICAgY2ggPSBzb3VyY2VbaW5kZXhdO1xuICAgIGNvZGUgPSAwO1xuXG4gICAgLy8gQXQgbGVhc3Qgb25lIGhleCBkaWdpdCBpcyByZXF1aXJlZC5cbiAgICBpZiAoY2ggPT09IFwifVwiKSB7XG4gICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCJJTExFR0FMXCIpO1xuICAgIH1cblxuICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBjaCA9IHNvdXJjZVtpbmRleCsrXTtcbiAgICAgICAgaWYgKCFzeW50YXguaXNIZXhEaWdpdChjaCkpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNvZGUgPSBjb2RlICogMTYgKyBcIjAxMjM0NTY3ODlhYmNkZWZcIi5pbmRleE9mKGNoLnRvTG93ZXJDYXNlKCkpO1xuICAgIH1cblxuICAgIGlmIChjb2RlID4gMHgxMEZGRkYgfHwgY2ggIT09IFwifVwiKSB7XG4gICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCJJTExFR0FMXCIpO1xuICAgIH1cblxuICAgIC8vIFVURi0xNiBFbmNvZGluZ1xuICAgIGlmIChjb2RlIDw9IDB4RkZGRikge1xuICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKTtcbiAgICB9XG4gICAgY3UxID0gKChjb2RlIC0gMHgxMDAwMCkgPj4gMTApICsgMHhEODAwO1xuICAgIGN1MiA9ICgoY29kZSAtIDB4MTAwMDApICYgMTAyMykgKyAweERDMDA7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoY3UxLCBjdTIpO1xufVxuXG5mdW5jdGlvbiBnZXRFc2NhcGVkSWRlbnRpZmllcigpIHtcbiAgICB2YXIgY2gsIGlkO1xuXG4gICAgY2ggPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCsrKTtcbiAgICBpZCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2gpO1xuXG4gICAgLy8gXCJcXHVcIiAoVSswMDVDLCBVKzAwNzUpIGRlbm90ZXMgYW4gZXNjYXBlZCBjaGFyYWN0ZXIuXG4gICAgaWYgKGNoID09PSAweDVDKSB7XG4gICAgICAgIGlmIChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkgIT09IDB4NzUpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCJJTExFR0FMXCIpO1xuICAgICAgICB9XG4gICAgICAgICsraW5kZXg7XG4gICAgICAgIGNoID0gc2NhbkhleEVzY2FwZShcInVcIik7XG4gICAgICAgIGlmICghY2ggfHwgY2ggPT09IFwiXFxcXFwiIHx8ICFzeW50YXguaXNJZGVudGlmaWVyU3RhcnQoY2guY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCJJTExFR0FMXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlkID0gY2g7XG4gICAgfVxuXG4gICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNoID0gc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpO1xuICAgICAgICBpZiAoIXN5bnRheC5pc0lkZW50aWZpZXJQYXJ0KGNoKSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgKytpbmRleDtcbiAgICAgICAgaWQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjaCk7XG5cbiAgICAgICAgLy8gXCJcXHVcIiAoVSswMDVDLCBVKzAwNzUpIGRlbm90ZXMgYW4gZXNjYXBlZCBjaGFyYWN0ZXIuXG4gICAgICAgIGlmIChjaCA9PT0gMHg1Qykge1xuICAgICAgICAgICAgaWQgPSBpZC5zdWJzdHIoMCwgaWQubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpICE9PSAweDc1KSB7XG4gICAgICAgICAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuVW5leHBlY3RlZFRva2VuLCBcIklMTEVHQUxcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgY2ggPSBzY2FuSGV4RXNjYXBlKFwidVwiKTtcbiAgICAgICAgICAgIGlmICghY2ggfHwgY2ggPT09IFwiXFxcXFwiIHx8ICFzeW50YXguaXNJZGVudGlmaWVyUGFydChjaC5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgICAgICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCJJTExFR0FMXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWQgKz0gY2g7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaWQ7XG59XG5cbmZ1bmN0aW9uIGdldElkZW50aWZpZXIoKSB7XG4gICAgdmFyIHN0YXJ0LCBjaDtcblxuICAgIHN0YXJ0ID0gaW5kZXgrKztcbiAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgY2ggPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCk7XG4gICAgICAgIGlmIChjaCA9PT0gMHg1Qykge1xuICAgICAgICAgICAgLy8gQmxhY2tzbGFzaCAoVSswMDVDKSBtYXJrcyBVbmljb2RlIGVzY2FwZSBzZXF1ZW5jZS5cbiAgICAgICAgICAgIGluZGV4ID0gc3RhcnQ7XG4gICAgICAgICAgICByZXR1cm4gZ2V0RXNjYXBlZElkZW50aWZpZXIoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3ludGF4LmlzSWRlbnRpZmllclBhcnQoY2gpKSB7XG4gICAgICAgICAgICArK2luZGV4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc291cmNlLnNsaWNlKHN0YXJ0LCBpbmRleCk7XG59XG5cbmZ1bmN0aW9uIHNjYW5JZGVudGlmaWVyKCkge1xuICAgIHZhciBzdGFydCwgaWQsIHR5cGU7XG5cbiAgICBzdGFydCA9IGluZGV4O1xuXG4gICAgLy8gQmFja3NsYXNoIChVKzAwNUMpIHN0YXJ0cyBhbiBlc2NhcGVkIGNoYXJhY3Rlci5cbiAgICBpZCA9IChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkgPT09IDB4NUMpID8gZ2V0RXNjYXBlZElkZW50aWZpZXIoKSA6IGdldElkZW50aWZpZXIoKTtcblxuICAgIC8vIFRoZXJlIGlzIG5vIGtleXdvcmQgb3IgbGl0ZXJhbCB3aXRoIG9ubHkgb25lIGNoYXJhY3Rlci5cbiAgICAvLyBUaHVzLCBpdCBtdXN0IGJlIGFuIGlkZW50aWZpZXIuXG4gICAgaWYgKGlkLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICB0eXBlID0gVG9rZW4uSWRlbnRpZmllcjtcbiAgICB9IGVsc2UgaWYgKHN5bnRheC5pc0tleXdvcmQoaWQsIHN0cmljdCwgZXh0cmEuZWNtYUZlYXR1cmVzKSkge1xuICAgICAgICB0eXBlID0gVG9rZW4uS2V5d29yZDtcbiAgICB9IGVsc2UgaWYgKGlkID09PSBcIm51bGxcIikge1xuICAgICAgICB0eXBlID0gVG9rZW4uTnVsbExpdGVyYWw7XG4gICAgfSBlbHNlIGlmIChpZCA9PT0gXCJ0cnVlXCIgfHwgaWQgPT09IFwiZmFsc2VcIikge1xuICAgICAgICB0eXBlID0gVG9rZW4uQm9vbGVhbkxpdGVyYWw7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdHlwZSA9IFRva2VuLklkZW50aWZpZXI7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgICAgdmFsdWU6IGlkLFxuICAgICAgICBsaW5lTnVtYmVyOiBsaW5lTnVtYmVyLFxuICAgICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgICAgcmFuZ2U6IFtzdGFydCwgaW5kZXhdXG4gICAgfTtcbn1cblxuXG4vLyA3LjcgUHVuY3R1YXRvcnNcblxuZnVuY3Rpb24gc2NhblB1bmN0dWF0b3IoKSB7XG4gICAgdmFyIHN0YXJ0ID0gaW5kZXgsXG4gICAgICAgIGNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCksXG4gICAgICAgIGNvZGUyLFxuICAgICAgICBjaDEgPSBzb3VyY2VbaW5kZXhdLFxuICAgICAgICBjaDIsXG4gICAgICAgIGNoMyxcbiAgICAgICAgY2g0O1xuXG4gICAgc3dpdGNoIChjb2RlKSB7XG4gICAgICAgIC8vIENoZWNrIGZvciBtb3N0IGNvbW1vbiBzaW5nbGUtY2hhcmFjdGVyIHB1bmN0dWF0b3JzLlxuICAgICAgICBjYXNlIDQwOiAgIC8vICggb3BlbiBicmFja2V0XG4gICAgICAgIGNhc2UgNDE6ICAgLy8gKSBjbG9zZSBicmFja2V0XG4gICAgICAgIGNhc2UgNTk6ICAgLy8gOyBzZW1pY29sb25cbiAgICAgICAgY2FzZSA0NDogICAvLyAsIGNvbW1hXG4gICAgICAgIGNhc2UgOTE6ICAgLy8gW1xuICAgICAgICBjYXNlIDkzOiAgIC8vIF1cbiAgICAgICAgY2FzZSA1ODogICAvLyA6XG4gICAgICAgIGNhc2UgNjM6ICAgLy8gP1xuICAgICAgICBjYXNlIDEyNjogIC8vIH5cbiAgICAgICAgICAgICsraW5kZXg7XG5cbiAgICAgICAgICAgIGlmIChleHRyYS50b2tlbml6ZSAmJiBjb2RlID09PSA0MCkge1xuICAgICAgICAgICAgICAgIGV4dHJhLm9wZW5QYXJlblRva2VuID0gZXh0cmEudG9rZW5zLmxlbmd0aDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBUb2tlbi5QdW5jdHVhdG9yLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGUpLFxuICAgICAgICAgICAgICAgIGxpbmVOdW1iZXI6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICAgICAgbGluZVN0YXJ0OiBsaW5lU3RhcnQsXG4gICAgICAgICAgICAgICAgcmFuZ2U6IFtzdGFydCwgaW5kZXhdXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgIGNhc2UgMTIzOiAgLy8geyBvcGVuIGN1cmx5IGJyYWNlXG4gICAgICAgIGNhc2UgMTI1OiAgLy8gfSBjbG9zZSBjdXJseSBicmFjZVxuICAgICAgICAgICAgKytpbmRleDtcblxuICAgICAgICAgICAgaWYgKGV4dHJhLnRva2VuaXplICYmIGNvZGUgPT09IDEyMykge1xuICAgICAgICAgICAgICAgIGV4dHJhLm9wZW5DdXJseVRva2VuID0gZXh0cmEudG9rZW5zLmxlbmd0aDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gbG9va2FoZWFkMiBmdW5jdGlvbiBjYW4gY2F1c2UgdG9rZW5zIHRvIGJlIHNjYW5uZWQgdHdpY2UgYW5kIGluIGRvaW5nIHNvXG4gICAgICAgICAgICAvLyB3b3VsZCB3cmVjayB0aGUgY3VybHkgc3RhY2sgYnkgcHVzaGluZyB0aGUgc2FtZSB0b2tlbiBvbnRvIHRoZSBzdGFjayB0d2ljZS5cbiAgICAgICAgICAgIC8vIGN1cmx5TGFzdEluZGV4IGVuc3VyZXMgZWFjaCB0b2tlbiBpcyBwdXNoZWQgb3IgcG9wcGVkIGV4YWN0bHkgb25jZVxuICAgICAgICAgICAgaWYgKGluZGV4ID4gc3RhdGUuY3VybHlMYXN0SW5kZXgpIHtcbiAgICAgICAgICAgICAgICBzdGF0ZS5jdXJseUxhc3RJbmRleCA9IGluZGV4O1xuICAgICAgICAgICAgICAgIGlmIChjb2RlID09PSAxMjMpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUuY3VybHlTdGFjay5wdXNoKFwie1wiKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5jdXJseVN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBUb2tlbi5QdW5jdHVhdG9yLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGUpLFxuICAgICAgICAgICAgICAgIGxpbmVOdW1iZXI6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICAgICAgbGluZVN0YXJ0OiBsaW5lU3RhcnQsXG4gICAgICAgICAgICAgICAgcmFuZ2U6IFtzdGFydCwgaW5kZXhdXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBjb2RlMiA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4ICsgMSk7XG5cbiAgICAgICAgICAgIC8vIFwiPVwiIChjaGFyICM2MSkgbWFya3MgYW4gYXNzaWdubWVudCBvciBjb21wYXJpc29uIG9wZXJhdG9yLlxuICAgICAgICAgICAgaWYgKGNvZGUyID09PSA2MSkge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoY29kZSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDM3OiAgLy8gJVxuICAgICAgICAgICAgICAgICAgICBjYXNlIDM4OiAgLy8gJlxuICAgICAgICAgICAgICAgICAgICBjYXNlIDQyOiAgLy8gKjpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0MzogIC8vICtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0NTogIC8vIC1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0NzogIC8vIC9cbiAgICAgICAgICAgICAgICAgICAgY2FzZSA2MDogIC8vIDxcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA2MjogIC8vID5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSA5NDogIC8vIF5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxMjQ6IC8vIHxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFRva2VuLlB1bmN0dWF0b3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZSkgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGUyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lTnVtYmVyOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlOiBbc3RhcnQsIGluZGV4XVxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICBjYXNlIDMzOiAvLyAhXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNjE6IC8vID1cbiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDI7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICE9PSBhbmQgPT09XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpID09PSA2MSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFRva2VuLlB1bmN0dWF0b3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHNvdXJjZS5zbGljZShzdGFydCwgaW5kZXgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVOdW1iZXI6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZVN0YXJ0OiBsaW5lU3RhcnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2U6IFtzdGFydCwgaW5kZXhdXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gUGVlayBtb3JlIGNoYXJhY3RlcnMuXG5cbiAgICBjaDIgPSBzb3VyY2VbaW5kZXggKyAxXTtcbiAgICBjaDMgPSBzb3VyY2VbaW5kZXggKyAyXTtcbiAgICBjaDQgPSBzb3VyY2VbaW5kZXggKyAzXTtcblxuICAgIC8vIDQtY2hhcmFjdGVyIHB1bmN0dWF0b3I6ID4+Pj1cblxuICAgIGlmIChjaDEgPT09IFwiPlwiICYmIGNoMiA9PT0gXCI+XCIgJiYgY2gzID09PSBcIj5cIikge1xuICAgICAgICBpZiAoY2g0ID09PSBcIj1cIikge1xuICAgICAgICAgICAgaW5kZXggKz0gNDtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdHlwZTogVG9rZW4uUHVuY3R1YXRvcixcbiAgICAgICAgICAgICAgICB2YWx1ZTogXCI+Pj49XCIsXG4gICAgICAgICAgICAgICAgbGluZU51bWJlcjogbGluZU51bWJlcixcbiAgICAgICAgICAgICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgICAgICAgICAgICByYW5nZTogW3N0YXJ0LCBpbmRleF1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAzLWNoYXJhY3RlciBwdW5jdHVhdG9yczogPT09ICE9PSA+Pj4gPDw9ID4+PVxuXG4gICAgaWYgKGNoMSA9PT0gXCI+XCIgJiYgY2gyID09PSBcIj5cIiAmJiBjaDMgPT09IFwiPlwiKSB7XG4gICAgICAgIGluZGV4ICs9IDM7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBUb2tlbi5QdW5jdHVhdG9yLFxuICAgICAgICAgICAgdmFsdWU6IFwiPj4+XCIsXG4gICAgICAgICAgICBsaW5lTnVtYmVyOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgbGluZVN0YXJ0OiBsaW5lU3RhcnQsXG4gICAgICAgICAgICByYW5nZTogW3N0YXJ0LCBpbmRleF1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoY2gxID09PSBcIjxcIiAmJiBjaDIgPT09IFwiPFwiICYmIGNoMyA9PT0gXCI9XCIpIHtcbiAgICAgICAgaW5kZXggKz0gMztcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IFRva2VuLlB1bmN0dWF0b3IsXG4gICAgICAgICAgICB2YWx1ZTogXCI8PD1cIixcbiAgICAgICAgICAgIGxpbmVOdW1iZXI6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgICAgICAgIHJhbmdlOiBbc3RhcnQsIGluZGV4XVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGlmIChjaDEgPT09IFwiPlwiICYmIGNoMiA9PT0gXCI+XCIgJiYgY2gzID09PSBcIj1cIikge1xuICAgICAgICBpbmRleCArPSAzO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogVG9rZW4uUHVuY3R1YXRvcixcbiAgICAgICAgICAgIHZhbHVlOiBcIj4+PVwiLFxuICAgICAgICAgICAgbGluZU51bWJlcjogbGluZU51bWJlcixcbiAgICAgICAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgICAgICAgcmFuZ2U6IFtzdGFydCwgaW5kZXhdXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gVGhlIC4uLiBvcGVyYXRvciAoc3ByZWFkLCByZXN0UGFyYW1zLCBKU1gsIGV0Yy4pXG4gICAgaWYgKGV4dHJhLmVjbWFGZWF0dXJlcy5zcHJlYWQgfHxcbiAgICAgICAgZXh0cmEuZWNtYUZlYXR1cmVzLnJlc3RQYXJhbXMgfHxcbiAgICAgICAgKGV4dHJhLmVjbWFGZWF0dXJlcy5qc3ggJiYgc3RhdGUuaW5KU1hTcHJlYWRBdHRyaWJ1dGUpXG4gICAgKSB7XG4gICAgICAgIGlmIChjaDEgPT09IFwiLlwiICYmIGNoMiA9PT0gXCIuXCIgJiYgY2gzID09PSBcIi5cIikge1xuICAgICAgICAgICAgaW5kZXggKz0gMztcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdHlwZTogVG9rZW4uUHVuY3R1YXRvcixcbiAgICAgICAgICAgICAgICB2YWx1ZTogXCIuLi5cIixcbiAgICAgICAgICAgICAgICBsaW5lTnVtYmVyOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgICAgICAgICAgIHJhbmdlOiBbc3RhcnQsIGluZGV4XVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIE90aGVyIDItY2hhcmFjdGVyIHB1bmN0dWF0b3JzOiArKyAtLSA8PCA+PiAmJiB8fFxuICAgIGlmIChjaDEgPT09IGNoMiAmJiAoXCIrLTw+JnxcIi5pbmRleE9mKGNoMSkgPj0gMCkpIHtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IFRva2VuLlB1bmN0dWF0b3IsXG4gICAgICAgICAgICB2YWx1ZTogY2gxICsgY2gyLFxuICAgICAgICAgICAgbGluZU51bWJlcjogbGluZU51bWJlcixcbiAgICAgICAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgICAgICAgcmFuZ2U6IFtzdGFydCwgaW5kZXhdXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gdGhlID0+IGZvciBhcnJvdyBmdW5jdGlvbnNcbiAgICBpZiAoZXh0cmEuZWNtYUZlYXR1cmVzLmFycm93RnVuY3Rpb25zKSB7XG4gICAgICAgIGlmIChjaDEgPT09IFwiPVwiICYmIGNoMiA9PT0gXCI+XCIpIHtcbiAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHR5cGU6IFRva2VuLlB1bmN0dWF0b3IsXG4gICAgICAgICAgICAgICAgdmFsdWU6IFwiPT5cIixcbiAgICAgICAgICAgICAgICBsaW5lTnVtYmVyOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgICAgICAgICAgIHJhbmdlOiBbc3RhcnQsIGluZGV4XVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChcIjw+PSErLSolJnxeL1wiLmluZGV4T2YoY2gxKSA+PSAwKSB7XG4gICAgICAgICsraW5kZXg7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBUb2tlbi5QdW5jdHVhdG9yLFxuICAgICAgICAgICAgdmFsdWU6IGNoMSxcbiAgICAgICAgICAgIGxpbmVOdW1iZXI6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgICAgICAgIHJhbmdlOiBbc3RhcnQsIGluZGV4XVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGlmIChjaDEgPT09IFwiLlwiKSB7XG4gICAgICAgICsraW5kZXg7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBUb2tlbi5QdW5jdHVhdG9yLFxuICAgICAgICAgICAgdmFsdWU6IGNoMSxcbiAgICAgICAgICAgIGxpbmVOdW1iZXI6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgICAgICAgIHJhbmdlOiBbc3RhcnQsIGluZGV4XVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCJJTExFR0FMXCIpO1xufVxuXG4vLyA3LjguMyBOdW1lcmljIExpdGVyYWxzXG5cbmZ1bmN0aW9uIHNjYW5IZXhMaXRlcmFsKHN0YXJ0KSB7XG4gICAgdmFyIG51bWJlciA9IFwiXCI7XG5cbiAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgaWYgKCFzeW50YXguaXNIZXhEaWdpdChzb3VyY2VbaW5kZXhdKSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgbnVtYmVyICs9IHNvdXJjZVtpbmRleCsrXTtcbiAgICB9XG5cbiAgICBpZiAobnVtYmVyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlcy5VbmV4cGVjdGVkVG9rZW4sIFwiSUxMRUdBTFwiKTtcbiAgICB9XG5cbiAgICBpZiAoc3ludGF4LmlzSWRlbnRpZmllclN0YXJ0KHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSkpIHtcbiAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuVW5leHBlY3RlZFRva2VuLCBcIklMTEVHQUxcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogVG9rZW4uTnVtZXJpY0xpdGVyYWwsXG4gICAgICAgIHZhbHVlOiBwYXJzZUludChcIjB4XCIgKyBudW1iZXIsIDE2KSxcbiAgICAgICAgbGluZU51bWJlcjogbGluZU51bWJlcixcbiAgICAgICAgbGluZVN0YXJ0OiBsaW5lU3RhcnQsXG4gICAgICAgIHJhbmdlOiBbc3RhcnQsIGluZGV4XVxuICAgIH07XG59XG5cbmZ1bmN0aW9uIHNjYW5CaW5hcnlMaXRlcmFsKHN0YXJ0KSB7XG4gICAgdmFyIGNoLCBudW1iZXIgPSBcIlwiO1xuXG4gICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNoID0gc291cmNlW2luZGV4XTtcbiAgICAgICAgaWYgKGNoICE9PSBcIjBcIiAmJiBjaCAhPT0gXCIxXCIpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIG51bWJlciArPSBzb3VyY2VbaW5kZXgrK107XG4gICAgfVxuXG4gICAgaWYgKG51bWJlci5sZW5ndGggPT09IDApIHtcbiAgICAgICAgLy8gb25seSAwYiBvciAwQlxuICAgICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlcy5VbmV4cGVjdGVkVG9rZW4sIFwiSUxMRUdBTFwiKTtcbiAgICB9XG5cblxuICAgIGlmIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgICAgaWYgKHN5bnRheC5pc0lkZW50aWZpZXJTdGFydChjaCkgfHwgc3ludGF4LmlzRGVjaW1hbERpZ2l0KGNoKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuVW5leHBlY3RlZFRva2VuLCBcIklMTEVHQUxcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBUb2tlbi5OdW1lcmljTGl0ZXJhbCxcbiAgICAgICAgdmFsdWU6IHBhcnNlSW50KG51bWJlciwgMiksXG4gICAgICAgIGxpbmVOdW1iZXI6IGxpbmVOdW1iZXIsXG4gICAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgICByYW5nZTogW3N0YXJ0LCBpbmRleF1cbiAgICB9O1xufVxuXG5mdW5jdGlvbiBzY2FuT2N0YWxMaXRlcmFsKHByZWZpeCwgc3RhcnQpIHtcbiAgICB2YXIgbnVtYmVyLCBvY3RhbDtcblxuICAgIGlmIChzeW50YXguaXNPY3RhbERpZ2l0KHByZWZpeCkpIHtcbiAgICAgICAgb2N0YWwgPSB0cnVlO1xuICAgICAgICBudW1iZXIgPSBcIjBcIiArIHNvdXJjZVtpbmRleCsrXTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBvY3RhbCA9IGZhbHNlO1xuICAgICAgICArK2luZGV4O1xuICAgICAgICBudW1iZXIgPSBcIlwiO1xuICAgIH1cblxuICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBpZiAoIXN5bnRheC5pc09jdGFsRGlnaXQoc291cmNlW2luZGV4XSkpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIG51bWJlciArPSBzb3VyY2VbaW5kZXgrK107XG4gICAgfVxuXG4gICAgaWYgKCFvY3RhbCAmJiBudW1iZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIC8vIG9ubHkgMG8gb3IgME9cbiAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuVW5leHBlY3RlZFRva2VuLCBcIklMTEVHQUxcIik7XG4gICAgfVxuXG4gICAgaWYgKHN5bnRheC5pc0lkZW50aWZpZXJTdGFydChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkpIHx8IHN5bnRheC5pc0RlY2ltYWxEaWdpdChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkpKSB7XG4gICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCJJTExFR0FMXCIpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IFRva2VuLk51bWVyaWNMaXRlcmFsLFxuICAgICAgICB2YWx1ZTogcGFyc2VJbnQobnVtYmVyLCA4KSxcbiAgICAgICAgb2N0YWw6IG9jdGFsLFxuICAgICAgICBsaW5lTnVtYmVyOiBsaW5lTnVtYmVyLFxuICAgICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgICAgcmFuZ2U6IFtzdGFydCwgaW5kZXhdXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gc2Nhbk51bWVyaWNMaXRlcmFsKCkge1xuICAgIHZhciBudW1iZXIsIHN0YXJ0LCBjaDtcblxuICAgIGNoID0gc291cmNlW2luZGV4XTtcbiAgICBhc3NlcnQoc3ludGF4LmlzRGVjaW1hbERpZ2l0KGNoLmNoYXJDb2RlQXQoMCkpIHx8IChjaCA9PT0gXCIuXCIpLFxuICAgICAgICBcIk51bWVyaWMgbGl0ZXJhbCBtdXN0IHN0YXJ0IHdpdGggYSBkZWNpbWFsIGRpZ2l0IG9yIGEgZGVjaW1hbCBwb2ludFwiKTtcblxuICAgIHN0YXJ0ID0gaW5kZXg7XG4gICAgbnVtYmVyID0gXCJcIjtcbiAgICBpZiAoY2ggIT09IFwiLlwiKSB7XG4gICAgICAgIG51bWJlciA9IHNvdXJjZVtpbmRleCsrXTtcbiAgICAgICAgY2ggPSBzb3VyY2VbaW5kZXhdO1xuXG4gICAgICAgIC8vIEhleCBudW1iZXIgc3RhcnRzIHdpdGggXCIweFwiLlxuICAgICAgICAvLyBPY3RhbCBudW1iZXIgc3RhcnRzIHdpdGggXCIwXCIuXG4gICAgICAgIGlmIChudW1iZXIgPT09IFwiMFwiKSB7XG4gICAgICAgICAgICBpZiAoY2ggPT09IFwieFwiIHx8IGNoID09PSBcIlhcIikge1xuICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjYW5IZXhMaXRlcmFsKHN0YXJ0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQmluYXJ5IG51bWJlciBpbiBFUzYgc3RhcnRzIHdpdGggJzBiJ1xuICAgICAgICAgICAgaWYgKGV4dHJhLmVjbWFGZWF0dXJlcy5iaW5hcnlMaXRlcmFscykge1xuICAgICAgICAgICAgICAgIGlmIChjaCA9PT0gXCJiXCIgfHwgY2ggPT09IFwiQlwiKSB7XG4gICAgICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzY2FuQmluYXJ5TGl0ZXJhbChzdGFydCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoKGV4dHJhLmVjbWFGZWF0dXJlcy5vY3RhbExpdGVyYWxzICYmIChjaCA9PT0gXCJvXCIgfHwgY2ggPT09IFwiT1wiKSkgfHwgc3ludGF4LmlzT2N0YWxEaWdpdChjaCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2Nhbk9jdGFsTGl0ZXJhbChjaCwgc3RhcnQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBkZWNpbWFsIG51bWJlciBzdGFydHMgd2l0aCBcIjBcIiBzdWNoIGFzIFwiMDlcIiBpcyBpbGxlZ2FsLlxuICAgICAgICAgICAgaWYgKGNoICYmIHN5bnRheC5pc0RlY2ltYWxEaWdpdChjaC5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgICAgICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCJJTExFR0FMXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgd2hpbGUgKHN5bnRheC5pc0RlY2ltYWxEaWdpdChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkpKSB7XG4gICAgICAgICAgICBudW1iZXIgKz0gc291cmNlW2luZGV4KytdO1xuICAgICAgICB9XG4gICAgICAgIGNoID0gc291cmNlW2luZGV4XTtcbiAgICB9XG5cbiAgICBpZiAoY2ggPT09IFwiLlwiKSB7XG4gICAgICAgIG51bWJlciArPSBzb3VyY2VbaW5kZXgrK107XG4gICAgICAgIHdoaWxlIChzeW50YXguaXNEZWNpbWFsRGlnaXQoc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpKSkge1xuICAgICAgICAgICAgbnVtYmVyICs9IHNvdXJjZVtpbmRleCsrXTtcbiAgICAgICAgfVxuICAgICAgICBjaCA9IHNvdXJjZVtpbmRleF07XG4gICAgfVxuXG4gICAgaWYgKGNoID09PSBcImVcIiB8fCBjaCA9PT0gXCJFXCIpIHtcbiAgICAgICAgbnVtYmVyICs9IHNvdXJjZVtpbmRleCsrXTtcblxuICAgICAgICBjaCA9IHNvdXJjZVtpbmRleF07XG4gICAgICAgIGlmIChjaCA9PT0gXCIrXCIgfHwgY2ggPT09IFwiLVwiKSB7XG4gICAgICAgICAgICBudW1iZXIgKz0gc291cmNlW2luZGV4KytdO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzeW50YXguaXNEZWNpbWFsRGlnaXQoc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpKSkge1xuICAgICAgICAgICAgd2hpbGUgKHN5bnRheC5pc0RlY2ltYWxEaWdpdChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkpKSB7XG4gICAgICAgICAgICAgICAgbnVtYmVyICs9IHNvdXJjZVtpbmRleCsrXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCJJTExFR0FMXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHN5bnRheC5pc0lkZW50aWZpZXJTdGFydChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkpKSB7XG4gICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCJJTExFR0FMXCIpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IFRva2VuLk51bWVyaWNMaXRlcmFsLFxuICAgICAgICB2YWx1ZTogcGFyc2VGbG9hdChudW1iZXIpLFxuICAgICAgICBsaW5lTnVtYmVyOiBsaW5lTnVtYmVyLFxuICAgICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgICAgcmFuZ2U6IFtzdGFydCwgaW5kZXhdXG4gICAgfTtcbn1cblxuLyoqXG4gKiBTY2FuIGEgc3RyaW5nIGVzY2FwZSBzZXF1ZW5jZSBhbmQgcmV0dXJuIGl0cyBzcGVjaWFsIGNoYXJhY3Rlci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjaCBUaGUgc3RhcnRpbmcgY2hhcmFjdGVyIG9mIHRoZSBnaXZlbiBzZXF1ZW5jZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXIgYW5kIGEgZmxhZ1xuICogaWYgdGhlIGVzY2FwZSBzZXF1ZW5jZSB3YXMgYW4gb2N0YWwuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBzY2FuRXNjYXBlU2VxdWVuY2UoY2gpIHtcbiAgICB2YXIgY29kZSxcbiAgICAgICAgdW5lc2NhcGVkLFxuICAgICAgICByZXN0b3JlLFxuICAgICAgICBlc2NhcGVkQ2gsXG4gICAgICAgIG9jdGFsID0gZmFsc2U7XG5cbiAgICAvLyBBbiBlc2NhcGUgc2VxdWVuY2UgY2Fubm90IGJlIGVtcHR5XG4gICAgaWYgKCFjaCkge1xuICAgICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlcy5VbmV4cGVjdGVkVG9rZW4sIFwiSUxMRUdBTFwiKTtcbiAgICB9XG5cbiAgICBpZiAoc3ludGF4LmlzTGluZVRlcm1pbmF0b3IoY2guY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgICAgKytsaW5lTnVtYmVyO1xuICAgICAgICBpZiAoY2ggPT09IFwiXFxyXCIgJiYgc291cmNlW2luZGV4XSA9PT0gXCJcXG5cIikge1xuICAgICAgICAgICAgKytpbmRleDtcbiAgICAgICAgfVxuICAgICAgICBsaW5lU3RhcnQgPSBpbmRleDtcbiAgICAgICAgZXNjYXBlZENoID0gXCJcIjtcbiAgICB9IGVsc2UgaWYgKGNoID09PSBcInVcIiAmJiBzb3VyY2VbaW5kZXhdID09PSBcIntcIikge1xuICAgICAgICAvLyBIYW5kbGUgRVM2IGV4dGVuZGVkIHVuaWNvZGUgY29kZSBwb2ludCBlc2NhcGUgc2VxdWVuY2VzLlxuICAgICAgICBpZiAoZXh0cmEuZWNtYUZlYXR1cmVzLnVuaWNvZGVDb2RlUG9pbnRFc2NhcGVzKSB7XG4gICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgZXNjYXBlZENoID0gc2NhblVuaWNvZGVDb2RlUG9pbnRFc2NhcGUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCJJTExFR0FMXCIpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChjaCA9PT0gXCJ1XCIgfHwgY2ggPT09IFwieFwiKSB7XG4gICAgICAgIC8vIEhhbmRsZSBvdGhlciB1bmljb2RlIGFuZCBoZXggY29kZXMgbm9ybWFsbHlcbiAgICAgICAgcmVzdG9yZSA9IGluZGV4O1xuICAgICAgICB1bmVzY2FwZWQgPSBzY2FuSGV4RXNjYXBlKGNoKTtcbiAgICAgICAgaWYgKHVuZXNjYXBlZCkge1xuICAgICAgICAgICAgZXNjYXBlZENoID0gdW5lc2NhcGVkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5kZXggPSByZXN0b3JlO1xuICAgICAgICAgICAgZXNjYXBlZENoID0gY2g7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGNoID09PSBcIm5cIikge1xuICAgICAgICBlc2NhcGVkQ2ggPSBcIlxcblwiO1xuICAgIH0gZWxzZSBpZiAoY2ggPT09IFwiclwiKSB7XG4gICAgICAgIGVzY2FwZWRDaCA9IFwiXFxyXCI7XG4gICAgfSBlbHNlIGlmIChjaCA9PT0gXCJ0XCIpIHtcbiAgICAgICAgZXNjYXBlZENoID0gXCJcXHRcIjtcbiAgICB9IGVsc2UgaWYgKGNoID09PSBcImJcIikge1xuICAgICAgICBlc2NhcGVkQ2ggPSBcIlxcYlwiO1xuICAgIH0gZWxzZSBpZiAoY2ggPT09IFwiZlwiKSB7XG4gICAgICAgIGVzY2FwZWRDaCA9IFwiXFxmXCI7XG4gICAgfSBlbHNlIGlmIChjaCA9PT0gXCJ2XCIpIHtcbiAgICAgICAgZXNjYXBlZENoID0gXCJcXHZcIjtcbiAgICB9IGVsc2UgaWYgKHN5bnRheC5pc09jdGFsRGlnaXQoY2gpKSB7XG4gICAgICAgIGNvZGUgPSBcIjAxMjM0NTY3XCIuaW5kZXhPZihjaCk7XG5cbiAgICAgICAgLy8gXFwwIGlzIG5vdCBvY3RhbCBlc2NhcGUgc2VxdWVuY2VcbiAgICAgICAgaWYgKGNvZGUgIT09IDApIHtcbiAgICAgICAgICAgIG9jdGFsID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbmRleCA8IGxlbmd0aCAmJiBzeW50YXguaXNPY3RhbERpZ2l0KHNvdXJjZVtpbmRleF0pKSB7XG4gICAgICAgICAgICBvY3RhbCA9IHRydWU7XG4gICAgICAgICAgICBjb2RlID0gY29kZSAqIDggKyBcIjAxMjM0NTY3XCIuaW5kZXhPZihzb3VyY2VbaW5kZXgrK10pO1xuXG4gICAgICAgICAgICAvLyAzIGRpZ2l0cyBhcmUgb25seSBhbGxvd2VkIHdoZW4gc3RyaW5nIHN0YXJ0cyB3aXRoIDAsIDEsIDIsIDNcbiAgICAgICAgICAgIGlmIChcIjAxMjNcIi5pbmRleE9mKGNoKSA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgIGluZGV4IDwgbGVuZ3RoICYmXG4gICAgICAgICAgICAgICAgICAgIHN5bnRheC5pc09jdGFsRGlnaXQoc291cmNlW2luZGV4XSkpIHtcbiAgICAgICAgICAgICAgICBjb2RlID0gY29kZSAqIDggKyBcIjAxMjM0NTY3XCIuaW5kZXhPZihzb3VyY2VbaW5kZXgrK10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVzY2FwZWRDaCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZXNjYXBlZENoID0gY2g7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY2g6IGVzY2FwZWRDaCxcbiAgICAgICAgb2N0YWw6IG9jdGFsXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gc2NhblN0cmluZ0xpdGVyYWwoKSB7XG4gICAgdmFyIHN0ciA9IFwiXCIsXG4gICAgICAgIGNoLFxuICAgICAgICBlc2NhcGVkU2VxdWVuY2UsXG4gICAgICAgIG9jdGFsID0gZmFsc2UsXG4gICAgICAgIHN0YXJ0ID0gaW5kZXgsXG4gICAgICAgIHN0YXJ0TGluZU51bWJlciA9IGxpbmVOdW1iZXIsXG4gICAgICAgIHN0YXJ0TGluZVN0YXJ0ID0gbGluZVN0YXJ0LFxuICAgICAgICBxdW90ZSA9IHNvdXJjZVtpbmRleF07XG5cbiAgICBhc3NlcnQoKHF1b3RlID09PSBcIidcIiB8fCBxdW90ZSA9PT0gXCJcXFwiXCIpLFxuICAgICAgICBcIlN0cmluZyBsaXRlcmFsIG11c3Qgc3RhcnRzIHdpdGggYSBxdW90ZVwiKTtcblxuICAgICsraW5kZXg7XG5cbiAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgY2ggPSBzb3VyY2VbaW5kZXgrK107XG5cbiAgICAgICAgaWYgKHN5bnRheC5pc0xpbmVUZXJtaW5hdG9yKGNoLmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfSBlbHNlIGlmIChjaCA9PT0gcXVvdGUpIHtcbiAgICAgICAgICAgIHF1b3RlID0gXCJcIjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9IGVsc2UgaWYgKGNoID09PSBcIlxcXFxcIikge1xuICAgICAgICAgICAgY2ggPSBzb3VyY2VbaW5kZXgrK107XG4gICAgICAgICAgICBlc2NhcGVkU2VxdWVuY2UgPSBzY2FuRXNjYXBlU2VxdWVuY2UoY2gpO1xuICAgICAgICAgICAgc3RyICs9IGVzY2FwZWRTZXF1ZW5jZS5jaDtcbiAgICAgICAgICAgIG9jdGFsID0gZXNjYXBlZFNlcXVlbmNlLm9jdGFsIHx8IG9jdGFsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RyICs9IGNoO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHF1b3RlICE9PSBcIlwiKSB7XG4gICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCJJTExFR0FMXCIpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IFRva2VuLlN0cmluZ0xpdGVyYWwsXG4gICAgICAgIHZhbHVlOiBzdHIsXG4gICAgICAgIG9jdGFsOiBvY3RhbCxcbiAgICAgICAgc3RhcnRMaW5lTnVtYmVyOiBzdGFydExpbmVOdW1iZXIsXG4gICAgICAgIHN0YXJ0TGluZVN0YXJ0OiBzdGFydExpbmVTdGFydCxcbiAgICAgICAgbGluZU51bWJlcjogbGluZU51bWJlcixcbiAgICAgICAgbGluZVN0YXJ0OiBsaW5lU3RhcnQsXG4gICAgICAgIHJhbmdlOiBbc3RhcnQsIGluZGV4XVxuICAgIH07XG59XG5cbi8qKlxuICogU2NhbiBhIHRlbXBsYXRlIHN0cmluZyBhbmQgcmV0dXJuIGEgdG9rZW4uIFRoaXMgc2NhbnMgYm90aCB0aGUgZmlyc3QgYW5kXG4gKiBzdWJzZXF1ZW50IHBpZWNlcyBvZiBhIHRlbXBsYXRlIHN0cmluZyBhbmQgYXNzdW1lcyB0aGF0IHRoZSBmaXJzdCBiYWNrdGlja1xuICogb3IgdGhlIGNsb3NpbmcgfSBoYXZlIGFscmVhZHkgYmVlbiBzY2FubmVkLlxuICogQHJldHVybnMge1Rva2VufSBUaGUgdGVtcGxhdGUgc3RyaW5nIHRva2VuLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gc2NhblRlbXBsYXRlKCkge1xuICAgIHZhciBjb29rZWQgPSBcIlwiLFxuICAgICAgICBjaCxcbiAgICAgICAgZXNjYXBlZFNlcXVlbmNlLFxuICAgICAgICBzdGFydCA9IGluZGV4LFxuICAgICAgICB0ZXJtaW5hdGVkID0gZmFsc2UsXG4gICAgICAgIHRhaWwgPSBmYWxzZSxcbiAgICAgICAgaGVhZCA9IChzb3VyY2VbaW5kZXhdID09PSBcImBcIik7XG5cbiAgICArK2luZGV4O1xuXG4gICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNoID0gc291cmNlW2luZGV4KytdO1xuXG4gICAgICAgIGlmIChjaCA9PT0gXCJgXCIpIHtcbiAgICAgICAgICAgIHRhaWwgPSB0cnVlO1xuICAgICAgICAgICAgdGVybWluYXRlZCA9IHRydWU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfSBlbHNlIGlmIChjaCA9PT0gXCIkXCIpIHtcbiAgICAgICAgICAgIGlmIChzb3VyY2VbaW5kZXhdID09PSBcIntcIikge1xuICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICAgICAgdGVybWluYXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb29rZWQgKz0gY2g7XG4gICAgICAgIH0gZWxzZSBpZiAoY2ggPT09IFwiXFxcXFwiKSB7XG4gICAgICAgICAgICBjaCA9IHNvdXJjZVtpbmRleCsrXTtcbiAgICAgICAgICAgIGVzY2FwZWRTZXF1ZW5jZSA9IHNjYW5Fc2NhcGVTZXF1ZW5jZShjaCk7XG5cbiAgICAgICAgICAgIGlmIChlc2NhcGVkU2VxdWVuY2Uub2N0YWwpIHtcbiAgICAgICAgICAgICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlcy5UZW1wbGF0ZU9jdGFsTGl0ZXJhbCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvb2tlZCArPSBlc2NhcGVkU2VxdWVuY2UuY2g7XG5cbiAgICAgICAgfSBlbHNlIGlmIChzeW50YXguaXNMaW5lVGVybWluYXRvcihjaC5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgICAgICAgKytsaW5lTnVtYmVyO1xuICAgICAgICAgICAgaWYgKGNoID09PSBcIlxcclwiICYmIHNvdXJjZVtpbmRleF0gPT09IFwiXFxuXCIpIHtcbiAgICAgICAgICAgICAgICArK2luZGV4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGluZVN0YXJ0ID0gaW5kZXg7XG4gICAgICAgICAgICBjb29rZWQgKz0gXCJcXG5cIjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvb2tlZCArPSBjaDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdGVybWluYXRlZCkge1xuICAgICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlcy5VbmV4cGVjdGVkVG9rZW4sIFwiSUxMRUdBTFwiKTtcbiAgICB9XG5cbiAgICBpZiAoaW5kZXggPiBzdGF0ZS5jdXJseUxhc3RJbmRleCkge1xuICAgICAgICBzdGF0ZS5jdXJseUxhc3RJbmRleCA9IGluZGV4O1xuXG4gICAgICAgIGlmICghdGFpbCkge1xuICAgICAgICAgICAgc3RhdGUuY3VybHlTdGFjay5wdXNoKFwidGVtcGxhdGVcIik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWhlYWQpIHtcbiAgICAgICAgICAgIHN0YXRlLmN1cmx5U3RhY2sucG9wKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBUb2tlbi5UZW1wbGF0ZSxcbiAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICAgIGNvb2tlZDogY29va2VkLFxuICAgICAgICAgICAgcmF3OiBzb3VyY2Uuc2xpY2Uoc3RhcnQgKyAxLCBpbmRleCAtICgodGFpbCkgPyAxIDogMikpXG4gICAgICAgIH0sXG4gICAgICAgIGhlYWQ6IGhlYWQsXG4gICAgICAgIHRhaWw6IHRhaWwsXG4gICAgICAgIGxpbmVOdW1iZXI6IGxpbmVOdW1iZXIsXG4gICAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgICByYW5nZTogW3N0YXJ0LCBpbmRleF1cbiAgICB9O1xufVxuXG5mdW5jdGlvbiB0ZXN0UmVnRXhwKHBhdHRlcm4sIGZsYWdzKSB7XG4gICAgdmFyIHRtcCA9IHBhdHRlcm4sXG4gICAgICAgIHZhbGlkRmxhZ3MgPSBcImdtc2lcIjtcblxuICAgIGlmIChleHRyYS5lY21hRmVhdHVyZXMucmVnZXhZRmxhZykge1xuICAgICAgICB2YWxpZEZsYWdzICs9IFwieVwiO1xuICAgIH1cblxuICAgIGlmIChleHRyYS5lY21hRmVhdHVyZXMucmVnZXhVRmxhZykge1xuICAgICAgICB2YWxpZEZsYWdzICs9IFwidVwiO1xuICAgIH1cblxuICAgIGlmICghUmVnRXhwKFwiXltcIiArIHZhbGlkRmxhZ3MgKyBcIl0qJFwiKS50ZXN0KGZsYWdzKSkge1xuICAgICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlcy5JbnZhbGlkUmVnRXhwRmxhZyk7XG4gICAgfVxuXG5cbiAgICBpZiAoZmxhZ3MuaW5kZXhPZihcInVcIikgPj0gMCkge1xuICAgICAgICAvLyBSZXBsYWNlIGVhY2ggYXN0cmFsIHN5bWJvbCBhbmQgZXZlcnkgVW5pY29kZSBjb2RlIHBvaW50XG4gICAgICAgIC8vIGVzY2FwZSBzZXF1ZW5jZSB3aXRoIGEgc2luZ2xlIEFTQ0lJIHN5bWJvbCB0byBhdm9pZCB0aHJvd2luZyBvblxuICAgICAgICAvLyByZWd1bGFyIGV4cHJlc3Npb25zIHRoYXQgYXJlIG9ubHkgdmFsaWQgaW4gY29tYmluYXRpb24gd2l0aCB0aGVcbiAgICAgICAgLy8gYC91YCBmbGFnLlxuICAgICAgICAvLyBOb3RlOiByZXBsYWNpbmcgd2l0aCB0aGUgQVNDSUkgc3ltYm9sIGB4YCBtaWdodCBjYXVzZSBmYWxzZVxuICAgICAgICAvLyBuZWdhdGl2ZXMgaW4gdW5saWtlbHkgc2NlbmFyaW9zLiBGb3IgZXhhbXBsZSwgYFtcXHV7NjF9LWJdYCBpcyBhXG4gICAgICAgIC8vIHBlcmZlY3RseSB2YWxpZCBwYXR0ZXJuIHRoYXQgaXMgZXF1aXZhbGVudCB0byBgW2EtYl1gLCBidXQgaXRcbiAgICAgICAgLy8gd291bGQgYmUgcmVwbGFjZWQgYnkgYFt4LWJdYCB3aGljaCB0aHJvd3MgYW4gZXJyb3IuXG4gICAgICAgIHRtcCA9IHRtcFxuICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFx1XFx7KFswLTlhLWZBLUZdKylcXH0vZywgZnVuY3Rpb24gKCQwLCAkMSkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJzZUludCgkMSwgMTYpIDw9IDB4MTBGRkZGKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInhcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuSW52YWxpZFJlZ0V4cCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnJlcGxhY2UoL1tcXHVEODAwLVxcdURCRkZdW1xcdURDMDAtXFx1REZGRl0vZywgXCJ4XCIpO1xuICAgIH1cblxuICAgIC8vIEZpcnN0LCBkZXRlY3QgaW52YWxpZCByZWd1bGFyIGV4cHJlc3Npb25zLlxuICAgIHRyeSB7XG4gICAgICAgIFJlZ0V4cCh0bXApO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuSW52YWxpZFJlZ0V4cCk7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIGEgcmVndWxhciBleHByZXNzaW9uIG9iamVjdCBmb3IgdGhpcyBwYXR0ZXJuLWZsYWcgcGFpciwgb3JcbiAgICAvLyBgbnVsbGAgaW4gY2FzZSB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBkb2Vzbid0IHN1cHBvcnQgdGhlIGZsYWdzIGl0XG4gICAgLy8gdXNlcy5cbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gbmV3IFJlZ0V4cChwYXR0ZXJuLCBmbGFncyk7XG4gICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gc2NhblJlZ0V4cEJvZHkoKSB7XG4gICAgdmFyIGNoLCBzdHIsIGNsYXNzTWFya2VyLCB0ZXJtaW5hdGVkLCBib2R5O1xuXG4gICAgY2ggPSBzb3VyY2VbaW5kZXhdO1xuICAgIGFzc2VydChjaCA9PT0gXCIvXCIsIFwiUmVndWxhciBleHByZXNzaW9uIGxpdGVyYWwgbXVzdCBzdGFydCB3aXRoIGEgc2xhc2hcIik7XG4gICAgc3RyID0gc291cmNlW2luZGV4KytdO1xuXG4gICAgY2xhc3NNYXJrZXIgPSBmYWxzZTtcbiAgICB0ZXJtaW5hdGVkID0gZmFsc2U7XG4gICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNoID0gc291cmNlW2luZGV4KytdO1xuICAgICAgICBzdHIgKz0gY2g7XG4gICAgICAgIGlmIChjaCA9PT0gXCJcXFxcXCIpIHtcbiAgICAgICAgICAgIGNoID0gc291cmNlW2luZGV4KytdO1xuICAgICAgICAgICAgLy8gRUNNQS0yNjIgNy44LjVcbiAgICAgICAgICAgIGlmIChzeW50YXguaXNMaW5lVGVybWluYXRvcihjaC5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgICAgICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVudGVybWluYXRlZFJlZ0V4cCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdHIgKz0gY2g7XG4gICAgICAgIH0gZWxzZSBpZiAoc3ludGF4LmlzTGluZVRlcm1pbmF0b3IoY2guY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVudGVybWluYXRlZFJlZ0V4cCk7XG4gICAgICAgIH0gZWxzZSBpZiAoY2xhc3NNYXJrZXIpIHtcbiAgICAgICAgICAgIGlmIChjaCA9PT0gXCJdXCIpIHtcbiAgICAgICAgICAgICAgICBjbGFzc01hcmtlciA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNoID09PSBcIi9cIikge1xuICAgICAgICAgICAgICAgIHRlcm1pbmF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PT0gXCJbXCIpIHtcbiAgICAgICAgICAgICAgICBjbGFzc01hcmtlciA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRlcm1pbmF0ZWQpIHtcbiAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuVW50ZXJtaW5hdGVkUmVnRXhwKTtcbiAgICB9XG5cbiAgICAvLyBFeGNsdWRlIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHNsYXNoLlxuICAgIGJvZHkgPSBzdHIuc3Vic3RyKDEsIHN0ci5sZW5ndGggLSAyKTtcbiAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZTogYm9keSxcbiAgICAgICAgbGl0ZXJhbDogc3RyXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gc2NhblJlZ0V4cEZsYWdzKCkge1xuICAgIHZhciBjaCwgc3RyLCBmbGFncywgcmVzdG9yZTtcblxuICAgIHN0ciA9IFwiXCI7XG4gICAgZmxhZ3MgPSBcIlwiO1xuICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBjaCA9IHNvdXJjZVtpbmRleF07XG4gICAgICAgIGlmICghc3ludGF4LmlzSWRlbnRpZmllclBhcnQoY2guY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgKytpbmRleDtcbiAgICAgICAgaWYgKGNoID09PSBcIlxcXFxcIiAmJiBpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgY2ggPSBzb3VyY2VbaW5kZXhdO1xuICAgICAgICAgICAgaWYgKGNoID09PSBcInVcIikge1xuICAgICAgICAgICAgICAgICsraW5kZXg7XG4gICAgICAgICAgICAgICAgcmVzdG9yZSA9IGluZGV4O1xuICAgICAgICAgICAgICAgIGNoID0gc2NhbkhleEVzY2FwZShcInVcIik7XG4gICAgICAgICAgICAgICAgaWYgKGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGZsYWdzICs9IGNoO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHN0ciArPSBcIlxcXFx1XCI7IHJlc3RvcmUgPCBpbmRleDsgKytyZXN0b3JlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHIgKz0gc291cmNlW3Jlc3RvcmVdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaW5kZXggPSByZXN0b3JlO1xuICAgICAgICAgICAgICAgICAgICBmbGFncyArPSBcInVcIjtcbiAgICAgICAgICAgICAgICAgICAgc3RyICs9IFwiXFxcXHVcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3dFcnJvclRvbGVyYW50KHt9LCBNZXNzYWdlcy5VbmV4cGVjdGVkVG9rZW4sIFwiSUxMRUdBTFwiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RyICs9IFwiXFxcXFwiO1xuICAgICAgICAgICAgICAgIHRocm93RXJyb3JUb2xlcmFudCh7fSwgTWVzc2FnZXMuVW5leHBlY3RlZFRva2VuLCBcIklMTEVHQUxcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmbGFncyArPSBjaDtcbiAgICAgICAgICAgIHN0ciArPSBjaDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHZhbHVlOiBmbGFncyxcbiAgICAgICAgbGl0ZXJhbDogc3RyXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gc2NhblJlZ0V4cCgpIHtcbiAgICB2YXIgc3RhcnQsIGJvZHksIGZsYWdzLCB2YWx1ZTtcblxuICAgIGxvb2thaGVhZCA9IG51bGw7XG4gICAgc2tpcENvbW1lbnQoKTtcbiAgICBzdGFydCA9IGluZGV4O1xuXG4gICAgYm9keSA9IHNjYW5SZWdFeHBCb2R5KCk7XG4gICAgZmxhZ3MgPSBzY2FuUmVnRXhwRmxhZ3MoKTtcbiAgICB2YWx1ZSA9IHRlc3RSZWdFeHAoYm9keS52YWx1ZSwgZmxhZ3MudmFsdWUpO1xuXG4gICAgaWYgKGV4dHJhLnRva2VuaXplKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBUb2tlbi5SZWd1bGFyRXhwcmVzc2lvbixcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgIHJlZ2V4OiB7XG4gICAgICAgICAgICAgICAgcGF0dGVybjogYm9keS52YWx1ZSxcbiAgICAgICAgICAgICAgICBmbGFnczogZmxhZ3MudmFsdWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsaW5lTnVtYmVyOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgbGluZVN0YXJ0OiBsaW5lU3RhcnQsXG4gICAgICAgICAgICByYW5nZTogW3N0YXJ0LCBpbmRleF1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBsaXRlcmFsOiBib2R5LmxpdGVyYWwgKyBmbGFncy5saXRlcmFsLFxuICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgIHJlZ2V4OiB7XG4gICAgICAgICAgICBwYXR0ZXJuOiBib2R5LnZhbHVlLFxuICAgICAgICAgICAgZmxhZ3M6IGZsYWdzLnZhbHVlXG4gICAgICAgIH0sXG4gICAgICAgIHJhbmdlOiBbc3RhcnQsIGluZGV4XVxuICAgIH07XG59XG5cbmZ1bmN0aW9uIGNvbGxlY3RSZWdleCgpIHtcbiAgICB2YXIgcG9zLCBsb2MsIHJlZ2V4LCB0b2tlbjtcblxuICAgIHNraXBDb21tZW50KCk7XG5cbiAgICBwb3MgPSBpbmRleDtcbiAgICBsb2MgPSB7XG4gICAgICAgIHN0YXJ0OiB7XG4gICAgICAgICAgICBsaW5lOiBsaW5lTnVtYmVyLFxuICAgICAgICAgICAgY29sdW1uOiBpbmRleCAtIGxpbmVTdGFydFxuICAgICAgICB9XG4gICAgfTtcblxuICAgIHJlZ2V4ID0gc2NhblJlZ0V4cCgpO1xuICAgIGxvYy5lbmQgPSB7XG4gICAgICAgIGxpbmU6IGxpbmVOdW1iZXIsXG4gICAgICAgIGNvbHVtbjogaW5kZXggLSBsaW5lU3RhcnRcbiAgICB9O1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBpZiAoIWV4dHJhLnRva2VuaXplKSB7XG4gICAgICAgIC8vIFBvcCB0aGUgcHJldmlvdXMgdG9rZW4sIHdoaWNoIGlzIGxpa2VseSBcIi9cIiBvciBcIi89XCJcbiAgICAgICAgaWYgKGV4dHJhLnRva2Vucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0b2tlbiA9IGV4dHJhLnRva2Vuc1tleHRyYS50b2tlbnMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICBpZiAodG9rZW4ucmFuZ2VbMF0gPT09IHBvcyAmJiB0b2tlbi50eXBlID09PSBcIlB1bmN0dWF0b3JcIikge1xuICAgICAgICAgICAgICAgIGlmICh0b2tlbi52YWx1ZSA9PT0gXCIvXCIgfHwgdG9rZW4udmFsdWUgPT09IFwiLz1cIikge1xuICAgICAgICAgICAgICAgICAgICBleHRyYS50b2tlbnMucG9wKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZXh0cmEudG9rZW5zLnB1c2goe1xuICAgICAgICAgICAgdHlwZTogXCJSZWd1bGFyRXhwcmVzc2lvblwiLFxuICAgICAgICAgICAgdmFsdWU6IHJlZ2V4LmxpdGVyYWwsXG4gICAgICAgICAgICByZWdleDogcmVnZXgucmVnZXgsXG4gICAgICAgICAgICByYW5nZTogW3BvcywgaW5kZXhdLFxuICAgICAgICAgICAgbG9jOiBsb2NcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlZ2V4O1xufVxuXG5mdW5jdGlvbiBpc0lkZW50aWZpZXJOYW1lKHRva2VuKSB7XG4gICAgcmV0dXJuIHRva2VuLnR5cGUgPT09IFRva2VuLklkZW50aWZpZXIgfHxcbiAgICAgICAgdG9rZW4udHlwZSA9PT0gVG9rZW4uS2V5d29yZCB8fFxuICAgICAgICB0b2tlbi50eXBlID09PSBUb2tlbi5Cb29sZWFuTGl0ZXJhbCB8fFxuICAgICAgICB0b2tlbi50eXBlID09PSBUb2tlbi5OdWxsTGl0ZXJhbDtcbn1cblxuZnVuY3Rpb24gYWR2YW5jZVNsYXNoKCkge1xuICAgIHZhciBwcmV2VG9rZW4sXG4gICAgICAgIGNoZWNrVG9rZW47XG4gICAgLy8gVXNpbmcgdGhlIGZvbGxvd2luZyBhbGdvcml0aG06XG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21vemlsbGEvc3dlZXQuanMvd2lraS9kZXNpZ25cbiAgICBwcmV2VG9rZW4gPSBleHRyYS50b2tlbnNbZXh0cmEudG9rZW5zLmxlbmd0aCAtIDFdO1xuICAgIGlmICghcHJldlRva2VuKSB7XG4gICAgICAgIC8vIE5vdGhpbmcgYmVmb3JlIHRoYXQ6IGl0IGNhbm5vdCBiZSBhIGRpdmlzaW9uLlxuICAgICAgICByZXR1cm4gY29sbGVjdFJlZ2V4KCk7XG4gICAgfVxuICAgIGlmIChwcmV2VG9rZW4udHlwZSA9PT0gXCJQdW5jdHVhdG9yXCIpIHtcbiAgICAgICAgaWYgKHByZXZUb2tlbi52YWx1ZSA9PT0gXCJdXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBzY2FuUHVuY3R1YXRvcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcmV2VG9rZW4udmFsdWUgPT09IFwiKVwiKSB7XG4gICAgICAgICAgICBjaGVja1Rva2VuID0gZXh0cmEudG9rZW5zW2V4dHJhLm9wZW5QYXJlblRva2VuIC0gMV07XG4gICAgICAgICAgICBpZiAoY2hlY2tUb2tlbiAmJlxuICAgICAgICAgICAgICAgICAgICBjaGVja1Rva2VuLnR5cGUgPT09IFwiS2V5d29yZFwiICYmXG4gICAgICAgICAgICAgICAgICAgIChjaGVja1Rva2VuLnZhbHVlID09PSBcImlmXCIgfHxcbiAgICAgICAgICAgICAgICAgICAgIGNoZWNrVG9rZW4udmFsdWUgPT09IFwid2hpbGVcIiB8fFxuICAgICAgICAgICAgICAgICAgICAgY2hlY2tUb2tlbi52YWx1ZSA9PT0gXCJmb3JcIiB8fFxuICAgICAgICAgICAgICAgICAgICAgY2hlY2tUb2tlbi52YWx1ZSA9PT0gXCJ3aXRoXCIpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbGxlY3RSZWdleCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNjYW5QdW5jdHVhdG9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByZXZUb2tlbi52YWx1ZSA9PT0gXCJ9XCIpIHtcbiAgICAgICAgICAgIC8vIERpdmlkaW5nIGEgZnVuY3Rpb24gYnkgYW55dGhpbmcgbWFrZXMgbGl0dGxlIHNlbnNlLFxuICAgICAgICAgICAgLy8gYnV0IHdlIGhhdmUgdG8gY2hlY2sgZm9yIHRoYXQuXG4gICAgICAgICAgICBpZiAoZXh0cmEudG9rZW5zW2V4dHJhLm9wZW5DdXJseVRva2VuIC0gM10gJiZcbiAgICAgICAgICAgICAgICAgICAgZXh0cmEudG9rZW5zW2V4dHJhLm9wZW5DdXJseVRva2VuIC0gM10udHlwZSA9PT0gXCJLZXl3b3JkXCIpIHtcbiAgICAgICAgICAgICAgICAvLyBBbm9ueW1vdXMgZnVuY3Rpb24uXG4gICAgICAgICAgICAgICAgY2hlY2tUb2tlbiA9IGV4dHJhLnRva2Vuc1tleHRyYS5vcGVuQ3VybHlUb2tlbiAtIDRdO1xuICAgICAgICAgICAgICAgIGlmICghY2hlY2tUb2tlbikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2NhblB1bmN0dWF0b3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGV4dHJhLnRva2Vuc1tleHRyYS5vcGVuQ3VybHlUb2tlbiAtIDRdICYmXG4gICAgICAgICAgICAgICAgICAgIGV4dHJhLnRva2Vuc1tleHRyYS5vcGVuQ3VybHlUb2tlbiAtIDRdLnR5cGUgPT09IFwiS2V5d29yZFwiKSB7XG4gICAgICAgICAgICAgICAgLy8gTmFtZWQgZnVuY3Rpb24uXG4gICAgICAgICAgICAgICAgY2hlY2tUb2tlbiA9IGV4dHJhLnRva2Vuc1tleHRyYS5vcGVuQ3VybHlUb2tlbiAtIDVdO1xuICAgICAgICAgICAgICAgIGlmICghY2hlY2tUb2tlbikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29sbGVjdFJlZ2V4KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NhblB1bmN0dWF0b3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGNoZWNrVG9rZW4gZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBmdW5jdGlvbiBpc1xuICAgICAgICAgICAgLy8gYSBkZWNsYXJhdGlvbiBvciBhbiBleHByZXNzaW9uLlxuICAgICAgICAgICAgaWYgKEZuRXhwclRva2Vucy5pbmRleE9mKGNoZWNrVG9rZW4udmFsdWUpID49IDApIHtcbiAgICAgICAgICAgICAgICAvLyBJdCBpcyBhbiBleHByZXNzaW9uLlxuICAgICAgICAgICAgICAgIHJldHVybiBzY2FuUHVuY3R1YXRvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gSXQgaXMgYSBkZWNsYXJhdGlvbi5cbiAgICAgICAgICAgIHJldHVybiBjb2xsZWN0UmVnZXgoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29sbGVjdFJlZ2V4KCk7XG4gICAgfVxuICAgIGlmIChwcmV2VG9rZW4udHlwZSA9PT0gXCJLZXl3b3JkXCIpIHtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3RSZWdleCgpO1xuICAgIH1cbiAgICByZXR1cm4gc2NhblB1bmN0dWF0b3IoKTtcbn1cblxuZnVuY3Rpb24gYWR2YW5jZSgpIHtcbiAgICB2YXIgY2gsXG4gICAgICAgIGFsbG93SlNYID0gZXh0cmEuZWNtYUZlYXR1cmVzLmpzeCxcbiAgICAgICAgYWxsb3dUZW1wbGF0ZVN0cmluZ3MgPSBleHRyYS5lY21hRmVhdHVyZXMudGVtcGxhdGVTdHJpbmdzO1xuXG4gICAgLypcbiAgICAgKiBJZiBKU1ggaXNuJ3QgYWxsb3dlZCBvciBKU1ggaXMgYWxsb3dlZCBhbmQgd2UncmUgbm90IGluc2lkZSBhbiBKU1ggY2hpbGQsXG4gICAgICogdGhlbiBza2lwIGFueSBjb21tZW50cy5cbiAgICAgKi9cbiAgICBpZiAoIWFsbG93SlNYIHx8ICFzdGF0ZS5pbkpTWENoaWxkKSB7XG4gICAgICAgIHNraXBDb21tZW50KCk7XG4gICAgfVxuXG4gICAgaWYgKGluZGV4ID49IGxlbmd0aCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogVG9rZW4uRU9GLFxuICAgICAgICAgICAgbGluZU51bWJlcjogbGluZU51bWJlcixcbiAgICAgICAgICAgIGxpbmVTdGFydDogbGluZVN0YXJ0LFxuICAgICAgICAgICAgcmFuZ2U6IFtpbmRleCwgaW5kZXhdXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gaWYgaW5zaWRlIGFuIEpTWCBjaGlsZCwgdGhlbiBhYm9ydCByZWd1bGFyIHRva2VuaXphdGlvblxuICAgIGlmIChhbGxvd0pTWCAmJiBzdGF0ZS5pbkpTWENoaWxkKSB7XG4gICAgICAgIHJldHVybiBhZHZhbmNlSlNYQ2hpbGQoKTtcbiAgICB9XG5cbiAgICBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcblxuICAgIC8vIFZlcnkgY29tbW9uOiAoIGFuZCApIGFuZCA7XG4gICAgaWYgKGNoID09PSAweDI4IHx8IGNoID09PSAweDI5IHx8IGNoID09PSAweDNCKSB7XG4gICAgICAgIHJldHVybiBzY2FuUHVuY3R1YXRvcigpO1xuICAgIH1cblxuICAgIC8vIFN0cmluZyBsaXRlcmFsIHN0YXJ0cyB3aXRoIHNpbmdsZSBxdW90ZSAoVSswMDI3KSBvciBkb3VibGUgcXVvdGUgKFUrMDAyMikuXG4gICAgaWYgKGNoID09PSAweDI3IHx8IGNoID09PSAweDIyKSB7XG4gICAgICAgIGlmIChhbGxvd0pTWCAmJiBzdGF0ZS5pbkpTWFRhZykge1xuICAgICAgICAgICAgcmV0dXJuIHNjYW5KU1hTdHJpbmdMaXRlcmFsKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc2NhblN0cmluZ0xpdGVyYWwoKTtcbiAgICB9XG5cbiAgICBpZiAoYWxsb3dKU1ggJiYgc3RhdGUuaW5KU1hUYWcgJiYgc3ludGF4LmlzSlNYSWRlbnRpZmllclN0YXJ0KGNoKSkge1xuICAgICAgICByZXR1cm4gc2NhbkpTWElkZW50aWZpZXIoKTtcbiAgICB9XG5cbiAgICAvLyBUZW1wbGF0ZSBzdHJpbmdzIHN0YXJ0IHdpdGggYmFja3RpY2sgKFUrMDA5Nikgb3IgY2xvc2luZyBjdXJseSBicmFjZSAoMTI1KSBhbmQgYmFja3RpY2suXG4gICAgaWYgKGFsbG93VGVtcGxhdGVTdHJpbmdzKSB7XG5cbiAgICAgICAgLy8gdGVtcGxhdGUgc3RyaW5ncyBzdGFydCB3aXRoIGJhY2t0aWNrICg5Nikgb3Igb3BlbiBjdXJseSAoMTI1KSBidXQgb25seSBpZiB0aGUgb3BlblxuICAgICAgICAvLyBjdXJseSBjbG9zZXMgYSBwcmV2aW91c2x5IG9wZW5lZCBjdXJseSBmcm9tIGEgdGVtcGxhdGUuXG4gICAgICAgIGlmIChjaCA9PT0gOTYgfHwgKGNoID09PSAxMjUgJiYgc3RhdGUuY3VybHlTdGFja1tzdGF0ZS5jdXJseVN0YWNrLmxlbmd0aCAtIDFdID09PSBcInRlbXBsYXRlXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gc2NhblRlbXBsYXRlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3ludGF4LmlzSWRlbnRpZmllclN0YXJ0KGNoKSkge1xuICAgICAgICByZXR1cm4gc2NhbklkZW50aWZpZXIoKTtcbiAgICB9XG5cbiAgICAvLyBEb3QgKC4pIFUrMDAyRSBjYW4gYWxzbyBzdGFydCBhIGZsb2F0aW5nLXBvaW50IG51bWJlciwgaGVuY2UgdGhlIG5lZWRcbiAgICAvLyB0byBjaGVjayB0aGUgbmV4dCBjaGFyYWN0ZXIuXG4gICAgaWYgKGNoID09PSAweDJFKSB7XG4gICAgICAgIGlmIChzeW50YXguaXNEZWNpbWFsRGlnaXQoc291cmNlLmNoYXJDb2RlQXQoaW5kZXggKyAxKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBzY2FuTnVtZXJpY0xpdGVyYWwoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2NhblB1bmN0dWF0b3IoKTtcbiAgICB9XG5cbiAgICBpZiAoc3ludGF4LmlzRGVjaW1hbERpZ2l0KGNoKSkge1xuICAgICAgICByZXR1cm4gc2Nhbk51bWVyaWNMaXRlcmFsKCk7XG4gICAgfVxuXG4gICAgLy8gU2xhc2ggKC8pIFUrMDAyRiBjYW4gYWxzbyBzdGFydCBhIHJlZ2V4LlxuICAgIGlmIChleHRyYS50b2tlbml6ZSAmJiBjaCA9PT0gMHgyRikge1xuICAgICAgICByZXR1cm4gYWR2YW5jZVNsYXNoKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNjYW5QdW5jdHVhdG9yKCk7XG59XG5cbmZ1bmN0aW9uIGNvbGxlY3RUb2tlbigpIHtcbiAgICB2YXIgbG9jLCB0b2tlbiwgcmFuZ2UsIHZhbHVlLCBlbnRyeSxcbiAgICAgICAgYWxsb3dKU1ggPSBleHRyYS5lY21hRmVhdHVyZXMuanN4O1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAoIWFsbG93SlNYIHx8ICFzdGF0ZS5pbkpTWENoaWxkKSB7XG4gICAgICAgIHNraXBDb21tZW50KCk7XG4gICAgfVxuXG4gICAgbG9jID0ge1xuICAgICAgICBzdGFydDoge1xuICAgICAgICAgICAgbGluZTogbGluZU51bWJlcixcbiAgICAgICAgICAgIGNvbHVtbjogaW5kZXggLSBsaW5lU3RhcnRcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB0b2tlbiA9IGFkdmFuY2UoKTtcbiAgICBsb2MuZW5kID0ge1xuICAgICAgICBsaW5lOiBsaW5lTnVtYmVyLFxuICAgICAgICBjb2x1bW46IGluZGV4IC0gbGluZVN0YXJ0XG4gICAgfTtcblxuICAgIGlmICh0b2tlbi50eXBlICE9PSBUb2tlbi5FT0YpIHtcbiAgICAgICAgcmFuZ2UgPSBbdG9rZW4ucmFuZ2VbMF0sIHRva2VuLnJhbmdlWzFdXTtcbiAgICAgICAgdmFsdWUgPSBzb3VyY2Uuc2xpY2UodG9rZW4ucmFuZ2VbMF0sIHRva2VuLnJhbmdlWzFdKTtcbiAgICAgICAgZW50cnkgPSB7XG4gICAgICAgICAgICB0eXBlOiBUb2tlbk5hbWVbdG9rZW4udHlwZV0sXG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICByYW5nZTogcmFuZ2UsXG4gICAgICAgICAgICBsb2M6IGxvY1xuICAgICAgICB9O1xuICAgICAgICBpZiAodG9rZW4ucmVnZXgpIHtcbiAgICAgICAgICAgIGVudHJ5LnJlZ2V4ID0ge1xuICAgICAgICAgICAgICAgIHBhdHRlcm46IHRva2VuLnJlZ2V4LnBhdHRlcm4sXG4gICAgICAgICAgICAgICAgZmxhZ3M6IHRva2VuLnJlZ2V4LmZsYWdzXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGV4dHJhLnRva2Vucy5wdXNoKGVudHJ5KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdG9rZW47XG59XG5cbmZ1bmN0aW9uIGxleCgpIHtcbiAgICB2YXIgdG9rZW47XG5cbiAgICB0b2tlbiA9IGxvb2thaGVhZDtcbiAgICBpbmRleCA9IHRva2VuLnJhbmdlWzFdO1xuICAgIGxpbmVOdW1iZXIgPSB0b2tlbi5saW5lTnVtYmVyO1xuICAgIGxpbmVTdGFydCA9IHRva2VuLmxpbmVTdGFydDtcblxuICAgIGxvb2thaGVhZCA9ICh0eXBlb2YgZXh0cmEudG9rZW5zICE9PSBcInVuZGVmaW5lZFwiKSA/IGNvbGxlY3RUb2tlbigpIDogYWR2YW5jZSgpO1xuXG4gICAgaW5kZXggPSB0b2tlbi5yYW5nZVsxXTtcbiAgICBsaW5lTnVtYmVyID0gdG9rZW4ubGluZU51bWJlcjtcbiAgICBsaW5lU3RhcnQgPSB0b2tlbi5saW5lU3RhcnQ7XG5cbiAgICByZXR1cm4gdG9rZW47XG59XG5cbmZ1bmN0aW9uIHBlZWsoKSB7XG4gICAgdmFyIHBvcyxcbiAgICAgICAgbGluZSxcbiAgICAgICAgc3RhcnQ7XG5cbiAgICBwb3MgPSBpbmRleDtcbiAgICBsaW5lID0gbGluZU51bWJlcjtcbiAgICBzdGFydCA9IGxpbmVTdGFydDtcblxuICAgIGxvb2thaGVhZCA9ICh0eXBlb2YgZXh0cmEudG9rZW5zICE9PSBcInVuZGVmaW5lZFwiKSA/IGNvbGxlY3RUb2tlbigpIDogYWR2YW5jZSgpO1xuXG4gICAgaW5kZXggPSBwb3M7XG4gICAgbGluZU51bWJlciA9IGxpbmU7XG4gICAgbGluZVN0YXJ0ID0gc3RhcnQ7XG59XG5cbmZ1bmN0aW9uIGxvb2thaGVhZDIoKSB7XG4gICAgdmFyIGFkdiwgcG9zLCBsaW5lLCBzdGFydCwgcmVzdWx0O1xuXG4gICAgLy8gSWYgd2UgYXJlIGNvbGxlY3RpbmcgdGhlIHRva2VucywgZG9uJ3QgZ3JhYiB0aGUgbmV4dCBvbmUgeWV0LlxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgYWR2ID0gKHR5cGVvZiBleHRyYS5hZHZhbmNlID09PSBcImZ1bmN0aW9uXCIpID8gZXh0cmEuYWR2YW5jZSA6IGFkdmFuY2U7XG5cbiAgICBwb3MgPSBpbmRleDtcbiAgICBsaW5lID0gbGluZU51bWJlcjtcbiAgICBzdGFydCA9IGxpbmVTdGFydDtcblxuICAgIC8vIFNjYW4gZm9yIHRoZSBuZXh0IGltbWVkaWF0ZSB0b2tlbi5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAobG9va2FoZWFkID09PSBudWxsKSB7XG4gICAgICAgIGxvb2thaGVhZCA9IGFkdigpO1xuICAgIH1cbiAgICBpbmRleCA9IGxvb2thaGVhZC5yYW5nZVsxXTtcbiAgICBsaW5lTnVtYmVyID0gbG9va2FoZWFkLmxpbmVOdW1iZXI7XG4gICAgbGluZVN0YXJ0ID0gbG9va2FoZWFkLmxpbmVTdGFydDtcblxuICAgIC8vIEdyYWIgdGhlIHRva2VuIHJpZ2h0IGFmdGVyLlxuICAgIHJlc3VsdCA9IGFkdigpO1xuICAgIGluZGV4ID0gcG9zO1xuICAgIGxpbmVOdW1iZXIgPSBsaW5lO1xuICAgIGxpbmVTdGFydCA9IHN0YXJ0O1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gSlNYXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5mdW5jdGlvbiBnZXRRdWFsaWZpZWRKU1hOYW1lKG9iamVjdCkge1xuICAgIGlmIChvYmplY3QudHlwZSA9PT0gYXN0Tm9kZVR5cGVzLkpTWElkZW50aWZpZXIpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdC5uYW1lO1xuICAgIH1cbiAgICBpZiAob2JqZWN0LnR5cGUgPT09IGFzdE5vZGVUeXBlcy5KU1hOYW1lc3BhY2VkTmFtZSkge1xuICAgICAgICByZXR1cm4gb2JqZWN0Lm5hbWVzcGFjZS5uYW1lICsgXCI6XCIgKyBvYmplY3QubmFtZS5uYW1lO1xuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmIChvYmplY3QudHlwZSA9PT0gYXN0Tm9kZVR5cGVzLkpTWE1lbWJlckV4cHJlc3Npb24pIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIGdldFF1YWxpZmllZEpTWE5hbWUob2JqZWN0Lm9iamVjdCkgKyBcIi5cIiArXG4gICAgICAgICAgICBnZXRRdWFsaWZpZWRKU1hOYW1lKG9iamVjdC5wcm9wZXJ0eSlcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICB0aHJvd1VuZXhwZWN0ZWQob2JqZWN0KTtcbn1cblxuZnVuY3Rpb24gc2NhbkpTWElkZW50aWZpZXIoKSB7XG4gICAgdmFyIGNoLCBzdGFydCwgdmFsdWUgPSBcIlwiO1xuXG4gICAgc3RhcnQgPSBpbmRleDtcbiAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgY2ggPSBzb3VyY2UuY2hhckNvZGVBdChpbmRleCk7XG4gICAgICAgIGlmICghc3ludGF4LmlzSlNYSWRlbnRpZmllclBhcnQoY2gpKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICB2YWx1ZSArPSBzb3VyY2VbaW5kZXgrK107XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogVG9rZW4uSlNYSWRlbnRpZmllcixcbiAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICBsaW5lTnVtYmVyOiBsaW5lTnVtYmVyLFxuICAgICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgICAgcmFuZ2U6IFtzdGFydCwgaW5kZXhdXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gc2NhbkpTWEVudGl0eSgpIHtcbiAgICB2YXIgY2gsIHN0ciA9IFwiXCIsIHN0YXJ0ID0gaW5kZXgsIGNvdW50ID0gMCwgY29kZTtcbiAgICBjaCA9IHNvdXJjZVtpbmRleF07XG4gICAgYXNzZXJ0KGNoID09PSBcIiZcIiwgXCJFbnRpdHkgbXVzdCBzdGFydCB3aXRoIGFuIGFtcGVyc2FuZFwiKTtcbiAgICBpbmRleCsrO1xuICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCAmJiBjb3VudCsrIDwgMTApIHtcbiAgICAgICAgY2ggPSBzb3VyY2VbaW5kZXgrK107XG4gICAgICAgIGlmIChjaCA9PT0gXCI7XCIpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHN0ciArPSBjaDtcbiAgICB9XG5cbiAgICAvLyBXZWxsLWZvcm1lZCBlbnRpdHkgKGVuZGluZyB3YXMgZm91bmQpLlxuICAgIGlmIChjaCA9PT0gXCI7XCIpIHtcbiAgICAgICAgLy8gTnVtZXJpYyBlbnRpdHkuXG4gICAgICAgIGlmIChzdHJbMF0gPT09IFwiI1wiKSB7XG4gICAgICAgICAgICBpZiAoc3RyWzFdID09PSBcInhcIikge1xuICAgICAgICAgICAgICAgIGNvZGUgPSArKFwiMFwiICsgc3RyLnN1YnN0cigxKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFJlbW92aW5nIGxlYWRpbmcgemVyb3MgaW4gb3JkZXIgdG8gYXZvaWQgdHJlYXRpbmcgYXMgb2N0YWwgaW4gb2xkIGJyb3dzZXJzLlxuICAgICAgICAgICAgICAgIGNvZGUgPSArc3RyLnN1YnN0cigxKS5yZXBsYWNlKFJlZ2V4LkxlYWRpbmdaZXJvcywgXCJcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghaXNOYU4oY29kZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgICAgfSBlbHNlIGlmIChYSFRNTEVudGl0aWVzW3N0cl0pIHtcbiAgICAgICAgICAgIHJldHVybiBYSFRNTEVudGl0aWVzW3N0cl07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUcmVhdCBub24tZW50aXR5IHNlcXVlbmNlcyBhcyByZWd1bGFyIHRleHQuXG4gICAgaW5kZXggPSBzdGFydCArIDE7XG4gICAgcmV0dXJuIFwiJlwiO1xufVxuXG5mdW5jdGlvbiBzY2FuSlNYVGV4dChzdG9wQ2hhcnMpIHtcbiAgICB2YXIgY2gsIHN0ciA9IFwiXCIsIHN0YXJ0O1xuICAgIHN0YXJ0ID0gaW5kZXg7XG4gICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNoID0gc291cmNlW2luZGV4XTtcbiAgICAgICAgaWYgKHN0b3BDaGFycy5pbmRleE9mKGNoKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaCA9PT0gXCImXCIpIHtcbiAgICAgICAgICAgIHN0ciArPSBzY2FuSlNYRW50aXR5KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgaWYgKGNoID09PSBcIlxcclwiICYmIHNvdXJjZVtpbmRleF0gPT09IFwiXFxuXCIpIHtcbiAgICAgICAgICAgICAgICBzdHIgKz0gY2g7XG4gICAgICAgICAgICAgICAgY2ggPSBzb3VyY2VbaW5kZXhdO1xuICAgICAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc3ludGF4LmlzTGluZVRlcm1pbmF0b3IoY2guY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgICAgICAgICAgICArK2xpbmVOdW1iZXI7XG4gICAgICAgICAgICAgICAgbGluZVN0YXJ0ID0gaW5kZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdHIgKz0gY2g7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogVG9rZW4uSlNYVGV4dCxcbiAgICAgICAgdmFsdWU6IHN0cixcbiAgICAgICAgbGluZU51bWJlcjogbGluZU51bWJlcixcbiAgICAgICAgbGluZVN0YXJ0OiBsaW5lU3RhcnQsXG4gICAgICAgIHJhbmdlOiBbc3RhcnQsIGluZGV4XVxuICAgIH07XG59XG5cbmZ1bmN0aW9uIHNjYW5KU1hTdHJpbmdMaXRlcmFsKCkge1xuICAgIHZhciBpbm5lclRva2VuLCBxdW90ZSwgc3RhcnQ7XG5cbiAgICBxdW90ZSA9IHNvdXJjZVtpbmRleF07XG4gICAgYXNzZXJ0KChxdW90ZSA9PT0gXCJcXFwiXCIgfHwgcXVvdGUgPT09IFwiJ1wiKSxcbiAgICAgICAgXCJTdHJpbmcgbGl0ZXJhbCBtdXN0IHN0YXJ0cyB3aXRoIGEgcXVvdGVcIik7XG5cbiAgICBzdGFydCA9IGluZGV4O1xuICAgICsraW5kZXg7XG5cbiAgICBpbm5lclRva2VuID0gc2NhbkpTWFRleHQoW3F1b3RlXSk7XG5cbiAgICBpZiAocXVvdGUgIT09IHNvdXJjZVtpbmRleF0pIHtcbiAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuVW5leHBlY3RlZFRva2VuLCBcIklMTEVHQUxcIik7XG4gICAgfVxuXG4gICAgKytpbmRleDtcblxuICAgIGlubmVyVG9rZW4ucmFuZ2UgPSBbc3RhcnQsIGluZGV4XTtcblxuICAgIHJldHVybiBpbm5lclRva2VuO1xufVxuXG4vKlxuICogQmV0d2VlbiBKU1ggb3BlbmluZyBhbmQgY2xvc2luZyB0YWdzIChlLmcuIDxmb28+SEVSRTwvZm9vPiksIGFueXRoaW5nIHRoYXRcbiAqIGlzIG5vdCBhbm90aGVyIEpTWCB0YWcgYW5kIGlzIG5vdCBhbiBleHByZXNzaW9uIHdyYXBwZWQgYnkge30gaXMgdGV4dC5cbiAqL1xuZnVuY3Rpb24gYWR2YW5jZUpTWENoaWxkKCkge1xuICAgIHZhciBjaCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KTtcblxuICAgIC8vIHsgKDEyMykgYW5kIDwgKDYwKVxuICAgIGlmIChjaCAhPT0gMTIzICYmIGNoICE9PSA2MCkge1xuICAgICAgICByZXR1cm4gc2NhbkpTWFRleHQoW1wiPFwiLCBcIntcIl0pO1xuICAgIH1cblxuICAgIHJldHVybiBzY2FuUHVuY3R1YXRvcigpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUpTWElkZW50aWZpZXIoKSB7XG4gICAgdmFyIHRva2VuLCBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcblxuICAgIGlmIChsb29rYWhlYWQudHlwZSAhPT0gVG9rZW4uSlNYSWRlbnRpZmllcikge1xuICAgICAgICB0aHJvd1VuZXhwZWN0ZWQobG9va2FoZWFkKTtcbiAgICB9XG5cbiAgICB0b2tlbiA9IGxleCgpO1xuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUpTWElkZW50aWZpZXIodG9rZW4udmFsdWUpKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VKU1hOYW1lc3BhY2VkTmFtZSgpIHtcbiAgICB2YXIgbmFtZXNwYWNlLCBuYW1lLCBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcblxuICAgIG5hbWVzcGFjZSA9IHBhcnNlSlNYSWRlbnRpZmllcigpO1xuICAgIGV4cGVjdChcIjpcIik7XG4gICAgbmFtZSA9IHBhcnNlSlNYSWRlbnRpZmllcigpO1xuXG4gICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlSlNYTmFtZXNwYWNlZE5hbWUobmFtZXNwYWNlLCBuYW1lKSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlSlNYTWVtYmVyRXhwcmVzc2lvbigpIHtcbiAgICB2YXIgbWFya2VyID0gbWFya2VyQ3JlYXRlKCksXG4gICAgICAgIGV4cHIgPSBwYXJzZUpTWElkZW50aWZpZXIoKTtcblxuICAgIHdoaWxlIChtYXRjaChcIi5cIikpIHtcbiAgICAgICAgbGV4KCk7XG4gICAgICAgIGV4cHIgPSBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUpTWE1lbWJlckV4cHJlc3Npb24oZXhwciwgcGFyc2VKU1hJZGVudGlmaWVyKCkpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXhwcjtcbn1cblxuZnVuY3Rpb24gcGFyc2VKU1hFbGVtZW50TmFtZSgpIHtcbiAgICBpZiAobG9va2FoZWFkMigpLnZhbHVlID09PSBcIjpcIikge1xuICAgICAgICByZXR1cm4gcGFyc2VKU1hOYW1lc3BhY2VkTmFtZSgpO1xuICAgIH1cbiAgICBpZiAobG9va2FoZWFkMigpLnZhbHVlID09PSBcIi5cIikge1xuICAgICAgICByZXR1cm4gcGFyc2VKU1hNZW1iZXJFeHByZXNzaW9uKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcnNlSlNYSWRlbnRpZmllcigpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUpTWEF0dHJpYnV0ZU5hbWUoKSB7XG4gICAgaWYgKGxvb2thaGVhZDIoKS52YWx1ZSA9PT0gXCI6XCIpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlSlNYTmFtZXNwYWNlZE5hbWUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyc2VKU1hJZGVudGlmaWVyKCk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlSlNYQXR0cmlidXRlVmFsdWUoKSB7XG4gICAgdmFyIHZhbHVlLCBtYXJrZXI7XG4gICAgaWYgKG1hdGNoKFwie1wiKSkge1xuICAgICAgICB2YWx1ZSA9IHBhcnNlSlNYRXhwcmVzc2lvbkNvbnRhaW5lcigpO1xuICAgICAgICBpZiAodmFsdWUuZXhwcmVzc2lvbi50eXBlID09PSBhc3ROb2RlVHlwZXMuSlNYRW1wdHlFeHByZXNzaW9uKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKFxuICAgICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgICAgIFwiSlNYIGF0dHJpYnV0ZXMgbXVzdCBvbmx5IGJlIGFzc2lnbmVkIGEgbm9uLWVtcHR5IFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCJleHByZXNzaW9uXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG1hdGNoKFwiPFwiKSkge1xuICAgICAgICB2YWx1ZSA9IHBhcnNlSlNYRWxlbWVudCgpO1xuICAgIH0gZWxzZSBpZiAobG9va2FoZWFkLnR5cGUgPT09IFRva2VuLkpTWFRleHQpIHtcbiAgICAgICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG4gICAgICAgIHZhbHVlID0gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVMaXRlcmFsRnJvbVNvdXJjZShsZXgoKSwgc291cmNlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuSW52YWxpZEpTWEF0dHJpYnV0ZVZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiBwYXJzZUpTWEVtcHR5RXhwcmVzc2lvbigpIHtcbiAgICB2YXIgbWFya2VyID0gbWFya2VyQ3JlYXRlUHJlc2VydmVXaGl0ZXNwYWNlKCk7XG4gICAgd2hpbGUgKHNvdXJjZS5jaGFyQXQoaW5kZXgpICE9PSBcIn1cIikge1xuICAgICAgICBpbmRleCsrO1xuICAgIH1cbiAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVKU1hFbXB0eUV4cHJlc3Npb24oKSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlSlNYRXhwcmVzc2lvbkNvbnRhaW5lcigpIHtcbiAgICB2YXIgZXhwcmVzc2lvbiwgb3JpZ0luSlNYQ2hpbGQsIG9yaWdJbkpTWFRhZywgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG5cbiAgICBvcmlnSW5KU1hDaGlsZCA9IHN0YXRlLmluSlNYQ2hpbGQ7XG4gICAgb3JpZ0luSlNYVGFnID0gc3RhdGUuaW5KU1hUYWc7XG4gICAgc3RhdGUuaW5KU1hDaGlsZCA9IGZhbHNlO1xuICAgIHN0YXRlLmluSlNYVGFnID0gZmFsc2U7XG5cbiAgICBleHBlY3QoXCJ7XCIpO1xuXG4gICAgaWYgKG1hdGNoKFwifVwiKSkge1xuICAgICAgICBleHByZXNzaW9uID0gcGFyc2VKU1hFbXB0eUV4cHJlc3Npb24oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBleHByZXNzaW9uID0gcGFyc2VFeHByZXNzaW9uKCk7XG4gICAgfVxuXG4gICAgc3RhdGUuaW5KU1hDaGlsZCA9IG9yaWdJbkpTWENoaWxkO1xuICAgIHN0YXRlLmluSlNYVGFnID0gb3JpZ0luSlNYVGFnO1xuXG4gICAgZXhwZWN0KFwifVwiKTtcblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUpTWEV4cHJlc3Npb25Db250YWluZXIoZXhwcmVzc2lvbikpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUpTWFNwcmVhZEF0dHJpYnV0ZSgpIHtcbiAgICB2YXIgZXhwcmVzc2lvbiwgb3JpZ0luSlNYQ2hpbGQsIG9yaWdJbkpTWFRhZywgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG5cbiAgICBvcmlnSW5KU1hDaGlsZCA9IHN0YXRlLmluSlNYQ2hpbGQ7XG4gICAgb3JpZ0luSlNYVGFnID0gc3RhdGUuaW5KU1hUYWc7XG4gICAgc3RhdGUuaW5KU1hDaGlsZCA9IGZhbHNlO1xuICAgIHN0YXRlLmluSlNYVGFnID0gZmFsc2U7XG4gICAgc3RhdGUuaW5KU1hTcHJlYWRBdHRyaWJ1dGUgPSB0cnVlO1xuXG4gICAgZXhwZWN0KFwie1wiKTtcbiAgICBleHBlY3QoXCIuLi5cIik7XG5cbiAgICBzdGF0ZS5pbkpTWFNwcmVhZEF0dHJpYnV0ZSA9IGZhbHNlO1xuXG4gICAgZXhwcmVzc2lvbiA9IHBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24oKTtcblxuICAgIHN0YXRlLmluSlNYQ2hpbGQgPSBvcmlnSW5KU1hDaGlsZDtcbiAgICBzdGF0ZS5pbkpTWFRhZyA9IG9yaWdJbkpTWFRhZztcblxuICAgIGV4cGVjdChcIn1cIik7XG5cbiAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVKU1hTcHJlYWRBdHRyaWJ1dGUoZXhwcmVzc2lvbikpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUpTWEF0dHJpYnV0ZSgpIHtcbiAgICB2YXIgbmFtZSwgbWFya2VyO1xuXG4gICAgaWYgKG1hdGNoKFwie1wiKSkge1xuICAgICAgICByZXR1cm4gcGFyc2VKU1hTcHJlYWRBdHRyaWJ1dGUoKTtcbiAgICB9XG5cbiAgICBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcblxuICAgIG5hbWUgPSBwYXJzZUpTWEF0dHJpYnV0ZU5hbWUoKTtcblxuICAgIC8vIEhUTUwgZW1wdHkgYXR0cmlidXRlXG4gICAgaWYgKG1hdGNoKFwiPVwiKSkge1xuICAgICAgICBsZXgoKTtcbiAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlSlNYQXR0cmlidXRlKG5hbWUsIHBhcnNlSlNYQXR0cmlidXRlVmFsdWUoKSkpO1xuICAgIH1cblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUpTWEF0dHJpYnV0ZShuYW1lKSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlSlNYQ2hpbGQoKSB7XG4gICAgdmFyIHRva2VuLCBtYXJrZXI7XG4gICAgaWYgKG1hdGNoKFwie1wiKSkge1xuICAgICAgICB0b2tlbiA9IHBhcnNlSlNYRXhwcmVzc2lvbkNvbnRhaW5lcigpO1xuICAgIH0gZWxzZSBpZiAobG9va2FoZWFkLnR5cGUgPT09IFRva2VuLkpTWFRleHQpIHtcbiAgICAgICAgbWFya2VyID0gbWFya2VyQ3JlYXRlUHJlc2VydmVXaGl0ZXNwYWNlKCk7XG4gICAgICAgIHRva2VuID0gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVMaXRlcmFsRnJvbVNvdXJjZShsZXgoKSwgc291cmNlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdG9rZW4gPSBwYXJzZUpTWEVsZW1lbnQoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRva2VuO1xufVxuXG5mdW5jdGlvbiBwYXJzZUpTWENsb3NpbmdFbGVtZW50KCkge1xuICAgIHZhciBuYW1lLCBvcmlnSW5KU1hDaGlsZCwgb3JpZ0luSlNYVGFnLCBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcbiAgICBvcmlnSW5KU1hDaGlsZCA9IHN0YXRlLmluSlNYQ2hpbGQ7XG4gICAgb3JpZ0luSlNYVGFnID0gc3RhdGUuaW5KU1hUYWc7XG4gICAgc3RhdGUuaW5KU1hDaGlsZCA9IGZhbHNlO1xuICAgIHN0YXRlLmluSlNYVGFnID0gdHJ1ZTtcbiAgICBleHBlY3QoXCI8XCIpO1xuICAgIGV4cGVjdChcIi9cIik7XG4gICAgbmFtZSA9IHBhcnNlSlNYRWxlbWVudE5hbWUoKTtcbiAgICAvLyBCZWNhdXNlIGFkdmFuY2UoKSAoY2FsbGVkIGJ5IGxleCgpIGNhbGxlZCBieSBleHBlY3QoKSkgZXhwZWN0cyB0aGVyZVxuICAgIC8vIHRvIGJlIGEgdmFsaWQgdG9rZW4gYWZ0ZXIgPiwgaXQgbmVlZHMgdG8ga25vdyB3aGV0aGVyIHRvIGxvb2sgZm9yIGFcbiAgICAvLyBzdGFuZGFyZCBKUyB0b2tlbiBvciBhbiBKU1ggdGV4dCBub2RlXG4gICAgc3RhdGUuaW5KU1hDaGlsZCA9IG9yaWdJbkpTWENoaWxkO1xuICAgIHN0YXRlLmluSlNYVGFnID0gb3JpZ0luSlNYVGFnO1xuICAgIGV4cGVjdChcIj5cIik7XG4gICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlSlNYQ2xvc2luZ0VsZW1lbnQobmFtZSkpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUpTWE9wZW5pbmdFbGVtZW50KCkge1xuICAgIHZhciBuYW1lLCBhdHRyaWJ1dGVzID0gW10sIHNlbGZDbG9zaW5nID0gZmFsc2UsIG9yaWdJbkpTWENoaWxkLFxuICAgICAgICBvcmlnSW5KU1hUYWcsIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuXG4gICAgb3JpZ0luSlNYQ2hpbGQgPSBzdGF0ZS5pbkpTWENoaWxkO1xuICAgIG9yaWdJbkpTWFRhZyA9IHN0YXRlLmluSlNYVGFnO1xuICAgIHN0YXRlLmluSlNYQ2hpbGQgPSBmYWxzZTtcbiAgICBzdGF0ZS5pbkpTWFRhZyA9IHRydWU7XG5cbiAgICBleHBlY3QoXCI8XCIpO1xuXG4gICAgbmFtZSA9IHBhcnNlSlNYRWxlbWVudE5hbWUoKTtcblxuICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCAmJlxuICAgICAgICAgICAgbG9va2FoZWFkLnZhbHVlICE9PSBcIi9cIiAmJlxuICAgICAgICAgICAgbG9va2FoZWFkLnZhbHVlICE9PSBcIj5cIikge1xuICAgICAgICBhdHRyaWJ1dGVzLnB1c2gocGFyc2VKU1hBdHRyaWJ1dGUoKSk7XG4gICAgfVxuXG4gICAgc3RhdGUuaW5KU1hUYWcgPSBvcmlnSW5KU1hUYWc7XG5cbiAgICBpZiAobG9va2FoZWFkLnZhbHVlID09PSBcIi9cIikge1xuICAgICAgICBleHBlY3QoXCIvXCIpO1xuICAgICAgICAvLyBCZWNhdXNlIGFkdmFuY2UoKSAoY2FsbGVkIGJ5IGxleCgpIGNhbGxlZCBieSBleHBlY3QoKSkgZXhwZWN0c1xuICAgICAgICAvLyB0aGVyZSB0byBiZSBhIHZhbGlkIHRva2VuIGFmdGVyID4sIGl0IG5lZWRzIHRvIGtub3cgd2hldGhlciB0b1xuICAgICAgICAvLyBsb29rIGZvciBhIHN0YW5kYXJkIEpTIHRva2VuIG9yIGFuIEpTWCB0ZXh0IG5vZGVcbiAgICAgICAgc3RhdGUuaW5KU1hDaGlsZCA9IG9yaWdJbkpTWENoaWxkO1xuICAgICAgICBleHBlY3QoXCI+XCIpO1xuICAgICAgICBzZWxmQ2xvc2luZyA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdGUuaW5KU1hDaGlsZCA9IHRydWU7XG4gICAgICAgIGV4cGVjdChcIj5cIik7XG4gICAgfVxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUpTWE9wZW5pbmdFbGVtZW50KG5hbWUsIGF0dHJpYnV0ZXMsIHNlbGZDbG9zaW5nKSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlSlNYRWxlbWVudCgpIHtcbiAgICB2YXIgb3BlbmluZ0VsZW1lbnQsIGNsb3NpbmdFbGVtZW50ID0gbnVsbCwgY2hpbGRyZW4gPSBbXSwgb3JpZ0luSlNYQ2hpbGQsIG9yaWdJbkpTWFRhZywgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG5cbiAgICBvcmlnSW5KU1hDaGlsZCA9IHN0YXRlLmluSlNYQ2hpbGQ7XG4gICAgb3JpZ0luSlNYVGFnID0gc3RhdGUuaW5KU1hUYWc7XG4gICAgb3BlbmluZ0VsZW1lbnQgPSBwYXJzZUpTWE9wZW5pbmdFbGVtZW50KCk7XG5cbiAgICBpZiAoIW9wZW5pbmdFbGVtZW50LnNlbGZDbG9zaW5nKSB7XG4gICAgICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgc3RhdGUuaW5KU1hDaGlsZCA9IGZhbHNlOyAvLyBDYWxsIGxvb2thaGVhZDIoKSB3aXRoIGluSlNYQ2hpbGQgPSBmYWxzZSBiZWNhdXNlIDwvIHNob3VsZCBub3QgYmUgY29uc2lkZXJlZCBpbiB0aGUgY2hpbGRcbiAgICAgICAgICAgIGlmIChsb29rYWhlYWQudmFsdWUgPT09IFwiPFwiICYmIGxvb2thaGVhZDIoKS52YWx1ZSA9PT0gXCIvXCIpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0YXRlLmluSlNYQ2hpbGQgPSB0cnVlO1xuICAgICAgICAgICAgY2hpbGRyZW4ucHVzaChwYXJzZUpTWENoaWxkKCkpO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRlLmluSlNYQ2hpbGQgPSBvcmlnSW5KU1hDaGlsZDtcbiAgICAgICAgc3RhdGUuaW5KU1hUYWcgPSBvcmlnSW5KU1hUYWc7XG4gICAgICAgIGNsb3NpbmdFbGVtZW50ID0gcGFyc2VKU1hDbG9zaW5nRWxlbWVudCgpO1xuICAgICAgICBpZiAoZ2V0UXVhbGlmaWVkSlNYTmFtZShjbG9zaW5nRWxlbWVudC5uYW1lKSAhPT0gZ2V0UXVhbGlmaWVkSlNYTmFtZShvcGVuaW5nRWxlbWVudC5uYW1lKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuRXhwZWN0ZWRKU1hDbG9zaW5nVGFnLCBnZXRRdWFsaWZpZWRKU1hOYW1lKG9wZW5pbmdFbGVtZW50Lm5hbWUpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qXG4gICAgICogV2hlbiAoZXJyb25lb3VzbHkpIHdyaXRpbmcgdHdvIGFkamFjZW50IHRhZ3MgbGlrZVxuICAgICAqXG4gICAgICogICAgIHZhciB4ID0gPGRpdj5vbmU8L2Rpdj48ZGl2PnR3bzwvZGl2PjtcbiAgICAgKlxuICAgICAqIHRoZSBkZWZhdWx0IGVycm9yIG1lc3NhZ2UgaXMgYSBiaXQgaW5jb21wcmVoZW5zaWJsZS4gU2luY2UgaXRcInNcbiAgICAgKiByYXJlbHkgKG5ldmVyPykgdXNlZnVsIHRvIHdyaXRlIGEgbGVzcy10aGFuIHNpZ24gYWZ0ZXIgYW4gSlNYXG4gICAgICogZWxlbWVudCwgd2UgZGlzYWxsb3cgaXQgaGVyZSBpbiB0aGUgcGFyc2VyIGluIG9yZGVyIHRvIHByb3ZpZGUgYVxuICAgICAqIGJldHRlciBlcnJvciBtZXNzYWdlLiAoSW4gdGhlIHJhcmUgY2FzZSB0aGF0IHRoZSBsZXNzLXRoYW4gb3BlcmF0b3JcbiAgICAgKiB3YXMgaW50ZW5kZWQsIHRoZSBsZWZ0IHRhZyBjYW4gYmUgd3JhcHBlZCBpbiBwYXJlbnRoZXNlcy4pXG4gICAgICovXG4gICAgaWYgKCFvcmlnSW5KU1hDaGlsZCAmJiBtYXRjaChcIjxcIikpIHtcbiAgICAgICAgdGhyb3dFcnJvcihsb29rYWhlYWQsIE1lc3NhZ2VzLkFkamFjZW50SlNYRWxlbWVudHMpO1xuICAgIH1cblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUpTWEVsZW1lbnQob3BlbmluZ0VsZW1lbnQsIGNsb3NpbmdFbGVtZW50LCBjaGlsZHJlbikpO1xufVxuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gTG9jYXRpb24gbWFya2Vyc1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLyoqXG4gKiBBcHBsaWVzIGxvY2F0aW9uIGluZm9ybWF0aW9uIHRvIHRoZSBnaXZlbiBub2RlIGJ5IHVzaW5nIHRoZSBnaXZlbiBtYXJrZXIuXG4gKiBUaGUgbWFya2VyIGluZGljYXRlcyB0aGUgcG9pbnQgYXQgd2hpY2ggdGhlIG5vZGUgaXMgc2FpZCB0byBoYXZlIHRvIGJlZ3VuXG4gKiBpbiB0aGUgc291cmNlIGNvZGUuXG4gKiBAcGFyYW0ge09iamVjdH0gbWFya2VyIFRoZSBtYXJrZXIgdG8gdXNlIGZvciB0aGUgbm9kZS5cbiAqIEBwYXJhbSB7QVNUTm9kZX0gbm9kZSBUaGUgQVNUIG5vZGUgdG8gYXBwbHkgbG9jYXRpb24gaW5mb3JtYXRpb24gdG8uXG4gKiBAcmV0dXJucyB7QVNUTm9kZX0gVGhlIG5vZGUgdGhhdCB3YXMgcGFzc2VkIGluLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gbWFya2VyQXBwbHkobWFya2VyLCBub2RlKSB7XG5cbiAgICAvLyBhZGQgcmFuZ2UgaW5mb3JtYXRpb24gdG8gdGhlIG5vZGUgaWYgcHJlc2VudFxuICAgIGlmIChleHRyYS5yYW5nZSkge1xuICAgICAgICBub2RlLnJhbmdlID0gW21hcmtlci5vZmZzZXQsIGluZGV4XTtcbiAgICB9XG5cbiAgICAvLyBhZGQgbG9jYXRpb24gaW5mb3JtYXRpb24gdGhlIG5vZGUgaWYgcHJlc2VudFxuICAgIGlmIChleHRyYS5sb2MpIHtcbiAgICAgICAgbm9kZS5sb2MgPSB7XG4gICAgICAgICAgICBzdGFydDoge1xuICAgICAgICAgICAgICAgIGxpbmU6IG1hcmtlci5saW5lLFxuICAgICAgICAgICAgICAgIGNvbHVtbjogbWFya2VyLmNvbFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVuZDoge1xuICAgICAgICAgICAgICAgIGxpbmU6IGxpbmVOdW1iZXIsXG4gICAgICAgICAgICAgICAgY29sdW1uOiBpbmRleCAtIGxpbmVTdGFydFxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICAvLyBBdHRhY2ggZXh0cmEuc291cmNlIGluZm9ybWF0aW9uIHRvIHRoZSBsb2NhdGlvbiwgaWYgcHJlc2VudFxuICAgICAgICBpZiAoZXh0cmEuc291cmNlKSB7XG4gICAgICAgICAgICBub2RlLmxvYy5zb3VyY2UgPSBleHRyYS5zb3VyY2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhdHRhY2ggbGVhZGluZyBhbmQgdHJhaWxpbmcgY29tbWVudHMgaWYgcmVxdWVzdGVkXG4gICAgaWYgKGV4dHJhLmF0dGFjaENvbW1lbnQpIHtcbiAgICAgICAgY29tbWVudEF0dGFjaG1lbnQucHJvY2Vzc0NvbW1lbnQobm9kZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vZGU7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGxvY2F0aW9uIG1hcmtlciBpbiB0aGUgc291cmNlIGNvZGUuIExvY2F0aW9uIG1hcmtlcnMgYXJlIHVzZWQgZm9yXG4gKiB0cmFja2luZyB3aGVyZSB0b2tlbnMgYW5kIG5vZGVzIGFwcGVhciBpbiB0aGUgc291cmNlIGNvZGUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBBIG1hcmtlciBvYmplY3Qgb3IgdW5kZWZpbmVkIGlmIHRoZSBwYXJzZXIgZG9lc24ndCBoYXZlXG4gKiAgICAgIGFueSBsb2NhdGlvbiBpbmZvcm1hdGlvbi5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIG1hcmtlckNyZWF0ZSgpIHtcblxuICAgIGlmICghZXh0cmEubG9jICYmICFleHRyYS5yYW5nZSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHNraXBDb21tZW50KCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBvZmZzZXQ6IGluZGV4LFxuICAgICAgICBsaW5lOiBsaW5lTnVtYmVyLFxuICAgICAgICBjb2w6IGluZGV4IC0gbGluZVN0YXJ0XG4gICAgfTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbG9jYXRpb24gbWFya2VyIGluIHRoZSBzb3VyY2UgY29kZS4gTG9jYXRpb24gbWFya2VycyBhcmUgdXNlZCBmb3JcbiAqIHRyYWNraW5nIHdoZXJlIHRva2VucyBhbmQgbm9kZXMgYXBwZWFyIGluIHRoZSBzb3VyY2UgY29kZS4gVGhpcyBtZXRob2RcbiAqIGRvZXNuJ3Qgc2tpcCBjb21tZW50cyBvciBleHRyYSB3aGl0ZXNwYWNlIHdoaWNoIGlzIGltcG9ydGFudCBmb3IgSlNYLlxuICogQHJldHVybnMge09iamVjdH0gQSBtYXJrZXIgb2JqZWN0IG9yIHVuZGVmaW5lZCBpZiB0aGUgcGFyc2VyIGRvZXNuJ3QgaGF2ZVxuICogICAgICBhbnkgbG9jYXRpb24gaW5mb3JtYXRpb24uXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBtYXJrZXJDcmVhdGVQcmVzZXJ2ZVdoaXRlc3BhY2UoKSB7XG5cbiAgICBpZiAoIWV4dHJhLmxvYyAmJiAhZXh0cmEucmFuZ2UpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBvZmZzZXQ6IGluZGV4LFxuICAgICAgICBsaW5lOiBsaW5lTnVtYmVyLFxuICAgICAgICBjb2w6IGluZGV4IC0gbGluZVN0YXJ0XG4gICAgfTtcbn1cblxuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gU3ludGF4IFRyZWUgRGVsZWdhdGVcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIFJldHVybiB0cnVlIGlmIHRoZXJlIGlzIGEgbGluZSB0ZXJtaW5hdG9yIGJlZm9yZSB0aGUgbmV4dCB0b2tlbi5cblxuZnVuY3Rpb24gcGVla0xpbmVUZXJtaW5hdG9yKCkge1xuICAgIHZhciBwb3MsIGxpbmUsIHN0YXJ0LCBmb3VuZDtcblxuICAgIHBvcyA9IGluZGV4O1xuICAgIGxpbmUgPSBsaW5lTnVtYmVyO1xuICAgIHN0YXJ0ID0gbGluZVN0YXJ0O1xuICAgIHNraXBDb21tZW50KCk7XG4gICAgZm91bmQgPSBsaW5lTnVtYmVyICE9PSBsaW5lO1xuICAgIGluZGV4ID0gcG9zO1xuICAgIGxpbmVOdW1iZXIgPSBsaW5lO1xuICAgIGxpbmVTdGFydCA9IHN0YXJ0O1xuXG4gICAgcmV0dXJuIGZvdW5kO1xufVxuXG4vLyBUaHJvdyBhbiBleGNlcHRpb25cblxuZnVuY3Rpb24gdGhyb3dFcnJvcih0b2tlbiwgbWVzc2FnZUZvcm1hdCkge1xuXG4gICAgdmFyIGVycm9yLFxuICAgICAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKSxcbiAgICAgICAgbXNnID0gbWVzc2FnZUZvcm1hdC5yZXBsYWNlKFxuICAgICAgICAgICAgLyUoXFxkKS9nLFxuICAgICAgICAgICAgZnVuY3Rpb24gKHdob2xlLCBpbmRleCkge1xuICAgICAgICAgICAgICAgIGFzc2VydChpbmRleCA8IGFyZ3MubGVuZ3RoLCBcIk1lc3NhZ2UgcmVmZXJlbmNlIG11c3QgYmUgaW4gcmFuZ2VcIik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFyZ3NbaW5kZXhdO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgaWYgKHR5cGVvZiB0b2tlbi5saW5lTnVtYmVyID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgIGVycm9yID0gbmV3IEVycm9yKFwiTGluZSBcIiArIHRva2VuLmxpbmVOdW1iZXIgKyBcIjogXCIgKyBtc2cpO1xuICAgICAgICBlcnJvci5pbmRleCA9IHRva2VuLnJhbmdlWzBdO1xuICAgICAgICBlcnJvci5saW5lTnVtYmVyID0gdG9rZW4ubGluZU51bWJlcjtcbiAgICAgICAgZXJyb3IuY29sdW1uID0gdG9rZW4ucmFuZ2VbMF0gLSBsaW5lU3RhcnQgKyAxO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yID0gbmV3IEVycm9yKFwiTGluZSBcIiArIGxpbmVOdW1iZXIgKyBcIjogXCIgKyBtc2cpO1xuICAgICAgICBlcnJvci5pbmRleCA9IGluZGV4O1xuICAgICAgICBlcnJvci5saW5lTnVtYmVyID0gbGluZU51bWJlcjtcbiAgICAgICAgZXJyb3IuY29sdW1uID0gaW5kZXggLSBsaW5lU3RhcnQgKyAxO1xuICAgIH1cblxuICAgIGVycm9yLmRlc2NyaXB0aW9uID0gbXNnO1xuICAgIHRocm93IGVycm9yO1xufVxuXG5mdW5jdGlvbiB0aHJvd0Vycm9yVG9sZXJhbnQoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgdGhyb3dFcnJvci5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGV4dHJhLmVycm9ycykge1xuICAgICAgICAgICAgZXh0cmEuZXJyb3JzLnB1c2goZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5cbi8vIFRocm93IGFuIGV4Y2VwdGlvbiBiZWNhdXNlIG9mIHRoZSB0b2tlbi5cblxuZnVuY3Rpb24gdGhyb3dVbmV4cGVjdGVkKHRva2VuKSB7XG5cbiAgICBpZiAodG9rZW4udHlwZSA9PT0gVG9rZW4uRU9GKSB7XG4gICAgICAgIHRocm93RXJyb3IodG9rZW4sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRFT1MpO1xuICAgIH1cblxuICAgIGlmICh0b2tlbi50eXBlID09PSBUb2tlbi5OdW1lcmljTGl0ZXJhbCkge1xuICAgICAgICB0aHJvd0Vycm9yKHRva2VuLCBNZXNzYWdlcy5VbmV4cGVjdGVkTnVtYmVyKTtcbiAgICB9XG5cbiAgICBpZiAodG9rZW4udHlwZSA9PT0gVG9rZW4uU3RyaW5nTGl0ZXJhbCB8fCB0b2tlbi50eXBlID09PSBUb2tlbi5KU1hUZXh0KSB7XG4gICAgICAgIHRocm93RXJyb3IodG9rZW4sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRTdHJpbmcpO1xuICAgIH1cblxuICAgIGlmICh0b2tlbi50eXBlID09PSBUb2tlbi5JZGVudGlmaWVyKSB7XG4gICAgICAgIHRocm93RXJyb3IodG9rZW4sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRJZGVudGlmaWVyKTtcbiAgICB9XG5cbiAgICBpZiAodG9rZW4udHlwZSA9PT0gVG9rZW4uS2V5d29yZCkge1xuICAgICAgICBpZiAoc3ludGF4LmlzRnV0dXJlUmVzZXJ2ZWRXb3JkKHRva2VuLnZhbHVlKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcih0b2tlbiwgTWVzc2FnZXMuVW5leHBlY3RlZFJlc2VydmVkKTtcbiAgICAgICAgfSBlbHNlIGlmIChzdHJpY3QgJiYgc3ludGF4LmlzU3RyaWN0TW9kZVJlc2VydmVkV29yZCh0b2tlbi52YWx1ZSkpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3JUb2xlcmFudCh0b2tlbiwgTWVzc2FnZXMuU3RyaWN0UmVzZXJ2ZWRXb3JkKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aHJvd0Vycm9yKHRva2VuLCBNZXNzYWdlcy5VbmV4cGVjdGVkVG9rZW4sIHRva2VuLnZhbHVlKTtcbiAgICB9XG5cbiAgICBpZiAodG9rZW4udHlwZSA9PT0gVG9rZW4uVGVtcGxhdGUpIHtcbiAgICAgICAgdGhyb3dFcnJvcih0b2tlbiwgTWVzc2FnZXMuVW5leHBlY3RlZFRlbXBsYXRlLCB0b2tlbi52YWx1ZS5yYXcpO1xuICAgIH1cblxuICAgIC8vIEJvb2xlYW5MaXRlcmFsLCBOdWxsTGl0ZXJhbCwgb3IgUHVuY3R1YXRvci5cbiAgICB0aHJvd0Vycm9yKHRva2VuLCBNZXNzYWdlcy5VbmV4cGVjdGVkVG9rZW4sIHRva2VuLnZhbHVlKTtcbn1cblxuLy8gRXhwZWN0IHRoZSBuZXh0IHRva2VuIHRvIG1hdGNoIHRoZSBzcGVjaWZpZWQgcHVuY3R1YXRvci5cbi8vIElmIG5vdCwgYW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLlxuXG5mdW5jdGlvbiBleHBlY3QodmFsdWUpIHtcbiAgICB2YXIgdG9rZW4gPSBsZXgoKTtcbiAgICBpZiAodG9rZW4udHlwZSAhPT0gVG9rZW4uUHVuY3R1YXRvciB8fCB0b2tlbi52YWx1ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgdGhyb3dVbmV4cGVjdGVkKHRva2VuKTtcbiAgICB9XG59XG5cbi8vIEV4cGVjdCB0aGUgbmV4dCB0b2tlbiB0byBtYXRjaCB0aGUgc3BlY2lmaWVkIGtleXdvcmQuXG4vLyBJZiBub3QsIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi5cblxuZnVuY3Rpb24gZXhwZWN0S2V5d29yZChrZXl3b3JkKSB7XG4gICAgdmFyIHRva2VuID0gbGV4KCk7XG4gICAgaWYgKHRva2VuLnR5cGUgIT09IFRva2VuLktleXdvcmQgfHwgdG9rZW4udmFsdWUgIT09IGtleXdvcmQpIHtcbiAgICAgICAgdGhyb3dVbmV4cGVjdGVkKHRva2VuKTtcbiAgICB9XG59XG5cbi8vIFJldHVybiB0cnVlIGlmIHRoZSBuZXh0IHRva2VuIG1hdGNoZXMgdGhlIHNwZWNpZmllZCBwdW5jdHVhdG9yLlxuXG5mdW5jdGlvbiBtYXRjaCh2YWx1ZSkge1xuICAgIHJldHVybiBsb29rYWhlYWQudHlwZSA9PT0gVG9rZW4uUHVuY3R1YXRvciAmJiBsb29rYWhlYWQudmFsdWUgPT09IHZhbHVlO1xufVxuXG4vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgbmV4dCB0b2tlbiBtYXRjaGVzIHRoZSBzcGVjaWZpZWQga2V5d29yZFxuXG5mdW5jdGlvbiBtYXRjaEtleXdvcmQoa2V5d29yZCkge1xuICAgIHJldHVybiBsb29rYWhlYWQudHlwZSA9PT0gVG9rZW4uS2V5d29yZCAmJiBsb29rYWhlYWQudmFsdWUgPT09IGtleXdvcmQ7XG59XG5cbi8vIFJldHVybiB0cnVlIGlmIHRoZSBuZXh0IHRva2VuIG1hdGNoZXMgdGhlIHNwZWNpZmllZCBjb250ZXh0dWFsIGtleXdvcmRcbi8vICh3aGVyZSBhbiBpZGVudGlmaWVyIGlzIHNvbWV0aW1lcyBhIGtleXdvcmQgZGVwZW5kaW5nIG9uIHRoZSBjb250ZXh0KVxuXG5mdW5jdGlvbiBtYXRjaENvbnRleHR1YWxLZXl3b3JkKGtleXdvcmQpIHtcbiAgICByZXR1cm4gbG9va2FoZWFkLnR5cGUgPT09IFRva2VuLklkZW50aWZpZXIgJiYgbG9va2FoZWFkLnZhbHVlID09PSBrZXl3b3JkO1xufVxuXG4vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgbmV4dCB0b2tlbiBpcyBhbiBhc3NpZ25tZW50IG9wZXJhdG9yXG5cbmZ1bmN0aW9uIG1hdGNoQXNzaWduKCkge1xuICAgIHZhciBvcDtcblxuICAgIGlmIChsb29rYWhlYWQudHlwZSAhPT0gVG9rZW4uUHVuY3R1YXRvcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIG9wID0gbG9va2FoZWFkLnZhbHVlO1xuICAgIHJldHVybiBvcCA9PT0gXCI9XCIgfHxcbiAgICAgICAgb3AgPT09IFwiKj1cIiB8fFxuICAgICAgICBvcCA9PT0gXCIvPVwiIHx8XG4gICAgICAgIG9wID09PSBcIiU9XCIgfHxcbiAgICAgICAgb3AgPT09IFwiKz1cIiB8fFxuICAgICAgICBvcCA9PT0gXCItPVwiIHx8XG4gICAgICAgIG9wID09PSBcIjw8PVwiIHx8XG4gICAgICAgIG9wID09PSBcIj4+PVwiIHx8XG4gICAgICAgIG9wID09PSBcIj4+Pj1cIiB8fFxuICAgICAgICBvcCA9PT0gXCImPVwiIHx8XG4gICAgICAgIG9wID09PSBcIl49XCIgfHxcbiAgICAgICAgb3AgPT09IFwifD1cIjtcbn1cblxuZnVuY3Rpb24gY29uc3VtZVNlbWljb2xvbigpIHtcbiAgICB2YXIgbGluZTtcblxuICAgIC8vIENhdGNoIHRoZSB2ZXJ5IGNvbW1vbiBjYXNlIGZpcnN0OiBpbW1lZGlhdGVseSBhIHNlbWljb2xvbiAoVSswMDNCKS5cbiAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQoaW5kZXgpID09PSAweDNCIHx8IG1hdGNoKFwiO1wiKSkge1xuICAgICAgICBsZXgoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxpbmUgPSBsaW5lTnVtYmVyO1xuICAgIHNraXBDb21tZW50KCk7XG4gICAgaWYgKGxpbmVOdW1iZXIgIT09IGxpbmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChsb29rYWhlYWQudHlwZSAhPT0gVG9rZW4uRU9GICYmICFtYXRjaChcIn1cIikpIHtcbiAgICAgICAgdGhyb3dVbmV4cGVjdGVkKGxvb2thaGVhZCk7XG4gICAgfVxufVxuXG4vLyBSZXR1cm4gdHJ1ZSBpZiBwcm92aWRlZCBleHByZXNzaW9uIGlzIExlZnRIYW5kU2lkZUV4cHJlc3Npb25cblxuZnVuY3Rpb24gaXNMZWZ0SGFuZFNpZGUoZXhwcikge1xuICAgIHJldHVybiBleHByLnR5cGUgPT09IGFzdE5vZGVUeXBlcy5JZGVudGlmaWVyIHx8IGV4cHIudHlwZSA9PT0gYXN0Tm9kZVR5cGVzLk1lbWJlckV4cHJlc3Npb247XG59XG5cbi8vIDExLjEuNCBBcnJheSBJbml0aWFsaXNlclxuXG5mdW5jdGlvbiBwYXJzZUFycmF5SW5pdGlhbGlzZXIoKSB7XG4gICAgdmFyIGVsZW1lbnRzID0gW10sXG4gICAgICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpLFxuICAgICAgICB0bXA7XG5cbiAgICBleHBlY3QoXCJbXCIpO1xuXG4gICAgd2hpbGUgKCFtYXRjaChcIl1cIikpIHtcbiAgICAgICAgaWYgKG1hdGNoKFwiLFwiKSkge1xuICAgICAgICAgICAgbGV4KCk7IC8vIG9ubHkgZ2V0IGhlcmUgd2hlbiB5b3UgaGF2ZSBbYSwsXSBvciBzaW1pbGFyXG4gICAgICAgICAgICBlbGVtZW50cy5wdXNoKG51bGwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdG1wID0gcGFyc2VTcHJlYWRPckFzc2lnbm1lbnRFeHByZXNzaW9uKCk7XG4gICAgICAgICAgICBlbGVtZW50cy5wdXNoKHRtcCk7XG4gICAgICAgICAgICBpZiAoIShtYXRjaChcIl1cIikpKSB7XG4gICAgICAgICAgICAgICAgZXhwZWN0KFwiLFwiKTsgLy8gaGFuZGxlcyB0aGUgY29tbW9uIGNhc2Ugb2YgY29tbWEtc2VwYXJhdGVkIHZhbHVlc1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZXhwZWN0KFwiXVwiKTtcblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUFycmF5RXhwcmVzc2lvbihlbGVtZW50cykpO1xufVxuXG4vLyAxMS4xLjUgT2JqZWN0IEluaXRpYWxpc2VyXG5cbmZ1bmN0aW9uIHBhcnNlUHJvcGVydHlGdW5jdGlvbihwYXJhbUluZm8sIG9wdGlvbnMpIHtcbiAgICB2YXIgcHJldmlvdXNTdHJpY3QgPSBzdHJpY3QsXG4gICAgICAgIHByZXZpb3VzWWllbGRBbGxvd2VkID0gc3RhdGUueWllbGRBbGxvd2VkLFxuICAgICAgICBnZW5lcmF0b3IgPSBvcHRpb25zID8gb3B0aW9ucy5nZW5lcmF0b3IgOiBmYWxzZSxcbiAgICAgICAgYm9keTtcblxuICAgIHN0YXRlLnlpZWxkQWxsb3dlZCA9IGdlbmVyYXRvcjtcblxuICAgIC8qXG4gICAgICogRXNwcmltYSB1c2VzIHBhcnNlQ29uY2lzZUJvZHkoKSBoZXJlLCB3aGljaCBpcyBpbmNvcnJlY3QuIE9iamVjdCBsaXRlcmFsXG4gICAgICogbWV0aG9kcyBtdXN0IGhhdmUgYnJhY2VzLlxuICAgICAqL1xuICAgIGJvZHkgPSBwYXJzZUZ1bmN0aW9uU291cmNlRWxlbWVudHMoKTtcblxuICAgIGlmIChzdHJpY3QgJiYgcGFyYW1JbmZvLmZpcnN0UmVzdHJpY3RlZCkge1xuICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQocGFyYW1JbmZvLmZpcnN0UmVzdHJpY3RlZCwgTWVzc2FnZXMuU3RyaWN0UGFyYW1OYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoc3RyaWN0ICYmIHBhcmFtSW5mby5zdHJpY3RlZCkge1xuICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQocGFyYW1JbmZvLnN0cmljdGVkLCBwYXJhbUluZm8ubWVzc2FnZSk7XG4gICAgfVxuXG4gICAgc3RyaWN0ID0gcHJldmlvdXNTdHJpY3Q7XG4gICAgc3RhdGUueWllbGRBbGxvd2VkID0gcHJldmlvdXNZaWVsZEFsbG93ZWQ7XG5cbiAgICByZXR1cm4gbWFya2VyQXBwbHkob3B0aW9ucy5tYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUZ1bmN0aW9uRXhwcmVzc2lvbihcbiAgICAgICAgbnVsbCxcbiAgICAgICAgcGFyYW1JbmZvLnBhcmFtcyxcbiAgICAgICAgYm9keSxcbiAgICAgICAgZ2VuZXJhdG9yLFxuICAgICAgICBib2R5LnR5cGUgIT09IGFzdE5vZGVUeXBlcy5CbG9ja1N0YXRlbWVudFxuICAgICkpO1xufVxuXG5mdW5jdGlvbiBwYXJzZVByb3BlcnR5TWV0aG9kRnVuY3Rpb24ob3B0aW9ucykge1xuICAgIHZhciBwcmV2aW91c1N0cmljdCA9IHN0cmljdCxcbiAgICAgICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCksXG4gICAgICAgIHBhcmFtcyxcbiAgICAgICAgbWV0aG9kO1xuXG4gICAgc3RyaWN0ID0gdHJ1ZTtcblxuICAgIHBhcmFtcyA9IHBhcnNlUGFyYW1zKCk7XG5cbiAgICBpZiAocGFyYW1zLnN0cmljdGVkKSB7XG4gICAgICAgIHRocm93RXJyb3JUb2xlcmFudChwYXJhbXMuc3RyaWN0ZWQsIHBhcmFtcy5tZXNzYWdlKTtcbiAgICB9XG5cbiAgICBtZXRob2QgPSBwYXJzZVByb3BlcnR5RnVuY3Rpb24ocGFyYW1zLCB7XG4gICAgICAgIGdlbmVyYXRvcjogb3B0aW9ucyA/IG9wdGlvbnMuZ2VuZXJhdG9yIDogZmFsc2UsXG4gICAgICAgIG1hcmtlcjogbWFya2VyXG4gICAgfSk7XG5cbiAgICBzdHJpY3QgPSBwcmV2aW91c1N0cmljdDtcblxuICAgIHJldHVybiBtZXRob2Q7XG59XG5cbmZ1bmN0aW9uIHBhcnNlT2JqZWN0UHJvcGVydHlLZXkoKSB7XG4gICAgdmFyIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpLFxuICAgICAgICB0b2tlbiA9IGxleCgpLFxuICAgICAgICBhbGxvd09iamVjdExpdGVyYWxDb21wdXRlZCA9IGV4dHJhLmVjbWFGZWF0dXJlcy5vYmplY3RMaXRlcmFsQ29tcHV0ZWRQcm9wZXJ0aWVzLFxuICAgICAgICBleHByLFxuICAgICAgICByZXN1bHQ7XG5cbiAgICAvLyBOb3RlOiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBvbmx5IGZyb20gcGFyc2VPYmplY3RQcm9wZXJ0eSgpLCB3aGVyZVxuICAgIC8vIEVPRiBhbmQgUHVuY3R1YXRvciB0b2tlbnMgYXJlIGFscmVhZHkgZmlsdGVyZWQgb3V0LlxuXG4gICAgc3dpdGNoICh0b2tlbi50eXBlKSB7XG4gICAgICAgIGNhc2UgVG9rZW4uU3RyaW5nTGl0ZXJhbDpcbiAgICAgICAgY2FzZSBUb2tlbi5OdW1lcmljTGl0ZXJhbDpcbiAgICAgICAgICAgIGlmIChzdHJpY3QgJiYgdG9rZW4ub2N0YWwpIHtcbiAgICAgICAgICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQodG9rZW4sIE1lc3NhZ2VzLlN0cmljdE9jdGFsTGl0ZXJhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVMaXRlcmFsRnJvbVNvdXJjZSh0b2tlbiwgc291cmNlKSk7XG5cbiAgICAgICAgY2FzZSBUb2tlbi5JZGVudGlmaWVyOlxuICAgICAgICBjYXNlIFRva2VuLkJvb2xlYW5MaXRlcmFsOlxuICAgICAgICBjYXNlIFRva2VuLk51bGxMaXRlcmFsOlxuICAgICAgICBjYXNlIFRva2VuLktleXdvcmQ6XG4gICAgICAgICAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVJZGVudGlmaWVyKHRva2VuLnZhbHVlKSk7XG5cbiAgICAgICAgY2FzZSBUb2tlbi5QdW5jdHVhdG9yOlxuICAgICAgICAgICAgaWYgKCghc3RhdGUuaW5PYmplY3RMaXRlcmFsIHx8IGFsbG93T2JqZWN0TGl0ZXJhbENvbXB1dGVkKSAmJlxuICAgICAgICAgICAgICAgICAgICB0b2tlbi52YWx1ZSA9PT0gXCJbXCIpIHtcbiAgICAgICAgICAgICAgICAvLyBGb3IgY29tcHV0ZWQgcHJvcGVydGllcyB3ZSBzaG91bGQgc2tpcCB0aGUgWyBhbmQgXSwgYW5kXG4gICAgICAgICAgICAgICAgLy8gY2FwdHVyZSBpbiBtYXJrZXIgb25seSB0aGUgYXNzaWdubWVudCBleHByZXNzaW9uIGl0c2VsZi5cbiAgICAgICAgICAgICAgICBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcbiAgICAgICAgICAgICAgICBleHByID0gcGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbigpO1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IG1hcmtlckFwcGx5KG1hcmtlciwgZXhwcik7XG4gICAgICAgICAgICAgICAgZXhwZWN0KFwiXVwiKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIC8vIG5vIGRlZmF1bHRcbiAgICB9XG5cbiAgICB0aHJvd1VuZXhwZWN0ZWQodG9rZW4pO1xufVxuXG5mdW5jdGlvbiBsb29rYWhlYWRQcm9wZXJ0eU5hbWUoKSB7XG4gICAgc3dpdGNoIChsb29rYWhlYWQudHlwZSkge1xuICAgICAgICBjYXNlIFRva2VuLklkZW50aWZpZXI6XG4gICAgICAgIGNhc2UgVG9rZW4uU3RyaW5nTGl0ZXJhbDpcbiAgICAgICAgY2FzZSBUb2tlbi5Cb29sZWFuTGl0ZXJhbDpcbiAgICAgICAgY2FzZSBUb2tlbi5OdWxsTGl0ZXJhbDpcbiAgICAgICAgY2FzZSBUb2tlbi5OdW1lcmljTGl0ZXJhbDpcbiAgICAgICAgY2FzZSBUb2tlbi5LZXl3b3JkOlxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIGNhc2UgVG9rZW4uUHVuY3R1YXRvcjpcbiAgICAgICAgICAgIHJldHVybiBsb29rYWhlYWQudmFsdWUgPT09IFwiW1wiO1xuICAgICAgICAvLyBubyBkZWZhdWx0XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuLy8gVGhpcyBmdW5jdGlvbiBpcyB0byB0cnkgdG8gcGFyc2UgYSBNZXRob2REZWZpbml0aW9uIGFzIGRlZmluZWQgaW4gMTQuMy4gQnV0IGluIHRoZSBjYXNlIG9mIG9iamVjdCBsaXRlcmFscyxcbi8vIGl0IG1pZ2h0IGJlIGNhbGxlZCBhdCBhIHBvc2l0aW9uIHdoZXJlIHRoZXJlIGlzIGluIGZhY3QgYSBzaG9ydCBoYW5kIGlkZW50aWZpZXIgcGF0dGVybiBvciBhIGRhdGEgcHJvcGVydHkuXG4vLyBUaGlzIGNhbiBvbmx5IGJlIGRldGVybWluZWQgYWZ0ZXIgd2UgY29uc3VtZWQgdXAgdG8gdGhlIGxlZnQgcGFyZW50aGVzZXMuXG4vLyBJbiBvcmRlciB0byBhdm9pZCBiYWNrIHRyYWNraW5nLCBpdCByZXR1cm5zIGBudWxsYCBpZiB0aGUgcG9zaXRpb24gaXMgbm90IGEgTWV0aG9kRGVmaW5pdGlvbiBhbmQgdGhlIGNhbGxlclxuLy8gaXMgcmVzcG9uc2libGUgdG8gdmlzaXQgb3RoZXIgb3B0aW9ucy5cbmZ1bmN0aW9uIHRyeVBhcnNlTWV0aG9kRGVmaW5pdGlvbih0b2tlbiwga2V5LCBjb21wdXRlZCwgbWFya2VyKSB7XG4gICAgdmFyIHZhbHVlLCBvcHRpb25zLCBtZXRob2RNYXJrZXI7XG5cbiAgICBpZiAodG9rZW4udHlwZSA9PT0gVG9rZW4uSWRlbnRpZmllcikge1xuICAgICAgICAvLyBjaGVjayBmb3IgYGdldGAgYW5kIGBzZXRgO1xuXG4gICAgICAgIGlmICh0b2tlbi52YWx1ZSA9PT0gXCJnZXRcIiAmJiBsb29rYWhlYWRQcm9wZXJ0eU5hbWUoKSkge1xuXG4gICAgICAgICAgICBjb21wdXRlZCA9IG1hdGNoKFwiW1wiKTtcbiAgICAgICAgICAgIGtleSA9IHBhcnNlT2JqZWN0UHJvcGVydHlLZXkoKTtcbiAgICAgICAgICAgIG1ldGhvZE1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuICAgICAgICAgICAgZXhwZWN0KFwiKFwiKTtcbiAgICAgICAgICAgIGV4cGVjdChcIilcIik7XG5cbiAgICAgICAgICAgIHZhbHVlID0gcGFyc2VQcm9wZXJ0eUZ1bmN0aW9uKHtcbiAgICAgICAgICAgICAgICBwYXJhbXM6IFtdLFxuICAgICAgICAgICAgICAgIHN0cmljdGVkOiBudWxsLFxuICAgICAgICAgICAgICAgIGZpcnN0UmVzdHJpY3RlZDogbnVsbCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBudWxsXG4gICAgICAgICAgICB9LCB7XG4gICAgICAgICAgICAgICAgbWFya2VyOiBtZXRob2RNYXJrZXJcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVQcm9wZXJ0eShcImdldFwiLCBrZXksIHZhbHVlLCBmYWxzZSwgZmFsc2UsIGNvbXB1dGVkKSk7XG5cbiAgICAgICAgfSBlbHNlIGlmICh0b2tlbi52YWx1ZSA9PT0gXCJzZXRcIiAmJiBsb29rYWhlYWRQcm9wZXJ0eU5hbWUoKSkge1xuICAgICAgICAgICAgY29tcHV0ZWQgPSBtYXRjaChcIltcIik7XG4gICAgICAgICAgICBrZXkgPSBwYXJzZU9iamVjdFByb3BlcnR5S2V5KCk7XG4gICAgICAgICAgICBtZXRob2RNYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcbiAgICAgICAgICAgIGV4cGVjdChcIihcIik7XG5cbiAgICAgICAgICAgIG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgcGFyYW1zOiBbXSxcbiAgICAgICAgICAgICAgICBkZWZhdWx0Q291bnQ6IDAsXG4gICAgICAgICAgICAgICAgc3RyaWN0ZWQ6IG51bGwsXG4gICAgICAgICAgICAgICAgZmlyc3RSZXN0cmljdGVkOiBudWxsLFxuICAgICAgICAgICAgICAgIHBhcmFtU2V0OiBuZXcgU3RyaW5nTWFwKClcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAobWF0Y2goXCIpXCIpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3dFcnJvclRvbGVyYW50KGxvb2thaGVhZCwgTWVzc2FnZXMuVW5leHBlY3RlZFRva2VuLCBsb29rYWhlYWQudmFsdWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXJzZVBhcmFtKG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZXhwZWN0KFwiKVwiKTtcblxuICAgICAgICAgICAgdmFsdWUgPSBwYXJzZVByb3BlcnR5RnVuY3Rpb24ob3B0aW9ucywgeyBtYXJrZXI6IG1ldGhvZE1hcmtlciB9KTtcbiAgICAgICAgICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVByb3BlcnR5KFwic2V0XCIsIGtleSwgdmFsdWUsIGZhbHNlLCBmYWxzZSwgY29tcHV0ZWQpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtYXRjaChcIihcIikpIHtcbiAgICAgICAgdmFsdWUgPSBwYXJzZVByb3BlcnR5TWV0aG9kRnVuY3Rpb24oKTtcbiAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlUHJvcGVydHkoXCJpbml0XCIsIGtleSwgdmFsdWUsIHRydWUsIGZhbHNlLCBjb21wdXRlZCkpO1xuICAgIH1cblxuICAgIC8vIE5vdCBhIE1ldGhvZERlZmluaXRpb24uXG4gICAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogUGFyc2VzIEdlbmVyYXRvciBQcm9wZXJ0aWVzXG4gKiBAcGFyYW0ge0FTVE5vZGV9IGtleSBUaGUgcHJvcGVydHkga2V5ICh1c3VhbGx5IGFuIGlkZW50aWZpZXIpLlxuICogQHBhcmFtIHtPYmplY3R9IG1hcmtlciBUaGUgbWFya2VyIHRvIHVzZSBmb3IgdGhlIG5vZGUuXG4gKiBAcmV0dXJucyB7QVNUTm9kZX0gVGhlIGdlbmVyYXRvciBwcm9wZXJ0eSBub2RlLlxuICovXG5mdW5jdGlvbiBwYXJzZUdlbmVyYXRvclByb3BlcnR5KGtleSwgbWFya2VyKSB7XG5cbiAgICB2YXIgY29tcHV0ZWQgPSAobG9va2FoZWFkLnR5cGUgPT09IFRva2VuLlB1bmN0dWF0b3IgJiYgbG9va2FoZWFkLnZhbHVlID09PSBcIltcIik7XG5cbiAgICBpZiAoIW1hdGNoKFwiKFwiKSkge1xuICAgICAgICB0aHJvd1VuZXhwZWN0ZWQobGV4KCkpO1xuICAgIH1cblxuICAgIHJldHVybiBtYXJrZXJBcHBseShcbiAgICAgICAgbWFya2VyLFxuICAgICAgICBhc3ROb2RlRmFjdG9yeS5jcmVhdGVQcm9wZXJ0eShcbiAgICAgICAgICAgIFwiaW5pdFwiLFxuICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgcGFyc2VQcm9wZXJ0eU1ldGhvZEZ1bmN0aW9uKHsgZ2VuZXJhdG9yOiB0cnVlIH0pLFxuICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgY29tcHV0ZWRcbiAgICAgICAgKVxuICAgICk7XG59XG5cbi8vIFRPRE8obnpha2FzKTogVXBkYXRlIHRvIG1hdGNoIEVzcHJpbWFcbmZ1bmN0aW9uIHBhcnNlT2JqZWN0UHJvcGVydHkoKSB7XG4gICAgdmFyIHRva2VuLCBrZXksIGlkLCBjb21wdXRlZCwgbWV0aG9kTWFya2VyLCBvcHRpb25zO1xuICAgIHZhciBhbGxvd0NvbXB1dGVkID0gZXh0cmEuZWNtYUZlYXR1cmVzLm9iamVjdExpdGVyYWxDb21wdXRlZFByb3BlcnRpZXMsXG4gICAgICAgIGFsbG93TWV0aG9kID0gZXh0cmEuZWNtYUZlYXR1cmVzLm9iamVjdExpdGVyYWxTaG9ydGhhbmRNZXRob2RzLFxuICAgICAgICBhbGxvd1Nob3J0aGFuZCA9IGV4dHJhLmVjbWFGZWF0dXJlcy5vYmplY3RMaXRlcmFsU2hvcnRoYW5kUHJvcGVydGllcyxcbiAgICAgICAgYWxsb3dHZW5lcmF0b3JzID0gZXh0cmEuZWNtYUZlYXR1cmVzLmdlbmVyYXRvcnMsXG4gICAgICAgIGFsbG93RGVzdHJ1Y3R1cmluZyA9IGV4dHJhLmVjbWFGZWF0dXJlcy5kZXN0cnVjdHVyaW5nLFxuICAgICAgICBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcblxuICAgIHRva2VuID0gbG9va2FoZWFkO1xuICAgIGNvbXB1dGVkID0gKHRva2VuLnZhbHVlID09PSBcIltcIiAmJiB0b2tlbi50eXBlID09PSBUb2tlbi5QdW5jdHVhdG9yKTtcblxuICAgIGlmICh0b2tlbi50eXBlID09PSBUb2tlbi5JZGVudGlmaWVyIHx8IChhbGxvd0NvbXB1dGVkICYmIGNvbXB1dGVkKSkge1xuXG4gICAgICAgIGlkID0gcGFyc2VPYmplY3RQcm9wZXJ0eUtleSgpO1xuXG4gICAgICAgIC8qXG4gICAgICAgICAqIENoZWNrIGZvciBnZXR0ZXJzIGFuZCBzZXR0ZXJzLiBCZSBjYXJlZnVsISBcImdldFwiIGFuZCBcInNldFwiIGFyZSBsZWdhbFxuICAgICAgICAgKiBtZXRob2QgbmFtZXMuIEl0J3Mgb25seSBhIGdldHRlciBvciBzZXR0ZXIgaWYgZm9sbG93ZWQgYnkgYSBzcGFjZS5cbiAgICAgICAgICovXG4gICAgICAgIGlmICh0b2tlbi52YWx1ZSA9PT0gXCJnZXRcIiAmJlxuICAgICAgICAgICAgICAgICEobWF0Y2goXCI6XCIpIHx8IG1hdGNoKFwiKFwiKSB8fCBtYXRjaChcIixcIikgfHwgbWF0Y2goXCJ9XCIpKSkge1xuICAgICAgICAgICAgY29tcHV0ZWQgPSAobG9va2FoZWFkLnZhbHVlID09PSBcIltcIik7XG4gICAgICAgICAgICBrZXkgPSBwYXJzZU9iamVjdFByb3BlcnR5S2V5KCk7XG4gICAgICAgICAgICBtZXRob2RNYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcbiAgICAgICAgICAgIGV4cGVjdChcIihcIik7XG4gICAgICAgICAgICBleHBlY3QoXCIpXCIpO1xuXG4gICAgICAgICAgICByZXR1cm4gbWFya2VyQXBwbHkoXG4gICAgICAgICAgICAgICAgbWFya2VyLFxuICAgICAgICAgICAgICAgIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVByb3BlcnR5KFxuICAgICAgICAgICAgICAgICAgICBcImdldFwiLFxuICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlUHJvcGVydHlGdW5jdGlvbih7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0b3I6IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcmtlcjogbWV0aG9kTWFya2VyXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGNvbXB1dGVkXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0b2tlbi52YWx1ZSA9PT0gXCJzZXRcIiAmJlxuICAgICAgICAgICAgICAgICEobWF0Y2goXCI6XCIpIHx8IG1hdGNoKFwiKFwiKSB8fCBtYXRjaChcIixcIikgfHwgbWF0Y2goXCJ9XCIpKSkge1xuICAgICAgICAgICAgY29tcHV0ZWQgPSAobG9va2FoZWFkLnZhbHVlID09PSBcIltcIik7XG4gICAgICAgICAgICBrZXkgPSBwYXJzZU9iamVjdFByb3BlcnR5S2V5KCk7XG4gICAgICAgICAgICBtZXRob2RNYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcbiAgICAgICAgICAgIGV4cGVjdChcIihcIik7XG5cbiAgICAgICAgICAgIG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgcGFyYW1zOiBbXSxcbiAgICAgICAgICAgICAgICBkZWZhdWx0Q291bnQ6IDAsXG4gICAgICAgICAgICAgICAgc3RyaWN0ZWQ6IG51bGwsXG4gICAgICAgICAgICAgICAgZmlyc3RSZXN0cmljdGVkOiBudWxsLFxuICAgICAgICAgICAgICAgIHBhcmFtU2V0OiBuZXcgU3RyaW5nTWFwKClcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmIChtYXRjaChcIilcIikpIHtcbiAgICAgICAgICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQobG9va2FoZWFkLCBNZXNzYWdlcy5VbmV4cGVjdGVkVG9rZW4sIGxvb2thaGVhZC52YWx1ZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcnNlUGFyYW0ob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGV4cGVjdChcIilcIik7XG5cbiAgICAgICAgICAgIHJldHVybiBtYXJrZXJBcHBseShcbiAgICAgICAgICAgICAgICBtYXJrZXIsXG4gICAgICAgICAgICAgICAgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlUHJvcGVydHkoXG4gICAgICAgICAgICAgICAgICAgIFwic2V0XCIsXG4gICAgICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VQcm9wZXJ0eUZ1bmN0aW9uKG9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcmtlcjogbWV0aG9kTWFya2VyXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGNvbXB1dGVkXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIG5vcm1hbCBwcm9wZXJ0eSAoa2V5OnZhbHVlKVxuICAgICAgICBpZiAobWF0Y2goXCI6XCIpKSB7XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIHJldHVybiBtYXJrZXJBcHBseShcbiAgICAgICAgICAgICAgICBtYXJrZXIsXG4gICAgICAgICAgICAgICAgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlUHJvcGVydHkoXG4gICAgICAgICAgICAgICAgICAgIFwiaW5pdFwiLFxuICAgICAgICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbigpLFxuICAgICAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGNvbXB1dGVkXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIG1ldGhvZCBzaG9ydGhhbmQgKGtleSgpey4uLn0pXG4gICAgICAgIGlmIChhbGxvd01ldGhvZCAmJiBtYXRjaChcIihcIikpIHtcbiAgICAgICAgICAgIHJldHVybiBtYXJrZXJBcHBseShcbiAgICAgICAgICAgICAgICBtYXJrZXIsXG4gICAgICAgICAgICAgICAgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlUHJvcGVydHkoXG4gICAgICAgICAgICAgICAgICAgIFwiaW5pdFwiLFxuICAgICAgICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VQcm9wZXJ0eU1ldGhvZEZ1bmN0aW9uKHsgZ2VuZXJhdG9yOiBmYWxzZSB9KSxcbiAgICAgICAgICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGNvbXB1dGVkXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGRlc3RydWN0dXJpbmcgZGVmYXVsdHMgKHNob3J0aGFuZCBzeW50YXgpXG4gICAgICAgIGlmIChhbGxvd0Rlc3RydWN0dXJpbmcgJiYgbWF0Y2goXCI9XCIpKSB7XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IHBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24oKTtcbiAgICAgICAgICAgIHZhciBwcm9wID0gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVBc3NpZ25tZW50RXhwcmVzc2lvbihcIj1cIiwgaWQsIHZhbHVlKSk7XG4gICAgICAgICAgICBwcm9wLnR5cGUgPSBhc3ROb2RlVHlwZXMuQXNzaWdubWVudFBhdHRlcm47XG4gICAgICAgICAgICB2YXIgZnVsbFByb3BlcnR5ID0gYXN0Tm9kZUZhY3RvcnkuY3JlYXRlUHJvcGVydHkoXG4gICAgICAgICAgICAgICAgXCJpbml0XCIsXG4gICAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgICAgcHJvcCxcbiAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICB0cnVlLCAvLyBzaG9ydGhhbmRcbiAgICAgICAgICAgICAgICBjb21wdXRlZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGZ1bGxQcm9wZXJ0eSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKlxuICAgICAgICAgKiBPbmx5IG90aGVyIHBvc3NpYmlsaXR5IGlzIHRoYXQgdGhpcyBpcyBhIHNob3J0aGFuZCBwcm9wZXJ0eS4gQ29tcHV0ZWRcbiAgICAgICAgICogcHJvcGVydGllcyBjYW5ub3QgdXNlIHNob3J0aGFuZCBub3RhdGlvbiwgc28gdGhhdCdzIGEgc3ludGF4IGVycm9yLlxuICAgICAgICAgKiBJZiBzaG9ydGhhbmQgcHJvcGVydGllcyBhcmVuJ3QgYWxsb3csIHRoZW4gdGhpcyBpcyBhbiBhdXRvbWF0aWNcbiAgICAgICAgICogc3ludGF4IGVycm9yLiBEZXN0cnVjdHVyaW5nIGlzIGFub3RoZXIgY2FzZSB3aXRoIGEgc2ltaWxhciBzaG9ydGhhbmQgc3ludGF4LlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKGNvbXB1dGVkIHx8ICghYWxsb3dTaG9ydGhhbmQgJiYgIWFsbG93RGVzdHJ1Y3R1cmluZykpIHtcbiAgICAgICAgICAgIHRocm93VW5leHBlY3RlZChsb29rYWhlYWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gc2hvcnRoYW5kIHByb3BlcnR5XG4gICAgICAgIHJldHVybiBtYXJrZXJBcHBseShcbiAgICAgICAgICAgIG1hcmtlcixcbiAgICAgICAgICAgIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVByb3BlcnR5KFxuICAgICAgICAgICAgICAgIFwiaW5pdFwiLFxuICAgICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICAgICAgZmFsc2VcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBvbmx5IHBvc3NpYmlsaXR5IGluIHRoaXMgYnJhbmNoIGlzIGEgc2hvcnRoYW5kIGdlbmVyYXRvclxuICAgIGlmICh0b2tlbi50eXBlID09PSBUb2tlbi5FT0YgfHwgdG9rZW4udHlwZSA9PT0gVG9rZW4uUHVuY3R1YXRvcikge1xuICAgICAgICBpZiAoIWFsbG93R2VuZXJhdG9ycyB8fCAhbWF0Y2goXCIqXCIpIHx8ICFhbGxvd01ldGhvZCkge1xuICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkKHRva2VuKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxleCgpO1xuXG4gICAgICAgIGlkID0gcGFyc2VPYmplY3RQcm9wZXJ0eUtleSgpO1xuXG4gICAgICAgIHJldHVybiBwYXJzZUdlbmVyYXRvclByb3BlcnR5KGlkLCBtYXJrZXIpO1xuXG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBJZiB3ZSd2ZSBtYWRlIGl0IGhlcmUsIHRoZW4gdGhhdCBtZWFucyB0aGUgcHJvcGVydHkgbmFtZSBpcyByZXByZXNlbnRlZFxuICAgICAqIGJ5IGEgc3RyaW5nIChpLmUsIHsgXCJmb29cIjogMn0pLiBUaGUgb25seSBvcHRpb25zIGhlcmUgYXJlIG5vcm1hbFxuICAgICAqIHByb3BlcnR5IHdpdGggYSBjb2xvbiBvciBhIG1ldGhvZC5cbiAgICAgKi9cbiAgICBrZXkgPSBwYXJzZU9iamVjdFByb3BlcnR5S2V5KCk7XG5cbiAgICAvLyBjaGVjayBmb3IgcHJvcGVydHkgdmFsdWVcbiAgICBpZiAobWF0Y2goXCI6XCIpKSB7XG4gICAgICAgIGxleCgpO1xuICAgICAgICByZXR1cm4gbWFya2VyQXBwbHkoXG4gICAgICAgICAgICBtYXJrZXIsXG4gICAgICAgICAgICBhc3ROb2RlRmFjdG9yeS5jcmVhdGVQcm9wZXJ0eShcbiAgICAgICAgICAgICAgICBcImluaXRcIixcbiAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgcGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbigpLFxuICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICAgIGZhbHNlXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gY2hlY2sgZm9yIG1ldGhvZFxuICAgIGlmIChhbGxvd01ldGhvZCAmJiBtYXRjaChcIihcIikpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KFxuICAgICAgICAgICAgbWFya2VyLFxuICAgICAgICAgICAgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlUHJvcGVydHkoXG4gICAgICAgICAgICAgICAgXCJpbml0XCIsXG4gICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgIHBhcnNlUHJvcGVydHlNZXRob2RGdW5jdGlvbigpLFxuICAgICAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgZmFsc2VcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBubyBvdGhlciBvcHRpb25zLCB0aGlzIGlzIGJhZFxuICAgIHRocm93VW5leHBlY3RlZChsZXgoKSk7XG59XG5cbmZ1bmN0aW9uIGdldEZpZWxkTmFtZShrZXkpIHtcbiAgICB2YXIgdG9TdHJpbmcgPSBTdHJpbmc7XG4gICAgaWYgKGtleS50eXBlID09PSBhc3ROb2RlVHlwZXMuSWRlbnRpZmllcikge1xuICAgICAgICByZXR1cm4ga2V5Lm5hbWU7XG4gICAgfVxuICAgIHJldHVybiB0b1N0cmluZyhrZXkudmFsdWUpO1xufVxuXG5mdW5jdGlvbiBwYXJzZU9iamVjdEluaXRpYWxpc2VyKCkge1xuICAgIHZhciBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKSxcbiAgICAgICAgYWxsb3dEdXBsaWNhdGVzID0gZXh0cmEuZWNtYUZlYXR1cmVzLm9iamVjdExpdGVyYWxEdXBsaWNhdGVQcm9wZXJ0aWVzLFxuICAgICAgICBwcm9wZXJ0aWVzID0gW10sXG4gICAgICAgIHByb3BlcnR5LFxuICAgICAgICBuYW1lLFxuICAgICAgICBwcm9wZXJ0eUZuLFxuICAgICAgICBraW5kLFxuICAgICAgICBzdG9yZWRLaW5kLFxuICAgICAgICBwcmV2aW91c0luT2JqZWN0TGl0ZXJhbCA9IHN0YXRlLmluT2JqZWN0TGl0ZXJhbCxcbiAgICAgICAga2luZE1hcCA9IG5ldyBTdHJpbmdNYXAoKTtcblxuICAgIHN0YXRlLmluT2JqZWN0TGl0ZXJhbCA9IHRydWU7XG5cbiAgICBleHBlY3QoXCJ7XCIpO1xuXG4gICAgd2hpbGUgKCFtYXRjaChcIn1cIikpIHtcblxuICAgICAgICBwcm9wZXJ0eSA9IHBhcnNlT2JqZWN0UHJvcGVydHkoKTtcblxuICAgICAgICBpZiAoIXByb3BlcnR5LmNvbXB1dGVkKSB7XG5cbiAgICAgICAgICAgIG5hbWUgPSBnZXRGaWVsZE5hbWUocHJvcGVydHkua2V5KTtcbiAgICAgICAgICAgIHByb3BlcnR5Rm4gPSAocHJvcGVydHkua2luZCA9PT0gXCJnZXRcIikgPyBQcm9wZXJ0eUtpbmQuR2V0IDogUHJvcGVydHlLaW5kLlNldDtcbiAgICAgICAgICAgIGtpbmQgPSAocHJvcGVydHkua2luZCA9PT0gXCJpbml0XCIpID8gUHJvcGVydHlLaW5kLkRhdGEgOiBwcm9wZXJ0eUZuO1xuXG4gICAgICAgICAgICBpZiAoa2luZE1hcC5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgICAgICBzdG9yZWRLaW5kID0ga2luZE1hcC5nZXQobmFtZSk7XG4gICAgICAgICAgICAgICAgaWYgKHN0b3JlZEtpbmQgPT09IFByb3BlcnR5S2luZC5EYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChraW5kID09PSBQcm9wZXJ0eUtpbmQuRGF0YSAmJiBuYW1lID09PSBcIl9fcHJvdG9fX1wiICYmIGFsbG93RHVwbGljYXRlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRHVwbGljYXRlICdfX3Byb3RvX18nIGxpdGVyYWwgcHJvcGVydGllcyBhcmUgZm9yYmlkZGVuIGluIEVTIDZcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93RXJyb3JUb2xlcmFudCh7fSwgTWVzc2FnZXMuRHVwbGljYXRlUHJvdG90eXBlUHJvcGVydHkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0cmljdCAmJiBraW5kID09PSBQcm9wZXJ0eUtpbmQuRGF0YSAmJiAhYWxsb3dEdXBsaWNhdGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBEdXBsaWNhdGUgbGl0ZXJhbCBwcm9wZXJ0aWVzIGFyZSBvbmx5IGZvcmJpZGRlbiBpbiBFUyA1IHN0cmljdCBtb2RlXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQoe30sIE1lc3NhZ2VzLlN0cmljdER1cGxpY2F0ZVByb3BlcnR5KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChraW5kICE9PSBQcm9wZXJ0eUtpbmQuRGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dFcnJvclRvbGVyYW50KHt9LCBNZXNzYWdlcy5BY2Nlc3NvckRhdGFQcm9wZXJ0eSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoa2luZCA9PT0gUHJvcGVydHlLaW5kLkRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93RXJyb3JUb2xlcmFudCh7fSwgTWVzc2FnZXMuQWNjZXNzb3JEYXRhUHJvcGVydHkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0b3JlZEtpbmQgJiBraW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQoe30sIE1lc3NhZ2VzLkFjY2Vzc29yR2V0U2V0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBraW5kTWFwLnNldChuYW1lLCBzdG9yZWRLaW5kIHwga2luZCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGtpbmRNYXAuc2V0KG5hbWUsIGtpbmQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcHJvcGVydGllcy5wdXNoKHByb3BlcnR5KTtcblxuICAgICAgICBpZiAoIW1hdGNoKFwifVwiKSkge1xuICAgICAgICAgICAgZXhwZWN0KFwiLFwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGV4cGVjdChcIn1cIik7XG5cbiAgICBzdGF0ZS5pbk9iamVjdExpdGVyYWwgPSBwcmV2aW91c0luT2JqZWN0TGl0ZXJhbDtcblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZU9iamVjdEV4cHJlc3Npb24ocHJvcGVydGllcykpO1xufVxuXG4vKipcbiAqIFBhcnNlIGEgdGVtcGxhdGUgc3RyaW5nIGVsZW1lbnQgYW5kIHJldHVybiBpdHMgQVNUTm9kZSByZXByZXNlbnRhdGlvblxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbiBQYXJzaW5nICYgc2Nhbm5pbmcgb3B0aW9uc1xuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbi5oZWFkIFRydWUgaWYgdGhpcyBlbGVtZW50IGlzIHRoZSBmaXJzdCBpbiB0aGVcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlIHN0cmluZywgZmFsc2Ugb3RoZXJ3aXNlLlxuICogQHJldHVybnMge0FTVE5vZGV9IFRoZSB0ZW1wbGF0ZSBlbGVtZW50IG5vZGUgd2l0aCBtYXJrZXIgaW5mbyBhcHBsaWVkXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBwYXJzZVRlbXBsYXRlRWxlbWVudChvcHRpb24pIHtcbiAgICB2YXIgbWFya2VyLCB0b2tlbjtcblxuICAgIGlmIChsb29rYWhlYWQudHlwZSAhPT0gVG9rZW4uVGVtcGxhdGUgfHwgKG9wdGlvbi5oZWFkICYmICFsb29rYWhlYWQuaGVhZCkpIHtcbiAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuVW5leHBlY3RlZFRva2VuLCBcIklMTEVHQUxcIik7XG4gICAgfVxuXG4gICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG4gICAgdG9rZW4gPSBsZXgoKTtcblxuICAgIHJldHVybiBtYXJrZXJBcHBseShcbiAgICAgICAgbWFya2VyLFxuICAgICAgICBhc3ROb2RlRmFjdG9yeS5jcmVhdGVUZW1wbGF0ZUVsZW1lbnQoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcmF3OiB0b2tlbi52YWx1ZS5yYXcsXG4gICAgICAgICAgICAgICAgY29va2VkOiB0b2tlbi52YWx1ZS5jb29rZWRcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0b2tlbi50YWlsXG4gICAgICAgIClcbiAgICApO1xufVxuXG4vKipcbiAqIFBhcnNlIGEgdGVtcGxhdGUgc3RyaW5nIGxpdGVyYWwgYW5kIHJldHVybiBpdHMgQVNUTm9kZSByZXByZXNlbnRhdGlvblxuICogQHJldHVybnMge0FTVE5vZGV9IFRoZSB0ZW1wbGF0ZSBsaXRlcmFsIG5vZGUgd2l0aCBtYXJrZXIgaW5mbyBhcHBsaWVkXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBwYXJzZVRlbXBsYXRlTGl0ZXJhbCgpIHtcbiAgICB2YXIgcXVhc2ksIHF1YXNpcywgZXhwcmVzc2lvbnMsIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuXG4gICAgcXVhc2kgPSBwYXJzZVRlbXBsYXRlRWxlbWVudCh7IGhlYWQ6IHRydWUgfSk7XG4gICAgcXVhc2lzID0gWyBxdWFzaSBdO1xuICAgIGV4cHJlc3Npb25zID0gW107XG5cbiAgICB3aGlsZSAoIXF1YXNpLnRhaWwpIHtcbiAgICAgICAgZXhwcmVzc2lvbnMucHVzaChwYXJzZUV4cHJlc3Npb24oKSk7XG4gICAgICAgIHF1YXNpID0gcGFyc2VUZW1wbGF0ZUVsZW1lbnQoeyBoZWFkOiBmYWxzZSB9KTtcbiAgICAgICAgcXVhc2lzLnB1c2gocXVhc2kpO1xuICAgIH1cblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVRlbXBsYXRlTGl0ZXJhbChxdWFzaXMsIGV4cHJlc3Npb25zKSk7XG59XG5cbi8vIDExLjEuNiBUaGUgR3JvdXBpbmcgT3BlcmF0b3JcblxuZnVuY3Rpb24gcGFyc2VHcm91cEV4cHJlc3Npb24oKSB7XG4gICAgdmFyIGV4cHI7XG5cbiAgICBleHBlY3QoXCIoXCIpO1xuXG4gICAgKytzdGF0ZS5wYXJlbnRoZXNpc0NvdW50O1xuXG4gICAgZXhwciA9IHBhcnNlRXhwcmVzc2lvbigpO1xuXG4gICAgZXhwZWN0KFwiKVwiKTtcblxuICAgIHJldHVybiBleHByO1xufVxuXG5cbi8vIDExLjEgUHJpbWFyeSBFeHByZXNzaW9uc1xuXG5mdW5jdGlvbiBwYXJzZVByaW1hcnlFeHByZXNzaW9uKCkge1xuICAgIHZhciB0eXBlLCB0b2tlbiwgZXhwcixcbiAgICAgICAgbWFya2VyLFxuICAgICAgICBhbGxvd0pTWCA9IGV4dHJhLmVjbWFGZWF0dXJlcy5qc3gsXG4gICAgICAgIGFsbG93Q2xhc3NlcyA9IGV4dHJhLmVjbWFGZWF0dXJlcy5jbGFzc2VzLFxuICAgICAgICBhbGxvd1N1cGVyID0gYWxsb3dDbGFzc2VzIHx8IGV4dHJhLmVjbWFGZWF0dXJlcy5zdXBlckluRnVuY3Rpb25zO1xuXG4gICAgaWYgKG1hdGNoKFwiKFwiKSkge1xuICAgICAgICByZXR1cm4gcGFyc2VHcm91cEV4cHJlc3Npb24oKTtcbiAgICB9XG5cbiAgICBpZiAobWF0Y2goXCJbXCIpKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUFycmF5SW5pdGlhbGlzZXIoKTtcbiAgICB9XG5cbiAgICBpZiAobWF0Y2goXCJ7XCIpKSB7XG4gICAgICAgIHJldHVybiBwYXJzZU9iamVjdEluaXRpYWxpc2VyKCk7XG4gICAgfVxuXG4gICAgaWYgKGFsbG93SlNYICYmIG1hdGNoKFwiPFwiKSkge1xuICAgICAgICByZXR1cm4gcGFyc2VKU1hFbGVtZW50KCk7XG4gICAgfVxuXG4gICAgdHlwZSA9IGxvb2thaGVhZC50eXBlO1xuICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuXG4gICAgaWYgKHR5cGUgPT09IFRva2VuLklkZW50aWZpZXIpIHtcbiAgICAgICAgZXhwciA9IGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUlkZW50aWZpZXIobGV4KCkudmFsdWUpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gVG9rZW4uU3RyaW5nTGl0ZXJhbCB8fCB0eXBlID09PSBUb2tlbi5OdW1lcmljTGl0ZXJhbCkge1xuICAgICAgICBpZiAoc3RyaWN0ICYmIGxvb2thaGVhZC5vY3RhbCkge1xuICAgICAgICAgICAgdGhyb3dFcnJvclRvbGVyYW50KGxvb2thaGVhZCwgTWVzc2FnZXMuU3RyaWN0T2N0YWxMaXRlcmFsKTtcbiAgICAgICAgfVxuICAgICAgICBleHByID0gYXN0Tm9kZUZhY3RvcnkuY3JlYXRlTGl0ZXJhbEZyb21Tb3VyY2UobGV4KCksIHNvdXJjZSk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBUb2tlbi5LZXl3b3JkKSB7XG4gICAgICAgIGlmIChtYXRjaEtleXdvcmQoXCJmdW5jdGlvblwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHBhcnNlRnVuY3Rpb25FeHByZXNzaW9uKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYWxsb3dTdXBlciAmJiBtYXRjaEtleXdvcmQoXCJzdXBlclwiKSAmJiBzdGF0ZS5pbkZ1bmN0aW9uQm9keSkge1xuICAgICAgICAgICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVN1cGVyKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1hdGNoS2V5d29yZChcInRoaXNcIikpIHtcbiAgICAgICAgICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVUaGlzRXhwcmVzc2lvbigpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhbGxvd0NsYXNzZXMgJiYgbWF0Y2hLZXl3b3JkKFwiY2xhc3NcIikpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUNsYXNzRXhwcmVzc2lvbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3dVbmV4cGVjdGVkKGxleCgpKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFRva2VuLkJvb2xlYW5MaXRlcmFsKSB7XG4gICAgICAgIHRva2VuID0gbGV4KCk7XG4gICAgICAgIHRva2VuLnZhbHVlID0gKHRva2VuLnZhbHVlID09PSBcInRydWVcIik7XG4gICAgICAgIGV4cHIgPSBhc3ROb2RlRmFjdG9yeS5jcmVhdGVMaXRlcmFsRnJvbVNvdXJjZSh0b2tlbiwgc291cmNlKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFRva2VuLk51bGxMaXRlcmFsKSB7XG4gICAgICAgIHRva2VuID0gbGV4KCk7XG4gICAgICAgIHRva2VuLnZhbHVlID0gbnVsbDtcbiAgICAgICAgZXhwciA9IGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUxpdGVyYWxGcm9tU291cmNlKHRva2VuLCBzb3VyY2UpO1xuICAgIH0gZWxzZSBpZiAobWF0Y2goXCIvXCIpIHx8IG1hdGNoKFwiLz1cIikpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBleHRyYS50b2tlbnMgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIGV4cHIgPSBhc3ROb2RlRmFjdG9yeS5jcmVhdGVMaXRlcmFsRnJvbVNvdXJjZShjb2xsZWN0UmVnZXgoKSwgc291cmNlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4cHIgPSBhc3ROb2RlRmFjdG9yeS5jcmVhdGVMaXRlcmFsRnJvbVNvdXJjZShzY2FuUmVnRXhwKCksIHNvdXJjZSk7XG4gICAgICAgIH1cbiAgICAgICAgcGVlaygpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gVG9rZW4uVGVtcGxhdGUpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlVGVtcGxhdGVMaXRlcmFsKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICB0aHJvd1VuZXhwZWN0ZWQobGV4KCkpO1xuICAgIH1cblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGV4cHIpO1xufVxuXG4vLyAxMS4yIExlZnQtSGFuZC1TaWRlIEV4cHJlc3Npb25zXG5cbmZ1bmN0aW9uIHBhcnNlQXJndW1lbnRzKCkge1xuICAgIHZhciBhcmdzID0gW10sIGFyZztcblxuICAgIGV4cGVjdChcIihcIik7XG4gICAgaWYgKCFtYXRjaChcIilcIikpIHtcbiAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBhcmcgPSBwYXJzZVNwcmVhZE9yQXNzaWdubWVudEV4cHJlc3Npb24oKTtcbiAgICAgICAgICAgIGFyZ3MucHVzaChhcmcpO1xuXG4gICAgICAgICAgICBpZiAobWF0Y2goXCIpXCIpKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGV4cGVjdChcIixcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBleHBlY3QoXCIpXCIpO1xuXG4gICAgcmV0dXJuIGFyZ3M7XG59XG5cbmZ1bmN0aW9uIHBhcnNlU3ByZWFkT3JBc3NpZ25tZW50RXhwcmVzc2lvbigpIHtcbiAgICBpZiAobWF0Y2goXCIuLi5cIikpIHtcbiAgICAgICAgdmFyIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuICAgICAgICBsZXgoKTtcbiAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlU3ByZWFkRWxlbWVudChwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKCkpKTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24oKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VOb25Db21wdXRlZFByb3BlcnR5KCkge1xuICAgIHZhciB0b2tlbixcbiAgICAgICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG5cbiAgICB0b2tlbiA9IGxleCgpO1xuXG4gICAgaWYgKCFpc0lkZW50aWZpZXJOYW1lKHRva2VuKSkge1xuICAgICAgICB0aHJvd1VuZXhwZWN0ZWQodG9rZW4pO1xuICAgIH1cblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUlkZW50aWZpZXIodG9rZW4udmFsdWUpKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VOb25Db21wdXRlZE1lbWJlcigpIHtcbiAgICBleHBlY3QoXCIuXCIpO1xuXG4gICAgcmV0dXJuIHBhcnNlTm9uQ29tcHV0ZWRQcm9wZXJ0eSgpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUNvbXB1dGVkTWVtYmVyKCkge1xuICAgIHZhciBleHByO1xuXG4gICAgZXhwZWN0KFwiW1wiKTtcblxuICAgIGV4cHIgPSBwYXJzZUV4cHJlc3Npb24oKTtcblxuICAgIGV4cGVjdChcIl1cIik7XG5cbiAgICByZXR1cm4gZXhwcjtcbn1cblxuZnVuY3Rpb24gcGFyc2VOZXdFeHByZXNzaW9uKCkge1xuICAgIHZhciBjYWxsZWUsIGFyZ3MsXG4gICAgICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuXG4gICAgZXhwZWN0S2V5d29yZChcIm5ld1wiKTtcbiAgICBjYWxsZWUgPSBwYXJzZUxlZnRIYW5kU2lkZUV4cHJlc3Npb24oKTtcbiAgICBhcmdzID0gbWF0Y2goXCIoXCIpID8gcGFyc2VBcmd1bWVudHMoKSA6IFtdO1xuXG4gICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlTmV3RXhwcmVzc2lvbihjYWxsZWUsIGFyZ3MpKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VMZWZ0SGFuZFNpZGVFeHByZXNzaW9uQWxsb3dDYWxsKCkge1xuICAgIHZhciBleHByLCBhcmdzLFxuICAgICAgICBwcmV2aW91c0FsbG93SW4gPSBzdGF0ZS5hbGxvd0luLFxuICAgICAgICBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcblxuICAgIHN0YXRlLmFsbG93SW4gPSB0cnVlO1xuICAgIGV4cHIgPSBtYXRjaEtleXdvcmQoXCJuZXdcIikgPyBwYXJzZU5ld0V4cHJlc3Npb24oKSA6IHBhcnNlUHJpbWFyeUV4cHJlc3Npb24oKTtcbiAgICBzdGF0ZS5hbGxvd0luID0gcHJldmlvdXNBbGxvd0luO1xuXG4gICAgLy8gb25seSBzdGFydCBwYXJzaW5nIHRlbXBsYXRlIGxpdGVyYWwgaWYgdGhlIGxvb2thaGVhZCBpcyBhIGhlYWQgKGJlZ2lubmluZyB3aXRoIGApXG4gICAgd2hpbGUgKG1hdGNoKFwiLlwiKSB8fCBtYXRjaChcIltcIikgfHwgbWF0Y2goXCIoXCIpIHx8IChsb29rYWhlYWQudHlwZSA9PT0gVG9rZW4uVGVtcGxhdGUgJiYgbG9va2FoZWFkLmhlYWQpKSB7XG4gICAgICAgIGlmIChtYXRjaChcIihcIikpIHtcbiAgICAgICAgICAgIGFyZ3MgPSBwYXJzZUFyZ3VtZW50cygpO1xuICAgICAgICAgICAgZXhwciA9IG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlQ2FsbEV4cHJlc3Npb24oZXhwciwgYXJncykpO1xuICAgICAgICB9IGVsc2UgaWYgKG1hdGNoKFwiW1wiKSkge1xuICAgICAgICAgICAgZXhwciA9IG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlTWVtYmVyRXhwcmVzc2lvbihcIltcIiwgZXhwciwgcGFyc2VDb21wdXRlZE1lbWJlcigpKSk7XG4gICAgICAgIH0gZWxzZSBpZiAobWF0Y2goXCIuXCIpKSB7XG4gICAgICAgICAgICBleHByID0gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVNZW1iZXJFeHByZXNzaW9uKFwiLlwiLCBleHByLCBwYXJzZU5vbkNvbXB1dGVkTWVtYmVyKCkpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4cHIgPSBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVRhZ2dlZFRlbXBsYXRlRXhwcmVzc2lvbihleHByLCBwYXJzZVRlbXBsYXRlTGl0ZXJhbCgpKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZXhwcjtcbn1cblxuZnVuY3Rpb24gcGFyc2VMZWZ0SGFuZFNpZGVFeHByZXNzaW9uKCkge1xuICAgIHZhciBleHByLFxuICAgICAgICBwcmV2aW91c0FsbG93SW4gPSBzdGF0ZS5hbGxvd0luLFxuICAgICAgICBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcblxuICAgIGV4cHIgPSBtYXRjaEtleXdvcmQoXCJuZXdcIikgPyBwYXJzZU5ld0V4cHJlc3Npb24oKSA6IHBhcnNlUHJpbWFyeUV4cHJlc3Npb24oKTtcbiAgICBzdGF0ZS5hbGxvd0luID0gcHJldmlvdXNBbGxvd0luO1xuXG4gICAgLy8gb25seSBzdGFydCBwYXJzaW5nIHRlbXBsYXRlIGxpdGVyYWwgaWYgdGhlIGxvb2thaGVhZCBpcyBhIGhlYWQgKGJlZ2lubmluZyB3aXRoIGApXG4gICAgd2hpbGUgKG1hdGNoKFwiLlwiKSB8fCBtYXRjaChcIltcIikgfHwgKGxvb2thaGVhZC50eXBlID09PSBUb2tlbi5UZW1wbGF0ZSAmJiBsb29rYWhlYWQuaGVhZCkpIHtcbiAgICAgICAgaWYgKG1hdGNoKFwiW1wiKSkge1xuICAgICAgICAgICAgZXhwciA9IG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlTWVtYmVyRXhwcmVzc2lvbihcIltcIiwgZXhwciwgcGFyc2VDb21wdXRlZE1lbWJlcigpKSk7XG4gICAgICAgIH0gZWxzZSBpZiAobWF0Y2goXCIuXCIpKSB7XG4gICAgICAgICAgICBleHByID0gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVNZW1iZXJFeHByZXNzaW9uKFwiLlwiLCBleHByLCBwYXJzZU5vbkNvbXB1dGVkTWVtYmVyKCkpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4cHIgPSBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVRhZ2dlZFRlbXBsYXRlRXhwcmVzc2lvbihleHByLCBwYXJzZVRlbXBsYXRlTGl0ZXJhbCgpKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZXhwcjtcbn1cblxuXG4vLyAxMS4zIFBvc3RmaXggRXhwcmVzc2lvbnNcblxuZnVuY3Rpb24gcGFyc2VQb3N0Zml4RXhwcmVzc2lvbigpIHtcbiAgICB2YXIgZXhwciwgdG9rZW4sXG4gICAgICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuXG4gICAgZXhwciA9IHBhcnNlTGVmdEhhbmRTaWRlRXhwcmVzc2lvbkFsbG93Q2FsbCgpO1xuXG4gICAgaWYgKGxvb2thaGVhZC50eXBlID09PSBUb2tlbi5QdW5jdHVhdG9yKSB7XG4gICAgICAgIGlmICgobWF0Y2goXCIrK1wiKSB8fCBtYXRjaChcIi0tXCIpKSAmJiAhcGVla0xpbmVUZXJtaW5hdG9yKCkpIHtcbiAgICAgICAgICAgIC8vIDExLjMuMSwgMTEuMy4yXG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmIGV4cHIudHlwZSA9PT0gYXN0Tm9kZVR5cGVzLklkZW50aWZpZXIgJiYgc3ludGF4LmlzUmVzdHJpY3RlZFdvcmQoZXhwci5uYW1lKSkge1xuICAgICAgICAgICAgICAgIHRocm93RXJyb3JUb2xlcmFudCh7fSwgTWVzc2FnZXMuU3RyaWN0TEhTUG9zdGZpeCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghaXNMZWZ0SGFuZFNpZGUoZXhwcikpIHtcbiAgICAgICAgICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQoe30sIE1lc3NhZ2VzLkludmFsaWRMSFNJbkFzc2lnbm1lbnQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0b2tlbiA9IGxleCgpO1xuICAgICAgICAgICAgZXhwciA9IG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlUG9zdGZpeEV4cHJlc3Npb24odG9rZW4udmFsdWUsIGV4cHIpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBleHByO1xufVxuXG4vLyAxMS40IFVuYXJ5IE9wZXJhdG9yc1xuXG5mdW5jdGlvbiBwYXJzZVVuYXJ5RXhwcmVzc2lvbigpIHtcbiAgICB2YXIgdG9rZW4sIGV4cHIsXG4gICAgICAgIG1hcmtlcjtcblxuICAgIGlmIChsb29rYWhlYWQudHlwZSAhPT0gVG9rZW4uUHVuY3R1YXRvciAmJiBsb29rYWhlYWQudHlwZSAhPT0gVG9rZW4uS2V5d29yZCkge1xuICAgICAgICBleHByID0gcGFyc2VQb3N0Zml4RXhwcmVzc2lvbigpO1xuICAgIH0gZWxzZSBpZiAobWF0Y2goXCIrK1wiKSB8fCBtYXRjaChcIi0tXCIpKSB7XG4gICAgICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuICAgICAgICB0b2tlbiA9IGxleCgpO1xuICAgICAgICBleHByID0gcGFyc2VVbmFyeUV4cHJlc3Npb24oKTtcbiAgICAgICAgLy8gMTEuNC40LCAxMS40LjVcbiAgICAgICAgaWYgKHN0cmljdCAmJiBleHByLnR5cGUgPT09IGFzdE5vZGVUeXBlcy5JZGVudGlmaWVyICYmIHN5bnRheC5pc1Jlc3RyaWN0ZWRXb3JkKGV4cHIubmFtZSkpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3JUb2xlcmFudCh7fSwgTWVzc2FnZXMuU3RyaWN0TEhTUHJlZml4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNMZWZ0SGFuZFNpZGUoZXhwcikpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3JUb2xlcmFudCh7fSwgTWVzc2FnZXMuSW52YWxpZExIU0luQXNzaWdubWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBleHByID0gYXN0Tm9kZUZhY3RvcnkuY3JlYXRlVW5hcnlFeHByZXNzaW9uKHRva2VuLnZhbHVlLCBleHByKTtcbiAgICAgICAgZXhwciA9IG1hcmtlckFwcGx5KG1hcmtlciwgZXhwcik7XG4gICAgfSBlbHNlIGlmIChtYXRjaChcIitcIikgfHwgbWF0Y2goXCItXCIpIHx8IG1hdGNoKFwiflwiKSB8fCBtYXRjaChcIiFcIikpIHtcbiAgICAgICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG4gICAgICAgIHRva2VuID0gbGV4KCk7XG4gICAgICAgIGV4cHIgPSBwYXJzZVVuYXJ5RXhwcmVzc2lvbigpO1xuICAgICAgICBleHByID0gYXN0Tm9kZUZhY3RvcnkuY3JlYXRlVW5hcnlFeHByZXNzaW9uKHRva2VuLnZhbHVlLCBleHByKTtcbiAgICAgICAgZXhwciA9IG1hcmtlckFwcGx5KG1hcmtlciwgZXhwcik7XG4gICAgfSBlbHNlIGlmIChtYXRjaEtleXdvcmQoXCJkZWxldGVcIikgfHwgbWF0Y2hLZXl3b3JkKFwidm9pZFwiKSB8fCBtYXRjaEtleXdvcmQoXCJ0eXBlb2ZcIikpIHtcbiAgICAgICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG4gICAgICAgIHRva2VuID0gbGV4KCk7XG4gICAgICAgIGV4cHIgPSBwYXJzZVVuYXJ5RXhwcmVzc2lvbigpO1xuICAgICAgICBleHByID0gYXN0Tm9kZUZhY3RvcnkuY3JlYXRlVW5hcnlFeHByZXNzaW9uKHRva2VuLnZhbHVlLCBleHByKTtcbiAgICAgICAgZXhwciA9IG1hcmtlckFwcGx5KG1hcmtlciwgZXhwcik7XG4gICAgICAgIGlmIChzdHJpY3QgJiYgZXhwci5vcGVyYXRvciA9PT0gXCJkZWxldGVcIiAmJiBleHByLmFyZ3VtZW50LnR5cGUgPT09IGFzdE5vZGVUeXBlcy5JZGVudGlmaWVyKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQoe30sIE1lc3NhZ2VzLlN0cmljdERlbGV0ZSk7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBleHByID0gcGFyc2VQb3N0Zml4RXhwcmVzc2lvbigpO1xuICAgIH1cblxuICAgIHJldHVybiBleHByO1xufVxuXG5mdW5jdGlvbiBiaW5hcnlQcmVjZWRlbmNlKHRva2VuLCBhbGxvd0luKSB7XG4gICAgdmFyIHByZWMgPSAwO1xuXG4gICAgaWYgKHRva2VuLnR5cGUgIT09IFRva2VuLlB1bmN0dWF0b3IgJiYgdG9rZW4udHlwZSAhPT0gVG9rZW4uS2V5d29yZCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHRva2VuLnZhbHVlKSB7XG4gICAgY2FzZSBcInx8XCI6XG4gICAgICAgIHByZWMgPSAxO1xuICAgICAgICBicmVhaztcblxuICAgIGNhc2UgXCImJlwiOlxuICAgICAgICBwcmVjID0gMjtcbiAgICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFwifFwiOlxuICAgICAgICBwcmVjID0gMztcbiAgICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFwiXlwiOlxuICAgICAgICBwcmVjID0gNDtcbiAgICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFwiJlwiOlxuICAgICAgICBwcmVjID0gNTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFwiPT1cIjpcbiAgICBjYXNlIFwiIT1cIjpcbiAgICBjYXNlIFwiPT09XCI6XG4gICAgY2FzZSBcIiE9PVwiOlxuICAgICAgICBwcmVjID0gNjtcbiAgICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFwiPFwiOlxuICAgIGNhc2UgXCI+XCI6XG4gICAgY2FzZSBcIjw9XCI6XG4gICAgY2FzZSBcIj49XCI6XG4gICAgY2FzZSBcImluc3RhbmNlb2ZcIjpcbiAgICAgICAgcHJlYyA9IDc7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBcImluXCI6XG4gICAgICAgIHByZWMgPSBhbGxvd0luID8gNyA6IDA7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBcIjw8XCI6XG4gICAgY2FzZSBcIj4+XCI6XG4gICAgY2FzZSBcIj4+PlwiOlxuICAgICAgICBwcmVjID0gODtcbiAgICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFwiK1wiOlxuICAgIGNhc2UgXCItXCI6XG4gICAgICAgIHByZWMgPSA5O1xuICAgICAgICBicmVhaztcblxuICAgIGNhc2UgXCIqXCI6XG4gICAgY2FzZSBcIi9cIjpcbiAgICBjYXNlIFwiJVwiOlxuICAgICAgICBwcmVjID0gMTE7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgcmV0dXJuIHByZWM7XG59XG5cbi8vIDExLjUgTXVsdGlwbGljYXRpdmUgT3BlcmF0b3JzXG4vLyAxMS42IEFkZGl0aXZlIE9wZXJhdG9yc1xuLy8gMTEuNyBCaXR3aXNlIFNoaWZ0IE9wZXJhdG9yc1xuLy8gMTEuOCBSZWxhdGlvbmFsIE9wZXJhdG9yc1xuLy8gMTEuOSBFcXVhbGl0eSBPcGVyYXRvcnNcbi8vIDExLjEwIEJpbmFyeSBCaXR3aXNlIE9wZXJhdG9yc1xuLy8gMTEuMTEgQmluYXJ5IExvZ2ljYWwgT3BlcmF0b3JzXG5mdW5jdGlvbiBwYXJzZUJpbmFyeUV4cHJlc3Npb24oKSB7XG4gICAgdmFyIGV4cHIsIHRva2VuLCBwcmVjLCBwcmV2aW91c0FsbG93SW4sIHN0YWNrLCByaWdodCwgb3BlcmF0b3IsIGxlZnQsIGksXG4gICAgICAgIG1hcmtlciwgbWFya2VycztcblxuICAgIHByZXZpb3VzQWxsb3dJbiA9IHN0YXRlLmFsbG93SW47XG4gICAgc3RhdGUuYWxsb3dJbiA9IHRydWU7XG5cbiAgICBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcbiAgICBsZWZ0ID0gcGFyc2VVbmFyeUV4cHJlc3Npb24oKTtcblxuICAgIHRva2VuID0gbG9va2FoZWFkO1xuICAgIHByZWMgPSBiaW5hcnlQcmVjZWRlbmNlKHRva2VuLCBwcmV2aW91c0FsbG93SW4pO1xuICAgIGlmIChwcmVjID09PSAwKSB7XG4gICAgICAgIHJldHVybiBsZWZ0O1xuICAgIH1cbiAgICB0b2tlbi5wcmVjID0gcHJlYztcbiAgICBsZXgoKTtcblxuICAgIG1hcmtlcnMgPSBbbWFya2VyLCBtYXJrZXJDcmVhdGUoKV07XG4gICAgcmlnaHQgPSBwYXJzZVVuYXJ5RXhwcmVzc2lvbigpO1xuXG4gICAgc3RhY2sgPSBbbGVmdCwgdG9rZW4sIHJpZ2h0XTtcblxuICAgIHdoaWxlICgocHJlYyA9IGJpbmFyeVByZWNlZGVuY2UobG9va2FoZWFkLCBwcmV2aW91c0FsbG93SW4pKSA+IDApIHtcblxuICAgICAgICAvLyBSZWR1Y2U6IG1ha2UgYSBiaW5hcnkgZXhwcmVzc2lvbiBmcm9tIHRoZSB0aHJlZSB0b3Btb3N0IGVudHJpZXMuXG4gICAgICAgIHdoaWxlICgoc3RhY2subGVuZ3RoID4gMikgJiYgKHByZWMgPD0gc3RhY2tbc3RhY2subGVuZ3RoIC0gMl0ucHJlYykpIHtcbiAgICAgICAgICAgIHJpZ2h0ID0gc3RhY2sucG9wKCk7XG4gICAgICAgICAgICBvcGVyYXRvciA9IHN0YWNrLnBvcCgpLnZhbHVlO1xuICAgICAgICAgICAgbGVmdCA9IHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgZXhwciA9IGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUJpbmFyeUV4cHJlc3Npb24ob3BlcmF0b3IsIGxlZnQsIHJpZ2h0KTtcbiAgICAgICAgICAgIG1hcmtlcnMucG9wKCk7XG4gICAgICAgICAgICBtYXJrZXIgPSBtYXJrZXJzLnBvcCgpO1xuICAgICAgICAgICAgbWFya2VyQXBwbHkobWFya2VyLCBleHByKTtcbiAgICAgICAgICAgIHN0YWNrLnB1c2goZXhwcik7XG4gICAgICAgICAgICBtYXJrZXJzLnB1c2gobWFya2VyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNoaWZ0LlxuICAgICAgICB0b2tlbiA9IGxleCgpO1xuICAgICAgICB0b2tlbi5wcmVjID0gcHJlYztcbiAgICAgICAgc3RhY2sucHVzaCh0b2tlbik7XG4gICAgICAgIG1hcmtlcnMucHVzaChtYXJrZXJDcmVhdGUoKSk7XG4gICAgICAgIGV4cHIgPSBwYXJzZVVuYXJ5RXhwcmVzc2lvbigpO1xuICAgICAgICBzdGFjay5wdXNoKGV4cHIpO1xuICAgIH1cblxuICAgIHN0YXRlLmFsbG93SW4gPSBwcmV2aW91c0FsbG93SW47XG5cbiAgICAvLyBGaW5hbCByZWR1Y2UgdG8gY2xlYW4tdXAgdGhlIHN0YWNrLlxuICAgIGkgPSBzdGFjay5sZW5ndGggLSAxO1xuICAgIGV4cHIgPSBzdGFja1tpXTtcbiAgICBtYXJrZXJzLnBvcCgpO1xuICAgIHdoaWxlIChpID4gMSkge1xuICAgICAgICBleHByID0gYXN0Tm9kZUZhY3RvcnkuY3JlYXRlQmluYXJ5RXhwcmVzc2lvbihzdGFja1tpIC0gMV0udmFsdWUsIHN0YWNrW2kgLSAyXSwgZXhwcik7XG4gICAgICAgIGkgLT0gMjtcbiAgICAgICAgbWFya2VyID0gbWFya2Vycy5wb3AoKTtcbiAgICAgICAgbWFya2VyQXBwbHkobWFya2VyLCBleHByKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXhwcjtcbn1cblxuLy8gMTEuMTIgQ29uZGl0aW9uYWwgT3BlcmF0b3JcblxuZnVuY3Rpb24gcGFyc2VDb25kaXRpb25hbEV4cHJlc3Npb24oKSB7XG4gICAgdmFyIGV4cHIsIHByZXZpb3VzQWxsb3dJbiwgY29uc2VxdWVudCwgYWx0ZXJuYXRlLFxuICAgICAgICBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcblxuICAgIGV4cHIgPSBwYXJzZUJpbmFyeUV4cHJlc3Npb24oKTtcblxuICAgIGlmIChtYXRjaChcIj9cIikpIHtcbiAgICAgICAgbGV4KCk7XG4gICAgICAgIHByZXZpb3VzQWxsb3dJbiA9IHN0YXRlLmFsbG93SW47XG4gICAgICAgIHN0YXRlLmFsbG93SW4gPSB0cnVlO1xuICAgICAgICBjb25zZXF1ZW50ID0gcGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbigpO1xuICAgICAgICBzdGF0ZS5hbGxvd0luID0gcHJldmlvdXNBbGxvd0luO1xuICAgICAgICBleHBlY3QoXCI6XCIpO1xuICAgICAgICBhbHRlcm5hdGUgPSBwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKCk7XG5cbiAgICAgICAgZXhwciA9IGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUNvbmRpdGlvbmFsRXhwcmVzc2lvbihleHByLCBjb25zZXF1ZW50LCBhbHRlcm5hdGUpO1xuICAgICAgICBtYXJrZXJBcHBseShtYXJrZXIsIGV4cHIpO1xuICAgIH1cblxuICAgIHJldHVybiBleHByO1xufVxuXG4vLyBbRVM2XSAxNC4yIEFycm93IEZ1bmN0aW9uXG5cbmZ1bmN0aW9uIHBhcnNlQ29uY2lzZUJvZHkoKSB7XG4gICAgaWYgKG1hdGNoKFwie1wiKSkge1xuICAgICAgICByZXR1cm4gcGFyc2VGdW5jdGlvblNvdXJjZUVsZW1lbnRzKCk7XG4gICAgfVxuICAgIHJldHVybiBwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKCk7XG59XG5cbmZ1bmN0aW9uIHJlaW50ZXJwcmV0QXNDb3ZlckZvcm1hbHNMaXN0KGV4cHJlc3Npb25zKSB7XG4gICAgdmFyIGksIGxlbiwgcGFyYW0sIHBhcmFtcywgb3B0aW9ucyxcbiAgICAgICAgYWxsb3dSZXN0UGFyYW1zID0gZXh0cmEuZWNtYUZlYXR1cmVzLnJlc3RQYXJhbXM7XG5cbiAgICBwYXJhbXMgPSBbXTtcbiAgICBvcHRpb25zID0ge1xuICAgICAgICBwYXJhbVNldDogbmV3IFN0cmluZ01hcCgpXG4gICAgfTtcblxuICAgIGZvciAoaSA9IDAsIGxlbiA9IGV4cHJlc3Npb25zLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgICAgIHBhcmFtID0gZXhwcmVzc2lvbnNbaV07XG4gICAgICAgIGlmIChwYXJhbS50eXBlID09PSBhc3ROb2RlVHlwZXMuSWRlbnRpZmllcikge1xuICAgICAgICAgICAgcGFyYW1zLnB1c2gocGFyYW0pO1xuICAgICAgICAgICAgdmFsaWRhdGVQYXJhbShvcHRpb25zLCBwYXJhbSwgcGFyYW0ubmFtZSk7XG4gICAgICAgIH0gIGVsc2UgaWYgKHBhcmFtLnR5cGUgPT09IGFzdE5vZGVUeXBlcy5PYmplY3RFeHByZXNzaW9uIHx8IHBhcmFtLnR5cGUgPT09IGFzdE5vZGVUeXBlcy5BcnJheUV4cHJlc3Npb24pIHtcbiAgICAgICAgICAgIHJlaW50ZXJwcmV0QXNEZXN0cnVjdHVyZWRQYXJhbWV0ZXIob3B0aW9ucywgcGFyYW0pO1xuICAgICAgICAgICAgcGFyYW1zLnB1c2gocGFyYW0pO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcmFtLnR5cGUgPT09IGFzdE5vZGVUeXBlcy5TcHJlYWRFbGVtZW50KSB7XG4gICAgICAgICAgICBhc3NlcnQoaSA9PT0gbGVuIC0gMSwgXCJJdCBpcyBndWFyYW50ZWVkIHRoYXQgU3ByZWFkRWxlbWVudCBpcyBsYXN0IGVsZW1lbnQgYnkgcGFyc2VFeHByZXNzaW9uXCIpO1xuICAgICAgICAgICAgaWYgKHBhcmFtLmFyZ3VtZW50LnR5cGUgIT09IGFzdE5vZGVUeXBlcy5JZGVudGlmaWVyKSB7XG4gICAgICAgICAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuVW5leHBlY3RlZFRva2VuLCBcIltcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghYWxsb3dSZXN0UGFyYW1zKSB7XG4gICAgICAgICAgICAgICAgLy8gY2FuJ3QgZ2V0IGNvcnJlY3QgbGluZS9jb2x1bW4gaGVyZSA6KFxuICAgICAgICAgICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgXCIuXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZWludGVycHJldEFzRGVzdHJ1Y3R1cmVkUGFyYW1ldGVyKG9wdGlvbnMsIHBhcmFtLmFyZ3VtZW50KTtcbiAgICAgICAgICAgIHBhcmFtLnR5cGUgPSBhc3ROb2RlVHlwZXMuUmVzdEVsZW1lbnQ7XG4gICAgICAgICAgICBwYXJhbXMucHVzaChwYXJhbSk7XG4gICAgICAgIH0gZWxzZSBpZiAocGFyYW0udHlwZSA9PT0gYXN0Tm9kZVR5cGVzLlJlc3RFbGVtZW50KSB7XG4gICAgICAgICAgICBwYXJhbXMucHVzaChwYXJhbSk7XG4gICAgICAgICAgICB2YWxpZGF0ZVBhcmFtKG9wdGlvbnMsIHBhcmFtLmFyZ3VtZW50LCBwYXJhbS5hcmd1bWVudC5uYW1lKTtcbiAgICAgICAgfSBlbHNlIGlmIChwYXJhbS50eXBlID09PSBhc3ROb2RlVHlwZXMuQXNzaWdubWVudEV4cHJlc3Npb24pIHtcblxuICAgICAgICAgICAgLy8gVE9ETzogRmluZCBhIGxlc3MgaGFja3kgd2F5IG9mIGRvaW5nIHRoaXNcbiAgICAgICAgICAgIHBhcmFtLnR5cGUgPSBhc3ROb2RlVHlwZXMuQXNzaWdubWVudFBhdHRlcm47XG4gICAgICAgICAgICBkZWxldGUgcGFyYW0ub3BlcmF0b3I7XG5cbiAgICAgICAgICAgIHBhcmFtcy5wdXNoKHBhcmFtKTtcbiAgICAgICAgICAgIHZhbGlkYXRlUGFyYW0ob3B0aW9ucywgcGFyYW0ubGVmdCwgcGFyYW0ubGVmdC5uYW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMubWVzc2FnZSA9PT0gTWVzc2FnZXMuU3RyaWN0UGFyYW1EdXBlKSB7XG4gICAgICAgIHRocm93RXJyb3IoXG4gICAgICAgICAgICBzdHJpY3QgPyBvcHRpb25zLnN0cmljdGVkIDogb3B0aW9ucy5maXJzdFJlc3RyaWN0ZWQsXG4gICAgICAgICAgICBvcHRpb25zLm1lc3NhZ2VcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBwYXJhbXM6IHBhcmFtcyxcbiAgICAgICAgc3RyaWN0ZWQ6IG9wdGlvbnMuc3RyaWN0ZWQsXG4gICAgICAgIGZpcnN0UmVzdHJpY3RlZDogb3B0aW9ucy5maXJzdFJlc3RyaWN0ZWQsXG4gICAgICAgIG1lc3NhZ2U6IG9wdGlvbnMubWVzc2FnZVxuICAgIH07XG59XG5cbmZ1bmN0aW9uIHBhcnNlQXJyb3dGdW5jdGlvbkV4cHJlc3Npb24ob3B0aW9ucywgbWFya2VyKSB7XG4gICAgdmFyIHByZXZpb3VzU3RyaWN0LCBib2R5O1xuXG4gICAgZXhwZWN0KFwiPT5cIik7XG4gICAgcHJldmlvdXNTdHJpY3QgPSBzdHJpY3Q7XG5cbiAgICBib2R5ID0gcGFyc2VDb25jaXNlQm9keSgpO1xuXG4gICAgaWYgKHN0cmljdCAmJiBvcHRpb25zLmZpcnN0UmVzdHJpY3RlZCkge1xuICAgICAgICB0aHJvd0Vycm9yKG9wdGlvbnMuZmlyc3RSZXN0cmljdGVkLCBvcHRpb25zLm1lc3NhZ2UpO1xuICAgIH1cbiAgICBpZiAoc3RyaWN0ICYmIG9wdGlvbnMuc3RyaWN0ZWQpIHtcbiAgICAgICAgdGhyb3dFcnJvclRvbGVyYW50KG9wdGlvbnMuc3RyaWN0ZWQsIG9wdGlvbnMubWVzc2FnZSk7XG4gICAgfVxuXG4gICAgc3RyaWN0ID0gcHJldmlvdXNTdHJpY3Q7XG4gICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlQXJyb3dGdW5jdGlvbkV4cHJlc3Npb24oXG4gICAgICAgIG9wdGlvbnMucGFyYW1zLFxuICAgICAgICBib2R5LFxuICAgICAgICBib2R5LnR5cGUgIT09IGFzdE5vZGVUeXBlcy5CbG9ja1N0YXRlbWVudFxuICAgICkpO1xufVxuXG4vLyAxMS4xMyBBc3NpZ25tZW50IE9wZXJhdG9yc1xuXG4vLyAxMi4xNC41IEFzc2lnbm1lbnRQYXR0ZXJuXG5cbmZ1bmN0aW9uIHJlaW50ZXJwcmV0QXNBc3NpZ25tZW50QmluZGluZ1BhdHRlcm4oZXhwcikge1xuICAgIHZhciBpLCBsZW4sIHByb3BlcnR5LCBlbGVtZW50LFxuICAgICAgICBhbGxvd0Rlc3RydWN0dXJpbmcgPSBleHRyYS5lY21hRmVhdHVyZXMuZGVzdHJ1Y3R1cmluZztcblxuICAgIGlmICghYWxsb3dEZXN0cnVjdHVyaW5nKSB7XG4gICAgICAgIHRocm93VW5leHBlY3RlZChsZXgoKSk7XG4gICAgfVxuXG4gICAgaWYgKGV4cHIudHlwZSA9PT0gYXN0Tm9kZVR5cGVzLk9iamVjdEV4cHJlc3Npb24pIHtcbiAgICAgICAgZXhwci50eXBlID0gYXN0Tm9kZVR5cGVzLk9iamVjdFBhdHRlcm47XG4gICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGV4cHIucHJvcGVydGllcy5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgICAgICAgICAgcHJvcGVydHkgPSBleHByLnByb3BlcnRpZXNbaV07XG4gICAgICAgICAgICBpZiAocHJvcGVydHkua2luZCAhPT0gXCJpbml0XCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQoe30sIE1lc3NhZ2VzLkludmFsaWRMSFNJbkFzc2lnbm1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVpbnRlcnByZXRBc0Fzc2lnbm1lbnRCaW5kaW5nUGF0dGVybihwcm9wZXJ0eS52YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGV4cHIudHlwZSA9PT0gYXN0Tm9kZVR5cGVzLkFycmF5RXhwcmVzc2lvbikge1xuICAgICAgICBleHByLnR5cGUgPSBhc3ROb2RlVHlwZXMuQXJyYXlQYXR0ZXJuO1xuICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSBleHByLmVsZW1lbnRzLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgICAgICAgICBlbGVtZW50ID0gZXhwci5lbGVtZW50c1tpXTtcbiAgICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHJlaW50ZXJwcmV0QXNBc3NpZ25tZW50QmluZGluZ1BhdHRlcm4oZWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGV4cHIudHlwZSA9PT0gYXN0Tm9kZVR5cGVzLklkZW50aWZpZXIpIHtcbiAgICAgICAgaWYgKHN5bnRheC5pc1Jlc3RyaWN0ZWRXb3JkKGV4cHIubmFtZSkpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3JUb2xlcmFudCh7fSwgTWVzc2FnZXMuSW52YWxpZExIU0luQXNzaWdubWVudCk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGV4cHIudHlwZSA9PT0gYXN0Tm9kZVR5cGVzLlNwcmVhZEVsZW1lbnQpIHtcbiAgICAgICAgcmVpbnRlcnByZXRBc0Fzc2lnbm1lbnRCaW5kaW5nUGF0dGVybihleHByLmFyZ3VtZW50KTtcbiAgICAgICAgaWYgKGV4cHIuYXJndW1lbnQudHlwZSA9PT0gYXN0Tm9kZVR5cGVzLk9iamVjdFBhdHRlcm4pIHtcbiAgICAgICAgICAgIHRocm93RXJyb3JUb2xlcmFudCh7fSwgTWVzc2FnZXMuT2JqZWN0UGF0dGVybkFzU3ByZWFkKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZXhwci50eXBlID09PSBcIkFzc2lnbm1lbnRFeHByZXNzaW9uXCIgJiYgZXhwci5vcGVyYXRvciA9PT0gXCI9XCIpIHtcbiAgICAgICAgZXhwci50eXBlID0gYXN0Tm9kZVR5cGVzLkFzc2lnbm1lbnRQYXR0ZXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICAgIGlmIChleHByLnR5cGUgIT09IGFzdE5vZGVUeXBlcy5NZW1iZXJFeHByZXNzaW9uICYmXG4gICAgICAgICAgICBleHByLnR5cGUgIT09IGFzdE5vZGVUeXBlcy5DYWxsRXhwcmVzc2lvbiAmJlxuICAgICAgICAgICAgZXhwci50eXBlICE9PSBhc3ROb2RlVHlwZXMuTmV3RXhwcmVzc2lvbiAmJlxuICAgICAgICAgICAgZXhwci50eXBlICE9PSBhc3ROb2RlVHlwZXMuQXNzaWdubWVudFBhdHRlcm5cbiAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQoe30sIE1lc3NhZ2VzLkludmFsaWRMSFNJbkFzc2lnbm1lbnQpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vLyAxMy4yLjMgQmluZGluZ1BhdHRlcm5cblxuZnVuY3Rpb24gcmVpbnRlcnByZXRBc0Rlc3RydWN0dXJlZFBhcmFtZXRlcihvcHRpb25zLCBleHByKSB7XG4gICAgdmFyIGksIGxlbiwgcHJvcGVydHksIGVsZW1lbnQsXG4gICAgICAgIGFsbG93RGVzdHJ1Y3R1cmluZyA9IGV4dHJhLmVjbWFGZWF0dXJlcy5kZXN0cnVjdHVyaW5nO1xuXG4gICAgaWYgKCFhbGxvd0Rlc3RydWN0dXJpbmcpIHtcbiAgICAgICAgdGhyb3dVbmV4cGVjdGVkKGxleCgpKTtcbiAgICB9XG5cbiAgICBpZiAoZXhwci50eXBlID09PSBhc3ROb2RlVHlwZXMuT2JqZWN0RXhwcmVzc2lvbikge1xuICAgICAgICBleHByLnR5cGUgPSBhc3ROb2RlVHlwZXMuT2JqZWN0UGF0dGVybjtcbiAgICAgICAgZm9yIChpID0gMCwgbGVuID0gZXhwci5wcm9wZXJ0aWVzLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgICAgICAgICBwcm9wZXJ0eSA9IGV4cHIucHJvcGVydGllc1tpXTtcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0eS5raW5kICE9PSBcImluaXRcIikge1xuICAgICAgICAgICAgICAgIHRocm93RXJyb3JUb2xlcmFudCh7fSwgTWVzc2FnZXMuSW52YWxpZExIU0luRm9ybWFsc0xpc3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVpbnRlcnByZXRBc0Rlc3RydWN0dXJlZFBhcmFtZXRlcihvcHRpb25zLCBwcm9wZXJ0eS52YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGV4cHIudHlwZSA9PT0gYXN0Tm9kZVR5cGVzLkFycmF5RXhwcmVzc2lvbikge1xuICAgICAgICBleHByLnR5cGUgPSBhc3ROb2RlVHlwZXMuQXJyYXlQYXR0ZXJuO1xuICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSBleHByLmVsZW1lbnRzLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgICAgICAgICBlbGVtZW50ID0gZXhwci5lbGVtZW50c1tpXTtcbiAgICAgICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgcmVpbnRlcnByZXRBc0Rlc3RydWN0dXJlZFBhcmFtZXRlcihvcHRpb25zLCBlbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZXhwci50eXBlID09PSBhc3ROb2RlVHlwZXMuSWRlbnRpZmllcikge1xuICAgICAgICB2YWxpZGF0ZVBhcmFtKG9wdGlvbnMsIGV4cHIsIGV4cHIubmFtZSk7XG4gICAgfSBlbHNlIGlmIChleHByLnR5cGUgPT09IGFzdE5vZGVUeXBlcy5TcHJlYWRFbGVtZW50KSB7XG4gICAgICAgIC8vIEJpbmRpbmdSZXN0RWxlbWVudCBvbmx5IGFsbG93cyBCaW5kaW5nSWRlbnRpZmllclxuICAgICAgICBpZiAoZXhwci5hcmd1bWVudC50eXBlICE9PSBhc3ROb2RlVHlwZXMuSWRlbnRpZmllcikge1xuICAgICAgICAgICAgdGhyb3dFcnJvclRvbGVyYW50KHt9LCBNZXNzYWdlcy5JbnZhbGlkTEhTSW5Gb3JtYWxzTGlzdCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFsaWRhdGVQYXJhbShvcHRpb25zLCBleHByLmFyZ3VtZW50LCBleHByLmFyZ3VtZW50Lm5hbWUpO1xuICAgIH0gZWxzZSBpZiAoZXhwci50eXBlID09PSBhc3ROb2RlVHlwZXMuQXNzaWdubWVudEV4cHJlc3Npb24gJiYgZXhwci5vcGVyYXRvciA9PT0gXCI9XCIpIHtcbiAgICAgICAgZXhwci50eXBlID0gYXN0Tm9kZVR5cGVzLkFzc2lnbm1lbnRQYXR0ZXJuO1xuICAgIH0gZWxzZSBpZiAoZXhwci50eXBlICE9PSBhc3ROb2RlVHlwZXMuQXNzaWdubWVudFBhdHRlcm4pIHtcbiAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuSW52YWxpZExIU0luRm9ybWFsc0xpc3QpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbigpIHtcbiAgICB2YXIgdG9rZW4sIGxlZnQsIHJpZ2h0LCBub2RlLCBwYXJhbXMsXG4gICAgICAgIG1hcmtlcixcbiAgICAgICAgc3RhcnRzV2l0aFBhcmVuID0gZmFsc2UsXG4gICAgICAgIG9sZFBhcmVudGhlc2lzQ291bnQgPSBzdGF0ZS5wYXJlbnRoZXNpc0NvdW50LFxuICAgICAgICBhbGxvd0dlbmVyYXRvcnMgPSBleHRyYS5lY21hRmVhdHVyZXMuZ2VuZXJhdG9ycztcblxuICAgIC8vIE5vdGUgdGhhdCAneWllbGQnIGlzIHRyZWF0ZWQgYXMgYSBrZXl3b3JkIGluIHN0cmljdCBtb2RlLCBidXQgYVxuICAgIC8vIGNvbnRleHR1YWwga2V5d29yZCAoaWRlbnRpZmllcikgaW4gbm9uLXN0cmljdCBtb2RlLCBzbyB3ZSBuZWVkXG4gICAgLy8gdG8gdXNlIG1hdGNoS2V5d29yZCBhbmQgbWF0Y2hDb250ZXh0dWFsS2V5d29yZCBhcHByb3ByaWF0ZWx5LlxuICAgIGlmIChhbGxvd0dlbmVyYXRvcnMgJiYgKChzdGF0ZS55aWVsZEFsbG93ZWQgJiYgbWF0Y2hDb250ZXh0dWFsS2V5d29yZChcInlpZWxkXCIpKSB8fCAoc3RyaWN0ICYmIG1hdGNoS2V5d29yZChcInlpZWxkXCIpKSkpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlWWllbGRFeHByZXNzaW9uKCk7XG4gICAgfVxuXG4gICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG5cbiAgICBpZiAobWF0Y2goXCIoXCIpKSB7XG4gICAgICAgIHRva2VuID0gbG9va2FoZWFkMigpO1xuICAgICAgICBpZiAoKHRva2VuLnZhbHVlID09PSBcIilcIiAmJiB0b2tlbi50eXBlID09PSBUb2tlbi5QdW5jdHVhdG9yKSB8fCB0b2tlbi52YWx1ZSA9PT0gXCIuLi5cIikge1xuICAgICAgICAgICAgcGFyYW1zID0gcGFyc2VQYXJhbXMoKTtcbiAgICAgICAgICAgIGlmICghbWF0Y2goXCI9PlwiKSkge1xuICAgICAgICAgICAgICAgIHRocm93VW5leHBlY3RlZChsZXgoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VBcnJvd0Z1bmN0aW9uRXhwcmVzc2lvbihwYXJhbXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICAgICAgc3RhcnRzV2l0aFBhcmVuID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyByZXZlcnQgdG8gdGhlIHByZXZpb3VzIGxvb2thaGVhZCBzdHlsZSBvYmplY3RcbiAgICB0b2tlbiA9IGxvb2thaGVhZDtcbiAgICBub2RlID0gbGVmdCA9IHBhcnNlQ29uZGl0aW9uYWxFeHByZXNzaW9uKCk7XG5cbiAgICBpZiAobWF0Y2goXCI9PlwiKSAmJlxuICAgICAgICAgICAgKHN0YXRlLnBhcmVudGhlc2lzQ291bnQgPT09IG9sZFBhcmVudGhlc2lzQ291bnQgfHxcbiAgICAgICAgICAgIHN0YXRlLnBhcmVudGhlc2lzQ291bnQgPT09IChvbGRQYXJlbnRoZXNpc0NvdW50ICsgMSkpKSB7XG5cbiAgICAgICAgaWYgKG5vZGUudHlwZSA9PT0gYXN0Tm9kZVR5cGVzLklkZW50aWZpZXIpIHtcbiAgICAgICAgICAgIHBhcmFtcyA9IHJlaW50ZXJwcmV0QXNDb3ZlckZvcm1hbHNMaXN0KFsgbm9kZSBdKTtcbiAgICAgICAgfSBlbHNlIGlmIChub2RlLnR5cGUgPT09IGFzdE5vZGVUeXBlcy5Bc3NpZ25tZW50RXhwcmVzc2lvbiB8fFxuICAgICAgICAgICAgbm9kZS50eXBlID09PSBhc3ROb2RlVHlwZXMuQXJyYXlFeHByZXNzaW9uIHx8XG4gICAgICAgICAgICBub2RlLnR5cGUgPT09IGFzdE5vZGVUeXBlcy5PYmplY3RFeHByZXNzaW9uKSB7XG4gICAgICAgICAgICBpZiAoIXN0YXJ0c1dpdGhQYXJlbikge1xuICAgICAgICAgICAgICAgIHRocm93VW5leHBlY3RlZChsZXgoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwYXJhbXMgPSByZWludGVycHJldEFzQ292ZXJGb3JtYWxzTGlzdChbIG5vZGUgXSk7XG4gICAgICAgIH0gZWxzZSBpZiAobm9kZS50eXBlID09PSBhc3ROb2RlVHlwZXMuU2VxdWVuY2VFeHByZXNzaW9uKSB7XG4gICAgICAgICAgICBwYXJhbXMgPSByZWludGVycHJldEFzQ292ZXJGb3JtYWxzTGlzdChub2RlLmV4cHJlc3Npb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJhbXMpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUFycm93RnVuY3Rpb25FeHByZXNzaW9uKHBhcmFtcywgbWFya2VyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtYXRjaEFzc2lnbigpKSB7XG5cbiAgICAgICAgLy8gMTEuMTMuMVxuICAgICAgICBpZiAoc3RyaWN0ICYmIGxlZnQudHlwZSA9PT0gYXN0Tm9kZVR5cGVzLklkZW50aWZpZXIgJiYgc3ludGF4LmlzUmVzdHJpY3RlZFdvcmQobGVmdC5uYW1lKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvclRvbGVyYW50KHRva2VuLCBNZXNzYWdlcy5TdHJpY3RMSFNBc3NpZ25tZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEVTLm5leHQgZHJhZiAxMS4xMyBSdW50aW1lIFNlbWFudGljcyBzdGVwIDFcbiAgICAgICAgaWYgKG1hdGNoKFwiPVwiKSAmJiAobm9kZS50eXBlID09PSBhc3ROb2RlVHlwZXMuT2JqZWN0RXhwcmVzc2lvbiB8fCBub2RlLnR5cGUgPT09IGFzdE5vZGVUeXBlcy5BcnJheUV4cHJlc3Npb24pKSB7XG4gICAgICAgICAgICByZWludGVycHJldEFzQXNzaWdubWVudEJpbmRpbmdQYXR0ZXJuKG5vZGUpO1xuICAgICAgICB9IGVsc2UgaWYgKCFpc0xlZnRIYW5kU2lkZShub2RlKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvclRvbGVyYW50KHt9LCBNZXNzYWdlcy5JbnZhbGlkTEhTSW5Bc3NpZ25tZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRva2VuID0gbGV4KCk7XG4gICAgICAgIHJpZ2h0ID0gcGFyc2VBc3NpZ25tZW50RXhwcmVzc2lvbigpO1xuICAgICAgICBub2RlID0gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVBc3NpZ25tZW50RXhwcmVzc2lvbih0b2tlbi52YWx1ZSwgbGVmdCwgcmlnaHQpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbm9kZTtcbn1cblxuLy8gMTEuMTQgQ29tbWEgT3BlcmF0b3JcblxuZnVuY3Rpb24gcGFyc2VFeHByZXNzaW9uKCkge1xuICAgIHZhciBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKSxcbiAgICAgICAgZXhwciA9IHBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24oKSxcbiAgICAgICAgZXhwcmVzc2lvbnMgPSBbIGV4cHIgXSxcbiAgICAgICAgc2VxdWVuY2UsIHNwcmVhZEZvdW5kO1xuXG4gICAgaWYgKG1hdGNoKFwiLFwiKSkge1xuICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghbWF0Y2goXCIsXCIpKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIGV4cHIgPSBwYXJzZVNwcmVhZE9yQXNzaWdubWVudEV4cHJlc3Npb24oKTtcbiAgICAgICAgICAgIGV4cHJlc3Npb25zLnB1c2goZXhwcik7XG5cbiAgICAgICAgICAgIGlmIChleHByLnR5cGUgPT09IGFzdE5vZGVUeXBlcy5TcHJlYWRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgc3ByZWFkRm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGlmICghbWF0Y2goXCIpXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLkVsZW1lbnRBZnRlclNwcmVhZEVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHNlcXVlbmNlID0gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVTZXF1ZW5jZUV4cHJlc3Npb24oZXhwcmVzc2lvbnMpKTtcbiAgICB9XG5cbiAgICBpZiAoc3ByZWFkRm91bmQgJiYgbG9va2FoZWFkMigpLnZhbHVlICE9PSBcIj0+XCIpIHtcbiAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuSWxsZWdhbFNwcmVhZCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlcXVlbmNlIHx8IGV4cHI7XG59XG5cbi8vIDEyLjEgQmxvY2tcblxuZnVuY3Rpb24gcGFyc2VTdGF0ZW1lbnRMaXN0KCkge1xuICAgIHZhciBsaXN0ID0gW10sXG4gICAgICAgIHN0YXRlbWVudDtcblxuICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBpZiAobWF0Y2goXCJ9XCIpKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBzdGF0ZW1lbnQgPSBwYXJzZVNvdXJjZUVsZW1lbnQoKTtcbiAgICAgICAgaWYgKHR5cGVvZiBzdGF0ZW1lbnQgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGxpc3QucHVzaChzdGF0ZW1lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBsaXN0O1xufVxuXG5mdW5jdGlvbiBwYXJzZUJsb2NrKCkge1xuICAgIHZhciBibG9jayxcbiAgICAgICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG5cbiAgICBleHBlY3QoXCJ7XCIpO1xuXG4gICAgYmxvY2sgPSBwYXJzZVN0YXRlbWVudExpc3QoKTtcblxuICAgIGV4cGVjdChcIn1cIik7XG5cbiAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVCbG9ja1N0YXRlbWVudChibG9jaykpO1xufVxuXG4vLyAxMi4yIFZhcmlhYmxlIFN0YXRlbWVudFxuXG5mdW5jdGlvbiBwYXJzZVZhcmlhYmxlSWRlbnRpZmllcigpIHtcbiAgICB2YXIgdG9rZW4sXG4gICAgICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuXG4gICAgdG9rZW4gPSBsZXgoKTtcblxuICAgIGlmICh0b2tlbi50eXBlICE9PSBUb2tlbi5JZGVudGlmaWVyKSB7XG4gICAgICAgIGlmIChzdHJpY3QgJiYgdG9rZW4udHlwZSA9PT0gVG9rZW4uS2V5d29yZCAmJiBzeW50YXguaXNTdHJpY3RNb2RlUmVzZXJ2ZWRXb3JkKHRva2VuLnZhbHVlKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvclRvbGVyYW50KHRva2VuLCBNZXNzYWdlcy5TdHJpY3RSZXNlcnZlZFdvcmQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkKHRva2VuKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUlkZW50aWZpZXIodG9rZW4udmFsdWUpKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VWYXJpYWJsZURlY2xhcmF0aW9uKGtpbmQpIHtcbiAgICB2YXIgaWQsXG4gICAgICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpLFxuICAgICAgICBpbml0ID0gbnVsbDtcbiAgICBpZiAobWF0Y2goXCJ7XCIpKSB7XG4gICAgICAgIGlkID0gcGFyc2VPYmplY3RJbml0aWFsaXNlcigpO1xuICAgICAgICByZWludGVycHJldEFzQXNzaWdubWVudEJpbmRpbmdQYXR0ZXJuKGlkKTtcbiAgICB9IGVsc2UgaWYgKG1hdGNoKFwiW1wiKSkge1xuICAgICAgICBpZCA9IHBhcnNlQXJyYXlJbml0aWFsaXNlcigpO1xuICAgICAgICByZWludGVycHJldEFzQXNzaWdubWVudEJpbmRpbmdQYXR0ZXJuKGlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBpZCA9IHN0YXRlLmFsbG93S2V5d29yZCA/IHBhcnNlTm9uQ29tcHV0ZWRQcm9wZXJ0eSgpIDogcGFyc2VWYXJpYWJsZUlkZW50aWZpZXIoKTtcbiAgICAgICAgLy8gMTIuMi4xXG4gICAgICAgIGlmIChzdHJpY3QgJiYgc3ludGF4LmlzUmVzdHJpY3RlZFdvcmQoaWQubmFtZSkpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3JUb2xlcmFudCh7fSwgTWVzc2FnZXMuU3RyaWN0VmFyTmFtZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPOiBWZXJpZnkgYWdhaW5zdCBmZWF0dXJlIGZsYWdzXG4gICAgaWYgKGtpbmQgPT09IFwiY29uc3RcIikge1xuICAgICAgICBpZiAoIW1hdGNoKFwiPVwiKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuTm9VbmludGlhbGl6ZWRDb25zdCk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwZWN0KFwiPVwiKTtcbiAgICAgICAgaW5pdCA9IHBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24oKTtcbiAgICB9IGVsc2UgaWYgKG1hdGNoKFwiPVwiKSkge1xuICAgICAgICBsZXgoKTtcbiAgICAgICAgaW5pdCA9IHBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVWYXJpYWJsZURlY2xhcmF0b3IoaWQsIGluaXQpKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VWYXJpYWJsZURlY2xhcmF0aW9uTGlzdChraW5kKSB7XG4gICAgdmFyIGxpc3QgPSBbXTtcblxuICAgIGRvIHtcbiAgICAgICAgbGlzdC5wdXNoKHBhcnNlVmFyaWFibGVEZWNsYXJhdGlvbihraW5kKSk7XG4gICAgICAgIGlmICghbWF0Y2goXCIsXCIpKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBsZXgoKTtcbiAgICB9IHdoaWxlIChpbmRleCA8IGxlbmd0aCk7XG5cbiAgICByZXR1cm4gbGlzdDtcbn1cblxuZnVuY3Rpb24gcGFyc2VWYXJpYWJsZVN0YXRlbWVudCgpIHtcbiAgICB2YXIgZGVjbGFyYXRpb25zO1xuXG4gICAgZXhwZWN0S2V5d29yZChcInZhclwiKTtcblxuICAgIGRlY2xhcmF0aW9ucyA9IHBhcnNlVmFyaWFibGVEZWNsYXJhdGlvbkxpc3QoKTtcblxuICAgIGNvbnN1bWVTZW1pY29sb24oKTtcblxuICAgIHJldHVybiBhc3ROb2RlRmFjdG9yeS5jcmVhdGVWYXJpYWJsZURlY2xhcmF0aW9uKGRlY2xhcmF0aW9ucywgXCJ2YXJcIik7XG59XG5cbi8vIGtpbmQgbWF5IGJlIGBjb25zdGAgb3IgYGxldGBcbi8vIEJvdGggYXJlIGV4cGVyaW1lbnRhbCBhbmQgbm90IGluIHRoZSBzcGVjaWZpY2F0aW9uIHlldC5cbi8vIHNlZSBodHRwOi8vd2lraS5lY21hc2NyaXB0Lm9yZy9kb2t1LnBocD9pZD1oYXJtb255OmNvbnN0XG4vLyBhbmQgaHR0cDovL3dpa2kuZWNtYXNjcmlwdC5vcmcvZG9rdS5waHA/aWQ9aGFybW9ueTpsZXRcbmZ1bmN0aW9uIHBhcnNlQ29uc3RMZXREZWNsYXJhdGlvbihraW5kKSB7XG4gICAgdmFyIGRlY2xhcmF0aW9ucyxcbiAgICAgICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG5cbiAgICBleHBlY3RLZXl3b3JkKGtpbmQpO1xuXG4gICAgZGVjbGFyYXRpb25zID0gcGFyc2VWYXJpYWJsZURlY2xhcmF0aW9uTGlzdChraW5kKTtcblxuICAgIGNvbnN1bWVTZW1pY29sb24oKTtcblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVZhcmlhYmxlRGVjbGFyYXRpb24oZGVjbGFyYXRpb25zLCBraW5kKSk7XG59XG5cblxuZnVuY3Rpb24gcGFyc2VSZXN0RWxlbWVudCgpIHtcbiAgICB2YXIgcGFyYW0sXG4gICAgICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuXG4gICAgbGV4KCk7XG5cbiAgICBpZiAobWF0Y2goXCJ7XCIpKSB7XG4gICAgICAgIHRocm93RXJyb3IobG9va2FoZWFkLCBNZXNzYWdlcy5PYmplY3RQYXR0ZXJuQXNSZXN0UGFyYW1ldGVyKTtcbiAgICB9XG5cbiAgICBwYXJhbSA9IHBhcnNlVmFyaWFibGVJZGVudGlmaWVyKCk7XG5cbiAgICBpZiAobWF0Y2goXCI9XCIpKSB7XG4gICAgICAgIHRocm93RXJyb3IobG9va2FoZWFkLCBNZXNzYWdlcy5EZWZhdWx0UmVzdFBhcmFtZXRlcik7XG4gICAgfVxuXG4gICAgaWYgKCFtYXRjaChcIilcIikpIHtcbiAgICAgICAgdGhyb3dFcnJvcihsb29rYWhlYWQsIE1lc3NhZ2VzLlBhcmFtZXRlckFmdGVyUmVzdFBhcmFtZXRlcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlUmVzdEVsZW1lbnQocGFyYW0pKTtcbn1cblxuLy8gMTIuMyBFbXB0eSBTdGF0ZW1lbnRcblxuZnVuY3Rpb24gcGFyc2VFbXB0eVN0YXRlbWVudCgpIHtcbiAgICBleHBlY3QoXCI7XCIpO1xuICAgIHJldHVybiBhc3ROb2RlRmFjdG9yeS5jcmVhdGVFbXB0eVN0YXRlbWVudCgpO1xufVxuXG4vLyAxMi40IEV4cHJlc3Npb24gU3RhdGVtZW50XG5cbmZ1bmN0aW9uIHBhcnNlRXhwcmVzc2lvblN0YXRlbWVudCgpIHtcbiAgICB2YXIgZXhwciA9IHBhcnNlRXhwcmVzc2lvbigpO1xuICAgIGNvbnN1bWVTZW1pY29sb24oKTtcbiAgICByZXR1cm4gYXN0Tm9kZUZhY3RvcnkuY3JlYXRlRXhwcmVzc2lvblN0YXRlbWVudChleHByKTtcbn1cblxuLy8gMTIuNSBJZiBzdGF0ZW1lbnRcblxuZnVuY3Rpb24gcGFyc2VJZlN0YXRlbWVudCgpIHtcbiAgICB2YXIgdGVzdCwgY29uc2VxdWVudCwgYWx0ZXJuYXRlO1xuXG4gICAgZXhwZWN0S2V5d29yZChcImlmXCIpO1xuXG4gICAgZXhwZWN0KFwiKFwiKTtcblxuICAgIHRlc3QgPSBwYXJzZUV4cHJlc3Npb24oKTtcblxuICAgIGV4cGVjdChcIilcIik7XG5cbiAgICBjb25zZXF1ZW50ID0gcGFyc2VTdGF0ZW1lbnQoKTtcblxuICAgIGlmIChtYXRjaEtleXdvcmQoXCJlbHNlXCIpKSB7XG4gICAgICAgIGxleCgpO1xuICAgICAgICBhbHRlcm5hdGUgPSBwYXJzZVN0YXRlbWVudCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGFsdGVybmF0ZSA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUlmU3RhdGVtZW50KHRlc3QsIGNvbnNlcXVlbnQsIGFsdGVybmF0ZSk7XG59XG5cbi8vIDEyLjYgSXRlcmF0aW9uIFN0YXRlbWVudHNcblxuZnVuY3Rpb24gcGFyc2VEb1doaWxlU3RhdGVtZW50KCkge1xuICAgIHZhciBib2R5LCB0ZXN0LCBvbGRJbkl0ZXJhdGlvbjtcblxuICAgIGV4cGVjdEtleXdvcmQoXCJkb1wiKTtcblxuICAgIG9sZEluSXRlcmF0aW9uID0gc3RhdGUuaW5JdGVyYXRpb247XG4gICAgc3RhdGUuaW5JdGVyYXRpb24gPSB0cnVlO1xuXG4gICAgYm9keSA9IHBhcnNlU3RhdGVtZW50KCk7XG5cbiAgICBzdGF0ZS5pbkl0ZXJhdGlvbiA9IG9sZEluSXRlcmF0aW9uO1xuXG4gICAgZXhwZWN0S2V5d29yZChcIndoaWxlXCIpO1xuXG4gICAgZXhwZWN0KFwiKFwiKTtcblxuICAgIHRlc3QgPSBwYXJzZUV4cHJlc3Npb24oKTtcblxuICAgIGV4cGVjdChcIilcIik7XG5cbiAgICBpZiAobWF0Y2goXCI7XCIpKSB7XG4gICAgICAgIGxleCgpO1xuICAgIH1cblxuICAgIHJldHVybiBhc3ROb2RlRmFjdG9yeS5jcmVhdGVEb1doaWxlU3RhdGVtZW50KHRlc3QsIGJvZHkpO1xufVxuXG5mdW5jdGlvbiBwYXJzZVdoaWxlU3RhdGVtZW50KCkge1xuICAgIHZhciB0ZXN0LCBib2R5LCBvbGRJbkl0ZXJhdGlvbjtcblxuICAgIGV4cGVjdEtleXdvcmQoXCJ3aGlsZVwiKTtcblxuICAgIGV4cGVjdChcIihcIik7XG5cbiAgICB0ZXN0ID0gcGFyc2VFeHByZXNzaW9uKCk7XG5cbiAgICBleHBlY3QoXCIpXCIpO1xuXG4gICAgb2xkSW5JdGVyYXRpb24gPSBzdGF0ZS5pbkl0ZXJhdGlvbjtcbiAgICBzdGF0ZS5pbkl0ZXJhdGlvbiA9IHRydWU7XG5cbiAgICBib2R5ID0gcGFyc2VTdGF0ZW1lbnQoKTtcblxuICAgIHN0YXRlLmluSXRlcmF0aW9uID0gb2xkSW5JdGVyYXRpb247XG5cbiAgICByZXR1cm4gYXN0Tm9kZUZhY3RvcnkuY3JlYXRlV2hpbGVTdGF0ZW1lbnQodGVzdCwgYm9keSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlRm9yVmFyaWFibGVEZWNsYXJhdGlvbigpIHtcbiAgICB2YXIgdG9rZW4sIGRlY2xhcmF0aW9ucyxcbiAgICAgICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG5cbiAgICB0b2tlbiA9IGxleCgpO1xuICAgIGRlY2xhcmF0aW9ucyA9IHBhcnNlVmFyaWFibGVEZWNsYXJhdGlvbkxpc3QoKTtcblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVZhcmlhYmxlRGVjbGFyYXRpb24oZGVjbGFyYXRpb25zLCB0b2tlbi52YWx1ZSkpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUZvclN0YXRlbWVudChvcHRzKSB7XG4gICAgdmFyIGluaXQsIHRlc3QsIHVwZGF0ZSwgbGVmdCwgcmlnaHQsIGJvZHksIG9wZXJhdG9yLCBvbGRJbkl0ZXJhdGlvbjtcbiAgICB2YXIgYWxsb3dGb3JPZiA9IGV4dHJhLmVjbWFGZWF0dXJlcy5mb3JPZixcbiAgICAgICAgYWxsb3dCbG9ja0JpbmRpbmdzID0gZXh0cmEuZWNtYUZlYXR1cmVzLmJsb2NrQmluZGluZ3M7XG5cbiAgICBpbml0ID0gdGVzdCA9IHVwZGF0ZSA9IG51bGw7XG5cbiAgICBleHBlY3RLZXl3b3JkKFwiZm9yXCIpO1xuXG4gICAgZXhwZWN0KFwiKFwiKTtcblxuICAgIGlmIChtYXRjaChcIjtcIikpIHtcbiAgICAgICAgbGV4KCk7XG4gICAgfSBlbHNlIHtcblxuICAgICAgICBpZiAobWF0Y2hLZXl3b3JkKFwidmFyXCIpIHx8XG4gICAgICAgICAgICAoYWxsb3dCbG9ja0JpbmRpbmdzICYmIChtYXRjaEtleXdvcmQoXCJsZXRcIikgfHwgbWF0Y2hLZXl3b3JkKFwiY29uc3RcIikpKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIHN0YXRlLmFsbG93SW4gPSBmYWxzZTtcbiAgICAgICAgICAgIGluaXQgPSBwYXJzZUZvclZhcmlhYmxlRGVjbGFyYXRpb24oKTtcbiAgICAgICAgICAgIHN0YXRlLmFsbG93SW4gPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAoaW5pdC5kZWNsYXJhdGlvbnMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoS2V5d29yZChcImluXCIpIHx8IChhbGxvd0Zvck9mICYmIG1hdGNoQ29udGV4dHVhbEtleXdvcmQoXCJvZlwiKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgb3BlcmF0b3IgPSBsb29rYWhlYWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogaXMgXCJ2YXJcIiBjaGVjayBoZXJlIHJlYWxseSBuZWVkZWQ/IHdhc25cInQgaW4gMS4yLjJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEoKG9wZXJhdG9yLnZhbHVlID09PSBcImluXCIgfHwgaW5pdC5raW5kICE9PSBcInZhclwiKSAmJiBpbml0LmRlY2xhcmF0aW9uc1swXS5pbml0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0ID0gaW5pdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0ID0gcGFyc2VFeHByZXNzaW9uKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0ID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RhdGUuYWxsb3dJbiA9IGZhbHNlO1xuICAgICAgICAgICAgaW5pdCA9IHBhcnNlRXhwcmVzc2lvbigpO1xuICAgICAgICAgICAgc3RhdGUuYWxsb3dJbiA9IHRydWU7XG5cbiAgICAgICAgICAgIGlmIChhbGxvd0Zvck9mICYmIG1hdGNoQ29udGV4dHVhbEtleXdvcmQoXCJvZlwiKSkge1xuICAgICAgICAgICAgICAgIG9wZXJhdG9yID0gbGV4KCk7XG4gICAgICAgICAgICAgICAgbGVmdCA9IGluaXQ7XG4gICAgICAgICAgICAgICAgcmlnaHQgPSBwYXJzZUV4cHJlc3Npb24oKTtcbiAgICAgICAgICAgICAgICBpbml0ID0gbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobWF0Y2hLZXl3b3JkKFwiaW5cIikpIHtcbiAgICAgICAgICAgICAgICAvLyBMZWZ0SGFuZFNpZGVFeHByZXNzaW9uXG4gICAgICAgICAgICAgICAgaWYgKCFpc0xlZnRIYW5kU2lkZShpbml0KSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQoe30sIE1lc3NhZ2VzLkludmFsaWRMSFNJbkZvckluKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBvcGVyYXRvciA9IGxleCgpO1xuICAgICAgICAgICAgICAgIGxlZnQgPSBpbml0O1xuICAgICAgICAgICAgICAgIHJpZ2h0ID0gcGFyc2VFeHByZXNzaW9uKCk7XG4gICAgICAgICAgICAgICAgaW5pdCA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGxlZnQgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIGV4cGVjdChcIjtcIik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGxlZnQgPT09IFwidW5kZWZpbmVkXCIpIHtcblxuICAgICAgICBpZiAoIW1hdGNoKFwiO1wiKSkge1xuICAgICAgICAgICAgdGVzdCA9IHBhcnNlRXhwcmVzc2lvbigpO1xuICAgICAgICB9XG4gICAgICAgIGV4cGVjdChcIjtcIik7XG5cbiAgICAgICAgaWYgKCFtYXRjaChcIilcIikpIHtcbiAgICAgICAgICAgIHVwZGF0ZSA9IHBhcnNlRXhwcmVzc2lvbigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZXhwZWN0KFwiKVwiKTtcblxuICAgIG9sZEluSXRlcmF0aW9uID0gc3RhdGUuaW5JdGVyYXRpb247XG4gICAgc3RhdGUuaW5JdGVyYXRpb24gPSB0cnVlO1xuXG4gICAgaWYgKCEob3B0cyAhPT0gdW5kZWZpbmVkICYmIG9wdHMuaWdub3JlQm9keSkpIHtcbiAgICAgICAgYm9keSA9IHBhcnNlU3RhdGVtZW50KCk7XG4gICAgfVxuXG4gICAgc3RhdGUuaW5JdGVyYXRpb24gPSBvbGRJbkl0ZXJhdGlvbjtcblxuICAgIGlmICh0eXBlb2YgbGVmdCA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICByZXR1cm4gYXN0Tm9kZUZhY3RvcnkuY3JlYXRlRm9yU3RhdGVtZW50KGluaXQsIHRlc3QsIHVwZGF0ZSwgYm9keSk7XG4gICAgfVxuXG4gICAgaWYgKGV4dHJhLmVjbWFGZWF0dXJlcy5mb3JPZiAmJiBvcGVyYXRvci52YWx1ZSA9PT0gXCJvZlwiKSB7XG4gICAgICAgIHJldHVybiBhc3ROb2RlRmFjdG9yeS5jcmVhdGVGb3JPZlN0YXRlbWVudChsZWZ0LCByaWdodCwgYm9keSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUZvckluU3RhdGVtZW50KGxlZnQsIHJpZ2h0LCBib2R5KTtcbn1cblxuLy8gMTIuNyBUaGUgY29udGludWUgc3RhdGVtZW50XG5cbmZ1bmN0aW9uIHBhcnNlQ29udGludWVTdGF0ZW1lbnQoKSB7XG4gICAgdmFyIGxhYmVsID0gbnVsbDtcblxuICAgIGV4cGVjdEtleXdvcmQoXCJjb250aW51ZVwiKTtcblxuICAgIC8vIE9wdGltaXplIHRoZSBtb3N0IGNvbW1vbiBmb3JtOiBcImNvbnRpbnVlO1wiLlxuICAgIGlmIChzb3VyY2UuY2hhckNvZGVBdChpbmRleCkgPT09IDB4M0IpIHtcbiAgICAgICAgbGV4KCk7XG5cbiAgICAgICAgaWYgKCFzdGF0ZS5pbkl0ZXJhdGlvbikge1xuICAgICAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuSWxsZWdhbENvbnRpbnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhc3ROb2RlRmFjdG9yeS5jcmVhdGVDb250aW51ZVN0YXRlbWVudChudWxsKTtcbiAgICB9XG5cbiAgICBpZiAocGVla0xpbmVUZXJtaW5hdG9yKCkpIHtcbiAgICAgICAgaWYgKCFzdGF0ZS5pbkl0ZXJhdGlvbikge1xuICAgICAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuSWxsZWdhbENvbnRpbnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhc3ROb2RlRmFjdG9yeS5jcmVhdGVDb250aW51ZVN0YXRlbWVudChudWxsKTtcbiAgICB9XG5cbiAgICBpZiAobG9va2FoZWFkLnR5cGUgPT09IFRva2VuLklkZW50aWZpZXIpIHtcbiAgICAgICAgbGFiZWwgPSBwYXJzZVZhcmlhYmxlSWRlbnRpZmllcigpO1xuXG4gICAgICAgIGlmICghc3RhdGUubGFiZWxTZXQuaGFzKGxhYmVsLm5hbWUpKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlcy5Vbmtub3duTGFiZWwsIGxhYmVsLm5hbWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29uc3VtZVNlbWljb2xvbigpO1xuXG4gICAgaWYgKGxhYmVsID09PSBudWxsICYmICFzdGF0ZS5pbkl0ZXJhdGlvbikge1xuICAgICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlcy5JbGxlZ2FsQ29udGludWUpO1xuICAgIH1cblxuICAgIHJldHVybiBhc3ROb2RlRmFjdG9yeS5jcmVhdGVDb250aW51ZVN0YXRlbWVudChsYWJlbCk7XG59XG5cbi8vIDEyLjggVGhlIGJyZWFrIHN0YXRlbWVudFxuXG5mdW5jdGlvbiBwYXJzZUJyZWFrU3RhdGVtZW50KCkge1xuICAgIHZhciBsYWJlbCA9IG51bGw7XG5cbiAgICBleHBlY3RLZXl3b3JkKFwiYnJlYWtcIik7XG5cbiAgICAvLyBDYXRjaCB0aGUgdmVyeSBjb21tb24gY2FzZSBmaXJzdDogaW1tZWRpYXRlbHkgYSBzZW1pY29sb24gKFUrMDAzQikuXG4gICAgaWYgKHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSA9PT0gMHgzQikge1xuICAgICAgICBsZXgoKTtcblxuICAgICAgICBpZiAoIShzdGF0ZS5pbkl0ZXJhdGlvbiB8fCBzdGF0ZS5pblN3aXRjaCkpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLklsbGVnYWxCcmVhayk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXN0Tm9kZUZhY3RvcnkuY3JlYXRlQnJlYWtTdGF0ZW1lbnQobnVsbCk7XG4gICAgfVxuXG4gICAgaWYgKHBlZWtMaW5lVGVybWluYXRvcigpKSB7XG4gICAgICAgIGlmICghKHN0YXRlLmluSXRlcmF0aW9uIHx8IHN0YXRlLmluU3dpdGNoKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuSWxsZWdhbEJyZWFrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhc3ROb2RlRmFjdG9yeS5jcmVhdGVCcmVha1N0YXRlbWVudChudWxsKTtcbiAgICB9XG5cbiAgICBpZiAobG9va2FoZWFkLnR5cGUgPT09IFRva2VuLklkZW50aWZpZXIpIHtcbiAgICAgICAgbGFiZWwgPSBwYXJzZVZhcmlhYmxlSWRlbnRpZmllcigpO1xuXG4gICAgICAgIGlmICghc3RhdGUubGFiZWxTZXQuaGFzKGxhYmVsLm5hbWUpKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlcy5Vbmtub3duTGFiZWwsIGxhYmVsLm5hbWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29uc3VtZVNlbWljb2xvbigpO1xuXG4gICAgaWYgKGxhYmVsID09PSBudWxsICYmICEoc3RhdGUuaW5JdGVyYXRpb24gfHwgc3RhdGUuaW5Td2l0Y2gpKSB7XG4gICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLklsbGVnYWxCcmVhayk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUJyZWFrU3RhdGVtZW50KGxhYmVsKTtcbn1cblxuLy8gMTIuOSBUaGUgcmV0dXJuIHN0YXRlbWVudFxuXG5mdW5jdGlvbiBwYXJzZVJldHVyblN0YXRlbWVudCgpIHtcbiAgICB2YXIgYXJndW1lbnQgPSBudWxsO1xuXG4gICAgZXhwZWN0S2V5d29yZChcInJldHVyblwiKTtcblxuICAgIGlmICghc3RhdGUuaW5GdW5jdGlvbkJvZHkgJiYgIWV4dHJhLmVjbWFGZWF0dXJlcy5nbG9iYWxSZXR1cm4pIHtcbiAgICAgICAgdGhyb3dFcnJvclRvbGVyYW50KHt9LCBNZXNzYWdlcy5JbGxlZ2FsUmV0dXJuKTtcbiAgICB9XG5cbiAgICAvLyBcInJldHVyblwiIGZvbGxvd2VkIGJ5IGEgc3BhY2UgYW5kIGFuIGlkZW50aWZpZXIgaXMgdmVyeSBjb21tb24uXG4gICAgaWYgKHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KSA9PT0gMHgyMCkge1xuICAgICAgICBpZiAoc3ludGF4LmlzSWRlbnRpZmllclN0YXJ0KHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4ICsgMSkpKSB7XG4gICAgICAgICAgICBhcmd1bWVudCA9IHBhcnNlRXhwcmVzc2lvbigpO1xuICAgICAgICAgICAgY29uc3VtZVNlbWljb2xvbigpO1xuICAgICAgICAgICAgcmV0dXJuIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVJldHVyblN0YXRlbWVudChhcmd1bWVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocGVla0xpbmVUZXJtaW5hdG9yKCkpIHtcbiAgICAgICAgcmV0dXJuIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVJldHVyblN0YXRlbWVudChudWxsKTtcbiAgICB9XG5cbiAgICBpZiAoIW1hdGNoKFwiO1wiKSkge1xuICAgICAgICBpZiAoIW1hdGNoKFwifVwiKSAmJiBsb29rYWhlYWQudHlwZSAhPT0gVG9rZW4uRU9GKSB7XG4gICAgICAgICAgICBhcmd1bWVudCA9IHBhcnNlRXhwcmVzc2lvbigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29uc3VtZVNlbWljb2xvbigpO1xuXG4gICAgcmV0dXJuIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVJldHVyblN0YXRlbWVudChhcmd1bWVudCk7XG59XG5cbi8vIDEyLjEwIFRoZSB3aXRoIHN0YXRlbWVudFxuXG5mdW5jdGlvbiBwYXJzZVdpdGhTdGF0ZW1lbnQoKSB7XG4gICAgdmFyIG9iamVjdCwgYm9keTtcblxuICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgLy8gVE9ETyhpa2FyaWVuYXRvcik6IFNob3VsZCB3ZSB1cGRhdGUgdGhlIHRlc3QgY2FzZXMgaW5zdGVhZD9cbiAgICAgICAgc2tpcENvbW1lbnQoKTtcbiAgICAgICAgdGhyb3dFcnJvclRvbGVyYW50KHt9LCBNZXNzYWdlcy5TdHJpY3RNb2RlV2l0aCk7XG4gICAgfVxuXG4gICAgZXhwZWN0S2V5d29yZChcIndpdGhcIik7XG5cbiAgICBleHBlY3QoXCIoXCIpO1xuXG4gICAgb2JqZWN0ID0gcGFyc2VFeHByZXNzaW9uKCk7XG5cbiAgICBleHBlY3QoXCIpXCIpO1xuXG4gICAgYm9keSA9IHBhcnNlU3RhdGVtZW50KCk7XG5cbiAgICByZXR1cm4gYXN0Tm9kZUZhY3RvcnkuY3JlYXRlV2l0aFN0YXRlbWVudChvYmplY3QsIGJvZHkpO1xufVxuXG4vLyAxMi4xMCBUaGUgc3dpdGggc3RhdGVtZW50XG5cbmZ1bmN0aW9uIHBhcnNlU3dpdGNoQ2FzZSgpIHtcbiAgICB2YXIgdGVzdCwgY29uc2VxdWVudCA9IFtdLCBzdGF0ZW1lbnQsXG4gICAgICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuXG4gICAgaWYgKG1hdGNoS2V5d29yZChcImRlZmF1bHRcIikpIHtcbiAgICAgICAgbGV4KCk7XG4gICAgICAgIHRlc3QgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGV4cGVjdEtleXdvcmQoXCJjYXNlXCIpO1xuICAgICAgICB0ZXN0ID0gcGFyc2VFeHByZXNzaW9uKCk7XG4gICAgfVxuICAgIGV4cGVjdChcIjpcIik7XG5cbiAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgaWYgKG1hdGNoKFwifVwiKSB8fCBtYXRjaEtleXdvcmQoXCJkZWZhdWx0XCIpIHx8IG1hdGNoS2V5d29yZChcImNhc2VcIikpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRlbWVudCA9IHBhcnNlU291cmNlRWxlbWVudCgpO1xuICAgICAgICBpZiAodHlwZW9mIHN0YXRlbWVudCA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY29uc2VxdWVudC5wdXNoKHN0YXRlbWVudCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlU3dpdGNoQ2FzZSh0ZXN0LCBjb25zZXF1ZW50KSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlU3dpdGNoU3RhdGVtZW50KCkge1xuICAgIHZhciBkaXNjcmltaW5hbnQsIGNhc2VzLCBjbGF1c2UsIG9sZEluU3dpdGNoLCBkZWZhdWx0Rm91bmQ7XG5cbiAgICBleHBlY3RLZXl3b3JkKFwic3dpdGNoXCIpO1xuXG4gICAgZXhwZWN0KFwiKFwiKTtcblxuICAgIGRpc2NyaW1pbmFudCA9IHBhcnNlRXhwcmVzc2lvbigpO1xuXG4gICAgZXhwZWN0KFwiKVwiKTtcblxuICAgIGV4cGVjdChcIntcIik7XG5cbiAgICBjYXNlcyA9IFtdO1xuXG4gICAgaWYgKG1hdGNoKFwifVwiKSkge1xuICAgICAgICBsZXgoKTtcbiAgICAgICAgcmV0dXJuIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVN3aXRjaFN0YXRlbWVudChkaXNjcmltaW5hbnQsIGNhc2VzKTtcbiAgICB9XG5cbiAgICBvbGRJblN3aXRjaCA9IHN0YXRlLmluU3dpdGNoO1xuICAgIHN0YXRlLmluU3dpdGNoID0gdHJ1ZTtcbiAgICBkZWZhdWx0Rm91bmQgPSBmYWxzZTtcblxuICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBpZiAobWF0Y2goXCJ9XCIpKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjbGF1c2UgPSBwYXJzZVN3aXRjaENhc2UoKTtcbiAgICAgICAgaWYgKGNsYXVzZS50ZXN0ID09PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoZGVmYXVsdEZvdW5kKSB7XG4gICAgICAgICAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZXMuTXVsdGlwbGVEZWZhdWx0c0luU3dpdGNoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHRGb3VuZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZXMucHVzaChjbGF1c2UpO1xuICAgIH1cblxuICAgIHN0YXRlLmluU3dpdGNoID0gb2xkSW5Td2l0Y2g7XG5cbiAgICBleHBlY3QoXCJ9XCIpO1xuXG4gICAgcmV0dXJuIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVN3aXRjaFN0YXRlbWVudChkaXNjcmltaW5hbnQsIGNhc2VzKTtcbn1cblxuLy8gMTIuMTMgVGhlIHRocm93IHN0YXRlbWVudFxuXG5mdW5jdGlvbiBwYXJzZVRocm93U3RhdGVtZW50KCkge1xuICAgIHZhciBhcmd1bWVudDtcblxuICAgIGV4cGVjdEtleXdvcmQoXCJ0aHJvd1wiKTtcblxuICAgIGlmIChwZWVrTGluZVRlcm1pbmF0b3IoKSkge1xuICAgICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlcy5OZXdsaW5lQWZ0ZXJUaHJvdyk7XG4gICAgfVxuXG4gICAgYXJndW1lbnQgPSBwYXJzZUV4cHJlc3Npb24oKTtcblxuICAgIGNvbnN1bWVTZW1pY29sb24oKTtcblxuICAgIHJldHVybiBhc3ROb2RlRmFjdG9yeS5jcmVhdGVUaHJvd1N0YXRlbWVudChhcmd1bWVudCk7XG59XG5cbi8vIDEyLjE0IFRoZSB0cnkgc3RhdGVtZW50XG5cbmZ1bmN0aW9uIHBhcnNlQ2F0Y2hDbGF1c2UoKSB7XG4gICAgdmFyIHBhcmFtLCBib2R5LFxuICAgICAgICBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKSxcbiAgICAgICAgYWxsb3dEZXN0cnVjdHVyaW5nID0gZXh0cmEuZWNtYUZlYXR1cmVzLmRlc3RydWN0dXJpbmcsXG4gICAgICAgIG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBwYXJhbVNldDogbmV3IFN0cmluZ01hcCgpXG4gICAgICAgIH07XG5cbiAgICBleHBlY3RLZXl3b3JkKFwiY2F0Y2hcIik7XG5cbiAgICBleHBlY3QoXCIoXCIpO1xuICAgIGlmIChtYXRjaChcIilcIikpIHtcbiAgICAgICAgdGhyb3dVbmV4cGVjdGVkKGxvb2thaGVhZCk7XG4gICAgfVxuXG4gICAgaWYgKG1hdGNoKFwiW1wiKSkge1xuICAgICAgICBpZiAoIWFsbG93RGVzdHJ1Y3R1cmluZykge1xuICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkKGxvb2thaGVhZCk7XG4gICAgICAgIH1cbiAgICAgICAgcGFyYW0gPSBwYXJzZUFycmF5SW5pdGlhbGlzZXIoKTtcbiAgICAgICAgcmVpbnRlcnByZXRBc0Rlc3RydWN0dXJlZFBhcmFtZXRlcihvcHRpb25zLCBwYXJhbSk7XG4gICAgfSBlbHNlIGlmIChtYXRjaChcIntcIikpIHtcblxuICAgICAgICBpZiAoIWFsbG93RGVzdHJ1Y3R1cmluZykge1xuICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkKGxvb2thaGVhZCk7XG4gICAgICAgIH1cbiAgICAgICAgcGFyYW0gPSBwYXJzZU9iamVjdEluaXRpYWxpc2VyKCk7XG4gICAgICAgIHJlaW50ZXJwcmV0QXNEZXN0cnVjdHVyZWRQYXJhbWV0ZXIob3B0aW9ucywgcGFyYW0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHBhcmFtID0gcGFyc2VWYXJpYWJsZUlkZW50aWZpZXIoKTtcbiAgICB9XG5cbiAgICAvLyAxMi4xNC4xXG4gICAgaWYgKHN0cmljdCAmJiBwYXJhbS5uYW1lICYmIHN5bnRheC5pc1Jlc3RyaWN0ZWRXb3JkKHBhcmFtLm5hbWUpKSB7XG4gICAgICAgIHRocm93RXJyb3JUb2xlcmFudCh7fSwgTWVzc2FnZXMuU3RyaWN0Q2F0Y2hWYXJpYWJsZSk7XG4gICAgfVxuXG4gICAgZXhwZWN0KFwiKVwiKTtcbiAgICBib2R5ID0gcGFyc2VCbG9jaygpO1xuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUNhdGNoQ2xhdXNlKHBhcmFtLCBib2R5KSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlVHJ5U3RhdGVtZW50KCkge1xuICAgIHZhciBibG9jaywgaGFuZGxlciA9IG51bGwsIGZpbmFsaXplciA9IG51bGw7XG5cbiAgICBleHBlY3RLZXl3b3JkKFwidHJ5XCIpO1xuXG4gICAgYmxvY2sgPSBwYXJzZUJsb2NrKCk7XG5cbiAgICBpZiAobWF0Y2hLZXl3b3JkKFwiY2F0Y2hcIikpIHtcbiAgICAgICAgaGFuZGxlciA9IHBhcnNlQ2F0Y2hDbGF1c2UoKTtcbiAgICB9XG5cbiAgICBpZiAobWF0Y2hLZXl3b3JkKFwiZmluYWxseVwiKSkge1xuICAgICAgICBsZXgoKTtcbiAgICAgICAgZmluYWxpemVyID0gcGFyc2VCbG9jaygpO1xuICAgIH1cblxuICAgIGlmICghaGFuZGxlciAmJiAhZmluYWxpemVyKSB7XG4gICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLk5vQ2F0Y2hPckZpbmFsbHkpO1xuICAgIH1cblxuICAgIHJldHVybiBhc3ROb2RlRmFjdG9yeS5jcmVhdGVUcnlTdGF0ZW1lbnQoYmxvY2ssIGhhbmRsZXIsIGZpbmFsaXplcik7XG59XG5cbi8vIDEyLjE1IFRoZSBkZWJ1Z2dlciBzdGF0ZW1lbnRcblxuZnVuY3Rpb24gcGFyc2VEZWJ1Z2dlclN0YXRlbWVudCgpIHtcbiAgICBleHBlY3RLZXl3b3JkKFwiZGVidWdnZXJcIik7XG5cbiAgICBjb25zdW1lU2VtaWNvbG9uKCk7XG5cbiAgICByZXR1cm4gYXN0Tm9kZUZhY3RvcnkuY3JlYXRlRGVidWdnZXJTdGF0ZW1lbnQoKTtcbn1cblxuLy8gMTIgU3RhdGVtZW50c1xuXG5mdW5jdGlvbiBwYXJzZVN0YXRlbWVudCgpIHtcbiAgICB2YXIgdHlwZSA9IGxvb2thaGVhZC50eXBlLFxuICAgICAgICBleHByLFxuICAgICAgICBsYWJlbGVkQm9keSxcbiAgICAgICAgbWFya2VyO1xuXG4gICAgaWYgKHR5cGUgPT09IFRva2VuLkVPRikge1xuICAgICAgICB0aHJvd1VuZXhwZWN0ZWQobG9va2FoZWFkKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZSA9PT0gVG9rZW4uUHVuY3R1YXRvciAmJiBsb29rYWhlYWQudmFsdWUgPT09IFwie1wiKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUJsb2NrKCk7XG4gICAgfVxuXG4gICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG5cbiAgICBpZiAodHlwZSA9PT0gVG9rZW4uUHVuY3R1YXRvcikge1xuICAgICAgICBzd2l0Y2ggKGxvb2thaGVhZC52YWx1ZSkge1xuICAgICAgICAgICAgY2FzZSBcIjtcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBwYXJzZUVtcHR5U3RhdGVtZW50KCkpO1xuICAgICAgICAgICAgY2FzZSBcIntcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VCbG9jaygpO1xuICAgICAgICAgICAgY2FzZSBcIihcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBwYXJzZUV4cHJlc3Npb25TdGF0ZW1lbnQoKSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG5cbiAgICBpZiAodHlwZSA9PT0gVG9rZW4uS2V5d29yZCkge1xuICAgICAgICBzd2l0Y2ggKGxvb2thaGVhZC52YWx1ZSkge1xuICAgICAgICAgICAgY2FzZSBcImJyZWFrXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgcGFyc2VCcmVha1N0YXRlbWVudCgpKTtcbiAgICAgICAgICAgIGNhc2UgXCJjb250aW51ZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIHBhcnNlQ29udGludWVTdGF0ZW1lbnQoKSk7XG4gICAgICAgICAgICBjYXNlIFwiZGVidWdnZXJcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBwYXJzZURlYnVnZ2VyU3RhdGVtZW50KCkpO1xuICAgICAgICAgICAgY2FzZSBcImRvXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgcGFyc2VEb1doaWxlU3RhdGVtZW50KCkpO1xuICAgICAgICAgICAgY2FzZSBcImZvclwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIHBhcnNlRm9yU3RhdGVtZW50KCkpO1xuICAgICAgICAgICAgY2FzZSBcImZ1bmN0aW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgcGFyc2VGdW5jdGlvbkRlY2xhcmF0aW9uKCkpO1xuICAgICAgICAgICAgY2FzZSBcImlmXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgcGFyc2VJZlN0YXRlbWVudCgpKTtcbiAgICAgICAgICAgIGNhc2UgXCJyZXR1cm5cIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBwYXJzZVJldHVyblN0YXRlbWVudCgpKTtcbiAgICAgICAgICAgIGNhc2UgXCJzd2l0Y2hcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBwYXJzZVN3aXRjaFN0YXRlbWVudCgpKTtcbiAgICAgICAgICAgIGNhc2UgXCJ0aHJvd1wiOlxuICAgICAgICAgICAgICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIHBhcnNlVGhyb3dTdGF0ZW1lbnQoKSk7XG4gICAgICAgICAgICBjYXNlIFwidHJ5XCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgcGFyc2VUcnlTdGF0ZW1lbnQoKSk7XG4gICAgICAgICAgICBjYXNlIFwidmFyXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgcGFyc2VWYXJpYWJsZVN0YXRlbWVudCgpKTtcbiAgICAgICAgICAgIGNhc2UgXCJ3aGlsZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIHBhcnNlV2hpbGVTdGF0ZW1lbnQoKSk7XG4gICAgICAgICAgICBjYXNlIFwid2l0aFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIHBhcnNlV2l0aFN0YXRlbWVudCgpKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcbiAgICBleHByID0gcGFyc2VFeHByZXNzaW9uKCk7XG5cbiAgICAvLyAxMi4xMiBMYWJlbGxlZCBTdGF0ZW1lbnRzXG4gICAgaWYgKChleHByLnR5cGUgPT09IGFzdE5vZGVUeXBlcy5JZGVudGlmaWVyKSAmJiBtYXRjaChcIjpcIikpIHtcbiAgICAgICAgbGV4KCk7XG5cbiAgICAgICAgaWYgKHN0YXRlLmxhYmVsU2V0LmhhcyhleHByLm5hbWUpKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlcy5SZWRlY2xhcmF0aW9uLCBcIkxhYmVsXCIsIGV4cHIubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5sYWJlbFNldC5zZXQoZXhwci5uYW1lLCB0cnVlKTtcbiAgICAgICAgbGFiZWxlZEJvZHkgPSBwYXJzZVN0YXRlbWVudCgpO1xuICAgICAgICBzdGF0ZS5sYWJlbFNldC5kZWxldGUoZXhwci5uYW1lKTtcbiAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlTGFiZWxlZFN0YXRlbWVudChleHByLCBsYWJlbGVkQm9keSkpO1xuICAgIH1cblxuICAgIGNvbnN1bWVTZW1pY29sb24oKTtcblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUV4cHJlc3Npb25TdGF0ZW1lbnQoZXhwcikpO1xufVxuXG4vLyAxMyBGdW5jdGlvbiBEZWZpbml0aW9uXG5cbi8vIGZ1bmN0aW9uIHBhcnNlQ29uY2lzZUJvZHkoKSB7XG4vLyAgICAgaWYgKG1hdGNoKFwie1wiKSkge1xuLy8gICAgICAgICByZXR1cm4gcGFyc2VGdW5jdGlvblNvdXJjZUVsZW1lbnRzKCk7XG4vLyAgICAgfVxuLy8gICAgIHJldHVybiBwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKCk7XG4vLyB9XG5cbmZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25Tb3VyY2VFbGVtZW50cygpIHtcbiAgICB2YXIgc291cmNlRWxlbWVudCwgc291cmNlRWxlbWVudHMgPSBbXSwgdG9rZW4sIGRpcmVjdGl2ZSwgZmlyc3RSZXN0cmljdGVkLFxuICAgICAgICBvbGRMYWJlbFNldCwgb2xkSW5JdGVyYXRpb24sIG9sZEluU3dpdGNoLCBvbGRJbkZ1bmN0aW9uQm9keSwgb2xkUGFyZW50aGVzaXNDb3VudCxcbiAgICAgICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG5cbiAgICBleHBlY3QoXCJ7XCIpO1xuXG4gICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGlmIChsb29rYWhlYWQudHlwZSAhPT0gVG9rZW4uU3RyaW5nTGl0ZXJhbCkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgdG9rZW4gPSBsb29rYWhlYWQ7XG5cbiAgICAgICAgc291cmNlRWxlbWVudCA9IHBhcnNlU291cmNlRWxlbWVudCgpO1xuICAgICAgICBzb3VyY2VFbGVtZW50cy5wdXNoKHNvdXJjZUVsZW1lbnQpO1xuICAgICAgICBpZiAoc291cmNlRWxlbWVudC5leHByZXNzaW9uLnR5cGUgIT09IGFzdE5vZGVUeXBlcy5MaXRlcmFsKSB7XG4gICAgICAgICAgICAvLyB0aGlzIGlzIG5vdCBkaXJlY3RpdmVcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGRpcmVjdGl2ZSA9IHNvdXJjZS5zbGljZSh0b2tlbi5yYW5nZVswXSArIDEsIHRva2VuLnJhbmdlWzFdIC0gMSk7XG4gICAgICAgIGlmIChkaXJlY3RpdmUgPT09IFwidXNlIHN0cmljdFwiKSB7XG4gICAgICAgICAgICBzdHJpY3QgPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAoZmlyc3RSZXN0cmljdGVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3dFcnJvclRvbGVyYW50KGZpcnN0UmVzdHJpY3RlZCwgTWVzc2FnZXMuU3RyaWN0T2N0YWxMaXRlcmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghZmlyc3RSZXN0cmljdGVkICYmIHRva2VuLm9jdGFsKSB7XG4gICAgICAgICAgICAgICAgZmlyc3RSZXN0cmljdGVkID0gdG9rZW47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbGRMYWJlbFNldCA9IHN0YXRlLmxhYmVsU2V0O1xuICAgIG9sZEluSXRlcmF0aW9uID0gc3RhdGUuaW5JdGVyYXRpb247XG4gICAgb2xkSW5Td2l0Y2ggPSBzdGF0ZS5pblN3aXRjaDtcbiAgICBvbGRJbkZ1bmN0aW9uQm9keSA9IHN0YXRlLmluRnVuY3Rpb25Cb2R5O1xuICAgIG9sZFBhcmVudGhlc2lzQ291bnQgPSBzdGF0ZS5wYXJlbnRoZXNpemVkQ291bnQ7XG5cbiAgICBzdGF0ZS5sYWJlbFNldCA9IG5ldyBTdHJpbmdNYXAoKTtcbiAgICBzdGF0ZS5pbkl0ZXJhdGlvbiA9IGZhbHNlO1xuICAgIHN0YXRlLmluU3dpdGNoID0gZmFsc2U7XG4gICAgc3RhdGUuaW5GdW5jdGlvbkJvZHkgPSB0cnVlO1xuXG4gICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7XG5cbiAgICAgICAgaWYgKG1hdGNoKFwifVwiKSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBzb3VyY2VFbGVtZW50ID0gcGFyc2VTb3VyY2VFbGVtZW50KCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBzb3VyY2VFbGVtZW50ID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHNvdXJjZUVsZW1lbnRzLnB1c2goc291cmNlRWxlbWVudCk7XG4gICAgfVxuXG4gICAgZXhwZWN0KFwifVwiKTtcblxuICAgIHN0YXRlLmxhYmVsU2V0ID0gb2xkTGFiZWxTZXQ7XG4gICAgc3RhdGUuaW5JdGVyYXRpb24gPSBvbGRJbkl0ZXJhdGlvbjtcbiAgICBzdGF0ZS5pblN3aXRjaCA9IG9sZEluU3dpdGNoO1xuICAgIHN0YXRlLmluRnVuY3Rpb25Cb2R5ID0gb2xkSW5GdW5jdGlvbkJvZHk7XG4gICAgc3RhdGUucGFyZW50aGVzaXplZENvdW50ID0gb2xkUGFyZW50aGVzaXNDb3VudDtcblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUJsb2NrU3RhdGVtZW50KHNvdXJjZUVsZW1lbnRzKSk7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUGFyYW0ob3B0aW9ucywgcGFyYW0sIG5hbWUpIHtcblxuICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgaWYgKHN5bnRheC5pc1Jlc3RyaWN0ZWRXb3JkKG5hbWUpKSB7XG4gICAgICAgICAgICBvcHRpb25zLnN0cmljdGVkID0gcGFyYW07XG4gICAgICAgICAgICBvcHRpb25zLm1lc3NhZ2UgPSBNZXNzYWdlcy5TdHJpY3RQYXJhbU5hbWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucy5wYXJhbVNldC5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgIG9wdGlvbnMuc3RyaWN0ZWQgPSBwYXJhbTtcbiAgICAgICAgICAgIG9wdGlvbnMubWVzc2FnZSA9IE1lc3NhZ2VzLlN0cmljdFBhcmFtRHVwZTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIW9wdGlvbnMuZmlyc3RSZXN0cmljdGVkKSB7XG4gICAgICAgIGlmIChzeW50YXguaXNSZXN0cmljdGVkV29yZChuYW1lKSkge1xuICAgICAgICAgICAgb3B0aW9ucy5maXJzdFJlc3RyaWN0ZWQgPSBwYXJhbTtcbiAgICAgICAgICAgIG9wdGlvbnMubWVzc2FnZSA9IE1lc3NhZ2VzLlN0cmljdFBhcmFtTmFtZTtcbiAgICAgICAgfSBlbHNlIGlmIChzeW50YXguaXNTdHJpY3RNb2RlUmVzZXJ2ZWRXb3JkKG5hbWUpKSB7XG4gICAgICAgICAgICBvcHRpb25zLmZpcnN0UmVzdHJpY3RlZCA9IHBhcmFtO1xuICAgICAgICAgICAgb3B0aW9ucy5tZXNzYWdlID0gTWVzc2FnZXMuU3RyaWN0UmVzZXJ2ZWRXb3JkO1xuICAgICAgICB9IGVsc2UgaWYgKG9wdGlvbnMucGFyYW1TZXQuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICBvcHRpb25zLmZpcnN0UmVzdHJpY3RlZCA9IHBhcmFtO1xuICAgICAgICAgICAgb3B0aW9ucy5tZXNzYWdlID0gTWVzc2FnZXMuU3RyaWN0UGFyYW1EdXBlO1xuICAgICAgICB9XG4gICAgfVxuICAgIG9wdGlvbnMucGFyYW1TZXQuc2V0KG5hbWUsIHRydWUpO1xufVxuXG5mdW5jdGlvbiBwYXJzZVBhcmFtKG9wdGlvbnMpIHtcbiAgICB2YXIgdG9rZW4sIHBhcmFtLCBkZWYsXG4gICAgICAgIGFsbG93UmVzdFBhcmFtcyA9IGV4dHJhLmVjbWFGZWF0dXJlcy5yZXN0UGFyYW1zLFxuICAgICAgICBhbGxvd0Rlc3RydWN0dXJpbmcgPSBleHRyYS5lY21hRmVhdHVyZXMuZGVzdHJ1Y3R1cmluZyxcbiAgICAgICAgYWxsb3dEZWZhdWx0UGFyYW1zID0gZXh0cmEuZWNtYUZlYXR1cmVzLmRlZmF1bHRQYXJhbXMsXG4gICAgICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuXG4gICAgdG9rZW4gPSBsb29rYWhlYWQ7XG4gICAgaWYgKHRva2VuLnZhbHVlID09PSBcIi4uLlwiKSB7XG4gICAgICAgIGlmICghYWxsb3dSZXN0UGFyYW1zKSB7XG4gICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWQobG9va2FoZWFkKTtcbiAgICAgICAgfVxuICAgICAgICBwYXJhbSA9IHBhcnNlUmVzdEVsZW1lbnQoKTtcbiAgICAgICAgdmFsaWRhdGVQYXJhbShvcHRpb25zLCBwYXJhbS5hcmd1bWVudCwgcGFyYW0uYXJndW1lbnQubmFtZSk7XG4gICAgICAgIG9wdGlvbnMucGFyYW1zLnB1c2gocGFyYW0pO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKG1hdGNoKFwiW1wiKSkge1xuICAgICAgICBpZiAoIWFsbG93RGVzdHJ1Y3R1cmluZykge1xuICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkKGxvb2thaGVhZCk7XG4gICAgICAgIH1cbiAgICAgICAgcGFyYW0gPSBwYXJzZUFycmF5SW5pdGlhbGlzZXIoKTtcbiAgICAgICAgcmVpbnRlcnByZXRBc0Rlc3RydWN0dXJlZFBhcmFtZXRlcihvcHRpb25zLCBwYXJhbSk7XG4gICAgfSBlbHNlIGlmIChtYXRjaChcIntcIikpIHtcbiAgICAgICAgaWYgKCFhbGxvd0Rlc3RydWN0dXJpbmcpIHtcbiAgICAgICAgICAgIHRocm93VW5leHBlY3RlZChsb29rYWhlYWQpO1xuICAgICAgICB9XG4gICAgICAgIHBhcmFtID0gcGFyc2VPYmplY3RJbml0aWFsaXNlcigpO1xuICAgICAgICByZWludGVycHJldEFzRGVzdHJ1Y3R1cmVkUGFyYW1ldGVyKG9wdGlvbnMsIHBhcmFtKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBwYXJhbSA9IHBhcnNlVmFyaWFibGVJZGVudGlmaWVyKCk7XG4gICAgICAgIHZhbGlkYXRlUGFyYW0ob3B0aW9ucywgdG9rZW4sIHRva2VuLnZhbHVlKTtcbiAgICB9XG5cbiAgICBpZiAobWF0Y2goXCI9XCIpKSB7XG4gICAgICAgIGlmIChhbGxvd0RlZmF1bHRQYXJhbXMgfHwgYWxsb3dEZXN0cnVjdHVyaW5nKSB7XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIGRlZiA9IHBhcnNlQXNzaWdubWVudEV4cHJlc3Npb24oKTtcbiAgICAgICAgICAgICsrb3B0aW9ucy5kZWZhdWx0Q291bnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWQobG9va2FoZWFkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChkZWYpIHtcbiAgICAgICAgb3B0aW9ucy5wYXJhbXMucHVzaChtYXJrZXJBcHBseShcbiAgICAgICAgICAgIG1hcmtlcixcbiAgICAgICAgICAgIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUFzc2lnbm1lbnRQYXR0ZXJuKFxuICAgICAgICAgICAgICAgIHBhcmFtLFxuICAgICAgICAgICAgICAgIGRlZlxuICAgICAgICAgICAgKVxuICAgICAgICApKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBvcHRpb25zLnBhcmFtcy5wdXNoKHBhcmFtKTtcbiAgICB9XG5cbiAgICByZXR1cm4gIW1hdGNoKFwiKVwiKTtcbn1cblxuXG5mdW5jdGlvbiBwYXJzZVBhcmFtcyhmaXJzdFJlc3RyaWN0ZWQpIHtcbiAgICB2YXIgb3B0aW9ucztcblxuICAgIG9wdGlvbnMgPSB7XG4gICAgICAgIHBhcmFtczogW10sXG4gICAgICAgIGRlZmF1bHRDb3VudDogMCxcbiAgICAgICAgZmlyc3RSZXN0cmljdGVkOiBmaXJzdFJlc3RyaWN0ZWRcbiAgICB9O1xuXG4gICAgZXhwZWN0KFwiKFwiKTtcblxuICAgIGlmICghbWF0Y2goXCIpXCIpKSB7XG4gICAgICAgIG9wdGlvbnMucGFyYW1TZXQgPSBuZXcgU3RyaW5nTWFwKCk7XG4gICAgICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKCFwYXJzZVBhcmFtKG9wdGlvbnMpKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBleHBlY3QoXCIsXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZXhwZWN0KFwiKVwiKTtcblxuICAgIHJldHVybiB7XG4gICAgICAgIHBhcmFtczogb3B0aW9ucy5wYXJhbXMsXG4gICAgICAgIHN0cmljdGVkOiBvcHRpb25zLnN0cmljdGVkLFxuICAgICAgICBmaXJzdFJlc3RyaWN0ZWQ6IG9wdGlvbnMuZmlyc3RSZXN0cmljdGVkLFxuICAgICAgICBtZXNzYWdlOiBvcHRpb25zLm1lc3NhZ2VcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBwYXJzZUZ1bmN0aW9uRGVjbGFyYXRpb24oaWRlbnRpZmllcklzT3B0aW9uYWwpIHtcbiAgICAgICAgdmFyIGlkID0gbnVsbCwgYm9keSwgdG9rZW4sIHRtcCwgZmlyc3RSZXN0cmljdGVkLCBtZXNzYWdlLCBwcmV2aW91c1N0cmljdCwgcHJldmlvdXNZaWVsZEFsbG93ZWQsIGdlbmVyYXRvcixcbiAgICAgICAgICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpLFxuICAgICAgICAgICAgYWxsb3dHZW5lcmF0b3JzID0gZXh0cmEuZWNtYUZlYXR1cmVzLmdlbmVyYXRvcnM7XG5cbiAgICAgICAgZXhwZWN0S2V5d29yZChcImZ1bmN0aW9uXCIpO1xuXG4gICAgICAgIGdlbmVyYXRvciA9IGZhbHNlO1xuICAgICAgICBpZiAoYWxsb3dHZW5lcmF0b3JzICYmIG1hdGNoKFwiKlwiKSkge1xuICAgICAgICAgICAgbGV4KCk7XG4gICAgICAgICAgICBnZW5lcmF0b3IgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpZGVudGlmaWVySXNPcHRpb25hbCB8fCAhbWF0Y2goXCIoXCIpKSB7XG5cbiAgICAgICAgICAgIHRva2VuID0gbG9va2FoZWFkO1xuXG4gICAgICAgICAgICBpZCA9IHBhcnNlVmFyaWFibGVJZGVudGlmaWVyKCk7XG5cbiAgICAgICAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgICAgICBpZiAoc3ludGF4LmlzUmVzdHJpY3RlZFdvcmQodG9rZW4udmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93RXJyb3JUb2xlcmFudCh0b2tlbiwgTWVzc2FnZXMuU3RyaWN0RnVuY3Rpb25OYW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChzeW50YXguaXNSZXN0cmljdGVkV29yZCh0b2tlbi52YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZmlyc3RSZXN0cmljdGVkID0gdG9rZW47XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBNZXNzYWdlcy5TdHJpY3RGdW5jdGlvbk5hbWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzeW50YXguaXNTdHJpY3RNb2RlUmVzZXJ2ZWRXb3JkKHRva2VuLnZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICBmaXJzdFJlc3RyaWN0ZWQgPSB0b2tlbjtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IE1lc3NhZ2VzLlN0cmljdFJlc2VydmVkV29yZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0bXAgPSBwYXJzZVBhcmFtcyhmaXJzdFJlc3RyaWN0ZWQpO1xuICAgICAgICBmaXJzdFJlc3RyaWN0ZWQgPSB0bXAuZmlyc3RSZXN0cmljdGVkO1xuICAgICAgICBpZiAodG1wLm1lc3NhZ2UpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSB0bXAubWVzc2FnZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHByZXZpb3VzU3RyaWN0ID0gc3RyaWN0O1xuICAgICAgICBwcmV2aW91c1lpZWxkQWxsb3dlZCA9IHN0YXRlLnlpZWxkQWxsb3dlZDtcbiAgICAgICAgc3RhdGUueWllbGRBbGxvd2VkID0gZ2VuZXJhdG9yO1xuXG4gICAgICAgIGJvZHkgPSBwYXJzZUZ1bmN0aW9uU291cmNlRWxlbWVudHMoKTtcblxuICAgICAgICBpZiAoc3RyaWN0ICYmIGZpcnN0UmVzdHJpY3RlZCkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihmaXJzdFJlc3RyaWN0ZWQsIG1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdHJpY3QgJiYgdG1wLnN0cmljdGVkKSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQodG1wLnN0cmljdGVkLCBtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgICBzdHJpY3QgPSBwcmV2aW91c1N0cmljdDtcbiAgICAgICAgc3RhdGUueWllbGRBbGxvd2VkID0gcHJldmlvdXNZaWVsZEFsbG93ZWQ7XG5cbiAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KFxuICAgICAgICAgICAgbWFya2VyLFxuICAgICAgICAgICAgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlRnVuY3Rpb25EZWNsYXJhdGlvbihcbiAgICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgICB0bXAucGFyYW1zLFxuICAgICAgICAgICAgICAgIGJvZHksXG4gICAgICAgICAgICAgICAgZ2VuZXJhdG9yLFxuICAgICAgICAgICAgICAgIGZhbHNlXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG5mdW5jdGlvbiBwYXJzZUZ1bmN0aW9uRXhwcmVzc2lvbigpIHtcbiAgICB2YXIgdG9rZW4sIGlkID0gbnVsbCwgZmlyc3RSZXN0cmljdGVkLCBtZXNzYWdlLCB0bXAsIGJvZHksIHByZXZpb3VzU3RyaWN0LCBwcmV2aW91c1lpZWxkQWxsb3dlZCwgZ2VuZXJhdG9yLFxuICAgICAgICBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKSxcbiAgICAgICAgYWxsb3dHZW5lcmF0b3JzID0gZXh0cmEuZWNtYUZlYXR1cmVzLmdlbmVyYXRvcnM7XG5cbiAgICBleHBlY3RLZXl3b3JkKFwiZnVuY3Rpb25cIik7XG5cbiAgICBnZW5lcmF0b3IgPSBmYWxzZTtcblxuICAgIGlmIChhbGxvd0dlbmVyYXRvcnMgJiYgbWF0Y2goXCIqXCIpKSB7XG4gICAgICAgIGxleCgpO1xuICAgICAgICBnZW5lcmF0b3IgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICghbWF0Y2goXCIoXCIpKSB7XG4gICAgICAgIHRva2VuID0gbG9va2FoZWFkO1xuICAgICAgICBpZCA9IHBhcnNlVmFyaWFibGVJZGVudGlmaWVyKCk7XG4gICAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgIGlmIChzeW50YXguaXNSZXN0cmljdGVkV29yZCh0b2tlbi52YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQodG9rZW4sIE1lc3NhZ2VzLlN0cmljdEZ1bmN0aW9uTmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoc3ludGF4LmlzUmVzdHJpY3RlZFdvcmQodG9rZW4udmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgZmlyc3RSZXN0cmljdGVkID0gdG9rZW47XG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IE1lc3NhZ2VzLlN0cmljdEZ1bmN0aW9uTmFtZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc3ludGF4LmlzU3RyaWN0TW9kZVJlc2VydmVkV29yZCh0b2tlbi52YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBmaXJzdFJlc3RyaWN0ZWQgPSB0b2tlbjtcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gTWVzc2FnZXMuU3RyaWN0UmVzZXJ2ZWRXb3JkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdG1wID0gcGFyc2VQYXJhbXMoZmlyc3RSZXN0cmljdGVkKTtcbiAgICBmaXJzdFJlc3RyaWN0ZWQgPSB0bXAuZmlyc3RSZXN0cmljdGVkO1xuICAgIGlmICh0bXAubWVzc2FnZSkge1xuICAgICAgICBtZXNzYWdlID0gdG1wLm1lc3NhZ2U7XG4gICAgfVxuXG4gICAgcHJldmlvdXNTdHJpY3QgPSBzdHJpY3Q7XG4gICAgcHJldmlvdXNZaWVsZEFsbG93ZWQgPSBzdGF0ZS55aWVsZEFsbG93ZWQ7XG4gICAgc3RhdGUueWllbGRBbGxvd2VkID0gZ2VuZXJhdG9yO1xuXG4gICAgYm9keSA9IHBhcnNlRnVuY3Rpb25Tb3VyY2VFbGVtZW50cygpO1xuXG4gICAgaWYgKHN0cmljdCAmJiBmaXJzdFJlc3RyaWN0ZWQpIHtcbiAgICAgICAgdGhyb3dFcnJvcihmaXJzdFJlc3RyaWN0ZWQsIG1lc3NhZ2UpO1xuICAgIH1cbiAgICBpZiAoc3RyaWN0ICYmIHRtcC5zdHJpY3RlZCkge1xuICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQodG1wLnN0cmljdGVkLCBtZXNzYWdlKTtcbiAgICB9XG4gICAgc3RyaWN0ID0gcHJldmlvdXNTdHJpY3Q7XG4gICAgc3RhdGUueWllbGRBbGxvd2VkID0gcHJldmlvdXNZaWVsZEFsbG93ZWQ7XG5cbiAgICByZXR1cm4gbWFya2VyQXBwbHkoXG4gICAgICAgIG1hcmtlcixcbiAgICAgICAgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlRnVuY3Rpb25FeHByZXNzaW9uKFxuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICB0bXAucGFyYW1zLFxuICAgICAgICAgICAgYm9keSxcbiAgICAgICAgICAgIGdlbmVyYXRvcixcbiAgICAgICAgICAgIGZhbHNlXG4gICAgICAgIClcbiAgICApO1xufVxuXG5mdW5jdGlvbiBwYXJzZVlpZWxkRXhwcmVzc2lvbigpIHtcbiAgICB2YXIgeWllbGRUb2tlbiwgZGVsZWdhdGVGbGFnLCBleHByLCBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcblxuICAgIHlpZWxkVG9rZW4gPSBsZXgoKTtcbiAgICBhc3NlcnQoeWllbGRUb2tlbi52YWx1ZSA9PT0gXCJ5aWVsZFwiLCBcIkNhbGxlZCBwYXJzZVlpZWxkRXhwcmVzc2lvbiB3aXRoIG5vbi15aWVsZCBsb29rYWhlYWQuXCIpO1xuXG4gICAgaWYgKCFzdGF0ZS55aWVsZEFsbG93ZWQpIHtcbiAgICAgICAgdGhyb3dFcnJvclRvbGVyYW50KHt9LCBNZXNzYWdlcy5JbGxlZ2FsWWllbGQpO1xuICAgIH1cblxuICAgIGRlbGVnYXRlRmxhZyA9IGZhbHNlO1xuICAgIGlmIChtYXRjaChcIipcIikpIHtcbiAgICAgICAgbGV4KCk7XG4gICAgICAgIGRlbGVnYXRlRmxhZyA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHBlZWtMaW5lVGVybWluYXRvcigpKSB7XG4gICAgICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZVlpZWxkRXhwcmVzc2lvbihudWxsLCBkZWxlZ2F0ZUZsYWcpKTtcbiAgICB9XG5cbiAgICBpZiAoIW1hdGNoKFwiO1wiKSAmJiAhbWF0Y2goXCIpXCIpKSB7XG4gICAgICAgIGlmICghbWF0Y2goXCJ9XCIpICYmIGxvb2thaGVhZC50eXBlICE9PSBUb2tlbi5FT0YpIHtcbiAgICAgICAgICAgIGV4cHIgPSBwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVZaWVsZEV4cHJlc3Npb24oZXhwciwgZGVsZWdhdGVGbGFnKSk7XG59XG5cbi8vIE1vZHVsZXMgZ3JhbW1hciBmcm9tOlxuLy8gcGVvcGxlLm1vemlsbGEub3JnL35qb3JlbmRvcmZmL2VzNi1kcmFmdC5odG1sXG5cbmZ1bmN0aW9uIHBhcnNlTW9kdWxlU3BlY2lmaWVyKCkge1xuICAgIHZhciBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKSxcbiAgICAgICAgc3BlY2lmaWVyO1xuXG4gICAgaWYgKGxvb2thaGVhZC50eXBlICE9PSBUb2tlbi5TdHJpbmdMaXRlcmFsKSB7XG4gICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLkludmFsaWRNb2R1bGVTcGVjaWZpZXIpO1xuICAgIH1cbiAgICBzcGVjaWZpZXIgPSBhc3ROb2RlRmFjdG9yeS5jcmVhdGVMaXRlcmFsRnJvbVNvdXJjZShsZXgoKSwgc291cmNlKTtcbiAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBzcGVjaWZpZXIpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUV4cG9ydFNwZWNpZmllcigpIHtcbiAgICB2YXIgZXhwb3J0ZWQsIGxvY2FsLCBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcbiAgICBpZiAobWF0Y2hLZXl3b3JkKFwiZGVmYXVsdFwiKSkge1xuICAgICAgICBsZXgoKTtcbiAgICAgICAgbG9jYWwgPSBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUlkZW50aWZpZXIoXCJkZWZhdWx0XCIpKTtcbiAgICAgICAgLy8gZXhwb3J0IHtkZWZhdWx0fSBmcm9tIFwic29tZXRoaW5nXCI7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgbG9jYWwgPSBwYXJzZVZhcmlhYmxlSWRlbnRpZmllcigpO1xuICAgIH1cbiAgICBpZiAobWF0Y2hDb250ZXh0dWFsS2V5d29yZChcImFzXCIpKSB7XG4gICAgICAgIGxleCgpO1xuICAgICAgICBleHBvcnRlZCA9IHBhcnNlTm9uQ29tcHV0ZWRQcm9wZXJ0eSgpO1xuICAgIH1cbiAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVFeHBvcnRTcGVjaWZpZXIobG9jYWwsIGV4cG9ydGVkKSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlRXhwb3J0TmFtZWREZWNsYXJhdGlvbigpIHtcbiAgICB2YXIgZGVjbGFyYXRpb24gPSBudWxsLFxuICAgICAgICBpc0V4cG9ydEZyb21JZGVudGlmaWVyLFxuICAgICAgICBzcmMgPSBudWxsLCBzcGVjaWZpZXJzID0gW10sXG4gICAgICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuXG4gICAgZXhwZWN0S2V5d29yZChcImV4cG9ydFwiKTtcblxuICAgIC8vIG5vbi1kZWZhdWx0IGV4cG9ydFxuICAgIGlmIChsb29rYWhlYWQudHlwZSA9PT0gVG9rZW4uS2V5d29yZCkge1xuICAgICAgICAvLyBjb3ZlcnM6XG4gICAgICAgIC8vIGV4cG9ydCB2YXIgZiA9IDE7XG4gICAgICAgIHN3aXRjaCAobG9va2FoZWFkLnZhbHVlKSB7XG4gICAgICAgICAgICBjYXNlIFwibGV0XCI6XG4gICAgICAgICAgICBjYXNlIFwiY29uc3RcIjpcbiAgICAgICAgICAgIGNhc2UgXCJ2YXJcIjpcbiAgICAgICAgICAgIGNhc2UgXCJjbGFzc1wiOlxuICAgICAgICAgICAgY2FzZSBcImZ1bmN0aW9uXCI6XG4gICAgICAgICAgICAgICAgZGVjbGFyYXRpb24gPSBwYXJzZVNvdXJjZUVsZW1lbnQoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVFeHBvcnROYW1lZERlY2xhcmF0aW9uKGRlY2xhcmF0aW9uLCBzcGVjaWZpZXJzLCBudWxsKSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZXhwZWN0KFwie1wiKTtcbiAgICBpZiAoIW1hdGNoKFwifVwiKSkge1xuICAgICAgICBkbyB7XG4gICAgICAgICAgICBpc0V4cG9ydEZyb21JZGVudGlmaWVyID0gaXNFeHBvcnRGcm9tSWRlbnRpZmllciB8fCBtYXRjaEtleXdvcmQoXCJkZWZhdWx0XCIpO1xuICAgICAgICAgICAgc3BlY2lmaWVycy5wdXNoKHBhcnNlRXhwb3J0U3BlY2lmaWVyKCkpO1xuICAgICAgICB9IHdoaWxlIChtYXRjaChcIixcIikgJiYgbGV4KCkpO1xuICAgIH1cbiAgICBleHBlY3QoXCJ9XCIpO1xuXG4gICAgaWYgKG1hdGNoQ29udGV4dHVhbEtleXdvcmQoXCJmcm9tXCIpKSB7XG4gICAgICAgIC8vIGNvdmVyaW5nOlxuICAgICAgICAvLyBleHBvcnQge2RlZmF1bHR9IGZyb20gXCJmb29cIjtcbiAgICAgICAgLy8gZXhwb3J0IHtmb299IGZyb20gXCJmb29cIjtcbiAgICAgICAgbGV4KCk7XG4gICAgICAgIHNyYyA9IHBhcnNlTW9kdWxlU3BlY2lmaWVyKCk7XG4gICAgICAgIGNvbnN1bWVTZW1pY29sb24oKTtcbiAgICB9IGVsc2UgaWYgKGlzRXhwb3J0RnJvbUlkZW50aWZpZXIpIHtcbiAgICAgICAgLy8gY292ZXJpbmc6XG4gICAgICAgIC8vIGV4cG9ydCB7ZGVmYXVsdH07IC8vIG1pc3NpbmcgZnJvbUNsYXVzZVxuICAgICAgICB0aHJvd0Vycm9yKHt9LCBsb29rYWhlYWQudmFsdWUgP1xuICAgICAgICAgICAgICAgIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiA6IE1lc3NhZ2VzLk1pc3NpbmdGcm9tQ2xhdXNlLCBsb29rYWhlYWQudmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGNvdmVyXG4gICAgICAgIC8vIGV4cG9ydCB7Zm9vfTtcbiAgICAgICAgY29uc3VtZVNlbWljb2xvbigpO1xuICAgIH1cbiAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVFeHBvcnROYW1lZERlY2xhcmF0aW9uKGRlY2xhcmF0aW9uLCBzcGVjaWZpZXJzLCBzcmMpKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VFeHBvcnREZWZhdWx0RGVjbGFyYXRpb24oKSB7XG4gICAgdmFyIGRlY2xhcmF0aW9uID0gbnVsbCxcbiAgICAgICAgZXhwcmVzc2lvbiA9IG51bGwsXG4gICAgICAgIHBvc3NpYmxlSWRlbnRpZmllclRva2VuLFxuICAgICAgICBhbGxvd0NsYXNzZXMgPSBleHRyYS5lY21hRmVhdHVyZXMuY2xhc3NlcyxcbiAgICAgICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG5cbiAgICAvLyBjb3ZlcnM6XG4gICAgLy8gZXhwb3J0IGRlZmF1bHQgLi4uXG4gICAgZXhwZWN0S2V5d29yZChcImV4cG9ydFwiKTtcbiAgICBleHBlY3RLZXl3b3JkKFwiZGVmYXVsdFwiKTtcblxuICAgIGlmIChtYXRjaEtleXdvcmQoXCJmdW5jdGlvblwiKSB8fCBtYXRjaEtleXdvcmQoXCJjbGFzc1wiKSkge1xuICAgICAgICBwb3NzaWJsZUlkZW50aWZpZXJUb2tlbiA9IGxvb2thaGVhZDIoKTtcbiAgICAgICAgaWYgKHBvc3NpYmxlSWRlbnRpZmllclRva2VuLnR5cGUgPT09IFRva2VuLklkZW50aWZpZXIpIHtcbiAgICAgICAgICAgIC8vIGNvdmVyczpcbiAgICAgICAgICAgIC8vIGV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGZvbyAoKSB7fVxuICAgICAgICAgICAgLy8gZXhwb3J0IGRlZmF1bHQgY2xhc3MgZm9vIHt9XG4gICAgICAgICAgICBkZWNsYXJhdGlvbiA9IHBhcnNlU291cmNlRWxlbWVudCgpO1xuICAgICAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uKGRlY2xhcmF0aW9uKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY292ZXJzOlxuICAgICAgICAvLyBleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoKSB7fVxuICAgICAgICAvLyBleHBvcnQgZGVmYXVsdCBjbGFzcyB7fVxuICAgICAgICBpZiAobG9va2FoZWFkLnZhbHVlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGRlY2xhcmF0aW9uID0gcGFyc2VGdW5jdGlvbkRlY2xhcmF0aW9uKHRydWUpO1xuICAgICAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uKGRlY2xhcmF0aW9uKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoYWxsb3dDbGFzc2VzICYmIGxvb2thaGVhZC52YWx1ZSA9PT0gXCJjbGFzc1wiKSB7XG4gICAgICAgICAgICBkZWNsYXJhdGlvbiA9IHBhcnNlQ2xhc3NEZWNsYXJhdGlvbih0cnVlKTtcbiAgICAgICAgICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUV4cG9ydERlZmF1bHREZWNsYXJhdGlvbihkZWNsYXJhdGlvbikpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1hdGNoQ29udGV4dHVhbEtleXdvcmQoXCJmcm9tXCIpKSB7XG4gICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLlVuZXhwZWN0ZWRUb2tlbiwgbG9va2FoZWFkLnZhbHVlKTtcbiAgICB9XG5cbiAgICAvLyBjb3ZlcnM6XG4gICAgLy8gZXhwb3J0IGRlZmF1bHQge307XG4gICAgLy8gZXhwb3J0IGRlZmF1bHQgW107XG4gICAgLy8gZXhwb3J0IGRlZmF1bHQgKDEgKyAyKTtcbiAgICBpZiAobWF0Y2goXCJ7XCIpKSB7XG4gICAgICAgIGV4cHJlc3Npb24gPSBwYXJzZU9iamVjdEluaXRpYWxpc2VyKCk7XG4gICAgfSBlbHNlIGlmIChtYXRjaChcIltcIikpIHtcbiAgICAgICAgZXhwcmVzc2lvbiA9IHBhcnNlQXJyYXlJbml0aWFsaXNlcigpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGV4cHJlc3Npb24gPSBwYXJzZUFzc2lnbm1lbnRFeHByZXNzaW9uKCk7XG4gICAgfVxuICAgIGNvbnN1bWVTZW1pY29sb24oKTtcbiAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVFeHBvcnREZWZhdWx0RGVjbGFyYXRpb24oZXhwcmVzc2lvbikpO1xufVxuXG5cbmZ1bmN0aW9uIHBhcnNlRXhwb3J0QWxsRGVjbGFyYXRpb24oKSB7XG4gICAgdmFyIHNyYyxcbiAgICAgICAgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG5cbiAgICAvLyBjb3ZlcnM6XG4gICAgLy8gZXhwb3J0ICogZnJvbSBcImZvb1wiO1xuICAgIGV4cGVjdEtleXdvcmQoXCJleHBvcnRcIik7XG4gICAgZXhwZWN0KFwiKlwiKTtcbiAgICBpZiAoIW1hdGNoQ29udGV4dHVhbEtleXdvcmQoXCJmcm9tXCIpKSB7XG4gICAgICAgIHRocm93RXJyb3Ioe30sIGxvb2thaGVhZC52YWx1ZSA/XG4gICAgICAgICAgICAgICAgTWVzc2FnZXMuVW5leHBlY3RlZFRva2VuIDogTWVzc2FnZXMuTWlzc2luZ0Zyb21DbGF1c2UsIGxvb2thaGVhZC52YWx1ZSk7XG4gICAgfVxuICAgIGxleCgpO1xuICAgIHNyYyA9IHBhcnNlTW9kdWxlU3BlY2lmaWVyKCk7XG4gICAgY29uc3VtZVNlbWljb2xvbigpO1xuXG4gICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlRXhwb3J0QWxsRGVjbGFyYXRpb24oc3JjKSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlRXhwb3J0RGVjbGFyYXRpb24oKSB7XG4gICAgaWYgKHN0YXRlLmluRnVuY3Rpb25Cb2R5KSB7XG4gICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLklsbGVnYWxFeHBvcnREZWNsYXJhdGlvbik7XG4gICAgfVxuICAgIHZhciBkZWNsYXJhdGlvblR5cGUgPSBsb29rYWhlYWQyKCkudmFsdWU7XG4gICAgaWYgKGRlY2xhcmF0aW9uVHlwZSA9PT0gXCJkZWZhdWx0XCIpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uKCk7XG4gICAgfSBlbHNlIGlmIChkZWNsYXJhdGlvblR5cGUgPT09IFwiKlwiKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUV4cG9ydEFsbERlY2xhcmF0aW9uKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlRXhwb3J0TmFtZWREZWNsYXJhdGlvbigpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcGFyc2VJbXBvcnRTcGVjaWZpZXIoKSB7XG4gICAgLy8gaW1wb3J0IHs8Zm9vIGFzIGJhcj59IC4uLjtcbiAgICB2YXIgbG9jYWwsIGltcG9ydGVkLCBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcblxuICAgIGltcG9ydGVkID0gcGFyc2VOb25Db21wdXRlZFByb3BlcnR5KCk7XG4gICAgaWYgKG1hdGNoQ29udGV4dHVhbEtleXdvcmQoXCJhc1wiKSkge1xuICAgICAgICBsZXgoKTtcbiAgICAgICAgbG9jYWwgPSBwYXJzZVZhcmlhYmxlSWRlbnRpZmllcigpO1xuICAgIH1cblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUltcG9ydFNwZWNpZmllcihsb2NhbCwgaW1wb3J0ZWQpKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VOYW1lZEltcG9ydHMoKSB7XG4gICAgdmFyIHNwZWNpZmllcnMgPSBbXTtcbiAgICAvLyB7Zm9vLCBiYXIgYXMgYmFzfVxuICAgIGV4cGVjdChcIntcIik7XG4gICAgaWYgKCFtYXRjaChcIn1cIikpIHtcbiAgICAgICAgZG8ge1xuICAgICAgICAgICAgc3BlY2lmaWVycy5wdXNoKHBhcnNlSW1wb3J0U3BlY2lmaWVyKCkpO1xuICAgICAgICB9IHdoaWxlIChtYXRjaChcIixcIikgJiYgbGV4KCkpO1xuICAgIH1cbiAgICBleHBlY3QoXCJ9XCIpO1xuICAgIHJldHVybiBzcGVjaWZpZXJzO1xufVxuXG5mdW5jdGlvbiBwYXJzZUltcG9ydERlZmF1bHRTcGVjaWZpZXIoKSB7XG4gICAgLy8gaW1wb3J0IDxmb28+IC4uLjtcbiAgICB2YXIgbG9jYWwsIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuXG4gICAgbG9jYWwgPSBwYXJzZU5vbkNvbXB1dGVkUHJvcGVydHkoKTtcblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUltcG9ydERlZmF1bHRTcGVjaWZpZXIobG9jYWwpKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VJbXBvcnROYW1lc3BhY2VTcGVjaWZpZXIoKSB7XG4gICAgLy8gaW1wb3J0IDwqIGFzIGZvbz4gLi4uO1xuICAgIHZhciBsb2NhbCwgbWFya2VyID0gbWFya2VyQ3JlYXRlKCk7XG5cbiAgICBleHBlY3QoXCIqXCIpO1xuICAgIGlmICghbWF0Y2hDb250ZXh0dWFsS2V5d29yZChcImFzXCIpKSB7XG4gICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VzLk5vQXNBZnRlckltcG9ydE5hbWVzcGFjZSk7XG4gICAgfVxuICAgIGxleCgpO1xuICAgIGxvY2FsID0gcGFyc2VOb25Db21wdXRlZFByb3BlcnR5KCk7XG5cbiAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVJbXBvcnROYW1lc3BhY2VTcGVjaWZpZXIobG9jYWwpKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VJbXBvcnREZWNsYXJhdGlvbigpIHtcbiAgICB2YXIgc3BlY2lmaWVycywgc3JjLCBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKTtcblxuICAgIGlmIChzdGF0ZS5pbkZ1bmN0aW9uQm9keSkge1xuICAgICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlcy5JbGxlZ2FsSW1wb3J0RGVjbGFyYXRpb24pO1xuICAgIH1cblxuICAgIGV4cGVjdEtleXdvcmQoXCJpbXBvcnRcIik7XG4gICAgc3BlY2lmaWVycyA9IFtdO1xuXG4gICAgaWYgKGxvb2thaGVhZC50eXBlID09PSBUb2tlbi5TdHJpbmdMaXRlcmFsKSB7XG4gICAgICAgIC8vIGNvdmVyczpcbiAgICAgICAgLy8gaW1wb3J0IFwiZm9vXCI7XG4gICAgICAgIHNyYyA9IHBhcnNlTW9kdWxlU3BlY2lmaWVyKCk7XG4gICAgICAgIGNvbnN1bWVTZW1pY29sb24oKTtcbiAgICAgICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlSW1wb3J0RGVjbGFyYXRpb24oc3BlY2lmaWVycywgc3JjKSk7XG4gICAgfVxuXG4gICAgaWYgKCFtYXRjaEtleXdvcmQoXCJkZWZhdWx0XCIpICYmIGlzSWRlbnRpZmllck5hbWUobG9va2FoZWFkKSkge1xuICAgICAgICAvLyBjb3ZlcnM6XG4gICAgICAgIC8vIGltcG9ydCBmb29cbiAgICAgICAgLy8gaW1wb3J0IGZvbywgLi4uXG4gICAgICAgIHNwZWNpZmllcnMucHVzaChwYXJzZUltcG9ydERlZmF1bHRTcGVjaWZpZXIoKSk7XG4gICAgICAgIGlmIChtYXRjaChcIixcIikpIHtcbiAgICAgICAgICAgIGxleCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChtYXRjaChcIipcIikpIHtcbiAgICAgICAgLy8gY292ZXJzOlxuICAgICAgICAvLyBpbXBvcnQgZm9vLCAqIGFzIGZvb1xuICAgICAgICAvLyBpbXBvcnQgKiBhcyBmb29cbiAgICAgICAgc3BlY2lmaWVycy5wdXNoKHBhcnNlSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyKCkpO1xuICAgIH0gZWxzZSBpZiAobWF0Y2goXCJ7XCIpKSB7XG4gICAgICAgIC8vIGNvdmVyczpcbiAgICAgICAgLy8gaW1wb3J0IGZvbywge2Jhcn1cbiAgICAgICAgLy8gaW1wb3J0IHtiYXJ9XG4gICAgICAgIHNwZWNpZmllcnMgPSBzcGVjaWZpZXJzLmNvbmNhdChwYXJzZU5hbWVkSW1wb3J0cygpKTtcbiAgICB9XG5cbiAgICBpZiAoIW1hdGNoQ29udGV4dHVhbEtleXdvcmQoXCJmcm9tXCIpKSB7XG4gICAgICAgIHRocm93RXJyb3Ioe30sIGxvb2thaGVhZC52YWx1ZSA/XG4gICAgICAgICAgICAgICAgTWVzc2FnZXMuVW5leHBlY3RlZFRva2VuIDogTWVzc2FnZXMuTWlzc2luZ0Zyb21DbGF1c2UsIGxvb2thaGVhZC52YWx1ZSk7XG4gICAgfVxuICAgIGxleCgpO1xuICAgIHNyYyA9IHBhcnNlTW9kdWxlU3BlY2lmaWVyKCk7XG4gICAgY29uc3VtZVNlbWljb2xvbigpO1xuXG4gICAgcmV0dXJuIG1hcmtlckFwcGx5KG1hcmtlciwgYXN0Tm9kZUZhY3RvcnkuY3JlYXRlSW1wb3J0RGVjbGFyYXRpb24oc3BlY2lmaWVycywgc3JjKSk7XG59XG5cbi8vIDE0IEZ1bmN0aW9ucyBhbmQgY2xhc3Nlc1xuXG4vLyAxNC4xIEZ1bmN0aW9ucyBpcyBkZWZpbmVkIGFib3ZlICgxMyBpbiBFUzUpXG4vLyAxNC4yIEFycm93IEZ1bmN0aW9ucyBEZWZpbml0aW9ucyBpcyBkZWZpbmVkIGluICg3LjMgYXNzaWdubWVudHMpXG5cbi8vIDE0LjMgTWV0aG9kIERlZmluaXRpb25zXG4vLyAxNC4zLjdcblxuLy8gMTQuNSBDbGFzcyBEZWZpbml0aW9uc1xuXG5mdW5jdGlvbiBwYXJzZUNsYXNzQm9keSgpIHtcbiAgICB2YXIgaGFzQ29uc3RydWN0b3IgPSBmYWxzZSwgZ2VuZXJhdG9yID0gZmFsc2UsXG4gICAgICAgIGFsbG93R2VuZXJhdG9ycyA9IGV4dHJhLmVjbWFGZWF0dXJlcy5nZW5lcmF0b3JzLFxuICAgICAgICB0b2tlbiwgaXNTdGF0aWMsIGJvZHkgPSBbXSwgbWV0aG9kLCBjb21wdXRlZCwga2V5O1xuXG4gICAgdmFyIGV4aXN0aW5nUHJvcHMgPSB7fSxcbiAgICAgICAgdG9wTWFya2VyID0gbWFya2VyQ3JlYXRlKCksXG4gICAgICAgIG1hcmtlcjtcblxuICAgIGV4aXN0aW5nUHJvcHMuc3RhdGljID0gbmV3IFN0cmluZ01hcCgpO1xuICAgIGV4aXN0aW5nUHJvcHMucHJvdG90eXBlID0gbmV3IFN0cmluZ01hcCgpO1xuXG4gICAgZXhwZWN0KFwie1wiKTtcblxuICAgIHdoaWxlICghbWF0Y2goXCJ9XCIpKSB7XG5cbiAgICAgICAgLy8gZXh0cmEgc2VtaWNvbG9ucyBhcmUgZmluZVxuICAgICAgICBpZiAobWF0Y2goXCI7XCIpKSB7XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdG9rZW4gPSBsb29rYWhlYWQ7XG4gICAgICAgIGlzU3RhdGljID0gZmFsc2U7XG4gICAgICAgIGdlbmVyYXRvciA9IG1hdGNoKFwiKlwiKTtcbiAgICAgICAgY29tcHV0ZWQgPSBtYXRjaChcIltcIik7XG4gICAgICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuXG4gICAgICAgIGlmIChnZW5lcmF0b3IpIHtcbiAgICAgICAgICAgIGlmICghYWxsb3dHZW5lcmF0b3JzKSB7XG4gICAgICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkKGxvb2thaGVhZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGtleSA9IHBhcnNlT2JqZWN0UHJvcGVydHlLZXkoKTtcblxuICAgICAgICAvLyBzdGF0aWMgZ2VuZXJhdG9yIG1ldGhvZHNcbiAgICAgICAgaWYgKGtleS5uYW1lID09PSBcInN0YXRpY1wiICYmIG1hdGNoKFwiKlwiKSkge1xuICAgICAgICAgICAgaWYgKCFhbGxvd0dlbmVyYXRvcnMpIHtcbiAgICAgICAgICAgICAgICB0aHJvd1VuZXhwZWN0ZWQobG9va2FoZWFkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGdlbmVyYXRvciA9IHRydWU7XG4gICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChrZXkubmFtZSA9PT0gXCJzdGF0aWNcIiAmJiBsb29rYWhlYWRQcm9wZXJ0eU5hbWUoKSkge1xuICAgICAgICAgICAgdG9rZW4gPSBsb29rYWhlYWQ7XG4gICAgICAgICAgICBpc1N0YXRpYyA9IHRydWU7XG4gICAgICAgICAgICBjb21wdXRlZCA9IG1hdGNoKFwiW1wiKTtcbiAgICAgICAgICAgIGtleSA9IHBhcnNlT2JqZWN0UHJvcGVydHlLZXkoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChnZW5lcmF0b3IpIHtcbiAgICAgICAgICAgIG1ldGhvZCA9IHBhcnNlR2VuZXJhdG9yUHJvcGVydHkoa2V5LCBtYXJrZXIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbWV0aG9kID0gdHJ5UGFyc2VNZXRob2REZWZpbml0aW9uKHRva2VuLCBrZXksIGNvbXB1dGVkLCBtYXJrZXIsIGdlbmVyYXRvcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWV0aG9kKSB7XG4gICAgICAgICAgICBtZXRob2Quc3RhdGljID0gaXNTdGF0aWM7XG4gICAgICAgICAgICBpZiAobWV0aG9kLmtpbmQgPT09IFwiaW5pdFwiKSB7XG4gICAgICAgICAgICAgICAgbWV0aG9kLmtpbmQgPSBcIm1ldGhvZFwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWlzU3RhdGljKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAoIW1ldGhvZC5jb21wdXRlZCAmJiAobWV0aG9kLmtleS5uYW1lIHx8IChtZXRob2Qua2V5LnZhbHVlICYmIG1ldGhvZC5rZXkudmFsdWUudG9TdHJpbmcoKSkpID09PSBcImNvbnN0cnVjdG9yXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1ldGhvZC5raW5kICE9PSBcIm1ldGhvZFwiIHx8ICFtZXRob2QubWV0aG9kIHx8IG1ldGhvZC52YWx1ZS5nZW5lcmF0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93VW5leHBlY3RlZCh0b2tlbiwgTWVzc2FnZXMuQ29uc3RydWN0b3JTcGVjaWFsTWV0aG9kKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoaGFzQ29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93VW5leHBlY3RlZCh0b2tlbiwgTWVzc2FnZXMuRHVwbGljYXRlQ29uc3RydWN0b3IpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaGFzQ29uc3RydWN0b3IgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZC5raW5kID0gXCJjb25zdHJ1Y3RvclwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKCFtZXRob2QuY29tcHV0ZWQgJiYgKG1ldGhvZC5rZXkubmFtZSB8fCBtZXRob2Qua2V5LnZhbHVlLnRvU3RyaW5nKCkpID09PSBcInByb3RvdHlwZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93VW5leHBlY3RlZCh0b2tlbiwgTWVzc2FnZXMuU3RhdGljUHJvdG90eXBlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtZXRob2QudHlwZSA9IGFzdE5vZGVUeXBlcy5NZXRob2REZWZpbml0aW9uO1xuICAgICAgICAgICAgZGVsZXRlIG1ldGhvZC5tZXRob2Q7XG4gICAgICAgICAgICBkZWxldGUgbWV0aG9kLnNob3J0aGFuZDtcbiAgICAgICAgICAgIGJvZHkucHVzaChtZXRob2QpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3dVbmV4cGVjdGVkKGxvb2thaGVhZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBsZXgoKTtcbiAgICByZXR1cm4gbWFya2VyQXBwbHkodG9wTWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVDbGFzc0JvZHkoYm9keSkpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUNsYXNzRXhwcmVzc2lvbigpIHtcbiAgICB2YXIgaWQgPSBudWxsLCBzdXBlckNsYXNzID0gbnVsbCwgbWFya2VyID0gbWFya2VyQ3JlYXRlKCksXG4gICAgICAgIHByZXZpb3VzU3RyaWN0ID0gc3RyaWN0LCBjbGFzc0JvZHk7XG5cbiAgICAvLyBjbGFzc2VzIHJ1biBpbiBzdHJpY3QgbW9kZVxuICAgIHN0cmljdCA9IHRydWU7XG5cbiAgICBleHBlY3RLZXl3b3JkKFwiY2xhc3NcIik7XG5cbiAgICBpZiAobG9va2FoZWFkLnR5cGUgPT09IFRva2VuLklkZW50aWZpZXIpIHtcbiAgICAgICAgaWQgPSBwYXJzZVZhcmlhYmxlSWRlbnRpZmllcigpO1xuICAgIH1cblxuICAgIGlmIChtYXRjaEtleXdvcmQoXCJleHRlbmRzXCIpKSB7XG4gICAgICAgIGxleCgpO1xuICAgICAgICBzdXBlckNsYXNzID0gcGFyc2VMZWZ0SGFuZFNpZGVFeHByZXNzaW9uQWxsb3dDYWxsKCk7XG4gICAgfVxuXG4gICAgY2xhc3NCb2R5ID0gcGFyc2VDbGFzc0JvZHkoKTtcbiAgICBzdHJpY3QgPSBwcmV2aW91c1N0cmljdDtcblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUNsYXNzRXhwcmVzc2lvbihpZCwgc3VwZXJDbGFzcywgY2xhc3NCb2R5KSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlQ2xhc3NEZWNsYXJhdGlvbihpZGVudGlmaWVySXNPcHRpb25hbCkge1xuICAgIHZhciBpZCA9IG51bGwsIHN1cGVyQ2xhc3MgPSBudWxsLCBtYXJrZXIgPSBtYXJrZXJDcmVhdGUoKSxcbiAgICAgICAgcHJldmlvdXNTdHJpY3QgPSBzdHJpY3QsIGNsYXNzQm9keTtcblxuICAgIC8vIGNsYXNzZXMgcnVuIGluIHN0cmljdCBtb2RlXG4gICAgc3RyaWN0ID0gdHJ1ZTtcblxuICAgIGV4cGVjdEtleXdvcmQoXCJjbGFzc1wiKTtcblxuICAgIGlmICghaWRlbnRpZmllcklzT3B0aW9uYWwgfHwgbG9va2FoZWFkLnR5cGUgPT09IFRva2VuLklkZW50aWZpZXIpIHtcbiAgICAgICAgaWQgPSBwYXJzZVZhcmlhYmxlSWRlbnRpZmllcigpO1xuICAgIH1cblxuICAgIGlmIChtYXRjaEtleXdvcmQoXCJleHRlbmRzXCIpKSB7XG4gICAgICAgIGxleCgpO1xuICAgICAgICBzdXBlckNsYXNzID0gcGFyc2VMZWZ0SGFuZFNpZGVFeHByZXNzaW9uQWxsb3dDYWxsKCk7XG4gICAgfVxuXG4gICAgY2xhc3NCb2R5ID0gcGFyc2VDbGFzc0JvZHkoKTtcbiAgICBzdHJpY3QgPSBwcmV2aW91c1N0cmljdDtcblxuICAgIHJldHVybiBtYXJrZXJBcHBseShtYXJrZXIsIGFzdE5vZGVGYWN0b3J5LmNyZWF0ZUNsYXNzRGVjbGFyYXRpb24oaWQsIHN1cGVyQ2xhc3MsIGNsYXNzQm9keSkpO1xufVxuXG4vLyAxNSBQcm9ncmFtXG5cbmZ1bmN0aW9uIHBhcnNlU291cmNlRWxlbWVudCgpIHtcblxuICAgIHZhciBhbGxvd0NsYXNzZXMgPSBleHRyYS5lY21hRmVhdHVyZXMuY2xhc3NlcyxcbiAgICAgICAgYWxsb3dNb2R1bGVzID0gZXh0cmEuZWNtYUZlYXR1cmVzLm1vZHVsZXMsXG4gICAgICAgIGFsbG93QmxvY2tCaW5kaW5ncyA9IGV4dHJhLmVjbWFGZWF0dXJlcy5ibG9ja0JpbmRpbmdzO1xuXG4gICAgaWYgKGxvb2thaGVhZC50eXBlID09PSBUb2tlbi5LZXl3b3JkKSB7XG4gICAgICAgIHN3aXRjaCAobG9va2FoZWFkLnZhbHVlKSB7XG4gICAgICAgICAgICBjYXNlIFwiZXhwb3J0XCI6XG4gICAgICAgICAgICAgICAgaWYgKCFhbGxvd01vZHVsZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3dFcnJvclRvbGVyYW50KHt9LCBNZXNzYWdlcy5JbGxlZ2FsRXhwb3J0RGVjbGFyYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VFeHBvcnREZWNsYXJhdGlvbigpO1xuICAgICAgICAgICAgY2FzZSBcImltcG9ydFwiOlxuICAgICAgICAgICAgICAgIGlmICghYWxsb3dNb2R1bGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93RXJyb3JUb2xlcmFudCh7fSwgTWVzc2FnZXMuSWxsZWdhbEltcG9ydERlY2xhcmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW1wb3J0RGVjbGFyYXRpb24oKTtcbiAgICAgICAgICAgIGNhc2UgXCJmdW5jdGlvblwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUZ1bmN0aW9uRGVjbGFyYXRpb24oKTtcbiAgICAgICAgICAgIGNhc2UgXCJjbGFzc1wiOlxuICAgICAgICAgICAgICAgIGlmIChhbGxvd0NsYXNzZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlQ2xhc3NEZWNsYXJhdGlvbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJjb25zdFwiOlxuICAgICAgICAgICAgY2FzZSBcImxldFwiOlxuICAgICAgICAgICAgICAgIGlmIChhbGxvd0Jsb2NrQmluZGluZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlQ29uc3RMZXREZWNsYXJhdGlvbihsb29rYWhlYWQudmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZVN0YXRlbWVudCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGxvb2thaGVhZC50eXBlICE9PSBUb2tlbi5FT0YpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlU3RhdGVtZW50KCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBwYXJzZVNvdXJjZUVsZW1lbnRzKCkge1xuICAgIHZhciBzb3VyY2VFbGVtZW50LCBzb3VyY2VFbGVtZW50cyA9IFtdLCB0b2tlbiwgZGlyZWN0aXZlLCBmaXJzdFJlc3RyaWN0ZWQ7XG5cbiAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdG9rZW4gPSBsb29rYWhlYWQ7XG4gICAgICAgIGlmICh0b2tlbi50eXBlICE9PSBUb2tlbi5TdHJpbmdMaXRlcmFsKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHNvdXJjZUVsZW1lbnQgPSBwYXJzZVNvdXJjZUVsZW1lbnQoKTtcbiAgICAgICAgc291cmNlRWxlbWVudHMucHVzaChzb3VyY2VFbGVtZW50KTtcbiAgICAgICAgaWYgKHNvdXJjZUVsZW1lbnQuZXhwcmVzc2lvbi50eXBlICE9PSBhc3ROb2RlVHlwZXMuTGl0ZXJhbCkge1xuICAgICAgICAgICAgLy8gdGhpcyBpcyBub3QgZGlyZWN0aXZlXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBkaXJlY3RpdmUgPSBzb3VyY2Uuc2xpY2UodG9rZW4ucmFuZ2VbMF0gKyAxLCB0b2tlbi5yYW5nZVsxXSAtIDEpO1xuICAgICAgICBpZiAoZGlyZWN0aXZlID09PSBcInVzZSBzdHJpY3RcIikge1xuICAgICAgICAgICAgc3RyaWN0ID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChmaXJzdFJlc3RyaWN0ZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvd0Vycm9yVG9sZXJhbnQoZmlyc3RSZXN0cmljdGVkLCBNZXNzYWdlcy5TdHJpY3RPY3RhbExpdGVyYWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFmaXJzdFJlc3RyaWN0ZWQgJiYgdG9rZW4ub2N0YWwpIHtcbiAgICAgICAgICAgICAgICBmaXJzdFJlc3RyaWN0ZWQgPSB0b2tlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBzb3VyY2VFbGVtZW50ID0gcGFyc2VTb3VyY2VFbGVtZW50KCk7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICBpZiAodHlwZW9mIHNvdXJjZUVsZW1lbnQgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHNvdXJjZUVsZW1lbnRzLnB1c2goc291cmNlRWxlbWVudCk7XG4gICAgfVxuICAgIHJldHVybiBzb3VyY2VFbGVtZW50cztcbn1cblxuZnVuY3Rpb24gcGFyc2VQcm9ncmFtKCkge1xuICAgIHZhciBib2R5LFxuICAgICAgICBtYXJrZXIsXG4gICAgICAgIGlzTW9kdWxlID0gISFleHRyYS5lY21hRmVhdHVyZXMubW9kdWxlcztcblxuICAgIHNraXBDb21tZW50KCk7XG4gICAgcGVlaygpO1xuICAgIG1hcmtlciA9IG1hcmtlckNyZWF0ZSgpO1xuICAgIHN0cmljdCA9IGlzTW9kdWxlO1xuXG4gICAgYm9keSA9IHBhcnNlU291cmNlRWxlbWVudHMoKTtcbiAgICByZXR1cm4gbWFya2VyQXBwbHkobWFya2VyLCBhc3ROb2RlRmFjdG9yeS5jcmVhdGVQcm9ncmFtKGJvZHksIGlzTW9kdWxlID8gXCJtb2R1bGVcIiA6IFwic2NyaXB0XCIpKTtcbn1cblxuZnVuY3Rpb24gZmlsdGVyVG9rZW5Mb2NhdGlvbigpIHtcbiAgICB2YXIgaSwgZW50cnksIHRva2VuLCB0b2tlbnMgPSBbXTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBleHRyYS50b2tlbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgZW50cnkgPSBleHRyYS50b2tlbnNbaV07XG4gICAgICAgIHRva2VuID0ge1xuICAgICAgICAgICAgdHlwZTogZW50cnkudHlwZSxcbiAgICAgICAgICAgIHZhbHVlOiBlbnRyeS52YWx1ZVxuICAgICAgICB9O1xuICAgICAgICBpZiAoZW50cnkucmVnZXgpIHtcbiAgICAgICAgICAgIHRva2VuLnJlZ2V4ID0ge1xuICAgICAgICAgICAgICAgIHBhdHRlcm46IGVudHJ5LnJlZ2V4LnBhdHRlcm4sXG4gICAgICAgICAgICAgICAgZmxhZ3M6IGVudHJ5LnJlZ2V4LmZsYWdzXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChleHRyYS5yYW5nZSkge1xuICAgICAgICAgICAgdG9rZW4ucmFuZ2UgPSBlbnRyeS5yYW5nZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXh0cmEubG9jKSB7XG4gICAgICAgICAgICB0b2tlbi5sb2MgPSBlbnRyeS5sb2M7XG4gICAgICAgIH1cbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgIH1cblxuICAgIGV4dHJhLnRva2VucyA9IHRva2Vucztcbn1cblxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRva2VuaXplclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuZnVuY3Rpb24gdG9rZW5pemUoY29kZSwgb3B0aW9ucykge1xuICAgIHZhciB0b1N0cmluZyxcbiAgICAgICAgdG9rZW5zO1xuXG4gICAgdG9TdHJpbmcgPSBTdHJpbmc7XG4gICAgaWYgKHR5cGVvZiBjb2RlICE9PSBcInN0cmluZ1wiICYmICEoY29kZSBpbnN0YW5jZW9mIFN0cmluZykpIHtcbiAgICAgICAgY29kZSA9IHRvU3RyaW5nKGNvZGUpO1xuICAgIH1cblxuICAgIHNvdXJjZSA9IGNvZGU7XG4gICAgaW5kZXggPSAwO1xuICAgIGxpbmVOdW1iZXIgPSAoc291cmNlLmxlbmd0aCA+IDApID8gMSA6IDA7XG4gICAgbGluZVN0YXJ0ID0gMDtcbiAgICBsZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuICAgIGxvb2thaGVhZCA9IG51bGw7XG4gICAgc3RhdGUgPSB7XG4gICAgICAgIGFsbG93SW46IHRydWUsXG4gICAgICAgIGxhYmVsU2V0OiB7fSxcbiAgICAgICAgcGFyZW50aGVzaXNDb3VudDogMCxcbiAgICAgICAgaW5GdW5jdGlvbkJvZHk6IGZhbHNlLFxuICAgICAgICBpbkl0ZXJhdGlvbjogZmFsc2UsXG4gICAgICAgIGluU3dpdGNoOiBmYWxzZSxcbiAgICAgICAgbGFzdENvbW1lbnRTdGFydDogLTEsXG4gICAgICAgIHlpZWxkQWxsb3dlZDogZmFsc2UsXG4gICAgICAgIGN1cmx5U3RhY2s6IFtdLFxuICAgICAgICBjdXJseUxhc3RJbmRleDogMCxcbiAgICAgICAgaW5KU1hTcHJlYWRBdHRyaWJ1dGU6IGZhbHNlLFxuICAgICAgICBpbkpTWENoaWxkOiBmYWxzZSxcbiAgICAgICAgaW5KU1hUYWc6IGZhbHNlXG4gICAgfTtcblxuICAgIGV4dHJhID0ge1xuICAgICAgICBlY21hRmVhdHVyZXM6IGRlZmF1bHRGZWF0dXJlc1xuICAgIH07XG5cbiAgICAvLyBPcHRpb25zIG1hdGNoaW5nLlxuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgLy8gT2YgY291cnNlIHdlIGNvbGxlY3QgdG9rZW5zIGhlcmUuXG4gICAgb3B0aW9ucy50b2tlbnMgPSB0cnVlO1xuICAgIGV4dHJhLnRva2VucyA9IFtdO1xuICAgIGV4dHJhLnRva2VuaXplID0gdHJ1ZTtcblxuICAgIC8vIFRoZSBmb2xsb3dpbmcgdHdvIGZpZWxkcyBhcmUgbmVjZXNzYXJ5IHRvIGNvbXB1dGUgdGhlIFJlZ2V4IHRva2Vucy5cbiAgICBleHRyYS5vcGVuUGFyZW5Ub2tlbiA9IC0xO1xuICAgIGV4dHJhLm9wZW5DdXJseVRva2VuID0gLTE7XG5cbiAgICBleHRyYS5yYW5nZSA9ICh0eXBlb2Ygb3B0aW9ucy5yYW5nZSA9PT0gXCJib29sZWFuXCIpICYmIG9wdGlvbnMucmFuZ2U7XG4gICAgZXh0cmEubG9jID0gKHR5cGVvZiBvcHRpb25zLmxvYyA9PT0gXCJib29sZWFuXCIpICYmIG9wdGlvbnMubG9jO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmNvbW1lbnQgPT09IFwiYm9vbGVhblwiICYmIG9wdGlvbnMuY29tbWVudCkge1xuICAgICAgICBleHRyYS5jb21tZW50cyA9IFtdO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMudG9sZXJhbnQgPT09IFwiYm9vbGVhblwiICYmIG9wdGlvbnMudG9sZXJhbnQpIHtcbiAgICAgICAgZXh0cmEuZXJyb3JzID0gW107XG4gICAgfVxuXG4gICAgLy8gYXBwbHkgcGFyc2luZyBmbGFnc1xuICAgIGlmIChvcHRpb25zLmVjbWFGZWF0dXJlcyAmJiB0eXBlb2Ygb3B0aW9ucy5lY21hRmVhdHVyZXMgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgZXh0cmEuZWNtYUZlYXR1cmVzID0gb3B0aW9ucy5lY21hRmVhdHVyZXM7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgcGVlaygpO1xuICAgICAgICBpZiAobG9va2FoZWFkLnR5cGUgPT09IFRva2VuLkVPRikge1xuICAgICAgICAgICAgcmV0dXJuIGV4dHJhLnRva2VucztcbiAgICAgICAgfVxuXG4gICAgICAgIGxleCgpO1xuICAgICAgICB3aGlsZSAobG9va2FoZWFkLnR5cGUgIT09IFRva2VuLkVPRikge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsZXgoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGxleEVycm9yKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV4dHJhLmVycm9ycykge1xuICAgICAgICAgICAgICAgICAgICBleHRyYS5lcnJvcnMucHVzaChsZXhFcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdlIGhhdmUgdG8gYnJlYWsgb24gdGhlIGZpcnN0IGVycm9yXG4gICAgICAgICAgICAgICAgICAgIC8vIHRvIGF2b2lkIGluZmluaXRlIGxvb3BzLlxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBsZXhFcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmaWx0ZXJUb2tlbkxvY2F0aW9uKCk7XG4gICAgICAgIHRva2VucyA9IGV4dHJhLnRva2VucztcblxuICAgICAgICBpZiAodHlwZW9mIGV4dHJhLmNvbW1lbnRzICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICB0b2tlbnMuY29tbWVudHMgPSBleHRyYS5jb21tZW50cztcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGV4dHJhLmVycm9ycyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgdG9rZW5zLmVycm9ycyA9IGV4dHJhLmVycm9ycztcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgICBleHRyYSA9IHt9O1xuICAgIH1cbiAgICByZXR1cm4gdG9rZW5zO1xufVxuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUGFyc2VyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5mdW5jdGlvbiBwYXJzZShjb2RlLCBvcHRpb25zKSB7XG4gICAgdmFyIHByb2dyYW0sIHRvU3RyaW5nO1xuXG4gICAgdG9TdHJpbmcgPSBTdHJpbmc7XG4gICAgaWYgKHR5cGVvZiBjb2RlICE9PSBcInN0cmluZ1wiICYmICEoY29kZSBpbnN0YW5jZW9mIFN0cmluZykpIHtcbiAgICAgICAgY29kZSA9IHRvU3RyaW5nKGNvZGUpO1xuICAgIH1cblxuICAgIHNvdXJjZSA9IGNvZGU7XG4gICAgaW5kZXggPSAwO1xuICAgIGxpbmVOdW1iZXIgPSAoc291cmNlLmxlbmd0aCA+IDApID8gMSA6IDA7XG4gICAgbGluZVN0YXJ0ID0gMDtcbiAgICBsZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuICAgIGxvb2thaGVhZCA9IG51bGw7XG4gICAgc3RhdGUgPSB7XG4gICAgICAgIGFsbG93SW46IHRydWUsXG4gICAgICAgIGxhYmVsU2V0OiBuZXcgU3RyaW5nTWFwKCksXG4gICAgICAgIHBhcmVudGhlc2lzQ291bnQ6IDAsXG4gICAgICAgIGluRnVuY3Rpb25Cb2R5OiBmYWxzZSxcbiAgICAgICAgaW5JdGVyYXRpb246IGZhbHNlLFxuICAgICAgICBpblN3aXRjaDogZmFsc2UsXG4gICAgICAgIGxhc3RDb21tZW50U3RhcnQ6IC0xLFxuICAgICAgICB5aWVsZEFsbG93ZWQ6IGZhbHNlLFxuICAgICAgICBjdXJseVN0YWNrOiBbXSxcbiAgICAgICAgY3VybHlMYXN0SW5kZXg6IDAsXG4gICAgICAgIGluSlNYU3ByZWFkQXR0cmlidXRlOiBmYWxzZSxcbiAgICAgICAgaW5KU1hDaGlsZDogZmFsc2UsXG4gICAgICAgIGluSlNYVGFnOiBmYWxzZVxuICAgIH07XG5cbiAgICBleHRyYSA9IHtcbiAgICAgICAgZWNtYUZlYXR1cmVzOiBPYmplY3QuY3JlYXRlKGRlZmF1bHRGZWF0dXJlcylcbiAgICB9O1xuXG4gICAgLy8gZm9yIHRlbXBsYXRlIHN0cmluZ3NcbiAgICBzdGF0ZS5jdXJseVN0YWNrID0gW107XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgZXh0cmEucmFuZ2UgPSAodHlwZW9mIG9wdGlvbnMucmFuZ2UgPT09IFwiYm9vbGVhblwiKSAmJiBvcHRpb25zLnJhbmdlO1xuICAgICAgICBleHRyYS5sb2MgPSAodHlwZW9mIG9wdGlvbnMubG9jID09PSBcImJvb2xlYW5cIikgJiYgb3B0aW9ucy5sb2M7XG4gICAgICAgIGV4dHJhLmF0dGFjaENvbW1lbnQgPSAodHlwZW9mIG9wdGlvbnMuYXR0YWNoQ29tbWVudCA9PT0gXCJib29sZWFuXCIpICYmIG9wdGlvbnMuYXR0YWNoQ29tbWVudDtcblxuICAgICAgICBpZiAoZXh0cmEubG9jICYmIG9wdGlvbnMuc291cmNlICE9PSBudWxsICYmIG9wdGlvbnMuc291cmNlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGV4dHJhLnNvdXJjZSA9IHRvU3RyaW5nKG9wdGlvbnMuc291cmNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy50b2tlbnMgPT09IFwiYm9vbGVhblwiICYmIG9wdGlvbnMudG9rZW5zKSB7XG4gICAgICAgICAgICBleHRyYS50b2tlbnMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMuY29tbWVudCA9PT0gXCJib29sZWFuXCIgJiYgb3B0aW9ucy5jb21tZW50KSB7XG4gICAgICAgICAgICBleHRyYS5jb21tZW50cyA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy50b2xlcmFudCA9PT0gXCJib29sZWFuXCIgJiYgb3B0aW9ucy50b2xlcmFudCkge1xuICAgICAgICAgICAgZXh0cmEuZXJyb3JzID0gW107XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV4dHJhLmF0dGFjaENvbW1lbnQpIHtcbiAgICAgICAgICAgIGV4dHJhLnJhbmdlID0gdHJ1ZTtcbiAgICAgICAgICAgIGV4dHJhLmNvbW1lbnRzID0gW107XG4gICAgICAgICAgICBjb21tZW50QXR0YWNobWVudC5yZXNldCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuc291cmNlVHlwZSA9PT0gXCJtb2R1bGVcIikge1xuICAgICAgICAgICAgZXh0cmEuZWNtYUZlYXR1cmVzID0ge1xuICAgICAgICAgICAgICAgIGFycm93RnVuY3Rpb25zOiB0cnVlLFxuICAgICAgICAgICAgICAgIGJsb2NrQmluZGluZ3M6IHRydWUsXG4gICAgICAgICAgICAgICAgcmVnZXhVRmxhZzogdHJ1ZSxcbiAgICAgICAgICAgICAgICByZWdleFlGbGFnOiB0cnVlLFxuICAgICAgICAgICAgICAgIHRlbXBsYXRlU3RyaW5nczogdHJ1ZSxcbiAgICAgICAgICAgICAgICBiaW5hcnlMaXRlcmFsczogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvY3RhbExpdGVyYWxzOiB0cnVlLFxuICAgICAgICAgICAgICAgIHVuaWNvZGVDb2RlUG9pbnRFc2NhcGVzOiB0cnVlLFxuICAgICAgICAgICAgICAgIHN1cGVySW5GdW5jdGlvbnM6IHRydWUsXG4gICAgICAgICAgICAgICAgZGVmYXVsdFBhcmFtczogdHJ1ZSxcbiAgICAgICAgICAgICAgICByZXN0UGFyYW1zOiB0cnVlLFxuICAgICAgICAgICAgICAgIGZvck9mOiB0cnVlLFxuICAgICAgICAgICAgICAgIG9iamVjdExpdGVyYWxDb21wdXRlZFByb3BlcnRpZXM6IHRydWUsXG4gICAgICAgICAgICAgICAgb2JqZWN0TGl0ZXJhbFNob3J0aGFuZE1ldGhvZHM6IHRydWUsXG4gICAgICAgICAgICAgICAgb2JqZWN0TGl0ZXJhbFNob3J0aGFuZFByb3BlcnRpZXM6IHRydWUsXG4gICAgICAgICAgICAgICAgb2JqZWN0TGl0ZXJhbER1cGxpY2F0ZVByb3BlcnRpZXM6IHRydWUsXG4gICAgICAgICAgICAgICAgZ2VuZXJhdG9yczogdHJ1ZSxcbiAgICAgICAgICAgICAgICBkZXN0cnVjdHVyaW5nOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNsYXNzZXM6IHRydWUsXG4gICAgICAgICAgICAgICAgbW9kdWxlczogdHJ1ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGFwcGx5IHBhcnNpbmcgZmxhZ3MgYWZ0ZXIgc291cmNlVHlwZSB0byBhbGxvdyBvdmVycmlkaW5nXG4gICAgICAgIGlmIChvcHRpb25zLmVjbWFGZWF0dXJlcyAmJiB0eXBlb2Ygb3B0aW9ucy5lY21hRmVhdHVyZXMgPT09IFwib2JqZWN0XCIpIHtcblxuICAgICAgICAgICAgLy8gaWYgaXQncyBhIG1vZHVsZSwgYXVnbWVudCB0aGUgZWNtYUZlYXR1cmVzXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5zb3VyY2VUeXBlID09PSBcIm1vZHVsZVwiKSB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmtleXMob3B0aW9ucy5lY21hRmVhdHVyZXMpLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIGV4dHJhLmVjbWFGZWF0dXJlc1trZXldID0gb3B0aW9ucy5lY21hRmVhdHVyZXNba2V5XTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZXh0cmEuZWNtYUZlYXR1cmVzID0gb3B0aW9ucy5lY21hRmVhdHVyZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAgIHByb2dyYW0gPSBwYXJzZVByb2dyYW0oKTtcbiAgICAgICAgaWYgKHR5cGVvZiBleHRyYS5jb21tZW50cyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcHJvZ3JhbS5jb21tZW50cyA9IGV4dHJhLmNvbW1lbnRzO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZXh0cmEudG9rZW5zICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICBmaWx0ZXJUb2tlbkxvY2F0aW9uKCk7XG4gICAgICAgICAgICBwcm9ncmFtLnRva2VucyA9IGV4dHJhLnRva2VucztcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGV4dHJhLmVycm9ycyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcHJvZ3JhbS5lcnJvcnMgPSBleHRyYS5lcnJvcnM7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IGU7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgZXh0cmEgPSB7fTtcbiAgICB9XG5cbiAgICByZXR1cm4gcHJvZ3JhbTtcbn1cblxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFB1YmxpY1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuZXhwb3J0cy52ZXJzaW9uID0gcmVxdWlyZShcIi4vcGFja2FnZS5qc29uXCIpLnZlcnNpb247XG5cbmV4cG9ydHMudG9rZW5pemUgPSB0b2tlbml6ZTtcblxuZXhwb3J0cy5wYXJzZSA9IHBhcnNlO1xuXG4vLyBEZWVwIGNvcHkuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZXhwb3J0cy5TeW50YXggPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBuYW1lLCB0eXBlcyA9IHt9O1xuXG4gICAgaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdHlwZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIH1cblxuICAgIGZvciAobmFtZSBpbiBhc3ROb2RlVHlwZXMpIHtcbiAgICAgICAgaWYgKGFzdE5vZGVUeXBlcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICAgICAgdHlwZXNbbmFtZV0gPSBhc3ROb2RlVHlwZXNbbmFtZV07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIE9iamVjdC5mcmVlemUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBPYmplY3QuZnJlZXplKHR5cGVzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHlwZXM7XG59KCkpO1xuIiwiLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IEEgZmFjdG9yeSBmb3IgY3JlYXRpbmcgQVNUIG5vZGVzXG4gKiBAYXV0aG9yIEZyZWQgSy4gU2Nob3R0XG4gKiBAY29weXJpZ2h0IDIwMTQgRnJlZCBLLiBTY2hvdHQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBAY29weXJpZ2h0IDIwMTEtMjAxMyBBcml5YSBIaWRheWF0IDxhcml5YS5oaWRheWF0QGdtYWlsLmNvbT5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAqICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICogKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICogICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4gKiAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cblwidXNlIHN0cmljdFwiO1xuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUmVxdWlyZW1lbnRzXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG52YXIgYXN0Tm9kZVR5cGVzID0gcmVxdWlyZShcIi4vYXN0LW5vZGUtdHlwZXNcIik7XG5cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBQdWJsaWNcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFycmF5IEV4cHJlc3Npb24gQVNUTm9kZSBvdXQgb2YgYW4gYXJyYXkgb2YgZWxlbWVudHNcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGVbXX0gZWxlbWVudHMgQW4gYXJyYXkgb2YgQVNUTm9kZSBlbGVtZW50c1xuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyB0aGUgZW50aXJlIGFycmF5IGV4cHJlc3Npb25cbiAgICAgKi9cbiAgICBjcmVhdGVBcnJheUV4cHJlc3Npb246IGZ1bmN0aW9uKGVsZW1lbnRzKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuQXJyYXlFeHByZXNzaW9uLFxuICAgICAgICAgICAgZWxlbWVudHM6IGVsZW1lbnRzXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhbiBBcnJvdyBGdW5jdGlvbiBFeHByZXNzaW9uIEFTVE5vZGVcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IHBhcmFtcyBUaGUgZnVuY3Rpb24gYXJndW1lbnRzXG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSBib2R5IFRoZSBmdW5jdGlvbiBib2R5XG4gICAgICogQHBhcmFtIHtib29sZWFufSBleHByZXNzaW9uIFRydWUgaWYgdGhlIGFycm93IGZ1bmN0aW9uIGlzIGNyZWF0ZWQgdmlhIGFuIGV4cHJlc3Npb24uXG4gICAgICogICAgICBBbHdheXMgZmFsc2UgZm9yIGRlY2xhcmF0aW9ucywgYnV0IGtlcHQgaGVyZSB0byBiZSBpbiBzeW5jIHdpdGhcbiAgICAgKiAgICAgIEZ1bmN0aW9uRXhwcmVzc2lvbiBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyB0aGUgZW50aXJlIGFycm93IGZ1bmN0aW9uIGV4cHJlc3Npb25cbiAgICAgKi9cbiAgICBjcmVhdGVBcnJvd0Z1bmN0aW9uRXhwcmVzc2lvbjogZnVuY3Rpb24gKHBhcmFtcywgYm9keSwgZXhwcmVzc2lvbikge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLkFycm93RnVuY3Rpb25FeHByZXNzaW9uLFxuICAgICAgICAgICAgaWQ6IG51bGwsXG4gICAgICAgICAgICBwYXJhbXM6IHBhcmFtcyxcbiAgICAgICAgICAgIGJvZHk6IGJvZHksXG4gICAgICAgICAgICBnZW5lcmF0b3I6IGZhbHNlLFxuICAgICAgICAgICAgZXhwcmVzc2lvbjogZXhwcmVzc2lvblxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhbiBhc3NpZ25tZW50IGV4cHJlc3Npb25cbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IG9wZXJhdG9yIFRoZSBhc3NpZ25tZW50IG9wZXJhdG9yXG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSBsZWZ0IFRoZSBsZWZ0IG9wZXJhbmRcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IHJpZ2h0IFRoZSByaWdodCBvcGVyYW5kXG4gICAgICogQHJldHVybnMge0FTVE5vZGV9IEFuIEFTVE5vZGUgcmVwcmVzZW50aW5nIHRoZSBlbnRpcmUgYXNzaWdubWVudCBleHByZXNzaW9uXG4gICAgICovXG4gICAgY3JlYXRlQXNzaWdubWVudEV4cHJlc3Npb246IGZ1bmN0aW9uKG9wZXJhdG9yLCBsZWZ0LCByaWdodCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLkFzc2lnbm1lbnRFeHByZXNzaW9uLFxuICAgICAgICAgICAgb3BlcmF0b3I6IG9wZXJhdG9yLFxuICAgICAgICAgICAgbGVmdDogbGVmdCxcbiAgICAgICAgICAgIHJpZ2h0OiByaWdodFxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhbiBhc3NpZ25tZW50IHBhdHRlcm4gKGRlZmF1bHQgcGFyYW1ldGVycylcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGxlZnQgVGhlIGxlZnQgb3BlcmFuZFxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gcmlnaHQgVGhlIHJpZ2h0IG9wZXJhbmRcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgdGhlIGVudGlyZSBhc3NpZ25tZW50IHBhdHRlcm5cbiAgICAgKi9cbiAgICBjcmVhdGVBc3NpZ25tZW50UGF0dGVybjogZnVuY3Rpb24obGVmdCwgcmlnaHQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5Bc3NpZ25tZW50UGF0dGVybixcbiAgICAgICAgICAgIGxlZnQ6IGxlZnQsXG4gICAgICAgICAgICByaWdodDogcmlnaHRcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSBiaW5hcnkgZXhwcmVzc2lvblxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gb3BlcmF0b3IgVGhlIGFzc2lnbm1lbnQgb3BlcmF0b3JcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGxlZnQgVGhlIGxlZnQgb3BlcmFuZFxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gcmlnaHQgVGhlIHJpZ2h0IG9wZXJhbmRcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgdGhlIGVudGlyZSBiaW5hcnkgZXhwcmVzc2lvblxuICAgICAqL1xuICAgIGNyZWF0ZUJpbmFyeUV4cHJlc3Npb246IGZ1bmN0aW9uKG9wZXJhdG9yLCBsZWZ0LCByaWdodCkge1xuICAgICAgICB2YXIgdHlwZSA9IChvcGVyYXRvciA9PT0gXCJ8fFwiIHx8IG9wZXJhdG9yID09PSBcIiYmXCIpID8gYXN0Tm9kZVR5cGVzLkxvZ2ljYWxFeHByZXNzaW9uIDpcbiAgICAgICAgICAgICAgICAgICAgYXN0Tm9kZVR5cGVzLkJpbmFyeUV4cHJlc3Npb247XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiB0eXBlLFxuICAgICAgICAgICAgb3BlcmF0b3I6IG9wZXJhdG9yLFxuICAgICAgICAgICAgbGVmdDogbGVmdCxcbiAgICAgICAgICAgIHJpZ2h0OiByaWdodFxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhIGJsb2NrIHN0YXRlbWVudFxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gYm9keSBUaGUgYmxvY2sgc3RhdGVtZW50IGJvZHlcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgdGhlIGVudGlyZSBibG9jayBzdGF0ZW1lbnRcbiAgICAgKi9cbiAgICBjcmVhdGVCbG9ja1N0YXRlbWVudDogZnVuY3Rpb24oYm9keSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLkJsb2NrU3RhdGVtZW50LFxuICAgICAgICAgICAgYm9keTogYm9keVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhIGJyZWFrIHN0YXRlbWVudFxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gbGFiZWwgVGhlIGJyZWFrIHN0YXRlbWVudCBsYWJlbFxuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyB0aGUgYnJlYWsgc3RhdGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlQnJlYWtTdGF0ZW1lbnQ6IGZ1bmN0aW9uKGxhYmVsKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuQnJlYWtTdGF0ZW1lbnQsXG4gICAgICAgICAgICBsYWJlbDogbGFiZWxcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSBjYWxsIGV4cHJlc3Npb25cbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGNhbGxlZSBUaGUgZnVuY3Rpb24gYmVpbmcgY2FsbGVkXG4gICAgICogQHBhcmFtIHtBU1ROb2RlW119IGFyZ3MgQW4gYXJyYXkgb2YgQVNUTm9kZXMgcmVwcmVzZW50aW5nIHRoZSBmdW5jdGlvbiBjYWxsIGFyZ3VtZW50c1xuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyB0aGUgZW50aXJlIGNhbGwgZXhwcmVzc2lvblxuICAgICAqL1xuICAgIGNyZWF0ZUNhbGxFeHByZXNzaW9uOiBmdW5jdGlvbihjYWxsZWUsIGFyZ3MpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5DYWxsRXhwcmVzc2lvbixcbiAgICAgICAgICAgIGNhbGxlZTogY2FsbGVlLFxuICAgICAgICAgICAgXCJhcmd1bWVudHNcIjogYXJnc1xuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhIGNhdGNoIGNsYXVzZS9ibG9ja1xuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gcGFyYW0gQW55IGNhdGNoIGNsYXVzZSBleGVwdGlvbi9jb25kaXRpb25hbCBwYXJhbWV0ZXIgaW5mb3JtYXRpb25cbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGJvZHkgVGhlIGNhdGNoIGJsb2NrIGJvZHlcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgdGhlIGVudGlyZSBjYXRjaCBjbGF1c2VcbiAgICAgKi9cbiAgICBjcmVhdGVDYXRjaENsYXVzZTogZnVuY3Rpb24ocGFyYW0sIGJvZHkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5DYXRjaENsYXVzZSxcbiAgICAgICAgICAgIHBhcmFtOiBwYXJhbSxcbiAgICAgICAgICAgIGJvZHk6IGJvZHlcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBBU1ROb2RlIHJlcHJlc2VudGF0aW9uIG9mIGEgY2xhc3MgYm9keS5cbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGJvZHkgVGhlIG5vZGUgcmVwcmVzZW50aW5nIHRoZSBib2R5IG9mIHRoZSBjbGFzcy5cbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgdGhlIGNsYXNzIGJvZHkuXG4gICAgICovXG4gICAgY3JlYXRlQ2xhc3NCb2R5OiBmdW5jdGlvbihib2R5KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuQ2xhc3NCb2R5LFxuICAgICAgICAgICAgYm9keTogYm9keVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBjcmVhdGVDbGFzc0V4cHJlc3Npb246IGZ1bmN0aW9uKGlkLCBzdXBlckNsYXNzLCBib2R5KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuQ2xhc3NFeHByZXNzaW9uLFxuICAgICAgICAgICAgaWQ6IGlkLFxuICAgICAgICAgICAgc3VwZXJDbGFzczogc3VwZXJDbGFzcyxcbiAgICAgICAgICAgIGJvZHk6IGJvZHlcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgY3JlYXRlQ2xhc3NEZWNsYXJhdGlvbjogZnVuY3Rpb24oaWQsIHN1cGVyQ2xhc3MsIGJvZHkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5DbGFzc0RlY2xhcmF0aW9uLFxuICAgICAgICAgICAgaWQ6IGlkLFxuICAgICAgICAgICAgc3VwZXJDbGFzczogc3VwZXJDbGFzcyxcbiAgICAgICAgICAgIGJvZHk6IGJvZHlcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgY3JlYXRlTWV0aG9kRGVmaW5pdGlvbjogZnVuY3Rpb24ocHJvcGVydHlUeXBlLCBraW5kLCBrZXksIHZhbHVlLCBjb21wdXRlZCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLk1ldGhvZERlZmluaXRpb24sXG4gICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgIGtpbmQ6IGtpbmQsXG4gICAgICAgICAgICBcInN0YXRpY1wiOiBwcm9wZXJ0eVR5cGUgPT09IFwic3RhdGljXCIsXG4gICAgICAgICAgICBjb21wdXRlZDogY29tcHV0ZWRcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSBjb25kaXRpb25hbCBleHByZXNzaW9uXG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSB0ZXN0IFRoZSBjb25kaXRpb25hbCB0byBldmFsdWF0ZVxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gY29uc2VxdWVudCBUaGUgY29kZSB0byBiZSBydW4gaWYgdGhlIHRlc3QgcmV0dXJucyB0cnVlXG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSBhbHRlcm5hdGUgVGhlIGNvZGUgdG8gYmUgcnVuIGlmIHRoZSB0ZXN0IHJldHVybnMgZmFsc2VcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgdGhlIGVudGlyZSBjb25kaXRpb25hbCBleHByZXNzaW9uXG4gICAgICovXG4gICAgY3JlYXRlQ29uZGl0aW9uYWxFeHByZXNzaW9uOiBmdW5jdGlvbih0ZXN0LCBjb25zZXF1ZW50LCBhbHRlcm5hdGUpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5Db25kaXRpb25hbEV4cHJlc3Npb24sXG4gICAgICAgICAgICB0ZXN0OiB0ZXN0LFxuICAgICAgICAgICAgY29uc2VxdWVudDogY29uc2VxdWVudCxcbiAgICAgICAgICAgIGFsdGVybmF0ZTogYWx0ZXJuYXRlXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhbiBBU1ROb2RlIHJlcHJlc2VudGF0aW9uIG9mIGEgY29udGludWUgc3RhdGVtZW50XG4gICAgICogQHBhcmFtIHs/QVNUTm9kZX0gbGFiZWwgVGhlIG9wdGlvbmFsIGNvbnRpbnVlIGxhYmVsIChudWxsIGlmIG5vdCBzZXQpXG4gICAgICogQHJldHVybnMge0FTVE5vZGV9IEFuIEFTVE5vZGUgcmVwcmVzZW50aW5nIHRoZSBjb250aW51ZSBzdGF0ZW1lbnRcbiAgICAgKi9cbiAgICBjcmVhdGVDb250aW51ZVN0YXRlbWVudDogZnVuY3Rpb24obGFiZWwpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5Db250aW51ZVN0YXRlbWVudCxcbiAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhIGRlYnVnZ2VyIHN0YXRlbWVudFxuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyB0aGUgZGVidWdnZXIgc3RhdGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlRGVidWdnZXJTdGF0ZW1lbnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLkRlYnVnZ2VyU3RhdGVtZW50XG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhbiBBU1ROb2RlIHJlcHJlc2VudGF0aW9uIG9mIGFuIGVtcHR5IHN0YXRlbWVudFxuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyBhbiBlbXB0eSBzdGF0ZW1lbnRcbiAgICAgKi9cbiAgICBjcmVhdGVFbXB0eVN0YXRlbWVudDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuRW1wdHlTdGF0ZW1lbnRcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYW4gZXhwcmVzc2lvbiBzdGF0ZW1lbnRcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGV4cHJlc3Npb24gVGhlIGV4cHJlc3Npb25cbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgYW4gZXhwcmVzc2lvbiBzdGF0ZW1lbnRcbiAgICAgKi9cbiAgICBjcmVhdGVFeHByZXNzaW9uU3RhdGVtZW50OiBmdW5jdGlvbihleHByZXNzaW9uKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuRXhwcmVzc2lvblN0YXRlbWVudCxcbiAgICAgICAgICAgIGV4cHJlc3Npb246IGV4cHJlc3Npb25cbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSB3aGlsZSBzdGF0ZW1lbnRcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IHRlc3QgVGhlIHdoaWxlIGNvbmRpdGlvbmFsXG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSBib2R5IFRoZSB3aGlsZSBsb29wIGJvZHlcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgYSB3aGlsZSBzdGF0ZW1lbnRcbiAgICAgKi9cbiAgICBjcmVhdGVXaGlsZVN0YXRlbWVudDogZnVuY3Rpb24odGVzdCwgYm9keSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLldoaWxlU3RhdGVtZW50LFxuICAgICAgICAgICAgdGVzdDogdGVzdCxcbiAgICAgICAgICAgIGJvZHk6IGJvZHlcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSBkby4ud2hpbGUgc3RhdGVtZW50XG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSB0ZXN0IFRoZSBkby4ud2hpbGUgY29uZGl0aW9uYWxcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGJvZHkgVGhlIGRvLi53aGlsZSBsb29wIGJvZHlcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgYSBkby4ud2hpbGUgc3RhdGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlRG9XaGlsZVN0YXRlbWVudDogZnVuY3Rpb24odGVzdCwgYm9keSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLkRvV2hpbGVTdGF0ZW1lbnQsXG4gICAgICAgICAgICBib2R5OiBib2R5LFxuICAgICAgICAgICAgdGVzdDogdGVzdFxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhIGZvciBzdGF0ZW1lbnRcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGluaXQgVGhlIGluaXRpYWxpemF0aW9uIGV4cHJlc3Npb25cbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IHRlc3QgVGhlIGNvbmRpdGlvbmFsIHRlc3QgZXhwcmVzc2lvblxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gdXBkYXRlIFRoZSB1cGRhdGUgZXhwcmVzc2lvblxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gYm9keSBUaGUgc3RhdGVtZW50IGJvZHlcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgYSBmb3Igc3RhdGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlRm9yU3RhdGVtZW50OiBmdW5jdGlvbihpbml0LCB0ZXN0LCB1cGRhdGUsIGJvZHkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5Gb3JTdGF0ZW1lbnQsXG4gICAgICAgICAgICBpbml0OiBpbml0LFxuICAgICAgICAgICAgdGVzdDogdGVzdCxcbiAgICAgICAgICAgIHVwZGF0ZTogdXBkYXRlLFxuICAgICAgICAgICAgYm9keTogYm9keVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhIGZvci4uaW4gc3RhdGVtZW50XG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSBsZWZ0IFRoZSBsZWZ0LXNpZGUgdmFyaWFibGUgZm9yIHRoZSBwcm9wZXJ0eSBuYW1lXG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSByaWdodCBUaGUgcmlnaHQtc2lkZSBvYmplY3RcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGJvZHkgVGhlIHN0YXRlbWVudCBib2R5XG4gICAgICogQHJldHVybnMge0FTVE5vZGV9IEFuIEFTVE5vZGUgcmVwcmVzZW50aW5nIGEgZm9yLi5pbiBzdGF0ZW1lbnRcbiAgICAgKi9cbiAgICBjcmVhdGVGb3JJblN0YXRlbWVudDogZnVuY3Rpb24obGVmdCwgcmlnaHQsIGJvZHkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5Gb3JJblN0YXRlbWVudCxcbiAgICAgICAgICAgIGxlZnQ6IGxlZnQsXG4gICAgICAgICAgICByaWdodDogcmlnaHQsXG4gICAgICAgICAgICBib2R5OiBib2R5LFxuICAgICAgICAgICAgZWFjaDogZmFsc2VcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSBmb3IuLm9mIHN0YXRlbWVudFxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gbGVmdCBUaGUgbGVmdC1zaWRlIHZhcmlhYmxlIGZvciB0aGUgcHJvcGVydHkgdmFsdWVcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IHJpZ2h0IFRoZSByaWdodC1zaWRlIG9iamVjdFxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gYm9keSBUaGUgc3RhdGVtZW50IGJvZHlcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgYSBmb3IuLm9mIHN0YXRlbWVudFxuICAgICAqL1xuICAgIGNyZWF0ZUZvck9mU3RhdGVtZW50OiBmdW5jdGlvbihsZWZ0LCByaWdodCwgYm9keSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLkZvck9mU3RhdGVtZW50LFxuICAgICAgICAgICAgbGVmdDogbGVmdCxcbiAgICAgICAgICAgIHJpZ2h0OiByaWdodCxcbiAgICAgICAgICAgIGJvZHk6IGJvZHlcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSBmdW5jdGlvbiBkZWNsYXJhdGlvblxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gaWQgVGhlIGZ1bmN0aW9uIG5hbWVcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IHBhcmFtcyBUaGUgZnVuY3Rpb24gYXJndW1lbnRzXG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSBib2R5IFRoZSBmdW5jdGlvbiBib2R5XG4gICAgICogQHBhcmFtIHtib29sZWFufSBnZW5lcmF0b3IgVHJ1ZSBpZiB0aGUgZnVuY3Rpb24gaXMgYSBnZW5lcmF0b3IsIGZhbHNlIGlmIG5vdC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGV4cHJlc3Npb24gVHJ1ZSBpZiB0aGUgZnVuY3Rpb24gaXMgY3JlYXRlZCB2aWEgYW4gZXhwcmVzc2lvbi5cbiAgICAgKiAgICAgIEFsd2F5cyBmYWxzZSBmb3IgZGVjbGFyYXRpb25zLCBidXQga2VwdCBoZXJlIHRvIGJlIGluIHN5bmMgd2l0aFxuICAgICAqICAgICAgRnVuY3Rpb25FeHByZXNzaW9uIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge0FTVE5vZGV9IEFuIEFTVE5vZGUgcmVwcmVzZW50aW5nIGEgZnVuY3Rpb24gZGVjbGFyYXRpb25cbiAgICAgKi9cbiAgICBjcmVhdGVGdW5jdGlvbkRlY2xhcmF0aW9uOiBmdW5jdGlvbiAoaWQsIHBhcmFtcywgYm9keSwgZ2VuZXJhdG9yLCBleHByZXNzaW9uKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuRnVuY3Rpb25EZWNsYXJhdGlvbixcbiAgICAgICAgICAgIGlkOiBpZCxcbiAgICAgICAgICAgIHBhcmFtczogcGFyYW1zIHx8IFtdLFxuICAgICAgICAgICAgYm9keTogYm9keSxcbiAgICAgICAgICAgIGdlbmVyYXRvcjogISFnZW5lcmF0b3IsXG4gICAgICAgICAgICBleHByZXNzaW9uOiAhIWV4cHJlc3Npb25cbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSBmdW5jdGlvbiBleHByZXNzaW9uXG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSBpZCBUaGUgZnVuY3Rpb24gbmFtZVxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gcGFyYW1zIFRoZSBmdW5jdGlvbiBhcmd1bWVudHNcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGJvZHkgVGhlIGZ1bmN0aW9uIGJvZHlcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGdlbmVyYXRvciBUcnVlIGlmIHRoZSBmdW5jdGlvbiBpcyBhIGdlbmVyYXRvciwgZmFsc2UgaWYgbm90LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZXhwcmVzc2lvbiBUcnVlIGlmIHRoZSBmdW5jdGlvbiBpcyBjcmVhdGVkIHZpYSBhbiBleHByZXNzaW9uLlxuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyBhIGZ1bmN0aW9uIGRlY2xhcmF0aW9uXG4gICAgICovXG4gICAgY3JlYXRlRnVuY3Rpb25FeHByZXNzaW9uOiBmdW5jdGlvbiAoaWQsIHBhcmFtcywgYm9keSwgZ2VuZXJhdG9yLCBleHByZXNzaW9uKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuRnVuY3Rpb25FeHByZXNzaW9uLFxuICAgICAgICAgICAgaWQ6IGlkLFxuICAgICAgICAgICAgcGFyYW1zOiBwYXJhbXMgfHwgW10sXG4gICAgICAgICAgICBib2R5OiBib2R5LFxuICAgICAgICAgICAgZ2VuZXJhdG9yOiAhIWdlbmVyYXRvcixcbiAgICAgICAgICAgIGV4cHJlc3Npb246ICEhZXhwcmVzc2lvblxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhbiBpZGVudGlmaWVyXG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSBuYW1lIFRoZSBpZGVudGlmaWVyIG5hbWVcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgYW4gaWRlbnRpZmllclxuICAgICAqL1xuICAgIGNyZWF0ZUlkZW50aWZpZXI6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5JZGVudGlmaWVyLFxuICAgICAgICAgICAgbmFtZTogbmFtZVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhbiBpZiBzdGF0ZW1lbnRcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IHRlc3QgVGhlIGlmIGNvbmRpdGlvbmFsIGV4cHJlc3Npb25cbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGNvbnNlcXVlbnQgVGhlIGNvbnNlcXVlbnQgaWYgc3RhdGVtZW50IHRvIHJ1blxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gYWx0ZXJuYXRlIHRoZSBcImVsc2VcIiBhbHRlcm5hdGUgc3RhdGVtZW50XG4gICAgICogQHJldHVybnMge0FTVE5vZGV9IEFuIEFTVE5vZGUgcmVwcmVzZW50aW5nIGFuIGlmIHN0YXRlbWVudFxuICAgICAqL1xuICAgIGNyZWF0ZUlmU3RhdGVtZW50OiBmdW5jdGlvbih0ZXN0LCBjb25zZXF1ZW50LCBhbHRlcm5hdGUpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5JZlN0YXRlbWVudCxcbiAgICAgICAgICAgIHRlc3Q6IHRlc3QsXG4gICAgICAgICAgICBjb25zZXF1ZW50OiBjb25zZXF1ZW50LFxuICAgICAgICAgICAgYWx0ZXJuYXRlOiBhbHRlcm5hdGVcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSBsYWJlbGVkIHN0YXRlbWVudFxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gbGFiZWwgVGhlIHN0YXRlbWVudCBsYWJlbFxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gYm9keSBUaGUgbGFiZWxlZCBzdGF0ZW1lbnQgYm9keVxuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyBhIGxhYmVsZWQgc3RhdGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlTGFiZWxlZFN0YXRlbWVudDogZnVuY3Rpb24obGFiZWwsIGJvZHkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5MYWJlbGVkU3RhdGVtZW50LFxuICAgICAgICAgICAgbGFiZWw6IGxhYmVsLFxuICAgICAgICAgICAgYm9keTogYm9keVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSBsaXRlcmFsIGZyb20gdGhlIHNvdXJjZSBjb2RlXG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSB0b2tlbiBUaGUgQVNUTm9kZSB0b2tlblxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgVGhlIHNvdXJjZSBjb2RlIHRvIGdldCB0aGUgbGl0ZXJhbCBmcm9tXG4gICAgICogQHJldHVybnMge0FTVE5vZGV9IEFuIEFTVE5vZGUgcmVwcmVzZW50aW5nIHRoZSBuZXcgbGl0ZXJhbFxuICAgICAqL1xuICAgIGNyZWF0ZUxpdGVyYWxGcm9tU291cmNlOiBmdW5jdGlvbih0b2tlbiwgc291cmNlKSB7XG4gICAgICAgIHZhciBub2RlID0ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLkxpdGVyYWwsXG4gICAgICAgICAgICB2YWx1ZTogdG9rZW4udmFsdWUsXG4gICAgICAgICAgICByYXc6IHNvdXJjZS5zbGljZSh0b2tlbi5yYW5nZVswXSwgdG9rZW4ucmFuZ2VbMV0pXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gcmVndWxhciBleHByZXNzaW9ucyBoYXZlIHJlZ2V4IHByb3BlcnRpZXNcbiAgICAgICAgaWYgKHRva2VuLnJlZ2V4KSB7XG4gICAgICAgICAgICBub2RlLnJlZ2V4ID0gdG9rZW4ucmVnZXg7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgdGVtcGxhdGUgZWxlbWVudFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSB2YWx1ZSBEYXRhIG9uIHRoZSBlbGVtZW50IHZhbHVlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlLnJhdyBUaGUgcmF3IHRlbXBsYXRlIHN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZS5jb29rZWQgVGhlIHByb2Nlc3NlZCB0ZW1wbGF0ZSBzdHJpbmdcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHRhaWwgVHJ1ZSBpZiB0aGlzIGlzIHRoZSBmaW5hbCBlbGVtZW50IGluIGEgdGVtcGxhdGUgc3RyaW5nXG4gICAgICogQHJldHVybnMge0FTVE5vZGV9IEFuIEFTVE5vZGUgcmVwcmVzZW50aW5nIHRoZSB0ZW1wbGF0ZSBzdHJpbmcgZWxlbWVudFxuICAgICAqL1xuICAgIGNyZWF0ZVRlbXBsYXRlRWxlbWVudDogZnVuY3Rpb24odmFsdWUsIHRhaWwpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5UZW1wbGF0ZUVsZW1lbnQsXG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICB0YWlsOiB0YWlsXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhbiBBU1ROb2RlIHRlbXBsYXRlIGxpdGVyYWxcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGVbXX0gcXVhc2lzIEFuIGFycmF5IG9mIHRoZSB0ZW1wbGF0ZSBzdHJpbmcgZWxlbWVudHNcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGVbXX0gZXhwcmVzc2lvbnMgQW4gYXJyYXkgb2YgdGhlIHRlbXBsYXRlIHN0cmluZyBleHByZXNzaW9uc1xuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyB0aGUgdGVtcGxhdGUgc3RyaW5nXG4gICAgICovXG4gICAgY3JlYXRlVGVtcGxhdGVMaXRlcmFsOiBmdW5jdGlvbihxdWFzaXMsIGV4cHJlc3Npb25zKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuVGVtcGxhdGVMaXRlcmFsLFxuICAgICAgICAgICAgcXVhc2lzOiBxdWFzaXMsXG4gICAgICAgICAgICBleHByZXNzaW9uczogZXhwcmVzc2lvbnNcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSBzcHJlYWQgZWxlbWVudFxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gYXJndW1lbnQgVGhlIGFycmF5IGJlaW5nIHNwcmVhZFxuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyBhIHNwcmVhZCBlbGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlU3ByZWFkRWxlbWVudDogZnVuY3Rpb24oYXJndW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5TcHJlYWRFbGVtZW50LFxuICAgICAgICAgICAgYXJndW1lbnQ6IGFyZ3VtZW50XG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhbiBBU1ROb2RlIHRhZ2dlZCB0ZW1wbGF0ZSBleHByZXNzaW9uXG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSB0YWcgVGhlIHRhZyBleHByZXNzaW9uXG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSBxdWFzaSBBIFRlbXBsYXRlTGl0ZXJhbCBBU1ROb2RlIHJlcHJlc2VudGluZ1xuICAgICAqIHRoZSB0ZW1wbGF0ZSBzdHJpbmcgaXRzZWxmLlxuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyB0aGUgdGFnZ2VkIHRlbXBsYXRlXG4gICAgICovXG4gICAgY3JlYXRlVGFnZ2VkVGVtcGxhdGVFeHByZXNzaW9uOiBmdW5jdGlvbih0YWcsIHF1YXNpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuVGFnZ2VkVGVtcGxhdGVFeHByZXNzaW9uLFxuICAgICAgICAgICAgdGFnOiB0YWcsXG4gICAgICAgICAgICBxdWFzaTogcXVhc2lcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSBtZW1iZXIgZXhwcmVzc2lvblxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhY2Nlc3NvciBUaGUgbWVtYmVyIGFjY2VzcyBtZXRob2QgKGJyYWNrZXQgb3IgcGVyaW9kKVxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gb2JqZWN0IFRoZSBvYmplY3QgYmVpbmcgcmVmZXJlbmNlZFxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gcHJvcGVydHkgVGhlIG9iamVjdC1wcm9wZXJ0eSBiZWluZyByZWZlcmVuY2VkXG4gICAgICogQHJldHVybnMge0FTVE5vZGV9IEFuIEFTVE5vZGUgcmVwcmVzZW50aW5nIGEgbWVtYmVyIGV4cHJlc3Npb25cbiAgICAgKi9cbiAgICBjcmVhdGVNZW1iZXJFeHByZXNzaW9uOiBmdW5jdGlvbihhY2Nlc3Nvciwgb2JqZWN0LCBwcm9wZXJ0eSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLk1lbWJlckV4cHJlc3Npb24sXG4gICAgICAgICAgICBjb21wdXRlZDogYWNjZXNzb3IgPT09IFwiW1wiLFxuICAgICAgICAgICAgb2JqZWN0OiBvYmplY3QsXG4gICAgICAgICAgICBwcm9wZXJ0eTogcHJvcGVydHlcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSBuZXcgZXhwcmVzc2lvblxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gY2FsbGVlIFRoZSBjb25zdHJ1Y3RvciBmb3IgdGhlIG5ldyBvYmplY3QgdHlwZVxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gYXJncyBUaGUgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgY29uc3RydWN0b3JcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgYSBuZXcgZXhwcmVzc2lvblxuICAgICAqL1xuICAgIGNyZWF0ZU5ld0V4cHJlc3Npb246IGZ1bmN0aW9uKGNhbGxlZSwgYXJncykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLk5ld0V4cHJlc3Npb24sXG4gICAgICAgICAgICBjYWxsZWU6IGNhbGxlZSxcbiAgICAgICAgICAgIFwiYXJndW1lbnRzXCI6IGFyZ3NcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSBuZXcgb2JqZWN0IGV4cHJlc3Npb25cbiAgICAgKiBAcGFyYW0ge0FTVE5vZGVbXX0gcHJvcGVydGllcyBBbiBhcnJheSBvZiBBU1ROb2RlcyB0aGF0IHJlcHJlc2VudCBhbGwgb2JqZWN0XG4gICAgICogICAgICBwcm9wZXJ0aWVzIGFuZCBhc3NvY2lhdGVkIHZhbHVlc1xuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyBhIG5ldyBvYmplY3QgZXhwcmVzc2lvblxuICAgICAqL1xuICAgIGNyZWF0ZU9iamVjdEV4cHJlc3Npb246IGZ1bmN0aW9uKHByb3BlcnRpZXMpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5PYmplY3RFeHByZXNzaW9uLFxuICAgICAgICAgICAgcHJvcGVydGllczogcHJvcGVydGllc1xuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhIHBvc3RmaXggZXhwcmVzc2lvblxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvcGVyYXRvciBUaGUgcG9zdGZpeCBvcGVyYXRvciAoXCIrK1wiLCBcIi0tXCIsIGV0Yy4pXG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSBhcmd1bWVudCBUaGUgb3BlcmF0b3IgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgYSBwb3N0Zml4IGV4cHJlc3Npb25cbiAgICAgKi9cbiAgICBjcmVhdGVQb3N0Zml4RXhwcmVzc2lvbjogZnVuY3Rpb24ob3BlcmF0b3IsIGFyZ3VtZW50KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuVXBkYXRlRXhwcmVzc2lvbixcbiAgICAgICAgICAgIG9wZXJhdG9yOiBvcGVyYXRvcixcbiAgICAgICAgICAgIGFyZ3VtZW50OiBhcmd1bWVudCxcbiAgICAgICAgICAgIHByZWZpeDogZmFsc2VcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYW4gZW50aXJlIHByb2dyYW1cbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGJvZHkgVGhlIHByb2dyYW0gYm9keVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2VUeXBlIEVpdGhlciBcIm1vZHVsZVwiIG9yIFwic2NyaXB0XCIuXG4gICAgICogQHJldHVybnMge0FTVE5vZGV9IEFuIEFTVE5vZGUgcmVwcmVzZW50aW5nIGFuIGVudGlyZSBwcm9ncmFtXG4gICAgICovXG4gICAgY3JlYXRlUHJvZ3JhbTogZnVuY3Rpb24oYm9keSwgc291cmNlVHlwZSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLlByb2dyYW0sXG4gICAgICAgICAgICBib2R5OiBib2R5LFxuICAgICAgICAgICAgc291cmNlVHlwZTogc291cmNlVHlwZVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhbiBvYmplY3QgcHJvcGVydHlcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2luZCBUaGUgdHlwZSBvZiBwcm9wZXJ0eSByZXByZXNlbnRlZCAoXCJnZXRcIiwgXCJzZXRcIiwgZXRjLilcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGtleSBUaGUgcHJvcGVydHkga2V5XG4gICAgICogQHBhcmFtIHtBU1ROb2RlfSB2YWx1ZSBUaGUgbmV3IHByb3BlcnR5IHZhbHVlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBtZXRob2QgVHJ1ZSBpZiB0aGUgcHJvcGVydHkgaXMgYWxzbyBhIG1ldGhvZCAodmFsdWUgaXMgYSBmdW5jdGlvbilcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHNob3J0aGFuZCBUcnVlIGlmIHRoZSBwcm9wZXJ0eSBpcyBzaG9ydGhhbmRcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGNvbXB1dGVkIFRydWUgaWYgdGhlIHByb3BlcnR5IHZhbHVlIGhhcyBiZWVuIGNvbXB1dGVkXG4gICAgICogQHJldHVybnMge0FTVE5vZGV9IEFuIEFTVE5vZGUgcmVwcmVzZW50aW5nIGFuIG9iamVjdCBwcm9wZXJ0eVxuICAgICAqL1xuICAgIGNyZWF0ZVByb3BlcnR5OiBmdW5jdGlvbihraW5kLCBrZXksIHZhbHVlLCBtZXRob2QsIHNob3J0aGFuZCwgY29tcHV0ZWQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5Qcm9wZXJ0eSxcbiAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAga2luZDoga2luZCxcbiAgICAgICAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgICAgICAgc2hvcnRoYW5kOiBzaG9ydGhhbmQsXG4gICAgICAgICAgICBjb21wdXRlZDogY29tcHV0ZWRcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSByZXN0IGVsZW1lbnRcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGFyZ3VtZW50IFRoZSByZXN0IGFyZ3VtZW50XG4gICAgICogQHJldHVybnMge0FTVE5vZGV9IEFuIEFTVE5vZGUgcmVwcmVzZW50aW5nIGEgcmVzdCBlbGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlUmVzdEVsZW1lbnQ6IGZ1bmN0aW9uIChhcmd1bWVudCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLlJlc3RFbGVtZW50LFxuICAgICAgICAgICAgYXJndW1lbnQ6IGFyZ3VtZW50XG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhbiBBU1ROb2RlIHJlcHJlc2VudGF0aW9uIG9mIGEgcmV0dXJuIHN0YXRlbWVudFxuICAgICAqIEBwYXJhbSB7P0FTVE5vZGV9IGFyZ3VtZW50IFRoZSByZXR1cm4gYXJndW1lbnQsIG51bGwgaWYgbm8gYXJndW1lbnQgaXMgcHJvdmlkZWRcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgYSByZXR1cm4gc3RhdGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlUmV0dXJuU3RhdGVtZW50OiBmdW5jdGlvbihhcmd1bWVudCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLlJldHVyblN0YXRlbWVudCxcbiAgICAgICAgICAgIGFyZ3VtZW50OiBhcmd1bWVudFxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhIHNlcXVlbmNlIG9mIGV4cHJlc3Npb25zXG4gICAgICogQHBhcmFtIHtBU1ROb2RlW119IGV4cHJlc3Npb25zIEFuIGFycmF5IGNvbnRhaW5pbmcgZWFjaCBleHByZXNzaW9uLCBpbiBvcmRlclxuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyBhIHNlcXVlbmNlIG9mIGV4cHJlc3Npb25zXG4gICAgICovXG4gICAgY3JlYXRlU2VxdWVuY2VFeHByZXNzaW9uOiBmdW5jdGlvbihleHByZXNzaW9ucykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLlNlcXVlbmNlRXhwcmVzc2lvbixcbiAgICAgICAgICAgIGV4cHJlc3Npb25zOiBleHByZXNzaW9uc1xuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBzdXBlclxuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyBzdXBlclxuICAgICAqL1xuICAgIGNyZWF0ZVN1cGVyOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5TdXBlclxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhIHN3aXRjaCBjYXNlIHN0YXRlbWVudFxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gdGVzdCBUaGUgY2FzZSB2YWx1ZSB0byB0ZXN0IGFnYWluc3QgdGhlIHN3aXRjaCB2YWx1ZVxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gY29uc2VxdWVudCBUaGUgY29uc2VxdWVudCBjYXNlIHN0YXRlbWVudFxuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyBhIHN3aXRjaCBjYXNlXG4gICAgICovXG4gICAgY3JlYXRlU3dpdGNoQ2FzZTogZnVuY3Rpb24odGVzdCwgY29uc2VxdWVudCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLlN3aXRjaENhc2UsXG4gICAgICAgICAgICB0ZXN0OiB0ZXN0LFxuICAgICAgICAgICAgY29uc2VxdWVudDogY29uc2VxdWVudFxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhIHN3aXRjaCBzdGF0ZW1lbnRcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGRpc2NyaW1pbmFudCBBbiBleHByZXNzaW9uIHRvIHRlc3QgYWdhaW5zdCBlYWNoIGNhc2UgdmFsdWVcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGVbXX0gY2FzZXMgQW4gYXJyYXkgb2Ygc3dpdGNoIGNhc2Ugc3RhdGVtZW50c1xuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyBhIHN3aXRjaCBzdGF0ZW1lbnRcbiAgICAgKi9cbiAgICBjcmVhdGVTd2l0Y2hTdGF0ZW1lbnQ6IGZ1bmN0aW9uKGRpc2NyaW1pbmFudCwgY2FzZXMpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5Td2l0Y2hTdGF0ZW1lbnQsXG4gICAgICAgICAgICBkaXNjcmltaW5hbnQ6IGRpc2NyaW1pbmFudCxcbiAgICAgICAgICAgIGNhc2VzOiBjYXNlc1xuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhIHRoaXMgc3RhdGVtZW50XG4gICAgICogQHJldHVybnMge0FTVE5vZGV9IEFuIEFTVE5vZGUgcmVwcmVzZW50aW5nIGEgdGhpcyBzdGF0ZW1lbnRcbiAgICAgKi9cbiAgICBjcmVhdGVUaGlzRXhwcmVzc2lvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuVGhpc0V4cHJlc3Npb25cbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSB0aHJvdyBzdGF0ZW1lbnRcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGFyZ3VtZW50IFRoZSBhcmd1bWVudCB0byB0aHJvd1xuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyBhIHRocm93IHN0YXRlbWVudFxuICAgICAqL1xuICAgIGNyZWF0ZVRocm93U3RhdGVtZW50OiBmdW5jdGlvbihhcmd1bWVudCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLlRocm93U3RhdGVtZW50LFxuICAgICAgICAgICAgYXJndW1lbnQ6IGFyZ3VtZW50XG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhbiBBU1ROb2RlIHJlcHJlc2VudGF0aW9uIG9mIGEgdHJ5IHN0YXRlbWVudFxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gYmxvY2sgVGhlIHRyeSBibG9ja1xuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gaGFuZGxlciBBIGNhdGNoIGhhbmRsZXJcbiAgICAgKiBAcGFyYW0gez9BU1ROb2RlfSBmaW5hbGl6ZXIgVGhlIGZpbmFsIGNvZGUgYmxvY2sgdG8gcnVuIGFmdGVyIHRoZSB0cnkvY2F0Y2ggaGFzIHJ1blxuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyBhIHRyeSBzdGF0ZW1lbnRcbiAgICAgKi9cbiAgICBjcmVhdGVUcnlTdGF0ZW1lbnQ6IGZ1bmN0aW9uKGJsb2NrLCBoYW5kbGVyLCBmaW5hbGl6ZXIpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5UcnlTdGF0ZW1lbnQsXG4gICAgICAgICAgICBibG9jazogYmxvY2ssXG4gICAgICAgICAgICBoYW5kbGVyOiBoYW5kbGVyLFxuICAgICAgICAgICAgZmluYWxpemVyOiBmaW5hbGl6ZXJcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIEFTVE5vZGUgcmVwcmVzZW50YXRpb24gb2YgYSB1bmFyeSBleHByZXNzaW9uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG9wZXJhdG9yIFRoZSB1bmFyeSBvcGVyYXRvclxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gYXJndW1lbnQgVGhlIHVuYXJ5IG9wZXJhbmRcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgYSB1bmFyeSBleHByZXNzaW9uXG4gICAgICovXG4gICAgY3JlYXRlVW5hcnlFeHByZXNzaW9uOiBmdW5jdGlvbihvcGVyYXRvciwgYXJndW1lbnQpIHtcbiAgICAgICAgaWYgKG9wZXJhdG9yID09PSBcIisrXCIgfHwgb3BlcmF0b3IgPT09IFwiLS1cIikge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuVXBkYXRlRXhwcmVzc2lvbixcbiAgICAgICAgICAgICAgICBvcGVyYXRvcjogb3BlcmF0b3IsXG4gICAgICAgICAgICAgICAgYXJndW1lbnQ6IGFyZ3VtZW50LFxuICAgICAgICAgICAgICAgIHByZWZpeDogdHJ1ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLlVuYXJ5RXhwcmVzc2lvbixcbiAgICAgICAgICAgIG9wZXJhdG9yOiBvcGVyYXRvcixcbiAgICAgICAgICAgIGFyZ3VtZW50OiBhcmd1bWVudCxcbiAgICAgICAgICAgIHByZWZpeDogdHJ1ZVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhIHZhcmlhYmxlIGRlY2xhcmF0aW9uXG4gICAgICogQHBhcmFtIHtBU1ROb2RlW119IGRlY2xhcmF0aW9ucyBBbiBhcnJheSBvZiB2YXJpYWJsZSBkZWNsYXJhdGlvbnNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2luZCBUaGUga2luZCBvZiB2YXJpYWJsZSBjcmVhdGVkIChcInZhclwiLCBcImxldFwiLCBldGMuKVxuICAgICAqIEByZXR1cm5zIHtBU1ROb2RlfSBBbiBBU1ROb2RlIHJlcHJlc2VudGluZyBhIHZhcmlhYmxlIGRlY2xhcmF0aW9uXG4gICAgICovXG4gICAgY3JlYXRlVmFyaWFibGVEZWNsYXJhdGlvbjogZnVuY3Rpb24oZGVjbGFyYXRpb25zLCBraW5kKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuVmFyaWFibGVEZWNsYXJhdGlvbixcbiAgICAgICAgICAgIGRlY2xhcmF0aW9uczogZGVjbGFyYXRpb25zLFxuICAgICAgICAgICAga2luZDoga2luZFxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gQVNUTm9kZSByZXByZXNlbnRhdGlvbiBvZiBhIHZhcmlhYmxlIGRlY2xhcmF0b3JcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGlkIFRoZSB2YXJpYWJsZSBJRFxuICAgICAqIEBwYXJhbSB7QVNUTm9kZX0gaW5pdCBUaGUgdmFyaWFibGUncyBpbml0aWFsIHZhbHVlXG4gICAgICogQHJldHVybnMge0FTVE5vZGV9IEFuIEFTVE5vZGUgcmVwcmVzZW50aW5nIGEgdmFyaWFibGUgZGVjbGFyYXRvclxuICAgICAqL1xuICAgIGNyZWF0ZVZhcmlhYmxlRGVjbGFyYXRvcjogZnVuY3Rpb24oaWQsIGluaXQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5WYXJpYWJsZURlY2xhcmF0b3IsXG4gICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICBpbml0OiBpbml0XG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhbiBBU1ROb2RlIHJlcHJlc2VudGF0aW9uIG9mIGEgd2l0aCBzdGF0ZW1lbnRcbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IG9iamVjdCBUaGUgd2l0aCBzdGF0ZW1lbnQgb2JqZWN0IGV4cHJlc3Npb25cbiAgICAgKiBAcGFyYW0ge0FTVE5vZGV9IGJvZHkgVGhlIHdpdGggc3RhdGVtZW50IGJvZHlcbiAgICAgKiBAcmV0dXJucyB7QVNUTm9kZX0gQW4gQVNUTm9kZSByZXByZXNlbnRpbmcgYSB3aXRoIHN0YXRlbWVudFxuICAgICAqL1xuICAgIGNyZWF0ZVdpdGhTdGF0ZW1lbnQ6IGZ1bmN0aW9uKG9iamVjdCwgYm9keSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLldpdGhTdGF0ZW1lbnQsXG4gICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgICAgIGJvZHk6IGJvZHlcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgY3JlYXRlWWllbGRFeHByZXNzaW9uOiBmdW5jdGlvbihhcmd1bWVudCwgZGVsZWdhdGUpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5ZaWVsZEV4cHJlc3Npb24sXG4gICAgICAgICAgICBhcmd1bWVudDogYXJndW1lbnQgfHwgbnVsbCxcbiAgICAgICAgICAgIGRlbGVnYXRlOiBkZWxlZ2F0ZVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBjcmVhdGVKU1hBdHRyaWJ1dGU6IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuSlNYQXR0cmlidXRlLFxuICAgICAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSB8fCBudWxsXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGNyZWF0ZUpTWFNwcmVhZEF0dHJpYnV0ZTogZnVuY3Rpb24oYXJndW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5KU1hTcHJlYWRBdHRyaWJ1dGUsXG4gICAgICAgICAgICBhcmd1bWVudDogYXJndW1lbnRcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgY3JlYXRlSlNYSWRlbnRpZmllcjogZnVuY3Rpb24obmFtZSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLkpTWElkZW50aWZpZXIsXG4gICAgICAgICAgICBuYW1lOiBuYW1lXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGNyZWF0ZUpTWE5hbWVzcGFjZWROYW1lOiBmdW5jdGlvbihuYW1lc3BhY2UsIG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5KU1hOYW1lc3BhY2VkTmFtZSxcbiAgICAgICAgICAgIG5hbWVzcGFjZTogbmFtZXNwYWNlLFxuICAgICAgICAgICAgbmFtZTogbmFtZVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBjcmVhdGVKU1hNZW1iZXJFeHByZXNzaW9uOiBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuSlNYTWVtYmVyRXhwcmVzc2lvbixcbiAgICAgICAgICAgIG9iamVjdDogb2JqZWN0LFxuICAgICAgICAgICAgcHJvcGVydHk6IHByb3BlcnR5XG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGNyZWF0ZUpTWEVsZW1lbnQ6IGZ1bmN0aW9uKG9wZW5pbmdFbGVtZW50LCBjbG9zaW5nRWxlbWVudCwgY2hpbGRyZW4pIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5KU1hFbGVtZW50LFxuICAgICAgICAgICAgb3BlbmluZ0VsZW1lbnQ6IG9wZW5pbmdFbGVtZW50LFxuICAgICAgICAgICAgY2xvc2luZ0VsZW1lbnQ6IGNsb3NpbmdFbGVtZW50LFxuICAgICAgICAgICAgY2hpbGRyZW46IGNoaWxkcmVuXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGNyZWF0ZUpTWEVtcHR5RXhwcmVzc2lvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuSlNYRW1wdHlFeHByZXNzaW9uXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGNyZWF0ZUpTWEV4cHJlc3Npb25Db250YWluZXI6IGZ1bmN0aW9uKGV4cHJlc3Npb24pIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5KU1hFeHByZXNzaW9uQ29udGFpbmVyLFxuICAgICAgICAgICAgZXhwcmVzc2lvbjogZXhwcmVzc2lvblxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBjcmVhdGVKU1hPcGVuaW5nRWxlbWVudDogZnVuY3Rpb24obmFtZSwgYXR0cmlidXRlcywgc2VsZkNsb3NpbmcpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5KU1hPcGVuaW5nRWxlbWVudCxcbiAgICAgICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgICAgICBzZWxmQ2xvc2luZzogc2VsZkNsb3NpbmcsXG4gICAgICAgICAgICBhdHRyaWJ1dGVzOiBhdHRyaWJ1dGVzXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGNyZWF0ZUpTWENsb3NpbmdFbGVtZW50OiBmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuSlNYQ2xvc2luZ0VsZW1lbnQsXG4gICAgICAgICAgICBuYW1lOiBuYW1lXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGNyZWF0ZUV4cG9ydFNwZWNpZmllcjogZnVuY3Rpb24obG9jYWwsIGV4cG9ydGVkKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuRXhwb3J0U3BlY2lmaWVyLFxuICAgICAgICAgICAgZXhwb3J0ZWQ6IGV4cG9ydGVkIHx8IGxvY2FsLFxuICAgICAgICAgICAgbG9jYWw6IGxvY2FsXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGNyZWF0ZUltcG9ydERlZmF1bHRTcGVjaWZpZXI6IGZ1bmN0aW9uKGxvY2FsKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuSW1wb3J0RGVmYXVsdFNwZWNpZmllcixcbiAgICAgICAgICAgIGxvY2FsOiBsb2NhbFxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBjcmVhdGVJbXBvcnROYW1lc3BhY2VTcGVjaWZpZXI6IGZ1bmN0aW9uKGxvY2FsKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBhc3ROb2RlVHlwZXMuSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyLFxuICAgICAgICAgICAgbG9jYWw6IGxvY2FsXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGNyZWF0ZUV4cG9ydE5hbWVkRGVjbGFyYXRpb246IGZ1bmN0aW9uKGRlY2xhcmF0aW9uLCBzcGVjaWZpZXJzLCBzb3VyY2UpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5FeHBvcnROYW1lZERlY2xhcmF0aW9uLFxuICAgICAgICAgICAgZGVjbGFyYXRpb246IGRlY2xhcmF0aW9uLFxuICAgICAgICAgICAgc3BlY2lmaWVyczogc3BlY2lmaWVycyxcbiAgICAgICAgICAgIHNvdXJjZTogc291cmNlXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGNyZWF0ZUV4cG9ydERlZmF1bHREZWNsYXJhdGlvbjogZnVuY3Rpb24oZGVjbGFyYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5FeHBvcnREZWZhdWx0RGVjbGFyYXRpb24sXG4gICAgICAgICAgICBkZWNsYXJhdGlvbjogZGVjbGFyYXRpb25cbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgY3JlYXRlRXhwb3J0QWxsRGVjbGFyYXRpb246IGZ1bmN0aW9uKHNvdXJjZSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLkV4cG9ydEFsbERlY2xhcmF0aW9uLFxuICAgICAgICAgICAgc291cmNlOiBzb3VyY2VcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgY3JlYXRlSW1wb3J0U3BlY2lmaWVyOiBmdW5jdGlvbihsb2NhbCwgaW1wb3J0ZWQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IGFzdE5vZGVUeXBlcy5JbXBvcnRTcGVjaWZpZXIsXG4gICAgICAgICAgICBsb2NhbDogbG9jYWwgfHwgaW1wb3J0ZWQsXG4gICAgICAgICAgICBpbXBvcnRlZDogaW1wb3J0ZWRcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgY3JlYXRlSW1wb3J0RGVjbGFyYXRpb246IGZ1bmN0aW9uKHNwZWNpZmllcnMsIHNvdXJjZSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogYXN0Tm9kZVR5cGVzLkltcG9ydERlY2xhcmF0aW9uLFxuICAgICAgICAgICAgc3BlY2lmaWVyczogc3BlY2lmaWVycyxcbiAgICAgICAgICAgIHNvdXJjZTogc291cmNlXG4gICAgICAgIH07XG4gICAgfVxuXG59O1xuIiwiLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IFRoZSBBU1Qgbm9kZSB0eXBlcyBwcm9kdWNlZCBieSB0aGUgcGFyc2VyLlxuICogQGF1dGhvciBOaWNob2xhcyBDLiBaYWthc1xuICogQGNvcHlyaWdodCAyMDE0IE5pY2hvbGFzIEMuIFpha2FzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogQGNvcHlyaWdodCAyMDExLTIwMTMgQXJpeWEgSGlkYXlhdCA8YXJpeWEuaGlkYXlhdEBnbWFpbC5jb20+XG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gKiAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAqICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuICogICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuICogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxuICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcbiAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxuICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuICogVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJlcXVpcmVtZW50c1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gTm9uZSFcblxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFB1YmxpY1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgQXNzaWdubWVudEV4cHJlc3Npb246IFwiQXNzaWdubWVudEV4cHJlc3Npb25cIixcbiAgICBBc3NpZ25tZW50UGF0dGVybjogXCJBc3NpZ25tZW50UGF0dGVyblwiLFxuICAgIEFycmF5RXhwcmVzc2lvbjogXCJBcnJheUV4cHJlc3Npb25cIixcbiAgICBBcnJheVBhdHRlcm46IFwiQXJyYXlQYXR0ZXJuXCIsXG4gICAgQXJyb3dGdW5jdGlvbkV4cHJlc3Npb246IFwiQXJyb3dGdW5jdGlvbkV4cHJlc3Npb25cIixcbiAgICBCbG9ja1N0YXRlbWVudDogXCJCbG9ja1N0YXRlbWVudFwiLFxuICAgIEJpbmFyeUV4cHJlc3Npb246IFwiQmluYXJ5RXhwcmVzc2lvblwiLFxuICAgIEJyZWFrU3RhdGVtZW50OiBcIkJyZWFrU3RhdGVtZW50XCIsXG4gICAgQ2FsbEV4cHJlc3Npb246IFwiQ2FsbEV4cHJlc3Npb25cIixcbiAgICBDYXRjaENsYXVzZTogXCJDYXRjaENsYXVzZVwiLFxuICAgIENsYXNzQm9keTogXCJDbGFzc0JvZHlcIixcbiAgICBDbGFzc0RlY2xhcmF0aW9uOiBcIkNsYXNzRGVjbGFyYXRpb25cIixcbiAgICBDbGFzc0V4cHJlc3Npb246IFwiQ2xhc3NFeHByZXNzaW9uXCIsXG4gICAgQ29uZGl0aW9uYWxFeHByZXNzaW9uOiBcIkNvbmRpdGlvbmFsRXhwcmVzc2lvblwiLFxuICAgIENvbnRpbnVlU3RhdGVtZW50OiBcIkNvbnRpbnVlU3RhdGVtZW50XCIsXG4gICAgRG9XaGlsZVN0YXRlbWVudDogXCJEb1doaWxlU3RhdGVtZW50XCIsXG4gICAgRGVidWdnZXJTdGF0ZW1lbnQ6IFwiRGVidWdnZXJTdGF0ZW1lbnRcIixcbiAgICBFbXB0eVN0YXRlbWVudDogXCJFbXB0eVN0YXRlbWVudFwiLFxuICAgIEV4cHJlc3Npb25TdGF0ZW1lbnQ6IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiLFxuICAgIEZvclN0YXRlbWVudDogXCJGb3JTdGF0ZW1lbnRcIixcbiAgICBGb3JJblN0YXRlbWVudDogXCJGb3JJblN0YXRlbWVudFwiLFxuICAgIEZvck9mU3RhdGVtZW50OiBcIkZvck9mU3RhdGVtZW50XCIsXG4gICAgRnVuY3Rpb25EZWNsYXJhdGlvbjogXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCIsXG4gICAgRnVuY3Rpb25FeHByZXNzaW9uOiBcIkZ1bmN0aW9uRXhwcmVzc2lvblwiLFxuICAgIElkZW50aWZpZXI6IFwiSWRlbnRpZmllclwiLFxuICAgIElmU3RhdGVtZW50OiBcIklmU3RhdGVtZW50XCIsXG4gICAgTGl0ZXJhbDogXCJMaXRlcmFsXCIsXG4gICAgTGFiZWxlZFN0YXRlbWVudDogXCJMYWJlbGVkU3RhdGVtZW50XCIsXG4gICAgTG9naWNhbEV4cHJlc3Npb246IFwiTG9naWNhbEV4cHJlc3Npb25cIixcbiAgICBNZW1iZXJFeHByZXNzaW9uOiBcIk1lbWJlckV4cHJlc3Npb25cIixcbiAgICBNZXRob2REZWZpbml0aW9uOiBcIk1ldGhvZERlZmluaXRpb25cIixcbiAgICBOZXdFeHByZXNzaW9uOiBcIk5ld0V4cHJlc3Npb25cIixcbiAgICBPYmplY3RFeHByZXNzaW9uOiBcIk9iamVjdEV4cHJlc3Npb25cIixcbiAgICBPYmplY3RQYXR0ZXJuOiBcIk9iamVjdFBhdHRlcm5cIixcbiAgICBQcm9ncmFtOiBcIlByb2dyYW1cIixcbiAgICBQcm9wZXJ0eTogXCJQcm9wZXJ0eVwiLFxuICAgIFJlc3RFbGVtZW50OiBcIlJlc3RFbGVtZW50XCIsXG4gICAgUmV0dXJuU3RhdGVtZW50OiBcIlJldHVyblN0YXRlbWVudFwiLFxuICAgIFNlcXVlbmNlRXhwcmVzc2lvbjogXCJTZXF1ZW5jZUV4cHJlc3Npb25cIixcbiAgICBTcHJlYWRFbGVtZW50OiBcIlNwcmVhZEVsZW1lbnRcIixcbiAgICBTdXBlcjogXCJTdXBlclwiLFxuICAgIFN3aXRjaENhc2U6IFwiU3dpdGNoQ2FzZVwiLFxuICAgIFN3aXRjaFN0YXRlbWVudDogXCJTd2l0Y2hTdGF0ZW1lbnRcIixcbiAgICBUYWdnZWRUZW1wbGF0ZUV4cHJlc3Npb246IFwiVGFnZ2VkVGVtcGxhdGVFeHByZXNzaW9uXCIsXG4gICAgVGVtcGxhdGVFbGVtZW50OiBcIlRlbXBsYXRlRWxlbWVudFwiLFxuICAgIFRlbXBsYXRlTGl0ZXJhbDogXCJUZW1wbGF0ZUxpdGVyYWxcIixcbiAgICBUaGlzRXhwcmVzc2lvbjogXCJUaGlzRXhwcmVzc2lvblwiLFxuICAgIFRocm93U3RhdGVtZW50OiBcIlRocm93U3RhdGVtZW50XCIsXG4gICAgVHJ5U3RhdGVtZW50OiBcIlRyeVN0YXRlbWVudFwiLFxuICAgIFVuYXJ5RXhwcmVzc2lvbjogXCJVbmFyeUV4cHJlc3Npb25cIixcbiAgICBVcGRhdGVFeHByZXNzaW9uOiBcIlVwZGF0ZUV4cHJlc3Npb25cIixcbiAgICBWYXJpYWJsZURlY2xhcmF0aW9uOiBcIlZhcmlhYmxlRGVjbGFyYXRpb25cIixcbiAgICBWYXJpYWJsZURlY2xhcmF0b3I6IFwiVmFyaWFibGVEZWNsYXJhdG9yXCIsXG4gICAgV2hpbGVTdGF0ZW1lbnQ6IFwiV2hpbGVTdGF0ZW1lbnRcIixcbiAgICBXaXRoU3RhdGVtZW50OiBcIldpdGhTdGF0ZW1lbnRcIixcbiAgICBZaWVsZEV4cHJlc3Npb246IFwiWWllbGRFeHByZXNzaW9uXCIsXG4gICAgSlNYSWRlbnRpZmllcjogXCJKU1hJZGVudGlmaWVyXCIsXG4gICAgSlNYTmFtZXNwYWNlZE5hbWU6IFwiSlNYTmFtZXNwYWNlZE5hbWVcIixcbiAgICBKU1hNZW1iZXJFeHByZXNzaW9uOiBcIkpTWE1lbWJlckV4cHJlc3Npb25cIixcbiAgICBKU1hFbXB0eUV4cHJlc3Npb246IFwiSlNYRW1wdHlFeHByZXNzaW9uXCIsXG4gICAgSlNYRXhwcmVzc2lvbkNvbnRhaW5lcjogXCJKU1hFeHByZXNzaW9uQ29udGFpbmVyXCIsXG4gICAgSlNYRWxlbWVudDogXCJKU1hFbGVtZW50XCIsXG4gICAgSlNYQ2xvc2luZ0VsZW1lbnQ6IFwiSlNYQ2xvc2luZ0VsZW1lbnRcIixcbiAgICBKU1hPcGVuaW5nRWxlbWVudDogXCJKU1hPcGVuaW5nRWxlbWVudFwiLFxuICAgIEpTWEF0dHJpYnV0ZTogXCJKU1hBdHRyaWJ1dGVcIixcbiAgICBKU1hTcHJlYWRBdHRyaWJ1dGU6IFwiSlNYU3ByZWFkQXR0cmlidXRlXCIsXG4gICAgSlNYVGV4dDogXCJKU1hUZXh0XCIsXG4gICAgRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uOiBcIkV4cG9ydERlZmF1bHREZWNsYXJhdGlvblwiLFxuICAgIEV4cG9ydE5hbWVkRGVjbGFyYXRpb246IFwiRXhwb3J0TmFtZWREZWNsYXJhdGlvblwiLFxuICAgIEV4cG9ydEFsbERlY2xhcmF0aW9uOiBcIkV4cG9ydEFsbERlY2xhcmF0aW9uXCIsXG4gICAgRXhwb3J0U3BlY2lmaWVyOiBcIkV4cG9ydFNwZWNpZmllclwiLFxuICAgIEltcG9ydERlY2xhcmF0aW9uOiBcIkltcG9ydERlY2xhcmF0aW9uXCIsXG4gICAgSW1wb3J0U3BlY2lmaWVyOiBcIkltcG9ydFNwZWNpZmllclwiLFxuICAgIEltcG9ydERlZmF1bHRTcGVjaWZpZXI6IFwiSW1wb3J0RGVmYXVsdFNwZWNpZmllclwiLFxuICAgIEltcG9ydE5hbWVzcGFjZVNwZWNpZmllcjogXCJJbXBvcnROYW1lc3BhY2VTcGVjaWZpZXJcIlxufTtcbiIsIi8qKlxuICogQGZpbGVvdmVydmlldyBBdHRhY2hlcyBjb21tZW50cyB0byB0aGUgQVNULlxuICogQGF1dGhvciBOaWNob2xhcyBDLiBaYWthc1xuICogQGNvcHlyaWdodCAyMDE1IE5pY2hvbGFzIEMuIFpha2FzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogQGNvcHlyaWdodCAyMDExLTIwMTMgQXJpeWEgSGlkYXlhdCA8YXJpeWEuaGlkYXlhdEBnbWFpbC5jb20+XG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gKiAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAqICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuICogICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuICogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxuICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcbiAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxuICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuICogVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJlcXVpcmVtZW50c1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxudmFyIGFzdE5vZGVUeXBlcyA9IHJlcXVpcmUoXCIuL2FzdC1ub2RlLXR5cGVzXCIpO1xuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUHJpdmF0ZVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxudmFyIGV4dHJhID0ge1xuICAgICAgICB0cmFpbGluZ0NvbW1lbnRzOiBbXSxcbiAgICAgICAgbGVhZGluZ0NvbW1lbnRzOiBbXSxcbiAgICAgICAgYm90dG9tUmlnaHRTdGFjazogW11cbiAgICB9O1xuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUHVibGljXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICAgIHJlc2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgZXh0cmEudHJhaWxpbmdDb21tZW50cyA9IFtdO1xuICAgICAgICBleHRyYS5sZWFkaW5nQ29tbWVudHMgPSBbXTtcbiAgICAgICAgZXh0cmEuYm90dG9tUmlnaHRTdGFjayA9IFtdO1xuICAgIH0sXG5cbiAgICBhZGRDb21tZW50OiBmdW5jdGlvbihjb21tZW50KSB7XG4gICAgICAgIGV4dHJhLnRyYWlsaW5nQ29tbWVudHMucHVzaChjb21tZW50KTtcbiAgICAgICAgZXh0cmEubGVhZGluZ0NvbW1lbnRzLnB1c2goY29tbWVudCk7XG4gICAgfSxcblxuICAgIHByb2Nlc3NDb21tZW50OiBmdW5jdGlvbihub2RlKSB7XG4gICAgICAgIHZhciBsYXN0Q2hpbGQsXG4gICAgICAgICAgICB0cmFpbGluZ0NvbW1lbnRzLFxuICAgICAgICAgICAgaTtcblxuICAgICAgICBpZiAobm9kZS50eXBlID09PSBhc3ROb2RlVHlwZXMuUHJvZ3JhbSkge1xuICAgICAgICAgICAgaWYgKG5vZGUuYm9keS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV4dHJhLnRyYWlsaW5nQ29tbWVudHMubGVuZ3RoID4gMCkge1xuXG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogSWYgdGhlIGZpcnN0IGNvbW1lbnQgaW4gdHJhaWxpbmdDb21tZW50cyBjb21lcyBhZnRlciB0aGVcbiAgICAgICAgICAgICAqIGN1cnJlbnQgbm9kZSwgdGhlbiB3ZSdyZSBnb29kIC0gYWxsIGNvbW1lbnRzIGluIHRoZSBhcnJheSB3aWxsXG4gICAgICAgICAgICAgKiBjb21lIGFmdGVyIHRoZSBub2RlIGFuZCBzbyBpdCdzIHNhZmUgdG8gYWRkIHRoZW4gYXMgb2ZmaWNpYWxcbiAgICAgICAgICAgICAqIHRyYWlsaW5nQ29tbWVudHMuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmIChleHRyYS50cmFpbGluZ0NvbW1lbnRzWzBdLnJhbmdlWzBdID49IG5vZGUucmFuZ2VbMV0pIHtcbiAgICAgICAgICAgICAgICB0cmFpbGluZ0NvbW1lbnRzID0gZXh0cmEudHJhaWxpbmdDb21tZW50cztcbiAgICAgICAgICAgICAgICBleHRyYS50cmFpbGluZ0NvbW1lbnRzID0gW107XG4gICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgKiBPdGhlcndpc2UsIGlmIHRoZSBmaXJzdCBjb21tZW50IGRvZXNuJ3QgY29tZSBhZnRlciB0aGVcbiAgICAgICAgICAgICAgICAgKiBjdXJyZW50IG5vZGUsIHRoYXQgbWVhbnMgd2UgaGF2ZSBhIG1peCBvZiBsZWFkaW5nIGFuZCB0cmFpbGluZ1xuICAgICAgICAgICAgICAgICAqIGNvbW1lbnRzIGluIHRoZSBhcnJheSBhbmQgdGhhdCBsZWFkaW5nQ29tbWVudHMgY29udGFpbnMgdGhlXG4gICAgICAgICAgICAgICAgICogc2FtZSBpdGVtcyBhcyB0cmFpbGluZ0NvbW1lbnRzLiBSZXNldCB0cmFpbGluZ0NvbW1lbnRzIHRvXG4gICAgICAgICAgICAgICAgICogemVybyBpdGVtcyBhbmQgd2UnbGwgaGFuZGxlIHRoaXMgYnkgZXZhbHVhdGluZyBsZWFkaW5nQ29tbWVudHNcbiAgICAgICAgICAgICAgICAgKiBsYXRlci5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBleHRyYS50cmFpbGluZ0NvbW1lbnRzLmxlbmd0aCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoZXh0cmEuYm90dG9tUmlnaHRTdGFjay5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgICAgICAgIGV4dHJhLmJvdHRvbVJpZ2h0U3RhY2tbZXh0cmEuYm90dG9tUmlnaHRTdGFjay5sZW5ndGggLSAxXS50cmFpbGluZ0NvbW1lbnRzICYmXG4gICAgICAgICAgICAgICAgICAgIGV4dHJhLmJvdHRvbVJpZ2h0U3RhY2tbZXh0cmEuYm90dG9tUmlnaHRTdGFjay5sZW5ndGggLSAxXS50cmFpbGluZ0NvbW1lbnRzWzBdLnJhbmdlWzBdID49IG5vZGUucmFuZ2VbMV0pIHtcbiAgICAgICAgICAgICAgICB0cmFpbGluZ0NvbW1lbnRzID0gZXh0cmEuYm90dG9tUmlnaHRTdGFja1tleHRyYS5ib3R0b21SaWdodFN0YWNrLmxlbmd0aCAtIDFdLnRyYWlsaW5nQ29tbWVudHM7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGV4dHJhLmJvdHRvbVJpZ2h0U3RhY2tbZXh0cmEuYm90dG9tUmlnaHRTdGFjay5sZW5ndGggLSAxXS50cmFpbGluZ0NvbW1lbnRzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRWF0aW5nIHRoZSBzdGFjay5cbiAgICAgICAgd2hpbGUgKGV4dHJhLmJvdHRvbVJpZ2h0U3RhY2subGVuZ3RoID4gMCAmJiBleHRyYS5ib3R0b21SaWdodFN0YWNrW2V4dHJhLmJvdHRvbVJpZ2h0U3RhY2subGVuZ3RoIC0gMV0ucmFuZ2VbMF0gPj0gbm9kZS5yYW5nZVswXSkge1xuICAgICAgICAgICAgbGFzdENoaWxkID0gZXh0cmEuYm90dG9tUmlnaHRTdGFjay5wb3AoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsYXN0Q2hpbGQpIHtcbiAgICAgICAgICAgIGlmIChsYXN0Q2hpbGQubGVhZGluZ0NvbW1lbnRzICYmIGxhc3RDaGlsZC5sZWFkaW5nQ29tbWVudHNbbGFzdENoaWxkLmxlYWRpbmdDb21tZW50cy5sZW5ndGggLSAxXS5yYW5nZVsxXSA8PSBub2RlLnJhbmdlWzBdKSB7XG4gICAgICAgICAgICAgICAgbm9kZS5sZWFkaW5nQ29tbWVudHMgPSBsYXN0Q2hpbGQubGVhZGluZ0NvbW1lbnRzO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBsYXN0Q2hpbGQubGVhZGluZ0NvbW1lbnRzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGV4dHJhLmxlYWRpbmdDb21tZW50cy5sZW5ndGggPiAwKSB7XG5cbiAgICAgICAgICAgIGlmIChleHRyYS5sZWFkaW5nQ29tbWVudHNbZXh0cmEubGVhZGluZ0NvbW1lbnRzLmxlbmd0aCAtIDFdLnJhbmdlWzFdIDw9IG5vZGUucmFuZ2VbMF0pIHtcbiAgICAgICAgICAgICAgICBub2RlLmxlYWRpbmdDb21tZW50cyA9IGV4dHJhLmxlYWRpbmdDb21tZW50cztcbiAgICAgICAgICAgICAgICBleHRyYS5sZWFkaW5nQ29tbWVudHMgPSBbXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZXNsaW50L2VzcHJlZS9pc3N1ZXMvMlxuXG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgKiBJbiBzcGVjaWFsIGNhc2VzLCBzdWNoIGFzIHJldHVybiAod2l0aG91dCBhIHZhbHVlKSBhbmRcbiAgICAgICAgICAgICAgICAgKiBkZWJ1Z2dlciwgYWxsIGNvbW1lbnRzIHdpbGwgZW5kIHVwIGFzIGxlYWRpbmdDb21tZW50cyBhbmRcbiAgICAgICAgICAgICAgICAgKiB3aWxsIG90aGVyd2lzZSBiZSBlbGltaW5hdGVkLiBUaGlzIGV4dHJhIHN0ZXAgcnVucyB3aGVuIHRoZVxuICAgICAgICAgICAgICAgICAqIGJvdHRvbVJpZ2h0U3RhY2sgaXMgZW1wdHkgYW5kIHRoZXJlIGFyZSBjb21tZW50cyBsZWZ0XG4gICAgICAgICAgICAgICAgICogaW4gbGVhZGluZ0NvbW1lbnRzLlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogVGhpcyBsb29wIGZpZ3VyZXMgb3V0IHRoZSBzdG9wcGluZyBwb2ludCBiZXR3ZWVuIHRoZSBhY3R1YWxcbiAgICAgICAgICAgICAgICAgKiBsZWFkaW5nIGFuZCB0cmFpbGluZyBjb21tZW50cyBieSBmaW5kaW5nIHRoZSBsb2NhdGlvbiBvZiB0aGVcbiAgICAgICAgICAgICAgICAgKiBmaXJzdCBjb21tZW50IHRoYXQgY29tZXMgYWZ0ZXIgdGhlIGdpdmVuIG5vZGUuXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGV4dHJhLmxlYWRpbmdDb21tZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXh0cmEubGVhZGluZ0NvbW1lbnRzW2ldLnJhbmdlWzFdID4gbm9kZS5yYW5nZVswXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIFNwbGl0IHRoZSBhcnJheSBiYXNlZCBvbiB0aGUgbG9jYXRpb24gb2YgdGhlIGZpcnN0IGNvbW1lbnRcbiAgICAgICAgICAgICAgICAgKiB0aGF0IGNvbWVzIGFmdGVyIHRoZSBub2RlLiBLZWVwIGluIG1pbmQgdGhhdCB0aGlzIGNvdWxkXG4gICAgICAgICAgICAgICAgICogcmVzdWx0IGluIGFuIGVtcHR5IGFycmF5LCBhbmQgaWYgc28sIHRoZSBhcnJheSBtdXN0IGJlXG4gICAgICAgICAgICAgICAgICogZGVsZXRlZC5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBub2RlLmxlYWRpbmdDb21tZW50cyA9IGV4dHJhLmxlYWRpbmdDb21tZW50cy5zbGljZSgwLCBpKTtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5sZWFkaW5nQ29tbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBub2RlLmxlYWRpbmdDb21tZW50cztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIFNpbWlsYXJseSwgdHJhaWxpbmcgY29tbWVudHMgYXJlIGF0dGFjaGVkIGxhdGVyLiBUaGUgdmFyaWFibGVcbiAgICAgICAgICAgICAgICAgKiBtdXN0IGJlIHJlc2V0IHRvIG51bGwgaWYgdGhlcmUgYXJlIG5vIHRyYWlsaW5nIGNvbW1lbnRzLlxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIHRyYWlsaW5nQ29tbWVudHMgPSBleHRyYS5sZWFkaW5nQ29tbWVudHMuc2xpY2UoaSk7XG4gICAgICAgICAgICAgICAgaWYgKHRyYWlsaW5nQ29tbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyYWlsaW5nQ29tbWVudHMgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0cmFpbGluZ0NvbW1lbnRzKSB7XG4gICAgICAgICAgICBub2RlLnRyYWlsaW5nQ29tbWVudHMgPSB0cmFpbGluZ0NvbW1lbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgZXh0cmEuYm90dG9tUmlnaHRTdGFjay5wdXNoKG5vZGUpO1xuICAgIH1cblxufTtcbiIsIi8qKlxuICogQGZpbGVvdmVydmlldyBUaGUgbGlzdCBvZiBmZWF0dXJlIGZsYWdzIHN1cHBvcnRlZCBieSB0aGUgcGFyc2VyIGFuZCB0aGVpciBkZWZhdWx0XG4gKiAgICAgIHNldHRpbmdzLlxuICogQGF1dGhvciBOaWNob2xhcyBDLiBaYWthc1xuICogQGNvcHlyaWdodCAyMDE1IEZyZWQgSy4gU2Nob3R0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogQGNvcHlyaWdodCAyMDE0IE5pY2hvbGFzIEMuIFpha2FzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4gKlxuICogKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuICogICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0XG4gKiAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiAqICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiAqIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCA8Q09QWVJJR0hUIEhPTERFUj4gQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XG4gKiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBSZXF1aXJlbWVudHNcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIE5vbmUhXG5cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBQdWJsaWNcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gICAgLy8gZW5hYmxlIHBhcnNpbmcgb2YgYXJyb3cgZnVuY3Rpb25zXG4gICAgYXJyb3dGdW5jdGlvbnM6IGZhbHNlLFxuXG4gICAgLy8gZW5hYmxlIHBhcnNpbmcgb2YgbGV0IGFuZCBjb25zdFxuICAgIGJsb2NrQmluZGluZ3M6IHRydWUsXG5cbiAgICAvLyBlbmFibGUgcGFyc2luZyBvZiBkZXN0cnVjdHVyZWQgYXJyYXlzIGFuZCBvYmplY3RzXG4gICAgZGVzdHJ1Y3R1cmluZzogZmFsc2UsXG5cbiAgICAvLyBlbmFibGUgcGFyc2luZyBvZiByZWdleCB1IGZsYWdcbiAgICByZWdleFVGbGFnOiBmYWxzZSxcblxuICAgIC8vIGVuYWJsZSBwYXJzaW5nIG9mIHJlZ2V4IHkgZmxhZ1xuICAgIHJlZ2V4WUZsYWc6IGZhbHNlLFxuXG4gICAgLy8gZW5hYmxlIHBhcnNpbmcgb2YgdGVtcGxhdGUgc3RyaW5nc1xuICAgIHRlbXBsYXRlU3RyaW5nczogZmFsc2UsXG5cbiAgICAvLyBlbmFibGUgcGFyc2luZyBiaW5hcnkgbGl0ZXJhbHNcbiAgICBiaW5hcnlMaXRlcmFsczogZmFsc2UsXG5cbiAgICAvLyBlbmFibGUgcGFyc2luZyBFUzYgb2N0YWwgbGl0ZXJhbHNcbiAgICBvY3RhbExpdGVyYWxzOiBmYWxzZSxcblxuICAgIC8vIGVuYWJsZSBwYXJzaW5nIHVuaWNvZGUgY29kZSBwb2ludCBlc2NhcGUgc2VxdWVuY2VzXG4gICAgdW5pY29kZUNvZGVQb2ludEVzY2FwZXM6IHRydWUsXG5cbiAgICAvLyBlbmFibGUgcGFyc2luZyBvZiBkZWZhdWx0IHBhcmFtZXRlcnNcbiAgICBkZWZhdWx0UGFyYW1zOiBmYWxzZSxcblxuICAgIC8vIGVuYWJsZSBwYXJzaW5nIG9mIHJlc3QgcGFyYW1ldGVyc1xuICAgIHJlc3RQYXJhbXM6IGZhbHNlLFxuXG4gICAgLy8gZW5hYmxlIHBhcnNpbmcgb2YgZm9yLW9mIHN0YXRlbWVudHNcbiAgICBmb3JPZjogZmFsc2UsXG5cbiAgICAvLyBlbmFibGUgcGFyc2luZyBjb21wdXRlZCBvYmplY3QgbGl0ZXJhbCBwcm9wZXJ0aWVzXG4gICAgb2JqZWN0TGl0ZXJhbENvbXB1dGVkUHJvcGVydGllczogZmFsc2UsXG5cbiAgICAvLyBlbmFibGUgcGFyc2luZyBvZiBzaG9ydGhhbmQgb2JqZWN0IGxpdGVyYWwgbWV0aG9kc1xuICAgIG9iamVjdExpdGVyYWxTaG9ydGhhbmRNZXRob2RzOiBmYWxzZSxcblxuICAgIC8vIGVuYWJsZSBwYXJzaW5nIG9mIHNob3J0aGFuZCBvYmplY3QgbGl0ZXJhbCBwcm9wZXJ0aWVzXG4gICAgb2JqZWN0TGl0ZXJhbFNob3J0aGFuZFByb3BlcnRpZXM6IGZhbHNlLFxuXG4gICAgLy8gQWxsb3cgZHVwbGljYXRlIG9iamVjdCBsaXRlcmFsIHByb3BlcnRpZXMgKGV4Y2VwdCAnX19wcm90b19fJylcbiAgICBvYmplY3RMaXRlcmFsRHVwbGljYXRlUHJvcGVydGllczogZmFsc2UsXG5cbiAgICAvLyBlbmFibGUgcGFyc2luZyBvZiBnZW5lcmF0b3JzL3lpZWxkXG4gICAgZ2VuZXJhdG9yczogZmFsc2UsXG5cbiAgICAvLyBzdXBwb3J0IHRoZSBzcHJlYWQgb3BlcmF0b3JcbiAgICBzcHJlYWQ6IGZhbHNlLFxuXG4gICAgLy8gZW5hYmxlIHN1cGVyIGluIGZ1bmN0aW9uc1xuICAgIHN1cGVySW5GdW5jdGlvbnM6IGZhbHNlLFxuXG4gICAgLy8gZW5hYmxlIHBhcnNpbmcgb2YgY2xhc3Nlc1xuICAgIGNsYXNzZXM6IGZhbHNlLFxuXG4gICAgLy8gZW5hYmxlIHBhcnNpbmcgb2YgbW9kdWxlc1xuICAgIG1vZHVsZXM6IGZhbHNlLFxuXG4gICAgLy8gUmVhY3QgSlNYIHBhcnNpbmdcbiAgICBqc3g6IGZhbHNlLFxuXG4gICAgLy8gYWxsb3cgcmV0dXJuIHN0YXRlbWVudCBpbiBnbG9iYWwgc2NvcGVcbiAgICBnbG9iYWxSZXR1cm46IGZhbHNlXG59O1xuIiwiLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IEVycm9yIG1lc3NhZ2VzIHJldHVybmVkIGJ5IHRoZSBwYXJzZXIuXG4gKiBAYXV0aG9yIE5pY2hvbGFzIEMuIFpha2FzXG4gKiBAY29weXJpZ2h0IDIwMTQgTmljaG9sYXMgQy4gWmFrYXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBAY29weXJpZ2h0IDIwMTEtMjAxMyBBcml5YSBIaWRheWF0IDxhcml5YS5oaWRheWF0QGdtYWlsLmNvbT5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAqICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICogKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICogICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4gKiAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cblwidXNlIHN0cmljdFwiO1xuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUmVxdWlyZW1lbnRzXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBOb25lIVxuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUHVibGljXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBlcnJvciBtZXNzYWdlcyBzaG91bGQgYmUgaWRlbnRpY2FsIHRvIFY4IHdoZXJlIHBvc3NpYmxlXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBVbmV4cGVjdGVkVG9rZW46IFwiVW5leHBlY3RlZCB0b2tlbiAlMFwiLFxuICAgIFVuZXhwZWN0ZWROdW1iZXI6IFwiVW5leHBlY3RlZCBudW1iZXJcIixcbiAgICBVbmV4cGVjdGVkU3RyaW5nOiBcIlVuZXhwZWN0ZWQgc3RyaW5nXCIsXG4gICAgVW5leHBlY3RlZElkZW50aWZpZXI6IFwiVW5leHBlY3RlZCBpZGVudGlmaWVyXCIsXG4gICAgVW5leHBlY3RlZFJlc2VydmVkOiBcIlVuZXhwZWN0ZWQgcmVzZXJ2ZWQgd29yZFwiLFxuICAgIFVuZXhwZWN0ZWRUZW1wbGF0ZTogXCJVbmV4cGVjdGVkIHF1YXNpICUwXCIsXG4gICAgVW5leHBlY3RlZEVPUzogXCJVbmV4cGVjdGVkIGVuZCBvZiBpbnB1dFwiLFxuICAgIE5ld2xpbmVBZnRlclRocm93OiBcIklsbGVnYWwgbmV3bGluZSBhZnRlciB0aHJvd1wiLFxuICAgIEludmFsaWRSZWdFeHA6IFwiSW52YWxpZCByZWd1bGFyIGV4cHJlc3Npb25cIixcbiAgICBJbnZhbGlkUmVnRXhwRmxhZzogXCJJbnZhbGlkIHJlZ3VsYXIgZXhwcmVzc2lvbiBmbGFnXCIsXG4gICAgVW50ZXJtaW5hdGVkUmVnRXhwOiBcIkludmFsaWQgcmVndWxhciBleHByZXNzaW9uOiBtaXNzaW5nIC9cIixcbiAgICBJbnZhbGlkTEhTSW5Bc3NpZ25tZW50OiBcIkludmFsaWQgbGVmdC1oYW5kIHNpZGUgaW4gYXNzaWdubWVudFwiLFxuICAgIEludmFsaWRMSFNJbkZvcm1hbHNMaXN0OiBcIkludmFsaWQgbGVmdC1oYW5kIHNpZGUgaW4gZm9ybWFscyBsaXN0XCIsXG4gICAgSW52YWxpZExIU0luRm9ySW46IFwiSW52YWxpZCBsZWZ0LWhhbmQgc2lkZSBpbiBmb3ItaW5cIixcbiAgICBNdWx0aXBsZURlZmF1bHRzSW5Td2l0Y2g6IFwiTW9yZSB0aGFuIG9uZSBkZWZhdWx0IGNsYXVzZSBpbiBzd2l0Y2ggc3RhdGVtZW50XCIsXG4gICAgTm9DYXRjaE9yRmluYWxseTogXCJNaXNzaW5nIGNhdGNoIG9yIGZpbmFsbHkgYWZ0ZXIgdHJ5XCIsXG4gICAgTm9VbmludGlhbGl6ZWRDb25zdDogXCJDb25zdCBtdXN0IGJlIGluaXRpYWxpemVkXCIsXG4gICAgVW5rbm93bkxhYmVsOiBcIlVuZGVmaW5lZCBsYWJlbCAnJTAnXCIsXG4gICAgUmVkZWNsYXJhdGlvbjogXCIlMCAnJTEnIGhhcyBhbHJlYWR5IGJlZW4gZGVjbGFyZWRcIixcbiAgICBJbGxlZ2FsQ29udGludWU6IFwiSWxsZWdhbCBjb250aW51ZSBzdGF0ZW1lbnRcIixcbiAgICBJbGxlZ2FsQnJlYWs6IFwiSWxsZWdhbCBicmVhayBzdGF0ZW1lbnRcIixcbiAgICBJbGxlZ2FsUmV0dXJuOiBcIklsbGVnYWwgcmV0dXJuIHN0YXRlbWVudFwiLFxuICAgIElsbGVnYWxZaWVsZDogXCJJbGxlZ2FsIHlpZWxkIGV4cHJlc3Npb25cIixcbiAgICBJbGxlZ2FsU3ByZWFkOiBcIklsbGVnYWwgc3ByZWFkIGVsZW1lbnRcIixcbiAgICBTdHJpY3RNb2RlV2l0aDogXCJTdHJpY3QgbW9kZSBjb2RlIG1heSBub3QgaW5jbHVkZSBhIHdpdGggc3RhdGVtZW50XCIsXG4gICAgU3RyaWN0Q2F0Y2hWYXJpYWJsZTogXCJDYXRjaCB2YXJpYWJsZSBtYXkgbm90IGJlIGV2YWwgb3IgYXJndW1lbnRzIGluIHN0cmljdCBtb2RlXCIsXG4gICAgU3RyaWN0VmFyTmFtZTogXCJWYXJpYWJsZSBuYW1lIG1heSBub3QgYmUgZXZhbCBvciBhcmd1bWVudHMgaW4gc3RyaWN0IG1vZGVcIixcbiAgICBTdHJpY3RQYXJhbU5hbWU6IFwiUGFyYW1ldGVyIG5hbWUgZXZhbCBvciBhcmd1bWVudHMgaXMgbm90IGFsbG93ZWQgaW4gc3RyaWN0IG1vZGVcIixcbiAgICBTdHJpY3RQYXJhbUR1cGU6IFwiU3RyaWN0IG1vZGUgZnVuY3Rpb24gbWF5IG5vdCBoYXZlIGR1cGxpY2F0ZSBwYXJhbWV0ZXIgbmFtZXNcIixcbiAgICBUZW1wbGF0ZU9jdGFsTGl0ZXJhbDogXCJPY3RhbCBsaXRlcmFscyBhcmUgbm90IGFsbG93ZWQgaW4gdGVtcGxhdGUgc3RyaW5ncy5cIixcbiAgICBQYXJhbWV0ZXJBZnRlclJlc3RQYXJhbWV0ZXI6IFwiUmVzdCBwYXJhbWV0ZXIgbXVzdCBiZSBsYXN0IGZvcm1hbCBwYXJhbWV0ZXJcIixcbiAgICBEZWZhdWx0UmVzdFBhcmFtZXRlcjogXCJSZXN0IHBhcmFtZXRlciBjYW4gbm90IGhhdmUgYSBkZWZhdWx0IHZhbHVlXCIsXG4gICAgRWxlbWVudEFmdGVyU3ByZWFkRWxlbWVudDogXCJTcHJlYWQgbXVzdCBiZSB0aGUgZmluYWwgZWxlbWVudCBvZiBhbiBlbGVtZW50IGxpc3RcIixcbiAgICBPYmplY3RQYXR0ZXJuQXNSZXN0UGFyYW1ldGVyOiBcIkludmFsaWQgcmVzdCBwYXJhbWV0ZXJcIixcbiAgICBPYmplY3RQYXR0ZXJuQXNTcHJlYWQ6IFwiSW52YWxpZCBzcHJlYWQgYXJndW1lbnRcIixcbiAgICBTdHJpY3RGdW5jdGlvbk5hbWU6IFwiRnVuY3Rpb24gbmFtZSBtYXkgbm90IGJlIGV2YWwgb3IgYXJndW1lbnRzIGluIHN0cmljdCBtb2RlXCIsXG4gICAgU3RyaWN0T2N0YWxMaXRlcmFsOiBcIk9jdGFsIGxpdGVyYWxzIGFyZSBub3QgYWxsb3dlZCBpbiBzdHJpY3QgbW9kZS5cIixcbiAgICBTdHJpY3REZWxldGU6IFwiRGVsZXRlIG9mIGFuIHVucXVhbGlmaWVkIGlkZW50aWZpZXIgaW4gc3RyaWN0IG1vZGUuXCIsXG4gICAgU3RyaWN0RHVwbGljYXRlUHJvcGVydHk6IFwiRHVwbGljYXRlIGRhdGEgcHJvcGVydHkgaW4gb2JqZWN0IGxpdGVyYWwgbm90IGFsbG93ZWQgaW4gc3RyaWN0IG1vZGVcIixcbiAgICBEdXBsaWNhdGVQcm90b3R5cGVQcm9wZXJ0eTogXCJEdXBsaWNhdGUgJ19fcHJvdG9fXycgcHJvcGVydHkgaW4gb2JqZWN0IGxpdGVyYWwgYXJlIG5vdCBhbGxvd2VkXCIsXG4gICAgQ29uc3RydWN0b3JTcGVjaWFsTWV0aG9kOiBcIkNsYXNzIGNvbnN0cnVjdG9yIG1heSBub3QgYmUgYW4gYWNjZXNzb3JcIixcbiAgICBEdXBsaWNhdGVDb25zdHJ1Y3RvcjogXCJBIGNsYXNzIG1heSBvbmx5IGhhdmUgb25lIGNvbnN0cnVjdG9yXCIsXG4gICAgU3RhdGljUHJvdG90eXBlOiBcIkNsYXNzZXMgbWF5IG5vdCBoYXZlIHN0YXRpYyBwcm9wZXJ0eSBuYW1lZCBwcm90b3R5cGVcIixcbiAgICBBY2Nlc3NvckRhdGFQcm9wZXJ0eTogXCJPYmplY3QgbGl0ZXJhbCBtYXkgbm90IGhhdmUgZGF0YSBhbmQgYWNjZXNzb3IgcHJvcGVydHkgd2l0aCB0aGUgc2FtZSBuYW1lXCIsXG4gICAgQWNjZXNzb3JHZXRTZXQ6IFwiT2JqZWN0IGxpdGVyYWwgbWF5IG5vdCBoYXZlIG11bHRpcGxlIGdldC9zZXQgYWNjZXNzb3JzIHdpdGggdGhlIHNhbWUgbmFtZVwiLFxuICAgIFN0cmljdExIU0Fzc2lnbm1lbnQ6IFwiQXNzaWdubWVudCB0byBldmFsIG9yIGFyZ3VtZW50cyBpcyBub3QgYWxsb3dlZCBpbiBzdHJpY3QgbW9kZVwiLFxuICAgIFN0cmljdExIU1Bvc3RmaXg6IFwiUG9zdGZpeCBpbmNyZW1lbnQvZGVjcmVtZW50IG1heSBub3QgaGF2ZSBldmFsIG9yIGFyZ3VtZW50cyBvcGVyYW5kIGluIHN0cmljdCBtb2RlXCIsXG4gICAgU3RyaWN0TEhTUHJlZml4OiBcIlByZWZpeCBpbmNyZW1lbnQvZGVjcmVtZW50IG1heSBub3QgaGF2ZSBldmFsIG9yIGFyZ3VtZW50cyBvcGVyYW5kIGluIHN0cmljdCBtb2RlXCIsXG4gICAgU3RyaWN0UmVzZXJ2ZWRXb3JkOiBcIlVzZSBvZiBmdXR1cmUgcmVzZXJ2ZWQgd29yZCBpbiBzdHJpY3QgbW9kZVwiLFxuICAgIEludmFsaWRKU1hBdHRyaWJ1dGVWYWx1ZTogXCJKU1ggdmFsdWUgc2hvdWxkIGJlIGVpdGhlciBhbiBleHByZXNzaW9uIG9yIGEgcXVvdGVkIEpTWCB0ZXh0XCIsXG4gICAgRXhwZWN0ZWRKU1hDbG9zaW5nVGFnOiBcIkV4cGVjdGVkIGNvcnJlc3BvbmRpbmcgSlNYIGNsb3NpbmcgdGFnIGZvciAlMFwiLFxuICAgIEFkamFjZW50SlNYRWxlbWVudHM6IFwiQWRqYWNlbnQgSlNYIGVsZW1lbnRzIG11c3QgYmUgd3JhcHBlZCBpbiBhbiBlbmNsb3NpbmcgdGFnXCIsXG4gICAgTWlzc2luZ0Zyb21DbGF1c2U6IFwiTWlzc2luZyBmcm9tIGNsYXVzZVwiLFxuICAgIE5vQXNBZnRlckltcG9ydE5hbWVzcGFjZTogXCJNaXNzaW5nIGFzIGFmdGVyIGltcG9ydCAqXCIsXG4gICAgSW52YWxpZE1vZHVsZVNwZWNpZmllcjogXCJJbnZhbGlkIG1vZHVsZSBzcGVjaWZpZXJcIixcbiAgICBJbGxlZ2FsSW1wb3J0RGVjbGFyYXRpb246IFwiSWxsZWdhbCBpbXBvcnQgZGVjbGFyYXRpb25cIixcbiAgICBJbGxlZ2FsRXhwb3J0RGVjbGFyYXRpb246IFwiSWxsZWdhbCBleHBvcnQgZGVjbGFyYXRpb25cIlxufTtcbiIsIi8qKlxuICogQGZpbGVvdmVydmlldyBBIHNpbXBsZSBtYXAgdGhhdCBoZWxwcyBhdm9pZCBjb2xsaXNpb25zIG9uIHRoZSBPYmplY3QgcHJvdG90eXBlLlxuICogQGF1dGhvciBKYW11bmQgRmVyZ3Vzb25cbiAqIEBjb3B5cmlnaHQgMjAxNSBKYW11bmQgRmVyZ3Vzb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBAY29weXJpZ2h0IDIwMTEtMjAxMyBBcml5YSBIaWRheWF0IDxhcml5YS5oaWRheWF0QGdtYWlsLmNvbT5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAqICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICogKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICogICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4gKiAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cblwidXNlIHN0cmljdFwiO1xuXG5mdW5jdGlvbiBTdHJpbmdNYXAoKSB7XG4gICAgdGhpcy4kZGF0YSA9IHt9O1xufVxuXG5TdHJpbmdNYXAucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICBrZXkgPSBcIiRcIiArIGtleTtcbiAgICByZXR1cm4gdGhpcy4kZGF0YVtrZXldO1xufTtcblxuU3RyaW5nTWFwLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgIGtleSA9IFwiJFwiICsga2V5O1xuICAgIHRoaXMuJGRhdGFba2V5XSA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuU3RyaW5nTWFwLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAga2V5ID0gXCIkXCIgKyBrZXk7XG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLiRkYXRhLCBrZXkpO1xufTtcblxuU3RyaW5nTWFwLnByb3RvdHlwZS5kZWxldGUgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAga2V5ID0gXCIkXCIgKyBrZXk7XG4gICAgcmV0dXJuIGRlbGV0ZSB0aGlzLiRkYXRhW2tleV07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN0cmluZ01hcDtcbiIsIi8qKlxuICogQGZpbGVvdmVydmlldyBWYXJpb3VzIHN5bnRheC9wYXR0ZXJuIGNoZWNrcyBmb3IgcGFyc2luZy5cbiAqIEBhdXRob3IgTmljaG9sYXMgQy4gWmFrYXNcbiAqIEBjb3B5cmlnaHQgMjAxNCBOaWNob2xhcyBDLiBaYWthcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIEBjb3B5cmlnaHQgMjAxMS0yMDEzIEFyaXlhIEhpZGF5YXQgPGFyaXlhLmhpZGF5YXRAZ21haWwuY29tPlxuICogQGNvcHlyaWdodCAyMDEyLTIwMTMgTWF0aGlhcyBCeW5lbnMgPG1hdGhpYXNAcWl3aS5iZT5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAqICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICogKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICogICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4gKiAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cblwidXNlIHN0cmljdFwiO1xuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUmVxdWlyZW1lbnRzXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBOb25lIVxuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUHJpdmF0ZVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gU2VlIGFsc28gdG9vbHMvZ2VuZXJhdGUtaWRlbnRpZmllci1yZWdleC5qcy5cbnZhciBSZWdleCA9IHtcbiAgICBOb25Bc2NpaUlkZW50aWZpZXJTdGFydDogbmV3IFJlZ0V4cChcIltcXHhBQVxceEI1XFx4QkFcXHhDMC1cXHhENlxceEQ4LVxceEY2XFx4RjgtXFx1MDJDMVxcdTAyQzYtXFx1MDJEMVxcdTAyRTAtXFx1MDJFNFxcdTAyRUNcXHUwMkVFXFx1MDM3MC1cXHUwMzc0XFx1MDM3NlxcdTAzNzdcXHUwMzdBLVxcdTAzN0RcXHUwMzg2XFx1MDM4OC1cXHUwMzhBXFx1MDM4Q1xcdTAzOEUtXFx1MDNBMVxcdTAzQTMtXFx1MDNGNVxcdTAzRjctXFx1MDQ4MVxcdTA0OEEtXFx1MDUyN1xcdTA1MzEtXFx1MDU1NlxcdTA1NTlcXHUwNTYxLVxcdTA1ODdcXHUwNUQwLVxcdTA1RUFcXHUwNUYwLVxcdTA1RjJcXHUwNjIwLVxcdTA2NEFcXHUwNjZFXFx1MDY2RlxcdTA2NzEtXFx1MDZEM1xcdTA2RDVcXHUwNkU1XFx1MDZFNlxcdTA2RUVcXHUwNkVGXFx1MDZGQS1cXHUwNkZDXFx1MDZGRlxcdTA3MTBcXHUwNzEyLVxcdTA3MkZcXHUwNzRELVxcdTA3QTVcXHUwN0IxXFx1MDdDQS1cXHUwN0VBXFx1MDdGNFxcdTA3RjVcXHUwN0ZBXFx1MDgwMC1cXHUwODE1XFx1MDgxQVxcdTA4MjRcXHUwODI4XFx1MDg0MC1cXHUwODU4XFx1MDhBMFxcdTA4QTItXFx1MDhBQ1xcdTA5MDQtXFx1MDkzOVxcdTA5M0RcXHUwOTUwXFx1MDk1OC1cXHUwOTYxXFx1MDk3MS1cXHUwOTc3XFx1MDk3OS1cXHUwOTdGXFx1MDk4NS1cXHUwOThDXFx1MDk4RlxcdTA5OTBcXHUwOTkzLVxcdTA5QThcXHUwOUFBLVxcdTA5QjBcXHUwOUIyXFx1MDlCNi1cXHUwOUI5XFx1MDlCRFxcdTA5Q0VcXHUwOURDXFx1MDlERFxcdTA5REYtXFx1MDlFMVxcdTA5RjBcXHUwOUYxXFx1MEEwNS1cXHUwQTBBXFx1MEEwRlxcdTBBMTBcXHUwQTEzLVxcdTBBMjhcXHUwQTJBLVxcdTBBMzBcXHUwQTMyXFx1MEEzM1xcdTBBMzVcXHUwQTM2XFx1MEEzOFxcdTBBMzlcXHUwQTU5LVxcdTBBNUNcXHUwQTVFXFx1MEE3Mi1cXHUwQTc0XFx1MEE4NS1cXHUwQThEXFx1MEE4Ri1cXHUwQTkxXFx1MEE5My1cXHUwQUE4XFx1MEFBQS1cXHUwQUIwXFx1MEFCMlxcdTBBQjNcXHUwQUI1LVxcdTBBQjlcXHUwQUJEXFx1MEFEMFxcdTBBRTBcXHUwQUUxXFx1MEIwNS1cXHUwQjBDXFx1MEIwRlxcdTBCMTBcXHUwQjEzLVxcdTBCMjhcXHUwQjJBLVxcdTBCMzBcXHUwQjMyXFx1MEIzM1xcdTBCMzUtXFx1MEIzOVxcdTBCM0RcXHUwQjVDXFx1MEI1RFxcdTBCNUYtXFx1MEI2MVxcdTBCNzFcXHUwQjgzXFx1MEI4NS1cXHUwQjhBXFx1MEI4RS1cXHUwQjkwXFx1MEI5Mi1cXHUwQjk1XFx1MEI5OVxcdTBCOUFcXHUwQjlDXFx1MEI5RVxcdTBCOUZcXHUwQkEzXFx1MEJBNFxcdTBCQTgtXFx1MEJBQVxcdTBCQUUtXFx1MEJCOVxcdTBCRDBcXHUwQzA1LVxcdTBDMENcXHUwQzBFLVxcdTBDMTBcXHUwQzEyLVxcdTBDMjhcXHUwQzJBLVxcdTBDMzNcXHUwQzM1LVxcdTBDMzlcXHUwQzNEXFx1MEM1OFxcdTBDNTlcXHUwQzYwXFx1MEM2MVxcdTBDODUtXFx1MEM4Q1xcdTBDOEUtXFx1MEM5MFxcdTBDOTItXFx1MENBOFxcdTBDQUEtXFx1MENCM1xcdTBDQjUtXFx1MENCOVxcdTBDQkRcXHUwQ0RFXFx1MENFMFxcdTBDRTFcXHUwQ0YxXFx1MENGMlxcdTBEMDUtXFx1MEQwQ1xcdTBEMEUtXFx1MEQxMFxcdTBEMTItXFx1MEQzQVxcdTBEM0RcXHUwRDRFXFx1MEQ2MFxcdTBENjFcXHUwRDdBLVxcdTBEN0ZcXHUwRDg1LVxcdTBEOTZcXHUwRDlBLVxcdTBEQjFcXHUwREIzLVxcdTBEQkJcXHUwREJEXFx1MERDMC1cXHUwREM2XFx1MEUwMS1cXHUwRTMwXFx1MEUzMlxcdTBFMzNcXHUwRTQwLVxcdTBFNDZcXHUwRTgxXFx1MEU4MlxcdTBFODRcXHUwRTg3XFx1MEU4OFxcdTBFOEFcXHUwRThEXFx1MEU5NC1cXHUwRTk3XFx1MEU5OS1cXHUwRTlGXFx1MEVBMS1cXHUwRUEzXFx1MEVBNVxcdTBFQTdcXHUwRUFBXFx1MEVBQlxcdTBFQUQtXFx1MEVCMFxcdTBFQjJcXHUwRUIzXFx1MEVCRFxcdTBFQzAtXFx1MEVDNFxcdTBFQzZcXHUwRURDLVxcdTBFREZcXHUwRjAwXFx1MEY0MC1cXHUwRjQ3XFx1MEY0OS1cXHUwRjZDXFx1MEY4OC1cXHUwRjhDXFx1MTAwMC1cXHUxMDJBXFx1MTAzRlxcdTEwNTAtXFx1MTA1NVxcdTEwNUEtXFx1MTA1RFxcdTEwNjFcXHUxMDY1XFx1MTA2NlxcdTEwNkUtXFx1MTA3MFxcdTEwNzUtXFx1MTA4MVxcdTEwOEVcXHUxMEEwLVxcdTEwQzVcXHUxMEM3XFx1MTBDRFxcdTEwRDAtXFx1MTBGQVxcdTEwRkMtXFx1MTI0OFxcdTEyNEEtXFx1MTI0RFxcdTEyNTAtXFx1MTI1NlxcdTEyNThcXHUxMjVBLVxcdTEyNURcXHUxMjYwLVxcdTEyODhcXHUxMjhBLVxcdTEyOERcXHUxMjkwLVxcdTEyQjBcXHUxMkIyLVxcdTEyQjVcXHUxMkI4LVxcdTEyQkVcXHUxMkMwXFx1MTJDMi1cXHUxMkM1XFx1MTJDOC1cXHUxMkQ2XFx1MTJEOC1cXHUxMzEwXFx1MTMxMi1cXHUxMzE1XFx1MTMxOC1cXHUxMzVBXFx1MTM4MC1cXHUxMzhGXFx1MTNBMC1cXHUxM0Y0XFx1MTQwMS1cXHUxNjZDXFx1MTY2Ri1cXHUxNjdGXFx1MTY4MS1cXHUxNjlBXFx1MTZBMC1cXHUxNkVBXFx1MTZFRS1cXHUxNkYwXFx1MTcwMC1cXHUxNzBDXFx1MTcwRS1cXHUxNzExXFx1MTcyMC1cXHUxNzMxXFx1MTc0MC1cXHUxNzUxXFx1MTc2MC1cXHUxNzZDXFx1MTc2RS1cXHUxNzcwXFx1MTc4MC1cXHUxN0IzXFx1MTdEN1xcdTE3RENcXHUxODIwLVxcdTE4NzdcXHUxODgwLVxcdTE4QThcXHUxOEFBXFx1MThCMC1cXHUxOEY1XFx1MTkwMC1cXHUxOTFDXFx1MTk1MC1cXHUxOTZEXFx1MTk3MC1cXHUxOTc0XFx1MTk4MC1cXHUxOUFCXFx1MTlDMS1cXHUxOUM3XFx1MUEwMC1cXHUxQTE2XFx1MUEyMC1cXHUxQTU0XFx1MUFBN1xcdTFCMDUtXFx1MUIzM1xcdTFCNDUtXFx1MUI0QlxcdTFCODMtXFx1MUJBMFxcdTFCQUVcXHUxQkFGXFx1MUJCQS1cXHUxQkU1XFx1MUMwMC1cXHUxQzIzXFx1MUM0RC1cXHUxQzRGXFx1MUM1QS1cXHUxQzdEXFx1MUNFOS1cXHUxQ0VDXFx1MUNFRS1cXHUxQ0YxXFx1MUNGNVxcdTFDRjZcXHUxRDAwLVxcdTFEQkZcXHUxRTAwLVxcdTFGMTVcXHUxRjE4LVxcdTFGMURcXHUxRjIwLVxcdTFGNDVcXHUxRjQ4LVxcdTFGNERcXHUxRjUwLVxcdTFGNTdcXHUxRjU5XFx1MUY1QlxcdTFGNURcXHUxRjVGLVxcdTFGN0RcXHUxRjgwLVxcdTFGQjRcXHUxRkI2LVxcdTFGQkNcXHUxRkJFXFx1MUZDMi1cXHUxRkM0XFx1MUZDNi1cXHUxRkNDXFx1MUZEMC1cXHUxRkQzXFx1MUZENi1cXHUxRkRCXFx1MUZFMC1cXHUxRkVDXFx1MUZGMi1cXHUxRkY0XFx1MUZGNi1cXHUxRkZDXFx1MjA3MVxcdTIwN0ZcXHUyMDkwLVxcdTIwOUNcXHUyMTAyXFx1MjEwN1xcdTIxMEEtXFx1MjExM1xcdTIxMTVcXHUyMTE5LVxcdTIxMURcXHUyMTI0XFx1MjEyNlxcdTIxMjhcXHUyMTJBLVxcdTIxMkRcXHUyMTJGLVxcdTIxMzlcXHUyMTNDLVxcdTIxM0ZcXHUyMTQ1LVxcdTIxNDlcXHUyMTRFXFx1MjE2MC1cXHUyMTg4XFx1MkMwMC1cXHUyQzJFXFx1MkMzMC1cXHUyQzVFXFx1MkM2MC1cXHUyQ0U0XFx1MkNFQi1cXHUyQ0VFXFx1MkNGMlxcdTJDRjNcXHUyRDAwLVxcdTJEMjVcXHUyRDI3XFx1MkQyRFxcdTJEMzAtXFx1MkQ2N1xcdTJENkZcXHUyRDgwLVxcdTJEOTZcXHUyREEwLVxcdTJEQTZcXHUyREE4LVxcdTJEQUVcXHUyREIwLVxcdTJEQjZcXHUyREI4LVxcdTJEQkVcXHUyREMwLVxcdTJEQzZcXHUyREM4LVxcdTJEQ0VcXHUyREQwLVxcdTJERDZcXHUyREQ4LVxcdTJEREVcXHUyRTJGXFx1MzAwNS1cXHUzMDA3XFx1MzAyMS1cXHUzMDI5XFx1MzAzMS1cXHUzMDM1XFx1MzAzOC1cXHUzMDNDXFx1MzA0MS1cXHUzMDk2XFx1MzA5RC1cXHUzMDlGXFx1MzBBMS1cXHUzMEZBXFx1MzBGQy1cXHUzMEZGXFx1MzEwNS1cXHUzMTJEXFx1MzEzMS1cXHUzMThFXFx1MzFBMC1cXHUzMUJBXFx1MzFGMC1cXHUzMUZGXFx1MzQwMC1cXHU0REI1XFx1NEUwMC1cXHU5RkNDXFx1QTAwMC1cXHVBNDhDXFx1QTREMC1cXHVBNEZEXFx1QTUwMC1cXHVBNjBDXFx1QTYxMC1cXHVBNjFGXFx1QTYyQVxcdUE2MkJcXHVBNjQwLVxcdUE2NkVcXHVBNjdGLVxcdUE2OTdcXHVBNkEwLVxcdUE2RUZcXHVBNzE3LVxcdUE3MUZcXHVBNzIyLVxcdUE3ODhcXHVBNzhCLVxcdUE3OEVcXHVBNzkwLVxcdUE3OTNcXHVBN0EwLVxcdUE3QUFcXHVBN0Y4LVxcdUE4MDFcXHVBODAzLVxcdUE4MDVcXHVBODA3LVxcdUE4MEFcXHVBODBDLVxcdUE4MjJcXHVBODQwLVxcdUE4NzNcXHVBODgyLVxcdUE4QjNcXHVBOEYyLVxcdUE4RjdcXHVBOEZCXFx1QTkwQS1cXHVBOTI1XFx1QTkzMC1cXHVBOTQ2XFx1QTk2MC1cXHVBOTdDXFx1QTk4NC1cXHVBOUIyXFx1QTlDRlxcdUFBMDAtXFx1QUEyOFxcdUFBNDAtXFx1QUE0MlxcdUFBNDQtXFx1QUE0QlxcdUFBNjAtXFx1QUE3NlxcdUFBN0FcXHVBQTgwLVxcdUFBQUZcXHVBQUIxXFx1QUFCNVxcdUFBQjZcXHVBQUI5LVxcdUFBQkRcXHVBQUMwXFx1QUFDMlxcdUFBREItXFx1QUFERFxcdUFBRTAtXFx1QUFFQVxcdUFBRjItXFx1QUFGNFxcdUFCMDEtXFx1QUIwNlxcdUFCMDktXFx1QUIwRVxcdUFCMTEtXFx1QUIxNlxcdUFCMjAtXFx1QUIyNlxcdUFCMjgtXFx1QUIyRVxcdUFCQzAtXFx1QUJFMlxcdUFDMDAtXFx1RDdBM1xcdUQ3QjAtXFx1RDdDNlxcdUQ3Q0ItXFx1RDdGQlxcdUY5MDAtXFx1RkE2RFxcdUZBNzAtXFx1RkFEOVxcdUZCMDAtXFx1RkIwNlxcdUZCMTMtXFx1RkIxN1xcdUZCMURcXHVGQjFGLVxcdUZCMjhcXHVGQjJBLVxcdUZCMzZcXHVGQjM4LVxcdUZCM0NcXHVGQjNFXFx1RkI0MFxcdUZCNDFcXHVGQjQzXFx1RkI0NFxcdUZCNDYtXFx1RkJCMVxcdUZCRDMtXFx1RkQzRFxcdUZENTAtXFx1RkQ4RlxcdUZEOTItXFx1RkRDN1xcdUZERjAtXFx1RkRGQlxcdUZFNzAtXFx1RkU3NFxcdUZFNzYtXFx1RkVGQ1xcdUZGMjEtXFx1RkYzQVxcdUZGNDEtXFx1RkY1QVxcdUZGNjYtXFx1RkZCRVxcdUZGQzItXFx1RkZDN1xcdUZGQ0EtXFx1RkZDRlxcdUZGRDItXFx1RkZEN1xcdUZGREEtXFx1RkZEQ11cIiksXG4gICAgTm9uQXNjaWlJZGVudGlmaWVyUGFydDogbmV3IFJlZ0V4cChcIltcXHhBQVxceEI1XFx4QkFcXHhDMC1cXHhENlxceEQ4LVxceEY2XFx4RjgtXFx1MDJDMVxcdTAyQzYtXFx1MDJEMVxcdTAyRTAtXFx1MDJFNFxcdTAyRUNcXHUwMkVFXFx1MDMwMC1cXHUwMzc0XFx1MDM3NlxcdTAzNzdcXHUwMzdBLVxcdTAzN0RcXHUwMzg2XFx1MDM4OC1cXHUwMzhBXFx1MDM4Q1xcdTAzOEUtXFx1MDNBMVxcdTAzQTMtXFx1MDNGNVxcdTAzRjctXFx1MDQ4MVxcdTA0ODMtXFx1MDQ4N1xcdTA0OEEtXFx1MDUyN1xcdTA1MzEtXFx1MDU1NlxcdTA1NTlcXHUwNTYxLVxcdTA1ODdcXHUwNTkxLVxcdTA1QkRcXHUwNUJGXFx1MDVDMVxcdTA1QzJcXHUwNUM0XFx1MDVDNVxcdTA1QzdcXHUwNUQwLVxcdTA1RUFcXHUwNUYwLVxcdTA1RjJcXHUwNjEwLVxcdTA2MUFcXHUwNjIwLVxcdTA2NjlcXHUwNjZFLVxcdTA2RDNcXHUwNkQ1LVxcdTA2RENcXHUwNkRGLVxcdTA2RThcXHUwNkVBLVxcdTA2RkNcXHUwNkZGXFx1MDcxMC1cXHUwNzRBXFx1MDc0RC1cXHUwN0IxXFx1MDdDMC1cXHUwN0Y1XFx1MDdGQVxcdTA4MDAtXFx1MDgyRFxcdTA4NDAtXFx1MDg1QlxcdTA4QTBcXHUwOEEyLVxcdTA4QUNcXHUwOEU0LVxcdTA4RkVcXHUwOTAwLVxcdTA5NjNcXHUwOTY2LVxcdTA5NkZcXHUwOTcxLVxcdTA5NzdcXHUwOTc5LVxcdTA5N0ZcXHUwOTgxLVxcdTA5ODNcXHUwOTg1LVxcdTA5OENcXHUwOThGXFx1MDk5MFxcdTA5OTMtXFx1MDlBOFxcdTA5QUEtXFx1MDlCMFxcdTA5QjJcXHUwOUI2LVxcdTA5QjlcXHUwOUJDLVxcdTA5QzRcXHUwOUM3XFx1MDlDOFxcdTA5Q0ItXFx1MDlDRVxcdTA5RDdcXHUwOURDXFx1MDlERFxcdTA5REYtXFx1MDlFM1xcdTA5RTYtXFx1MDlGMVxcdTBBMDEtXFx1MEEwM1xcdTBBMDUtXFx1MEEwQVxcdTBBMEZcXHUwQTEwXFx1MEExMy1cXHUwQTI4XFx1MEEyQS1cXHUwQTMwXFx1MEEzMlxcdTBBMzNcXHUwQTM1XFx1MEEzNlxcdTBBMzhcXHUwQTM5XFx1MEEzQ1xcdTBBM0UtXFx1MEE0MlxcdTBBNDdcXHUwQTQ4XFx1MEE0Qi1cXHUwQTREXFx1MEE1MVxcdTBBNTktXFx1MEE1Q1xcdTBBNUVcXHUwQTY2LVxcdTBBNzVcXHUwQTgxLVxcdTBBODNcXHUwQTg1LVxcdTBBOERcXHUwQThGLVxcdTBBOTFcXHUwQTkzLVxcdTBBQThcXHUwQUFBLVxcdTBBQjBcXHUwQUIyXFx1MEFCM1xcdTBBQjUtXFx1MEFCOVxcdTBBQkMtXFx1MEFDNVxcdTBBQzctXFx1MEFDOVxcdTBBQ0ItXFx1MEFDRFxcdTBBRDBcXHUwQUUwLVxcdTBBRTNcXHUwQUU2LVxcdTBBRUZcXHUwQjAxLVxcdTBCMDNcXHUwQjA1LVxcdTBCMENcXHUwQjBGXFx1MEIxMFxcdTBCMTMtXFx1MEIyOFxcdTBCMkEtXFx1MEIzMFxcdTBCMzJcXHUwQjMzXFx1MEIzNS1cXHUwQjM5XFx1MEIzQy1cXHUwQjQ0XFx1MEI0N1xcdTBCNDhcXHUwQjRCLVxcdTBCNERcXHUwQjU2XFx1MEI1N1xcdTBCNUNcXHUwQjVEXFx1MEI1Ri1cXHUwQjYzXFx1MEI2Ni1cXHUwQjZGXFx1MEI3MVxcdTBCODJcXHUwQjgzXFx1MEI4NS1cXHUwQjhBXFx1MEI4RS1cXHUwQjkwXFx1MEI5Mi1cXHUwQjk1XFx1MEI5OVxcdTBCOUFcXHUwQjlDXFx1MEI5RVxcdTBCOUZcXHUwQkEzXFx1MEJBNFxcdTBCQTgtXFx1MEJBQVxcdTBCQUUtXFx1MEJCOVxcdTBCQkUtXFx1MEJDMlxcdTBCQzYtXFx1MEJDOFxcdTBCQ0EtXFx1MEJDRFxcdTBCRDBcXHUwQkQ3XFx1MEJFNi1cXHUwQkVGXFx1MEMwMS1cXHUwQzAzXFx1MEMwNS1cXHUwQzBDXFx1MEMwRS1cXHUwQzEwXFx1MEMxMi1cXHUwQzI4XFx1MEMyQS1cXHUwQzMzXFx1MEMzNS1cXHUwQzM5XFx1MEMzRC1cXHUwQzQ0XFx1MEM0Ni1cXHUwQzQ4XFx1MEM0QS1cXHUwQzREXFx1MEM1NVxcdTBDNTZcXHUwQzU4XFx1MEM1OVxcdTBDNjAtXFx1MEM2M1xcdTBDNjYtXFx1MEM2RlxcdTBDODJcXHUwQzgzXFx1MEM4NS1cXHUwQzhDXFx1MEM4RS1cXHUwQzkwXFx1MEM5Mi1cXHUwQ0E4XFx1MENBQS1cXHUwQ0IzXFx1MENCNS1cXHUwQ0I5XFx1MENCQy1cXHUwQ0M0XFx1MENDNi1cXHUwQ0M4XFx1MENDQS1cXHUwQ0NEXFx1MENENVxcdTBDRDZcXHUwQ0RFXFx1MENFMC1cXHUwQ0UzXFx1MENFNi1cXHUwQ0VGXFx1MENGMVxcdTBDRjJcXHUwRDAyXFx1MEQwM1xcdTBEMDUtXFx1MEQwQ1xcdTBEMEUtXFx1MEQxMFxcdTBEMTItXFx1MEQzQVxcdTBEM0QtXFx1MEQ0NFxcdTBENDYtXFx1MEQ0OFxcdTBENEEtXFx1MEQ0RVxcdTBENTdcXHUwRDYwLVxcdTBENjNcXHUwRDY2LVxcdTBENkZcXHUwRDdBLVxcdTBEN0ZcXHUwRDgyXFx1MEQ4M1xcdTBEODUtXFx1MEQ5NlxcdTBEOUEtXFx1MERCMVxcdTBEQjMtXFx1MERCQlxcdTBEQkRcXHUwREMwLVxcdTBEQzZcXHUwRENBXFx1MERDRi1cXHUwREQ0XFx1MERENlxcdTBERDgtXFx1MERERlxcdTBERjJcXHUwREYzXFx1MEUwMS1cXHUwRTNBXFx1MEU0MC1cXHUwRTRFXFx1MEU1MC1cXHUwRTU5XFx1MEU4MVxcdTBFODJcXHUwRTg0XFx1MEU4N1xcdTBFODhcXHUwRThBXFx1MEU4RFxcdTBFOTQtXFx1MEU5N1xcdTBFOTktXFx1MEU5RlxcdTBFQTEtXFx1MEVBM1xcdTBFQTVcXHUwRUE3XFx1MEVBQVxcdTBFQUJcXHUwRUFELVxcdTBFQjlcXHUwRUJCLVxcdTBFQkRcXHUwRUMwLVxcdTBFQzRcXHUwRUM2XFx1MEVDOC1cXHUwRUNEXFx1MEVEMC1cXHUwRUQ5XFx1MEVEQy1cXHUwRURGXFx1MEYwMFxcdTBGMThcXHUwRjE5XFx1MEYyMC1cXHUwRjI5XFx1MEYzNVxcdTBGMzdcXHUwRjM5XFx1MEYzRS1cXHUwRjQ3XFx1MEY0OS1cXHUwRjZDXFx1MEY3MS1cXHUwRjg0XFx1MEY4Ni1cXHUwRjk3XFx1MEY5OS1cXHUwRkJDXFx1MEZDNlxcdTEwMDAtXFx1MTA0OVxcdTEwNTAtXFx1MTA5RFxcdTEwQTAtXFx1MTBDNVxcdTEwQzdcXHUxMENEXFx1MTBEMC1cXHUxMEZBXFx1MTBGQy1cXHUxMjQ4XFx1MTI0QS1cXHUxMjREXFx1MTI1MC1cXHUxMjU2XFx1MTI1OFxcdTEyNUEtXFx1MTI1RFxcdTEyNjAtXFx1MTI4OFxcdTEyOEEtXFx1MTI4RFxcdTEyOTAtXFx1MTJCMFxcdTEyQjItXFx1MTJCNVxcdTEyQjgtXFx1MTJCRVxcdTEyQzBcXHUxMkMyLVxcdTEyQzVcXHUxMkM4LVxcdTEyRDZcXHUxMkQ4LVxcdTEzMTBcXHUxMzEyLVxcdTEzMTVcXHUxMzE4LVxcdTEzNUFcXHUxMzVELVxcdTEzNUZcXHUxMzgwLVxcdTEzOEZcXHUxM0EwLVxcdTEzRjRcXHUxNDAxLVxcdTE2NkNcXHUxNjZGLVxcdTE2N0ZcXHUxNjgxLVxcdTE2OUFcXHUxNkEwLVxcdTE2RUFcXHUxNkVFLVxcdTE2RjBcXHUxNzAwLVxcdTE3MENcXHUxNzBFLVxcdTE3MTRcXHUxNzIwLVxcdTE3MzRcXHUxNzQwLVxcdTE3NTNcXHUxNzYwLVxcdTE3NkNcXHUxNzZFLVxcdTE3NzBcXHUxNzcyXFx1MTc3M1xcdTE3ODAtXFx1MTdEM1xcdTE3RDdcXHUxN0RDXFx1MTdERFxcdTE3RTAtXFx1MTdFOVxcdTE4MEItXFx1MTgwRFxcdTE4MTAtXFx1MTgxOVxcdTE4MjAtXFx1MTg3N1xcdTE4ODAtXFx1MThBQVxcdTE4QjAtXFx1MThGNVxcdTE5MDAtXFx1MTkxQ1xcdTE5MjAtXFx1MTkyQlxcdTE5MzAtXFx1MTkzQlxcdTE5NDYtXFx1MTk2RFxcdTE5NzAtXFx1MTk3NFxcdTE5ODAtXFx1MTlBQlxcdTE5QjAtXFx1MTlDOVxcdTE5RDAtXFx1MTlEOVxcdTFBMDAtXFx1MUExQlxcdTFBMjAtXFx1MUE1RVxcdTFBNjAtXFx1MUE3Q1xcdTFBN0YtXFx1MUE4OVxcdTFBOTAtXFx1MUE5OVxcdTFBQTdcXHUxQjAwLVxcdTFCNEJcXHUxQjUwLVxcdTFCNTlcXHUxQjZCLVxcdTFCNzNcXHUxQjgwLVxcdTFCRjNcXHUxQzAwLVxcdTFDMzdcXHUxQzQwLVxcdTFDNDlcXHUxQzRELVxcdTFDN0RcXHUxQ0QwLVxcdTFDRDJcXHUxQ0Q0LVxcdTFDRjZcXHUxRDAwLVxcdTFERTZcXHUxREZDLVxcdTFGMTVcXHUxRjE4LVxcdTFGMURcXHUxRjIwLVxcdTFGNDVcXHUxRjQ4LVxcdTFGNERcXHUxRjUwLVxcdTFGNTdcXHUxRjU5XFx1MUY1QlxcdTFGNURcXHUxRjVGLVxcdTFGN0RcXHUxRjgwLVxcdTFGQjRcXHUxRkI2LVxcdTFGQkNcXHUxRkJFXFx1MUZDMi1cXHUxRkM0XFx1MUZDNi1cXHUxRkNDXFx1MUZEMC1cXHUxRkQzXFx1MUZENi1cXHUxRkRCXFx1MUZFMC1cXHUxRkVDXFx1MUZGMi1cXHUxRkY0XFx1MUZGNi1cXHUxRkZDXFx1MjAwQ1xcdTIwMERcXHUyMDNGXFx1MjA0MFxcdTIwNTRcXHUyMDcxXFx1MjA3RlxcdTIwOTAtXFx1MjA5Q1xcdTIwRDAtXFx1MjBEQ1xcdTIwRTFcXHUyMEU1LVxcdTIwRjBcXHUyMTAyXFx1MjEwN1xcdTIxMEEtXFx1MjExM1xcdTIxMTVcXHUyMTE5LVxcdTIxMURcXHUyMTI0XFx1MjEyNlxcdTIxMjhcXHUyMTJBLVxcdTIxMkRcXHUyMTJGLVxcdTIxMzlcXHUyMTNDLVxcdTIxM0ZcXHUyMTQ1LVxcdTIxNDlcXHUyMTRFXFx1MjE2MC1cXHUyMTg4XFx1MkMwMC1cXHUyQzJFXFx1MkMzMC1cXHUyQzVFXFx1MkM2MC1cXHUyQ0U0XFx1MkNFQi1cXHUyQ0YzXFx1MkQwMC1cXHUyRDI1XFx1MkQyN1xcdTJEMkRcXHUyRDMwLVxcdTJENjdcXHUyRDZGXFx1MkQ3Ri1cXHUyRDk2XFx1MkRBMC1cXHUyREE2XFx1MkRBOC1cXHUyREFFXFx1MkRCMC1cXHUyREI2XFx1MkRCOC1cXHUyREJFXFx1MkRDMC1cXHUyREM2XFx1MkRDOC1cXHUyRENFXFx1MkREMC1cXHUyREQ2XFx1MkREOC1cXHUyRERFXFx1MkRFMC1cXHUyREZGXFx1MkUyRlxcdTMwMDUtXFx1MzAwN1xcdTMwMjEtXFx1MzAyRlxcdTMwMzEtXFx1MzAzNVxcdTMwMzgtXFx1MzAzQ1xcdTMwNDEtXFx1MzA5NlxcdTMwOTlcXHUzMDlBXFx1MzA5RC1cXHUzMDlGXFx1MzBBMS1cXHUzMEZBXFx1MzBGQy1cXHUzMEZGXFx1MzEwNS1cXHUzMTJEXFx1MzEzMS1cXHUzMThFXFx1MzFBMC1cXHUzMUJBXFx1MzFGMC1cXHUzMUZGXFx1MzQwMC1cXHU0REI1XFx1NEUwMC1cXHU5RkNDXFx1QTAwMC1cXHVBNDhDXFx1QTREMC1cXHVBNEZEXFx1QTUwMC1cXHVBNjBDXFx1QTYxMC1cXHVBNjJCXFx1QTY0MC1cXHVBNjZGXFx1QTY3NC1cXHVBNjdEXFx1QTY3Ri1cXHVBNjk3XFx1QTY5Ri1cXHVBNkYxXFx1QTcxNy1cXHVBNzFGXFx1QTcyMi1cXHVBNzg4XFx1QTc4Qi1cXHVBNzhFXFx1QTc5MC1cXHVBNzkzXFx1QTdBMC1cXHVBN0FBXFx1QTdGOC1cXHVBODI3XFx1QTg0MC1cXHVBODczXFx1QTg4MC1cXHVBOEM0XFx1QThEMC1cXHVBOEQ5XFx1QThFMC1cXHVBOEY3XFx1QThGQlxcdUE5MDAtXFx1QTkyRFxcdUE5MzAtXFx1QTk1M1xcdUE5NjAtXFx1QTk3Q1xcdUE5ODAtXFx1QTlDMFxcdUE5Q0YtXFx1QTlEOVxcdUFBMDAtXFx1QUEzNlxcdUFBNDAtXFx1QUE0RFxcdUFBNTAtXFx1QUE1OVxcdUFBNjAtXFx1QUE3NlxcdUFBN0FcXHVBQTdCXFx1QUE4MC1cXHVBQUMyXFx1QUFEQi1cXHVBQUREXFx1QUFFMC1cXHVBQUVGXFx1QUFGMi1cXHVBQUY2XFx1QUIwMS1cXHVBQjA2XFx1QUIwOS1cXHVBQjBFXFx1QUIxMS1cXHVBQjE2XFx1QUIyMC1cXHVBQjI2XFx1QUIyOC1cXHVBQjJFXFx1QUJDMC1cXHVBQkVBXFx1QUJFQ1xcdUFCRURcXHVBQkYwLVxcdUFCRjlcXHVBQzAwLVxcdUQ3QTNcXHVEN0IwLVxcdUQ3QzZcXHVEN0NCLVxcdUQ3RkJcXHVGOTAwLVxcdUZBNkRcXHVGQTcwLVxcdUZBRDlcXHVGQjAwLVxcdUZCMDZcXHVGQjEzLVxcdUZCMTdcXHVGQjFELVxcdUZCMjhcXHVGQjJBLVxcdUZCMzZcXHVGQjM4LVxcdUZCM0NcXHVGQjNFXFx1RkI0MFxcdUZCNDFcXHVGQjQzXFx1RkI0NFxcdUZCNDYtXFx1RkJCMVxcdUZCRDMtXFx1RkQzRFxcdUZENTAtXFx1RkQ4RlxcdUZEOTItXFx1RkRDN1xcdUZERjAtXFx1RkRGQlxcdUZFMDAtXFx1RkUwRlxcdUZFMjAtXFx1RkUyNlxcdUZFMzNcXHVGRTM0XFx1RkU0RC1cXHVGRTRGXFx1RkU3MC1cXHVGRTc0XFx1RkU3Ni1cXHVGRUZDXFx1RkYxMC1cXHVGRjE5XFx1RkYyMS1cXHVGRjNBXFx1RkYzRlxcdUZGNDEtXFx1RkY1QVxcdUZGNjYtXFx1RkZCRVxcdUZGQzItXFx1RkZDN1xcdUZGQ0EtXFx1RkZDRlxcdUZGRDItXFx1RkZEN1xcdUZGREEtXFx1RkZEQ11cIiksXG4gICAgTGVhZGluZ1plcm9zOiBuZXcgUmVnRXhwKFwiXjArKD8hJClcIilcbn07XG5cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBQdWJsaWNcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gICAgUmVnZXg6IFJlZ2V4LFxuXG4gICAgaXNEZWNpbWFsRGlnaXQ6IGZ1bmN0aW9uKGNoKSB7XG4gICAgICAgIHJldHVybiAoY2ggPj0gNDggJiYgY2ggPD0gNTcpOyAgIC8vIDAuLjlcbiAgICB9LFxuXG4gICAgaXNIZXhEaWdpdDogZnVuY3Rpb24oY2gpIHtcbiAgICAgICAgcmV0dXJuIFwiMDEyMzQ1Njc4OWFiY2RlZkFCQ0RFRlwiLmluZGV4T2YoY2gpID49IDA7XG4gICAgfSxcblxuICAgIGlzT2N0YWxEaWdpdDogZnVuY3Rpb24oY2gpIHtcbiAgICAgICAgcmV0dXJuIFwiMDEyMzQ1NjdcIi5pbmRleE9mKGNoKSA+PSAwO1xuICAgIH0sXG5cbiAgICAvLyA3LjIgV2hpdGUgU3BhY2VcblxuICAgIGlzV2hpdGVTcGFjZTogZnVuY3Rpb24oY2gpIHtcbiAgICAgICAgcmV0dXJuIChjaCA9PT0gMHgyMCkgfHwgKGNoID09PSAweDA5KSB8fCAoY2ggPT09IDB4MEIpIHx8IChjaCA9PT0gMHgwQykgfHwgKGNoID09PSAweEEwKSB8fFxuICAgICAgICAgICAgKGNoID49IDB4MTY4MCAmJiBbMHgxNjgwLCAweDE4MEUsIDB4MjAwMCwgMHgyMDAxLCAweDIwMDIsIDB4MjAwMywgMHgyMDA0LCAweDIwMDUsIDB4MjAwNiwgMHgyMDA3LCAweDIwMDgsIDB4MjAwOSwgMHgyMDBBLCAweDIwMkYsIDB4MjA1RiwgMHgzMDAwLCAweEZFRkZdLmluZGV4T2YoY2gpID49IDApO1xuICAgIH0sXG5cbiAgICAvLyA3LjMgTGluZSBUZXJtaW5hdG9yc1xuXG4gICAgaXNMaW5lVGVybWluYXRvcjogZnVuY3Rpb24oY2gpIHtcbiAgICAgICAgcmV0dXJuIChjaCA9PT0gMHgwQSkgfHwgKGNoID09PSAweDBEKSB8fCAoY2ggPT09IDB4MjAyOCkgfHwgKGNoID09PSAweDIwMjkpO1xuICAgIH0sXG5cbiAgICAvLyA3LjYgSWRlbnRpZmllciBOYW1lcyBhbmQgSWRlbnRpZmllcnNcblxuICAgIGlzSWRlbnRpZmllclN0YXJ0OiBmdW5jdGlvbihjaCkge1xuICAgICAgICByZXR1cm4gKGNoID09PSAweDI0KSB8fCAoY2ggPT09IDB4NUYpIHx8ICAvLyAkIChkb2xsYXIpIGFuZCBfICh1bmRlcnNjb3JlKVxuICAgICAgICAgICAgKGNoID49IDB4NDEgJiYgY2ggPD0gMHg1QSkgfHwgICAgICAgICAvLyBBLi5aXG4gICAgICAgICAgICAoY2ggPj0gMHg2MSAmJiBjaCA8PSAweDdBKSB8fCAgICAgICAgIC8vIGEuLnpcbiAgICAgICAgICAgIChjaCA9PT0gMHg1QykgfHwgICAgICAgICAgICAgICAgICAgICAgLy8gXFwgKGJhY2tzbGFzaClcbiAgICAgICAgICAgICgoY2ggPj0gMHg4MCkgJiYgUmVnZXguTm9uQXNjaWlJZGVudGlmaWVyU3RhcnQudGVzdChTdHJpbmcuZnJvbUNoYXJDb2RlKGNoKSkpO1xuICAgIH0sXG5cbiAgICBpc0lkZW50aWZpZXJQYXJ0OiBmdW5jdGlvbihjaCkge1xuICAgICAgICByZXR1cm4gKGNoID09PSAweDI0KSB8fCAoY2ggPT09IDB4NUYpIHx8ICAvLyAkIChkb2xsYXIpIGFuZCBfICh1bmRlcnNjb3JlKVxuICAgICAgICAgICAgKGNoID49IDB4NDEgJiYgY2ggPD0gMHg1QSkgfHwgICAgICAgICAvLyBBLi5aXG4gICAgICAgICAgICAoY2ggPj0gMHg2MSAmJiBjaCA8PSAweDdBKSB8fCAgICAgICAgIC8vIGEuLnpcbiAgICAgICAgICAgIChjaCA+PSAweDMwICYmIGNoIDw9IDB4MzkpIHx8ICAgICAgICAgLy8gMC4uOVxuICAgICAgICAgICAgKGNoID09PSAweDVDKSB8fCAgICAgICAgICAgICAgICAgICAgICAvLyBcXCAoYmFja3NsYXNoKVxuICAgICAgICAgICAgKChjaCA+PSAweDgwKSAmJiBSZWdleC5Ob25Bc2NpaUlkZW50aWZpZXJQYXJ0LnRlc3QoU3RyaW5nLmZyb21DaGFyQ29kZShjaCkpKTtcbiAgICB9LFxuXG4gICAgLy8gNy42LjEuMiBGdXR1cmUgUmVzZXJ2ZWQgV29yZHNcblxuICAgIGlzRnV0dXJlUmVzZXJ2ZWRXb3JkOiBmdW5jdGlvbihpZCkge1xuICAgICAgICBzd2l0Y2ggKGlkKSB7XG4gICAgICAgICAgICBjYXNlIFwiY2xhc3NcIjpcbiAgICAgICAgICAgIGNhc2UgXCJlbnVtXCI6XG4gICAgICAgICAgICBjYXNlIFwiZXhwb3J0XCI6XG4gICAgICAgICAgICBjYXNlIFwiZXh0ZW5kc1wiOlxuICAgICAgICAgICAgY2FzZSBcImltcG9ydFwiOlxuICAgICAgICAgICAgY2FzZSBcInN1cGVyXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBpc1N0cmljdE1vZGVSZXNlcnZlZFdvcmQ6IGZ1bmN0aW9uKGlkKSB7XG4gICAgICAgIHN3aXRjaCAoaWQpIHtcbiAgICAgICAgICAgIGNhc2UgXCJpbXBsZW1lbnRzXCI6XG4gICAgICAgICAgICBjYXNlIFwiaW50ZXJmYWNlXCI6XG4gICAgICAgICAgICBjYXNlIFwicGFja2FnZVwiOlxuICAgICAgICAgICAgY2FzZSBcInByaXZhdGVcIjpcbiAgICAgICAgICAgIGNhc2UgXCJwcm90ZWN0ZWRcIjpcbiAgICAgICAgICAgIGNhc2UgXCJwdWJsaWNcIjpcbiAgICAgICAgICAgIGNhc2UgXCJzdGF0aWNcIjpcbiAgICAgICAgICAgIGNhc2UgXCJ5aWVsZFwiOlxuICAgICAgICAgICAgY2FzZSBcImxldFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgaXNSZXN0cmljdGVkV29yZDogZnVuY3Rpb24oaWQpIHtcbiAgICAgICAgcmV0dXJuIGlkID09PSBcImV2YWxcIiB8fCBpZCA9PT0gXCJhcmd1bWVudHNcIjtcbiAgICB9LFxuXG4gICAgLy8gNy42LjEuMSBLZXl3b3Jkc1xuXG4gICAgaXNLZXl3b3JkOiBmdW5jdGlvbihpZCwgc3RyaWN0LCBlY21hRmVhdHVyZXMpIHtcblxuICAgICAgICBpZiAoc3RyaWN0ICYmIHRoaXMuaXNTdHJpY3RNb2RlUmVzZXJ2ZWRXb3JkKGlkKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBcImNvbnN0XCIgaXMgc3BlY2lhbGl6ZWQgYXMgS2V5d29yZCBpbiBWOC5cbiAgICAgICAgLy8gXCJ5aWVsZFwiIGFuZCBcImxldFwiIGFyZSBmb3IgY29tcGF0aWJsaXR5IHdpdGggU3BpZGVyTW9ua2V5IGFuZCBFUy5uZXh0LlxuICAgICAgICAvLyBTb21lIG90aGVycyBhcmUgZnJvbSBmdXR1cmUgcmVzZXJ2ZWQgd29yZHMuXG5cbiAgICAgICAgc3dpdGNoIChpZC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICByZXR1cm4gKGlkID09PSBcImlmXCIpIHx8IChpZCA9PT0gXCJpblwiKSB8fCAoaWQgPT09IFwiZG9cIik7XG4gICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgcmV0dXJuIChpZCA9PT0gXCJ2YXJcIikgfHwgKGlkID09PSBcImZvclwiKSB8fCAoaWQgPT09IFwibmV3XCIpIHx8XG4gICAgICAgICAgICAgICAgICAgIChpZCA9PT0gXCJ0cnlcIikgfHwgKGlkID09PSBcImxldFwiKTtcbiAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICByZXR1cm4gKGlkID09PSBcInRoaXNcIikgfHwgKGlkID09PSBcImVsc2VcIikgfHwgKGlkID09PSBcImNhc2VcIikgfHxcbiAgICAgICAgICAgICAgICAgICAgKGlkID09PSBcInZvaWRcIikgfHwgKGlkID09PSBcIndpdGhcIikgfHwgKGlkID09PSBcImVudW1cIik7XG4gICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgcmV0dXJuIChpZCA9PT0gXCJ3aGlsZVwiKSB8fCAoaWQgPT09IFwiYnJlYWtcIikgfHwgKGlkID09PSBcImNhdGNoXCIpIHx8XG4gICAgICAgICAgICAgICAgICAgIChpZCA9PT0gXCJ0aHJvd1wiKSB8fCAoaWQgPT09IFwiY29uc3RcIikgfHwgKCFlY21hRmVhdHVyZXMuZ2VuZXJhdG9ycyAmJiBpZCA9PT0gXCJ5aWVsZFwiKSB8fFxuICAgICAgICAgICAgICAgICAgICAoaWQgPT09IFwiY2xhc3NcIikgfHwgKGlkID09PSBcInN1cGVyXCIpO1xuICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgIHJldHVybiAoaWQgPT09IFwicmV0dXJuXCIpIHx8IChpZCA9PT0gXCJ0eXBlb2ZcIikgfHwgKGlkID09PSBcImRlbGV0ZVwiKSB8fFxuICAgICAgICAgICAgICAgICAgICAoaWQgPT09IFwic3dpdGNoXCIpIHx8IChpZCA9PT0gXCJleHBvcnRcIikgfHwgKGlkID09PSBcImltcG9ydFwiKTtcbiAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgICByZXR1cm4gKGlkID09PSBcImRlZmF1bHRcIikgfHwgKGlkID09PSBcImZpbmFsbHlcIikgfHwgKGlkID09PSBcImV4dGVuZHNcIik7XG4gICAgICAgICAgICBjYXNlIDg6XG4gICAgICAgICAgICAgICAgcmV0dXJuIChpZCA9PT0gXCJmdW5jdGlvblwiKSB8fCAoaWQgPT09IFwiY29udGludWVcIikgfHwgKGlkID09PSBcImRlYnVnZ2VyXCIpO1xuICAgICAgICAgICAgY2FzZSAxMDpcbiAgICAgICAgICAgICAgICByZXR1cm4gKGlkID09PSBcImluc3RhbmNlb2ZcIik7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBpc0pTWElkZW50aWZpZXJTdGFydDogZnVuY3Rpb24oY2gpIHtcbiAgICAgICAgLy8gZXhjbHVkZSBiYWNrc2xhc2ggKFxcKVxuICAgICAgICByZXR1cm4gKGNoICE9PSA5MikgJiYgdGhpcy5pc0lkZW50aWZpZXJTdGFydChjaCk7XG4gICAgfSxcblxuICAgIGlzSlNYSWRlbnRpZmllclBhcnQ6IGZ1bmN0aW9uKGNoKSB7XG4gICAgICAgIC8vIGV4Y2x1ZGUgYmFja3NsYXNoIChcXCkgYW5kIGFkZCBoeXBoZW4gKC0pXG4gICAgICAgIHJldHVybiAoY2ggIT09IDkyKSAmJiAoY2ggPT09IDQ1IHx8IHRoaXMuaXNJZGVudGlmaWVyUGFydChjaCkpO1xuICAgIH1cblxuXG59O1xuIiwiLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IENvbnRhaW5zIHRva2VuIGluZm9ybWF0aW9uLlxuICogQGF1dGhvciBOaWNob2xhcyBDLiBaYWthc1xuICogQGNvcHlyaWdodCAyMDE0IE5pY2hvbGFzIEMuIFpha2FzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogQGNvcHlyaWdodCAyMDEzIFRoYWRkZWUgVHlsIDx0aGFkZGVlLnR5bEBnbWFpbC5jb20+XG4gKiBAY29weXJpZ2h0IDIwMTEtMjAxMyBBcml5YSBIaWRheWF0IDxhcml5YS5oaWRheWF0QGdtYWlsLmNvbT5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAqICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICogKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICogICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4gKiAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gKiBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cblwidXNlIHN0cmljdFwiO1xuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUmVxdWlyZW1lbnRzXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBOb25lIVxuXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUHJpdmF0ZVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxudmFyIFRva2VuID0ge1xuICAgIEJvb2xlYW5MaXRlcmFsOiAxLFxuICAgIEVPRjogMixcbiAgICBJZGVudGlmaWVyOiAzLFxuICAgIEtleXdvcmQ6IDQsXG4gICAgTnVsbExpdGVyYWw6IDUsXG4gICAgTnVtZXJpY0xpdGVyYWw6IDYsXG4gICAgUHVuY3R1YXRvcjogNyxcbiAgICBTdHJpbmdMaXRlcmFsOiA4LFxuICAgIFJlZ3VsYXJFeHByZXNzaW9uOiA5LFxuICAgIFRlbXBsYXRlOiAxMCxcbiAgICBKU1hJZGVudGlmaWVyOiAxMSxcbiAgICBKU1hUZXh0OiAxMlxufTtcblxudmFyIFRva2VuTmFtZSA9IHt9O1xuVG9rZW5OYW1lW1Rva2VuLkJvb2xlYW5MaXRlcmFsXSA9IFwiQm9vbGVhblwiO1xuVG9rZW5OYW1lW1Rva2VuLkVPRl0gPSBcIjxlbmQ+XCI7XG5Ub2tlbk5hbWVbVG9rZW4uSWRlbnRpZmllcl0gPSBcIklkZW50aWZpZXJcIjtcblRva2VuTmFtZVtUb2tlbi5LZXl3b3JkXSA9IFwiS2V5d29yZFwiO1xuVG9rZW5OYW1lW1Rva2VuLk51bGxMaXRlcmFsXSA9IFwiTnVsbFwiO1xuVG9rZW5OYW1lW1Rva2VuLk51bWVyaWNMaXRlcmFsXSA9IFwiTnVtZXJpY1wiO1xuVG9rZW5OYW1lW1Rva2VuLlB1bmN0dWF0b3JdID0gXCJQdW5jdHVhdG9yXCI7XG5Ub2tlbk5hbWVbVG9rZW4uU3RyaW5nTGl0ZXJhbF0gPSBcIlN0cmluZ1wiO1xuVG9rZW5OYW1lW1Rva2VuLlJlZ3VsYXJFeHByZXNzaW9uXSA9IFwiUmVndWxhckV4cHJlc3Npb25cIjtcblRva2VuTmFtZVtUb2tlbi5UZW1wbGF0ZV0gPSBcIlRlbXBsYXRlXCI7XG5Ub2tlbk5hbWVbVG9rZW4uSlNYSWRlbnRpZmllcl0gPSBcIkpTWElkZW50aWZpZXJcIjtcblRva2VuTmFtZVtUb2tlbi5KU1hUZXh0XSA9IFwiSlNYVGV4dFwiO1xuXG4vLyBBIGZ1bmN0aW9uIGZvbGxvd2luZyBvbmUgb2YgdGhvc2UgdG9rZW5zIGlzIGFuIGV4cHJlc3Npb24uXG52YXIgRm5FeHByVG9rZW5zID0gW1wiKFwiLCBcIntcIiwgXCJbXCIsIFwiaW5cIiwgXCJ0eXBlb2ZcIiwgXCJpbnN0YW5jZW9mXCIsIFwibmV3XCIsXG4gICAgICAgICAgICAgICAgXCJyZXR1cm5cIiwgXCJjYXNlXCIsIFwiZGVsZXRlXCIsIFwidGhyb3dcIiwgXCJ2b2lkXCIsXG4gICAgICAgICAgICAgICAgLy8gYXNzaWdubWVudCBvcGVyYXRvcnNcbiAgICAgICAgICAgICAgICBcIj1cIiwgXCIrPVwiLCBcIi09XCIsIFwiKj1cIiwgXCIvPVwiLCBcIiU9XCIsIFwiPDw9XCIsIFwiPj49XCIsIFwiPj4+PVwiLFxuICAgICAgICAgICAgICAgIFwiJj1cIiwgXCJ8PVwiLCBcIl49XCIsIFwiLFwiLFxuICAgICAgICAgICAgICAgIC8vIGJpbmFyeS91bmFyeSBvcGVyYXRvcnNcbiAgICAgICAgICAgICAgICBcIitcIiwgXCItXCIsIFwiKlwiLCBcIi9cIiwgXCIlXCIsIFwiKytcIiwgXCItLVwiLCBcIjw8XCIsIFwiPj5cIiwgXCI+Pj5cIiwgXCImXCIsXG4gICAgICAgICAgICAgICAgXCJ8XCIsIFwiXlwiLCBcIiFcIiwgXCJ+XCIsIFwiJiZcIiwgXCJ8fFwiLCBcIj9cIiwgXCI6XCIsIFwiPT09XCIsIFwiPT1cIiwgXCI+PVwiLFxuICAgICAgICAgICAgICAgIFwiPD1cIiwgXCI8XCIsIFwiPlwiLCBcIiE9XCIsIFwiIT09XCJdO1xuXG5cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBQdWJsaWNcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIFRva2VuOiBUb2tlbixcbiAgICBUb2tlbk5hbWU6IFRva2VuTmFtZSxcbiAgICBGbkV4cHJUb2tlbnM6IEZuRXhwclRva2Vuc1xufTtcbiIsIi8qKlxuICogQGZpbGVvdmVydmlldyBUaGUgbGlzdCBvZiBYSFRNTCBlbnRpdGllcyB0aGF0IGFyZSB2YWxpZCBpbiBKU1guXG4gKiBAYXV0aG9yIE5pY2hvbGFzIEMuIFpha2FzXG4gKiBAY29weXJpZ2h0IDIwMTQgTmljaG9sYXMgQy4gWmFrYXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gKiAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAqICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuICogICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuICogQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxuICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcbiAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxuICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuICogVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJlcXVpcmVtZW50c1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gTm9uZSFcblxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFB1YmxpY1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgcXVvdDogXCJcXHUwMDIyXCIsXG4gICAgYW1wOiBcIiZcIixcbiAgICBhcG9zOiBcIlxcdTAwMjdcIixcbiAgICBsdDogXCI8XCIsXG4gICAgZ3Q6IFwiPlwiLFxuICAgIG5ic3A6IFwiXFx1MDBBMFwiLFxuICAgIGlleGNsOiBcIlxcdTAwQTFcIixcbiAgICBjZW50OiBcIlxcdTAwQTJcIixcbiAgICBwb3VuZDogXCJcXHUwMEEzXCIsXG4gICAgY3VycmVuOiBcIlxcdTAwQTRcIixcbiAgICB5ZW46IFwiXFx1MDBBNVwiLFxuICAgIGJydmJhcjogXCJcXHUwMEE2XCIsXG4gICAgc2VjdDogXCJcXHUwMEE3XCIsXG4gICAgdW1sOiBcIlxcdTAwQThcIixcbiAgICBjb3B5OiBcIlxcdTAwQTlcIixcbiAgICBvcmRmOiBcIlxcdTAwQUFcIixcbiAgICBsYXF1bzogXCJcXHUwMEFCXCIsXG4gICAgbm90OiBcIlxcdTAwQUNcIixcbiAgICBzaHk6IFwiXFx1MDBBRFwiLFxuICAgIHJlZzogXCJcXHUwMEFFXCIsXG4gICAgbWFjcjogXCJcXHUwMEFGXCIsXG4gICAgZGVnOiBcIlxcdTAwQjBcIixcbiAgICBwbHVzbW46IFwiXFx1MDBCMVwiLFxuICAgIHN1cDI6IFwiXFx1MDBCMlwiLFxuICAgIHN1cDM6IFwiXFx1MDBCM1wiLFxuICAgIGFjdXRlOiBcIlxcdTAwQjRcIixcbiAgICBtaWNybzogXCJcXHUwMEI1XCIsXG4gICAgcGFyYTogXCJcXHUwMEI2XCIsXG4gICAgbWlkZG90OiBcIlxcdTAwQjdcIixcbiAgICBjZWRpbDogXCJcXHUwMEI4XCIsXG4gICAgc3VwMTogXCJcXHUwMEI5XCIsXG4gICAgb3JkbTogXCJcXHUwMEJBXCIsXG4gICAgcmFxdW86IFwiXFx1MDBCQlwiLFxuICAgIGZyYWMxNDogXCJcXHUwMEJDXCIsXG4gICAgZnJhYzEyOiBcIlxcdTAwQkRcIixcbiAgICBmcmFjMzQ6IFwiXFx1MDBCRVwiLFxuICAgIGlxdWVzdDogXCJcXHUwMEJGXCIsXG4gICAgQWdyYXZlOiBcIlxcdTAwQzBcIixcbiAgICBBYWN1dGU6IFwiXFx1MDBDMVwiLFxuICAgIEFjaXJjOiBcIlxcdTAwQzJcIixcbiAgICBBdGlsZGU6IFwiXFx1MDBDM1wiLFxuICAgIEF1bWw6IFwiXFx1MDBDNFwiLFxuICAgIEFyaW5nOiBcIlxcdTAwQzVcIixcbiAgICBBRWxpZzogXCJcXHUwMEM2XCIsXG4gICAgQ2NlZGlsOiBcIlxcdTAwQzdcIixcbiAgICBFZ3JhdmU6IFwiXFx1MDBDOFwiLFxuICAgIEVhY3V0ZTogXCJcXHUwMEM5XCIsXG4gICAgRWNpcmM6IFwiXFx1MDBDQVwiLFxuICAgIEV1bWw6IFwiXFx1MDBDQlwiLFxuICAgIElncmF2ZTogXCJcXHUwMENDXCIsXG4gICAgSWFjdXRlOiBcIlxcdTAwQ0RcIixcbiAgICBJY2lyYzogXCJcXHUwMENFXCIsXG4gICAgSXVtbDogXCJcXHUwMENGXCIsXG4gICAgRVRIOiBcIlxcdTAwRDBcIixcbiAgICBOdGlsZGU6IFwiXFx1MDBEMVwiLFxuICAgIE9ncmF2ZTogXCJcXHUwMEQyXCIsXG4gICAgT2FjdXRlOiBcIlxcdTAwRDNcIixcbiAgICBPY2lyYzogXCJcXHUwMEQ0XCIsXG4gICAgT3RpbGRlOiBcIlxcdTAwRDVcIixcbiAgICBPdW1sOiBcIlxcdTAwRDZcIixcbiAgICB0aW1lczogXCJcXHUwMEQ3XCIsXG4gICAgT3NsYXNoOiBcIlxcdTAwRDhcIixcbiAgICBVZ3JhdmU6IFwiXFx1MDBEOVwiLFxuICAgIFVhY3V0ZTogXCJcXHUwMERBXCIsXG4gICAgVWNpcmM6IFwiXFx1MDBEQlwiLFxuICAgIFV1bWw6IFwiXFx1MDBEQ1wiLFxuICAgIFlhY3V0ZTogXCJcXHUwMEREXCIsXG4gICAgVEhPUk46IFwiXFx1MDBERVwiLFxuICAgIHN6bGlnOiBcIlxcdTAwREZcIixcbiAgICBhZ3JhdmU6IFwiXFx1MDBFMFwiLFxuICAgIGFhY3V0ZTogXCJcXHUwMEUxXCIsXG4gICAgYWNpcmM6IFwiXFx1MDBFMlwiLFxuICAgIGF0aWxkZTogXCJcXHUwMEUzXCIsXG4gICAgYXVtbDogXCJcXHUwMEU0XCIsXG4gICAgYXJpbmc6IFwiXFx1MDBFNVwiLFxuICAgIGFlbGlnOiBcIlxcdTAwRTZcIixcbiAgICBjY2VkaWw6IFwiXFx1MDBFN1wiLFxuICAgIGVncmF2ZTogXCJcXHUwMEU4XCIsXG4gICAgZWFjdXRlOiBcIlxcdTAwRTlcIixcbiAgICBlY2lyYzogXCJcXHUwMEVBXCIsXG4gICAgZXVtbDogXCJcXHUwMEVCXCIsXG4gICAgaWdyYXZlOiBcIlxcdTAwRUNcIixcbiAgICBpYWN1dGU6IFwiXFx1MDBFRFwiLFxuICAgIGljaXJjOiBcIlxcdTAwRUVcIixcbiAgICBpdW1sOiBcIlxcdTAwRUZcIixcbiAgICBldGg6IFwiXFx1MDBGMFwiLFxuICAgIG50aWxkZTogXCJcXHUwMEYxXCIsXG4gICAgb2dyYXZlOiBcIlxcdTAwRjJcIixcbiAgICBvYWN1dGU6IFwiXFx1MDBGM1wiLFxuICAgIG9jaXJjOiBcIlxcdTAwRjRcIixcbiAgICBvdGlsZGU6IFwiXFx1MDBGNVwiLFxuICAgIG91bWw6IFwiXFx1MDBGNlwiLFxuICAgIGRpdmlkZTogXCJcXHUwMEY3XCIsXG4gICAgb3NsYXNoOiBcIlxcdTAwRjhcIixcbiAgICB1Z3JhdmU6IFwiXFx1MDBGOVwiLFxuICAgIHVhY3V0ZTogXCJcXHUwMEZBXCIsXG4gICAgdWNpcmM6IFwiXFx1MDBGQlwiLFxuICAgIHV1bWw6IFwiXFx1MDBGQ1wiLFxuICAgIHlhY3V0ZTogXCJcXHUwMEZEXCIsXG4gICAgdGhvcm46IFwiXFx1MDBGRVwiLFxuICAgIHl1bWw6IFwiXFx1MDBGRlwiLFxuICAgIE9FbGlnOiBcIlxcdTAxNTJcIixcbiAgICBvZWxpZzogXCJcXHUwMTUzXCIsXG4gICAgU2Nhcm9uOiBcIlxcdTAxNjBcIixcbiAgICBzY2Fyb246IFwiXFx1MDE2MVwiLFxuICAgIFl1bWw6IFwiXFx1MDE3OFwiLFxuICAgIGZub2Y6IFwiXFx1MDE5MlwiLFxuICAgIGNpcmM6IFwiXFx1MDJDNlwiLFxuICAgIHRpbGRlOiBcIlxcdTAyRENcIixcbiAgICBBbHBoYTogXCJcXHUwMzkxXCIsXG4gICAgQmV0YTogXCJcXHUwMzkyXCIsXG4gICAgR2FtbWE6IFwiXFx1MDM5M1wiLFxuICAgIERlbHRhOiBcIlxcdTAzOTRcIixcbiAgICBFcHNpbG9uOiBcIlxcdTAzOTVcIixcbiAgICBaZXRhOiBcIlxcdTAzOTZcIixcbiAgICBFdGE6IFwiXFx1MDM5N1wiLFxuICAgIFRoZXRhOiBcIlxcdTAzOThcIixcbiAgICBJb3RhOiBcIlxcdTAzOTlcIixcbiAgICBLYXBwYTogXCJcXHUwMzlBXCIsXG4gICAgTGFtYmRhOiBcIlxcdTAzOUJcIixcbiAgICBNdTogXCJcXHUwMzlDXCIsXG4gICAgTnU6IFwiXFx1MDM5RFwiLFxuICAgIFhpOiBcIlxcdTAzOUVcIixcbiAgICBPbWljcm9uOiBcIlxcdTAzOUZcIixcbiAgICBQaTogXCJcXHUwM0EwXCIsXG4gICAgUmhvOiBcIlxcdTAzQTFcIixcbiAgICBTaWdtYTogXCJcXHUwM0EzXCIsXG4gICAgVGF1OiBcIlxcdTAzQTRcIixcbiAgICBVcHNpbG9uOiBcIlxcdTAzQTVcIixcbiAgICBQaGk6IFwiXFx1MDNBNlwiLFxuICAgIENoaTogXCJcXHUwM0E3XCIsXG4gICAgUHNpOiBcIlxcdTAzQThcIixcbiAgICBPbWVnYTogXCJcXHUwM0E5XCIsXG4gICAgYWxwaGE6IFwiXFx1MDNCMVwiLFxuICAgIGJldGE6IFwiXFx1MDNCMlwiLFxuICAgIGdhbW1hOiBcIlxcdTAzQjNcIixcbiAgICBkZWx0YTogXCJcXHUwM0I0XCIsXG4gICAgZXBzaWxvbjogXCJcXHUwM0I1XCIsXG4gICAgemV0YTogXCJcXHUwM0I2XCIsXG4gICAgZXRhOiBcIlxcdTAzQjdcIixcbiAgICB0aGV0YTogXCJcXHUwM0I4XCIsXG4gICAgaW90YTogXCJcXHUwM0I5XCIsXG4gICAga2FwcGE6IFwiXFx1MDNCQVwiLFxuICAgIGxhbWJkYTogXCJcXHUwM0JCXCIsXG4gICAgbXU6IFwiXFx1MDNCQ1wiLFxuICAgIG51OiBcIlxcdTAzQkRcIixcbiAgICB4aTogXCJcXHUwM0JFXCIsXG4gICAgb21pY3JvbjogXCJcXHUwM0JGXCIsXG4gICAgcGk6IFwiXFx1MDNDMFwiLFxuICAgIHJobzogXCJcXHUwM0MxXCIsXG4gICAgc2lnbWFmOiBcIlxcdTAzQzJcIixcbiAgICBzaWdtYTogXCJcXHUwM0MzXCIsXG4gICAgdGF1OiBcIlxcdTAzQzRcIixcbiAgICB1cHNpbG9uOiBcIlxcdTAzQzVcIixcbiAgICBwaGk6IFwiXFx1MDNDNlwiLFxuICAgIGNoaTogXCJcXHUwM0M3XCIsXG4gICAgcHNpOiBcIlxcdTAzQzhcIixcbiAgICBvbWVnYTogXCJcXHUwM0M5XCIsXG4gICAgdGhldGFzeW06IFwiXFx1MDNEMVwiLFxuICAgIHVwc2loOiBcIlxcdTAzRDJcIixcbiAgICBwaXY6IFwiXFx1MDNENlwiLFxuICAgIGVuc3A6IFwiXFx1MjAwMlwiLFxuICAgIGVtc3A6IFwiXFx1MjAwM1wiLFxuICAgIHRoaW5zcDogXCJcXHUyMDA5XCIsXG4gICAgenduajogXCJcXHUyMDBDXCIsXG4gICAgendqOiBcIlxcdTIwMERcIixcbiAgICBscm06IFwiXFx1MjAwRVwiLFxuICAgIHJsbTogXCJcXHUyMDBGXCIsXG4gICAgbmRhc2g6IFwiXFx1MjAxM1wiLFxuICAgIG1kYXNoOiBcIlxcdTIwMTRcIixcbiAgICBsc3F1bzogXCJcXHUyMDE4XCIsXG4gICAgcnNxdW86IFwiXFx1MjAxOVwiLFxuICAgIHNicXVvOiBcIlxcdTIwMUFcIixcbiAgICBsZHF1bzogXCJcXHUyMDFDXCIsXG4gICAgcmRxdW86IFwiXFx1MjAxRFwiLFxuICAgIGJkcXVvOiBcIlxcdTIwMUVcIixcbiAgICBkYWdnZXI6IFwiXFx1MjAyMFwiLFxuICAgIERhZ2dlcjogXCJcXHUyMDIxXCIsXG4gICAgYnVsbDogXCJcXHUyMDIyXCIsXG4gICAgaGVsbGlwOiBcIlxcdTIwMjZcIixcbiAgICBwZXJtaWw6IFwiXFx1MjAzMFwiLFxuICAgIHByaW1lOiBcIlxcdTIwMzJcIixcbiAgICBQcmltZTogXCJcXHUyMDMzXCIsXG4gICAgbHNhcXVvOiBcIlxcdTIwMzlcIixcbiAgICByc2FxdW86IFwiXFx1MjAzQVwiLFxuICAgIG9saW5lOiBcIlxcdTIwM0VcIixcbiAgICBmcmFzbDogXCJcXHUyMDQ0XCIsXG4gICAgZXVybzogXCJcXHUyMEFDXCIsXG4gICAgaW1hZ2U6IFwiXFx1MjExMVwiLFxuICAgIHdlaWVycDogXCJcXHUyMTE4XCIsXG4gICAgcmVhbDogXCJcXHUyMTFDXCIsXG4gICAgdHJhZGU6IFwiXFx1MjEyMlwiLFxuICAgIGFsZWZzeW06IFwiXFx1MjEzNVwiLFxuICAgIGxhcnI6IFwiXFx1MjE5MFwiLFxuICAgIHVhcnI6IFwiXFx1MjE5MVwiLFxuICAgIHJhcnI6IFwiXFx1MjE5MlwiLFxuICAgIGRhcnI6IFwiXFx1MjE5M1wiLFxuICAgIGhhcnI6IFwiXFx1MjE5NFwiLFxuICAgIGNyYXJyOiBcIlxcdTIxQjVcIixcbiAgICBsQXJyOiBcIlxcdTIxRDBcIixcbiAgICB1QXJyOiBcIlxcdTIxRDFcIixcbiAgICByQXJyOiBcIlxcdTIxRDJcIixcbiAgICBkQXJyOiBcIlxcdTIxRDNcIixcbiAgICBoQXJyOiBcIlxcdTIxRDRcIixcbiAgICBmb3JhbGw6IFwiXFx1MjIwMFwiLFxuICAgIHBhcnQ6IFwiXFx1MjIwMlwiLFxuICAgIGV4aXN0OiBcIlxcdTIyMDNcIixcbiAgICBlbXB0eTogXCJcXHUyMjA1XCIsXG4gICAgbmFibGE6IFwiXFx1MjIwN1wiLFxuICAgIGlzaW46IFwiXFx1MjIwOFwiLFxuICAgIG5vdGluOiBcIlxcdTIyMDlcIixcbiAgICBuaTogXCJcXHUyMjBCXCIsXG4gICAgcHJvZDogXCJcXHUyMjBGXCIsXG4gICAgc3VtOiBcIlxcdTIyMTFcIixcbiAgICBtaW51czogXCJcXHUyMjEyXCIsXG4gICAgbG93YXN0OiBcIlxcdTIyMTdcIixcbiAgICByYWRpYzogXCJcXHUyMjFBXCIsXG4gICAgcHJvcDogXCJcXHUyMjFEXCIsXG4gICAgaW5maW46IFwiXFx1MjIxRVwiLFxuICAgIGFuZzogXCJcXHUyMjIwXCIsXG4gICAgYW5kOiBcIlxcdTIyMjdcIixcbiAgICBvcjogXCJcXHUyMjI4XCIsXG4gICAgY2FwOiBcIlxcdTIyMjlcIixcbiAgICBjdXA6IFwiXFx1MjIyQVwiLFxuICAgIFwiaW50XCI6IFwiXFx1MjIyQlwiLFxuICAgIHRoZXJlNDogXCJcXHUyMjM0XCIsXG4gICAgc2ltOiBcIlxcdTIyM0NcIixcbiAgICBjb25nOiBcIlxcdTIyNDVcIixcbiAgICBhc3ltcDogXCJcXHUyMjQ4XCIsXG4gICAgbmU6IFwiXFx1MjI2MFwiLFxuICAgIGVxdWl2OiBcIlxcdTIyNjFcIixcbiAgICBsZTogXCJcXHUyMjY0XCIsXG4gICAgZ2U6IFwiXFx1MjI2NVwiLFxuICAgIHN1YjogXCJcXHUyMjgyXCIsXG4gICAgc3VwOiBcIlxcdTIyODNcIixcbiAgICBuc3ViOiBcIlxcdTIyODRcIixcbiAgICBzdWJlOiBcIlxcdTIyODZcIixcbiAgICBzdXBlOiBcIlxcdTIyODdcIixcbiAgICBvcGx1czogXCJcXHUyMjk1XCIsXG4gICAgb3RpbWVzOiBcIlxcdTIyOTdcIixcbiAgICBwZXJwOiBcIlxcdTIyQTVcIixcbiAgICBzZG90OiBcIlxcdTIyQzVcIixcbiAgICBsY2VpbDogXCJcXHUyMzA4XCIsXG4gICAgcmNlaWw6IFwiXFx1MjMwOVwiLFxuICAgIGxmbG9vcjogXCJcXHUyMzBBXCIsXG4gICAgcmZsb29yOiBcIlxcdTIzMEJcIixcbiAgICBsYW5nOiBcIlxcdTIzMjlcIixcbiAgICByYW5nOiBcIlxcdTIzMkFcIixcbiAgICBsb3o6IFwiXFx1MjVDQVwiLFxuICAgIHNwYWRlczogXCJcXHUyNjYwXCIsXG4gICAgY2x1YnM6IFwiXFx1MjY2M1wiLFxuICAgIGhlYXJ0czogXCJcXHUyNjY1XCIsXG4gICAgZGlhbXM6IFwiXFx1MjY2NlwiXG59O1xuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcIm5hbWVcIjogXCJlc3ByZWVcIixcbiAgXCJkZXNjcmlwdGlvblwiOiBcIkFuIGFjdGl2ZWx5LW1haW50YWluZWQgZm9yayBvZiBFc3ByaW1hLCB0aGUgRUNNQVNjcmlwdCBwYXJzaW5nIGluZnJhc3RydWN0dXJlIGZvciBtdWx0aXB1cnBvc2UgYW5hbHlzaXNcIixcbiAgXCJhdXRob3JcIjoge1xuICAgIFwibmFtZVwiOiBcIk5pY2hvbGFzIEMuIFpha2FzXCIsXG4gICAgXCJlbWFpbFwiOiBcIm5pY2hvbGFzK25wbUBuY3pjb25zdWx0aW5nLmNvbVwiXG4gIH0sXG4gIFwiaG9tZXBhZ2VcIjogXCJodHRwczovL2dpdGh1Yi5jb20vZXNsaW50L2VzcHJlZVwiLFxuICBcIm1haW5cIjogXCJlc3ByZWUuanNcIixcbiAgXCJiaW5cIjoge1xuICAgIFwiZXNwYXJzZVwiOiBcIi4vYmluL2VzcGFyc2UuanNcIixcbiAgICBcImVzdmFsaWRhdGVcIjogXCIuL2Jpbi9lc3ZhbGlkYXRlLmpzXCJcbiAgfSxcbiAgXCJ2ZXJzaW9uXCI6IFwiMi4wLjNcIixcbiAgXCJmaWxlc1wiOiBbXG4gICAgXCJiaW5cIixcbiAgICBcImxpYlwiLFxuICAgIFwidGVzdC9ydW4uanNcIixcbiAgICBcInRlc3QvcnVubmVyLmpzXCIsXG4gICAgXCJ0ZXN0L3Rlc3QuanNcIixcbiAgICBcInRlc3QvY29tcGF0LmpzXCIsXG4gICAgXCJ0ZXN0L3JlZmxlY3QuanNcIixcbiAgICBcImVzcHJlZS5qc1wiXG4gIF0sXG4gIFwiZW5naW5lc1wiOiB7XG4gICAgXCJub2RlXCI6IFwiPj0wLjEwLjBcIlxuICB9LFxuICBcInJlcG9zaXRvcnlcIjoge1xuICAgIFwidHlwZVwiOiBcImdpdFwiLFxuICAgIFwidXJsXCI6IFwiaHR0cDovL2dpdGh1Yi5jb20vZXNsaW50L2VzcHJlZS5naXRcIlxuICB9LFxuICBcImJ1Z3NcIjoge1xuICAgIFwidXJsXCI6IFwiaHR0cDovL2dpdGh1Yi5jb20vZXNsaW50L2VzcHJlZS5naXRcIlxuICB9LFxuICBcImxpY2Vuc2VzXCI6IFtcbiAgICB7XG4gICAgICBcInR5cGVcIjogXCJCU0RcIixcbiAgICAgIFwidXJsXCI6IFwiaHR0cDovL2dpdGh1Yi5jb20vbnpha2FzL2VzcHJlZS9yYXcvbWFzdGVyL0xJQ0VOU0VcIlxuICAgIH1cbiAgXSxcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiYnJvd3NlcmlmeVwiOiBcIl43LjAuMFwiLFxuICAgIFwiY2hhaVwiOiBcIl4xLjEwLjBcIixcbiAgICBcImNvbXBsZXhpdHktcmVwb3J0XCI6IFwifjAuNi4xXCIsXG4gICAgXCJkYXRlZm9ybWF0XCI6IFwiXjEuMC4xMVwiLFxuICAgIFwiZXNsaW50XCI6IFwiXjAuOS4yXCIsXG4gICAgXCJlc3ByaW1hXCI6IFwiZ2l0Oi8vZ2l0aHViLmNvbS9qcXVlcnkvZXNwcmltYVwiLFxuICAgIFwiZXNwcmltYS1mYlwiOiBcIl44MDAxLjIwMDEuMC1kZXYtaGFybW9ueS1mYlwiLFxuICAgIFwiaXN0YW5idWxcIjogXCJ+MC4yLjZcIixcbiAgICBcImpzb24tZGlmZlwiOiBcIn4wLjMuMVwiLFxuICAgIFwibGVjaGVcIjogXCJeMS4wLjFcIixcbiAgICBcIm1vY2hhXCI6IFwiXjIuMC4xXCIsXG4gICAgXCJucG0tbGljZW5zZVwiOiBcIl4wLjIuM1wiLFxuICAgIFwib3B0aW1pc3RcIjogXCJ+MC42LjBcIixcbiAgICBcInJlZ2VuZXJhdGVcIjogXCJ+MC41LjRcIixcbiAgICBcInNlbXZlclwiOiBcIl40LjEuMVwiLFxuICAgIFwic2hlbGxqc1wiOiBcIl4wLjMuMFwiLFxuICAgIFwic2hlbGxqcy1ub2RlY2xpXCI6IFwiXjAuMS4xXCIsXG4gICAgXCJ1bmljb2RlLTYuMy4wXCI6IFwifjAuMS4wXCJcbiAgfSxcbiAgXCJrZXl3b3Jkc1wiOiBbXG4gICAgXCJhc3RcIixcbiAgICBcImVjbWFzY3JpcHRcIixcbiAgICBcImphdmFzY3JpcHRcIixcbiAgICBcInBhcnNlclwiLFxuICAgIFwic3ludGF4XCJcbiAgXSxcbiAgXCJzY3JpcHRzXCI6IHtcbiAgICBcImdlbmVyYXRlLXJlZ2V4XCI6IFwibm9kZSB0b29scy9nZW5lcmF0ZS1pZGVudGlmaWVyLXJlZ2V4LmpzXCIsXG4gICAgXCJ0ZXN0XCI6IFwibnBtIHJ1bi1zY3JpcHQgbGludCAmJiBub2RlIE1ha2VmaWxlLmpzIHRlc3QgJiYgbm9kZSB0ZXN0L3J1bi5qc1wiLFxuICAgIFwibGludFwiOiBcIm5vZGUgTWFrZWZpbGUuanMgbGludFwiLFxuICAgIFwicGF0Y2hcIjogXCJub2RlIE1ha2VmaWxlLmpzIHBhdGNoXCIsXG4gICAgXCJtaW5vclwiOiBcIm5vZGUgTWFrZWZpbGUuanMgbWlub3JcIixcbiAgICBcIm1ham9yXCI6IFwibm9kZSBNYWtlZmlsZS5qcyBtYWpvclwiLFxuICAgIFwiYnJvd3NlcmlmeVwiOiBcIm5vZGUgTWFrZWZpbGUuanMgYnJvd3NlcmlmeVwiLFxuICAgIFwiY292ZXJhZ2VcIjogXCJucG0gcnVuLXNjcmlwdCBhbmFseXplLWNvdmVyYWdlICYmIG5wbSBydW4tc2NyaXB0IGNoZWNrLWNvdmVyYWdlXCIsXG4gICAgXCJhbmFseXplLWNvdmVyYWdlXCI6IFwibm9kZSBub2RlX21vZHVsZXMvaXN0YW5idWwvbGliL2NsaS5qcyBjb3ZlciB0ZXN0L3J1bm5lci5qc1wiLFxuICAgIFwiY2hlY2stY292ZXJhZ2VcIjogXCJub2RlIG5vZGVfbW9kdWxlcy9pc3RhbmJ1bC9saWIvY2xpLmpzIGNoZWNrLWNvdmVyYWdlIC0tc3RhdGVtZW50IDk5IC0tYnJhbmNoIDk5IC0tZnVuY3Rpb24gOTlcIixcbiAgICBcImNvbXBsZXhpdHlcIjogXCJucG0gcnVuLXNjcmlwdCBhbmFseXplLWNvbXBsZXhpdHkgJiYgbnBtIHJ1bi1zY3JpcHQgY2hlY2stY29tcGxleGl0eVwiLFxuICAgIFwiYW5hbHl6ZS1jb21wbGV4aXR5XCI6IFwibm9kZSB0b29scy9saXN0LWNvbXBsZXhpdHkuanNcIixcbiAgICBcImNoZWNrLWNvbXBsZXhpdHlcIjogXCJub2RlIG5vZGVfbW9kdWxlcy9jb21wbGV4aXR5LXJlcG9ydC9zcmMvY2xpLmpzIC0tbWF4Y2MgMTQgLS1zaWxlbnQgLWwgLXcgZXNwcmVlLmpzXCIsXG4gICAgXCJiZW5jaG1hcmtcIjogXCJub2RlIHRlc3QvYmVuY2htYXJrcy5qc1wiLFxuICAgIFwiYmVuY2htYXJrLXF1aWNrXCI6IFwibm9kZSB0ZXN0L2JlbmNobWFya3MuanMgcXVpY2tcIlxuICB9LFxuICBcImRlcGVuZGVuY2llc1wiOiB7fSxcbiAgXCJnaXRIZWFkXCI6IFwiYjYwYjU5N2NmZTQ4MzRhYWNkMTZjOTAxNzljZTczZTIyNzA1YzEzMlwiLFxuICBcIl9pZFwiOiBcImVzcHJlZUAyLjAuM1wiLFxuICBcIl9zaGFzdW1cIjogXCIxZmJkZmY2MGE0MTBiZDBkNDE2YjFhYjNkNjIzMGQzNGI3YTQ1MGUxXCIsXG4gIFwiX2Zyb21cIjogXCJlc3ByZWVAPj0yLjAuMSA8My4wLjBcIixcbiAgXCJfbnBtVmVyc2lvblwiOiBcIjEuNC4yOFwiLFxuICBcIl9ucG1Vc2VyXCI6IHtcbiAgICBcIm5hbWVcIjogXCJuemFrYXNcIixcbiAgICBcImVtYWlsXCI6IFwibmljaG9sYXNAbmN6Y29uc3VsdGluZy5jb21cIlxuICB9LFxuICBcIm1haW50YWluZXJzXCI6IFtcbiAgICB7XG4gICAgICBcIm5hbWVcIjogXCJuemFrYXNcIixcbiAgICAgIFwiZW1haWxcIjogXCJuaWNob2xhc0BuY3pjb25zdWx0aW5nLmNvbVwiXG4gICAgfVxuICBdLFxuICBcImRpc3RcIjoge1xuICAgIFwic2hhc3VtXCI6IFwiMWZiZGZmNjBhNDEwYmQwZDQxNmIxYWIzZDYyMzBkMzRiN2E0NTBlMVwiLFxuICAgIFwidGFyYmFsbFwiOiBcImh0dHA6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvZXNwcmVlLy0vZXNwcmVlLTIuMC4zLnRnelwiXG4gIH0sXG4gIFwiZGlyZWN0b3JpZXNcIjoge30sXG4gIFwiX3Jlc29sdmVkXCI6IFwiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvZXNwcmVlLy0vZXNwcmVlLTIuMC4zLnRnelwiLFxuICBcInJlYWRtZVwiOiBcIkVSUk9SOiBObyBSRUFETUUgZGF0YSBmb3VuZCFcIlxufVxuIiwiLypcbiAgQ29weXJpZ2h0IChDKSAyMDEyLTIwMTMgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuICBDb3B5cmlnaHQgKEMpIDIwMTIgQXJpeWEgSGlkYXlhdCA8YXJpeWEuaGlkYXlhdEBnbWFpbC5jb20+XG5cbiAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuXG4gICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiAgICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG5cbiAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4gIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcbiAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4gIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuKi9cbi8qanNsaW50IHZhcnM6ZmFsc2UsIGJpdHdpc2U6dHJ1ZSovXG4vKmpzaGludCBpbmRlbnQ6NCovXG4vKmdsb2JhbCBleHBvcnRzOnRydWUqL1xuKGZ1bmN0aW9uIGNsb25lKGV4cG9ydHMpIHtcbiAgICAndXNlIHN0cmljdCc7XG5cbiAgICB2YXIgU3ludGF4LFxuICAgICAgICBpc0FycmF5LFxuICAgICAgICBWaXNpdG9yT3B0aW9uLFxuICAgICAgICBWaXNpdG9yS2V5cyxcbiAgICAgICAgb2JqZWN0Q3JlYXRlLFxuICAgICAgICBvYmplY3RLZXlzLFxuICAgICAgICBCUkVBSyxcbiAgICAgICAgU0tJUCxcbiAgICAgICAgUkVNT1ZFO1xuXG4gICAgZnVuY3Rpb24gaWdub3JlSlNIaW50RXJyb3IoKSB7IH1cblxuICAgIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuICAgIGlmICghaXNBcnJheSkge1xuICAgICAgICBpc0FycmF5ID0gZnVuY3Rpb24gaXNBcnJheShhcnJheSkge1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcnJheSkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVlcENvcHkob2JqKSB7XG4gICAgICAgIHZhciByZXQgPSB7fSwga2V5LCB2YWw7XG4gICAgICAgIGZvciAoa2V5IGluIG9iaikge1xuICAgICAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgdmFsID0gb2JqW2tleV07XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHZhbCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXRba2V5XSA9IGRlZXBDb3B5KHZhbCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0W2tleV0gPSB2YWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2hhbGxvd0NvcHkob2JqKSB7XG4gICAgICAgIHZhciByZXQgPSB7fSwga2V5O1xuICAgICAgICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICAgICAgICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIHJldFtrZXldID0gb2JqW2tleV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG4gICAgaWdub3JlSlNIaW50RXJyb3Ioc2hhbGxvd0NvcHkpO1xuXG4gICAgLy8gYmFzZWQgb24gTExWTSBsaWJjKysgdXBwZXJfYm91bmQgLyBsb3dlcl9ib3VuZFxuICAgIC8vIE1JVCBMaWNlbnNlXG5cbiAgICBmdW5jdGlvbiB1cHBlckJvdW5kKGFycmF5LCBmdW5jKSB7XG4gICAgICAgIHZhciBkaWZmLCBsZW4sIGksIGN1cnJlbnQ7XG5cbiAgICAgICAgbGVuID0gYXJyYXkubGVuZ3RoO1xuICAgICAgICBpID0gMDtcblxuICAgICAgICB3aGlsZSAobGVuKSB7XG4gICAgICAgICAgICBkaWZmID0gbGVuID4+PiAxO1xuICAgICAgICAgICAgY3VycmVudCA9IGkgKyBkaWZmO1xuICAgICAgICAgICAgaWYgKGZ1bmMoYXJyYXlbY3VycmVudF0pKSB7XG4gICAgICAgICAgICAgICAgbGVuID0gZGlmZjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaSA9IGN1cnJlbnQgKyAxO1xuICAgICAgICAgICAgICAgIGxlbiAtPSBkaWZmICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsb3dlckJvdW5kKGFycmF5LCBmdW5jKSB7XG4gICAgICAgIHZhciBkaWZmLCBsZW4sIGksIGN1cnJlbnQ7XG5cbiAgICAgICAgbGVuID0gYXJyYXkubGVuZ3RoO1xuICAgICAgICBpID0gMDtcblxuICAgICAgICB3aGlsZSAobGVuKSB7XG4gICAgICAgICAgICBkaWZmID0gbGVuID4+PiAxO1xuICAgICAgICAgICAgY3VycmVudCA9IGkgKyBkaWZmO1xuICAgICAgICAgICAgaWYgKGZ1bmMoYXJyYXlbY3VycmVudF0pKSB7XG4gICAgICAgICAgICAgICAgaSA9IGN1cnJlbnQgKyAxO1xuICAgICAgICAgICAgICAgIGxlbiAtPSBkaWZmICsgMTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbGVuID0gZGlmZjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaTtcbiAgICB9XG4gICAgaWdub3JlSlNIaW50RXJyb3IobG93ZXJCb3VuZCk7XG5cbiAgICBvYmplY3RDcmVhdGUgPSBPYmplY3QuY3JlYXRlIHx8IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGZ1bmN0aW9uIEYoKSB7IH1cblxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgICAgIEYucHJvdG90eXBlID0gbztcbiAgICAgICAgICAgIHJldHVybiBuZXcgRigpO1xuICAgICAgICB9O1xuICAgIH0pKCk7XG5cbiAgICBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgdmFyIGtleXMgPSBbXSwga2V5O1xuICAgICAgICBmb3IgKGtleSBpbiBvKSB7XG4gICAgICAgICAgICBrZXlzLnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ga2V5cztcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gZXh0ZW5kKHRvLCBmcm9tKSB7XG4gICAgICAgIHZhciBrZXlzID0gb2JqZWN0S2V5cyhmcm9tKSwga2V5LCBpLCBsZW47XG4gICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGtleXMubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgICAgICB0b1trZXldID0gZnJvbVtrZXldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0bztcbiAgICB9XG5cbiAgICBTeW50YXggPSB7XG4gICAgICAgIEFzc2lnbm1lbnRFeHByZXNzaW9uOiAnQXNzaWdubWVudEV4cHJlc3Npb24nLFxuICAgICAgICBBc3NpZ25tZW50UGF0dGVybjogJ0Fzc2lnbm1lbnRQYXR0ZXJuJyxcbiAgICAgICAgQXJyYXlFeHByZXNzaW9uOiAnQXJyYXlFeHByZXNzaW9uJyxcbiAgICAgICAgQXJyYXlQYXR0ZXJuOiAnQXJyYXlQYXR0ZXJuJyxcbiAgICAgICAgQXJyb3dGdW5jdGlvbkV4cHJlc3Npb246ICdBcnJvd0Z1bmN0aW9uRXhwcmVzc2lvbicsXG4gICAgICAgIEF3YWl0RXhwcmVzc2lvbjogJ0F3YWl0RXhwcmVzc2lvbicsIC8vIENBVVRJT046IEl0J3MgZGVmZXJyZWQgdG8gRVM3LlxuICAgICAgICBCbG9ja1N0YXRlbWVudDogJ0Jsb2NrU3RhdGVtZW50JyxcbiAgICAgICAgQmluYXJ5RXhwcmVzc2lvbjogJ0JpbmFyeUV4cHJlc3Npb24nLFxuICAgICAgICBCcmVha1N0YXRlbWVudDogJ0JyZWFrU3RhdGVtZW50JyxcbiAgICAgICAgQ2FsbEV4cHJlc3Npb246ICdDYWxsRXhwcmVzc2lvbicsXG4gICAgICAgIENhdGNoQ2xhdXNlOiAnQ2F0Y2hDbGF1c2UnLFxuICAgICAgICBDbGFzc0JvZHk6ICdDbGFzc0JvZHknLFxuICAgICAgICBDbGFzc0RlY2xhcmF0aW9uOiAnQ2xhc3NEZWNsYXJhdGlvbicsXG4gICAgICAgIENsYXNzRXhwcmVzc2lvbjogJ0NsYXNzRXhwcmVzc2lvbicsXG4gICAgICAgIENvbXByZWhlbnNpb25CbG9jazogJ0NvbXByZWhlbnNpb25CbG9jaycsICAvLyBDQVVUSU9OOiBJdCdzIGRlZmVycmVkIHRvIEVTNy5cbiAgICAgICAgQ29tcHJlaGVuc2lvbkV4cHJlc3Npb246ICdDb21wcmVoZW5zaW9uRXhwcmVzc2lvbicsICAvLyBDQVVUSU9OOiBJdCdzIGRlZmVycmVkIHRvIEVTNy5cbiAgICAgICAgQ29uZGl0aW9uYWxFeHByZXNzaW9uOiAnQ29uZGl0aW9uYWxFeHByZXNzaW9uJyxcbiAgICAgICAgQ29udGludWVTdGF0ZW1lbnQ6ICdDb250aW51ZVN0YXRlbWVudCcsXG4gICAgICAgIERlYnVnZ2VyU3RhdGVtZW50OiAnRGVidWdnZXJTdGF0ZW1lbnQnLFxuICAgICAgICBEaXJlY3RpdmVTdGF0ZW1lbnQ6ICdEaXJlY3RpdmVTdGF0ZW1lbnQnLFxuICAgICAgICBEb1doaWxlU3RhdGVtZW50OiAnRG9XaGlsZVN0YXRlbWVudCcsXG4gICAgICAgIEVtcHR5U3RhdGVtZW50OiAnRW1wdHlTdGF0ZW1lbnQnLFxuICAgICAgICBFeHBvcnRBbGxEZWNsYXJhdGlvbjogJ0V4cG9ydEFsbERlY2xhcmF0aW9uJyxcbiAgICAgICAgRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uOiAnRXhwb3J0RGVmYXVsdERlY2xhcmF0aW9uJyxcbiAgICAgICAgRXhwb3J0TmFtZWREZWNsYXJhdGlvbjogJ0V4cG9ydE5hbWVkRGVjbGFyYXRpb24nLFxuICAgICAgICBFeHBvcnRTcGVjaWZpZXI6ICdFeHBvcnRTcGVjaWZpZXInLFxuICAgICAgICBFeHByZXNzaW9uU3RhdGVtZW50OiAnRXhwcmVzc2lvblN0YXRlbWVudCcsXG4gICAgICAgIEZvclN0YXRlbWVudDogJ0ZvclN0YXRlbWVudCcsXG4gICAgICAgIEZvckluU3RhdGVtZW50OiAnRm9ySW5TdGF0ZW1lbnQnLFxuICAgICAgICBGb3JPZlN0YXRlbWVudDogJ0Zvck9mU3RhdGVtZW50JyxcbiAgICAgICAgRnVuY3Rpb25EZWNsYXJhdGlvbjogJ0Z1bmN0aW9uRGVjbGFyYXRpb24nLFxuICAgICAgICBGdW5jdGlvbkV4cHJlc3Npb246ICdGdW5jdGlvbkV4cHJlc3Npb24nLFxuICAgICAgICBHZW5lcmF0b3JFeHByZXNzaW9uOiAnR2VuZXJhdG9yRXhwcmVzc2lvbicsICAvLyBDQVVUSU9OOiBJdCdzIGRlZmVycmVkIHRvIEVTNy5cbiAgICAgICAgSWRlbnRpZmllcjogJ0lkZW50aWZpZXInLFxuICAgICAgICBJZlN0YXRlbWVudDogJ0lmU3RhdGVtZW50JyxcbiAgICAgICAgSW1wb3J0RGVjbGFyYXRpb246ICdJbXBvcnREZWNsYXJhdGlvbicsXG4gICAgICAgIEltcG9ydERlZmF1bHRTcGVjaWZpZXI6ICdJbXBvcnREZWZhdWx0U3BlY2lmaWVyJyxcbiAgICAgICAgSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyOiAnSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyJyxcbiAgICAgICAgSW1wb3J0U3BlY2lmaWVyOiAnSW1wb3J0U3BlY2lmaWVyJyxcbiAgICAgICAgTGl0ZXJhbDogJ0xpdGVyYWwnLFxuICAgICAgICBMYWJlbGVkU3RhdGVtZW50OiAnTGFiZWxlZFN0YXRlbWVudCcsXG4gICAgICAgIExvZ2ljYWxFeHByZXNzaW9uOiAnTG9naWNhbEV4cHJlc3Npb24nLFxuICAgICAgICBNZW1iZXJFeHByZXNzaW9uOiAnTWVtYmVyRXhwcmVzc2lvbicsXG4gICAgICAgIE1ldGhvZERlZmluaXRpb246ICdNZXRob2REZWZpbml0aW9uJyxcbiAgICAgICAgTW9kdWxlU3BlY2lmaWVyOiAnTW9kdWxlU3BlY2lmaWVyJyxcbiAgICAgICAgTmV3RXhwcmVzc2lvbjogJ05ld0V4cHJlc3Npb24nLFxuICAgICAgICBPYmplY3RFeHByZXNzaW9uOiAnT2JqZWN0RXhwcmVzc2lvbicsXG4gICAgICAgIE9iamVjdFBhdHRlcm46ICdPYmplY3RQYXR0ZXJuJyxcbiAgICAgICAgUHJvZ3JhbTogJ1Byb2dyYW0nLFxuICAgICAgICBQcm9wZXJ0eTogJ1Byb3BlcnR5JyxcbiAgICAgICAgUmVzdEVsZW1lbnQ6ICdSZXN0RWxlbWVudCcsXG4gICAgICAgIFJldHVyblN0YXRlbWVudDogJ1JldHVyblN0YXRlbWVudCcsXG4gICAgICAgIFNlcXVlbmNlRXhwcmVzc2lvbjogJ1NlcXVlbmNlRXhwcmVzc2lvbicsXG4gICAgICAgIFNwcmVhZEVsZW1lbnQ6ICdTcHJlYWRFbGVtZW50JyxcbiAgICAgICAgU3VwZXJFeHByZXNzaW9uOiAnU3VwZXJFeHByZXNzaW9uJyxcbiAgICAgICAgU3dpdGNoU3RhdGVtZW50OiAnU3dpdGNoU3RhdGVtZW50JyxcbiAgICAgICAgU3dpdGNoQ2FzZTogJ1N3aXRjaENhc2UnLFxuICAgICAgICBUYWdnZWRUZW1wbGF0ZUV4cHJlc3Npb246ICdUYWdnZWRUZW1wbGF0ZUV4cHJlc3Npb24nLFxuICAgICAgICBUZW1wbGF0ZUVsZW1lbnQ6ICdUZW1wbGF0ZUVsZW1lbnQnLFxuICAgICAgICBUZW1wbGF0ZUxpdGVyYWw6ICdUZW1wbGF0ZUxpdGVyYWwnLFxuICAgICAgICBUaGlzRXhwcmVzc2lvbjogJ1RoaXNFeHByZXNzaW9uJyxcbiAgICAgICAgVGhyb3dTdGF0ZW1lbnQ6ICdUaHJvd1N0YXRlbWVudCcsXG4gICAgICAgIFRyeVN0YXRlbWVudDogJ1RyeVN0YXRlbWVudCcsXG4gICAgICAgIFVuYXJ5RXhwcmVzc2lvbjogJ1VuYXJ5RXhwcmVzc2lvbicsXG4gICAgICAgIFVwZGF0ZUV4cHJlc3Npb246ICdVcGRhdGVFeHByZXNzaW9uJyxcbiAgICAgICAgVmFyaWFibGVEZWNsYXJhdGlvbjogJ1ZhcmlhYmxlRGVjbGFyYXRpb24nLFxuICAgICAgICBWYXJpYWJsZURlY2xhcmF0b3I6ICdWYXJpYWJsZURlY2xhcmF0b3InLFxuICAgICAgICBXaGlsZVN0YXRlbWVudDogJ1doaWxlU3RhdGVtZW50JyxcbiAgICAgICAgV2l0aFN0YXRlbWVudDogJ1dpdGhTdGF0ZW1lbnQnLFxuICAgICAgICBZaWVsZEV4cHJlc3Npb246ICdZaWVsZEV4cHJlc3Npb24nXG4gICAgfTtcblxuICAgIFZpc2l0b3JLZXlzID0ge1xuICAgICAgICBBc3NpZ25tZW50RXhwcmVzc2lvbjogWydsZWZ0JywgJ3JpZ2h0J10sXG4gICAgICAgIEFzc2lnbm1lbnRQYXR0ZXJuOiBbJ2xlZnQnLCAncmlnaHQnXSxcbiAgICAgICAgQXJyYXlFeHByZXNzaW9uOiBbJ2VsZW1lbnRzJ10sXG4gICAgICAgIEFycmF5UGF0dGVybjogWydlbGVtZW50cyddLFxuICAgICAgICBBcnJvd0Z1bmN0aW9uRXhwcmVzc2lvbjogWydwYXJhbXMnLCAnYm9keSddLFxuICAgICAgICBBd2FpdEV4cHJlc3Npb246IFsnYXJndW1lbnQnXSwgLy8gQ0FVVElPTjogSXQncyBkZWZlcnJlZCB0byBFUzcuXG4gICAgICAgIEJsb2NrU3RhdGVtZW50OiBbJ2JvZHknXSxcbiAgICAgICAgQmluYXJ5RXhwcmVzc2lvbjogWydsZWZ0JywgJ3JpZ2h0J10sXG4gICAgICAgIEJyZWFrU3RhdGVtZW50OiBbJ2xhYmVsJ10sXG4gICAgICAgIENhbGxFeHByZXNzaW9uOiBbJ2NhbGxlZScsICdhcmd1bWVudHMnXSxcbiAgICAgICAgQ2F0Y2hDbGF1c2U6IFsncGFyYW0nLCAnYm9keSddLFxuICAgICAgICBDbGFzc0JvZHk6IFsnYm9keSddLFxuICAgICAgICBDbGFzc0RlY2xhcmF0aW9uOiBbJ2lkJywgJ3N1cGVyQ2xhc3MnLCAnYm9keSddLFxuICAgICAgICBDbGFzc0V4cHJlc3Npb246IFsnaWQnLCAnc3VwZXJDbGFzcycsICdib2R5J10sXG4gICAgICAgIENvbXByZWhlbnNpb25CbG9jazogWydsZWZ0JywgJ3JpZ2h0J10sICAvLyBDQVVUSU9OOiBJdCdzIGRlZmVycmVkIHRvIEVTNy5cbiAgICAgICAgQ29tcHJlaGVuc2lvbkV4cHJlc3Npb246IFsnYmxvY2tzJywgJ2ZpbHRlcicsICdib2R5J10sICAvLyBDQVVUSU9OOiBJdCdzIGRlZmVycmVkIHRvIEVTNy5cbiAgICAgICAgQ29uZGl0aW9uYWxFeHByZXNzaW9uOiBbJ3Rlc3QnLCAnY29uc2VxdWVudCcsICdhbHRlcm5hdGUnXSxcbiAgICAgICAgQ29udGludWVTdGF0ZW1lbnQ6IFsnbGFiZWwnXSxcbiAgICAgICAgRGVidWdnZXJTdGF0ZW1lbnQ6IFtdLFxuICAgICAgICBEaXJlY3RpdmVTdGF0ZW1lbnQ6IFtdLFxuICAgICAgICBEb1doaWxlU3RhdGVtZW50OiBbJ2JvZHknLCAndGVzdCddLFxuICAgICAgICBFbXB0eVN0YXRlbWVudDogW10sXG4gICAgICAgIEV4cG9ydEFsbERlY2xhcmF0aW9uOiBbJ3NvdXJjZSddLFxuICAgICAgICBFeHBvcnREZWZhdWx0RGVjbGFyYXRpb246IFsnZGVjbGFyYXRpb24nXSxcbiAgICAgICAgRXhwb3J0TmFtZWREZWNsYXJhdGlvbjogWydkZWNsYXJhdGlvbicsICdzcGVjaWZpZXJzJywgJ3NvdXJjZSddLFxuICAgICAgICBFeHBvcnRTcGVjaWZpZXI6IFsnZXhwb3J0ZWQnLCAnbG9jYWwnXSxcbiAgICAgICAgRXhwcmVzc2lvblN0YXRlbWVudDogWydleHByZXNzaW9uJ10sXG4gICAgICAgIEZvclN0YXRlbWVudDogWydpbml0JywgJ3Rlc3QnLCAndXBkYXRlJywgJ2JvZHknXSxcbiAgICAgICAgRm9ySW5TdGF0ZW1lbnQ6IFsnbGVmdCcsICdyaWdodCcsICdib2R5J10sXG4gICAgICAgIEZvck9mU3RhdGVtZW50OiBbJ2xlZnQnLCAncmlnaHQnLCAnYm9keSddLFxuICAgICAgICBGdW5jdGlvbkRlY2xhcmF0aW9uOiBbJ2lkJywgJ3BhcmFtcycsICdib2R5J10sXG4gICAgICAgIEZ1bmN0aW9uRXhwcmVzc2lvbjogWydpZCcsICdwYXJhbXMnLCAnYm9keSddLFxuICAgICAgICBHZW5lcmF0b3JFeHByZXNzaW9uOiBbJ2Jsb2NrcycsICdmaWx0ZXInLCAnYm9keSddLCAgLy8gQ0FVVElPTjogSXQncyBkZWZlcnJlZCB0byBFUzcuXG4gICAgICAgIElkZW50aWZpZXI6IFtdLFxuICAgICAgICBJZlN0YXRlbWVudDogWyd0ZXN0JywgJ2NvbnNlcXVlbnQnLCAnYWx0ZXJuYXRlJ10sXG4gICAgICAgIEltcG9ydERlY2xhcmF0aW9uOiBbJ3NwZWNpZmllcnMnLCAnc291cmNlJ10sXG4gICAgICAgIEltcG9ydERlZmF1bHRTcGVjaWZpZXI6IFsnbG9jYWwnXSxcbiAgICAgICAgSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyOiBbJ2xvY2FsJ10sXG4gICAgICAgIEltcG9ydFNwZWNpZmllcjogWydpbXBvcnRlZCcsICdsb2NhbCddLFxuICAgICAgICBMaXRlcmFsOiBbXSxcbiAgICAgICAgTGFiZWxlZFN0YXRlbWVudDogWydsYWJlbCcsICdib2R5J10sXG4gICAgICAgIExvZ2ljYWxFeHByZXNzaW9uOiBbJ2xlZnQnLCAncmlnaHQnXSxcbiAgICAgICAgTWVtYmVyRXhwcmVzc2lvbjogWydvYmplY3QnLCAncHJvcGVydHknXSxcbiAgICAgICAgTWV0aG9kRGVmaW5pdGlvbjogWydrZXknLCAndmFsdWUnXSxcbiAgICAgICAgTW9kdWxlU3BlY2lmaWVyOiBbXSxcbiAgICAgICAgTmV3RXhwcmVzc2lvbjogWydjYWxsZWUnLCAnYXJndW1lbnRzJ10sXG4gICAgICAgIE9iamVjdEV4cHJlc3Npb246IFsncHJvcGVydGllcyddLFxuICAgICAgICBPYmplY3RQYXR0ZXJuOiBbJ3Byb3BlcnRpZXMnXSxcbiAgICAgICAgUHJvZ3JhbTogWydib2R5J10sXG4gICAgICAgIFByb3BlcnR5OiBbJ2tleScsICd2YWx1ZSddLFxuICAgICAgICBSZXN0RWxlbWVudDogWyAnYXJndW1lbnQnIF0sXG4gICAgICAgIFJldHVyblN0YXRlbWVudDogWydhcmd1bWVudCddLFxuICAgICAgICBTZXF1ZW5jZUV4cHJlc3Npb246IFsnZXhwcmVzc2lvbnMnXSxcbiAgICAgICAgU3ByZWFkRWxlbWVudDogWydhcmd1bWVudCddLFxuICAgICAgICBTdXBlckV4cHJlc3Npb246IFsnc3VwZXInXSxcbiAgICAgICAgU3dpdGNoU3RhdGVtZW50OiBbJ2Rpc2NyaW1pbmFudCcsICdjYXNlcyddLFxuICAgICAgICBTd2l0Y2hDYXNlOiBbJ3Rlc3QnLCAnY29uc2VxdWVudCddLFxuICAgICAgICBUYWdnZWRUZW1wbGF0ZUV4cHJlc3Npb246IFsndGFnJywgJ3F1YXNpJ10sXG4gICAgICAgIFRlbXBsYXRlRWxlbWVudDogW10sXG4gICAgICAgIFRlbXBsYXRlTGl0ZXJhbDogWydxdWFzaXMnLCAnZXhwcmVzc2lvbnMnXSxcbiAgICAgICAgVGhpc0V4cHJlc3Npb246IFtdLFxuICAgICAgICBUaHJvd1N0YXRlbWVudDogWydhcmd1bWVudCddLFxuICAgICAgICBUcnlTdGF0ZW1lbnQ6IFsnYmxvY2snLCAnaGFuZGxlcicsICdmaW5hbGl6ZXInXSxcbiAgICAgICAgVW5hcnlFeHByZXNzaW9uOiBbJ2FyZ3VtZW50J10sXG4gICAgICAgIFVwZGF0ZUV4cHJlc3Npb246IFsnYXJndW1lbnQnXSxcbiAgICAgICAgVmFyaWFibGVEZWNsYXJhdGlvbjogWydkZWNsYXJhdGlvbnMnXSxcbiAgICAgICAgVmFyaWFibGVEZWNsYXJhdG9yOiBbJ2lkJywgJ2luaXQnXSxcbiAgICAgICAgV2hpbGVTdGF0ZW1lbnQ6IFsndGVzdCcsICdib2R5J10sXG4gICAgICAgIFdpdGhTdGF0ZW1lbnQ6IFsnb2JqZWN0JywgJ2JvZHknXSxcbiAgICAgICAgWWllbGRFeHByZXNzaW9uOiBbJ2FyZ3VtZW50J11cbiAgICB9O1xuXG4gICAgLy8gdW5pcXVlIGlkXG4gICAgQlJFQUsgPSB7fTtcbiAgICBTS0lQID0ge307XG4gICAgUkVNT1ZFID0ge307XG5cbiAgICBWaXNpdG9yT3B0aW9uID0ge1xuICAgICAgICBCcmVhazogQlJFQUssXG4gICAgICAgIFNraXA6IFNLSVAsXG4gICAgICAgIFJlbW92ZTogUkVNT1ZFXG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIFJlZmVyZW5jZShwYXJlbnQsIGtleSkge1xuICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDtcbiAgICAgICAgdGhpcy5rZXkgPSBrZXk7XG4gICAgfVxuXG4gICAgUmVmZXJlbmNlLnByb3RvdHlwZS5yZXBsYWNlID0gZnVuY3Rpb24gcmVwbGFjZShub2RlKSB7XG4gICAgICAgIHRoaXMucGFyZW50W3RoaXMua2V5XSA9IG5vZGU7XG4gICAgfTtcblxuICAgIFJlZmVyZW5jZS5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gcmVtb3ZlKCkge1xuICAgICAgICBpZiAoaXNBcnJheSh0aGlzLnBhcmVudCkpIHtcbiAgICAgICAgICAgIHRoaXMucGFyZW50LnNwbGljZSh0aGlzLmtleSwgMSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucmVwbGFjZShudWxsKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBFbGVtZW50KG5vZGUsIHBhdGgsIHdyYXAsIHJlZikge1xuICAgICAgICB0aGlzLm5vZGUgPSBub2RlO1xuICAgICAgICB0aGlzLnBhdGggPSBwYXRoO1xuICAgICAgICB0aGlzLndyYXAgPSB3cmFwO1xuICAgICAgICB0aGlzLnJlZiA9IHJlZjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBDb250cm9sbGVyKCkgeyB9XG5cbiAgICAvLyBBUEk6XG4gICAgLy8gcmV0dXJuIHByb3BlcnR5IHBhdGggYXJyYXkgZnJvbSByb290IHRvIGN1cnJlbnQgbm9kZVxuICAgIENvbnRyb2xsZXIucHJvdG90eXBlLnBhdGggPSBmdW5jdGlvbiBwYXRoKCkge1xuICAgICAgICB2YXIgaSwgaXosIGosIGp6LCByZXN1bHQsIGVsZW1lbnQ7XG5cbiAgICAgICAgZnVuY3Rpb24gYWRkVG9QYXRoKHJlc3VsdCwgcGF0aCkge1xuICAgICAgICAgICAgaWYgKGlzQXJyYXkocGF0aCkpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBqeiA9IHBhdGgubGVuZ3RoOyBqIDwgano7ICsraikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChwYXRoW2pdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHBhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gcm9vdCBub2RlXG4gICAgICAgIGlmICghdGhpcy5fX2N1cnJlbnQucGF0aCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmaXJzdCBub2RlIGlzIHNlbnRpbmVsLCBzZWNvbmQgbm9kZSBpcyByb290IGVsZW1lbnRcbiAgICAgICAgcmVzdWx0ID0gW107XG4gICAgICAgIGZvciAoaSA9IDIsIGl6ID0gdGhpcy5fX2xlYXZlbGlzdC5sZW5ndGg7IGkgPCBpejsgKytpKSB7XG4gICAgICAgICAgICBlbGVtZW50ID0gdGhpcy5fX2xlYXZlbGlzdFtpXTtcbiAgICAgICAgICAgIGFkZFRvUGF0aChyZXN1bHQsIGVsZW1lbnQucGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgYWRkVG9QYXRoKHJlc3VsdCwgdGhpcy5fX2N1cnJlbnQucGF0aCk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIC8vIEFQSTpcbiAgICAvLyByZXR1cm4gdHlwZSBvZiBjdXJyZW50IG5vZGVcbiAgICBDb250cm9sbGVyLnByb3RvdHlwZS50eXBlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbm9kZSA9IHRoaXMuY3VycmVudCgpO1xuICAgICAgICByZXR1cm4gbm9kZS50eXBlIHx8IHRoaXMuX19jdXJyZW50LndyYXA7XG4gICAgfTtcblxuICAgIC8vIEFQSTpcbiAgICAvLyByZXR1cm4gYXJyYXkgb2YgcGFyZW50IGVsZW1lbnRzXG4gICAgQ29udHJvbGxlci5wcm90b3R5cGUucGFyZW50cyA9IGZ1bmN0aW9uIHBhcmVudHMoKSB7XG4gICAgICAgIHZhciBpLCBpeiwgcmVzdWx0O1xuXG4gICAgICAgIC8vIGZpcnN0IG5vZGUgaXMgc2VudGluZWxcbiAgICAgICAgcmVzdWx0ID0gW107XG4gICAgICAgIGZvciAoaSA9IDEsIGl6ID0gdGhpcy5fX2xlYXZlbGlzdC5sZW5ndGg7IGkgPCBpejsgKytpKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaCh0aGlzLl9fbGVhdmVsaXN0W2ldLm5vZGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgLy8gQVBJOlxuICAgIC8vIHJldHVybiBjdXJyZW50IG5vZGVcbiAgICBDb250cm9sbGVyLnByb3RvdHlwZS5jdXJyZW50ID0gZnVuY3Rpb24gY3VycmVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX19jdXJyZW50Lm5vZGU7XG4gICAgfTtcblxuICAgIENvbnRyb2xsZXIucHJvdG90eXBlLl9fZXhlY3V0ZSA9IGZ1bmN0aW9uIF9fZXhlY3V0ZShjYWxsYmFjaywgZWxlbWVudCkge1xuICAgICAgICB2YXIgcHJldmlvdXMsIHJlc3VsdDtcblxuICAgICAgICByZXN1bHQgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgcHJldmlvdXMgID0gdGhpcy5fX2N1cnJlbnQ7XG4gICAgICAgIHRoaXMuX19jdXJyZW50ID0gZWxlbWVudDtcbiAgICAgICAgdGhpcy5fX3N0YXRlID0gbnVsbDtcbiAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICByZXN1bHQgPSBjYWxsYmFjay5jYWxsKHRoaXMsIGVsZW1lbnQubm9kZSwgdGhpcy5fX2xlYXZlbGlzdFt0aGlzLl9fbGVhdmVsaXN0Lmxlbmd0aCAtIDFdLm5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX19jdXJyZW50ID0gcHJldmlvdXM7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgLy8gQVBJOlxuICAgIC8vIG5vdGlmeSBjb250cm9sIHNraXAgLyBicmVha1xuICAgIENvbnRyb2xsZXIucHJvdG90eXBlLm5vdGlmeSA9IGZ1bmN0aW9uIG5vdGlmeShmbGFnKSB7XG4gICAgICAgIHRoaXMuX19zdGF0ZSA9IGZsYWc7XG4gICAgfTtcblxuICAgIC8vIEFQSTpcbiAgICAvLyBza2lwIGNoaWxkIG5vZGVzIG9mIGN1cnJlbnQgbm9kZVxuICAgIENvbnRyb2xsZXIucHJvdG90eXBlLnNraXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMubm90aWZ5KFNLSVApO1xuICAgIH07XG5cbiAgICAvLyBBUEk6XG4gICAgLy8gYnJlYWsgdHJhdmVyc2Fsc1xuICAgIENvbnRyb2xsZXIucHJvdG90eXBlWydicmVhayddID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLm5vdGlmeShCUkVBSyk7XG4gICAgfTtcblxuICAgIC8vIEFQSTpcbiAgICAvLyByZW1vdmUgbm9kZVxuICAgIENvbnRyb2xsZXIucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5ub3RpZnkoUkVNT1ZFKTtcbiAgICB9O1xuXG4gICAgQ29udHJvbGxlci5wcm90b3R5cGUuX19pbml0aWFsaXplID0gZnVuY3Rpb24ocm9vdCwgdmlzaXRvcikge1xuICAgICAgICB0aGlzLnZpc2l0b3IgPSB2aXNpdG9yO1xuICAgICAgICB0aGlzLnJvb3QgPSByb290O1xuICAgICAgICB0aGlzLl9fd29ya2xpc3QgPSBbXTtcbiAgICAgICAgdGhpcy5fX2xlYXZlbGlzdCA9IFtdO1xuICAgICAgICB0aGlzLl9fY3VycmVudCA9IG51bGw7XG4gICAgICAgIHRoaXMuX19zdGF0ZSA9IG51bGw7XG4gICAgICAgIHRoaXMuX19mYWxsYmFjayA9IHZpc2l0b3IuZmFsbGJhY2sgPT09ICdpdGVyYXRpb24nO1xuICAgICAgICB0aGlzLl9fa2V5cyA9IFZpc2l0b3JLZXlzO1xuICAgICAgICBpZiAodmlzaXRvci5rZXlzKSB7XG4gICAgICAgICAgICB0aGlzLl9fa2V5cyA9IGV4dGVuZChvYmplY3RDcmVhdGUodGhpcy5fX2tleXMpLCB2aXNpdG9yLmtleXMpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGlzTm9kZShub2RlKSB7XG4gICAgICAgIGlmIChub2RlID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHlwZW9mIG5vZGUgPT09ICdvYmplY3QnICYmIHR5cGVvZiBub2RlLnR5cGUgPT09ICdzdHJpbmcnO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzUHJvcGVydHkobm9kZVR5cGUsIGtleSkge1xuICAgICAgICByZXR1cm4gKG5vZGVUeXBlID09PSBTeW50YXguT2JqZWN0RXhwcmVzc2lvbiB8fCBub2RlVHlwZSA9PT0gU3ludGF4Lk9iamVjdFBhdHRlcm4pICYmICdwcm9wZXJ0aWVzJyA9PT0ga2V5O1xuICAgIH1cblxuICAgIENvbnRyb2xsZXIucHJvdG90eXBlLnRyYXZlcnNlID0gZnVuY3Rpb24gdHJhdmVyc2Uocm9vdCwgdmlzaXRvcikge1xuICAgICAgICB2YXIgd29ya2xpc3QsXG4gICAgICAgICAgICBsZWF2ZWxpc3QsXG4gICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgbm9kZSxcbiAgICAgICAgICAgIG5vZGVUeXBlLFxuICAgICAgICAgICAgcmV0LFxuICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgY3VycmVudCxcbiAgICAgICAgICAgIGN1cnJlbnQyLFxuICAgICAgICAgICAgY2FuZGlkYXRlcyxcbiAgICAgICAgICAgIGNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNlbnRpbmVsO1xuXG4gICAgICAgIHRoaXMuX19pbml0aWFsaXplKHJvb3QsIHZpc2l0b3IpO1xuXG4gICAgICAgIHNlbnRpbmVsID0ge307XG5cbiAgICAgICAgLy8gcmVmZXJlbmNlXG4gICAgICAgIHdvcmtsaXN0ID0gdGhpcy5fX3dvcmtsaXN0O1xuICAgICAgICBsZWF2ZWxpc3QgPSB0aGlzLl9fbGVhdmVsaXN0O1xuXG4gICAgICAgIC8vIGluaXRpYWxpemVcbiAgICAgICAgd29ya2xpc3QucHVzaChuZXcgRWxlbWVudChyb290LCBudWxsLCBudWxsLCBudWxsKSk7XG4gICAgICAgIGxlYXZlbGlzdC5wdXNoKG5ldyBFbGVtZW50KG51bGwsIG51bGwsIG51bGwsIG51bGwpKTtcblxuICAgICAgICB3aGlsZSAod29ya2xpc3QubGVuZ3RoKSB7XG4gICAgICAgICAgICBlbGVtZW50ID0gd29ya2xpc3QucG9wKCk7XG5cbiAgICAgICAgICAgIGlmIChlbGVtZW50ID09PSBzZW50aW5lbCkge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBsZWF2ZWxpc3QucG9wKCk7XG5cbiAgICAgICAgICAgICAgICByZXQgPSB0aGlzLl9fZXhlY3V0ZSh2aXNpdG9yLmxlYXZlLCBlbGVtZW50KTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9fc3RhdGUgPT09IEJSRUFLIHx8IHJldCA9PT0gQlJFQUspIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGVsZW1lbnQubm9kZSkge1xuXG4gICAgICAgICAgICAgICAgcmV0ID0gdGhpcy5fX2V4ZWN1dGUodmlzaXRvci5lbnRlciwgZWxlbWVudCk7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fX3N0YXRlID09PSBCUkVBSyB8fCByZXQgPT09IEJSRUFLKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB3b3JrbGlzdC5wdXNoKHNlbnRpbmVsKTtcbiAgICAgICAgICAgICAgICBsZWF2ZWxpc3QucHVzaChlbGVtZW50KTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9fc3RhdGUgPT09IFNLSVAgfHwgcmV0ID09PSBTS0lQKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG5vZGUgPSBlbGVtZW50Lm5vZGU7XG4gICAgICAgICAgICAgICAgbm9kZVR5cGUgPSBlbGVtZW50LndyYXAgfHwgbm9kZS50eXBlO1xuICAgICAgICAgICAgICAgIGNhbmRpZGF0ZXMgPSB0aGlzLl9fa2V5c1tub2RlVHlwZV07XG4gICAgICAgICAgICAgICAgaWYgKCFjYW5kaWRhdGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9fZmFsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbmRpZGF0ZXMgPSBvYmplY3RLZXlzKG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIG5vZGUgdHlwZSAnICsgbm9kZVR5cGUgKyAnLicpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY3VycmVudCA9IGNhbmRpZGF0ZXMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIHdoaWxlICgoY3VycmVudCAtPSAxKSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGtleSA9IGNhbmRpZGF0ZXNbY3VycmVudF07XG4gICAgICAgICAgICAgICAgICAgIGNhbmRpZGF0ZSA9IG5vZGVba2V5XTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXJyYXkoY2FuZGlkYXRlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudDIgPSBjYW5kaWRhdGUubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChjdXJyZW50MiAtPSAxKSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjYW5kaWRhdGVbY3VycmVudDJdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNQcm9wZXJ0eShub2RlVHlwZSwgY2FuZGlkYXRlc1tjdXJyZW50XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IG5ldyBFbGVtZW50KGNhbmRpZGF0ZVtjdXJyZW50Ml0sIFtrZXksIGN1cnJlbnQyXSwgJ1Byb3BlcnR5JywgbnVsbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc05vZGUoY2FuZGlkYXRlW2N1cnJlbnQyXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IG5ldyBFbGVtZW50KGNhbmRpZGF0ZVtjdXJyZW50Ml0sIFtrZXksIGN1cnJlbnQyXSwgbnVsbCwgbnVsbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvcmtsaXN0LnB1c2goZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNOb2RlKGNhbmRpZGF0ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdvcmtsaXN0LnB1c2gobmV3IEVsZW1lbnQoY2FuZGlkYXRlLCBrZXksIG51bGwsIG51bGwpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBDb250cm9sbGVyLnByb3RvdHlwZS5yZXBsYWNlID0gZnVuY3Rpb24gcmVwbGFjZShyb290LCB2aXNpdG9yKSB7XG4gICAgICAgIGZ1bmN0aW9uIHJlbW92ZUVsZW0oZWxlbWVudCkge1xuICAgICAgICAgICAgdmFyIGksXG4gICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgIG5leHRFbGVtLFxuICAgICAgICAgICAgICAgIHBhcmVudDtcblxuICAgICAgICAgICAgaWYgKGVsZW1lbnQucmVmLnJlbW92ZSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gV2hlbiB0aGUgcmVmZXJlbmNlIGlzIGFuIGVsZW1lbnQgb2YgYW4gYXJyYXkuXG4gICAgICAgICAgICAgICAga2V5ID0gZWxlbWVudC5yZWYua2V5O1xuICAgICAgICAgICAgICAgIHBhcmVudCA9IGVsZW1lbnQucmVmLnBhcmVudDtcblxuICAgICAgICAgICAgICAgIC8vIElmIHJlbW92ZWQgZnJvbSBhcnJheSwgdGhlbiBkZWNyZWFzZSBmb2xsb3dpbmcgaXRlbXMnIGtleXMuXG4gICAgICAgICAgICAgICAgaSA9IHdvcmtsaXN0Lmxlbmd0aDtcbiAgICAgICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgICAgIG5leHRFbGVtID0gd29ya2xpc3RbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXh0RWxlbS5yZWYgJiYgbmV4dEVsZW0ucmVmLnBhcmVudCA9PT0gcGFyZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAgKG5leHRFbGVtLnJlZi5rZXkgPCBrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC0tbmV4dEVsZW0ucmVmLmtleTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB3b3JrbGlzdCxcbiAgICAgICAgICAgIGxlYXZlbGlzdCxcbiAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICBub2RlVHlwZSxcbiAgICAgICAgICAgIHRhcmdldCxcbiAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICBjdXJyZW50LFxuICAgICAgICAgICAgY3VycmVudDIsXG4gICAgICAgICAgICBjYW5kaWRhdGVzLFxuICAgICAgICAgICAgY2FuZGlkYXRlLFxuICAgICAgICAgICAgc2VudGluZWwsXG4gICAgICAgICAgICBvdXRlcixcbiAgICAgICAgICAgIGtleTtcblxuICAgICAgICB0aGlzLl9faW5pdGlhbGl6ZShyb290LCB2aXNpdG9yKTtcblxuICAgICAgICBzZW50aW5lbCA9IHt9O1xuXG4gICAgICAgIC8vIHJlZmVyZW5jZVxuICAgICAgICB3b3JrbGlzdCA9IHRoaXMuX193b3JrbGlzdDtcbiAgICAgICAgbGVhdmVsaXN0ID0gdGhpcy5fX2xlYXZlbGlzdDtcblxuICAgICAgICAvLyBpbml0aWFsaXplXG4gICAgICAgIG91dGVyID0ge1xuICAgICAgICAgICAgcm9vdDogcm9vdFxuICAgICAgICB9O1xuICAgICAgICBlbGVtZW50ID0gbmV3IEVsZW1lbnQocm9vdCwgbnVsbCwgbnVsbCwgbmV3IFJlZmVyZW5jZShvdXRlciwgJ3Jvb3QnKSk7XG4gICAgICAgIHdvcmtsaXN0LnB1c2goZWxlbWVudCk7XG4gICAgICAgIGxlYXZlbGlzdC5wdXNoKGVsZW1lbnQpO1xuXG4gICAgICAgIHdoaWxlICh3b3JrbGlzdC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGVsZW1lbnQgPSB3b3JrbGlzdC5wb3AoKTtcblxuICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT09IHNlbnRpbmVsKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudCA9IGxlYXZlbGlzdC5wb3AoKTtcblxuICAgICAgICAgICAgICAgIHRhcmdldCA9IHRoaXMuX19leGVjdXRlKHZpc2l0b3IubGVhdmUsIGVsZW1lbnQpO1xuXG4gICAgICAgICAgICAgICAgLy8gbm9kZSBtYXkgYmUgcmVwbGFjZWQgd2l0aCBudWxsLFxuICAgICAgICAgICAgICAgIC8vIHNvIGRpc3Rpbmd1aXNoIGJldHdlZW4gdW5kZWZpbmVkIGFuZCBudWxsIGluIHRoaXMgcGxhY2VcbiAgICAgICAgICAgICAgICBpZiAodGFyZ2V0ICE9PSB1bmRlZmluZWQgJiYgdGFyZ2V0ICE9PSBCUkVBSyAmJiB0YXJnZXQgIT09IFNLSVAgJiYgdGFyZ2V0ICE9PSBSRU1PVkUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gcmVwbGFjZVxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJlZi5yZXBsYWNlKHRhcmdldCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX19zdGF0ZSA9PT0gUkVNT1ZFIHx8IHRhcmdldCA9PT0gUkVNT1ZFKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZUVsZW0oZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX19zdGF0ZSA9PT0gQlJFQUsgfHwgdGFyZ2V0ID09PSBCUkVBSykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3V0ZXIucm9vdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRhcmdldCA9IHRoaXMuX19leGVjdXRlKHZpc2l0b3IuZW50ZXIsIGVsZW1lbnQpO1xuXG4gICAgICAgICAgICAvLyBub2RlIG1heSBiZSByZXBsYWNlZCB3aXRoIG51bGwsXG4gICAgICAgICAgICAvLyBzbyBkaXN0aW5ndWlzaCBiZXR3ZWVuIHVuZGVmaW5lZCBhbmQgbnVsbCBpbiB0aGlzIHBsYWNlXG4gICAgICAgICAgICBpZiAodGFyZ2V0ICE9PSB1bmRlZmluZWQgJiYgdGFyZ2V0ICE9PSBCUkVBSyAmJiB0YXJnZXQgIT09IFNLSVAgJiYgdGFyZ2V0ICE9PSBSRU1PVkUpIHtcbiAgICAgICAgICAgICAgICAvLyByZXBsYWNlXG4gICAgICAgICAgICAgICAgZWxlbWVudC5yZWYucmVwbGFjZSh0YXJnZXQpO1xuICAgICAgICAgICAgICAgIGVsZW1lbnQubm9kZSA9IHRhcmdldDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuX19zdGF0ZSA9PT0gUkVNT1ZFIHx8IHRhcmdldCA9PT0gUkVNT1ZFKSB7XG4gICAgICAgICAgICAgICAgcmVtb3ZlRWxlbShlbGVtZW50KTtcbiAgICAgICAgICAgICAgICBlbGVtZW50Lm5vZGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5fX3N0YXRlID09PSBCUkVBSyB8fCB0YXJnZXQgPT09IEJSRUFLKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG91dGVyLnJvb3Q7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIG5vZGUgbWF5IGJlIG51bGxcbiAgICAgICAgICAgIG5vZGUgPSBlbGVtZW50Lm5vZGU7XG4gICAgICAgICAgICBpZiAoIW5vZGUpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgd29ya2xpc3QucHVzaChzZW50aW5lbCk7XG4gICAgICAgICAgICBsZWF2ZWxpc3QucHVzaChlbGVtZW50KTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuX19zdGF0ZSA9PT0gU0tJUCB8fCB0YXJnZXQgPT09IFNLSVApIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbm9kZVR5cGUgPSBlbGVtZW50LndyYXAgfHwgbm9kZS50eXBlO1xuICAgICAgICAgICAgY2FuZGlkYXRlcyA9IHRoaXMuX19rZXlzW25vZGVUeXBlXTtcbiAgICAgICAgICAgIGlmICghY2FuZGlkYXRlcykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9fZmFsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgY2FuZGlkYXRlcyA9IG9iamVjdEtleXMobm9kZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIG5vZGUgdHlwZSAnICsgbm9kZVR5cGUgKyAnLicpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY3VycmVudCA9IGNhbmRpZGF0ZXMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKChjdXJyZW50IC09IDEpID49IDApIHtcbiAgICAgICAgICAgICAgICBrZXkgPSBjYW5kaWRhdGVzW2N1cnJlbnRdO1xuICAgICAgICAgICAgICAgIGNhbmRpZGF0ZSA9IG5vZGVba2V5XTtcbiAgICAgICAgICAgICAgICBpZiAoIWNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoaXNBcnJheShjYW5kaWRhdGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnQyID0gY2FuZGlkYXRlLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChjdXJyZW50MiAtPSAxKSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNhbmRpZGF0ZVtjdXJyZW50Ml0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1Byb3BlcnR5KG5vZGVUeXBlLCBjYW5kaWRhdGVzW2N1cnJlbnRdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBuZXcgRWxlbWVudChjYW5kaWRhdGVbY3VycmVudDJdLCBba2V5LCBjdXJyZW50Ml0sICdQcm9wZXJ0eScsIG5ldyBSZWZlcmVuY2UoY2FuZGlkYXRlLCBjdXJyZW50MikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc05vZGUoY2FuZGlkYXRlW2N1cnJlbnQyXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gbmV3IEVsZW1lbnQoY2FuZGlkYXRlW2N1cnJlbnQyXSwgW2tleSwgY3VycmVudDJdLCBudWxsLCBuZXcgUmVmZXJlbmNlKGNhbmRpZGF0ZSwgY3VycmVudDIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB3b3JrbGlzdC5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc05vZGUoY2FuZGlkYXRlKSkge1xuICAgICAgICAgICAgICAgICAgICB3b3JrbGlzdC5wdXNoKG5ldyBFbGVtZW50KGNhbmRpZGF0ZSwga2V5LCBudWxsLCBuZXcgUmVmZXJlbmNlKG5vZGUsIGtleSkpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb3V0ZXIucm9vdDtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gdHJhdmVyc2Uocm9vdCwgdmlzaXRvcikge1xuICAgICAgICB2YXIgY29udHJvbGxlciA9IG5ldyBDb250cm9sbGVyKCk7XG4gICAgICAgIHJldHVybiBjb250cm9sbGVyLnRyYXZlcnNlKHJvb3QsIHZpc2l0b3IpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlcGxhY2Uocm9vdCwgdmlzaXRvcikge1xuICAgICAgICB2YXIgY29udHJvbGxlciA9IG5ldyBDb250cm9sbGVyKCk7XG4gICAgICAgIHJldHVybiBjb250cm9sbGVyLnJlcGxhY2Uocm9vdCwgdmlzaXRvcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXh0ZW5kQ29tbWVudFJhbmdlKGNvbW1lbnQsIHRva2Vucykge1xuICAgICAgICB2YXIgdGFyZ2V0O1xuXG4gICAgICAgIHRhcmdldCA9IHVwcGVyQm91bmQodG9rZW5zLCBmdW5jdGlvbiBzZWFyY2godG9rZW4pIHtcbiAgICAgICAgICAgIHJldHVybiB0b2tlbi5yYW5nZVswXSA+IGNvbW1lbnQucmFuZ2VbMF07XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbW1lbnQuZXh0ZW5kZWRSYW5nZSA9IFtjb21tZW50LnJhbmdlWzBdLCBjb21tZW50LnJhbmdlWzFdXTtcblxuICAgICAgICBpZiAodGFyZ2V0ICE9PSB0b2tlbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb21tZW50LmV4dGVuZGVkUmFuZ2VbMV0gPSB0b2tlbnNbdGFyZ2V0XS5yYW5nZVswXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRhcmdldCAtPSAxO1xuICAgICAgICBpZiAodGFyZ2V0ID49IDApIHtcbiAgICAgICAgICAgIGNvbW1lbnQuZXh0ZW5kZWRSYW5nZVswXSA9IHRva2Vuc1t0YXJnZXRdLnJhbmdlWzFdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbW1lbnQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYXR0YWNoQ29tbWVudHModHJlZSwgcHJvdmlkZWRDb21tZW50cywgdG9rZW5zKSB7XG4gICAgICAgIC8vIEF0IGZpcnN0LCB3ZSBzaG91bGQgY2FsY3VsYXRlIGV4dGVuZGVkIGNvbW1lbnQgcmFuZ2VzLlxuICAgICAgICB2YXIgY29tbWVudHMgPSBbXSwgY29tbWVudCwgbGVuLCBpLCBjdXJzb3I7XG5cbiAgICAgICAgaWYgKCF0cmVlLnJhbmdlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2F0dGFjaENvbW1lbnRzIG5lZWRzIHJhbmdlIGluZm9ybWF0aW9uJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB0b2tlbnMgYXJyYXkgaXMgZW1wdHksIHdlIGF0dGFjaCBjb21tZW50cyB0byB0cmVlIGFzICdsZWFkaW5nQ29tbWVudHMnXG4gICAgICAgIGlmICghdG9rZW5zLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKHByb3ZpZGVkQ29tbWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gcHJvdmlkZWRDb21tZW50cy5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gZGVlcENvcHkocHJvdmlkZWRDb21tZW50c1tpXSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbW1lbnQuZXh0ZW5kZWRSYW5nZSA9IFswLCB0cmVlLnJhbmdlWzBdXTtcbiAgICAgICAgICAgICAgICAgICAgY29tbWVudHMucHVzaChjb21tZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdHJlZS5sZWFkaW5nQ29tbWVudHMgPSBjb21tZW50cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cmVlO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChpID0gMCwgbGVuID0gcHJvdmlkZWRDb21tZW50cy5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgICAgICAgICAgY29tbWVudHMucHVzaChleHRlbmRDb21tZW50UmFuZ2UoZGVlcENvcHkocHJvdmlkZWRDb21tZW50c1tpXSksIHRva2VucykpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGhpcyBpcyBiYXNlZCBvbiBKb2huIEZyZWVtYW4ncyBpbXBsZW1lbnRhdGlvbi5cbiAgICAgICAgY3Vyc29yID0gMDtcbiAgICAgICAgdHJhdmVyc2UodHJlZSwge1xuICAgICAgICAgICAgZW50ZXI6IGZ1bmN0aW9uIChub2RlKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNvbW1lbnQ7XG5cbiAgICAgICAgICAgICAgICB3aGlsZSAoY3Vyc29yIDwgY29tbWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBjb21tZW50c1tjdXJzb3JdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWVudC5leHRlbmRlZFJhbmdlWzFdID4gbm9kZS5yYW5nZVswXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWVudC5leHRlbmRlZFJhbmdlWzFdID09PSBub2RlLnJhbmdlWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW5vZGUubGVhZGluZ0NvbW1lbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5sZWFkaW5nQ29tbWVudHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUubGVhZGluZ0NvbW1lbnRzLnB1c2goY29tbWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50cy5zcGxpY2UoY3Vyc29yLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnNvciArPSAxO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gYWxyZWFkeSBvdXQgb2Ygb3duZWQgbm9kZVxuICAgICAgICAgICAgICAgIGlmIChjdXJzb3IgPT09IGNvbW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVmlzaXRvck9wdGlvbi5CcmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoY29tbWVudHNbY3Vyc29yXS5leHRlbmRlZFJhbmdlWzBdID4gbm9kZS5yYW5nZVsxXSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVmlzaXRvck9wdGlvbi5Ta2lwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgY3Vyc29yID0gMDtcbiAgICAgICAgdHJhdmVyc2UodHJlZSwge1xuICAgICAgICAgICAgbGVhdmU6IGZ1bmN0aW9uIChub2RlKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNvbW1lbnQ7XG5cbiAgICAgICAgICAgICAgICB3aGlsZSAoY3Vyc29yIDwgY29tbWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBjb21tZW50c1tjdXJzb3JdO1xuICAgICAgICAgICAgICAgICAgICBpZiAobm9kZS5yYW5nZVsxXSA8IGNvbW1lbnQuZXh0ZW5kZWRSYW5nZVswXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAobm9kZS5yYW5nZVsxXSA9PT0gY29tbWVudC5leHRlbmRlZFJhbmdlWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW5vZGUudHJhaWxpbmdDb21tZW50cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUudHJhaWxpbmdDb21tZW50cyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS50cmFpbGluZ0NvbW1lbnRzLnB1c2goY29tbWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50cy5zcGxpY2UoY3Vyc29yLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnNvciArPSAxO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gYWxyZWFkeSBvdXQgb2Ygb3duZWQgbm9kZVxuICAgICAgICAgICAgICAgIGlmIChjdXJzb3IgPT09IGNvbW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVmlzaXRvck9wdGlvbi5CcmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoY29tbWVudHNbY3Vyc29yXS5leHRlbmRlZFJhbmdlWzBdID4gbm9kZS5yYW5nZVsxXSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVmlzaXRvck9wdGlvbi5Ta2lwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHRyZWU7XG4gICAgfVxuXG4gICAgZXhwb3J0cy52ZXJzaW9uID0gcmVxdWlyZSgnLi9wYWNrYWdlLmpzb24nKS52ZXJzaW9uO1xuICAgIGV4cG9ydHMuU3ludGF4ID0gU3ludGF4O1xuICAgIGV4cG9ydHMudHJhdmVyc2UgPSB0cmF2ZXJzZTtcbiAgICBleHBvcnRzLnJlcGxhY2UgPSByZXBsYWNlO1xuICAgIGV4cG9ydHMuYXR0YWNoQ29tbWVudHMgPSBhdHRhY2hDb21tZW50cztcbiAgICBleHBvcnRzLlZpc2l0b3JLZXlzID0gVmlzaXRvcktleXM7XG4gICAgZXhwb3J0cy5WaXNpdG9yT3B0aW9uID0gVmlzaXRvck9wdGlvbjtcbiAgICBleHBvcnRzLkNvbnRyb2xsZXIgPSBDb250cm9sbGVyO1xuICAgIGV4cG9ydHMuY2xvbmVFbnZpcm9ubWVudCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNsb25lKHt9KTsgfTtcblxuICAgIHJldHVybiBleHBvcnRzO1xufShleHBvcnRzKSk7XG4vKiB2aW06IHNldCBzdz00IHRzPTQgZXQgdHc9ODAgOiAqL1xuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcIm5hbWVcIjogXCJlc3RyYXZlcnNlXCIsXG4gIFwiZGVzY3JpcHRpb25cIjogXCJFQ01BU2NyaXB0IEpTIEFTVCB0cmF2ZXJzYWwgZnVuY3Rpb25zXCIsXG4gIFwiaG9tZXBhZ2VcIjogXCJodHRwczovL2dpdGh1Yi5jb20vZXN0b29scy9lc3RyYXZlcnNlXCIsXG4gIFwibWFpblwiOiBcImVzdHJhdmVyc2UuanNcIixcbiAgXCJ2ZXJzaW9uXCI6IFwiMy4xLjBcIixcbiAgXCJlbmdpbmVzXCI6IHtcbiAgICBcIm5vZGVcIjogXCI+PTAuMTAuMFwiXG4gIH0sXG4gIFwibWFpbnRhaW5lcnNcIjogW1xuICAgIHtcbiAgICAgIFwibmFtZVwiOiBcImNvbnN0ZWxsYXRpb25cIixcbiAgICAgIFwiZW1haWxcIjogXCJ1dGF0YW5lLnRlYUBnbWFpbC5jb21cIlxuICAgIH0sXG4gICAge1xuICAgICAgXCJuYW1lXCI6IFwibWljaGFlbGZpY2FycmFcIixcbiAgICAgIFwiZW1haWxcIjogXCJucG1AbWljaGFlbC5maWNhcnJhLm1lXCJcbiAgICB9XG4gIF0sXG4gIFwicmVwb3NpdG9yeVwiOiB7XG4gICAgXCJ0eXBlXCI6IFwiZ2l0XCIsXG4gICAgXCJ1cmxcIjogXCJodHRwOi8vZ2l0aHViLmNvbS9lc3Rvb2xzL2VzdHJhdmVyc2UuZ2l0XCJcbiAgfSxcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiY2hhaVwiOiBcIl4yLjEuMVwiLFxuICAgIFwiY29mZmVlLXNjcmlwdFwiOiBcIl4xLjguMFwiLFxuICAgIFwiZXNwcmVlXCI6IFwiXjEuMTEuMFwiLFxuICAgIFwiZ3VscFwiOiBcIl4zLjguMTBcIixcbiAgICBcImd1bHAtYnVtcFwiOiBcIl4wLjIuMlwiLFxuICAgIFwiZ3VscC1maWx0ZXJcIjogXCJeMi4wLjBcIixcbiAgICBcImd1bHAtZ2l0XCI6IFwiXjEuMC4xXCIsXG4gICAgXCJndWxwLXRhZy12ZXJzaW9uXCI6IFwiXjEuMi4xXCIsXG4gICAgXCJqc2hpbnRcIjogXCJeMi41LjZcIixcbiAgICBcIm1vY2hhXCI6IFwiXjIuMS4wXCJcbiAgfSxcbiAgXCJsaWNlbnNlc1wiOiBbXG4gICAge1xuICAgICAgXCJ0eXBlXCI6IFwiQlNEXCIsXG4gICAgICBcInVybFwiOiBcImh0dHA6Ly9naXRodWIuY29tL2VzdG9vbHMvZXN0cmF2ZXJzZS9yYXcvbWFzdGVyL0xJQ0VOU0UuQlNEXCJcbiAgICB9XG4gIF0sXG4gIFwic2NyaXB0c1wiOiB7XG4gICAgXCJ0ZXN0XCI6IFwibnBtIHJ1bi1zY3JpcHQgbGludCAmJiBucG0gcnVuLXNjcmlwdCB1bml0LXRlc3RcIixcbiAgICBcImxpbnRcIjogXCJqc2hpbnQgZXN0cmF2ZXJzZS5qc1wiLFxuICAgIFwidW5pdC10ZXN0XCI6IFwibW9jaGEgLS1jb21waWxlcnMgY29mZmVlOmNvZmZlZS1zY3JpcHQvcmVnaXN0ZXJcIlxuICB9LFxuICBcImdpdEhlYWRcIjogXCIxNjZlYmJlMGE4ZDQ1Y2ViMjM5MWI2ZjVlZjVkMWJhYjZiZmIyNjdhXCIsXG4gIFwiYnVnc1wiOiB7XG4gICAgXCJ1cmxcIjogXCJodHRwczovL2dpdGh1Yi5jb20vZXN0b29scy9lc3RyYXZlcnNlL2lzc3Vlc1wiXG4gIH0sXG4gIFwiX2lkXCI6IFwiZXN0cmF2ZXJzZUAzLjEuMFwiLFxuICBcIl9zaGFzdW1cIjogXCIxNWUyOGE0NDZiOGI4MmJjNzAwY2NjOGI5NmM3OGFmNGRhMGQ2Y2JhXCIsXG4gIFwiX2Zyb21cIjogXCJlc3RyYXZlcnNlQD49My4xLjAgPDQuMC4wXCIsXG4gIFwiX25wbVZlcnNpb25cIjogXCIyLjAuMC1hbHBoYS01XCIsXG4gIFwiX25wbVVzZXJcIjoge1xuICAgIFwibmFtZVwiOiBcImNvbnN0ZWxsYXRpb25cIixcbiAgICBcImVtYWlsXCI6IFwidXRhdGFuZS50ZWFAZ21haWwuY29tXCJcbiAgfSxcbiAgXCJkaXN0XCI6IHtcbiAgICBcInNoYXN1bVwiOiBcIjE1ZTI4YTQ0NmI4YjgyYmM3MDBjY2M4Yjk2Yzc4YWY0ZGEwZDZjYmFcIixcbiAgICBcInRhcmJhbGxcIjogXCJodHRwOi8vcmVnaXN0cnkubnBtanMub3JnL2VzdHJhdmVyc2UvLS9lc3RyYXZlcnNlLTMuMS4wLnRnelwiXG4gIH0sXG4gIFwiZGlyZWN0b3JpZXNcIjoge30sXG4gIFwiX3Jlc29sdmVkXCI6IFwiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvZXN0cmF2ZXJzZS8tL2VzdHJhdmVyc2UtMy4xLjAudGd6XCIsXG4gIFwicmVhZG1lXCI6IFwiRVJST1I6IE5vIFJFQURNRSBkYXRhIGZvdW5kIVwiXG59XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCwgdW5kZWZpbmVkKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICBpZiAoZ2xvYmFsLnNldEltbWVkaWF0ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIG5leHRIYW5kbGUgPSAxOyAvLyBTcGVjIHNheXMgZ3JlYXRlciB0aGFuIHplcm9cbiAgICB2YXIgdGFza3NCeUhhbmRsZSA9IHt9O1xuICAgIHZhciBjdXJyZW50bHlSdW5uaW5nQVRhc2sgPSBmYWxzZTtcbiAgICB2YXIgZG9jID0gZ2xvYmFsLmRvY3VtZW50O1xuICAgIHZhciBzZXRJbW1lZGlhdGU7XG5cbiAgICBmdW5jdGlvbiBhZGRGcm9tU2V0SW1tZWRpYXRlQXJndW1lbnRzKGFyZ3MpIHtcbiAgICAgICAgdGFza3NCeUhhbmRsZVtuZXh0SGFuZGxlXSA9IHBhcnRpYWxseUFwcGxpZWQuYXBwbHkodW5kZWZpbmVkLCBhcmdzKTtcbiAgICAgICAgcmV0dXJuIG5leHRIYW5kbGUrKztcbiAgICB9XG5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIGFjY2VwdHMgdGhlIHNhbWUgYXJndW1lbnRzIGFzIHNldEltbWVkaWF0ZSwgYnV0XG4gICAgLy8gcmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgcmVxdWlyZXMgbm8gYXJndW1lbnRzLlxuICAgIGZ1bmN0aW9uIHBhcnRpYWxseUFwcGxpZWQoaGFuZGxlcikge1xuICAgICAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBoYW5kbGVyLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIChuZXcgRnVuY3Rpb24oXCJcIiArIGhhbmRsZXIpKSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJ1bklmUHJlc2VudChoYW5kbGUpIHtcbiAgICAgICAgLy8gRnJvbSB0aGUgc3BlYzogXCJXYWl0IHVudGlsIGFueSBpbnZvY2F0aW9ucyBvZiB0aGlzIGFsZ29yaXRobSBzdGFydGVkIGJlZm9yZSB0aGlzIG9uZSBoYXZlIGNvbXBsZXRlZC5cIlxuICAgICAgICAvLyBTbyBpZiB3ZSdyZSBjdXJyZW50bHkgcnVubmluZyBhIHRhc2ssIHdlJ2xsIG5lZWQgdG8gZGVsYXkgdGhpcyBpbnZvY2F0aW9uLlxuICAgICAgICBpZiAoY3VycmVudGx5UnVubmluZ0FUYXNrKSB7XG4gICAgICAgICAgICAvLyBEZWxheSBieSBkb2luZyBhIHNldFRpbWVvdXQuIHNldEltbWVkaWF0ZSB3YXMgdHJpZWQgaW5zdGVhZCwgYnV0IGluIEZpcmVmb3ggNyBpdCBnZW5lcmF0ZWQgYVxuICAgICAgICAgICAgLy8gXCJ0b28gbXVjaCByZWN1cnNpb25cIiBlcnJvci5cbiAgICAgICAgICAgIHNldFRpbWVvdXQocGFydGlhbGx5QXBwbGllZChydW5JZlByZXNlbnQsIGhhbmRsZSksIDApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIHRhc2sgPSB0YXNrc0J5SGFuZGxlW2hhbmRsZV07XG4gICAgICAgICAgICBpZiAodGFzaykge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRseVJ1bm5pbmdBVGFzayA9IHRydWU7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgdGFzaygpO1xuICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgIGNsZWFySW1tZWRpYXRlKGhhbmRsZSk7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRseVJ1bm5pbmdBVGFzayA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlKGhhbmRsZSkge1xuICAgICAgICBkZWxldGUgdGFza3NCeUhhbmRsZVtoYW5kbGVdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxOZXh0VGlja0ltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICBzZXRJbW1lZGlhdGUgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBoYW5kbGUgPSBhZGRGcm9tU2V0SW1tZWRpYXRlQXJndW1lbnRzKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICBwcm9jZXNzLm5leHRUaWNrKHBhcnRpYWxseUFwcGxpZWQocnVuSWZQcmVzZW50LCBoYW5kbGUpKTtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FuVXNlUG9zdE1lc3NhZ2UoKSB7XG4gICAgICAgIC8vIFRoZSB0ZXN0IGFnYWluc3QgYGltcG9ydFNjcmlwdHNgIHByZXZlbnRzIHRoaXMgaW1wbGVtZW50YXRpb24gZnJvbSBiZWluZyBpbnN0YWxsZWQgaW5zaWRlIGEgd2ViIHdvcmtlcixcbiAgICAgICAgLy8gd2hlcmUgYGdsb2JhbC5wb3N0TWVzc2FnZWAgbWVhbnMgc29tZXRoaW5nIGNvbXBsZXRlbHkgZGlmZmVyZW50IGFuZCBjYW4ndCBiZSB1c2VkIGZvciB0aGlzIHB1cnBvc2UuXG4gICAgICAgIGlmIChnbG9iYWwucG9zdE1lc3NhZ2UgJiYgIWdsb2JhbC5pbXBvcnRTY3JpcHRzKSB7XG4gICAgICAgICAgICB2YXIgcG9zdE1lc3NhZ2VJc0FzeW5jaHJvbm91cyA9IHRydWU7XG4gICAgICAgICAgICB2YXIgb2xkT25NZXNzYWdlID0gZ2xvYmFsLm9ubWVzc2FnZTtcbiAgICAgICAgICAgIGdsb2JhbC5vbm1lc3NhZ2UgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZUlzQXN5bmNocm9ub3VzID0gZmFsc2U7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZ2xvYmFsLnBvc3RNZXNzYWdlKFwiXCIsIFwiKlwiKTtcbiAgICAgICAgICAgIGdsb2JhbC5vbm1lc3NhZ2UgPSBvbGRPbk1lc3NhZ2U7XG4gICAgICAgICAgICByZXR1cm4gcG9zdE1lc3NhZ2VJc0FzeW5jaHJvbm91cztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxQb3N0TWVzc2FnZUltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICAvLyBJbnN0YWxscyBhbiBldmVudCBoYW5kbGVyIG9uIGBnbG9iYWxgIGZvciB0aGUgYG1lc3NhZ2VgIGV2ZW50OiBzZWVcbiAgICAgICAgLy8gKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9ET00vd2luZG93LnBvc3RNZXNzYWdlXG4gICAgICAgIC8vICogaHR0cDovL3d3dy53aGF0d2cub3JnL3NwZWNzL3dlYi1hcHBzL2N1cnJlbnQtd29yay9tdWx0aXBhZ2UvY29tbXMuaHRtbCNjcm9zc0RvY3VtZW50TWVzc2FnZXNcblxuICAgICAgICB2YXIgbWVzc2FnZVByZWZpeCA9IFwic2V0SW1tZWRpYXRlJFwiICsgTWF0aC5yYW5kb20oKSArIFwiJFwiO1xuICAgICAgICB2YXIgb25HbG9iYWxNZXNzYWdlID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIGlmIChldmVudC5zb3VyY2UgPT09IGdsb2JhbCAmJlxuICAgICAgICAgICAgICAgIHR5cGVvZiBldmVudC5kYXRhID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgICAgICAgZXZlbnQuZGF0YS5pbmRleE9mKG1lc3NhZ2VQcmVmaXgpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcnVuSWZQcmVzZW50KCtldmVudC5kYXRhLnNsaWNlKG1lc3NhZ2VQcmVmaXgubGVuZ3RoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgb25HbG9iYWxNZXNzYWdlLCBmYWxzZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBnbG9iYWwuYXR0YWNoRXZlbnQoXCJvbm1lc3NhZ2VcIiwgb25HbG9iYWxNZXNzYWdlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNldEltbWVkaWF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIGhhbmRsZSA9IGFkZEZyb21TZXRJbW1lZGlhdGVBcmd1bWVudHMoYXJndW1lbnRzKTtcbiAgICAgICAgICAgIGdsb2JhbC5wb3N0TWVzc2FnZShtZXNzYWdlUHJlZml4ICsgaGFuZGxlLCBcIipcIik7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxNZXNzYWdlQ2hhbm5lbEltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICB2YXIgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgICAgICB2YXIgaGFuZGxlID0gZXZlbnQuZGF0YTtcbiAgICAgICAgICAgIHJ1bklmUHJlc2VudChoYW5kbGUpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHNldEltbWVkaWF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIGhhbmRsZSA9IGFkZEZyb21TZXRJbW1lZGlhdGVBcmd1bWVudHMoYXJndW1lbnRzKTtcbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoaGFuZGxlKTtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbFJlYWR5U3RhdGVDaGFuZ2VJbXBsZW1lbnRhdGlvbigpIHtcbiAgICAgICAgdmFyIGh0bWwgPSBkb2MuZG9jdW1lbnRFbGVtZW50O1xuICAgICAgICBzZXRJbW1lZGlhdGUgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBoYW5kbGUgPSBhZGRGcm9tU2V0SW1tZWRpYXRlQXJndW1lbnRzKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAvLyBDcmVhdGUgYSA8c2NyaXB0PiBlbGVtZW50OyBpdHMgcmVhZHlzdGF0ZWNoYW5nZSBldmVudCB3aWxsIGJlIGZpcmVkIGFzeW5jaHJvbm91c2x5IG9uY2UgaXQgaXMgaW5zZXJ0ZWRcbiAgICAgICAgICAgIC8vIGludG8gdGhlIGRvY3VtZW50LiBEbyBzbywgdGh1cyBxdWV1aW5nIHVwIHRoZSB0YXNrLiBSZW1lbWJlciB0byBjbGVhbiB1cCBvbmNlIGl0J3MgYmVlbiBjYWxsZWQuXG4gICAgICAgICAgICB2YXIgc2NyaXB0ID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIik7XG4gICAgICAgICAgICBzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJ1bklmUHJlc2VudChoYW5kbGUpO1xuICAgICAgICAgICAgICAgIHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsO1xuICAgICAgICAgICAgICAgIGh0bWwucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgICAgICAgICBzY3JpcHQgPSBudWxsO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGh0bWwuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbFNldFRpbWVvdXRJbXBsZW1lbnRhdGlvbigpIHtcbiAgICAgICAgc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB2YXIgaGFuZGxlID0gYWRkRnJvbVNldEltbWVkaWF0ZUFyZ3VtZW50cyhhcmd1bWVudHMpO1xuICAgICAgICAgICAgc2V0VGltZW91dChwYXJ0aWFsbHlBcHBsaWVkKHJ1bklmUHJlc2VudCwgaGFuZGxlKSwgMCk7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIElmIHN1cHBvcnRlZCwgd2Ugc2hvdWxkIGF0dGFjaCB0byB0aGUgcHJvdG90eXBlIG9mIGdsb2JhbCwgc2luY2UgdGhhdCBpcyB3aGVyZSBzZXRUaW1lb3V0IGV0IGFsLiBsaXZlLlxuICAgIHZhciBhdHRhY2hUbyA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoZ2xvYmFsKTtcbiAgICBhdHRhY2hUbyA9IGF0dGFjaFRvICYmIGF0dGFjaFRvLnNldFRpbWVvdXQgPyBhdHRhY2hUbyA6IGdsb2JhbDtcblxuICAgIC8vIERvbid0IGdldCBmb29sZWQgYnkgZS5nLiBicm93c2VyaWZ5IGVudmlyb25tZW50cy5cbiAgICBpZiAoe30udG9TdHJpbmcuY2FsbChnbG9iYWwucHJvY2VzcykgPT09IFwiW29iamVjdCBwcm9jZXNzXVwiKSB7XG4gICAgICAgIC8vIEZvciBOb2RlLmpzIGJlZm9yZSAwLjlcbiAgICAgICAgaW5zdGFsbE5leHRUaWNrSW1wbGVtZW50YXRpb24oKTtcblxuICAgIH0gZWxzZSBpZiAoY2FuVXNlUG9zdE1lc3NhZ2UoKSkge1xuICAgICAgICAvLyBGb3Igbm9uLUlFMTAgbW9kZXJuIGJyb3dzZXJzXG4gICAgICAgIGluc3RhbGxQb3N0TWVzc2FnZUltcGxlbWVudGF0aW9uKCk7XG5cbiAgICB9IGVsc2UgaWYgKGdsb2JhbC5NZXNzYWdlQ2hhbm5lbCkge1xuICAgICAgICAvLyBGb3Igd2ViIHdvcmtlcnMsIHdoZXJlIHN1cHBvcnRlZFxuICAgICAgICBpbnN0YWxsTWVzc2FnZUNoYW5uZWxJbXBsZW1lbnRhdGlvbigpO1xuXG4gICAgfSBlbHNlIGlmIChkb2MgJiYgXCJvbnJlYWR5c3RhdGVjaGFuZ2VcIiBpbiBkb2MuY3JlYXRlRWxlbWVudChcInNjcmlwdFwiKSkge1xuICAgICAgICAvLyBGb3IgSUUgNuKAkzhcbiAgICAgICAgaW5zdGFsbFJlYWR5U3RhdGVDaGFuZ2VJbXBsZW1lbnRhdGlvbigpO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRm9yIG9sZGVyIGJyb3dzZXJzXG4gICAgICAgIGluc3RhbGxTZXRUaW1lb3V0SW1wbGVtZW50YXRpb24oKTtcbiAgICB9XG5cbiAgICBhdHRhY2hUby5zZXRJbW1lZGlhdGUgPSBzZXRJbW1lZGlhdGU7XG4gICAgYXR0YWNoVG8uY2xlYXJJbW1lZGlhdGUgPSBjbGVhckltbWVkaWF0ZTtcbn0obmV3IEZ1bmN0aW9uKFwicmV0dXJuIHRoaXNcIikoKSkpO1xuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IChjKSAyMDE1IFRoZSBQb2x5bWVyIFByb2plY3QgQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFRoaXMgY29kZSBtYXkgb25seSBiZSB1c2VkIHVuZGVyIHRoZSBCU0Qgc3R5bGUgbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vTElDRU5TRS50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgYXV0aG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0FVVEhPUlMudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGNvbnRyaWJ1dG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0NPTlRSSUJVVE9SUy50eHRcbiAqIENvZGUgZGlzdHJpYnV0ZWQgYnkgR29vZ2xlIGFzIHBhcnQgb2YgdGhlIHBvbHltZXIgcHJvamVjdCBpcyBhbHNvXG4gKiBzdWJqZWN0IHRvIGFuIGFkZGl0aW9uYWwgSVAgcmlnaHRzIGdyYW50IGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9QQVRFTlRTLnR4dFxuICovXG4gLypqc2xpbnQgbm9kZTogdHJ1ZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIFN0YXRpYyBhbmFseXNpcyBmb3IgUG9seW1lci5cbiAqIEBuYW1lc3BhY2UgaHlkcm9seXNpc1xuICovXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQW5hbHl6ZXI6ICAgICByZXF1aXJlKCcuL2xpYi9hbmFseXplcicpLFxuICBkb2NzOiAgICAgICAgIHJlcXVpcmUoJy4vbGliL2FzdC11dGlscy9kb2NzJyksXG4gIEZTUmVzb2x2ZXI6ICAgcmVxdWlyZSgnLi9saWIvbG9hZGVyL2ZzLXJlc29sdmVyJyksXG4gIGpzZG9jOiAgICAgICAgcmVxdWlyZSgnLi9saWIvYXN0LXV0aWxzL2pzZG9jJyksXG4gIExvYWRlcjogICAgICAgcmVxdWlyZSgnLi9saWIvbG9hZGVyL2ZpbGUtbG9hZGVyJyksXG4gIE5vb3BSZXNvbHZlcjogcmVxdWlyZSgnLi9saWIvbG9hZGVyL25vb3AtcmVzb2x2ZXInKSxcbiAgWEhSUmVzb2x2ZXI6ICByZXF1aXJlKCcuL2xpYi9sb2FkZXIveGhyLXJlc29sdmVyJyksXG4gIF9qc1BhcnNlOiAgICAgcmVxdWlyZSgnLi9saWIvYXN0LXV0aWxzL2pzLXBhcnNlJyksXG4gIF9pbXBvcnRQYXJzZTogcmVxdWlyZSgnLi9saWIvYXN0LXV0aWxzL2ltcG9ydC1wYXJzZScpLFxufTtcbiJdfQ==
diff --git a/polymer_1.0.4/bower_components/hydrolysis/index.js b/polymer_1.0.4/bower_components/hydrolysis/index.js
new file mode 100644
index 0000000..157d450
--- /dev/null
+++ b/polymer_1.0.4/bower_components/hydrolysis/index.js
@@ -0,0 +1,27 @@
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+ /*jslint node: true */
+'use strict';
+
+/**
+ * Static analysis for Polymer.
+ * @namespace hydrolysis
+ */
+module.exports = {
+ Analyzer: require('./lib/analyzer'),
+ docs: require('./lib/ast-utils/docs'),
+ FSResolver: require('./lib/loader/fs-resolver'),
+ jsdoc: require('./lib/ast-utils/jsdoc'),
+ Loader: require('./lib/loader/file-loader'),
+ NoopResolver: require('./lib/loader/noop-resolver'),
+ XHRResolver: require('./lib/loader/xhr-resolver'),
+ _jsParse: require('./lib/ast-utils/js-parse'),
+ _importParse: require('./lib/ast-utils/import-parse'),
+};
diff --git a/polymer_1.0.4/bower_components/iron-a11y-announcer/.bower.json b/polymer_1.0.4/bower_components/iron-a11y-announcer/.bower.json
new file mode 100644
index 0000000..887caa2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-announcer/.bower.json
@@ -0,0 +1,42 @@
+{
+ "name": "iron-a11y-announcer",
+ "version": "1.0.1",
+ "description": "A singleton element that simplifies announcing text to screen readers.",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "a11y",
+ "live"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-a11y-announcer.git"
+ },
+ "main": "iron-a11y-announcer.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "dependencies": {
+ "polymer": "polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
+ "paper-button": "polymerelements/paper-button#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "web-component-tester": "*"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-a11y-announcer",
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "699697fe8935400ab11e3e33cd6a5a54d762300e"
+ },
+ "_source": "git://github.com/PolymerElements/iron-a11y-announcer.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-a11y-announcer"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-a11y-announcer/.gitignore b/polymer_1.0.4/bower_components/iron-a11y-announcer/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-announcer/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-a11y-announcer/README.md b/polymer_1.0.4/bower_components/iron-a11y-announcer/README.md
new file mode 100644
index 0000000..5988d8c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-announcer/README.md
@@ -0,0 +1,29 @@
+iron-a11y-announcer
+===================
+
+`iron-a11y-announcer` is a singleton element that is intended to add a11y
+to features that require on-demand announcement from screen readers. In
+order to make use of the announcer, it is best to request its availability
+in the announcing element.
+
+Example:
+
+ Polymer({
+ is: 'x-chatty',
+ attached: function() {
+ // This will create the singlton element if it has not
+ // been created yet:
+ Polymer.IronA11yAnnouncer.requestAvailability();
+ }
+ });
+
+After the `iron-a11y-announcer` has been made available, elements can
+make announces by firing bubbling `iron-announce` events.
+
+Example:
+
+ this.fire('iron-announce', {
+ text: 'This is an announcement!'
+ }, { bubbles: true });
+
+Note: announcements are only audible if you have a screen reader enabled.
diff --git a/polymer_1.0.4/bower_components/iron-a11y-announcer/bower.json b/polymer_1.0.4/bower_components/iron-a11y-announcer/bower.json
new file mode 100644
index 0000000..cbe80e0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-announcer/bower.json
@@ -0,0 +1,32 @@
+{
+ "name": "iron-a11y-announcer",
+ "version": "1.0.1",
+ "description": "A singleton element that simplifies announcing text to screen readers.",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "a11y",
+ "live"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-a11y-announcer.git"
+ },
+ "main": "iron-a11y-announcer.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "dependencies": {
+ "polymer": "polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
+ "paper-button": "polymerelements/paper-button#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "web-component-tester": "*"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-a11y-announcer/demo/index.html b/polymer_1.0.4/bower_components/iron-a11y-announcer/demo/index.html
new file mode 100644
index 0000000..d9e939c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-announcer/demo/index.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>iron-a11y-announcer demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="x-announces.html">
+
+
+</head>
+<body>
+ <div class="horizontal center-justified layout">
+ <div>
+ <div class="vertical-section">
+ <span>Note: in order to hear the announcements, be sure to turn on your favorite screen reader!</span>
+ <x-announces>Hello, my name is Ava.</x-announces>
+ <x-announces>This true sentence is false.</x-announces>
+ <x-announces>Are you paying attention?</x-announces>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-announcer/demo/x-announces.html b/polymer_1.0.4/bower_components/iron-a11y-announcer/demo/x-announces.html
new file mode 100644
index 0000000..404f7c0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-announcer/demo/x-announces.html
@@ -0,0 +1,50 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../../paper-button/paper-button.html">
+<link rel="import" href="../iron-a11y-announcer.html">
+
+<dom-module id="x-announces">
+ <style>
+ :host {
+ display: block;
+ position: relative;
+ padding: 1em 0;
+ }
+
+ paper-button {
+ background: #4285f4;
+ color: #fff;
+ }
+ </style>
+ <template>
+ <paper-button on-tap="_onTapAnnounce" raised>Announce</paper-button>
+ <span id="content" aria-hidden="true">
+ <content></content>
+ </span>
+ </template>
+ <script>
+ Polymer({
+ is: 'x-announces',
+
+ attached: function() {
+ Polymer.IronA11yAnnouncer.requestAvailability();
+ },
+
+ _onTapAnnounce: function() {
+ this.fire('iron-announce', {
+ text: this.$.content.textContent.trim()
+ }, {
+ bubbles: true
+ });
+ }
+ });
+ </script>
+</dom-module>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-announcer/index.html b/polymer_1.0.4/bower_components/iron-a11y-announcer/index.html
new file mode 100644
index 0000000..1f8889a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-announcer/index.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-a11y-announcer</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-announcer/iron-a11y-announcer.html b/polymer_1.0.4/bower_components/iron-a11y-announcer/iron-a11y-announcer.html
new file mode 100644
index 0000000..87e2be1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-announcer/iron-a11y-announcer.html
@@ -0,0 +1,125 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<!--
+`iron-a11y-announcer` is a singleton element that is intended to add a11y
+to features that require on-demand announcement from screen readers. In
+order to make use of the announcer, it is best to request its availability
+in the announcing element.
+
+Example:
+
+ Polymer({
+
+ is: 'x-chatty',
+
+ attached: function() {
+ // This will create the singlton element if it has not
+ // been created yet:
+ Polymer.IronA11yAnnouncer.requestAvailability();
+ }
+ });
+
+After the `iron-a11y-announcer` has been made available, elements can
+make announces by firing bubbling `iron-announce` events.
+
+Example:
+
+ this.fire('iron-announce', {
+ text: 'This is an announcement!'
+ }, { bubbles: true });
+
+Note: announcements are only audible if you have a screen reader enabled.
+
+@group Iron Elements
+@demo demo/index.html
+-->
+
+<dom-module id="iron-a11y-announcer">
+ <style>
+ :host {
+ display: inline-block;
+ position: fixed;
+ clip: rect(0px,0px,0px,0px);
+ }
+ </style>
+
+ <template>
+ <span aria-live$="[[mode]]">[[_text]]</span>
+ </template>
+
+ <script>
+
+ (function() {
+ 'use strict';
+
+ Polymer.IronA11yAnnouncer = Polymer({
+ is: 'iron-a11y-announcer',
+
+ properties: {
+
+ /**
+ * The value of mode is used to set the `aria-live` attribute
+ * for the element that will be announced. Valid values are: `off`,
+ * `polite` and `assertive`.
+ */
+ mode: {
+ type: String,
+ value: 'polite'
+ },
+
+ _text: {
+ type: String,
+ value: ''
+ }
+ },
+
+ created: function() {
+ if (!Polymer.IronA11yAnnouncer.instance) {
+ Polymer.IronA11yAnnouncer.instance = this;
+ }
+
+ document.body.addEventListener('iron-announce', this._onIronAnnounce.bind(this));
+ },
+
+ /**
+ * Cause a text string to be announced by screen readers.
+ *
+ * @param {string} text The text that should be announced.
+ */
+ announce: function(text) {
+ this._text = '';
+ this.async(function() {
+ this._text = text;
+ }, 100);
+ },
+
+ _onIronAnnounce: function(event) {
+ if (event.detail && event.detail.text) {
+ this.announce(event.detail.text);
+ }
+ }
+ });
+
+ Polymer.IronA11yAnnouncer.instance = null;
+
+ Polymer.IronA11yAnnouncer.requestAvailability = function() {
+ if (!Polymer.IronA11yAnnouncer.instance) {
+ document.createElement('iron-a11y-announcer');
+ }
+
+ document.body.appendChild(Polymer.IronA11yAnnouncer.instance);
+ };
+ })();
+
+ </script>
+</dom-module>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-announcer/test/index.html b/polymer_1.0.4/bower_components/iron-a11y-announcer/test/index.html
new file mode 100644
index 0000000..c65b801
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-announcer/test/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>iron-a11y-announcer tests</title>
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ </head>
+ <body>
+ <script>
+ WCT.loadSuites([
+ 'iron-a11y-announcer.html'
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-announcer/test/iron-a11y-announcer.html b/polymer_1.0.4/bower_components/iron-a11y-announcer/test/iron-a11y-announcer.html
new file mode 100644
index 0000000..f73cf6f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-announcer/test/iron-a11y-announcer.html
@@ -0,0 +1,59 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+ <title>iron-a11y-announcer</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-a11y-announcer.html">
+</head>
+<body>
+
+ <test-fixture id="Announcer">
+ <template>
+ <iron-a11y-announcer></iron-a11y-announcer>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('<iron-a11y-announcer>', function() {
+ var announcer;
+
+ setup(function() {
+ announcer = fixture('Announcer');
+ });
+
+ test('announces when there is an iron-announce event', function() {
+ var event = new CustomEvent('iron-announce', {
+ bubbles: true,
+ detail: {
+ text: 'foo'
+ }
+ });
+
+ sinon.spy(announcer, 'announce');
+
+ document.body.dispatchEvent(event);
+
+ expect(announcer.announce.callCount).to.be.equal(1);
+ });
+ });
+ </script>
+
+</body>
+</html>
+
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/.bower.json b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/.bower.json
new file mode 100644
index 0000000..8941cd5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/.bower.json
@@ -0,0 +1,42 @@
+{
+ "name": "iron-a11y-keys-behavior",
+ "version": "1.0.4",
+ "description": "A behavior that enables keybindings for greater a11y.",
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer",
+ "a11y",
+ "input"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-a11y-keys-behavior.git"
+ },
+ "main": "iron-a11y-keys-behavior.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.2",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-a11y-keys-behavior",
+ "_release": "1.0.4",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.4",
+ "commit": "a1f25fc34e1ef3767a9c68624a24be956d88d295"
+ },
+ "_source": "git://github.com/PolymerElements/iron-a11y-keys-behavior.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-a11y-keys-behavior"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/.gitignore b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/README.md b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/README.md
new file mode 100644
index 0000000..2d16daa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/README.md
@@ -0,0 +1,15 @@
+iron-a11y-keys-behavior
+=======================
+
+`Polymer.IronA11yKeysBehavior` provides a normalized interface for processing
+keyboard commands that pertain to [WAI-ARIA best practices](http://www.w3.org/TR/wai-aria-practices/#kbd_general_binding).
+The element takes care of browser differences with respect to Keyboard events
+and uses an expressive syntax to filter key presses.
+
+Use the `keyBindings` prototype property to express what combination of keys
+will trigger the event to fire.
+
+Use the `key-event-target` attribute to set up event handlers on a specific
+node.
+The `keys-pressed` event will fire when one of the key combinations set with the
+`keys` property is pressed.
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/bower.json b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/bower.json
new file mode 100644
index 0000000..3205bbe
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/bower.json
@@ -0,0 +1,32 @@
+{
+ "name": "iron-a11y-keys-behavior",
+ "version": "1.0.4",
+ "description": "A behavior that enables keybindings for greater a11y.",
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer",
+ "a11y",
+ "input"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-a11y-keys-behavior.git"
+ },
+ "main": "iron-a11y-keys-behavior.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.2",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/demo/index.html b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/demo/index.html
new file mode 100644
index 0000000..2c3fec7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/demo/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>Iron A11y Keys Behavior demo</title>
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="x-key-aware.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+</head>
+<body>
+ <div class="vertical-section vertical-section-container centered">
+ <x-key-aware></x-key-aware>
+ </div>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/demo/x-key-aware.html b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/demo/x-key-aware.html
new file mode 100644
index 0000000..a7f3205
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/demo/x-key-aware.html
@@ -0,0 +1,91 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../../paper-styles/paper-styles.html">
+<link rel="import" href="../iron-a11y-keys-behavior.html">
+
+<dom-module id="x-key-aware">
+ <style>
+ :host {
+ display: block;
+ position: relative;
+ }
+
+ pre {
+ color: var(--google-blue-700);
+ }
+
+ .keys {
+ line-height: 25px;
+ }
+
+ .keys span {
+ cursor: default;
+ background-color: var(--google-grey-100);
+ border: 1px solid var(--google-grey-300);
+ padding: 1px 5px;
+ border-radius: 5px;
+ }
+ </style>
+ <template>
+ <h4>Press any of these keys</h4>
+ <p class="keys">
+ <template is="dom-repeat" items="[[boundKeys]]">
+ <span>{{item}}</span>
+ </template>
+ </p>
+ <pre>[[pressed]]</pre>
+ </template>
+</dom-module>
+
+<script>
+ Polymer({
+ is: 'x-key-aware',
+
+ behaviors: [
+ Polymer.IronA11yKeysBehavior
+ ],
+
+ properties: {
+ pressed: {
+ type: String,
+ readOnly: true,
+ value: ''
+ },
+
+ boundKeys: {
+ type: Array,
+ value: function() {
+ return Object.keys(this.keyBindings).join(' ').split(' ');
+ }
+ },
+
+ keyEventTarget: {
+ type: Object,
+ value: function() {
+ return document.body;
+ }
+ }
+ },
+
+ keyBindings: {
+ '* pageup pagedown left right down up shift+a alt+a home end space enter': '_updatePressed'
+ },
+
+ _updatePressed: function(event) {
+ console.log(event.detail);
+
+ this._setPressed(
+ this.pressed + event.detail.combo + ' pressed!\n'
+ );
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/index.html b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/index.html
new file mode 100644
index 0000000..e533e79
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <title>iron-a11y-keys-behavior</title>
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html
new file mode 100644
index 0000000..47b7ee6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html
@@ -0,0 +1,421 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+ (function() {
+ 'use strict';
+
+ /**
+ * Chrome uses an older version of DOM Level 3 Keyboard Events
+ *
+ * Most keys are labeled as text, but some are Unicode codepoints.
+ * Values taken from: http://www.w3.org/TR/2007/WD-DOM-Level-3-Events-20071221/keyset.html#KeySet-Set
+ */
+ var KEY_IDENTIFIER = {
+ 'U+0009': 'tab',
+ 'U+001B': 'esc',
+ 'U+0020': 'space',
+ 'U+002A': '*',
+ 'U+0030': '0',
+ 'U+0031': '1',
+ 'U+0032': '2',
+ 'U+0033': '3',
+ 'U+0034': '4',
+ 'U+0035': '5',
+ 'U+0036': '6',
+ 'U+0037': '7',
+ 'U+0038': '8',
+ 'U+0039': '9',
+ 'U+0041': 'a',
+ 'U+0042': 'b',
+ 'U+0043': 'c',
+ 'U+0044': 'd',
+ 'U+0045': 'e',
+ 'U+0046': 'f',
+ 'U+0047': 'g',
+ 'U+0048': 'h',
+ 'U+0049': 'i',
+ 'U+004A': 'j',
+ 'U+004B': 'k',
+ 'U+004C': 'l',
+ 'U+004D': 'm',
+ 'U+004E': 'n',
+ 'U+004F': 'o',
+ 'U+0050': 'p',
+ 'U+0051': 'q',
+ 'U+0052': 'r',
+ 'U+0053': 's',
+ 'U+0054': 't',
+ 'U+0055': 'u',
+ 'U+0056': 'v',
+ 'U+0057': 'w',
+ 'U+0058': 'x',
+ 'U+0059': 'y',
+ 'U+005A': 'z',
+ 'U+007F': 'del'
+ };
+
+ /**
+ * Special table for KeyboardEvent.keyCode.
+ * KeyboardEvent.keyIdentifier is better, and KeyBoardEvent.key is even better
+ * than that.
+ *
+ * Values from: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent.keyCode#Value_of_keyCode
+ */
+ var KEY_CODE = {
+ 9: 'tab',
+ 13: 'enter',
+ 27: 'esc',
+ 33: 'pageup',
+ 34: 'pagedown',
+ 35: 'end',
+ 36: 'home',
+ 32: 'space',
+ 37: 'left',
+ 38: 'up',
+ 39: 'right',
+ 40: 'down',
+ 46: 'del',
+ 106: '*'
+ };
+
+ /**
+ * MODIFIER_KEYS maps the short name for modifier keys used in a key
+ * combo string to the property name that references those same keys
+ * in a KeyboardEvent instance.
+ */
+ var MODIFIER_KEYS = {
+ shift: 'shiftKey',
+ ctrl: 'ctrlKey',
+ alt: 'altKey',
+ meta: 'metaKey'
+ };
+
+ /**
+ * KeyboardEvent.key is mostly represented by printable character made by
+ * the keyboard, with unprintable keys labeled nicely.
+ *
+ * However, on OS X, Alt+char can make a Unicode character that follows an
+ * Apple-specific mapping. In this case, we
+ * fall back to .keyCode.
+ */
+ var KEY_CHAR = /[a-z0-9*]/;
+
+ /**
+ * Matches a keyIdentifier string.
+ */
+ var IDENT_CHAR = /U\+/;
+
+ /**
+ * Matches arrow keys in Gecko 27.0+
+ */
+ var ARROW_KEY = /^arrow/;
+
+ /**
+ * Matches space keys everywhere (notably including IE10's exceptional name
+ * `spacebar`).
+ */
+ var SPACE_KEY = /^space(bar)?/;
+
+ function transformKey(key) {
+ var validKey = '';
+ if (key) {
+ var lKey = key.toLowerCase();
+ if (lKey.length == 1) {
+ if (KEY_CHAR.test(lKey)) {
+ validKey = lKey;
+ }
+ } else if (ARROW_KEY.test(lKey)) {
+ validKey = lKey.replace('arrow', '');
+ } else if (SPACE_KEY.test(lKey)) {
+ validKey = 'space';
+ } else if (lKey == 'multiply') {
+ // numpad '*' can map to Multiply on IE/Windows
+ validKey = '*';
+ } else {
+ validKey = lKey;
+ }
+ }
+ return validKey;
+ }
+
+ function transformKeyIdentifier(keyIdent) {
+ var validKey = '';
+ if (keyIdent) {
+ if (IDENT_CHAR.test(keyIdent)) {
+ validKey = KEY_IDENTIFIER[keyIdent];
+ } else {
+ validKey = keyIdent.toLowerCase();
+ }
+ }
+ return validKey;
+ }
+
+ function transformKeyCode(keyCode) {
+ var validKey = '';
+ if (Number(keyCode)) {
+ if (keyCode >= 65 && keyCode <= 90) {
+ // ascii a-z
+ // lowercase is 32 offset from uppercase
+ validKey = String.fromCharCode(32 + keyCode);
+ } else if (keyCode >= 112 && keyCode <= 123) {
+ // function keys f1-f12
+ validKey = 'f' + (keyCode - 112);
+ } else if (keyCode >= 48 && keyCode <= 57) {
+ // top 0-9 keys
+ validKey = String(48 - keyCode);
+ } else if (keyCode >= 96 && keyCode <= 105) {
+ // num pad 0-9
+ validKey = String(96 - keyCode);
+ } else {
+ validKey = KEY_CODE[keyCode];
+ }
+ }
+ return validKey;
+ }
+
+ function normalizedKeyForEvent(keyEvent) {
+ // fall back from .key, to .keyIdentifier, to .keyCode, and then to
+ // .detail.key to support artificial keyboard events
+ return transformKey(keyEvent.key) ||
+ transformKeyIdentifier(keyEvent.keyIdentifier) ||
+ transformKeyCode(keyEvent.keyCode) ||
+ transformKey(keyEvent.detail.key) || '';
+ }
+
+ function keyComboMatchesEvent(keyCombo, keyEvent) {
+ return normalizedKeyForEvent(keyEvent) === keyCombo.key &&
+ !!keyEvent.shiftKey === !!keyCombo.shiftKey &&
+ !!keyEvent.ctrlKey === !!keyCombo.ctrlKey &&
+ !!keyEvent.altKey === !!keyCombo.altKey &&
+ !!keyEvent.metaKey === !!keyCombo.metaKey;
+ }
+
+ function parseKeyComboString(keyComboString) {
+ return keyComboString.split('+').reduce(function(parsedKeyCombo, keyComboPart) {
+ var eventParts = keyComboPart.split(':');
+ var keyName = eventParts[0];
+ var event = eventParts[1];
+
+ if (keyName in MODIFIER_KEYS) {
+ parsedKeyCombo[MODIFIER_KEYS[keyName]] = true;
+ } else {
+ parsedKeyCombo.key = keyName;
+ parsedKeyCombo.event = event || 'keydown';
+ }
+
+ return parsedKeyCombo;
+ }, {
+ combo: keyComboString.split(':').shift()
+ });
+ }
+
+ function parseEventString(eventString) {
+ return eventString.split(' ').map(function(keyComboString) {
+ return parseKeyComboString(keyComboString);
+ });
+ }
+
+
+ /**
+ * `Polymer.IronA11yKeysBehavior` provides a normalized interface for processing
+ * keyboard commands that pertain to [WAI-ARIA best practices](http://www.w3.org/TR/wai-aria-practices/#kbd_general_binding).
+ * The element takes care of browser differences with respect to Keyboard events
+ * and uses an expressive syntax to filter key presses.
+ *
+ * Use the `keyBindings` prototype property to express what combination of keys
+ * will trigger the event to fire.
+ *
+ * Use the `key-event-target` attribute to set up event handlers on a specific
+ * node.
+ * The `keys-pressed` event will fire when one of the key combinations set with the
+ * `keys` property is pressed.
+ *
+ * @demo demo/index.html
+ * @polymerBehavior IronA11yKeysBehavior
+ */
+ Polymer.IronA11yKeysBehavior = {
+ properties: {
+ /**
+ * The HTMLElement that will be firing relevant KeyboardEvents.
+ */
+ keyEventTarget: {
+ type: Object,
+ value: function() {
+ return this;
+ }
+ },
+
+ _boundKeyHandlers: {
+ type: Array,
+ value: function() {
+ return [];
+ }
+ },
+
+ // We use this due to a limitation in IE10 where instances will have
+ // own properties of everything on the "prototype".
+ _imperativeKeyBindings: {
+ type: Object,
+ value: function() {
+ return {};
+ }
+ }
+ },
+
+ observers: [
+ '_resetKeyEventListeners(keyEventTarget, _boundKeyHandlers)'
+ ],
+
+ keyBindings: {},
+
+ registered: function() {
+ this._prepKeyBindings();
+ },
+
+ attached: function() {
+ this._listenKeyEventListeners();
+ },
+
+ detached: function() {
+ this._unlistenKeyEventListeners();
+ },
+
+ /**
+ * Can be used to imperatively add a key binding to the implementing
+ * element. This is the imperative equivalent of declaring a keybinding
+ * in the `keyBindings` prototype property.
+ */
+ addOwnKeyBinding: function(eventString, handlerName) {
+ this._imperativeKeyBindings[eventString] = handlerName;
+ this._prepKeyBindings();
+ this._resetKeyEventListeners();
+ },
+
+ /**
+ * When called, will remove all imperatively-added key bindings.
+ */
+ removeOwnKeyBindings: function() {
+ this._imperativeKeyBindings = {};
+ this._prepKeyBindings();
+ this._resetKeyEventListeners();
+ },
+
+ keyboardEventMatchesKeys: function(event, eventString) {
+ var keyCombos = parseEventString(eventString);
+ var index;
+
+ for (index = 0; index < keyCombos.length; ++index) {
+ if (keyComboMatchesEvent(keyCombos[index], event)) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ _collectKeyBindings: function() {
+ var keyBindings = this.behaviors.map(function(behavior) {
+ return behavior.keyBindings;
+ });
+
+ if (keyBindings.indexOf(this.keyBindings) === -1) {
+ keyBindings.push(this.keyBindings);
+ }
+
+ return keyBindings;
+ },
+
+ _prepKeyBindings: function() {
+ this._keyBindings = {};
+
+ this._collectKeyBindings().forEach(function(keyBindings) {
+ for (var eventString in keyBindings) {
+ this._addKeyBinding(eventString, keyBindings[eventString]);
+ }
+ }, this);
+
+ for (var eventString in this._imperativeKeyBindings) {
+ this._addKeyBinding(eventString, this._imperativeKeyBindings[eventString]);
+ }
+ },
+
+ _addKeyBinding: function(eventString, handlerName) {
+ parseEventString(eventString).forEach(function(keyCombo) {
+ this._keyBindings[keyCombo.event] =
+ this._keyBindings[keyCombo.event] || [];
+
+ this._keyBindings[keyCombo.event].push([
+ keyCombo,
+ handlerName
+ ]);
+ }, this);
+ },
+
+ _resetKeyEventListeners: function() {
+ this._unlistenKeyEventListeners();
+
+ if (this.isAttached) {
+ this._listenKeyEventListeners();
+ }
+ },
+
+ _listenKeyEventListeners: function() {
+ Object.keys(this._keyBindings).forEach(function(eventName) {
+ var keyBindings = this._keyBindings[eventName];
+ var boundKeyHandler = this._onKeyBindingEvent.bind(this, keyBindings);
+
+ this._boundKeyHandlers.push([this.keyEventTarget, eventName, boundKeyHandler]);
+
+ this.keyEventTarget.addEventListener(eventName, boundKeyHandler);
+ }, this);
+ },
+
+ _unlistenKeyEventListeners: function() {
+ var keyHandlerTuple;
+ var keyEventTarget;
+ var eventName;
+ var boundKeyHandler;
+
+ while (this._boundKeyHandlers.length) {
+ // My kingdom for block-scope binding and destructuring assignment..
+ keyHandlerTuple = this._boundKeyHandlers.pop();
+ keyEventTarget = keyHandlerTuple[0];
+ eventName = keyHandlerTuple[1];
+ boundKeyHandler = keyHandlerTuple[2];
+
+ keyEventTarget.removeEventListener(eventName, boundKeyHandler);
+ }
+ },
+
+ _onKeyBindingEvent: function(keyBindings, event) {
+ keyBindings.forEach(function(keyBinding) {
+ var keyCombo = keyBinding[0];
+ var handlerName = keyBinding[1];
+
+ if (!event.defaultPrevented && keyComboMatchesEvent(keyCombo, event)) {
+ this._triggerKeyHandler(keyCombo, handlerName, event);
+ }
+ }, this);
+ },
+
+ _triggerKeyHandler: function(keyCombo, handlerName, keyboardEvent) {
+ var detail = Object.create(keyCombo);
+ detail.keyboardEvent = keyboardEvent;
+
+ this[handlerName].call(this, new CustomEvent(keyCombo.event, {
+ detail: detail
+ }));
+ }
+ };
+ })();
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/test/basic-test.html b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/test/basic-test.html
new file mode 100644
index 0000000..8e50c92
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/test/basic-test.html
@@ -0,0 +1,248 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>iron-a11y-keys</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+ <script src="../../iron-test-helpers/mock-interactions.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-a11y-keys-behavior.html">
+</head>
+<body>
+ <test-fixture id="BasicKeys">
+ <template>
+ <x-a11y-basic-keys></x-a11y-basic-keys>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="ComboKeys">
+ <template>
+ <x-a11y-combo-keys></x-a11y-combo-keys>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="AlternativeEventKeys">
+ <template>
+ <x-a11y-alternate-event-keys></x-a11y-alternate-event-keys>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="BehaviorKeys">
+ <template>
+ <x-a11y-behavior-keys></x-a11y-behavior-keys>
+ </template>
+ </test-fixture>
+
+ <script>
+suite('Polymer.IronA11yKeysBehavior', function() {
+ var keys;
+
+ suiteSetup(function() {
+ var KeysTestBehavior = [Polymer.IronA11yKeysBehavior, {
+ properties: {
+ keyCount: {
+ type: Number,
+ value: 0
+ }
+ },
+
+ _keyHandler: function(event) {
+ this.keyCount++;
+ this.lastEvent = event;
+ }
+ }];
+
+ Polymer({
+ is: 'x-a11y-basic-keys',
+
+ behaviors: [
+ KeysTestBehavior
+ ],
+
+ keyBindings: {
+ 'space': '_keyHandler'
+ }
+ });
+
+ Polymer({
+ is: 'x-a11y-combo-keys',
+
+ behaviors: [
+ KeysTestBehavior
+ ],
+
+ keyBindings: {
+ 'ctrl+shift+a': '_keyHandler'
+ }
+ });
+
+ Polymer({
+ is: 'x-a11y-alternate-event-keys',
+
+ behaviors: [
+ KeysTestBehavior
+ ],
+
+ keyBindings: {
+ 'space:keyup': '_keyHandler'
+ }
+ });
+
+ var XA11yBehavior = {
+ keyBindings: {
+ 'enter': '_keyHandler'
+ }
+ };
+
+ Polymer({
+ is: 'x-a11y-behavior-keys',
+
+ behaviors: [
+ KeysTestBehavior,
+ XA11yBehavior
+ ],
+
+ keyBindings: {
+ 'space': '_keyHandler'
+ }
+ });
+ });
+
+ suite('basic keys', function() {
+ setup(function() {
+ keys = fixture('BasicKeys');
+ });
+
+ test('trigger the handler when the specified key is pressed', function() {
+ MockInteractions.pressSpace(keys);
+
+ expect(keys.keyCount).to.be.equal(1);
+ });
+
+ test('do not trigger the handler for non-specified keys', function() {
+ MockInteractions.pressEnter(keys);
+
+ expect(keys.keyCount).to.be.equal(0);
+ });
+
+ test('can have bindings added imperatively', function() {
+ keys.addOwnKeyBinding('enter', '_keyHandler');
+
+ MockInteractions.pressEnter(keys);
+ expect(keys.keyCount).to.be.equal(1);
+
+ MockInteractions.pressSpace(keys);
+ expect(keys.keyCount).to.be.equal(2);
+ });
+
+ test('can remove imperatively added bindings', function() {
+ keys.addOwnKeyBinding('enter', '_keyHandler');
+ keys.removeOwnKeyBindings();
+
+ MockInteractions.pressEnter(keys);
+ expect(keys.keyCount).to.be.equal(0);
+
+ MockInteractions.pressSpace(keys);
+ expect(keys.keyCount).to.be.equal(1);
+ });
+
+ suite('edge cases', function() {
+ test('knows that `spacebar` is the same as `space`', function() {
+ var event = new CustomEvent('keydown');
+ event.key = 'spacebar';
+ expect(keys.keyboardEventMatchesKeys(event, 'space')).to.be.equal(true);
+ });
+ });
+
+ suite('matching keyboard events to keys', function() {
+ test('can be done imperatively', function() {
+ var event = new CustomEvent('keydown');
+ event.keyCode = 65;
+ expect(keys.keyboardEventMatchesKeys(event, 'a')).to.be.equal(true);
+ });
+
+ test('can be done with a provided keyboardEvent', function() {
+ var event;
+ MockInteractions.pressSpace(keys);
+ event = keys.lastEvent;
+
+ expect(event.detail.keyboardEvent).to.be.okay;
+ expect(keys.keyboardEventMatchesKeys(event, 'space')).to.be.equal(true);
+ });
+
+ test('can handle variations in arrow key names', function() {
+ var event = new CustomEvent('keydown');
+ event.key = 'up';
+ expect(keys.keyboardEventMatchesKeys(event, 'up')).to.be.equal(true);
+ event.key = 'ArrowUp';
+ expect(keys.keyboardEventMatchesKeys(event, 'up')).to.be.equal(true);
+ });
+ });
+ });
+
+ suite('combo keys', function() {
+ setup(function() {
+ keys = fixture('ComboKeys');
+ });
+
+ test('trigger the handler when the combo is pressed', function() {
+ var event = new CustomEvent('keydown');
+
+ event.ctrlKey = true;
+ event.shiftKey = true;
+ event.keyCode = event.code = 65;
+
+ keys.dispatchEvent(event);
+
+ expect(keys.keyCount).to.be.equal(1);
+ });
+ });
+
+ suite('alternative event keys', function() {
+ setup(function() {
+ keys = fixture('AlternativeEventKeys');
+ });
+
+ test('trigger on the specified alternative keyboard event', function() {
+ MockInteractions.keyDownOn(keys, 32);
+
+ expect(keys.keyCount).to.be.equal(0);
+
+ MockInteractions.keyUpOn(keys, 32);
+
+ expect(keys.keyCount).to.be.equal(1);
+ });
+ });
+
+ suite('behavior keys', function() {
+ setup(function() {
+ keys = fixture('BehaviorKeys');
+ });
+
+ test('bindings in other behaviors are transitive', function() {
+ MockInteractions.pressEnter(keys);
+ MockInteractions.pressSpace(keys);
+
+ expect(keys.keyCount).to.be.equal(2);
+ });
+ });
+
+});
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/test/index.html b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/test/index.html
new file mode 100755
index 0000000..24f9e35
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys-behavior/test/index.html
@@ -0,0 +1,29 @@
+<!--
+ @license
+ Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ Code distributed by Google as part of the polymer project is also
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!doctype html>
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>Tests</title>
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ </head>
+
+ <body>
+ <script>
+ // Load and run all tests (.html, .js) as one suite:
+ WCT.loadSuites([
+ 'basic-test.html',
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys/.bower.json b/polymer_1.0.4/bower_components/iron-a11y-keys/.bower.json
new file mode 100644
index 0000000..002aa8f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys/.bower.json
@@ -0,0 +1,43 @@
+{
+ "name": "iron-a11y-keys",
+ "version": "1.0.2",
+ "description": "A basic element implementation of iron-a11y-keys-behavior, matching the legacy core-a11y-keys.",
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer",
+ "a11y",
+ "input"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-a11y-keys.git"
+ },
+ "main": "iron-a11y-keys.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "dependencies": {
+ "polymer": "polymer/polymer#^1.0.0",
+ "iron-a11y-keys-behavior": "polymerelements/iron-a11y-keys-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.2",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "web-component-tester": "*",
+ "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-a11y-keys",
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "7a53ab4824ee61ab994abfa8b5a3e1ad2ff9655d"
+ },
+ "_source": "git://github.com/PolymerElements/iron-a11y-keys.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-a11y-keys"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys/.gitignore b/polymer_1.0.4/bower_components/iron-a11y-keys/.gitignore
new file mode 100644
index 0000000..1eb1fa5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys/.gitignore
@@ -0,0 +1,2 @@
+bower_components
+
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys/README.md b/polymer_1.0.4/bower_components/iron-a11y-keys/README.md
new file mode 100644
index 0000000..514b4f5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys/README.md
@@ -0,0 +1,3 @@
+iron-a11y-keys
+==============
+
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys/bower.json b/polymer_1.0.4/bower_components/iron-a11y-keys/bower.json
new file mode 100644
index 0000000..11c28c3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys/bower.json
@@ -0,0 +1,33 @@
+{
+ "name": "iron-a11y-keys",
+ "version": "1.0.2",
+ "description": "A basic element implementation of iron-a11y-keys-behavior, matching the legacy core-a11y-keys.",
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer",
+ "a11y",
+ "input"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-a11y-keys.git"
+ },
+ "main": "iron-a11y-keys.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "dependencies": {
+ "polymer": "polymer/polymer#^1.0.0",
+ "iron-a11y-keys-behavior": "polymerelements/iron-a11y-keys-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.2",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "web-component-tester": "*",
+ "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys/demo/index.html b/polymer_1.0.4/bower_components/iron-a11y-keys/demo/index.html
new file mode 100644
index 0000000..4fe9af4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys/demo/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>Iron A11y Keys demo</title>
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="x-key-aware.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+</head>
+<body>
+ <div class="vertical-section vertical-section-container centered">
+ <x-key-aware tabindex="0"></x-key-aware>
+ </div>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys/demo/x-key-aware.html b/polymer_1.0.4/bower_components/iron-a11y-keys/demo/x-key-aware.html
new file mode 100644
index 0000000..adfd44e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys/demo/x-key-aware.html
@@ -0,0 +1,90 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../../paper-styles/paper-styles.html">
+<link rel="import" href="../iron-a11y-keys.html">
+
+<dom-module id="x-key-aware">
+ <style>
+ :host {
+ display: block;
+ position: relative;
+ }
+
+ pre {
+ color: var(--google-blue-700);
+ }
+
+ .keys {
+ line-height: 25px;
+ }
+
+ .keys span {
+ cursor: default;
+ background-color: var(--google-grey-100);
+ border: 1px solid var(--google-grey-300);
+ padding: 1px 5px;
+ border-radius: 5px;
+ }
+ </style>
+ <template>
+ <h4>Press any of these keys</h4>
+ <span class="keys">
+ <template is="dom-repeat" items="[[boundKeys]]">
+ <span>{{item}}</span>
+ </template>
+ </span>
+ <iron-a11y-keys
+ id="keys"
+ keys="* pageup pagedown left right down up shift+a alt+a home end space enter"
+ target="[[target]]"
+ on-keys-pressed="_updatePressed">
+ </iron-a11y-keys>
+ <pre id="output">[[pressed]]</pre>
+ </template>
+</dom-module>
+
+<script>
+ Polymer({
+ is: 'x-key-aware',
+
+ properties: {
+ pressed: {
+ type: String,
+ readOnly: true,
+ value: ''
+ },
+
+ boundKeys: {
+ type: Array
+ },
+
+ target: {
+ type: Object,
+ value: function() {
+ return document.body;
+ }
+ }
+ },
+
+ ready: function() {
+ this.boundKeys = this.$.keys.keys.split(' ');
+ },
+
+ _updatePressed: function(event) {
+ console.log(event.detail);
+
+ this._setPressed(
+ this.pressed + event.detail.combo + ' pressed!\n'
+ );
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys/index.html b/polymer_1.0.4/bower_components/iron-a11y-keys/index.html
new file mode 100644
index 0000000..02c5182
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <title>iron-a11y-keys</title>
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys/iron-a11y-keys.html b/polymer_1.0.4/bower_components/iron-a11y-keys/iron-a11y-keys.html
new file mode 100644
index 0000000..b60a090
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys/iron-a11y-keys.html
@@ -0,0 +1,122 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
+
+
+<script>
+
+/*
+`iron-a11y-keys` provides a normalized interface for processing keyboard commands that pertain to [WAI-ARIA best
+practices](http://www.w3.org/TR/wai-aria-practices/#kbd_general_binding). The element takes care of browser differences
+with respect to Keyboard events and uses an expressive syntax to filter key presses.
+
+Use the `keys` attribute to express what combination of keys will trigger the event to fire.
+
+Use the `target` attribute to set up event handlers on a specific node.
+The `keys-pressed` event will fire when one of the key combinations set with the `keys` attribute is pressed.
+
+Example:
+
+This element will call `arrowHandler` on all arrow keys:
+
+ <iron-a11y-keys target="{{}}" keys="up down left right" on-keys-pressed="{{arrowHandler}}"></iron-a11y-keys>
+
+Keys Syntax:
+
+The `keys` attribute can accepts a space seprated, `+` concatenated set of modifier keys and some common keyboard keys.
+
+The common keys are `a-z`, `0-9` (top row and number pad), `*` (shift 8 and number pad), `F1-F12`, `Page Up`, `Page
+Down`, `Left Arrow`, `Right Arrow`, `Down Arrow`, `Up Arrow`, `Home`, `End`, `Escape`, `Space`, `Tab`, and `Enter` keys.
+
+The modifier keys are `Shift`, `Control`, and `Alt`.
+
+All keys are expected to be lowercase and shortened:
+`Left Arrow` is `left`, `Page Down` is `pagedown`, `Control` is `ctrl`, `F1` is `f1`, `Escape` is `esc` etc.
+
+Keys Syntax Example:
+
+Given the `keys` attribute value "ctrl+shift+f7 up pagedown esc space alt+m", the `<iron-a11y-keys>` element will send
+the `keys-pressed` event if any of the follow key combos are pressed: Control and Shift and F7 keys, Up Arrow key, Page
+Down key, Escape key, Space key, Alt and M key.
+
+Slider Example:
+
+The following is an example of the set of keys that fulfil the WAI-ARIA "slider" role [best
+practices](http://www.w3.org/TR/wai-aria-practices/#slider):
+
+ <iron-a11y-keys target="{{}}" keys="left pagedown down" on-keys-pressed="{{decrement}}"></iron-a11y-keys>
+ <iron-a11y-keys target="{{}}" keys="right pageup up" on-keys-pressed="{{increment}}"></iron-a11y-keys>
+ <iron-a11y-keys target="{{}}" keys="home" on-keys-pressed="{{setMin}}"></iron-a11y-keys>
+ <iron-a11y-keys target="{{}}" keys="end" on-keys-pressed="{{setMax}}"></iron-a11y-keys>
+
+The `increment` function will move the slider a set amount toward the maximum value.
+The `decrement` function will move the slider a set amount toward the minimum value.
+The `setMin` function will move the slider to the minimum value.
+The `setMax` function will move the slider to the maximum value.
+
+Keys Syntax Grammar:
+
+[EBNF](http://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form) Grammar of the `keys` attribute.
+
+ modifier = "shift" | "ctrl" | "alt";
+ ascii = ? /[a-z0-9]/ ? ;
+ fnkey = ? f1 through f12 ? ;
+ arrow = "up" | "down" | "left" | "right" ;
+ key = "tab" | "esc" | "space" | "*" | "pageup" | "pagedown" | "home" | "end" | arrow | ascii | fnkey ;
+ keycombo = { modifier, "+" }, key ;
+ keys = keycombo, { " ", keycombo } ;
+
+@demo demo/index.html
+*/
+
+
+ Polymer({
+ is: 'iron-a11y-keys',
+
+ behaviors: [
+ Polymer.IronA11yKeysBehavior
+ ],
+
+ properties: {
+ /** @type {?Node} */
+ target: {
+ type: Object,
+ observer: '_targetChanged'
+ },
+
+ keys: {
+ type: String,
+ reflectToAttribute: true,
+ observer: '_keysChanged'
+ }
+ },
+
+ attached: function() {
+ if (!this.target) {
+ this.target = this.parentNode;
+ }
+ },
+
+ _targetChanged: function(target) {
+ this.keyEventTarget = target;
+ },
+
+ _keysChanged: function() {
+ this.removeOwnKeyBindings();
+ this.addOwnKeyBinding(this.keys, '_fireKeysPressed');
+ },
+
+ _fireKeysPressed: function(event) {
+ this.fire('keys-pressed', event.detail, {});
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys/test/basic-test.html b/polymer_1.0.4/bower_components/iron-a11y-keys/test/basic-test.html
new file mode 100644
index 0000000..8483da7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys/test/basic-test.html
@@ -0,0 +1,122 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>iron-a11y-keys</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+
+ <link rel="import" href="../../iron-test-helpers/iron-test-helpers.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-a11y-keys.html">
+</head>
+<body>
+
+ <test-fixture id="BasicKeys">
+ <template>
+ <iron-a11y-keys></iron-a11y-keys>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('<iron-a11y-keys>', function() {
+ var keys;
+
+ setup(function() {
+ keys = fixture('BasicKeys');
+ });
+
+ test('target is parentNode by default', function() {
+ expect(keys.target).to.be.equal(keys.parentNode);
+ });
+
+ suite('keys attribute', function() {
+ test('causes an event listener to be added', function(done) {
+ keys.keys = 'space';
+
+ keys.addEventListener('keys-pressed', function() {
+ done();
+ });
+
+ Polymer.Base.async(function() {
+ MockInteractions.pressSpace(keys.parentNode);
+ });
+ });
+
+ test('will not trigger events for non-specified keys', function() {
+ var keysPressedCount = 0;
+
+ keys.keys = 'space';
+
+ keys.addEventListener('keys-pressed', function() {
+ keysPressedCount++;
+ });
+
+ MockInteractions.pressSpace(keys.parentNode);
+ MockInteractions.pressEnter(keys.parentNode);
+
+ expect(keysPressedCount).to.be.equal(1);
+ });
+
+ test('triggers events for space separated keys', function() {
+ var keysPressed = '';
+
+ keys.keys = 'a b c';
+
+ keys.addEventListener('keys-pressed', function(event) {
+ keysPressed += event.detail.key;
+ });
+
+ MockInteractions.pressAndReleaseKeyOn(keys.parentNode, 65);
+ MockInteractions.pressAndReleaseKeyOn(keys.parentNode, 66);
+ MockInteractions.pressAndReleaseKeyOn(keys.parentNode, 67);
+
+ expect(keysPressed).to.be.equal('abc');
+ });
+ });
+
+ suite('event listeners', function() {
+ test('listeners are only active when element is in document', function() {
+ var keysPressedCount = 0;
+ var parent = keys.parentNode;
+
+ keys.keys = 'space';
+
+ keys.addEventListener('keys-pressed', function(event) {
+ keysPressedCount++;
+ });
+
+ MockInteractions.pressSpace(parent);
+ expect(keysPressedCount).to.be.equal(1);
+
+ keys.parentNode.removeChild(keys);
+ TestHelpers.flushAsynchronousOperations();
+
+ MockInteractions.pressSpace(parent);
+ expect(keysPressedCount).to.be.equal(1);
+
+ parent.appendChild(keys);
+ TestHelpers.flushAsynchronousOperations();
+
+ MockInteractions.pressSpace(parent);
+ expect(keysPressedCount).to.be.equal(2);
+ });
+ });
+ });
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-a11y-keys/test/index.html b/polymer_1.0.4/bower_components/iron-a11y-keys/test/index.html
new file mode 100755
index 0000000..8f1d338
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-a11y-keys/test/index.html
@@ -0,0 +1,29 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!doctype html>
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>Tests</title>
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ </head>
+
+ <body>
+ <script>
+ // Load and run all tests (.html, .js) as one suite:
+ WCT.loadSuites([
+ 'basic-test.html',
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-ajax/.bower.json b/polymer_1.0.4/bower_components/iron-ajax/.bower.json
new file mode 100644
index 0000000..1f79f74
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-ajax/.bower.json
@@ -0,0 +1,47 @@
+{
+ "name": "iron-ajax",
+ "version": "1.0.0",
+ "description": "Makes it easy to make ajax calls and parse the response",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer"
+ ],
+ "main": [
+ "iron-ajax.html",
+ "iron-request.html"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-ajax.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-ajax",
+ "ignore": [],
+ "dependencies": {
+ "promise-polyfill": "polymerlabs/promise-polyfill#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "iron-image": "polymerelements/iron-image#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.0",
+ "commit": "97cc0c5e407ccde33f385ffbf9e6b6c706e63977"
+ },
+ "_source": "git://github.com/PolymerElements/iron-ajax.git",
+ "_target": "1.0.0",
+ "_originalSource": "PolymerElements/iron-ajax"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-ajax/.gitignore b/polymer_1.0.4/bower_components/iron-ajax/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-ajax/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-ajax/README.md b/polymer_1.0.4/bower_components/iron-ajax/README.md
new file mode 100644
index 0000000..6d9f223
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-ajax/README.md
@@ -0,0 +1,23 @@
+iron-ajax
+=========
+
+The `iron-ajax` element exposes network request functionality.
+
+```html
+<iron-ajax
+ auto
+ url="http://gdata.youtube.com/feeds/api/videos/"
+ params='{"alt":"json", "q":"chrome"}'
+ handle-as="json"
+ on-response="handleResponse"></iron-ajax>
+```
+
+With `auto` set to `true`, the element performs a request whenever
+its `url`, `params` or `body` properties are changed. Automatically generated
+requests will be debounced in the case that multiple attributes are changed
+sequentially.
+
+Note: The `params` attribute must be double quoted JSON.
+
+You can trigger a request explicitly by calling `generateRequest` on the
+element.
diff --git a/polymer_1.0.4/bower_components/iron-ajax/bower.json b/polymer_1.0.4/bower_components/iron-ajax/bower.json
new file mode 100644
index 0000000..33b3614
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-ajax/bower.json
@@ -0,0 +1,38 @@
+{
+ "name": "iron-ajax",
+ "version": "1.0.0",
+ "description": "Makes it easy to make ajax calls and parse the response",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer"
+ ],
+ "main": [
+ "iron-ajax.html",
+ "iron-request.html"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-ajax.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-ajax",
+ "ignore": [],
+ "dependencies": {
+ "promise-polyfill": "polymerlabs/promise-polyfill#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "iron-image": "polymerelements/iron-image#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-ajax/demo/index.html b/polymer_1.0.4/bower_components/iron-ajax/demo/index.html
new file mode 100644
index 0000000..8d58583
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-ajax/demo/index.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>iron-ajax</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-ajax.html">
+ <link rel="import" href="../../iron-image/iron-image.html">
+ <link rel="import" href="../../paper-styles/classes/typography.html">
+ <link rel="import" href="../../iron-flex-layout/classes/iron-flex-layout.html">
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+ <style>
+ iron-image {
+ background-color: lightgray;
+ margin: 1em;
+ }
+ </style>
+</head>
+<body>
+
+ <template is="dom-bind">
+ <iron-ajax auto url="//gdata.youtube.com/feeds/api/videos/"
+ params='{"alt":"json", "q":"polymer"}'
+ handle-as="json" last-response="{{ajaxResponse}}"></iron-ajax>
+ <h1>Video Feed</h1>
+ <section class="flex layout horizontal wrap">
+ <template is="dom-repeat" items="[[ajaxResponse.feed.entry]]">
+ <a href="[[item.link.0.href]]" target="_blank">
+ <iron-image src="[[item.media$group.media$thumbnail.0.url]]" width="256" height="256" sizing="cover" preload fade></iron-image>
+ </a>
+ </template>
+ </section>
+ </template>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-ajax/index.html b/polymer_1.0.4/bower_components/iron-ajax/index.html
new file mode 100644
index 0000000..0341b16
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-ajax/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <title>iron-ajax</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-ajax/iron-ajax.html b/polymer_1.0.4/bower_components/iron-ajax/iron-ajax.html
new file mode 100644
index 0000000..47d202b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-ajax/iron-ajax.html
@@ -0,0 +1,398 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="iron-request.html">
+
+<!--
+The `iron-ajax` element exposes network request functionality.
+
+ <iron-ajax
+ auto
+ url="http://gdata.youtube.com/feeds/api/videos/"
+ params='{"alt":"json", "q":"chrome"}'
+ handle-as="json"
+ on-response="handleResponse"
+ debounce-duration="300"></iron-ajax>
+
+With `auto` set to `true`, the element performs a request whenever
+its `url`, `params` or `body` properties are changed. Automatically generated
+requests will be debounced in the case that multiple attributes are changed
+sequentially.
+
+Note: The `params` attribute must be double quoted JSON.
+
+You can trigger a request explicitly by calling `generateRequest` on the
+element.
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'iron-ajax',
+
+ /**
+ * Fired when a request is sent.
+ *
+ * @event request
+ */
+
+ /**
+ * Fired when a response is received.
+ *
+ * @event response
+ */
+
+ /**
+ * Fired when an error is received.
+ *
+ * @event error
+ */
+
+ properties: {
+ /**
+ * The URL target of the request.
+ */
+ url: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * An object that contains query parameters to be appended to the
+ * specified `url` when generating a request.
+ */
+ params: {
+ type: Object,
+ value: function() {
+ return {};
+ }
+ },
+
+ /**
+ * The HTTP method to use such as 'GET', 'POST', 'PUT', or 'DELETE'.
+ * Default is 'GET'.
+ */
+ method: {
+ type: String,
+ value: 'GET'
+ },
+
+ /**
+ * HTTP request headers to send.
+ *
+ * Example:
+ *
+ * <iron-ajax
+ * auto
+ * url="http://somesite.com"
+ * headers='{"X-Requested-With": "XMLHttpRequest"}'
+ * handle-as="json"
+ * last-response-changed="{{handleResponse}}"></iron-ajax>
+ */
+ headers: {
+ type: Object,
+ value: function() {
+ return {};
+ }
+ },
+
+ /**
+ * Content type to use when sending data. If the contenttype is set
+ * and a `Content-Type` header is specified in the `headers` attribute,
+ * the `headers` attribute value will take precedence.
+ */
+ contentType: {
+ type: String,
+ value: 'application/x-www-form-urlencoded'
+ },
+
+ /**
+ * Optional raw body content to send when method === "POST".
+ *
+ * Example:
+ *
+ * <iron-ajax method="POST" auto url="http://somesite.com"
+ * body='{"foo":1, "bar":2}'>
+ * </iron-ajax>
+ */
+ body: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * Toggle whether XHR is synchronous or asynchronous. Don't change this
+ * to true unless You Know What You Are Doing™.
+ */
+ sync: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Specifies what data to store in the `response` property, and
+ * to deliver as `event.response` in `response` events.
+ *
+ * One of:
+ *
+ * `text`: uses `XHR.responseText`.
+ *
+ * `xml`: uses `XHR.responseXML`.
+ *
+ * `json`: uses `XHR.responseText` parsed as JSON.
+ *
+ * `arraybuffer`: uses `XHR.response`.
+ *
+ * `blob`: uses `XHR.response`.
+ *
+ * `document`: uses `XHR.response`.
+ */
+ handleAs: {
+ type: String,
+ value: 'json'
+ },
+
+ /**
+ * Set the withCredentials flag on the request.
+ */
+ withCredentials: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, automatically performs an Ajax request when either `url` or
+ * `params` changes.
+ */
+ auto: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, error messages will automatically be logged to the console.
+ */
+ verbose: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Will be set to true if there is at least one in-flight request
+ * associated with this iron-ajax element.
+ */
+ loading: {
+ type: Boolean,
+ notify: true,
+ readOnly: true
+ },
+
+ /**
+ * Will be set to the most recent request made by this iron-ajax element.
+ */
+ lastRequest: {
+ type: Object,
+ notify: true,
+ readOnly: true
+ },
+
+ /**
+ * Will be set to the most recent response received by a request
+ * that originated from this iron-ajax element. The type of the response
+ * is determined by the value of `handleas` at the time that the request
+ * was generated.
+ */
+ lastResponse: {
+ type: Object,
+ notify: true,
+ readOnly: true
+ },
+
+ /**
+ * Will be set to the most recent error that resulted from a request
+ * that originated from this iron-ajax element.
+ */
+ lastError: {
+ type: Object,
+ notify: true,
+ readOnly: true
+ },
+
+ /**
+ * An Array of all in-flight requests originating from this iron-ajax
+ * element.
+ */
+ activeRequests: {
+ type: Array,
+ notify: true,
+ readOnly: true,
+ value: function() {
+ this._setActiveRequests([]);
+ }
+ },
+
+ /**
+ * Length of time in milliseconds to debounce multiple requests.
+ */
+ debounceDuration: {
+ type: Number,
+ value: 0,
+ notify: true
+ },
+
+ _boundHandleResponse: {
+ type: Function,
+ value: function() {
+ return this.handleResponse.bind(this);
+ }
+ },
+
+ _boundDiscardRequest: {
+ type: Function,
+ value: function() {
+ return this.discardRequest.bind(this);
+ }
+ }
+ },
+
+ observers: [
+ 'requestOptionsChanged(url, method, params, headers,' +
+ 'contentType, body, sync, handleAs, withCredentials, auto)'
+ ],
+
+ get queryString () {
+ var queryParts = [];
+ var param;
+ var value;
+
+ for (param in this.params) {
+ value = this.params[param];
+ param = window.encodeURIComponent(param);
+
+ if (value !== null) {
+ param += '=' + window.encodeURIComponent(value);
+ }
+
+ queryParts.push(param);
+ }
+
+ return queryParts.join('&');
+ },
+
+ get requestUrl() {
+ var queryString = this.queryString;
+
+ if (queryString) {
+ return this.url + '?' + queryString;
+ }
+
+ return this.url;
+ },
+
+ get requestHeaders() {
+ var headers = {
+ 'content-type': this.contentType
+ };
+ var header;
+
+ if (this.headers instanceof Object) {
+ for (header in this.headers) {
+ headers[header] = this.headers[header].toString();
+ }
+ }
+
+ return headers;
+ },
+
+ toRequestOptions: function() {
+ return {
+ url: this.requestUrl,
+ method: this.method,
+ headers: this.requestHeaders,
+ body: this.body,
+ async: !this.sync,
+ handleAs: this.handleAs,
+ withCredentials: this.withCredentials
+ };
+ },
+
+ requestOptionsChanged: function() {
+ this.debounce('generate-request', function() {
+ if (!this.url && this.url !== '') {
+ return;
+ }
+
+ if (this.auto) {
+ this.generateRequest();
+ }
+ }, this.debounceDuration);
+ },
+
+ /**
+ * Performs an AJAX request to the specified URL.
+ *
+ * @method generateRequest
+ */
+ generateRequest: function() {
+ var request = document.createElement('iron-request');
+ var requestOptions = this.toRequestOptions();
+
+ this.activeRequests.push(request);
+
+ request.completes.then(
+ this._boundHandleResponse
+ ).catch(
+ this.handleError.bind(this, request)
+ ).then(
+ this._boundDiscardRequest
+ );
+
+ request.send(requestOptions);
+
+ this._setLastRequest(request);
+
+ this.fire('request', {
+ request: request,
+ options: requestOptions
+ });
+
+ return request;
+ },
+
+ handleResponse: function(request) {
+ this._setLastResponse(request.response);
+ this.fire('response', request);
+ },
+
+ handleError: function(request, error) {
+ if (this.verbose) {
+ console.error(error);
+ }
+
+ this._setLastError({
+ request: request,
+ error: error
+ });
+ this.fire('error', {
+ request: request,
+ error: error
+ });
+ },
+
+ discardRequest: function(request) {
+ var requestIndex = this.activeRequests.indexOf(request);
+
+ if (requestIndex > 0) {
+ this.activeRequests.splice(requestIndex, 1);
+ }
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-ajax/iron-request.html b/polymer_1.0.4/bower_components/iron-ajax/iron-request.html
new file mode 100644
index 0000000..d1737ca
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-ajax/iron-request.html
@@ -0,0 +1,267 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../promise-polyfill/promise-polyfill-lite.html">
+
+<!--
+@group Iron Elements
+
+iron-request can be used to perform XMLHttpRequests.
+
+ <iron-request id="xhr"></iron-request>
+ ...
+ this.$.xhr.send({url: url, params: params});
+
+@element iron-request
+-->
+
+<script>
+ Polymer({
+ is: 'iron-request',
+
+ properties: {
+
+ /**
+ * A reference to the XMLHttpRequest instance used to generate the
+ * network request.
+ *
+ * @attribute xhr
+ * @type XMLHttpRequest
+ * @default `new XMLHttpRequest`
+ */
+ xhr: {
+ type: Object,
+ notify: true,
+ readOnly: true,
+ value: function() {
+ return new XMLHttpRequest();
+ }
+ },
+
+ /**
+ * A reference to the parsed response body, if the `xhr` has completely
+ * resolved.
+ *
+ * @attribute response
+ * @type Object
+ * @default null
+ */
+ response: {
+ type: Object,
+ notify: true,
+ readOnly: true,
+ value: function() {
+ return null;
+ }
+ },
+
+ /**
+ * A promise that resolves when the `xhr` response comes back, or rejects
+ * if there is an error before the `xhr` completes.
+ *
+ * @attribute completes
+ * @type Promise
+ * @default `new Promise`
+ */
+ completes: {
+ type: Object,
+ readOnly: true,
+ notify: true,
+ value: function() {
+ return new Promise(function (resolve, reject) {
+ this.resolveCompletes = resolve;
+ this.rejectCompletes = reject;
+ }.bind(this));
+ }
+ },
+
+ /**
+ * An object that contains progress information emitted by the XHR if
+ * available.
+ *
+ * @attribute progress
+ * @type Object
+ * @default {}
+ */
+ progress: {
+ type: Object,
+ notify: true,
+ readOnly: true,
+ value: function() {
+ return {};
+ }
+ },
+
+ /**
+ * Aborted will be true if an abort of the request is attempted.
+ *
+ * @attribute aborted
+ * @type boolean
+ * @default false
+ */
+ aborted: {
+ type: Boolean,
+ notify: true,
+ readOnly: true,
+ value: false,
+ }
+ },
+
+ /**
+ * Succeeded is true if the request succeeded. The request succeeded if the
+ * status code is greater-than-or-equal-to 200, and less-than 300. Also,
+ * the status code 0 is accepted as a success even though the outcome may
+ * be ambiguous.
+ *
+ * @return boolean
+ */
+ get succeeded() {
+ var status = this.xhr.status || 0;
+
+ // Note: if we are using the file:// protocol, the status code will be 0
+ // for all outcomes (successful or otherwise).
+ return status === 0 ||
+ (status >= 200 && status < 300);
+ },
+
+ /**
+ * Sends an HTTP request to the server and returns the XHR object.
+ *
+ * @method request
+ * @param {{
+ * url: string,
+ * method: (string|undefined),
+ * async: (boolean|undefined),
+ * body: (ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string|undefined),
+ * headers: (Object|undefined),
+ * handleAs: (string|undefined),
+ * withCredentials: (boolean|undefined)}} options -
+ * url The url to which the request is sent.
+ * method The HTTP method to use, default is GET.
+ * async By default, all requests are sent asynchronously. To send synchronous requests,
+ * set to true.
+ * body The content for the request body for POST method.
+ * headers HTTP request headers.
+ * handleAs The response type. Default is 'text'.
+ * withCredentials Whether or not to send credentials on the request. Default is false.
+ * @return Promise
+ */
+ send: function (options) {
+ var xhr = this.xhr;
+
+ if (xhr.readyState > 0) {
+ return;
+ }
+
+ xhr.addEventListener('readystatechange', function () {
+ if (xhr.readyState === 4 && !this.aborted) {
+
+ if (!this.succeeded) {
+ this.rejectCompletes(new Error('The request failed with status code: ' + this.xhr.status));
+ return;
+ }
+
+ this._setResponse(this.parseResponse());
+ this.resolveCompletes(this);
+ }
+ }.bind(this));
+
+ xhr.addEventListener('progress', function (progress) {
+ this._setProgress({
+ lengthComputable: progress.lengthComputable,
+ loaded: progress.loaded,
+ total: progress.total
+ });
+ }.bind(this))
+
+ xhr.addEventListener('error', function (error) {
+ this.rejectCompletes(error);
+ }.bind(this));
+
+ xhr.addEventListener('abort', function () {
+ this.rejectCompletes(new Error('Request aborted.'));
+ }.bind(this));
+
+ xhr.open(
+ options.method || 'GET',
+ options.url,
+ options.async !== false
+ );
+
+ if (options.headers) {
+ Object.keys(options.headers).forEach(function (requestHeader) {
+ xhr.setRequestHeader(
+ requestHeader,
+ options.headers[requestHeader]
+ );
+ }, this);
+ }
+
+ // In IE, `xhr.responseType` is an empty string when the response
+ // returns. Hence, caching it as `xhr._responseType`.
+ xhr.responseType = xhr._responseType = (options.handleAs || 'text');
+ xhr.withCredentials = !!options.withCredentials;
+
+ xhr.send(options.body);
+
+ return this.completes;
+ },
+
+ parseResponse: function () {
+ var xhr = this.xhr;
+ var responseType = this.xhr.responseType ||
+ this.xhr._responseType;
+ // If we don't have a natural `xhr.responseType`, we prefer parsing
+ // `xhr.responseText` over returning `xhr.response`..
+ var preferResponseText = !this.xhr.responseType;
+
+ try {
+ switch (responseType) {
+ case 'json':
+ // If xhr.response is undefined, responseType `json` may
+ // not be supported.
+ if (preferResponseText || xhr.response === undefined) {
+ // If accessing `xhr.responseText` throws, responseType `json`
+ // is supported and the result is rightly `undefined`.
+ try {
+ xhr.responseText;
+ } catch (e) {
+ return xhr.response;
+ }
+
+ // Otherwise, attempt to parse `xhr.responseText` as JSON.
+ if (xhr.responseText) {
+ return JSON.parse(xhr.responseText);
+ }
+ }
+
+ return xhr.response;
+ case 'xml':
+ return xhr.responseXML;
+ case 'blob':
+ case 'document':
+ case 'arraybuffer':
+ return xhr.response;
+ case 'text':
+ default:
+ return xhr.responseText;
+ }
+ } catch (e) {
+ this.rejectCompletes(new Error('Could not parse response. ' + e.message));
+ }
+ },
+
+ abort: function () {
+ this._setAborted(true);
+ this.xhr.abort();
+ }
+ });
+</script>
+
diff --git a/polymer_1.0.4/bower_components/iron-ajax/test/index.html b/polymer_1.0.4/bower_components/iron-ajax/test/index.html
new file mode 100644
index 0000000..ea01e4c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-ajax/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ </head>
+ <body>
+ <script>
+ WCT.loadSuites([
+ 'iron-request.html',
+ 'iron-ajax.html'
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-ajax/test/iron-ajax.html b/polymer_1.0.4/bower_components/iron-ajax/test/iron-ajax.html
new file mode 100644
index 0000000..3fb0077
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-ajax/test/iron-ajax.html
@@ -0,0 +1,433 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>iron-ajax</title>
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-ajax.html">
+</head>
+<body>
+ <test-fixture id="TrivialGet">
+ <template>
+ <iron-ajax url="/responds_to_get_with_json"></iron-ajax>
+ </template>
+ </test-fixture>
+ <test-fixture id="ParamsGet">
+ <template>
+ <iron-ajax url="/responds_to_get_with_json"
+ params='{"a": "a"}'></iron-ajax>
+ </template>
+ </test-fixture>
+ <test-fixture id="AutoGet">
+ <template>
+ <iron-ajax auto url="/responds_to_get_with_json"></iron-ajax>
+ </template>
+ </test-fixture>
+ <test-fixture id="TrivialPost">
+ <template>
+ <iron-ajax method="POST"
+ url="/responds_to_post_with_json"></iron-ajax>
+ </template>
+ </test-fixture>
+ <test-fixture id="DebouncedGet">
+ <template>
+ <iron-ajax auto
+ url="/responds_to_debounced_get_with_json"
+ debounce-duration="150"></iron-ajax>
+ </template>
+ </test-fixture>
+ <script>
+ suite('<iron-ajax>', function () {
+ var responseHeaders = {
+ json: { 'Content-Type': 'application/json' },
+ plain: { 'Content-Type': 'text/plain' }
+ };
+ var ajax;
+ var request;
+ var server;
+
+ setup(function() {
+ server = sinon.fakeServer.create();
+ server.respondWith(
+ 'GET',
+ /\/responds_to_get_with_json.*/,
+ [
+ 200,
+ responseHeaders.json,
+ '{"success":true}'
+ ]
+ );
+
+ server.respondWith(
+ 'POST',
+ '/responds_to_post_with_json',
+ [
+ 200,
+ responseHeaders.json,
+ '{"post_success":true}'
+ ]
+ );
+
+ server.respondWith(
+ 'GET',
+ '/responds_to_get_with_text',
+ [
+ 200,
+ responseHeaders.plain,
+ 'Hello World'
+ ]
+ );
+
+ server.respondWith(
+ 'GET',
+ '/responds_to_debounced_get_with_json',
+ [
+ 200,
+ responseHeaders.json,
+ '{"success": "true"}'
+ ]
+ );
+
+ ajax = fixture('TrivialGet');
+ });
+
+ teardown(function() {
+ server.restore();
+ });
+
+ suite('when making simple GET requests for JSON', function() {
+ test('has sane defaults that love you', function() {
+ request = ajax.generateRequest();
+
+ server.respond();
+
+ expect(request.response).to.be.ok;
+ expect(request.response).to.be.an('object');
+ expect(request.response.success).to.be.equal(true);
+ });
+
+ test('will be asynchronous by default', function() {
+ expect(ajax.toRequestOptions().async).to.be.eql(true);
+ });
+ });
+
+ suite('when setting custom headers', function() {
+ test('are present in the request headers', function() {
+ ajax.headers['custom-header'] = 'valid';
+ var options = ajax.toRequestOptions();
+
+ expect(options.headers).to.be.ok;
+ expect(options.headers['custom-header']).to.be.an('string');
+ expect(options.headers.hasOwnProperty('custom-header')).to.be.equal(true);
+ });
+
+ test('non-objects in headers are not applied', function() {
+ ajax.headers = 'invalid';
+ var options = ajax.toRequestOptions();
+
+ expect(Object.keys(options.headers).length).to.be.equal(1);
+ });
+ });
+
+ suite('when properties are changed', function() {
+ test('generates simple-request elements that reflect the change', function() {
+ request = ajax.generateRequest();
+
+ expect(request.xhr.method).to.be.equal('GET');
+
+ ajax.method = 'POST';
+ ajax.url = '/responds_to_post_with_json';
+
+ request = ajax.generateRequest();
+
+ expect(request.xhr.method).to.be.equal('POST');
+ });
+ });
+
+ suite('when generating a request', function() {
+ test('yields a iron-request instance', function() {
+ var IronRequest = document.createElement('iron-request').constructor;
+
+ expect(ajax.generateRequest()).to.be.instanceOf(IronRequest);
+ });
+ });
+
+ suite('when there are multiple requests', function() {
+ var requests;
+
+ setup(function() {
+ requests = [];
+
+ for (var i = 0; i < 3; ++i) {
+ requests.push(ajax.generateRequest());
+ }
+ });
+
+ test('holds all requests in the `activeRequests` Array', function() {
+ expect(requests).to.deep.eql(ajax.activeRequests);
+ });
+ });
+
+ suite('when params are changed', function() {
+ test('generates a request that reflects the change', function() {
+ ajax = fixture('ParamsGet');
+ request = ajax.generateRequest();
+
+ expect(request.xhr.url).to.be.equal('/responds_to_get_with_json?a=a');
+
+ ajax.params = {b: 'b'};
+ request = ajax.generateRequest();
+
+ expect(request.xhr.url).to.be.equal('/responds_to_get_with_json?b=b');
+ });
+ });
+
+ suite('when `auto` is enabled', function() {
+ setup(function() {
+ ajax = fixture('AutoGet');
+ });
+
+ test('automatically generates new requests', function(done) {
+ ajax.addEventListener('request', function() {
+ done();
+ });
+ });
+
+ test('does not send requests if url is not a string', function(done) {
+ ajax.addEventListener('request', function() {
+ done(new Error('A request was generated but url is null!'));
+ });
+
+ ajax.url = null;
+ ajax.handleAs = 'text';
+
+ Polymer.Base.async(function() {
+ done();
+ }, 1);
+ });
+
+ test('deduplicates multiple changes to a single request', function(done) {
+ ajax.addEventListener('request', function() {
+ server.respond();
+ });
+
+ ajax.addEventListener('response', function() {
+ try {
+ expect(ajax.activeRequests.length).to.be.eql(1);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ });
+
+ ajax.handleas = 'text';
+ ajax.params = { foo: 'bar' };
+ ajax.headers = { 'X-Foo': 'Bar' };
+ });
+ });
+
+ suite('the last response', function() {
+ setup(function() {
+ request = ajax.generateRequest();
+ server.respond();
+ });
+
+ test('is accessible as a readonly property', function(done) {
+ request.completes.then(function (request) {
+ expect(ajax.lastResponse).to.be.equal(request.response);
+ done();
+ }).catch(done);
+ });
+
+
+ test('updates with each new response', function(done) {
+ request.completes.then(function(request) {
+
+ expect(request.response).to.be.an('object');
+ expect(ajax.lastResponse).to.be.equal(request.response);
+
+ ajax.handleAs = 'text';
+ request = ajax.generateRequest();
+ server.respond();
+
+ return request.completes;
+
+ }).then(function(request) {
+
+ expect(request.response).to.be.a('string');
+ expect(ajax.lastResponse).to.be.equal(request.response);
+
+ done();
+
+ }).catch(done);
+ });
+ });
+
+ suite('when making POST requests', function() {
+ setup(function() {
+ ajax = fixture('TrivialPost');
+ });
+
+ test('POSTs the value of the `body` attribute', function() {
+ var requestBody = JSON.stringify({foo: 'bar'});
+
+ ajax.body = requestBody;
+ ajax.generateRequest();
+
+ expect(server.requests[0]).to.be.ok;
+ expect(server.requests[0].requestBody).to.be.equal(requestBody);
+ });
+ });
+
+ suite('when debouncing requests', function() {
+ setup(function() {
+ ajax = fixture('DebouncedGet');
+ });
+
+ test('only requests a single resource', function(done) {
+ ajax.requestOptionsChanged();
+ expect(server.requests[0]).to.be.equal(undefined);
+ ajax.requestOptionsChanged();
+ window.setTimeout(function() {
+ expect(server.requests[0]).to.be.ok;
+ done();
+ }, 200);
+ });
+ });
+
+ suite('when a response handler is bound', function() {
+ var responseHandler;
+
+ setup(function() {
+ responseHandler = sinon.spy();
+ ajax.addEventListener('response', responseHandler);
+ });
+
+ test('calls the handler after every response', function(done) {
+ ajax.generateRequest();
+ ajax.generateRequest();
+
+ server.respond();
+
+ ajax.lastRequest.completes.then(function() {
+ expect(responseHandler.callCount).to.be.equal(2);
+ done();
+ }).catch(done);
+ });
+ });
+
+ suite('when the response type is `json`', function() {
+ setup(function() {
+ server.restore();
+ });
+
+ test('finds the JSON on any platform', function(done) {
+ ajax.url = '../bower.json';
+ request = ajax.generateRequest();
+ request.completes.then(function() {
+ expect(ajax.lastResponse).to.be.instanceOf(Object);
+ done();
+ }).catch(function(e) {
+ done(e);
+ });
+ });
+ });
+
+ suite('when handleAs parameter is `text`', function() {
+
+ test('response type is string', function (done) {
+
+ ajax.url = '/responds_to_get_with_json';
+ ajax.handleAs = 'text';
+
+ request = ajax.generateRequest();
+ request.completes.then(function () {
+ expect(typeof(ajax.lastResponse)).to.be.equal('string');
+ done();
+ }).catch(function (e) {
+ done(e);
+ });
+
+ server.respond();
+
+ });
+
+ });
+
+ suite('when a request fails', function() {
+ test('the error event has useful details', function(done) {
+
+ ajax.url = '/responds_to_get_with_text';
+ ajax.handleAs = 'json';
+ ajax.generateRequest();
+
+ ajax.addEventListener('error', function(event) {
+ try {
+ expect(event.detail.request).to.be.okay;
+ expect(event.detail.error).to.be.okay;
+ done();
+ } catch (e) {
+ done(e);
+ }
+ });
+
+ server.respond();
+ });
+ });
+
+ suite('when handleAs parameter is `json`', function() {
+
+ test('response type is string', function (done) {
+
+ ajax.url = '/responds_to_get_with_json';
+ ajax.handleAs = 'json';
+
+ request = ajax.generateRequest();
+ request.completes.then(function () {
+ expect(typeof(ajax.lastResponse)).to.be.equal('object');
+ done();
+ }).catch(function (e) {
+ done(e);
+ });
+
+ server.respond();
+
+ });
+
+ test('fails when getting invalid json data', function (done) {
+
+ ajax.url = '/responds_to_get_with_text';
+ ajax.handleAs = 'json';
+
+ request = ajax.generateRequest();
+ request.completes.catch(function (e) {
+ expect(e).to.be.instanceOf(Error);
+ done();
+ }).catch(function (e) {
+ done(e);
+ });
+
+ server.respond();
+
+ });
+
+ });
+
+ });
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-ajax/test/iron-request.html b/polymer_1.0.4/bower_components/iron-ajax/test/iron-request.html
new file mode 100644
index 0000000..8990fac
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-ajax/test/iron-request.html
@@ -0,0 +1,175 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>iron-request</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-request.html">
+</head>
+<body>
+ <test-fixture id="TrivialRequest">
+ <template>
+ <iron-request></iron-request>
+ </template>
+ </test-fixture>
+ <script>
+ suite('<iron-request>', function () {
+ var jsonResponseHeaders;
+ var successfulRequestOptions;
+ var request;
+ var server;
+
+ setup(function () {
+ jsonResponseHeaders = {
+ 'Content-Type': 'application/json'
+ };
+ server = sinon.fakeServer.create();
+ server.respondWith('GET', '/responds_to_get_with_json', [
+ 200,
+ jsonResponseHeaders,
+ '{"success":true}'
+ ]);
+
+ server.respondWith('GET', '/responds_to_get_with_500', [
+ 500,
+ {},
+ ''
+ ]);
+
+ server.respondWith('GET', '/responds_to_get_with_100', [
+ 100,
+ {},
+ ''
+ ]);
+
+ server.respondWith('GET', '/responds_to_get_with_0', [
+ 0,
+ jsonResponseHeaders,
+ '{"success":true}'
+ ]);
+
+
+ request = fixture('TrivialRequest');
+ successfulRequestOptions = {
+ url: '/responds_to_get_with_json'
+ };
+ });
+
+ teardown(function () {
+ server.restore();
+ });
+
+ suite('basic usage', function () {
+ test('creates network requests, requiring only `url`', function () {
+ request.send(successfulRequestOptions);
+
+ server.respond();
+
+ expect(request.response).to.be.ok;
+ });
+
+ test('sets async to true by default', function () {
+ request.send(successfulRequestOptions);
+ expect(request.xhr.async).to.be.eql(true);
+ });
+
+ test('can be aborted', function (done) {
+ request.send(successfulRequestOptions);
+
+ request.abort();
+
+ server.respond();
+
+ request.completes.then(function () {
+ done(new Error('Request did not abort appropriately!'));
+ }).catch(function (e) {
+ expect(request.response).to.not.be.ok;
+ done();
+ });
+ });
+
+ test('default responseType is text', function (done) {
+
+ request.send(successfulRequestOptions);
+ server.respond();
+
+ request.completes.then(function() {
+ expect(request.response).to.be.an('string')
+ done();
+ }).catch(function(e) {
+ done(new Error('Response was not a Object'));
+ });
+
+ });
+
+ test('responseType can be configured via handleAs option', function (done) {
+
+ var options = Object.create(successfulRequestOptions);
+ options.handleAs = 'json';
+
+ request.send(options);
+ server.respond();
+
+ request.completes.then(function() {
+ expect(request.response).to.be.an('object');
+ done();
+ }).catch(function(e) {
+ done(new Error('Response was not type Object'));
+ });
+
+ });
+
+ });
+
+ suite('special cases', function() {
+ test('treats status code 0 as success, though the outcome is ambiguous', function() {
+ // Note: file:// status code will probably be 0 no matter what happened.
+ request.send({
+ url: '/responds_to_get_with_0'
+ });
+
+ server.respond();
+
+ expect(request.succeeded).to.be.equal(true);
+ });
+ });
+
+ suite('errors', function() {
+ test('treats status codes between 1 and 199 as errors', function() {
+ request.send({
+ url: '/responds_to_get_with_100'
+ });
+
+ server.respond();
+
+ expect(request.succeeded).to.be.equal(false);
+ });
+
+ test('treats status codes between 300 and ∞ as errors', function() {
+ request.send({
+ url: '/responds_to_get_with_500'
+ });
+
+ server.respond();
+
+ expect(request.succeeded).to.be.equal(false);
+ });
+ });
+ });
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-autogrow-textarea/.bower.json b/polymer_1.0.4/bower_components/iron-autogrow-textarea/.bower.json
new file mode 100644
index 0000000..3ecd6f0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-autogrow-textarea/.bower.json
@@ -0,0 +1,48 @@
+{
+ "name": "iron-autogrow-textarea",
+ "version": "1.0.2",
+ "description": "A textarea element that automatically grows with input",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "input",
+ "textarea"
+ ],
+ "main": [
+ "iron-autogrow-textarea.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-autogrow-textarea.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-autogrow-textarea",
+ "ignore": [],
+ "dependencies": {
+ "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "iron-validatable-behavior": "PolymerElements/iron-validatable-behavior#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "1697690de3010aa7b4d3557e7f3fa582e82dee6a"
+ },
+ "_source": "git://github.com/PolymerElements/iron-autogrow-textarea.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-autogrow-textarea"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-autogrow-textarea/.gitignore b/polymer_1.0.4/bower_components/iron-autogrow-textarea/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-autogrow-textarea/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-autogrow-textarea/README.md b/polymer_1.0.4/bower_components/iron-autogrow-textarea/README.md
new file mode 100644
index 0000000..7242abc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-autogrow-textarea/README.md
@@ -0,0 +1,24 @@
+# iron-autogrow-textarea
+
+`iron-autogrow-textarea` is an element containing a textarea that grows in height as more
+lines of input are entered. Unless an explicit height or the `maxRows` property is set, it will
+never scroll.
+
+Example:
+
+ <iron-autogrow-textarea id="a1">
+ <textarea id="t1"></textarea>
+ </iron-autogrow-textarea>
+
+Because the `textarea`'s `value` property is not observable, you should use
+this element's `bind-value` instead for imperative updates. Alternatively, if
+you do set the `textarea`'s `value` imperatively, you must also call `update`
+to notify this element the value has changed.
+
+ Example:
+ /* preferred, using the example HTML above*/
+ a1.bindValue = 'some\ntext';
+
+ /* alternatively, */
+ t1.value = 'some\ntext';
+ a1.update();
diff --git a/polymer_1.0.4/bower_components/iron-autogrow-textarea/bower.json b/polymer_1.0.4/bower_components/iron-autogrow-textarea/bower.json
new file mode 100644
index 0000000..0ff6079
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-autogrow-textarea/bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "iron-autogrow-textarea",
+ "version": "1.0.2",
+ "description": "A textarea element that automatically grows with input",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "input",
+ "textarea"
+ ],
+ "main": [
+ "iron-autogrow-textarea.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-autogrow-textarea.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-autogrow-textarea",
+ "ignore": [],
+ "dependencies": {
+ "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "iron-validatable-behavior": "PolymerElements/iron-validatable-behavior#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-autogrow-textarea/demo/index.html b/polymer_1.0.4/bower_components/iron-autogrow-textarea/demo/index.html
new file mode 100644
index 0000000..25a1c25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-autogrow-textarea/demo/index.html
@@ -0,0 +1,81 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>iron-autogrow-textarea demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-autogrow-textarea.html">
+
+ <link rel="stylesheet" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ </head>
+ <style>
+ iron-autogrow-textarea {
+ width: 200px;
+ }
+ </style>
+ <body>
+ <div class="vertical-section-container centered">
+ <h4>Updating the value imperatively</h4>
+ <template is="dom-bind">
+ <div class="vertical-section">
+ <iron-autogrow-textarea bind-value="{{bindValue}}" id="a1"></iron-autogrow-textarea>
+ <br><br>
+
+ <code>bind-value</code>: <span>[[bindValue]]</span>
+
+ <p on-click="setValue">
+ set <code>bind-value</code> to: <br>
+ <textarea></textarea>
+ <button value="bindValue">set</button>
+ <br><br>
+
+ set <code>textarea.value</code> to: <br>
+ <textarea></textarea>
+ <button value="value">set</button>
+ </p>
+ </div>
+ </template>
+
+ <h4>Custom</h4>
+ <div class="vertical-section">
+ <p>Scrolls after 4 rows:</p>
+ <iron-autogrow-textarea max-rows="4"></iron-autogrow-textarea>
+ <p>Initial height of 4 rows</p>
+ <iron-autogrow-textarea rows="4"></iron-autogrow-textarea>
+ </div>
+ </div>
+
+ <script>
+ var scope = document.querySelector('template[is=dom-bind]');
+
+ scope.setValue = function(event) {
+ if (!(event.target instanceof HTMLButtonElement)) {
+ return;
+ }
+ var inputValue = event.target.previousElementSibling.value;
+ if (event.target.value == "bindValue") {
+ document.querySelector('iron-autogrow-textarea').bindValue = inputValue;
+ } else {
+ document.querySelector('iron-autogrow-textarea').textarea.value = inputValue;
+ }
+
+ }
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-autogrow-textarea/hero.svg b/polymer_1.0.4/bower_components/iron-autogrow-textarea/hero.svg
new file mode 100755
index 0000000..19ec70a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-autogrow-textarea/hero.svg
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <path d="M140,47c-3,0-4.7-2.4-6.2-4.4c-1.3-1.9-2.4-3.6-4.7-3.6c-2.3,0-3.4,1.7-4.7,3.6c-1.5,2.1-3.1,4.4-6.4,4.4
+ c-3.3,0-4.9-2.4-6.4-4.4c-1.3-1.9-2.5-3.6-4.8-3.6c-2.3,0-3.4,1.7-4.8,3.6c-1.5,2.1-3.1,4.4-6.4,4.4s-5.2-2.4-6.7-4.4
+ c-1.3-1.9-2-3.6-5-3.6v-2c4,0,5.2,2.4,6.7,4.4c1.3,1.9,2.6,3.6,4.9,3.6c2.3,0,3.5-1.7,4.8-3.6c1.5-2.1,3.1-4.4,6.5-4.4
+ s5,2.4,6.4,4.4c1.3,1.9,2.5,3.6,4.8,3.6c2.3,0,3.4-1.7,4.8-3.6c1.5-2.1,3.1-4.4,6.4-4.4c3.3,0,4.7,2.4,6.2,4.4
+ c1.3,1.9,2.5,3.6,4.5,3.6V47z"/>
+ <path d="M140,65c-3,0-4.7-2.4-6.2-4.4c-1.3-1.9-2.4-3.6-4.7-3.6c-2.3,0-3.4,1.7-4.7,3.6c-1.5,2.1-3.1,4.4-6.4,4.4
+ c-3.3,0-4.9-2.4-6.4-4.4c-1.3-1.9-2.5-3.6-4.8-3.6c-2.3,0-3.4,1.7-4.8,3.6c-1.5,2.1-3.1,4.4-6.4,4.4s-5.2-2.4-6.7-4.4
+ c-1.3-1.9-2-3.6-5-3.6v-2c4,0,5.2,2.4,6.7,4.4c1.3,1.9,2.6,3.6,4.9,3.6c2.3,0,3.5-1.7,4.8-3.6c1.5-2.1,3.1-4.4,6.5-4.4
+ s5,2.4,6.4,4.4c1.3,1.9,2.5,3.6,4.8,3.6c2.3,0,3.4-1.7,4.8-3.6c1.5-2.1,3.1-4.4,6.4-4.4c3.3,0,4.7,2.4,6.2,4.4
+ c1.3,1.9,2.5,3.6,4.5,3.6V65z"/>
+ <path d="M140,83c-3,0-4.7-2.4-6.2-4.4c-1.3-1.9-2.4-3.6-4.7-3.6c-2.3,0-3.4,1.7-4.7,3.6c-1.5,2.1-3.1,4.4-6.4,4.4
+ c-3.3,0-4.9-2.4-6.4-4.4c-1.3-1.9-2.5-3.6-4.8-3.6c-2.3,0-3.4,1.7-4.8,3.6c-1.5,2.1-3.1,4.4-6.4,4.4s-5.2-2.4-6.7-4.4
+ c-1.3-1.9-2-3.6-5-3.6v-2c4,0,5.2,2.4,6.7,4.4c1.3,1.9,2.6,3.6,4.9,3.6c2.3,0,3.5-1.7,4.8-3.6c1.5-2.1,3.1-4.4,6.5-4.4
+ s5,2.4,6.4,4.4c1.3,1.9,2.5,3.6,4.8,3.6c2.3,0,3.4-1.7,4.8-3.6c1.5-2.1,3.1-4.4,6.4-4.4c3.3,0,4.7,2.4,6.2,4.4
+ c1.3,1.9,2.5,3.6,4.5,3.6V83z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+ <path d="M151,102H73V24h78V102z M75,100h74V26H75V100z"/>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/iron-autogrow-textarea/index.html b/polymer_1.0.4/bower_components/iron-autogrow-textarea/index.html
new file mode 100644
index 0000000..3be2964
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-autogrow-textarea/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>iron-autogrow-textarea</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+ </head>
+ <body>
+
+ <iron-component-page></iron-component-page>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html b/polymer_1.0.4/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html
new file mode 100644
index 0000000..54decc8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html
@@ -0,0 +1,266 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-behaviors/iron-control-state.html">
+<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="../iron-validatable-behavior/iron-validatable-behavior.html">
+
+<!--
+`iron-autogrow-textarea` is an element containing a textarea that grows in height as more
+lines of input are entered. Unless an explicit height or the `maxRows` property is set, it will
+never scroll.
+
+Example:
+
+ <iron-autogrow-textarea id="a1">
+ <textarea id="t1"></textarea>
+ </iron-autogrow-textarea>
+
+Because the `textarea`'s `value` property is not observable, you should use
+this element's `bind-value` instead for imperative updates.
+
+@group Iron Elements
+@hero hero.svg
+@demo demo/index.html
+-->
+
+<dom-module id="iron-autogrow-textarea">
+
+ <style>
+ :host {
+ display: inline-block;
+ position: relative;
+ width: 400px;
+ border: 1px solid;
+ padding: 2px;
+ -moz-appearance: textarea;
+ -webkit-appearance: textarea;
+ }
+
+ .mirror-text {
+ visibility: hidden;
+ word-wrap: break-word;
+ }
+
+ textarea {
+ position: relative;
+ outline: none;
+ border: none;
+ resize: none;
+ background: inherit;
+ /* see comments in template */
+ width: 100%;
+ height: 100%;
+ font-size: inherit;
+ font-family: inherit;
+ }
+
+ ::content textarea:invalid {
+ box-shadow: none;
+ }
+
+ </style>
+ <template>
+ <!-- the mirror sizes the input/textarea so it grows with typing -->
+ <div id="mirror" class="mirror-text" aria-hidden="true"> </div>
+
+ <!-- size the input/textarea with a div, because the textarea has intrinsic size in ff -->
+ <div class="textarea-container fit">
+ <textarea id="textarea"
+ autocomplete$="[[autocomplete]]"
+ autofocus$="[[autofocus]]"
+ inputmode$="[[inputmode]]"
+ name$="[[name]]"
+ placeholder$="[[placeholder]]"
+ readonly$="[[readonly]]"
+ required$="[[required]]"
+ rows$="[[rows]]"
+ maxlength$="[[maxlength]]"></textarea>
+ </div>
+ </template>
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'iron-autogrow-textarea',
+
+ behaviors: [
+ Polymer.IronValidatableBehavior,
+ Polymer.IronControlState
+ ],
+
+ properties: {
+
+ /**
+ * Use this property instead of `value` for two-way data binding.
+ */
+ bindValue: {
+ observer: '_bindValueChanged',
+ type: String
+ },
+
+ /**
+ * The initial number of rows.
+ *
+ * @attribute rows
+ * @type number
+ * @default 1
+ */
+ rows: {
+ type: Number,
+ value: 1,
+ observer: '_updateCached'
+ },
+
+ /**
+ * The maximum number of rows this element can grow to until it
+ * scrolls. 0 means no maximum.
+ *
+ * @attribute maxRows
+ * @type number
+ * @default 0
+ */
+ maxRows: {
+ type: Number,
+ value: 0,
+ observer: '_updateCached'
+ },
+
+ /**
+ * Bound to the textarea's `autocomplete` attribute.
+ */
+ autocomplete: {
+ type: String,
+ value: 'off'
+ },
+
+ /**
+ * Bound to the textarea's `autofocus` attribute.
+ */
+ autofocus: {
+ type: String,
+ value: 'off'
+ },
+
+ /**
+ * Bound to the textarea's `inputmode` attribute.
+ */
+ inputmode: {
+ type: String
+ },
+
+ /**
+ * Bound to the textarea's `name` attribute.
+ */
+ name: {
+ type: String
+ },
+
+ /**
+ * Bound to the textarea's `placeholder` attribute.
+ */
+ placeholder: {
+ type: String
+ },
+
+ /**
+ * Bound to the textarea's `readonly` attribute.
+ */
+ readonly: {
+ type: String
+ },
+
+ /**
+ * Set to true to mark the textarea as required.
+ */
+ required: {
+ type: Boolean
+ },
+
+ /**
+ * The maximum length of the input value.
+ */
+ maxlength: {
+ type: Number
+ }
+
+ },
+
+ listeners: {
+ 'input': '_onInput'
+ },
+
+ /**
+ * Returns the underlying textarea.
+ */
+ get textarea() {
+ return this.$.textarea;
+ },
+
+ _update: function() {
+ this.$.mirror.innerHTML = this._valueForMirror();
+
+ var textarea = this.textarea;
+ // If the value of the textarea was updated imperatively, then we
+ // need to manually update bindValue as well.
+ if (textarea && this.bindValue != textarea.value) {
+ this.bindValue = textarea.value;
+ }
+ },
+
+ _bindValueChanged: function() {
+ var textarea = this.textarea;
+ if (!textarea) {
+ return;
+ }
+
+ textarea.value = this.bindValue;
+ this._update();
+ // manually notify because we don't want to notify until after setting value
+ this.fire('bind-value-changed', {value: this.bindValue});
+ },
+
+ _onInput: function(event) {
+ this.bindValue = event.path ? event.path[0].value : event.target.value;
+ this._update();
+ },
+
+ _constrain: function(tokens) {
+ var _tokens;
+ tokens = tokens || [''];
+ // Enforce the min and max heights for a multiline input to avoid measurement
+ if (this.maxRows > 0 && tokens.length > this.maxRows) {
+ _tokens = tokens.slice(0, this.maxRows);
+ } else {
+ _tokens = tokens.slice(0);
+ }
+ while (this.rows > 0 && _tokens.length < this.rows) {
+ _tokens.push('');
+ }
+ return _tokens.join('<br>') + ' ';
+ },
+
+ _valueForMirror: function() {
+ var input = this.textarea;
+ if (!input) {
+ return;
+ }
+ this.tokens = (input && input.value) ? input.value.replace(/&/gm, '&').replace(/"/gm, '"').replace(/'/gm, ''').replace(/</gm, '<').replace(/>/gm, '>').split('\n') : [''];
+ return this._constrain(this.tokens);
+ },
+
+ _updateCached: function() {
+ this.$.mirror.innerHTML = this._constrain(this.tokens);
+ }
+ })
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-autogrow-textarea/test/basic.html b/polymer_1.0.4/bower_components/iron-autogrow-textarea/test/basic.html
new file mode 100644
index 0000000..af736a0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-autogrow-textarea/test/basic.html
@@ -0,0 +1,126 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>iron-autogrow-textarea tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+ <script src="../../iron-test-helpers/mock-interactions.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-autogrow-textarea.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="basic">
+ <template>
+ <iron-autogrow-textarea></iron-autogrow-textarea>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="has-bindValue">
+ <template>
+ <iron-autogrow-textarea bind-value="foobar"></iron-autogrow-textarea>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="rows">
+ <template>
+ <iron-autogrow-textarea rows="3"></iron-autogrow-textarea>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+
+ test('setting bindValue sets textarea value', function() {
+ var autogrow = fixture('basic');
+ var textarea = autogrow.textarea;
+
+ autogrow.bindValue = 'batman';
+ assert.equal(textarea.value, autogrow.bindValue, 'textarea value equals to bindValue');
+ });
+
+ test('can set an initial bindValue', function() {
+ var autogrow = fixture('has-bindValue');
+ assert.equal(autogrow.textarea.value, 'foobar', 'textarea value equals to initial bindValue');
+ });
+
+ test('can set an initial number of rows', function() {
+ var autogrow = fixture("rows");
+ assert.equal(autogrow.textarea.rows, 3, 'textarea has rows=3');
+ });
+
+ test('adding rows grows the textarea', function() {
+ var autogrow = fixture('basic');
+ var initialHeight = autogrow.offsetHeight;
+
+ autogrow.bindValue = 'batman\nand\nrobin';
+ var finalHeight = autogrow.offsetHeight
+ assert.isTrue(finalHeight > initialHeight);
+ });
+
+ test('removing rows shrinks the textarea', function() {
+ var autogrow = fixture('basic');
+ autogrow.bindValue = 'batman\nand\nrobin';
+ var initialHeight = autogrow.offsetHeight;
+
+ autogrow.bindValue = 'batman';
+ var finalHeight = autogrow.offsetHeight
+ assert.isTrue(finalHeight < initialHeight);
+ });
+ });
+
+ suite('focus/blur events', function() {
+ var input;
+
+ setup(function() {
+ input = fixture('basic');
+ });
+
+ test('focus/blur events fired on host element', function(done) {
+ var nFocusEvents = 0;
+ var nBlurEvents = 0;
+ input.addEventListener('focus', function() {
+ nFocusEvents += 1;
+ // setTimeout to wait for potentially more, erroneous events
+ setTimeout(function() {
+ assert.equal(nFocusEvents, 1, 'one focus event fired');
+ MockInteractions.blur(input.textarea);
+ });
+ });
+ input.addEventListener('blur', function() {
+ nBlurEvents += 1;
+ // setTimeout to wait for potentially more, erroneous events
+ setTimeout(function() {
+ assert.equal(nBlurEvents, 1, 'one blur event fired');
+ done();
+ });
+ });
+ MockInteractions.focus(input.textarea);
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-autogrow-textarea/test/index.html b/polymer_1.0.4/bower_components/iron-autogrow-textarea/test/index.html
new file mode 100644
index 0000000..8790abe
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-autogrow-textarea/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>iron-autogrow-textarea tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+ </head>
+ <body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html',
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-behaviors/.bower.json b/polymer_1.0.4/bower_components/iron-behaviors/.bower.json
new file mode 100644
index 0000000..bf8b6cf
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-behaviors/.bower.json
@@ -0,0 +1,40 @@
+{
+ "name": "iron-behaviors",
+ "version": "1.0.4",
+ "description": "Provides a set of behaviors for the iron elements",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-behaviors.git"
+ },
+ "main": [
+ "iron-button-state.html",
+ "iron-control-state.html"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-behaviors",
+ "_release": "1.0.4",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.4",
+ "commit": "8792edd457de697a74f398c09b67df30adf7d866"
+ },
+ "_source": "git://github.com/PolymerElements/iron-behaviors.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-behaviors"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-behaviors/.gitignore b/polymer_1.0.4/bower_components/iron-behaviors/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-behaviors/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-behaviors/README.md b/polymer_1.0.4/bower_components/iron-behaviors/README.md
new file mode 100644
index 0000000..593986e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-behaviors/README.md
@@ -0,0 +1,4 @@
+iron-behaviors
+==============
+
+This repository collects shared behaviors that are mixed in to other elements.
diff --git a/polymer_1.0.4/bower_components/iron-behaviors/bower.json b/polymer_1.0.4/bower_components/iron-behaviors/bower.json
new file mode 100644
index 0000000..6a18575
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-behaviors/bower.json
@@ -0,0 +1,30 @@
+{
+ "name": "iron-behaviors",
+ "version": "1.0.4",
+ "description": "Provides a set of behaviors for the iron elements",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-behaviors.git"
+ },
+ "main": [
+ "iron-button-state.html",
+ "iron-control-state.html"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-behaviors/demo/index.html b/polymer_1.0.4/bower_components/iron-behaviors/demo/index.html
new file mode 100644
index 0000000..4001664
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-behaviors/demo/index.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>simple-button</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link href="../../paper-styles/demo-pages.html" rel="import">
+ <link href="simple-button.html" rel="import">
+
+ <style>
+
+ .vertical-section {
+ text-align: center;
+ }
+
+ </style>
+
+</head>
+<body>
+ <div class="vertical-section vertical-section-container centered">
+ <h3>Normal</h3>
+
+ <simple-button tabindex="0">Hello World</simple-button>
+
+ <h3>Toggles</h3>
+
+ <simple-button toggles tabindex="0">Hello World</simple-button>
+
+ <h3>Disabled</h3>
+
+ <simple-button disabled tabindex="0">Hello World</simple-button>
+ </div>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-behaviors/demo/simple-button.html b/polymer_1.0.4/bower_components/iron-behaviors/demo/simple-button.html
new file mode 100644
index 0000000..ab6432b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-behaviors/demo/simple-button.html
@@ -0,0 +1,70 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../iron-button-state.html">
+<link rel="import" href="../iron-control-state.html">
+
+<dom-module id="simple-button">
+
+ <style>
+
+ :host {
+ display: inline-block;
+ background-color: #4285F4;
+ color: #fff;
+ min-height: 8px;
+ min-width: 8px;
+ padding: 16px;
+ text-transform: uppercase;
+ border-radius: 3px;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -webkit-user-select: none;
+ user-select: none;
+ cursor: pointer;
+ }
+
+ :host([disabled]) {
+ opacity: 0.3;
+ pointer-events: none;
+ }
+
+ :host([active]),
+ :host([pressed]) {
+ background-color: #3367D6;
+ box-shadow: inset 0 3px 5px rgba(0,0,0,.2);
+ }
+
+ </style>
+
+ <template>
+
+ <content></content>
+
+ </template>
+
+ <script>
+
+ Polymer({
+
+ behaviors: [
+ Polymer.IronControlState,
+ Polymer.IronButtonState
+ ],
+
+ hostAttributes: {
+ role: 'button'
+ }
+ });
+
+ </script>
+
+</dom-module>
+
diff --git a/polymer_1.0.4/bower_components/iron-behaviors/index.html b/polymer_1.0.4/bower_components/iron-behaviors/index.html
new file mode 100644
index 0000000..220deb0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-behaviors/index.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>Iron Behaviors</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page src="iron-button-state.html"></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-behaviors/iron-button-state.html b/polymer_1.0.4/bower_components/iron-behaviors/iron-button-state.html
new file mode 100644
index 0000000..fc52e17
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-behaviors/iron-button-state.html
@@ -0,0 +1,186 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
+<link rel="import" href="iron-control-state.html">
+
+<script>
+
+ /**
+ * @demo demo/index.html
+ * @polymerBehavior Polymer.IronButtonState
+ */
+ Polymer.IronButtonStateImpl = {
+
+ properties: {
+
+ /**
+ * If true, the user is currently holding down the button.
+ */
+ pressed: {
+ type: Boolean,
+ readOnly: true,
+ value: false,
+ reflectToAttribute: true,
+ observer: '_pressedChanged'
+ },
+
+ /**
+ * If true, the button toggles the active state with each tap or press
+ * of the spacebar.
+ */
+ toggles: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true
+ },
+
+ /**
+ * If true, the button is a toggle and is currently in the active state.
+ */
+ active: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ reflectToAttribute: true,
+ observer: '_activeChanged'
+ },
+
+ /**
+ * True if the element is currently being pressed by a "pointer," which
+ * is loosely defined as mouse or touch input (but specifically excluding
+ * keyboard input).
+ */
+ pointerDown: {
+ type: Boolean,
+ readOnly: true,
+ value: false
+ },
+
+ /**
+ * True if the input device that caused the element to receive focus
+ * was a keyboard.
+ */
+ receivedFocusFromKeyboard: {
+ type: Boolean,
+ readOnly: true
+ }
+ },
+
+ listeners: {
+ down: '_downHandler',
+ up: '_upHandler',
+ tap: '_tapHandler'
+ },
+
+ observers: [
+ '_detectKeyboardFocus(focused)'
+ ],
+
+ keyBindings: {
+ 'enter:keydown': '_asyncClick',
+ 'space:keydown': '_spaceKeyDownHandler',
+ 'space:keyup': '_spaceKeyUpHandler',
+ },
+
+ _tapHandler: function() {
+ if (this.toggles) {
+ // a tap is needed to toggle the active state
+ this._userActivate(!this.active);
+ } else {
+ this.active = false;
+ }
+ },
+
+ _detectKeyboardFocus: function(focused) {
+ this._setReceivedFocusFromKeyboard(!this.pointerDown && focused);
+ },
+
+ // to emulate native checkbox, (de-)activations from a user interaction fire
+ // 'change' events
+ _userActivate: function(active) {
+ this.active = active;
+ this.fire('change');
+ },
+
+ _downHandler: function() {
+ this._setPointerDown(true);
+ this._setPressed(true);
+ this._setReceivedFocusFromKeyboard(false);
+ },
+
+ _upHandler: function() {
+ this._setPointerDown(false);
+ this._setPressed(false);
+ },
+
+ _spaceKeyDownHandler: function(event) {
+ var keyboardEvent = event.detail.keyboardEvent;
+ keyboardEvent.preventDefault();
+ keyboardEvent.stopImmediatePropagation();
+ this._setPressed(true);
+ },
+
+ _spaceKeyUpHandler: function() {
+ if (this.pressed) {
+ this._asyncClick();
+ }
+ this._setPressed(false);
+ },
+
+ // trigger click asynchronously, the asynchrony is useful to allow one
+ // event handler to unwind before triggering another event
+ _asyncClick: function() {
+ this.async(function() {
+ this.click();
+ }, 1);
+ },
+
+ // any of these changes are considered a change to button state
+
+ _pressedChanged: function(pressed) {
+ this._changedButtonState();
+ },
+
+ _activeChanged: function(active) {
+ if (this.toggles) {
+ this.setAttribute('aria-pressed', active ? 'true' : 'false');
+ } else {
+ this.removeAttribute('aria-pressed');
+ }
+ this._changedButtonState();
+ },
+
+ _controlStateChanged: function() {
+ if (this.disabled) {
+ this._setPressed(false);
+ } else {
+ this._changedButtonState();
+ }
+ },
+
+ // provide hook for follow-on behaviors to react to button-state
+
+ _changedButtonState: function() {
+ if (this._buttonStateChanged) {
+ this._buttonStateChanged(); // abstract
+ }
+ }
+
+ };
+
+ /** @polymerBehavior */
+ Polymer.IronButtonState = [
+ Polymer.IronA11yKeysBehavior,
+ Polymer.IronButtonStateImpl
+ ];
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-behaviors/iron-control-state.html b/polymer_1.0.4/bower_components/iron-behaviors/iron-control-state.html
new file mode 100644
index 0000000..33e42ea
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-behaviors/iron-control-state.html
@@ -0,0 +1,108 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+
+ /**
+ * @demo demo/index.html
+ * @polymerBehavior
+ */
+ Polymer.IronControlState = {
+
+ properties: {
+
+ /**
+ * If true, the element currently has focus.
+ */
+ focused: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ readOnly: true,
+ reflectToAttribute: true
+ },
+
+ /**
+ * If true, the user cannot interact with this element.
+ */
+ disabled: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ observer: '_disabledChanged',
+ reflectToAttribute: true
+ },
+
+ _oldTabIndex: {
+ type: Number
+ },
+
+ _boundFocusBlurHandler: {
+ type: Function,
+ value: function() {
+ return this._focusBlurHandler.bind(this);
+ }
+ }
+
+ },
+
+ observers: [
+ '_changedControlState(focused, disabled)'
+ ],
+
+ ready: function() {
+ // TODO(sjmiles): ensure read-only property is valued so the compound
+ // observer will fire
+ if (this.focused === undefined) {
+ this._setFocused(false);
+ }
+ this.addEventListener('focus', this._boundFocusBlurHandler, true);
+ this.addEventListener('blur', this._boundFocusBlurHandler, true);
+ },
+
+ _focusBlurHandler: function(event) {
+ var target = event.path ? event.path[0] : event.target;
+ if (target === this) {
+ var focused = event.type === 'focus';
+ this._setFocused(focused);
+ } else if (!this.shadowRoot) {
+ event.stopPropagation();
+ this.fire(event.type, {sourceEvent: event}, {
+ node: this,
+ bubbles: event.bubbles,
+ cancelable: event.cancelable
+ });
+ }
+ },
+
+ _disabledChanged: function(disabled, old) {
+ this.setAttribute('aria-disabled', disabled ? 'true' : 'false');
+ this.style.pointerEvents = disabled ? 'none' : '';
+ if (disabled) {
+ this._oldTabIndex = this.tabIndex;
+ this.focused = false;
+ this.tabIndex = -1;
+ } else if (this._oldTabIndex !== undefined) {
+ this.tabIndex = this._oldTabIndex;
+ }
+ },
+
+ _changedControlState: function() {
+ // _controlStateChanged is abstract, follow-on behaviors may implement it
+ if (this._controlStateChanged) {
+ this._controlStateChanged();
+ }
+ }
+
+ };
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-behaviors/test/active-state.html b/polymer_1.0.4/bower_components/iron-behaviors/test/active-state.html
new file mode 100644
index 0000000..bffa727
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-behaviors/test/active-state.html
@@ -0,0 +1,154 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>active-state</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+ <script src="../../iron-test-helpers/mock-interactions.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="test-elements.html">
+</head>
+<body>
+ <test-fixture id="TrivialActiveState">
+ <template>
+ <test-button></test-button>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="ToggleActiveState">
+ <template>
+ <test-button toggles></test-button>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('active-state', function() {
+ var activeTarget;
+
+ setup(function() {
+ activeTarget = fixture('TrivialActiveState');
+ });
+
+ suite('active state with toggles attribute', function() {
+ setup(function() {
+ activeTarget = fixture('ToggleActiveState');
+ });
+
+ suite('when clicked', function() {
+ test('is activated', function(done) {
+ MockInteractions.downAndUp(activeTarget, function() {
+ try {
+ expect(activeTarget.hasAttribute('active')).to.be.eql(true);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ });
+ });
+
+ test('is deactivated by a subsequent click', function(done) {
+ MockInteractions.downAndUp(activeTarget, function() {
+ MockInteractions.downAndUp(activeTarget, function() {
+ try {
+ expect(activeTarget.hasAttribute('active')).to.be.eql(false);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ });
+ });
+ });
+ });
+ });
+
+ suite('without toggles attribute', function() {
+ suite('when mouse is down', function() {
+ test('does not get an active attribute', function() {
+ expect(activeTarget.hasAttribute('active')).to.be.eql(false);
+ MockInteractions.down(activeTarget);
+ expect(activeTarget.hasAttribute('active')).to.be.eql(false);
+ });
+ });
+
+ suite('when mouse is up', function() {
+ test('does not get an active attribute', function() {
+ MockInteractions.down(activeTarget);
+ expect(activeTarget.hasAttribute('active')).to.be.eql(false);
+ MockInteractions.up(activeTarget);
+ expect(activeTarget.hasAttribute('active')).to.be.eql(false);
+ });
+ });
+ });
+
+ suite('when space is pressed', function() {
+ test('triggers a click event', function(done) {
+ activeTarget.addEventListener('click', function() {
+ done();
+ });
+ MockInteractions.pressSpace(activeTarget);
+ });
+
+ test('only triggers click after the key is released', function(done) {
+ var keyupTriggered = false;
+
+ activeTarget.addEventListener('keyup', function() {
+ keyupTriggered = true;
+ });
+
+ activeTarget.addEventListener('click', function() {
+ try {
+ expect(keyupTriggered).to.be.eql(true);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ });
+
+ MockInteractions.pressSpace(activeTarget);
+ });
+ });
+
+ suite('when enter is pressed', function() {
+ test('triggers a click event', function(done) {
+ activeTarget.addEventListener('click', function() {
+ done();
+ });
+
+ MockInteractions.pressEnter(activeTarget);
+ });
+
+ test('only triggers click before the key is released', function(done) {
+ var keyupTriggered = false;
+
+ activeTarget.addEventListener('keyup', function() {
+ keyupTriggered = true;
+ });
+
+ activeTarget.addEventListener('click', function() {
+ try {
+ expect(keyupTriggered).to.be.eql(false);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ });
+
+ MockInteractions.pressEnter(activeTarget);
+ });
+ });
+ });
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-behaviors/test/disabled-state.html b/polymer_1.0.4/bower_components/iron-behaviors/test/disabled-state.html
new file mode 100644
index 0000000..af24ee2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-behaviors/test/disabled-state.html
@@ -0,0 +1,85 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>disabled-state</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="test-elements.html">
+</head>
+<body>
+
+ <test-fixture id="TrivialDisabledState">
+ <template>
+ <test-control></test-control>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="InitiallyDisabledState">
+ <template>
+ <test-control disabled></test-control>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('disabled-state', function() {
+ var disableTarget;
+
+ suite('a trivial disabled state', function() {
+ setup(function() {
+ disableTarget = fixture('TrivialDisabledState');
+ });
+
+ suite('when disabled is true', function() {
+ test('receives a disabled attribute', function() {
+ disableTarget.disabled = true;
+ expect(disableTarget.hasAttribute('disabled')).to.be.eql(true);
+ });
+
+ test('receives an appropriate aria attribute', function() {
+ disableTarget.disabled = true;
+ expect(disableTarget.getAttribute('aria-disabled')).to.be.eql('true');
+ });
+ });
+
+ suite('when disabled is false', function() {
+ test('loses the disabled attribute', function() {
+ disableTarget.disabled = true;
+ expect(disableTarget.hasAttribute('disabled')).to.be.eql(true);
+ disableTarget.disabled = false;
+ expect(disableTarget.hasAttribute('disabled')).to.be.eql(false);
+ });
+ });
+ });
+
+ suite('a state with an initially disabled target', function() {
+ setup(function() {
+ disableTarget = fixture('InitiallyDisabledState');
+ });
+
+ test('preserves the disabled attribute on target', function() {
+ expect(disableTarget.hasAttribute('disabled')).to.be.eql(true);
+ expect(disableTarget.disabled).to.be.eql(true);
+ });
+
+ test('adds `aria-disabled` to the target', function() {
+ expect(disableTarget.getAttribute('aria-disabled')).to.be.eql('true');
+ });
+ });
+ });
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-behaviors/test/focused-state.html b/polymer_1.0.4/bower_components/iron-behaviors/test/focused-state.html
new file mode 100644
index 0000000..2d3af69
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-behaviors/test/focused-state.html
@@ -0,0 +1,120 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>focused-state</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+ <script src="../../iron-test-helpers/mock-interactions.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="test-elements.html">
+</head>
+<body>
+
+ <test-fixture id="TrivialFocusedState">
+ <template>
+ <test-control tabindex="-1"></test-control>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="NestedFocusedState">
+ <template>
+ <nested-focusable></nested-focusable>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('focused-state', function() {
+ var focusTarget;
+
+ setup(function() {
+ focusTarget = fixture('TrivialFocusedState');
+ });
+
+ suite('when is focused', function() {
+ test('receives a focused attribute', function() {
+ expect(focusTarget.hasAttribute('focused')).to.be.eql(false);
+ MockInteractions.focus(focusTarget);
+ expect(focusTarget.hasAttribute('focused')).to.be.eql(true);
+ });
+
+ test('focused property is true', function() {
+ expect(focusTarget.focused).to.not.be.eql(true);
+ MockInteractions.focus(focusTarget);
+ expect(focusTarget.focused).to.be.eql(true);
+ });
+ });
+
+ suite('when is blurred', function() {
+ test('loses the focused attribute', function() {
+ MockInteractions.focus(focusTarget);
+ expect(focusTarget.hasAttribute('focused')).to.be.eql(true);
+ MockInteractions.blur(focusTarget);
+ expect(focusTarget.hasAttribute('focused')).to.be.eql(false);
+ });
+
+ test('focused property is false', function() {
+ MockInteractions.focus(focusTarget);
+ expect(focusTarget.focused).to.be.eql(true);
+ MockInteractions.blur(focusTarget);
+ expect(focusTarget.focused).to.be.eql(false);
+ });
+ });
+
+ suite('when the focused state is disabled', function() {
+ setup(function() {
+ focusTarget.disabled = true;
+ });
+
+ test('will not be focusable', function() {
+ expect(focusTarget.getAttribute('tabindex')).to.be.eql('-1');
+ });
+ });
+ });
+
+ suite('nested focusable', function() {
+ var focusable;
+
+ setup(function() {
+ focusable = fixture('NestedFocusedState');
+ });
+
+ test('focus/blur events fired on host element', function(done) {
+ var nFocusEvents = 0;
+ var nBlurEvents = 0;
+ focusable.addEventListener('focus', function() {
+ nFocusEvents += 1;
+ // setTimeout to wait for potentially more, erroneous events
+ setTimeout(function() {
+ assert.equal(nFocusEvents, 1, 'one focus event fired');
+ MockInteractions.blur(focusable.$.input);
+ });
+ });
+ focusable.addEventListener('blur', function() {
+ nBlurEvents += 1;
+ // setTimeout to wait for potentially more, erroneous events
+ setTimeout(function() {
+ assert.equal(nBlurEvents, 1, 'one blur event fired');
+ done();
+ });
+ });
+ MockInteractions.focus(focusable.$.input);
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-behaviors/test/index.html b/polymer_1.0.4/bower_components/iron-behaviors/test/index.html
new file mode 100644
index 0000000..0eef4d6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-behaviors/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'focused-state.html',
+ 'active-state.html',
+ 'disabled-state.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-behaviors/test/test-elements.html b/polymer_1.0.4/bower_components/iron-behaviors/test/test-elements.html
new file mode 100644
index 0000000..43bd8e5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-behaviors/test/test-elements.html
@@ -0,0 +1,66 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-control-state.html">
+<link rel="import" href="../iron-button-state.html">
+
+<script>
+
+ Polymer({
+
+ is: 'test-control',
+
+ behaviors: [
+ Polymer.IronControlState
+ ]
+
+ });
+
+</script>
+
+<script>
+
+ Polymer({
+
+ is: 'test-button',
+
+ behaviors: [
+ Polymer.IronControlState,
+ Polymer.IronButtonState
+ ],
+
+ _buttonStateChanged: function() {
+
+ }
+
+ });
+
+</script>
+
+<dom-module id="nested-focusable">
+
+ <template>
+ <input id="input">
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'nested-focusable',
+
+ behaviors: [
+ Polymer.IronControlState
+ ]
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-collapse/.bower.json b/polymer_1.0.4/bower_components/iron-collapse/.bower.json
new file mode 100644
index 0000000..2dbabbf
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-collapse/.bower.json
@@ -0,0 +1,40 @@
+{
+ "name": "iron-collapse",
+ "version": "1.0.2",
+ "description": "Provides a collapsable container",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "container"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/PolymerElements/iron-collapse"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-collapse",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "0b0228632fa005a57664d3bda8dbe14c89bec942"
+ },
+ "_source": "git://github.com/PolymerElements/iron-collapse.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-collapse"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-collapse/.gitignore b/polymer_1.0.4/bower_components/iron-collapse/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-collapse/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-collapse/README.md b/polymer_1.0.4/bower_components/iron-collapse/README.md
new file mode 100644
index 0000000..b11ac66
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-collapse/README.md
@@ -0,0 +1,37 @@
+# iron-collapse
+
+`iron-collapse` creates a collapsible block of content. By default, the content
+will be collapsed. Use `opened` or `toggle()` to show/hide the content.
+
+```html
+<button on-click="toggle">toggle collapse</button>
+
+<iron-collapse id="collapse">
+ <div>Content goes here...</div>
+</iron-collapse>
+```
+
+```javascript
+toggle: function() {
+ this.$.collapse.toggle();
+}
+```
+
+`iron-collapse` adjusts the height/width of the collapsible element to show/hide
+the content. So avoid putting padding/margin/border on the collapsible directly,
+and instead put a div inside and style that.
+
+```html
+<style>
+ .collapse-content {
+ padding: 15px;
+ border: 1px solid #dedede;
+ }
+</style>
+
+<iron-collapse>
+ <div class="collapse-content">
+ <div>Content goes here...</div>
+ </div>
+</iron-collapse>
+```
diff --git a/polymer_1.0.4/bower_components/iron-collapse/bower.json b/polymer_1.0.4/bower_components/iron-collapse/bower.json
new file mode 100644
index 0000000..4c1a7a4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-collapse/bower.json
@@ -0,0 +1,31 @@
+{
+ "name": "iron-collapse",
+ "version": "1.0.2",
+ "description": "Provides a collapsable container",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "container"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/PolymerElements/iron-collapse"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-collapse",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-collapse/demo/index.html b/polymer_1.0.4/bower_components/iron-collapse/demo/index.html
new file mode 100644
index 0000000..c9571ea
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-collapse/demo/index.html
@@ -0,0 +1,74 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <title>iron-collapse demo</title>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-collapse.html">
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+
+ <style>
+ .heading {
+ padding: 10px 15px;
+ margin-top: 20px;
+ background-color: #f3f3f3;
+ border: 1px solid #dedede;
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+ font-size: 18px;
+ cursor: pointer;
+ -webkit-tap-highlight-color: rgba(0,0,0,0);
+ width: 100%;
+ text-align: left;
+ }
+
+ .content {
+ padding: 15px;
+ border: 1px solid #dedede;
+ border-top: none;
+ border-bottom-left-radius: 5px;
+ border-bottom-right-radius: 5px;
+ }
+
+ </style>
+
+ </head>
+ <body unresolved>
+
+ <button class="heading" onclick="document.querySelector('#collapse1').toggle();">Collapse #1</button>
+ <iron-collapse id="collapse1">
+ <div class="content">
+ <div>Lorem ipsum dolor sit amet, per in nusquam nominavi periculis, sit elit oportere ea, id minim maiestatis incorrupte duo. Dolorum verterem ad ius, his et nullam verterem. Eu alia debet usu, an doming tritani est. Vix ad ponderum petentium suavitate, eum eu tempor populo, graece sententiae constituam vim ex. Cu torquatos reprimique neglegentur nec, voluptua periculis has ut, at eos discere deleniti sensibus. Lorem ipsum dolor sit amet, per in nusquam nominavi periculis, sit elit oportere ea, id minim maiestatis incorrupte duo. Dolorum verterem ad ius, his et nullam verterem. Eu alia debet usu, an doming tritani est. Vix ad ponderum petentium suavitate, eum eu tempor populo, graece sententiae constituam vim ex. Cu torquatos reprimique neglegentur nec, voluptua periculis has ut, at eos discere deleniti sensibus.</div>
+ </div>
+ </iron-collapse>
+
+ <button class="heading" onclick="document.querySelector('#collapse2').toggle();">Collapse #2</button>
+ <iron-collapse id="collapse2">
+ <div class="content">
+ <div>Pro saepe pertinax ei, ad pri animal labores suscipiantur. Modus commodo minimum eum te, vero utinam assueverit per eu, zril oportere suscipiantur pri te. Partem percipitur deterruisset ad sea, at eam suas luptatum dissentiunt. No error alienum pro, erant senserit ex mei, pri semper alterum no. Ut habemus menandri vulputate mea. Feugiat verterem ut sed. Dolores maiestatis id per. Pro saepe pertinax ei, ad pri animal labores suscipiantur. Modus commodo minimum eum te, vero utinam assueverit per eu, zril oportere suscipiantur pri te. Partem percipitur deterruisset ad sea, at eam suas luptatum dissentiunt. No error alienum pro, erant senserit ex mei, pri semper alterum no. Ut habemus menandri vulputate mea. Feugiat verterem ut sed. Dolores maiestatis id per.</div>
+
+ <button class="heading" onclick="document.querySelector('#collapse3').toggle();">Collapse #3</button>
+ <iron-collapse id="collapse3">
+ <div class="content">
+ <div>Iisque perfecto dissentiet cum et, sit ut quot mandamus, ut vim tibique splendide instructior. Id nam odio natum malorum, tibique copiosae expetenda mel ea. Mea melius malorum ut. Ut nec tollit vocent timeam. Facer nonumy numquam id his, munere salutatus consequuntur eum et, eum cotidieque definitionem signiferumque id. Ei oblique graecis patrioque vis, et probatus dignissim inciderint vel. Sed id paulo erroribus, autem semper accusamus in mel. Iisque perfecto dissentiet cum et, sit ut quot mandamus, ut vim tibique splendide instructior. Id nam odio natum malorum, tibique copiosae expetenda mel ea. Mea melius malorum ut. Ut nec tollit vocent timeam. Facer nonumy numquam id his, munere salutatus consequuntur eum et, eum cotidieque definitionem signiferumque id. Ei oblique graecis patrioque vis, et probatus dignissim inciderint vel. Sed id paulo erroribus, autem semper accusamus in mel.</div>
+ </div>
+ </iron-collapse>
+ </div>
+ </iron-collapse>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-collapse/hero.svg b/polymer_1.0.4/bower_components/iron-collapse/hero.svg
new file mode 100755
index 0000000..ae1a49e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-collapse/hero.svg
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+ <path display="inline" fill="none" d="M167.5,51.7c3.7-0.8,6.9,2.4,6.1,6.1c-0.4,1.9-1.9,3.4-3.8,3.8c-3.7,0.8-6.9-2.4-6.1-6.1
+ C164.2,53.6,165.7,52.1,167.5,51.7z"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <path d="M151,102H73V52h78V102z M75,100h74V54H75V100z"/>
+ <path d="M151,38H73V24h78V38z M75,36h74V26H75V36z"/>
+ <circle cx="171" cy="51" r="4"/>
+ <path d="M151,72v-2c10.5,0,19-8.5,19-19s-8.5-19-19-19v-2c11.6,0,21,9.4,21,21S162.6,72,151,72z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/iron-collapse/index.html b/polymer_1.0.4/bower_components/iron-collapse/index.html
new file mode 100644
index 0000000..b5d2007
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-collapse/index.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>iron-collapse</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+ </head>
+ <body>
+
+ <iron-component-page></iron-component-page>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-collapse/iron-collapse.html b/polymer_1.0.4/bower_components/iron-collapse/iron-collapse.html
new file mode 100644
index 0000000..b8f72fd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-collapse/iron-collapse.html
@@ -0,0 +1,195 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<!--
+`iron-collapse` creates a collapsible block of content. By default, the content
+will be collapsed. Use `opened` or `toggle()` to show/hide the content.
+
+ <button on-click="{{toggle}}">toggle collapse</button>
+
+ <iron-collapse id="collapse">
+ <div>Content goes here...</div>
+ </iron-collapse>
+
+ ...
+
+ toggle: function() {
+ this.$.collapse.toggle();
+ }
+
+`iron-collapse` adjusts the height/width of the collapsible element to show/hide
+the content. So avoid putting padding/margin/border on the collapsible directly,
+and instead put a div inside and style that.
+
+ <style>
+ .collapse-content {
+ padding: 15px;
+ border: 1px solid #dedede;
+ }
+ </style>
+
+ <iron-collapse>
+ <div class="collapse-content">
+ <div>Content goes here...</div>
+ </div>
+ </iron-collapse>
+
+@group Iron Elements
+@hero hero.svg
+@demo demo/index.html
+@element iron-collapse
+-->
+
+<dom-module id="iron-collapse">
+
+ <style>
+
+ :host {
+ display: block;
+ transition-duration: 300ms;
+ }
+
+ :host(.iron-collapse-closed) {
+ display: none;
+ }
+
+ :host(:not(.iron-collapse-opened)) {
+ overflow: hidden;
+ }
+
+ </style>
+
+ <template>
+
+ <content></content>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'iron-collapse',
+
+ properties: {
+
+ /**
+ * If true, the orientation is horizontal; otherwise is vertical.
+ *
+ * @attribute horizontal
+ */
+ horizontal: {
+ type: Boolean,
+ value: false,
+ observer: '_horizontalChanged'
+ },
+
+ /**
+ * Set opened to true to show the collapse element and to false to hide it.
+ *
+ * @attribute opened
+ */
+ opened: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ observer: '_openedChanged'
+ }
+
+ },
+
+ hostAttributes: {
+ role: 'group',
+ 'aria-expanded': 'false'
+ },
+
+ listeners: {
+ transitionend: '_transitionEnd'
+ },
+
+ ready: function() {
+ // Avoid transition at the beginning e.g. page loads and enable
+ // transitions only after the element is rendered and ready.
+ this._enableTransition = true;
+ },
+
+ /**
+ * Toggle the opened state.
+ *
+ * @method toggle
+ */
+ toggle: function() {
+ this.opened = !this.opened;
+ },
+
+ show: function() {
+ this.toggleClass('iron-collapse-closed', false);
+ this.updateSize('auto', false);
+ var s = this._calcSize();
+ this.updateSize('0px', false);
+ // force layout to ensure transition will go
+ this.offsetHeight;
+ this.updateSize(s, true);
+ },
+
+ hide: function() {
+ this.toggleClass('iron-collapse-opened', false);
+ this.updateSize(this._calcSize(), false);
+ // force layout to ensure transition will go
+ this.offsetHeight;
+ this.updateSize('0px', true);
+ },
+
+ updateSize: function(size, animated) {
+ this.enableTransition(animated);
+ var s = this.style;
+ var nochange = s[this.dimension] === size;
+ s[this.dimension] = size;
+ if (animated && nochange) {
+ this._transitionEnd();
+ }
+ },
+
+ enableTransition: function(enabled) {
+ this.style.transitionDuration = (enabled && this._enableTransition) ? '' : '0s';
+ },
+
+ _horizontalChanged: function() {
+ this.dimension = this.horizontal ? 'width' : 'height';
+ this.style.transitionProperty = this.dimension;
+ },
+
+ _openedChanged: function() {
+ this[this.opened ? 'show' : 'hide']();
+ this.setAttribute('aria-expanded', this.opened ? 'true' : 'false');
+
+ },
+
+ _transitionEnd: function() {
+ if (this.opened) {
+ this.updateSize('auto', false);
+ }
+ this.toggleClass('iron-collapse-closed', !this.opened);
+ this.toggleClass('iron-collapse-opened', this.opened);
+ this.enableTransition(false);
+ },
+
+ _calcSize: function() {
+ return this.getBoundingClientRect()[this.dimension] + 'px';
+ },
+
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-collapse/test/basic.html b/polymer_1.0.4/bower_components/iron-collapse/test/basic.html
new file mode 100644
index 0000000..46b1b18
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-collapse/test/basic.html
@@ -0,0 +1,93 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <title>iron-collapse-basic</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-collapse.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="test">
+ <template>
+ <iron-collapse id="collapse" opened>
+ <div>
+ Forma temperiemque cornua sidera dissociata cornua recessit innabilis ligavit: solidumque coeptis nullus caelum sponte phoebe di regat mentisque tanta austro capacius amphitrite sui quin postquam semina fossae liquidum umor galeae coeptis caligine liberioris quin liquidum matutinis invasit posset: flexi glomeravit radiis certis invasit oppida postquam onerosior inclusum dominari opifex terris pace finxit quam aquae nunc sine altae auroram quam habentem homo totidemque scythiam in pondus ensis tegit caecoque poena lapidosos humanas coeperunt poena aetas totidem nec natura aethera locavit caelumque distinxit animalibus phoebe cingebant moderantum porrexerat terrae possedit sua sole diu summaque obliquis melioris orbem
+ </div>
+ </iron-collapse>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+
+ var collapse;
+ var delay = 500;
+ var collapseHeight;
+
+ setup(function () {
+ collapse = fixture('test');
+ });
+
+ test('opened attribute', function() {
+ assert.equal(collapse.opened, true);
+ });
+
+ test('horizontal attribute', function() {
+ assert.equal(collapse.horizontal, false);
+ });
+
+ test('default opened height', function(done) {
+ setTimeout(function() {
+ // store height
+ collapseHeight = getComputedStyle(collapse).height;
+ // verify height not 0px
+ assert.notEqual(collapseHeight, '0px');
+ done();
+ }, delay);
+ });
+
+ test('set opened to false', function(done) {
+ collapse.opened = false;
+ setTimeout(function() {
+ var h = getComputedStyle(collapse).height;
+ // verify height is 0px
+ assert.equal(h, '0px');
+ done();
+ }, delay);
+ });
+
+ test('set opened to true', function(done) {
+ collapse.opened = true;
+ setTimeout(function() {
+ var h = getComputedStyle(collapse).height;
+ // verify height
+ assert.equal(h, collapseHeight);
+ done();
+ }, delay);
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-collapse/test/horizontal.html b/polymer_1.0.4/bower_components/iron-collapse/test/horizontal.html
new file mode 100644
index 0000000..77ab89e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-collapse/test/horizontal.html
@@ -0,0 +1,91 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+ <title>iron-collapse-horizontal</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-collapse.html">
+ </head>
+ <body>
+
+ <test-fixture id="test">
+ <template>
+ <iron-collapse id="collapse" opened horizontal>
+ <div>
+ Forma temperiemque cornua sidera dissociata cornua recessit innabilis ligavit: solidumque coeptis nullus caelum sponte phoebe di regat mentisque tanta austro capacius amphitrite sui quin postquam semina fossae liquidum umor galeae coeptis caligine liberioris quin liquidum matutinis invasit posset: flexi glomeravit radiis certis invasit oppida postquam onerosior inclusum dominari opifex terris pace finxit quam aquae nunc sine altae auroram quam habentem homo totidemque scythiam in pondus ensis tegit caecoque poena lapidosos humanas coeperunt poena aetas totidem nec natura aethera locavit caelumque distinxit animalibus phoebe cingebant moderantum porrexerat terrae possedit sua sole diu summaque obliquis melioris orbem
+ </div>
+ </iron-collapse>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('horizontal', function() {
+
+ var collapse;
+ var delay = 500;
+ var collapseHeight;
+
+ setup(function () {
+ collapse = fixture('test');
+ });
+
+ test('opened attribute', function() {
+ assert.equal(collapse.opened, true);
+ });
+
+ test('horizontal attribute', function() {
+ assert.equal(collapse.horizontal, true);
+ });
+
+ test('default opened width', function(done) {
+ setTimeout(function() {
+ // store actual width
+ width = getComputedStyle(collapse).width;
+ // verify width not 0px
+ assert.notEqual(width, '0px');
+ done();
+ }, delay);
+ });
+
+ test('set opened to false', function(done) {
+ collapse.opened = false;
+ setTimeout(function() {
+ var h = getComputedStyle(collapse).width;
+ // verify width is 0px
+ assert.equal(h, '0px');
+ done();
+ }, delay);
+ });
+
+ test('set opened to true', function(done) {
+ collapse.opened = true;
+ setTimeout(function() {
+ var h = getComputedStyle(collapse).width;
+ // verify width
+ assert.equal(h, width);
+ done();
+ }, delay);
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-collapse/test/index.html b/polymer_1.0.4/bower_components/iron-collapse/test/index.html
new file mode 100644
index 0000000..e5e8a2e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-collapse/test/index.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <meta charset="utf-8">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'basic.html',
+ 'horizontal.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-component-page/.bower.json b/polymer_1.0.4/bower_components/iron-component-page/.bower.json
new file mode 100644
index 0000000..9ce6997
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-component-page/.bower.json
@@ -0,0 +1,46 @@
+{
+ "name": "iron-component-page",
+ "description": "Turns a raw element definition into beautiful documentation",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "docs"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-component-page.git"
+ },
+ "version": "1.0.5",
+ "private": true,
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-doc-viewer": "PolymerElements/iron-doc-viewer#^1.0.1",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "paper-toolbar": "PolymerElements/paper-toolbar#^1.0.0",
+ "iron-ajax": "PolymerElements/iron-ajax#^1.0.0",
+ "hydrolysis": "Polymer/hydrolysis#^1.11",
+ "paper-header-panel": "PolymerElements/paper-header-panel#^1.0.0",
+ "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+ "iron-selector": "PolymerElements/iron-selector#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0"
+ },
+ "devDependencies": {
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "web-component-tester": "*"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-component-page",
+ "_release": "1.0.5",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.5",
+ "commit": "2bc588824d9ddbbb042ec59f00cd379876137c99"
+ },
+ "_source": "git://github.com/PolymerElements/iron-component-page.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-component-page"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-component-page/.gitignore b/polymer_1.0.4/bower_components/iron-component-page/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-component-page/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-component-page/README.md b/polymer_1.0.4/bower_components/iron-component-page/README.md
new file mode 100644
index 0000000..de91192
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-component-page/README.md
@@ -0,0 +1,6 @@
+iron-component-page
+===================
+
+Loads Polymer element and behavior documentation using
+[Hydrolysis](https://github.com/PolymerLabs/hydrolysis) and renders a complete
+documentation page including demos (if available).
diff --git a/polymer_1.0.4/bower_components/iron-component-page/bower.json b/polymer_1.0.4/bower_components/iron-component-page/bower.json
new file mode 100644
index 0000000..7df8236
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-component-page/bower.json
@@ -0,0 +1,36 @@
+{
+ "name": "iron-component-page",
+ "description": "Turns a raw element definition into beautiful documentation",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "docs"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-component-page.git"
+ },
+ "version": "1.0.5",
+ "private": true,
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-doc-viewer": "PolymerElements/iron-doc-viewer#^1.0.1",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "paper-toolbar": "PolymerElements/paper-toolbar#^1.0.0",
+ "iron-ajax": "PolymerElements/iron-ajax#^1.0.0",
+ "hydrolysis": "Polymer/hydrolysis#^1.11",
+ "paper-header-panel": "PolymerElements/paper-header-panel#^1.0.0",
+ "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+ "iron-selector": "PolymerElements/iron-selector#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0"
+ },
+ "devDependencies": {
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "web-component-tester": "*"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-component-page/demo/index.html b/polymer_1.0.4/bower_components/iron-component-page/demo/index.html
new file mode 100644
index 0000000..581db5b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-component-page/demo/index.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <h2>iron-component-page</h2>
+ <iron-component-page doc-src="json-descriptor.json"></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-component-page/demo/json-descriptor.json b/polymer_1.0.4/bower_components/iron-component-page/demo/json-descriptor.json
new file mode 100644
index 0000000..55c6d5c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-component-page/demo/json-descriptor.json
@@ -0,0 +1 @@
+{"elements":[{"type":"element","desc":"Renders documentation describing an element's API.\n\n`iron-doc-viewer` renders element and behavior descriptions as extracted by\n[Hydrolysis](https://github.com/PolymerLabs/hydrolysis). You can provide them\neither via binding...\n\n <iron-doc-viewer descriptor=\"{{elementDescriptor}}\"></iron-doc-viewer>\n\n...or by placing the element descriptor in JSON as the text content of an\n`iron-doc-viewer`:\n\n <iron-doc-viewer>\n {\n \"is\": \"awesome-sauce\",\n \"properties\": [\n {\"name\": \"isAwesome\", \"type\": \"boolean\", \"desc\": \"Is it awesome?\"},\n ]\n }\n </iron-doc-viewer>\n\nHowever, be aware that due to current limitations in Polymer 0.8, _changes_ to\nthe text content will not be respected, only the initial value will be loaded.\nIf you wish to update the documented element, please set it via the `descriptor`\nproperty.\n","events":[],"properties":[{"name":"descriptor","type":"hydrolysis.ElementDescriptor","desc":"The [Hydrolysis](https://github.com/PolymerLabs/hydrolysis)-generated\nelement descriptor to display details for.\n\nAlternatively, the element descriptor can be provided as JSON via the text content\nof this element.\n","published":true},{"name":"_collapsedChanged","type":"Function","params":[],"private":true,"function":true},{"name":"_descriptorChanged","type":"Function","desc":"Converts `descriptor` into our template-friendly `_model`. ","params":[],"private":true,"function":true},{"name":"_loadJson","type":"Function","desc":"Loads a hydrolysis element descriptor (as JSON) from the text content of\nthis element, if present.\n","params":[],"private":true,"function":true,"return":{"type":"hydrolysis.ElementDescriptor","desc":"parsed descriptor, or `null`.\n "}},{"name":"_noneToShow","type":"Function","params":[{"name":"showPrivate"},{"name":"items"}],"private":true,"function":true},{"name":"_privateToggleLabel","type":"string","desc":"The label to show for the Private API toggle. ","published":true,"private":true},{"name":"_showPrivate","type":"Boolean","desc":"Whether private properties should be hidden or shown. ","published":true,"default":false,"private":true},{"name":"_showPrivateChanged","type":"Function","params":[],"private":true,"function":true},{"name":"_toggleCollapsed","type":"Function","params":[],"private":true,"function":true},{"name":"_togglePrivate","type":"Function","params":[],"private":true,"function":true},{"name":"ready","type":"Function","params":[],"private":true,"configuration":true,"function":true}],"is":"iron-doc-viewer","jsdoc":{"tags":[{"tag":"demo","type":null,"name":"demo/index.html","body":"Basic Demo\n"}]},"demos":[{"desc":"Basic Demo\n","path":"demo/index.html"}]},{"type":"element","desc":"Renders documentation describing a specific property of an element.\n\nGive it a hydrolysis `PropertyDescriptor` (via `descriptor`), and watch it go!\n","events":[],"properties":[{"name":"collapsed","type":"Boolean","desc":"Whether the property should show a one-liner, or full summary.\n\nNote that this property _is_ reflected as an attribute, but we perform\nthe reflection manually. In order to support the CSS transitions, we\nmust calculate the element height before setting the attribute.\n ","published":true,"default":false},{"name":"descriptor","type":"hydrolysis.PropertyDescriptor","desc":"The [Hydrolysis](https://github.com/PolymerLabs/hydrolysis)-generated\nelement descriptor to display details for.\n\nAlternatively, the element descriptor can be provided as JSON via the text content\nof this element.\n","published":true},{"name":"_collapsedChanged","type":"Function","desc":"Reflects `collapsed` as the `_collapsed` attribute.\n\n\"Why not use `reflectToAttribute: true`?\", you ask? A fine question!\n\nWe avoid simple reflection purely because there is no purely declarative\nway of transitioning to/from `height: auto`. This callback manages\nsetting explicit heights for the property so that CSS can interpolate it.\n","params":[],"jsdoc":{"tags":[{"tag":"see","type":null,"name":"#_onTransitionEnd","body":null}]},"private":true,"function":true},{"name":"_computeHideMeta","type":"Function","params":[{"name":"descriptor"}],"private":true,"function":true},{"name":"_computeHideParams","type":"Function","params":[{"name":"descriptor"}],"private":true,"function":true},{"name":"_descriptorChanged","type":"Function","params":[],"private":true,"function":true},{"name":"_onTransitionEnd","type":"Function","desc":"Resets any state that was set up for transitions.\n\nWe are careful to reset our explicit heights after a transition\ncompletes, so that the property doesn't clip values if the user resizes\ntheir viewport.\n ","params":[{"name":"event"}],"private":true,"function":true},{"name":"listeners","type":"Object","private":true,"configuration":true},{"name":"ready","type":"Function","params":[],"private":true,"configuration":true,"function":true}],"is":"iron-doc-property","demos":[]}],"elementsByTagName":{"iron-doc-viewer":{"type":"element","desc":"Renders documentation describing an element's API.\n\n`iron-doc-viewer` renders element and behavior descriptions as extracted by\n[Hydrolysis](https://github.com/PolymerLabs/hydrolysis). You can provide them\neither via binding...\n\n <iron-doc-viewer descriptor=\"{{elementDescriptor}}\"></iron-doc-viewer>\n\n...or by placing the element descriptor in JSON as the text content of an\n`iron-doc-viewer`:\n\n <iron-doc-viewer>\n {\n \"is\": \"awesome-sauce\",\n \"properties\": [\n {\"name\": \"isAwesome\", \"type\": \"boolean\", \"desc\": \"Is it awesome?\"},\n ]\n }\n </iron-doc-viewer>\n\nHowever, be aware that due to current limitations in Polymer 0.8, _changes_ to\nthe text content will not be respected, only the initial value will be loaded.\nIf you wish to update the documented element, please set it via the `descriptor`\nproperty.\n","events":[],"properties":[{"name":"descriptor","type":"hydrolysis.ElementDescriptor","desc":"The [Hydrolysis](https://github.com/PolymerLabs/hydrolysis)-generated\nelement descriptor to display details for.\n\nAlternatively, the element descriptor can be provided as JSON via the text content\nof this element.\n","published":true},{"name":"_collapsedChanged","type":"Function","params":[],"private":true,"function":true},{"name":"_descriptorChanged","type":"Function","desc":"Converts `descriptor` into our template-friendly `_model`. ","params":[],"private":true,"function":true},{"name":"_loadJson","type":"Function","desc":"Loads a hydrolysis element descriptor (as JSON) from the text content of\nthis element, if present.\n","params":[],"private":true,"function":true,"return":{"type":"hydrolysis.ElementDescriptor","desc":"parsed descriptor, or `null`.\n "}},{"name":"_noneToShow","type":"Function","params":[{"name":"showPrivate"},{"name":"items"}],"private":true,"function":true},{"name":"_privateToggleLabel","type":"string","desc":"The label to show for the Private API toggle. ","published":true,"private":true},{"name":"_showPrivate","type":"Boolean","desc":"Whether private properties should be hidden or shown. ","published":true,"default":false,"private":true},{"name":"_showPrivateChanged","type":"Function","params":[],"private":true,"function":true},{"name":"_toggleCollapsed","type":"Function","params":[],"private":true,"function":true},{"name":"_togglePrivate","type":"Function","params":[],"private":true,"function":true},{"name":"ready","type":"Function","params":[],"private":true,"configuration":true,"function":true}],"is":"iron-doc-viewer","jsdoc":{"tags":[{"tag":"demo","type":null,"name":"demo/index.html","body":"Basic Demo\n"}]},"demos":[{"desc":"Basic Demo\n","path":"demo/index.html"}]},"iron-doc-property":{"type":"element","desc":"Renders documentation describing a specific property of an element.\n\nGive it a hydrolysis `PropertyDescriptor` (via `descriptor`), and watch it go!\n","events":[],"properties":[{"name":"collapsed","type":"Boolean","desc":"Whether the property should show a one-liner, or full summary.\n\nNote that this property _is_ reflected as an attribute, but we perform\nthe reflection manually. In order to support the CSS transitions, we\nmust calculate the element height before setting the attribute.\n ","published":true,"default":false},{"name":"descriptor","type":"hydrolysis.PropertyDescriptor","desc":"The [Hydrolysis](https://github.com/PolymerLabs/hydrolysis)-generated\nelement descriptor to display details for.\n\nAlternatively, the element descriptor can be provided as JSON via the text content\nof this element.\n","published":true},{"name":"_collapsedChanged","type":"Function","desc":"Reflects `collapsed` as the `_collapsed` attribute.\n\n\"Why not use `reflectToAttribute: true`?\", you ask? A fine question!\n\nWe avoid simple reflection purely because there is no purely declarative\nway of transitioning to/from `height: auto`. This callback manages\nsetting explicit heights for the property so that CSS can interpolate it.\n","params":[],"jsdoc":{"tags":[{"tag":"see","type":null,"name":"#_onTransitionEnd","body":null}]},"private":true,"function":true},{"name":"_computeHideMeta","type":"Function","params":[{"name":"descriptor"}],"private":true,"function":true},{"name":"_computeHideParams","type":"Function","params":[{"name":"descriptor"}],"private":true,"function":true},{"name":"_descriptorChanged","type":"Function","params":[],"private":true,"function":true},{"name":"_onTransitionEnd","type":"Function","desc":"Resets any state that was set up for transitions.\n\nWe are careful to reset our explicit heights after a transition\ncompletes, so that the property doesn't clip values if the user resizes\ntheir viewport.\n ","params":[{"name":"event"}],"private":true,"function":true},{"name":"listeners","type":"Object","private":true,"configuration":true},{"name":"ready","type":"Function","params":[],"private":true,"configuration":true,"function":true}],"is":"iron-doc-property","demos":[]}},"behaviors":[],"features":[]}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-component-page/index.html b/polymer_1.0.4/bower_components/iron-component-page/index.html
new file mode 100644
index 0000000..0750f19
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-component-page/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-component-page/iron-component-page.css b/polymer_1.0.4/bower_components/iron-component-page/iron-component-page.css
new file mode 100644
index 0000000..4c2c7c7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-component-page/iron-component-page.css
@@ -0,0 +1,155 @@
+/**
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+
+*/
+:host {
+ font-family: 'Roboto', 'Noto', sans-serif;
+ @apply(--layout-fit);
+ @apply(--layout);
+ @apply(--layout-vertical);
+ overflow: hidden;
+ background: var(--paper-grey-50);
+}
+
+p {
+ max-width: 20em;
+}
+
+paper-header-panel {
+ @apply(--layout-flex);
+ background: var(--paper-grey-50);
+}
+
+paper-toolbar {
+ --paper-toolbar-background: var(--paper-grey-50);
+ --paper-toolbar-color: var(--paper-grey-800);
+ flex-shrink: 0;
+}
+
+:host > paper-header-panel {
+ opacity: 0;
+ transition: opacity 0.5s;
+}
+
+:host(.loaded) > paper-header-panel {
+ opacity: 1.0;
+}
+
+#content {
+ display: block;
+ background: var(--paper-grey-50);
+}
+
+paper-toolbar a {
+ margin: 0 10px;
+ cursor: pointer;
+}
+
+paper-toolbar a:last-child {
+ margin-right: 0;
+}
+
+paper-toolbar a, paper-toolbar a iron-icon {
+ font-weight: normal;
+ color: var(--paper-grey-500);
+}
+
+paper-toolbar iron-icon {
+ margin: -2px 5px 0 0;
+}
+
+paper-toolbar a:hover, paper-toolbar a:hover iron-icon, paper-toolbar a.iron-selected, paper-toolbar a.iron-selected iron-icon {
+ color: var(--paper-grey-800);
+}
+
+#demo {
+ @apply(--layout-fit);
+}
+
+#nodocs {
+ background: var(--paper-grey-50);
+ font-size: 24px;
+ font-weight: 400;
+ color: var(--paper-grey-400);
+}
+
+#demo {
+ border: 0;
+ background: transparent;
+ width: 100%;
+ height: 100%;
+ overflow-x: none;
+ overflow-y: auto;
+}
+
+#view > * {
+ display: none;
+}
+
+#view > .iron-selected {
+ display: block;
+}
+
+#docs {
+ padding: 20px;
+ max-width: 48em;
+ margin: 0 auto;
+}
+
+#active {
+ font-size: 20px;
+ font-family: Roboto, Noto;
+ border: 0;
+ background: transparent;
+}
+
+paper-toolbar a {
+ font-size: 14px;
+ text-transform: uppercase;
+ cursor: pointer;
+}
+
+#cart-icon {
+ margin-left: 10px;
+ cursor: pointer;
+}
+
+#catalog-heading {
+ margin: 4px 0 18px;
+}
+
+#catalog-heading h2 {
+ color: var(--paper-grey-800);
+ @apply(--paper-font-title);
+ margin: 0;
+}
+
+#catalog-heading .version {
+ color: var(--paper-grey-500);
+ font-size: 18px;
+ line-height: 24px;
+ font-weight: 400;
+}
+#catalog-heading .version:before {
+ content: "(";
+}
+#catalog-heading .version:after {
+ content: ")";
+}
+
+[catalog-only] {
+ display: none;
+}
+
+:host([_catalog]) [catalog-only] {
+ display: block;
+}
+:host([_catalog]) [catalog-hidden] {
+ display: none;
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-component-page/iron-component-page.html b/polymer_1.0.4/bower_components/iron-component-page/iron-component-page.html
new file mode 100644
index 0000000..d8693e9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-component-page/iron-component-page.html
@@ -0,0 +1,440 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../hydrolysis/hydrolysis-analyzer.html">
+<link rel="import" href="../iron-doc-viewer/iron-doc-viewer.html">
+<link rel="import" href="../iron-icons/iron-icons.html">
+<link rel="import" href="../iron-ajax/iron-ajax.html">
+<link rel="import" href="../iron-selector/iron-selector.html">
+<link rel="import" href="../paper-header-panel/paper-header-panel.html">
+<link rel="import" href="../paper-toolbar/paper-toolbar.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+
+<!--
+Loads Polymer element and behavior documentation using
+[Hydrolysis](https://github.com/PolymerLabs/hydrolysis) and renders a complete
+documentation page including demos (if available).
+-->
+<dom-module id="iron-component-page">
+ <link rel="import" type="css" href="iron-component-page.css">
+ <template>
+ <hydrolysis-analyzer id="analyzer" src="[[_srcUrl]]" transitive="[[transitive]]" clean analyzer="{{_hydroDesc}}" loading="{{_hydroLoading}}"></hydrolysis-analyzer>
+ <iron-ajax id="ajax" url="[[docSrc]]" handle-as="json" on-response="_handleAjaxResponse"></iron-ajax>
+
+ <paper-header-panel id="headerPanel" mode="waterfall">
+ <paper-toolbar catalog-hidden>
+ <div class="flex">
+ <!-- TODO: Replace with paper-dropdown-menu when available -->
+ <select id="active" value="{{active::change}}">
+ <template is="dom-repeat" items="[[docElements]]">
+ <option value="[[item.is]]">[[item.is]]</option>
+ </template>
+ <template is="dom-repeat" items="[[docBehaviors]]">
+ <option value="[[item.is]]">[[item.is]]</option>
+ </template>
+ </select>
+ </div>
+ <iron-selector attr-for-selected="view" selected="{{view}}" id="links" hidden$="[[!docDemos.length]]">
+ <a view="docs"><iron-icon icon="description"></iron-icon> Docs</a>
+ <a view="[[_demoView(docDemos.0.path)]]"><iron-icon icon="visibility"></iron-icon> <span>Demo</span></a>
+ </iron-selector>
+ </paper-toolbar>
+ <div id="content">
+ <iron-selector id="view" selected="[[_viewType(view)]]" attr-for-selected="id">
+ <div id="docs">
+ <div id="catalog-heading" catalog-only>
+ <h2><span>[[active]]</span> <span class="version" hidden$="[[!version]]">[[version]]</span></h2>
+ </div>
+ <iron-doc-viewer descriptor="{{_activeDescriptor}}"
+ on-iron-doc-viewer-component-selected="_handleComponentSelectedEvent"></iron-doc-viewer>
+ <div id="nodocs" hidden$="[[_activeDescriptor]]" class="layout fit horizontal center-center">
+ No documentation found.
+ </div>
+ </div>
+ <iframe id="demo" src="[[_frameSrc(view, base)]]"></iframe>
+ </iron-selector>
+ </div>
+ </paper-header-panel>
+ </template>
+</dom-module>
+
+<script>
+(function() {
+ // var hydrolysis = require('hydrolysis');
+
+ /**
+ * @param {string} url
+ * @return {string} `url` stripped of a file name, if one is present. This
+ * considers URLs like "example.com/foo" to already be a base (no `.` is)
+ * present in the final path part).
+ */
+ function _baseUrl(url) {
+ return url.match(/^(.*?)\/?([^\/]+\.[^\/]+)?$/)[1] + '/';
+ }
+
+ Polymer({
+ is: 'iron-component-page',
+ enableCustomStyleProperties: true,
+ properties: {
+ /**
+ * The URL to an import that declares (or transitively imports) the
+ * elements that you wish to see documented.
+ *
+ * If the URL is relative, it will be resolved relative to the master
+ * document.
+ *
+ * If a `src` URL is not specified, it will resolve the name of the
+ * directory containing this element, followed by `dirname.html`. For
+ * example:
+ *
+ * `awesome-sauce/index.html`:
+ *
+ * <iron-doc-viewer></iron-doc-viewer>
+ *
+ * Would implicitly have `src="awesome-sauce.html"`.
+ */
+ src: {
+ type: String,
+ observer: '_srcChanged',
+ },
+
+ /**
+ * The URL to a precompiled JSON descriptor. If you have precompiled
+ * and stored a documentation set using Hydrolysis, you can load the
+ * analyzer directly via AJAX by specifying this attribute.
+ *
+ * If a `doc-src` is not specified, it is ignored and the default
+ * rules according to the `src` attribute are used.
+ */
+ docSrc: {
+ type: String,
+ observer: '_srcChanged',
+ },
+
+ /**
+ * The relative root for determining paths to demos and default source
+ * detection.
+ */
+ base: {
+ type: String,
+ value: function() {
+ return this.ownerDocument.baseURI;
+ }
+ },
+
+ /**
+ * The element or behavior that will be displayed on the page. Defaults
+ * to the element matching the name of the source file.
+ */
+ active: {
+ type: String,
+ observer: '_activeChanged',
+ notify: true
+ },
+
+ /**
+ * The current view. Can be `docs` or `demo`.
+ */
+ view: {
+ type: String,
+ value: 'docs',
+ notify: true
+ },
+
+ /**
+ * Whether _all_ dependencies should be loaded and documented.
+ *
+ * Turning this on will probably slow down the load process dramatically.
+ */
+ transitive: {
+ type: Boolean,
+ value: false
+ },
+
+ /** The Hydrolysis element descriptors that have been loaded. */
+ docElements: {
+ type: Array,
+ observer: '_descriptorsChanged',
+ notify: true,
+ readOnly: true
+ },
+
+ /** The Hydrolysis behavior descriptors that have been loaded. */
+ docBehaviors: {
+ type: Array,
+ observer: '_descriptorsChanged',
+ notify: true,
+ readOnly: true
+ },
+
+ /**
+ * Demos for the currently selected element.
+ */
+ docDemos: {
+ type: Array,
+ notify: true,
+ readOnly: true
+ },
+
+ /**
+ * The currently displayed element.
+ *
+ * @type {!hydrolysis.ElementDescriptor}
+ */
+ _activeDescriptor: Object,
+
+ /**
+ * Toggle flag to be used when this element is being displayed in the
+ * Polymer Elements catalog.
+ */
+ _catalog: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true
+ },
+ /**
+ * An optional version string.
+ */
+ version: String,
+
+ /**
+ * The hydrolysis analyzer.
+ *
+ * @type {!hydrolysis.Analyzer}
+ */
+ _analyzer: {
+ type: Object,
+ observer: '_analyzerChanged',
+ },
+ _hydroDesc: {
+ type: Object,
+ observer: '_detectAnalyzer'
+ },
+ _ajaxDesc: {
+ type: Object,
+ observer: '_detectAnalyzer'
+ },
+
+ /** Whether the analyzer is loading source. */
+ _loading: {
+ type: Boolean,
+ observer: '_loadingChanged',
+ },
+ _hydroLoading: {
+ type: Boolean,
+ observer: '_detectLoading'
+ },
+ _ajaxLoading: {
+ type: Boolean,
+ observer: '_detectLoading'
+ },
+
+ /** The complete URL to this component's demo. */
+ _demoUrl: {
+ type: String,
+ value: '',
+ },
+
+ /** The complete URL to this component's source. */
+ _srcUrl: String,
+ },
+
+ ready: function() {
+ var elements = this._loadJson();
+ if (elements) {
+ this.docElements = elements;
+ this._loading = false;
+ } else {
+ // Make sure our change handlers trigger in all cases.
+ if (!this.src && !this._catalog) {
+ this._srcChanged();
+ }
+ }
+ },
+
+ /**
+ * Loads an array of hydrolysis element descriptors (as JSON) from the text
+ * content of this element, if present.
+ *
+ * @return {Array<hydrolysis.ElementDescriptor>} The descriptors, or `null`.
+ */
+ _loadJson: function() {
+ var textContent = '';
+ Array.prototype.forEach.call(Polymer.dom(this).childNodes, function(node) {
+ textContent = textContent + node.textContent;
+ });
+ textContent = textContent.trim();
+ if (textContent === '') return null;
+
+ try {
+ var json = JSON.parse(textContent);
+ if (!Array.isArray(json)) return [];
+ return json;
+ } catch(error) {
+ console.error('Failure when parsing JSON:', textContent, error);
+ throw error;
+ }
+ },
+
+ _srcChanged: function() {
+ var srcUrl;
+ if (this.docSrc) {
+ if (!this.$.ajax.lastRequest || (this.docSrc !== this.$.ajax.lastRequest.url && this.docSrc !== this._lastDocSrc)) {
+ this._ajaxLoading = true;
+ this._ajaxDesc = null;
+ this._activeDescriptor = null;
+ this.$.ajax.generateRequest();
+ }
+ this._lastDocSrc = this.docSrc;
+ return;
+ } else if (this.src) {
+ srcUrl = new URL(this.src, this.base).toString();
+ } else {
+ var base = _baseUrl(this.base);
+ srcUrl = new URL(base.match(/([^\/]*)\/$/)[1] + ".html", base).toString();
+ }
+
+ // Rewrite gh-pages URLs to https://rawgit.com/
+ var match = srcUrl.match(/([^\/\.]+)\.github\.io\/([^\/]+)\/?([^\/]*)$/);
+ if (match) {
+ srcUrl = "https://cdn.rawgit.com/" + match[1] + "/" + match[2] + "/master/" + match[3];
+ }
+
+ this._baseUrl = _baseUrl(srcUrl);
+ this._srcUrl = srcUrl;
+ if (!this._hydroLoading) this.$.analyzer.analyze();
+ },
+
+ _frameSrc: function(view) {
+ if (!view || view.indexOf("demo:") !== 0) return "about:blank";
+ var src = view.split(':')[1];
+ return new URL(src, this.base).toString();
+ },
+
+ _descriptorsChanged: function() {
+ if (this._findDescriptor(this.active)) {
+ this._activeChanged();
+ return;
+ }
+
+ if (this.docElements && this.docElements[0]) {
+ this.active = this.docElements[0].is;
+ } else if (this.docBehaviors && this.docBehaviors[0]) {
+ this.active = this.docBehaviors[0].is;
+ } else {
+ this.active = null;
+ }
+ },
+
+ _findDescriptor: function(name) {
+ if (!this._analyzer) return null;
+
+ var descriptor = this._analyzer.elementsByTagName[name];
+ if (descriptor) return descriptor;
+
+ for (var i = 0; i < this._analyzer.behaviors.length; i++) {
+ if (this._analyzer.behaviors[i].is === name) {
+ return this._analyzer.behaviors[i];
+ }
+ }
+ return null;
+ },
+
+ _activeChanged: function() {
+ this.async(function() { this.$.active.value = this.active; });
+ if (this._analyzer && this._analyzer.elementsByTagName) {
+ this.$.headerPanel.scroller.scrollTop = 0;
+ this._activeDescriptor = this._findDescriptor(this.active);
+ if (this._activeDescriptor) {
+ var hasDemo;
+ var demos = this._activeDescriptor.demos;
+ if (this.view && demos && demos.length) {
+ var parts = this.view.split(':');
+ if (parts[0] == 'demo') {
+ if (parts[1]) {
+ hasDemo = demos.some(function(d, i) {
+ if (d.path == parts[1]) {
+ return true;
+ }
+ });
+ }
+ if (!hasDemo) {
+ this.view = 'demo:' + demos[0].path;
+ hasDemo = true;
+ }
+ }
+ }
+ if (!hasDemo == undefined) {
+ this.view = 'docs';
+ }
+ if (this._activeDescriptor.is && !document.title) {
+ document.title = this._activeDescriptor.is + " documentation";
+ }
+ }
+ this._setDocDemos(this._activeDescriptor ? this._activeDescriptor.demos : []);
+ }
+ },
+
+ _loadingChanged: function() {
+ this.toggleClass('loaded', !this._loading);
+ },
+ _detectLoading: function() {
+ this._loading = this.docSrc ? this._ajaxLoading : this._hydroLoading;
+ },
+
+ _analyzerChanged: function() {
+ this._setDocElements(this._analyzer ? this._analyzer.elements : []);
+ this._setDocBehaviors(this._analyzer ? this._analyzer.behaviors : []);
+ },
+ _detectAnalyzer: function() {
+ this._analyzer = this.docSrc ? this._ajaxDesc : this._hydroDesc;
+ },
+
+ _handleAjaxResponse: function(e, req) {
+ this._ajaxLoading = false;
+ this._ajaxLastUrl = req.url;
+ this._ajaxDesc = req.response;
+ },
+
+ _handleComponentSelectedEvent: function(ev) {
+ var descriptor = this._findDescriptor(ev.detail);
+ if (!descriptor) {
+ console.warn("Could not navigate to ", ev.detail);
+ }
+ else {
+ this.active = ev.detail;
+ }
+ },
+
+ /**
+ * Renders this element into static HTML for offline use.
+ *
+ * This is mostly useful for debugging and one-off documentation generation.
+ * If you want to integrate doc generation into your build process, you
+ * probably want to be calling `hydrolysis.Analyzer.analyze()` directly.
+ *
+ * @return {string} The HTML for this element with all state baked in.
+ */
+ marshal: function() {
+ var jsonText = JSON.stringify(this.docElements || [], null, ' ');
+ return '<' + this.is + '>\n' +
+ jsonText.replace(/</g, '<').replace(/>/g, '>') + '\n' +
+ '</' + this.is + '>';
+ },
+
+ _demoView: function(path) {
+ return "demo:" + path;
+ },
+ _viewType: function(view) {
+ return view ? view.split(":")[0] : null;
+ }
+ });
+})();
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-component-page/test/index.html b/polymer_1.0.4/bower_components/iron-component-page/test/index.html
new file mode 100644
index 0000000..77a3705
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-component-page/test/index.html
@@ -0,0 +1,28 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>Tests</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ </head>
+
+ <body>
+ <script>
+ WCT.loadSuites([
+ 'iron-component-page.html',
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-component-page/test/iron-component-page.html b/polymer_1.0.4/bower_components/iron-component-page/test/iron-component-page.html
new file mode 100644
index 0000000..8b62004
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-component-page/test/iron-component-page.html
@@ -0,0 +1,42 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>iron-component-page</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-component-page.html">
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <iron-component-page src="test-element.html"></iron-component-page>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('active-state', function() {
+
+ var testElement;
+
+ setup(function() {
+ testElement = fixture('basic');
+ });
+
+ });
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-component-page/test/test-element.html b/polymer_1.0.4/bower_components/iron-component-page/test/test-element.html
new file mode 100644
index 0000000..2d1cd3a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-component-page/test/test-element.html
@@ -0,0 +1,20 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<dom-module id="test-element">
+
+ <script>
+
+ Polymer({
+
+ });
+
+ </script>
+
+</dom-module>
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-doc-viewer/.bower.json b/polymer_1.0.4/bower_components/iron-doc-viewer/.bower.json
new file mode 100644
index 0000000..2de5cf6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-doc-viewer/.bower.json
@@ -0,0 +1,46 @@
+{
+ "name": "iron-doc-viewer",
+ "version": "1.0.3",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "Elements for rendering Polymer component documentation.",
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-doc-viewer.git"
+ },
+ "main": "iron-doc-viewer.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-doc-viewer/",
+ "ignore": [
+ "/.*",
+ "/tests/"
+ ],
+ "dependencies": {
+ "marked-element": "PolymerElements/marked-element#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "paper-button": "PolymerElements/paper-button#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0",
+ "prism-element": "PolymerElements/prism-element#^1.0.2"
+ },
+ "devDependencies": {
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "web-component-tester": "*"
+ },
+ "_release": "1.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.3",
+ "commit": "034967a91951954b1de9f01559093b15b3b9c86d"
+ },
+ "_source": "git://github.com/PolymerElements/iron-doc-viewer.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-doc-viewer"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-doc-viewer/README.md b/polymer_1.0.4/bower_components/iron-doc-viewer/README.md
new file mode 100644
index 0000000..cf45c12
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-doc-viewer/README.md
@@ -0,0 +1,3 @@
+# iron-doc-viewer
+
+A suite of elements that render documentation for Polymer components.
diff --git a/polymer_1.0.4/bower_components/iron-doc-viewer/bower.json b/polymer_1.0.4/bower_components/iron-doc-viewer/bower.json
new file mode 100644
index 0000000..2133cd6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-doc-viewer/bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "iron-doc-viewer",
+ "version": "1.0.3",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "Elements for rendering Polymer component documentation.",
+ "keywords": [
+ "web-component",
+ "web-components",
+ "polymer"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-doc-viewer.git"
+ },
+ "main": "iron-doc-viewer.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-doc-viewer/",
+ "ignore": [
+ "/.*",
+ "/tests/"
+ ],
+ "dependencies": {
+ "marked-element": "PolymerElements/marked-element#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "paper-button": "PolymerElements/paper-button#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0",
+ "prism-element": "PolymerElements/prism-element#^1.0.2"
+ },
+ "devDependencies": {
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "web-component-tester": "*"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-doc-viewer/demo/index.html b/polymer_1.0.4/bower_components/iron-doc-viewer/demo/index.html
new file mode 100644
index 0000000..688a7b7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-doc-viewer/demo/index.html
@@ -0,0 +1,126 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title></title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../iron-doc-viewer.html">
+
+ <style>
+ body {
+ margin: 16px;
+ }
+
+ iron-doc-viewer {
+ margin: 0 auto;
+ max-width: 48em;
+ }
+ </style>
+ </head>
+ <body>
+
+ <!-- You can also bake documentation into the doc viewer: -->
+ <iron-doc-viewer></iron-doc-viewer>
+
+ <script>
+ var descriptor = {
+ "properties": [
+ {
+ "name": "marshal",
+ "type": "Function",
+ "desc": "Renders this element into static HTML for offline use.\n\nThis is mostly useful for debugging and one-off documentation generation.\nIf you want to integrate doc generation into your build process, you\nprobably want to be calling `hydrolysis.Analyzer.analyze()` directly.\n",
+ "params": [],
+ "function": true,
+ "return": {
+ "type": "string",
+ "desc": "HTML for this element with all state baked in.\n "
+ }
+ },
+ {
+ "name": "src",
+ "type": "string",
+ "desc": "The URL to an import that declares (or transitively imports) the\nelements that you wish to see documented.\n\nIf the URL is relative, it will be resolved relative to the master\ndocument.\n\nIf you change this value after the `<iron-doc-viewer>` has been\ninstantiated, you must call `load()`.\n ",
+ "published": true
+ },
+ {
+ "name": "transitive",
+ "type": "boolean",
+ "desc": "Whether _all_ dependencies should be loaded and documented.\n\nTurning this on will probably slow down the load process dramatically.\n ",
+ "published": true
+ },
+ {
+ "name": "_activeElement",
+ "type": "!hydrolysis.ElementDescriptor",
+ "desc": "The currently displayed element.\n",
+ "published": true,
+ "private": true
+ },
+ {
+ "name": "_analyzer",
+ "type": "!hydrolysis.Analyzer",
+ "desc": "The hydrolysis analyzer.\n",
+ "published": true,
+ "private": true
+ },
+ {
+ "name": "_analyzerChanged",
+ "type": "Function",
+ "params": [],
+ "private": true,
+ "function": true
+ },
+ {
+ "name": "_loading",
+ "type": "Object",
+ "desc": "Whether the analyzer is loading source. ",
+ "published": true,
+ "private": true
+ },
+ {
+ "name": "_loadingChanged",
+ "type": "Function",
+ "params": [],
+ "private": true,
+ "function": true
+ },
+ {
+ "name": "_onTapNavItem",
+ "type": "Function",
+ "desc": "Activates the element that the user selected.\n",
+ "params": [
+ {
+ "name": "event",
+ "type": "!Event",
+ "desc": null
+ }
+ ],
+ "private": true,
+ "function": true
+ },
+ {
+ "name": "enableCustomStyleProperties",
+ "type": "boolean",
+ "private": true,
+ "configuration": true
+ }
+ ],
+ "is": "doc-demo",
+ "desc": "This is an example of how `iron-doc-viewer` will render various types of\ninformation. You can use it as a style guide to see how various data will be\nrepresented. Markdown is used to format descriptive text throughout.\n\n# Level 1 Heading\n\nThis is a level one heading. **Bold text** and *italic text* are represented\nappropriately. [Links](#) have black underlines.\n\n## Level 2 Heading\n\nThis is a level two heading. `inline code` can be represented.\n\n <html>\n <p>This is a code block. Its syntax is highlighted automatically.</p>\n </html>\n\n### Level 3 Heading\n\nLists can also be used as you'd expect:\n\n* Unordered Lists\n * With Nesting\n* Or without nesting\n\nYou can also use ordered lists:\n\n1. First item\n2. Second item\n\n#### Level 4 Heading\n\nHeadings can be used all the way down to level 5.\n\n##### Level 5 Heading\n\nThis concludes our quick rundown of the various styles that you can commonly use."
+ }
+
+ document.querySelector('iron-doc-viewer').descriptor = descriptor;
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-doc-viewer/index.html b/polymer_1.0.4/bower_components/iron-doc-viewer/index.html
new file mode 100644
index 0000000..95d1991
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-doc-viewer/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-doc-viewer/iron-doc-property.css b/polymer_1.0.4/bower_components/iron-doc-viewer/iron-doc-property.css
new file mode 100644
index 0000000..dc4f210
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-doc-viewer/iron-doc-property.css
@@ -0,0 +1,158 @@
+/*
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+*/
+:host {
+ @apply(--paper-font-body1);
+ box-sizing: border-box;
+ display: block;
+ padding: 16px 24px;
+}
+
+.type:before {
+ content: '\007b'; /* https://github.com/Polymer/polymer/issues/1291 */
+}
+.type:after {
+ content: '\007d'; /* https://github.com/Polymer/polymer/issues/1291 */
+}
+
+#transitionMask {
+ position: relative;
+ overflow: hidden;
+ padding-left: 160px;
+}
+
+[hidden] {
+ display: none;
+}
+
+#signature {
+ @apply(--paper-font-code1);
+ width: 160px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ position: absolute;
+ left: 0;
+ top: 0;
+}
+
+#signature .name {
+ @apply(--paper-font-code2);
+}
+
+:host([function]) #signature {
+ position: static;
+ margin-left: -160px;
+ width: 100%;
+}
+
+:host:not([function]) #signature .params {
+ display: none;
+}
+
+:host([function]) #type {
+ display: none;
+}
+
+#details {
+ flex: 1;
+}
+
+/* Metadata */
+
+#meta {
+ display: flex;
+}
+
+#type {
+ @apply(--paper-font-code1);
+}
+
+#default {
+ flex: 1;
+ text-align: right;
+}
+#default .value {
+ @apply(--paper-font-code1);
+}
+
+/* Function Parameters */
+
+#params {
+ background: rgba(0,0,0,0.05);
+ list-style: none;
+ margin: 8px -8px 0 -8px;
+ padding: 0 8px;
+}
+
+#params .type {
+ @apply(--paper-font-code1);
+}
+
+#params li {
+ padding: 4px 0;
+}
+#params li:first-child {
+ padding-top: 8px;
+}
+#params li:last-child {
+ padding-bottom: 8px;
+}
+
+#params marked-element {
+ display: inline-block;
+}
+#params marked-element::shadow #content p {
+ margin: 0;
+}
+
+/* Description */
+
+#desc {
+ display: block;
+}
+
+#desc::shadow #content > :first-child {
+ margin-top: 0;
+}
+
+#desc::shadow #content > :last-child {
+ margin-bottom: 0;
+}
+
+#desc::shadow #content #content code {
+ @apply(--paper-font-code1);
+}
+
+/* State Transitions */
+
+#transitionMask {
+ transition: height ease-in-out 150ms;
+}
+#meta {
+ transition: opacity ease-in-out 150ms;
+}
+#desc {
+ transition: transform ease-in-out 150ms, opacity ease-in-out 150ms;
+}
+
+/* Collapsed State */
+
+:host([_collapsed]) #transitionMask {
+ height: 20px; /* 1 line of text */
+ overflow: hidden;
+}
+:host([_collapsed]) #meta {
+ opacity: 0;
+}
+:host([_collapsed]) #desc {
+ transform: translateY(-34px);
+}
+:host([_collapsed][function]) #desc {
+ opacity: 0;
+}
diff --git a/polymer_1.0.4/bower_components/iron-doc-viewer/iron-doc-property.html b/polymer_1.0.4/bower_components/iron-doc-viewer/iron-doc-property.html
new file mode 100644
index 0000000..91aa673
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-doc-viewer/iron-doc-property.html
@@ -0,0 +1,193 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../marked-element/marked-element.html">
+<link rel="import" href="../paper-styles/typography.html">
+<link rel="import" href="../polymer/polymer.html">
+
+<!--
+Renders documentation describing a specific property of an element.
+
+Give it a hydrolysis `PropertyDescriptor` (via `descriptor`), and watch it go!
+-->
+<dom-module id="iron-doc-property">
+
+ <link rel="import" type="css" href="iron-doc-property.css">
+
+ <template>
+ <div id="transitionMask">
+ <div id="signature">
+ <span class="name">{{descriptor.name}}</span><span class="params">(<span>{{_paramText}}</span>)</span>
+ <span class="return" hidden$="{{!descriptor.return}}">➙ <span class="type">{{descriptor.return.type}}</span></span>
+ </div>
+ <div id="details">
+ <div id="meta" hidden$="{{_computeHideMeta(descriptor)}}">
+ <span id="type" class="type">{{descriptor.type}}</span>
+ <span id="default" hidden$="{{_computeHideDefault(descriptor.default)}}">default: <span class="value">{{_computeDefaultDisplay(descriptor.default)}}</span></span>
+ <template is="dom-if" if="{{descriptor.readOnly}}"><span> readOnly</span></template>
+ <template is="dom-if" if="{{descriptor.notify}}"><span> notify</span></template>
+ </div>
+ <ol id="params" hidden$="{{_computeHideParams(descriptor,return)}}">
+ <template is="dom-repeat" items="{{descriptor.params}}">
+ <li hidden$="{{!item.type}}">
+ <span class="name">{{item.name}}</span>
+ <span class="type">{{item.type}}</span>
+ <marked-element markdown="{{item.desc}}"></marked-element>
+ </li>
+ </template>
+ <li class="return" hidden$="{{!descriptor.return}}">Returns
+ <span class="type">{{descriptor.return.type}}</span>
+ <marked-element markdown="{{descriptor.return.desc}}"></marked-element>
+ </li>
+ </ol>
+ <marked-element id="desc" markdown="{{descriptor.desc}}" hidden$="{{!descriptor.desc}}"></marked-element>
+ </div>
+ </div>
+ </template>
+
+</dom-module>
+
+<script>
+(function() {
+
+ Polymer({
+
+ is: 'iron-doc-property',
+
+ properties: {
+
+ /**
+ * The [Hydrolysis](https://github.com/PolymerLabs/hydrolysis)-generated
+ * element descriptor to display details for.
+ *
+ * Alternatively, the element descriptor can be provided as JSON via the text content
+ * of this element.
+ *
+ * @type {hydrolysis.PropertyDescriptor}
+ */
+ descriptor: {
+ type: Object,
+ observer: '_descriptorChanged',
+ },
+
+ /**
+ * Whether the property should show a one-liner, or full summary.
+ *
+ * Note that this property _is_ reflected as an attribute, but we perform
+ * the reflection manually. In order to support the CSS transitions, we
+ * must calculate the element height before setting the attribute.
+ */
+ collapsed: {
+ type: Boolean,
+ value: false,
+ observer: '_collapsedChanged',
+ },
+
+ },
+
+ listeners: {
+ 'transitionEnd': '_onTransitionEnd',
+ 'webkitTransitionEnd': '_onTransitionEnd',
+ },
+
+ ready: function() {
+ this._isReady = true;
+ },
+
+ /**
+ * Resets any state that was set up for transitions.
+ *
+ * We are careful to reset our explicit heights after a transition
+ * completes, so that the property doesn't clip values if the user resizes
+ * their viewport.
+ */
+ _onTransitionEnd: function(event) {
+ if (event.path[0] !== this.$.transitionMask) return;
+ this.$.transitionMask.style.height = '';
+ },
+
+ _descriptorChanged: function() {
+ this.toggleAttribute('private', this.descriptor.private);
+ this.toggleAttribute('configuration', this.descriptor.configuration);
+ this.toggleAttribute('function', this.descriptor.function);
+ this._paramText = (this.descriptor.params || []).map(function(param) {
+ return param.name;
+ }).join(', ');
+ },
+
+ /**
+ * Reflects `collapsed` as the `_collapsed` attribute.
+ *
+ * "Why not use `reflectToAttribute: true`?", you ask? A fine question!
+ *
+ * We avoid simple reflection purely because there is no purely declarative
+ * way of transitioning to/from `height: auto`. This callback manages
+ * setting explicit heights for the property so that CSS can interpolate it.
+ *
+ * @see #_onTransitionEnd
+ */
+ _collapsedChanged: function() {
+ if (!this._isReady) {
+ this.toggleAttribute('_collapsed', this.collapsed);
+ return;
+ }
+
+ var container = this.$.transitionMask;
+ var collapsed = this.collapsed;
+
+ // Measure `height: auto`, which we will need regardless of transition
+ // direction. We assume that the collapsed state has an explicit height
+ // set via CSS rules; so we do not bother measuring that.
+ container.style.height = 'auto';
+ var fullHeight = container.offsetHeight;
+
+ // Then, we reset to the start state. Changing directions mid-transition
+ // is _not_ supported!
+ if (this.collapsed) {
+ container.style.height = fullHeight + 'px'; // Height 'auto'.
+ } else {
+ container.style.height = ''; // Height specified by CSS rule.
+ }
+
+ // We must wait a frame so that the transition engine has a chance to know
+ // that something actually changed.
+ requestAnimationFrame(function() {
+ this.toggleAttribute('_collapsed', collapsed);
+ if (this.collapsed) {
+ container.style.height = ''; // Height specified by CSS rule.
+ } else {
+ container.style.height = fullHeight + 'px'; // Height 'auto'.
+ }
+ }.bind(this));
+ },
+
+ // hidden if no type and no defaults
+ _computeHideMeta: function(descriptor) {
+ return descriptor.type === undefined && descriptor.default === undefined;
+ },
+
+ // hidden if no params, and no return value
+ _computeHideParams: function(descriptor,ret) {
+ return (!descriptor.params || descriptor.params.length === 0) && !ret;
+ },
+
+ _computeHideDefault: function(def) {
+ return def === undefined;
+ },
+
+ _computeDefaultDisplay: function(def) {
+ if (def === '')
+ return "''";
+ return def;
+ }
+
+ });
+
+})();
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-doc-viewer/iron-doc-viewer.css b/polymer_1.0.4/bower_components/iron-doc-viewer/iron-doc-viewer.css
new file mode 100644
index 0000000..0e8646c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-doc-viewer/iron-doc-viewer.css
@@ -0,0 +1,151 @@
+/*
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+*/
+:host {
+ @apply(--paper-font-body1);
+ display: block;
+ color: #212121;
+}
+
+:host > header {
+ @apply(--paper-font-headline);
+ margin-bottom: 18px;
+}
+
+[hidden] {
+ display: none !important;
+}
+
+#api {
+ display: flex;
+ align-items: center;
+}
+#api header {
+ flex: 1;
+ padding-left: 16px;
+ @apply(--paper-font-subhead);
+}
+#api a {
+ @apply(--paper-font-button);
+ cursor: pointer;
+ display: block;
+ padding: 4px 16px;
+ color: var(--paper-grey-800);
+}
+
+/* Common Formatting */
+
+#summary {
+ padding: 4px 0;
+}
+
+#summary marked-element::shadow #content pre {
+ background-color: var(--paper-grey-50);
+ border: solid #e5e5e5;
+ border-width: 1px 0;
+ overflow-x: auto;
+ padding: 12px 24px;
+ font-size: 15px;
+}
+
+#summary marked-element::shadow #content table {
+ width: 100%;
+ border-collapse: collapse;
+ margin: 12px 0;
+ border-top: 1px solid #e5e5e5;
+}
+
+#summary marked-element::shadow #content tr {
+ border-bottom: 1px solid #e5e5e5;
+ padding: 0 18px;
+}
+
+#summary marked-element::shadow #content td,
+#summary marked-element::shadow #content th {
+ padding: 6px 12px;
+}
+
+#summary marked-element::shadow #content td:first-child,
+#summary marked-element::shadow #content th:first-child {
+ padding-left: 24px;
+}
+
+#summary marked-element::shadow #content td:last-child,
+#summary marked-element::shadow #content th:last-child {
+ padding-right: 24px;
+}
+
+#summary marked-element::shadow #content code {
+ @apply(--paper-font-code1);
+}
+
+#summary marked-element::shadow #content p {
+ padding: 0 24px;
+}
+
+#summary marked-element::shadow #content a {
+ color: var(--paper-indigo-a200);
+ font-weight: 500;
+ text-decoration: none;
+}
+
+#summary marked-element::shadow #content h1,
+#summary marked-element::shadow #content h2,
+#summary marked-element::shadow #content h3,
+#summary marked-element::shadow #content h4,
+#summary marked-element::shadow #content h5 {
+ padding: 0 18px;
+}
+
+/* Property Sections */
+
+.card {
+ background: white;
+ margin-bottom: 20px;
+ border-radius: 2px;
+ @apply(--shadow-elevation-2dp);
+}
+
+.card > header {
+ padding: 14px 24px;
+ border-bottom: 1px solid #e5e5e5;
+ font-size: 20px;
+ line-height: 28px;
+ font-weight: 400;
+}
+
+iron-doc-property {
+ border-bottom: 1px solid #e5e5e5;
+}
+iron-doc-property:last-of-type {
+ border-bottom-width: 0;
+}
+
+/* Private Properties */
+
+iron-doc-property[private] {
+ display: none;
+}
+
+:host(.show-private) iron-doc-property[private] {
+ display: block;
+}
+
+iron-doc-property[configuration] {
+ display: none !important; /* Never. */
+}
+
+#behaviors > p {
+ border-bottom: 1px solid #e5e5e5;
+ box-sizing: border-box;
+ display: block;
+ padding: 16px 24px;
+ cursor: pointer;
+}
+
diff --git a/polymer_1.0.4/bower_components/iron-doc-viewer/iron-doc-viewer.html b/polymer_1.0.4/bower_components/iron-doc-viewer/iron-doc-viewer.html
new file mode 100644
index 0000000..268aa7c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-doc-viewer/iron-doc-viewer.html
@@ -0,0 +1,237 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../marked-element/marked-element.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+<link rel="import" href="../paper-button/paper-button.html">
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../prism-element/prism-highlighter.html">
+
+<link rel="import" href="iron-doc-property.html">
+
+<!--
+Renders documentation describing an element's API.
+
+`iron-doc-viewer` renders element and behavior descriptions as extracted by
+[Hydrolysis](https://github.com/PolymerLabs/hydrolysis). You can provide them
+either via binding...
+
+ <iron-doc-viewer descriptor="{{elementDescriptor}}"></iron-doc-viewer>
+
+...or by placing the element descriptor in JSON as the text content of an
+`iron-doc-viewer`:
+
+ <iron-doc-viewer>
+ {
+ "is": "awesome-sauce",
+ "properties": [
+ {"name": "isAwesome", "type": "boolean", "desc": "Is it awesome?"},
+ ]
+ }
+ </iron-doc-viewer>
+
+However, be aware that due to current limitations in Polymer 0.8, _changes_ to
+the text content will not be respected, only the initial value will be loaded.
+If you wish to update the documented element, please set it via the `descriptor`
+property.
+
+@demo demo/index.html Basic Demo
+-->
+<dom-module id="iron-doc-viewer">
+
+ <link rel="import" type="css" href="iron-doc-viewer.css">
+
+ <template>
+ <prism-highlighter></prism-highlighter>
+
+ <section id="summary" class="card" hidden$="[[!descriptor.desc]]">
+ <header>Documentation</header>
+ <marked-element markdown="{{descriptor.desc}}"></marked-element>
+ </section>
+
+ <nav id="api">
+ <header>API Reference</header>
+ <paper-button id="togglePrivate"
+ on-tap="_togglePrivate">{{_privateToggleLabel}}</paper-button>
+ </nav>
+
+ <section id="properties" class="card" hidden$="{{_noneToShow(_showPrivate,_properties)}}">
+ <header>Properties</header>
+ <template is="dom-repeat" items="{{_properties}}" hidden$="{{!_properties.length}}">
+ <iron-doc-property descriptor="{{item}}"></iron-doc-property>
+ </template>
+ </section>
+
+ <section id="methods" class="card" hidden$="{{_noneToShow(_showPrivate,_methods)}}">
+ <header>Methods</header>
+ <template is="dom-repeat" items="{{_methods}}">
+ <iron-doc-property descriptor="{{item}}"></iron-doc-property>
+ </template>
+ </section>
+
+ <section id="events" class="card" hidden$="{{_noneToShow(_showPrivate,_events)}}">
+ <header>Events</header>
+ <template is="dom-repeat" items="{{_events}}">
+ <iron-doc-property descriptor="{{item}}"></iron-doc-property>
+ </template>
+ </section>
+
+ <section id="behaviors" class="card" hidden$="{{_hideBehaviors(_behaviors)}}">
+ <header>Behaviors</header>
+ <template is="dom-repeat" items="{{_behaviors}}">
+ <p on-click="_broadcastBehavior">{{item}}</p>
+ </template>
+ </section>
+
+ </template>
+
+</dom-module>
+
+<script>
+(function() {
+
+ Polymer({
+
+ is: 'iron-doc-viewer',
+
+ properties: {
+
+ /**
+ * The [Hydrolysis](https://github.com/PolymerLabs/hydrolysis)-generated
+ * element descriptor to display details for.
+ *
+ * Alternatively, the element descriptor can be provided as JSON via the text content
+ * of this element.
+ *
+ * @type {hydrolysis.ElementDescriptor}
+ */
+ descriptor: {
+ type: Object,
+ observer: '_descriptorChanged',
+ },
+
+ /** Whether private properties should be hidden or shown. */
+ _showPrivate: {
+ type: Boolean,
+ value: false,
+ observer: '_showPrivateChanged',
+ },
+
+ /** The label to show for the Private API toggle. */
+ _privateToggleLabel: String,
+
+ /**
+ * Broadcast when another component is clicked on
+ * @param {String} detail name of the component
+ * iron-doc-viewer container should load component if possible
+ * @event iron-doc-viewer-component-selected
+ */
+ },
+
+ ready: function() {
+ var jsonDescriptor = this._loadJson();
+ // Note that this is only an error during element creation. You are free
+ // to stomp over the descriptor after it is ready.
+ if (jsonDescriptor && this.descriptor) {
+ console.error(
+ this,
+ 'received both a bound descriptor:', this.descriptor,
+ 'and JSON descriptor:', this._jsonDescriptor,
+ 'Please provide only one');
+ throw new Error(
+ '<iron-doc-viewer> accepts either a bound or JSON descriptor; not both');
+ }
+
+ if (jsonDescriptor) {
+ this.descriptor = jsonDescriptor;
+ }
+ },
+
+ /**
+ * Loads a hydrolysis element descriptor (as JSON) from the text content of
+ * this element, if present.
+ *
+ * @return {hydrolysis.ElementDescriptor} The parsed descriptor, or `null`.
+ */
+ _loadJson: function() {
+ var textContent = '';
+ Array.prototype.forEach.call(Polymer.dom(this).childNodes, function(node) {
+ textContent = textContent + node.textContent;
+ });
+ textContent = textContent.trim();
+ if (textContent === '') return null;
+
+ try {
+ return JSON.parse(textContent);
+ } catch(error) {
+ console.error('Failure when parsing JSON:', textContent, error);
+ throw error;
+ }
+ },
+
+ /** Converts `descriptor` into our template-friendly `_model`. */
+ _descriptorChanged: function() {
+ if (!this.descriptor) return;
+
+ // Split the documented properties between functions and other types.
+ var properties = [];
+ var methods = [];
+
+ for (var i = 0, property; property = this.descriptor.properties[i]; i++) {
+ (property.type === 'Function' ? methods : properties).push(property);
+ }
+ this._properties = properties;
+ this._methods = methods;
+ this._events = this.descriptor.events || [];
+ this._behaviors = this.descriptor.behaviors || [];
+
+ this.toggleAttribute('abstract', this.descriptor.abstract);
+ },
+
+ _collapsedChanged: function() {
+ this._collapseToggleLabel = this._collapsed ? 'expand' : 'collapse';
+
+ // Bound values aren't exposed to dom-repeat's scope.
+ var properties = this.querySelectorAll('iron-doc-property');
+ for (var i = 0, property; property = properties[i]; i++) {
+ property.collapsed = this._collapsed;
+ }
+ },
+
+ _toggleCollapsed: function() {
+ this._collapsed = !this._collapsed;
+ },
+
+ _showPrivateChanged: function() {
+ this._privateToggleLabel = (this._showPrivate ? 'hide' : 'show') + ' private API';
+ this.toggleClass('show-private', this._showPrivate);
+ },
+
+ _togglePrivate: function() {
+ this._showPrivate = !this._showPrivate;
+ },
+
+ _noneToShow: function(showPrivate, items) {
+ for (var i = 0; i < items.length; i++) {
+ if (showPrivate || !items[i].private) return false;
+ }
+ return true;
+ },
+
+ _hideBehaviors: function(behaviors) {
+ return behaviors === null || behaviors.length === 0;
+ },
+
+ _broadcastBehavior: function(ev) {
+ this.fire('iron-doc-viewer-component-selected', ev.target._templateInstance.item);
+ }
+ });
+
+})();
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-doc-viewer/test/index.html b/polymer_1.0.4/bower_components/iron-doc-viewer/test/index.html
new file mode 100644
index 0000000..4ed7dbd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-doc-viewer/test/index.html
@@ -0,0 +1,28 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>Tests</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ </head>
+
+ <body>
+ <script>
+ WCT.loadSuites([
+ 'iron-doc-viewer.html',
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-doc-viewer/test/iron-doc-viewer.html b/polymer_1.0.4/bower_components/iron-doc-viewer/test/iron-doc-viewer.html
new file mode 100644
index 0000000..281064c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-doc-viewer/test/iron-doc-viewer.html
@@ -0,0 +1,123 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>Tests</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+
+ <link rel="import" href="../iron-doc-viewer.html">
+ </head>
+ <body>
+
+ <iron-doc-viewer>
+ {
+ "is": "awesome-sauce",
+ "properties": [
+ {"name": "isAwesome", "type": "boolean", "desc": "Is it awesome?"}
+ ]
+ }
+ </iron-doc-viewer>
+
+ <test-fixture id="bound">
+ <template is="dom-template">
+ <iron-doc-viewer descriptor="{{descriptor}}" bound></iron-doc-viewer>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="json">
+ <template is="dom-template">
+ <iron-doc-viewer json>
+ {
+ "is": "awesome-sauce",
+ "properties": [
+ {"name": "isAwesome", "type": "boolean", "desc": "Is it awesome?"}
+ ]
+ }
+ </iron-doc-viewer>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="json-and-bound">
+ <template is="dom-template">
+ <iron-doc-viewer descriptor="{{descriptor}}" jsonbound>
+ {
+ "is": "awesome-sauce",
+ "properties": [
+ {"name": "isAwesome", "type": "boolean", "desc": "Is it awesome?"}
+ ]
+ }
+ </iron-doc-viewer>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ var ELEMENT = {
+ "is": "awesome-sauce",
+ "properties": [
+ {"name": "isAwesome", "type": "boolean", "desc": "Is it awesome?"},
+ ]
+ };
+
+ describe('<iron-doc-viewer>', function() {
+
+ var page;
+ afterEach(function() {
+ page = null; // Make sure that we don't reuse another test's element.
+ });
+
+ describe('with a bound descriptor', function() {
+
+ beforeEach(function() { page = fixture('bound', {descriptor: ELEMENT}); });
+
+ it('loads the descriptor', function() {
+ expect(page.descriptor.is).to.eq('awesome-sauce');
+ expect(page.descriptor.properties.length).to.eq(1);
+ });
+
+ });
+
+ describe('with a JSON descriptor', function() {
+
+ beforeEach(function() { page = fixture('json'); });
+
+ it('loads the descriptor', function() {
+ expect(page.descriptor.is).to.eq('awesome-sauce');
+ expect(page.descriptor.properties.length).to.eq(1);
+ });
+
+ });
+
+ describe('edge cases', function() {
+
+ // TODO(nevir): Cannot enable until https://github.com/Polymer/polymer/issues/1200
+ it.skip('throws when a bound and JSON descriptor are provided', function() {
+ expect(function() {
+ fixture('json-and-bound', {descriptor: ELEMENT});
+ }).to.throw(Error, /descriptor/i);
+ });
+
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-elements/.bower.json b/polymer_1.0.4/bower_components/iron-elements/.bower.json
new file mode 100644
index 0000000..058c648
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-elements/.bower.json
@@ -0,0 +1,73 @@
+{
+ "name": "iron-elements",
+ "version": "1.0.1",
+ "description": "Iron elements are a set of visual and non-visual utility elements. They include elements for working with layout, user input, selection, and scaffolding apps.",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "utility",
+ "user-input",
+ "selection"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-elements.git"
+ },
+ "dependencies": {
+ "iron-a11y-announcer": "PolymerElements/iron-a11y-announcer#^1.0.0",
+ "iron-a11y-keys": "PolymerElements/iron-a11y-keys#^1.0.0",
+ "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0",
+ "iron-ajax": "PolymerElements/iron-ajax#^1.0.0",
+ "iron-autogrow-textarea": "PolymerElements/iron-autogrow-textarea#^1.0.0",
+ "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
+ "iron-collapse": "PolymerElements/iron-collapse#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-doc-viewer": "PolymerElements/iron-doc-viewer#^1.0.0",
+ "iron-fit-behavior": "PolymerElements/iron-fit-behavior#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "iron-form": "PolymerElements/iron-form#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+ "iron-iconset": "PolymerElements/iron-iconset#^1.0.0",
+ "iron-iconset-svg": "PolymerElements/iron-iconset-svg#^1.0.0",
+ "iron-image": "PolymerElements/iron-image#^1.0.0",
+ "iron-input": "PolymerElements/iron-input#^1.0.0",
+ "iron-jsonp-library": "PolymerElements/iron-jsonp-library#^1.0.0",
+ "iron-localstorage": "PolymerElements/iron-localstorage#^1.0.0",
+ "iron-media-query": "PolymerElements/iron-media-query#^1.0.0",
+ "iron-menu-behavior": "PolymerElements/iron-menu-behavior#^1.0.0",
+ "iron-meta": "PolymerElements/iron-meta#^1.0.0",
+ "iron-overlay-behavior": "PolymerElements/iron-overlay-behavior#^1.0.0",
+ "iron-pages": "PolymerElements/iron-pages#^1.0.0",
+ "iron-range-behavior": "PolymerElements/iron-range-behavior#^1.0.0",
+ "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.0",
+ "iron-selector": "PolymerElements/iron-selector#^1.0.0",
+ "iron-signals": "PolymerElements/iron-signals#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "iron-validatable-behavior": "PolymerElements/iron-validatable-behavior#^1.0.0",
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-elements",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "1369897060e0910887cabea6b33869ef563f5cdd"
+ },
+ "_source": "git://github.com/PolymerElements/iron-elements.git",
+ "_target": "~1.0.1",
+ "_originalSource": "PolymerElements/iron-elements",
+ "_direct": true
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-elements/README.md b/polymer_1.0.4/bower_components/iron-elements/README.md
new file mode 100644
index 0000000..b2ad025
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-elements/README.md
@@ -0,0 +1,34 @@
+# iron-elements
+
+Basic building blocks for creating an application. Most of the `iron` elements were previously named the `core` elements, when compatible with the "Developer Preview" version of the Polymer library.
+
+## Roadmap
+
+### Elements in progress
+
+* `iron-list` - the upgraded version of a virtualized infinite list, previously named `core-list`. ETA: Couple weeks.
+
+### Elements planned
+_Elements we're planning on building soon but haven't started yet_
+
+* `iron-label` - still looking for the right way to bring what used to be `core-label` into the 1.0 world.
+
+### Elements not planned, notably
+_Elements we're not planning on building as part of this product line, but that one might be wondering about_
+
+A number of elements existed as `core` elements that are not in this product line:
+* `core-action-icons` - This wasn't really an element, and wasn't particularly heavily used.
+* `core-animation` - The animation-related elements that were part of core will be created as part of the `neon` product line.
+* `core-docs` - Deprecated: use [`iron-doc-viewer`](https://github.com/polymerelements/iron-doc-viewer).
+* `core-drag-drop` - Not currently working on.
+* `core-dropdown` and `core-dropdown-menu` - These were confusing UI to have in `core`, so we've moved them to the `paper` element set for now and made them easier to customize. More on the thought process behind this change in the [blog](https://blog.polymer-project.org/announcements/2015/05/14/updated-elements/).
+* `core-focusable` - This has been re-implemented using Polymer behaviors - see for example the `paper-radio-button-behavior` in [`paper-behaviors`](https://github.com/PolymerElements/paper-behaviors).
+* `core-item` - This had UI opinion, so was re-implemented as [`paper-item`](https://github.com/polymerelements/paper-item).
+* `core-layout` - We're working on more stable, consistent layout elements.
+* `core-overlay` - This is re-implemented as a behavior, in [`iron-overlay-behavior`](https://github.com/polymerelements/iron-overlay-behavior).
+* `core-popup-menu` - This element wasn't particularly of unique value, so we're putting it away for now.
+* `core-scroll-header-panel` - This had UI opinion, so it's been moved to [`paper-scroll-header-panel`](https://github.com/polymerelements/paper-scroll-header-panel).
+* `core-splitter` - This element was relatively trivial, so we've put it off for now.
+* `core-style` - This element is not useful with Polymer's new styling system. Check out the latest docs for more.
+* `core-tooltip` - This will become `paper-tooltip`.
+* `core-menu` - This had UI opinion, and will become `paper-dropdown-menu`.
diff --git a/polymer_1.0.4/bower_components/iron-elements/bower.json b/polymer_1.0.4/bower_components/iron-elements/bower.json
new file mode 100644
index 0000000..0d9292c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-elements/bower.json
@@ -0,0 +1,63 @@
+{
+ "name": "iron-elements",
+ "version": "1.0.1",
+ "description": "Iron elements are a set of visual and non-visual utility elements. They include elements for working with layout, user input, selection, and scaffolding apps.",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "utility",
+ "user-input",
+ "selection"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-elements.git"
+ },
+ "dependencies": {
+ "iron-a11y-announcer": "PolymerElements/iron-a11y-announcer#^1.0.0",
+ "iron-a11y-keys": "PolymerElements/iron-a11y-keys#^1.0.0",
+ "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0",
+ "iron-ajax": "PolymerElements/iron-ajax#^1.0.0",
+ "iron-autogrow-textarea": "PolymerElements/iron-autogrow-textarea#^1.0.0",
+ "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
+ "iron-collapse": "PolymerElements/iron-collapse#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-doc-viewer": "PolymerElements/iron-doc-viewer#^1.0.0",
+ "iron-fit-behavior": "PolymerElements/iron-fit-behavior#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "iron-form": "PolymerElements/iron-form#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+ "iron-iconset": "PolymerElements/iron-iconset#^1.0.0",
+ "iron-iconset-svg": "PolymerElements/iron-iconset-svg#^1.0.0",
+ "iron-image": "PolymerElements/iron-image#^1.0.0",
+ "iron-input": "PolymerElements/iron-input#^1.0.0",
+ "iron-jsonp-library": "PolymerElements/iron-jsonp-library#^1.0.0",
+ "iron-localstorage": "PolymerElements/iron-localstorage#^1.0.0",
+ "iron-media-query": "PolymerElements/iron-media-query#^1.0.0",
+ "iron-menu-behavior": "PolymerElements/iron-menu-behavior#^1.0.0",
+ "iron-meta": "PolymerElements/iron-meta#^1.0.0",
+ "iron-overlay-behavior": "PolymerElements/iron-overlay-behavior#^1.0.0",
+ "iron-pages": "PolymerElements/iron-pages#^1.0.0",
+ "iron-range-behavior": "PolymerElements/iron-range-behavior#^1.0.0",
+ "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.0",
+ "iron-selector": "PolymerElements/iron-selector#^1.0.0",
+ "iron-signals": "PolymerElements/iron-signals#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "iron-validatable-behavior": "PolymerElements/iron-validatable-behavior#^1.0.0",
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-elements",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ]
+}
diff --git a/polymer_1.0.4/bower_components/iron-fit-behavior/.bower.json b/polymer_1.0.4/bower_components/iron-fit-behavior/.bower.json
new file mode 100644
index 0000000..5432d31
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-fit-behavior/.bower.json
@@ -0,0 +1,42 @@
+{
+ "name": "iron-fit-behavior",
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Fits an element inside another element",
+ "private": true,
+ "main": [
+ "iron-fit-behavior.html"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "behavior"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-fit-behavior.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-fit-behavior",
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "f82ad74c34aeadff247bcc224c0e07b1c0be4d86"
+ },
+ "_source": "git://github.com/PolymerElements/iron-fit-behavior.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-fit-behavior"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-fit-behavior/.gitignore b/polymer_1.0.4/bower_components/iron-fit-behavior/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-fit-behavior/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-fit-behavior/README.md b/polymer_1.0.4/bower_components/iron-fit-behavior/README.md
new file mode 100644
index 0000000..8f4fc76
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-fit-behavior/README.md
@@ -0,0 +1,3 @@
+# iron-fit-behavior
+
+Fits an element in the window, or another element.
diff --git a/polymer_1.0.4/bower_components/iron-fit-behavior/bower.json b/polymer_1.0.4/bower_components/iron-fit-behavior/bower.json
new file mode 100644
index 0000000..fdc80c2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-fit-behavior/bower.json
@@ -0,0 +1,32 @@
+{
+ "name": "iron-fit-behavior",
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Fits an element inside another element",
+ "private": true,
+ "main": [
+ "iron-fit-behavior.html"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "behavior"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-fit-behavior.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-fit-behavior/demo/index.html b/polymer_1.0.4/bower_components/iron-fit-behavior/demo/index.html
new file mode 100644
index 0000000..b841def
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-fit-behavior/demo/index.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>iron-fit-behavior demo</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link href="../../paper-styles/demo-pages.html" rel="import">
+ <link rel="import" href="simple-fit.html">
+
+ <style>
+
+ .sized {
+ width: 50%;
+ height: 50%;
+ }
+
+ </style>
+
+ </head>
+ <body unresolved>
+
+ <simple-fit auto-fit-on-attach class="sized">
+ centered in window
+ </simple-fit>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-fit-behavior/demo/simple-fit.html b/polymer_1.0.4/bower_components/iron-fit-behavior/demo/simple-fit.html
new file mode 100644
index 0000000..950ee3f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-fit-behavior/demo/simple-fit.html
@@ -0,0 +1,50 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../iron-fit-behavior.html">
+<link rel="import" href="../../paper-styles/paper-styles.html">
+
+<dom-module id="simple-fit">
+
+ <style>
+ :host {
+ @apply(--layout);
+
+ background-color: var(--paper-light-blue-500);
+ color: white;
+ text-align: center;
+
+ align-items:center;
+ -webkit-align-items: center;
+
+ justify-content:center;
+ -webkit-justify-content:center;
+ }
+ </style>
+
+ <template>
+ <content></content>
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'simple-fit',
+
+ behaviors: [
+ Polymer.IronFitBehavior
+ ]
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-fit-behavior/index.html b/polymer_1.0.4/bower_components/iron-fit-behavior/index.html
new file mode 100644
index 0000000..5ffa7d6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-fit-behavior/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>iron-fit-behavior</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-fit-behavior/iron-fit-behavior.html b/polymer_1.0.4/bower_components/iron-fit-behavior/iron-fit-behavior.html
new file mode 100644
index 0000000..887b7db
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-fit-behavior/iron-fit-behavior.html
@@ -0,0 +1,236 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+
+/**
+Polymer.IronFitBehavior fits an element in another element using `max-height` and `max-width`, and
+optionally centers it in the window or another element.
+
+The element will only be sized and/or positioned if it has not already been sized and/or positioned
+by CSS.
+
+CSS properties | Action
+-----------------------------|-------------------------------------------
+`position` set | Element is not centered horizontally or vertically
+`top` or `bottom` set | Element is not vertically centered
+`left` or `right` set | Element is not horizontally centered
+`max-height` or `height` set | Element respects `max-height` or `height`
+`max-width` or `width` set | Element respects `max-width` or `width`
+
+@demo demo/index.html
+@polymerBehavior
+*/
+
+ Polymer.IronFitBehavior = {
+
+ properties: {
+
+ /**
+ * The element that will receive a `max-height`/`width`. By default it is the same as `this`,
+ * but it can be set to a child element. This is useful, for example, for implementing a
+ * scrolling region inside the element.
+ * @type {!Element}
+ */
+ sizingTarget: {
+ type: Object,
+ value: function() {
+ return this;
+ }
+ },
+
+ /**
+ * The element to fit `this` into.
+ */
+ fitInto: {
+ type: Object,
+ value: window
+ },
+
+ /**
+ * Set to true to auto-fit on attach.
+ */
+ autoFitOnAttach: {
+ type: Boolean,
+ value: false
+ },
+
+ /** @type {?Object} */
+ _fitInfo: {
+ type: Object
+ }
+
+ },
+
+ get _fitWidth() {
+ var fitWidth;
+ if (this.fitInto === window) {
+ fitWidth = this.fitInto.innerWidth;
+ } else {
+ fitWidth = this.fitInto.getBoundingClientRect().width;
+ }
+ return fitWidth;
+ },
+
+ get _fitHeight() {
+ var fitHeight;
+ if (this.fitInto === window) {
+ fitHeight = this.fitInto.innerHeight;
+ } else {
+ fitHeight = this.fitInto.getBoundingClientRect().height;
+ }
+ return fitHeight;
+ },
+
+ attached: function() {
+ if (this.autoFitOnAttach) {
+ if (window.getComputedStyle(this).display === 'none') {
+ setTimeout(function() {
+ this.fit();
+ }.bind(this));
+ } else {
+ this.fit();
+ }
+ }
+ },
+
+ /**
+ * Fits and optionally centers the element into the window, or `fitInfo` if specified.
+ */
+ fit: function() {
+ this._discoverInfo();
+ this.constrain();
+ this.center();
+ },
+
+ /**
+ * Memoize information needed to position and size the target element.
+ */
+ _discoverInfo: function() {
+ if (this._fitInfo) {
+ return;
+ }
+ var target = window.getComputedStyle(this);
+ var sizer = window.getComputedStyle(this.sizingTarget);
+ this._fitInfo = {
+ inlineStyle: {
+ top: this.style.top || '',
+ left: this.style.left || ''
+ },
+ positionedBy: {
+ vertically: target.top !== 'auto' ? 'top' : (target.bottom !== 'auto' ?
+ 'bottom' : null),
+ horizontally: target.left !== 'auto' ? 'left' : (target.right !== 'auto' ?
+ 'right' : null),
+ css: target.position
+ },
+ sizedBy: {
+ height: sizer.maxHeight !== 'none',
+ width: sizer.maxWidth !== 'none'
+ },
+ margin: {
+ top: parseInt(target.marginTop, 10) || 0,
+ right: parseInt(target.marginRight, 10) || 0,
+ bottom: parseInt(target.marginBottom, 10) || 0,
+ left: parseInt(target.marginLeft, 10) || 0
+ }
+ };
+ },
+
+ /**
+ * Resets the target element's position and size constraints, and clear
+ * the memoized data.
+ */
+ resetFit: function() {
+ if (!this._fitInfo || !this._fitInfo.sizedBy.height) {
+ this.sizingTarget.style.maxHeight = '';
+ this.style.top = this._fitInfo ? this._fitInfo.inlineStyle.top : '';
+ }
+ if (!this._fitInfo || !this._fitInfo.sizedBy.width) {
+ this.sizingTarget.style.maxWidth = '';
+ this.style.left = this._fitInfo ? this._fitInfo.inlineStyle.left : '';
+ }
+ if (this._fitInfo) {
+ this.style.position = this._fitInfo.positionedBy.css;
+ }
+ this._fitInfo = null;
+ },
+
+ /**
+ * Equivalent to calling `resetFit()` and `fit()`. Useful to call this after the element,
+ * the window, or the `fitInfo` element has been resized.
+ */
+ refit: function() {
+ this.resetFit();
+ this.fit();
+ },
+
+ /**
+ * Constrains the size of the element to the window or `fitInfo` by setting `max-height`
+ * and/or `max-width`.
+ */
+ constrain: function() {
+ var info = this._fitInfo;
+ // position at (0px, 0px) if not already positioned, so we can measure the natural size.
+ if (!this._fitInfo.positionedBy.vertically) {
+ this.style.top = '0px';
+ }
+ if (!this._fitInfo.positionedBy.horizontally) {
+ this.style.left = '0px';
+ }
+ // need border-box for margin/padding
+ this.sizingTarget.style.boxSizing = 'border-box';
+ // constrain the width and height if not already set
+ var rect = this.getBoundingClientRect();
+ if (!info.sizedBy.height) {
+ this._sizeDimension(rect, info.positionedBy.vertically, 'top', 'bottom', 'Height');
+ }
+ if (!info.sizedBy.width) {
+ this._sizeDimension(rect, info.positionedBy.horizontally, 'left', 'right', 'Width');
+ }
+ },
+
+ _sizeDimension: function(rect, positionedBy, start, end, extent) {
+ var info = this._fitInfo;
+ var max = extent === 'Width' ? this._fitWidth : this._fitHeight;
+ var flip = (positionedBy === end);
+ var offset = flip ? max - rect[end] : rect[start];
+ var margin = info.margin[flip ? start : end];
+ var offsetExtent = 'offset' + extent;
+ var sizingOffset = this[offsetExtent] - this.sizingTarget[offsetExtent];
+ this.sizingTarget.style['max' + extent] = (max - margin - offset - sizingOffset) + 'px';
+ },
+
+ /**
+ * Centers horizontally and vertically if not already positioned. This also sets
+ * `position:fixed`.
+ */
+ center: function() {
+ if (!this._fitInfo.positionedBy.vertically || !this._fitInfo.positionedBy.horizontally) {
+ // need position:fixed to center
+ this.style.position = 'fixed';
+ }
+ if (!this._fitInfo.positionedBy.vertically) {
+ var top = (this._fitHeight - this.offsetHeight) / 2;
+ top -= this._fitInfo.margin.top;
+ this.style.top = top + 'px';
+ }
+ if (!this._fitInfo.positionedBy.horizontally) {
+ var left = (this._fitWidth - this.offsetWidth) / 2;
+ left -= this._fitInfo.margin.left;
+ this.style.left = left + 'px';
+ }
+ }
+
+ };
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-fit-behavior/test/index.html b/polymer_1.0.4/bower_components/iron-fit-behavior/test/index.html
new file mode 100644
index 0000000..5c3084c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-fit-behavior/test/index.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>iron-fit-behavior tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'iron-fit-behavior.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-fit-behavior/test/iron-fit-behavior.html b/polymer_1.0.4/bower_components/iron-fit-behavior/test/iron-fit-behavior.html
new file mode 100644
index 0000000..988e8a5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-fit-behavior/test/iron-fit-behavior.html
@@ -0,0 +1,339 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>iron-fit-behavior tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="test-fit.html">
+
+ <style>
+ body {
+ margin: 0;
+ padding: 0;
+ }
+
+ .absolute {
+ position: absolute;
+ top: 0;
+ left: 0;
+ }
+
+ .scrolling {
+ overflow: auto;
+ }
+
+ .sized-x {
+ width: 200px;
+ }
+
+ .sized-y {
+ height: 200px;
+ }
+
+ .positioned-left {
+ position: absolute;
+ left: 100px;
+ }
+
+ .positioned-right {
+ position: absolute;
+ right: 100px;
+ }
+
+ .positioned-top {
+ position: absolute;
+ top: 100px;
+ }
+
+ .positioned-bottom {
+ position: absolute;
+ bottom: 100px;
+ }
+
+ .with-max-width {
+ max-width: 500px;
+ }
+
+ .with-max-height {
+ max-height: 500px;
+ }
+
+ .with-margin {
+ margin: 20px;
+ }
+
+ </style>
+
+ </head>
+ <body>
+
+ <test-fixture id="absolute">
+ <template>
+ <test-fit auto-fit-on-attach class="absolute">
+ Absolutely positioned
+ </test-fit>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="sized-xy">
+ <template>
+ <test-fit auto-fit-on-attach class="sized-x sized-y">
+ Sized (x/y), auto center/center
+ </test-fit>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="sized-x">
+ <template>
+ <test-fit auto-fit-on-attach class="sized-x">
+ Sized (x), auto center/center
+ </test-fit>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="positioned-xy">
+ <template>
+ <test-fit auto-fit-on-attach class="sized-x positioned-left positioned-top">
+ Sized (x/y), positioned/positioned
+ </test-fit>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="inline-positioned-xy">
+ <template>
+ <test-fit auto-fit-on-attach class="sized-x sized-y" style="position:absolute;left:100px;top:100px;">
+ Sized (x/y), positioned/positioned
+ </test-fit>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="sectioned">
+ <template>
+ <test-fit auto-fit-on-attach class="sized-x">
+ <div>
+ Sized (x), auto center/center with scrolling section
+ </div>
+ <div class="internal"></div>
+ </test-fit>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="constrain-target">
+ <template>
+ <div class="constrain" style="position: fixed; top: 0; left: 0; width: 50vw; height: 50vh; border: 1px solid black;">
+ <test-fit auto-fit-on-attach class="el">
+ <div>
+ Auto center/center to parent element
+ </div>
+ </test-fit>
+ </div>
+ </template>
+ </test-fixture>
+
+ <template id="ipsum">
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ </template>
+
+ <script>
+
+ function makeScrolling(el) {
+ el.classList.add('scrolling');
+ var template = document.getElementById('ipsum');
+ for (var i = 0; i < 20; i++) {
+ el.appendChild(template.content.cloneNode(true));
+ }
+ }
+
+ suite('manual positioning', function() {
+
+ test('css positioned element is not re-positioned', function() {
+ var el = fixture('positioned-xy');
+ var rect = el.getBoundingClientRect();
+ assert.equal(rect.top, 100, 'top is unset');
+ assert.equal(rect.left, 100, 'left is unset');
+
+ });
+
+ test('inline positioned element is not re-positioned', function() {
+ var el = fixture('inline-positioned-xy');
+ var rect = el.getBoundingClientRect();
+ // need to measure document.body here because mocha sets a min-width on html,body, and
+ // the element is positioned wrt to that by css
+ var bodyRect = document.body.getBoundingClientRect();
+ assert.equal(rect.top, 100, 'top is unset');
+ assert.equal(rect.left, 100, 'left is unset');
+
+ el.refit();
+
+ rect = el.getBoundingClientRect();
+ assert.equal(rect.top, 100, 'top is unset after refit');
+ assert.equal(rect.left, 100, 'left is unset after refit');
+
+ });
+
+ test('position property is preserved after', function() {
+ var el = fixture('absolute');
+ assert.equal(getComputedStyle(el).position, 'absolute', 'position:absolute is preserved');
+ });
+ });
+
+ suite('fit to window', function() {
+
+ test('sized element is centered in viewport', function() {
+ var el = fixture('sized-xy');
+ var rect = el.getBoundingClientRect();
+ assert.closeTo(rect.left - (window.innerWidth - rect.right), 0, 5, 'centered horizontally');
+ assert.closeTo(rect.top - (window.innerHeight - rect.bottom), 0, 5, 'centered vertically');
+ });
+
+ test('sized element with margin is centered in viewport', function() {
+ var el = fixture('sized-xy');
+ el.classList.add('with-margin');
+ el.refit();
+ var rect = el.getBoundingClientRect();
+ assert.closeTo(rect.left - (window.innerWidth - rect.right), 0, 5, 'centered horizontally');
+ assert.closeTo(rect.top - (window.innerHeight - rect.bottom), 0, 5, 'centered vertically');
+ });
+
+ test('scrolling element is centered in viewport', function() {
+ var el = fixture('sized-x');
+ makeScrolling(el);
+ el.refit();
+ var rect = el.getBoundingClientRect();
+ assert.closeTo(rect.left - (window.innerWidth - rect.right), 0, 5, 'centered horizontally');
+ assert.closeTo(rect.top - (window.innerHeight - rect.bottom), 0, 5, 'centered vertically');
+ });
+
+ test('scrolling element is constrained to viewport height', function() {
+ var el = fixture('sized-x');
+ makeScrolling(el);
+ el.refit();
+ var rect = el.getBoundingClientRect();
+ assert.isTrue(rect.height <= window.innerHeight, 'height is less than or equal to viewport height');
+ });
+
+ test('scrolling element with max-height is centered in viewport', function() {
+ var el = fixture('sized-x');
+ el.classList.add('with-max-height');
+ makeScrolling(el);
+ el.refit();
+ var rect = el.getBoundingClientRect();
+ assert.closeTo(rect.left - (window.innerWidth - rect.right), 0, 5, 'centered horizontally');
+ assert.closeTo(rect.top - (window.innerHeight - rect.bottom), 0, 5, 'centered vertically');
+ });
+
+ test('scrolling element with max-height respects max-height', function() {
+ var el = fixture('sized-x');
+ el.classList.add('with-max-height');
+ makeScrolling(el);
+ el.refit();
+ var rect = el.getBoundingClientRect();
+ assert.isTrue(rect.height <= 500, 'height is less than or equal to max-height');
+ });
+
+ test('css positioned, scrolling element is constrained to viewport height (top,left)', function() {
+ var el = fixture('positioned-xy');
+ makeScrolling(el);
+ el.refit();
+ var rect = el.getBoundingClientRect();
+ assert.isTrue(rect.height <= window.innerHeight - 100, 'height is less than or equal to viewport height');
+ });
+
+ test('css positioned, scrolling element is constrained to viewport height (bottom, right)', function() {
+ var el = fixture('sized-x');
+ el.classList.add('positioned-bottom');
+ el.classList.add('positioned-right');
+ el.refit();
+ var rect = el.getBoundingClientRect();
+ assert.isTrue(rect.height <= window.innerHeight - 100, 'height is less than or equal to viewport height');
+ });
+
+ test('sized, scrolling element with margin is centered in viewport', function() {
+ var el = fixture('sized-x');
+ el.classList.add('with-margin');
+ makeScrolling(el);
+ el.refit();
+ var rect = el.getBoundingClientRect();
+ assert.closeTo(rect.left - (window.innerWidth - rect.right), 0, 5, 'centered horizontally');
+ assert.closeTo(rect.top - (window.innerHeight - rect.bottom), 0, 5, 'centered vertically');
+ });
+
+ test('sized, scrolling element is constrained to viewport height', function() {
+ var el = fixture('sized-x');
+ el.classList.add('with-margin');
+ makeScrolling(el);
+ el.refit();
+ var rect = el.getBoundingClientRect();
+ assert.isTrue(rect.height <= window.innerHeight - 20 * 2, 'height is less than or equal to viewport height');
+ });
+
+ test('css positioned, scrolling element with margin is constrained to viewport height (top, left)', function() {
+ var el = fixture('positioned-xy');
+ el.classList.add('with-margin');
+ makeScrolling(el);
+ el.refit();
+ var rect = el.getBoundingClientRect();
+ assert.isTrue(rect.height <= window.innerHeight - 100 - 20 * 2, 'height is less than or equal to viewport height');
+ });
+
+ test('css positioned, scrolling element with margin is constrained to viewport height (bottom, right)', function() {
+ var el = fixture('sized-x');
+ el.classList.add('positioned-bottom');
+ el.classList.add('positioned-right');
+ el.classList.add('with-margin')
+ el.refit();
+ var rect = el.getBoundingClientRect();
+ assert.isTrue(rect.height <= window.innerHeight - 100 - 20 * 2, 'height is less than or equal to viewport height');
+ });
+
+ test('scrolling sizingTarget is constrained to viewport height', function() {
+ el = fixture('sectioned');
+ var internal = Polymer.dom(el).querySelector('.internal');
+ el.sizingTarget = internal;
+ makeScrolling(internal);
+ el.refit();
+ var rect = el.getBoundingClientRect();
+ assert.isTrue(rect.height <= window.innerHeight, 'height is less than or equal to viewport height');
+ });
+
+ });
+
+ suite('fit to element', function() {
+
+ test('element fits in another element', function() {
+ var constrain = fixture('constrain-target');
+ var el = Polymer.dom(constrain).querySelector('.el')
+ makeScrolling(el);
+ el.fitInto = constrain;
+ el.refit();
+ var rect = el.getBoundingClientRect();
+ var crect = constrain.getBoundingClientRect();
+ assert.isTrue(rect.height <= crect.height, 'width is less than or equal to fitInto width');
+ assert.isTrue(rect.height <= crect.height, 'height is less than or equal to fitInto height');
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-fit-behavior/test/test-fit.html b/polymer_1.0.4/bower_components/iron-fit-behavior/test/test-fit.html
new file mode 100644
index 0000000..b8768fe
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-fit-behavior/test/test-fit.html
@@ -0,0 +1,42 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../iron-fit-behavior.html">
+
+<dom-module id="test-fit">
+
+ <style>
+ :host {
+ display: block;
+ background: black;
+ color: white;
+ padding: 8px;
+ }
+ </style>
+
+ <template>
+ <content></content>
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'test-fit',
+
+ behaviors: [
+ Polymer.IronFitBehavior
+ ]
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-flex-layout/.bower.json b/polymer_1.0.4/bower_components/iron-flex-layout/.bower.json
new file mode 100644
index 0000000..98650a2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-flex-layout/.bower.json
@@ -0,0 +1,36 @@
+{
+ "name": "iron-flex-layout",
+ "version": "1.0.2",
+ "description": "Provide flexbox-based layouts",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "layout"
+ ],
+ "private": true,
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-flex-layout.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-flex-layout",
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "50bcecf40ab23caa7c2cd90030555e00c5ba7154"
+ },
+ "_source": "git://github.com/PolymerElements/iron-flex-layout.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-flex-layout"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-flex-layout/.gitignore b/polymer_1.0.4/bower_components/iron-flex-layout/.gitignore
new file mode 100644
index 0000000..1eb1fa5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-flex-layout/.gitignore
@@ -0,0 +1,2 @@
+bower_components
+
diff --git a/polymer_1.0.4/bower_components/iron-flex-layout/README.md b/polymer_1.0.4/bower_components/iron-flex-layout/README.md
new file mode 100644
index 0000000..895ed0f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-flex-layout/README.md
@@ -0,0 +1,4 @@
+iron-flex-layout
+================
+
+Layout styles for the iron elements.
diff --git a/polymer_1.0.4/bower_components/iron-flex-layout/bower.json b/polymer_1.0.4/bower_components/iron-flex-layout/bower.json
new file mode 100644
index 0000000..202fbe0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-flex-layout/bower.json
@@ -0,0 +1,26 @@
+{
+ "name": "iron-flex-layout",
+ "version": "1.0.2",
+ "description": "Provide flexbox-based layouts",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "layout"
+ ],
+ "private": true,
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-flex-layout.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-flex-layout/classes/iron-flex-layout.html b/polymer_1.0.4/bower_components/iron-flex-layout/classes/iron-flex-layout.html
new file mode 100644
index 0000000..283c2a8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-flex-layout/classes/iron-flex-layout.html
@@ -0,0 +1,307 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="iron-shadow-flex-layout.html">
+
+<style>
+
+ /*******************************
+ Flex Layout
+ *******************************/
+
+ .layout.horizontal,
+ .layout.horizontal-reverse,
+ .layout.vertical,
+ .layout.vertical-reverse {
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+ }
+
+ .layout.inline {
+ display: -ms-inline-flexbox;
+ display: -webkit-inline-flex;
+ display: inline-flex;
+ }
+
+ .layout.horizontal {
+ -ms-flex-direction: row;
+ -webkit-flex-direction: row;
+ flex-direction: row;
+ }
+
+ .layout.horizontal-reverse {
+ -ms-flex-direction: row-reverse;
+ -webkit-flex-direction: row-reverse;
+ flex-direction: row-reverse;
+ }
+
+ .layout.vertical {
+ -ms-flex-direction: column;
+ -webkit-flex-direction: column;
+ flex-direction: column;
+ }
+
+ .layout.vertical-reverse {
+ -ms-flex-direction: column-reverse;
+ -webkit-flex-direction: column-reverse;
+ flex-direction: column-reverse;
+ }
+
+ .layout.wrap {
+ -ms-flex-wrap: wrap;
+ -webkit-flex-wrap: wrap;
+ flex-wrap: wrap;
+ }
+
+ .layout.wrap-reverse {
+ -ms-flex-wrap: wrap-reverse;
+ -webkit-flex-wrap: wrap-reverse;
+ flex-wrap: wrap-reverse;
+ }
+
+ .flex-auto {
+ -ms-flex: 1 1 auto;
+ -webkit-flex: 1 1 auto;
+ flex: 1 1 auto;
+ }
+
+ .flex-none {
+ -ms-flex: none;
+ -webkit-flex: none;
+ flex: none;
+ }
+
+ .flex,
+ .flex-1 {
+ -ms-flex: 1;
+ -webkit-flex: 1;
+ flex: 1;
+ }
+
+ .flex-2 {
+ -ms-flex: 2;
+ -webkit-flex: 2;
+ flex: 2;
+ }
+
+ .flex-3 {
+ -ms-flex: 3;
+ -webkit-flex: 3;
+ flex: 3;
+ }
+
+ .flex-4 {
+ -ms-flex: 4;
+ -webkit-flex: 4;
+ flex: 4;
+ }
+
+ .flex-5 {
+ -ms-flex: 5;
+ -webkit-flex: 5;
+ flex: 5;
+ }
+
+ .flex-6 {
+ -ms-flex: 6;
+ -webkit-flex: 6;
+ flex: 6;
+ }
+
+ .flex-7 {
+ -ms-flex: 7;
+ -webkit-flex: 7;
+ flex: 7;
+ }
+
+ .flex-8 {
+ -ms-flex: 8;
+ -webkit-flex: 8;
+ flex: 8;
+ }
+
+ .flex-9 {
+ -ms-flex: 9;
+ -webkit-flex: 9;
+ flex: 9;
+ }
+
+ .flex-10 {
+ -ms-flex: 10;
+ -webkit-flex: 10;
+ flex: 10;
+ }
+
+ .flex-11 {
+ -ms-flex: 11;
+ -webkit-flex: 11;
+ flex: 11;
+ }
+
+ .flex-12 {
+ -ms-flex: 12;
+ -webkit-flex: 12;
+ flex: 12;
+ }
+
+ /* alignment in cross axis */
+
+ .layout.start {
+ -ms-flex-align: start;
+ -webkit-align-items: flex-start;
+ align-items: flex-start;
+ }
+
+ .layout.center,
+ .layout.center-center {
+ -ms-flex-align: center;
+ -webkit-align-items: center;
+ align-items: center;
+ }
+
+ .layout.end {
+ -ms-flex-align: end;
+ -webkit-align-items: flex-end;
+ align-items: flex-end;
+ }
+
+ /* alignment in main axis */
+
+ .layout.start-justified {
+ -ms-flex-pack: start;
+ -webkit-justify-content: flex-start;
+ justify-content: flex-start;
+ }
+
+ .layout.center-justified,
+ .layout.center-center {
+ -ms-flex-pack: center;
+ -webkit-justify-content: center;
+ justify-content: center;
+ }
+
+ .layout.end-justified {
+ -ms-flex-pack: end;
+ -webkit-justify-content: flex-end;
+ justify-content: flex-end;
+ }
+
+ .layout.around-justified {
+ -ms-flex-pack: around;
+ -webkit-justify-content: space-around;
+ justify-content: space-around;
+ }
+
+ .layout.justified {
+ -ms-flex-pack: justify;
+ -webkit-justify-content: space-between;
+ justify-content: space-between;
+ }
+
+ /* self alignment */
+
+ .self-start {
+ -ms-align-self: flex-start;
+ -webkit-align-self: flex-start;
+ align-self: flex-start;
+ }
+
+ .self-center {
+ -ms-align-self: center;
+ -webkit-align-self: center;
+ align-self: center;
+ }
+
+ .self-end {
+ -ms-align-self: flex-end;
+ -webkit-align-self: flex-end;
+ align-self: flex-end;
+ }
+
+ .self-stretch {
+ -ms-align-self: stretch;
+ -webkit-align-self: stretch;
+ align-self: stretch;
+ }
+
+ /*******************************
+ Other Layout
+ *******************************/
+
+ .block {
+ display: block;
+ }
+
+ /* IE 10 support for HTML5 hidden attr */
+ [hidden] {
+ display: none !important;
+ }
+
+ .invisible {
+ visibility: hidden !important;
+ }
+
+ .relative {
+ position: relative;
+ }
+
+ .fit {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ }
+
+ body.fullbleed {
+ margin: 0;
+ height: 100vh;
+ }
+
+ .scroll {
+ -webkit-overflow-scrolling: touch;
+ overflow: auto;
+ }
+
+ /* fixed position */
+
+ .fixed-bottom,
+ .fixed-left,
+ .fixed-right,
+ .fixed-top {
+ position: fixed;
+ }
+
+ .fixed-top {
+ top: 0;
+ left: 0;
+ right: 0;
+ }
+
+ .fixed-right {
+ top: 0;
+ right: 0;
+ bottom: 0;
+ }
+
+ .fixed-bottom {
+ right: 0;
+ bottom: 0;
+ left: 0;
+ }
+
+ .fixed-left {
+ top: 0;
+ bottom: 0;
+ left: 0;
+ }
+
+</style>
diff --git a/polymer_1.0.4/bower_components/iron-flex-layout/classes/iron-shadow-flex-layout.html b/polymer_1.0.4/bower_components/iron-flex-layout/classes/iron-shadow-flex-layout.html
new file mode 100644
index 0000000..c42067a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-flex-layout/classes/iron-shadow-flex-layout.html
@@ -0,0 +1,302 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<style>
+
+ /*******************************
+ Flex Layout
+ *******************************/
+
+ html /deep/ .layout.horizontal,
+ html /deep/ .layout.horizontal-reverse,
+ html /deep/ .layout.vertical,
+ html /deep/ .layout.vertical-reverse {
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+ }
+
+ html /deep/ .layout.inline {
+ display: -ms-inline-flexbox;
+ display: -webkit-inline-flex;
+ display: inline-flex;
+ }
+
+ html /deep/ .layout.horizontal {
+ -ms-flex-direction: row;
+ -webkit-flex-direction: row;
+ flex-direction: row;
+ }
+
+ html /deep/ .layout.horizontal-reverse {
+ -ms-flex-direction: row-reverse;
+ -webkit-flex-direction: row-reverse;
+ flex-direction: row-reverse;
+ }
+
+ html /deep/ .layout.vertical {
+ -ms-flex-direction: column;
+ -webkit-flex-direction: column;
+ flex-direction: column;
+ }
+
+ html /deep/ .layout.vertical-reverse {
+ -ms-flex-direction: column-reverse;
+ -webkit-flex-direction: column-reverse;
+ flex-direction: column-reverse;
+ }
+
+ html /deep/ .layout.wrap {
+ -ms-flex-wrap: wrap;
+ -webkit-flex-wrap: wrap;
+ flex-wrap: wrap;
+ }
+
+ html /deep/ .layout.wrap-reverse {
+ -ms-flex-wrap: wrap-reverse;
+ -webkit-flex-wrap: wrap-reverse;
+ flex-wrap: wrap-reverse;
+ }
+
+ html /deep/ .flex-auto {
+ -ms-flex: 1 1 auto;
+ -webkit-flex: 1 1 auto;
+ flex: 1 1 auto;
+ }
+
+ html /deep/ .flex-none {
+ -ms-flex: none;
+ -webkit-flex: none;
+ flex: none;
+ }
+
+ html /deep/ .flex,
+ html /deep/ .flex-1 {
+ -ms-flex: 1;
+ -webkit-flex: 1;
+ flex: 1;
+ }
+
+ html /deep/ .flex-2 {
+ -ms-flex: 2;
+ -webkit-flex: 2;
+ flex: 2;
+ }
+
+ html /deep/ .flex-3 {
+ -ms-flex: 3;
+ -webkit-flex: 3;
+ flex: 3;
+ }
+
+ html /deep/ .flex-4 {
+ -ms-flex: 4;
+ -webkit-flex: 4;
+ flex: 4;
+ }
+
+ html /deep/ .flex-5 {
+ -ms-flex: 5;
+ -webkit-flex: 5;
+ flex: 5;
+ }
+
+ html /deep/ .flex-6 {
+ -ms-flex: 6;
+ -webkit-flex: 6;
+ flex: 6;
+ }
+
+ html /deep/ .flex-7 {
+ -ms-flex: 7;
+ -webkit-flex: 7;
+ flex: 7;
+ }
+
+ html /deep/ .flex-8 {
+ -ms-flex: 8;
+ -webkit-flex: 8;
+ flex: 8;
+ }
+
+ html /deep/ .flex-9 {
+ -ms-flex: 9;
+ -webkit-flex: 9;
+ flex: 9;
+ }
+
+ html /deep/ .flex-10 {
+ -ms-flex: 10;
+ -webkit-flex: 10;
+ flex: 10;
+ }
+
+ html /deep/ .flex-11 {
+ -ms-flex: 11;
+ -webkit-flex: 11;
+ flex: 11;
+ }
+
+ html /deep/ .flex-12 {
+ -ms-flex: 12;
+ -webkit-flex: 12;
+ flex: 12;
+ }
+
+ /* alignment in cross axis */
+
+ html /deep/ .layout.start {
+ -ms-flex-align: start;
+ -webkit-align-items: flex-start;
+ align-items: flex-start;
+ }
+
+ html /deep/ .layout.center,
+ html /deep/ .layout.center-center {
+ -ms-flex-align: center;
+ -webkit-align-items: center;
+ align-items: center;
+ }
+
+ html /deep/ .layout.end {
+ -ms-flex-align: end;
+ -webkit-align-items: flex-end;
+ align-items: flex-end;
+ }
+
+ /* alignment in main axis */
+
+ html /deep/ .layout.start-justified {
+ -ms-flex-pack: start;
+ -webkit-justify-content: flex-start;
+ justify-content: flex-start;
+ }
+
+ html /deep/ .layout.center-justified,
+ html /deep/ .layout.center-center {
+ -ms-flex-pack: center;
+ -webkit-justify-content: center;
+ justify-content: center;
+ }
+
+ html /deep/ .layout.end-justified {
+ -ms-flex-pack: end;
+ -webkit-justify-content: flex-end;
+ justify-content: flex-end;
+ }
+
+ html /deep/ .layout.around-justified {
+ -ms-flex-pack: around;
+ -webkit-justify-content: space-around;
+ justify-content: space-around;
+ }
+
+ html /deep/ .layout.justified {
+ -ms-flex-pack: justify;
+ -webkit-justify-content: space-between;
+ justify-content: space-between;
+ }
+
+ /* self alignment */
+
+ html /deep/ .self-start {
+ -ms-align-self: flex-start;
+ -webkit-align-self: flex-start;
+ align-self: flex-start;
+ }
+
+ html /deep/ .self-center {
+ -ms-align-self: center;
+ -webkit-align-self: center;
+ align-self: center;
+ }
+
+ html /deep/ .self-end {
+ -ms-align-self: flex-end;
+ -webkit-align-self: flex-end;
+ align-self: flex-end;
+ }
+
+ html /deep/ .self-stretch {
+ -ms-align-self: stretch;
+ -webkit-align-self: stretch;
+ align-self: stretch;
+ }
+
+ /*******************************
+ Other Layout
+ *******************************/
+
+ html /deep/ .block {
+ display: block;
+ }
+
+ /* IE 10 support for HTML5 hidden attr */
+ html /deep/ [hidden] {
+ display: none !important;
+ }
+
+ html /deep/ .invisible {
+ visibility: hidden !important;
+ }
+
+ html /deep/ .relative {
+ position: relative;
+ }
+
+ html /deep/ .fit {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ }
+
+ body.fullbleed {
+ margin: 0;
+ height: 100vh;
+ }
+
+ html /deep/ .scroll {
+ -webkit-overflow-scrolling: touch;
+ overflow: auto;
+ }
+
+ .fixed-bottom,
+ .fixed-left,
+ .fixed-right,
+ .fixed-top {
+ position: fixed;
+ }
+
+ html /deep/ .fixed-top {
+ top: 0;
+ left: 0;
+ right: 0;
+ }
+
+ html /deep/ .fixed-right {
+ top: 0;
+ right: 0;
+ botttom: 0;
+ }
+
+ html /deep/ .fixed-bottom {
+ right: 0;
+ bottom: 0;
+ left: 0;
+ }
+
+ html /deep/ .fixed-left {
+ top: 0;
+ botttom: 0;
+ left: 0;
+ }
+
+</style>
diff --git a/polymer_1.0.4/bower_components/iron-flex-layout/demo/index.html b/polymer_1.0.4/bower_components/iron-flex-layout/demo/index.html
new file mode 100644
index 0000000..ea4df38
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-flex-layout/demo/index.html
@@ -0,0 +1,42 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+
+<html>
+<head>
+
+ <title>iron-flex-layout</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="x-app.html">
+
+ <style>
+
+ html, body, x-app {
+ height: 100%;
+ }
+
+ body {
+ margin: 0;
+ }
+
+ </style>
+
+</head>
+<body class="fullbleed">
+
+ <x-app></x-app>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-flex-layout/demo/x-app.html b/polymer_1.0.4/bower_components/iron-flex-layout/demo/x-app.html
new file mode 100644
index 0000000..489a5f5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-flex-layout/demo/x-app.html
@@ -0,0 +1,118 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+
+<link rel="import" href="../iron-flex-layout.html">
+
+<dom-module id="x-app">
+
+ <style>
+
+ :host {
+ @apply(--layout-horizontal);
+ @apply(--paper-font-body2);
+ }
+
+ [nav] {
+ @apply(--layout-vertical);
+
+ width: 200px;
+ background-color: var(--paper-grey-300);
+ }
+
+ [item] {
+ @apply(--layout-horizontal);
+ @apply(--layout-center);
+
+ height: 60px;
+ padding-left: 16px;
+ border-bottom: 1px solid var(--paper-grey-400);
+ }
+
+ [main] {
+ @apply(--layout-flex);
+ @apply(--layout-vertical);
+ }
+
+ [header] {
+ @apply(--layout-horizontal);
+ @apply(--layout-center);
+
+ @apply(--paper-font-subhead);
+
+ height: 60px;
+ background-color: var(--google-blue-700);
+ padding: 0 16px;
+ color: white;
+ }
+
+ [tool] {
+ @apply(--layout-inline);
+ }
+
+ [content] {
+ @apply(--layout-flex);
+
+ overflow: auto;
+ padding: 0 10px;
+ }
+
+ [card] {
+ @apply(--layout-vertical);
+ @apply(--layout-center-center);
+
+ @apply(--shadow-elevation-2dp);
+
+ height: 300px;
+ max-width: 800px;
+ margin: 16px auto;
+ font-weight: bold;
+ background-color: var(--paper-grey-200);
+ }
+
+ </style>
+
+ <template>
+
+ <div nav>
+ <div content>
+ <div item>ITEM 1</div>
+ <div item>ITEM 2</div>
+ <div item>ITEM 3</div>
+ <div item>ITEM 4</div>
+ <div item>ITEM 5</div>
+ </div>
+ </div>
+
+ <div main>
+ <div header>
+ <div tool>Foo</div>
+ <div class="flex"></div>
+ <div tool>Bar</div>
+ </div>
+ <div content>
+ <div card>CARD 1</div>
+ <div card>CARD 2</div>
+ <div card>CARD 3</div>
+ <div card>CARD 4</div>
+ <div card>CARD 5</div>
+ </div>
+ </div>
+
+ </template>
+
+</dom-module>
+<script>
+
+ Polymer({
+ is: 'x-app'
+ });
+
+</script>
+
diff --git a/polymer_1.0.4/bower_components/iron-flex-layout/iron-flex-layout.html b/polymer_1.0.4/bower_components/iron-flex-layout/iron-flex-layout.html
new file mode 100644
index 0000000..ed9cd7b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-flex-layout/iron-flex-layout.html
@@ -0,0 +1,313 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<style is="custom-style">
+
+ :root {
+
+ --layout: {
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+ };
+
+ --layout-inline: {
+ display: -ms-inline-flexbox;
+ display: -webkit-inline-flex;
+ display: inline-flex;
+ };
+
+ --layout-horizontal: {
+ /* @apply(--layout); */
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+
+ -ms-flex-direction: row;
+ -webkit-flex-direction: row;
+ flex-direction: row;
+ };
+
+ --layout-horizontal-reverse: {
+ -ms-flex-direction: row-reverse;
+ -webkit-flex-direction: row-reverse;
+ flex-direction: row-reverse;
+ };
+
+ --layout-vertical: {
+ /* @apply(--layout); */
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+
+ -ms-flex-direction: column;
+ -webkit-flex-direction: column;
+ flex-direction: column;
+ };
+
+ --layout-vertical-reverse: {
+ -ms-flex-direction: column-reverse;
+ -webkit-flex-direction: column-reverse;
+ flex-direction: column-reverse;
+ };
+
+ --layout-wrap: {
+ -ms-flex-wrap: wrap;
+ -webkit-flex-wrap: wrap;
+ flex-wrap: wrap;
+ };
+
+ --layout-wrap-reverse: {
+ -ms-flex-wrap: wrap-reverse;
+ -webkit-flex-wrap: wrap-reverse;
+ flex-wrap: wrap-reverse;
+ };
+
+ --layout-flex-auto: {
+ -ms-flex: 1 1 auto;
+ -webkit-flex: 1 1 auto;
+ flex: 1 1 auto;
+ };
+
+ --layout-flex-none: {
+ -ms-flex: none;
+ -webkit-flex: none;
+ flex: none;
+ };
+
+ --layout-flex: {
+ -ms-flex: 1 1 0.000000001px;
+ -webkit-flex: 1;
+ flex: 1;
+ -webkit-flex-basis: 0.000000001px;
+ flex-basis: 0.000000001px;
+ };
+
+ --layout-flex-2: {
+ -ms-flex: 2;
+ -webkit-flex: 2;
+ flex: 2;
+ };
+
+ --layout-flex-3: {
+ -ms-flex: 3;
+ -webkit-flex: 3;
+ flex: 3;
+ };
+
+ --layout-flex-4: {
+ -ms-flex: 4;
+ -webkit-flex: 4;
+ flex: 4;
+ };
+
+ --layout-flex-5: {
+ -ms-flex: 5;
+ -webkit-flex: 5;
+ flex: 5;
+ };
+
+ --layout-flex-6: {
+ -ms-flex: 6;
+ -webkit-flex: 6;
+ flex: 6;
+ };
+
+ --layout-flex-7: {
+ -ms-flex: 7;
+ -webkit-flex: 7;
+ flex: 7;
+ };
+
+ --layout-flex-8: {
+ -ms-flex: 8;
+ -webkit-flex: 8;
+ flex: 8;
+ };
+
+ --layout-flex-9: {
+ -ms-flex: 9;
+ -webkit-flex: 9;
+ flex: 9;
+ };
+
+ --layout-flex-10: {
+ -ms-flex: 10;
+ -webkit-flex: 10;
+ flex: 10;
+ };
+
+ --layout-flex-11: {
+ -ms-flex: 11;
+ -webkit-flex: 11;
+ flex: 11;
+ };
+
+ --layout-flex-12: {
+ -ms-flex: 12;
+ -webkit-flex: 12;
+ flex: 12;
+ };
+
+ /* alignment in cross axis */
+
+ --layout-start: {
+ -ms-flex-align: start;
+ -webkit-align-items: flex-start;
+ align-items: flex-start;
+ };
+
+ --layout-center: {
+ -ms-flex-align: center;
+ -webkit-align-items: center;
+ align-items: center;
+ };
+
+ --layout-end: {
+ -ms-flex-align: end;
+ -webkit-align-items: flex-end;
+ align-items: flex-end;
+ };
+
+ /* alignment in main axis */
+
+ --layout-start-justified: {
+ -ms-flex-pack: start;
+ -webkit-justify-content: flex-start;
+ justify-content: flex-start;
+ };
+
+ --layout-center-justified: {
+ -ms-flex-pack: center;
+ -webkit-justify-content: center;
+ justify-content: center;
+ };
+
+ --layout-end-justified: {
+ -ms-flex-pack: end;
+ -webkit-justify-content: flex-end;
+ justify-content: flex-end;
+ };
+
+ --layout-around-justified: {
+ -ms-flex-pack: around;
+ -webkit-justify-content: space-around;
+ justify-content: space-around;
+ };
+
+ --layout-justified: {
+ -ms-flex-pack: justify;
+ -webkit-justify-content: space-between;
+ justify-content: space-between;
+ };
+
+ --layout-center-center: {
+ /* @apply(--layout-center --layout-center-justified); */
+ -ms-flex-align: center;
+ -webkit-align-items: center;
+ align-items: center;
+ -ms-flex-pack: center;
+ -webkit-justify-content: center;
+ justify-content: center;
+ };
+
+ /* self alignment */
+
+ --layout-self-start: {
+ -ms-align-self: flex-start;
+ -webkit-align-self: flex-start;
+ align-self: flex-start;
+ };
+
+ --layout-self-center: {
+ -ms-align-self: center;
+ -webkit-align-self: center;
+ align-self: center;
+ };
+
+ --layout-self-end: {
+ -ms-align-self: flex-end;
+ -webkit-align-self: flex-end;
+ align-self: flex-end;
+ };
+
+ --layout-self-stretch: {
+ -ms-align-self: stretch;
+ -webkit-align-self: stretch;
+ align-self: stretch;
+ };
+
+ /*******************************
+ Other Layout
+ *******************************/
+
+ --layout-block: {
+ display: block;
+ };
+
+ --layout-invisible: {
+ visibility: hidden !important;
+ };
+
+ --layout-relative: {
+ position: relative;
+ };
+
+ --layout-fit: {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ };
+
+ --layout-scroll: {
+ -webkit-overflow-scrolling: touch;
+ overflow: auto;
+ };
+
+ /* fixed position */
+
+ --layout-fixed-bottom:,
+ --layout-fixed-left:,
+ --layout-fixed-right:,
+ --layout-fixed-top: {
+ position: fixed;
+ };
+
+ --layout-fixed-top: {
+ top: 0;
+ left: 0;
+ right: 0;
+ };
+
+ --layout-fixed-right: {
+ top: 0;
+ right: 0;
+ bottom: 0;
+ };
+
+ --layout-fixed-bottom: {
+ right: 0;
+ bottom: 0;
+ left: 0;
+ };
+
+ --layout-fixed-left: {
+ top: 0;
+ bottom: 0;
+ left: 0;
+ };
+
+ }
+
+</style>
diff --git a/polymer_1.0.4/bower_components/iron-form-element-behavior/.bower.json b/polymer_1.0.4/bower_components/iron-form-element-behavior/.bower.json
new file mode 100644
index 0000000..f1369b1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form-element-behavior/.bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "iron-form-element-behavior",
+ "version": "1.0.1",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "private": true,
+ "main": "iron-form-element-behavior",
+ "authors": "The Polymer Authors",
+ "description": "Enables a custom element to be included in an iron-form",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "form"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-form-element-behavior.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-form-element-behavior",
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "f386143e866c320025589f3d79798c12103377a4"
+ },
+ "_source": "git://github.com/PolymerElements/iron-form-element-behavior.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-form-element-behavior"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-form-element-behavior/.gitignore b/polymer_1.0.4/bower_components/iron-form-element-behavior/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form-element-behavior/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-form-element-behavior/README.md b/polymer_1.0.4/bower_components/iron-form-element-behavior/README.md
new file mode 100644
index 0000000..555063f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form-element-behavior/README.md
@@ -0,0 +1,2 @@
+# iron-form-element-behavior
+Behavior that allows an element to be tracked by an iron-form
diff --git a/polymer_1.0.4/bower_components/iron-form-element-behavior/bower.json b/polymer_1.0.4/bower_components/iron-form-element-behavior/bower.json
new file mode 100644
index 0000000..1e141f2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form-element-behavior/bower.json
@@ -0,0 +1,27 @@
+{
+ "name": "iron-form-element-behavior",
+ "version": "1.0.1",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "private": true,
+ "main": "iron-form-element-behavior",
+ "authors": "The Polymer Authors",
+ "description": "Enables a custom element to be included in an iron-form",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "form"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-form-element-behavior.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-form-element-behavior/demo/index.html b/polymer_1.0.4/bower_components/iron-form-element-behavior/demo/index.html
new file mode 100644
index 0000000..b40998d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form-element-behavior/demo/index.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>iron-form-element-behavior demo</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="simple-form.html">
+ <link rel="import" href="simple-element.html">
+
+ </head>
+ <body>
+
+ <form is="simple-form" id="form">
+ Element the form is tracking: <input is="simple-element" type="text" name="one" value="one">
+ <br>
+ Element the form isn't tracking: <input type="text" name="two" value="two">
+ <br>
+ Another one the form is tracking: <input is="simple-element" type="text" name="three" value="three">
+
+ </form>
+
+ <h4>Elements tracked by the form: </h4>
+ <ul id="output">
+ </ul>
+ </body>
+ <script>
+ var output = document.getElementById('output');
+ var elements = document.getElementById('form').formElements;
+
+ for (var i = 0; i < elements.length; i++) {
+ var li = document.createElement('li');
+ var text = document.createTextNode(elements[i].value);
+ li.appendChild(text);
+ output.appendChild(li);
+ }
+ </script>
+
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-form-element-behavior/demo/simple-element.html b/polymer_1.0.4/bower_components/iron-form-element-behavior/demo/simple-element.html
new file mode 100644
index 0000000..4502769
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form-element-behavior/demo/simple-element.html
@@ -0,0 +1,27 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../iron-form-element-behavior.html">
+
+<script>
+
+ Polymer({
+
+ is: 'simple-element',
+
+ extends: 'input',
+
+ behaviors: [
+ Polymer.IronFormElementBehavior
+ ]
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-form-element-behavior/demo/simple-form.html b/polymer_1.0.4/bower_components/iron-form-element-behavior/demo/simple-form.html
new file mode 100644
index 0000000..82acbe5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form-element-behavior/demo/simple-form.html
@@ -0,0 +1,42 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../polymer/polymer.html">
+
+<script>
+
+ Polymer({
+
+ is: 'simple-form',
+
+ extends: 'form',
+
+ properties: {
+ formElements: {
+ type: Object,
+ notify: true
+ }
+ },
+
+ listeners: {
+ 'iron-form-element-register': '_elementRegistered'
+ },
+
+ ready: function() {
+ this.formElements = [];
+ },
+
+ _elementRegistered: function(e) {
+ this.formElements.push(e.target);
+ this.fire('element-registered');
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-form-element-behavior/index.html b/polymer_1.0.4/bower_components/iron-form-element-behavior/index.html
new file mode 100644
index 0000000..8d748c0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form-element-behavior/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>iron-form-element-behavior</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-form-element-behavior/iron-form-element-behavior.html b/polymer_1.0.4/bower_components/iron-form-element-behavior/iron-form-element-behavior.html
new file mode 100644
index 0000000..d7678a7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form-element-behavior/iron-form-element-behavior.html
@@ -0,0 +1,50 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<!--
+Enables a custom element to be included in an `iron-form`.
+-->
+<script>
+
+ /**
+
+ @demo demo/index.html
+ @polymerBehavior
+
+ */
+ Polymer.IronFormElementBehavior = {
+
+ properties: {
+
+ /**
+ * The name of this element.
+ */
+ name: {
+ type: String
+ },
+
+ /**
+ * The value for this element.
+ */
+ value: {
+ notify: true,
+ type: String
+ },
+ },
+
+ attached: function() {
+ this.fire('iron-form-element-register');
+ }
+
+ };
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-form/.bower.json b/polymer_1.0.4/bower_components/iron-form/.bower.json
new file mode 100644
index 0000000..90bea29
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form/.bower.json
@@ -0,0 +1,47 @@
+{
+ "name": "iron-form",
+ "version": "1.0.3",
+ "description": "Makes it easier to manage forms",
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "main": [
+ "iron-form.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-form.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-form",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-ajax": "PolymerElements/iron-ajax#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "^0.7.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-button": "PolymerElements/paper-button#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0"
+ },
+ "_release": "1.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.3",
+ "commit": "c0c007c3e6575d3bc3fcf89bed3e29f0e883dc78"
+ },
+ "_source": "git://github.com/PolymerElements/iron-form.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-form"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-form/.gitignore b/polymer_1.0.4/bower_components/iron-form/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-form/README.md b/polymer_1.0.4/bower_components/iron-form/README.md
new file mode 100644
index 0000000..424b29f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form/README.md
@@ -0,0 +1,2 @@
+# iron-form
+Custom form element
diff --git a/polymer_1.0.4/bower_components/iron-form/bower.json b/polymer_1.0.4/bower_components/iron-form/bower.json
new file mode 100644
index 0000000..6e611e4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form/bower.json
@@ -0,0 +1,43 @@
+{
+ "name": "iron-form",
+ "version": "1.0.3",
+ "description": "Makes it easier to manage forms",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "form"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer"
+ ],
+ "main": [
+ "iron-form.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-form.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-form",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-ajax": "PolymerElements/iron-ajax#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "^0.7.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-button": "PolymerElements/paper-button#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-form/demo/index.html b/polymer_1.0.4/bower_components/iron-form/demo/index.html
new file mode 100644
index 0000000..e9062ba
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form/demo/index.html
@@ -0,0 +1,125 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>iron-form demo</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../paper-input/paper-input.html">
+ <link rel="import" href="../../paper-button/paper-button.html">
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../iron-form.html">
+</head>
+<style>
+ .wide {
+ width: 474px;
+ }
+</style>
+<body>
+ <div class="horizontal center-center layout">
+ <div>
+ <h4>method="get"</h4>
+ <div class="horizontal-section">
+ <form is="iron-form" id="formGet" method="get" action="/">
+ <paper-input name="name" label="Name" required></paper-input>
+ <paper-input name="animal" label="Favourite animal" required></paper-input>
+ <br>
+
+ <input type="checkbox" name="food" value="donuts" checked> I like donuts<br>
+ <input type="checkbox" name="food" value="pizza" required> I like pizza<br>
+ <br>
+
+ <input type="radio" name="color" value="red" checked>Red<br>
+ <input type="radio" name="color" value="blue" checked>Blue<br>
+ <input type="radio" name="color" value="green">Green<br>
+
+ <br><br>
+
+ <paper-button raised
+ onclick="clickHandler(event)">Submit</paper-button>
+ <button type="submit">Native Submit</button>
+ </form>
+ </div>
+ </div>
+
+ <div>
+ <h4>method="post"</h4>
+ <div class="horizontal-section">
+ <form is="iron-form" id="formPost" method="post" action="/">
+ <paper-input name="name" label="Name" required></paper-input>
+ <br>
+ <p>Duplicate name <input name="name" required></p>
+ <br><br>
+
+ <label>Cars</label>
+ <select name="cars">
+ <option value="volvo">Volvo</option>
+ <option value="saab">Saab</option>
+ <option value="fiat">Fiat</option>
+ <option value="audi">Audi</option>
+ </select>
+
+ <br><br>
+ <label>Browsers</label>
+ <input list="browsers" name="browsers" required>
+ <datalist id="browsers">
+ <option value="Internet Explorer">
+ <option value="Firefox">
+ <option value="Chrome">
+ <option value="Opera">
+ <option value="Safari">
+ </datalist>
+ <br><br>
+
+ <label>Pick a number</label>
+ <input type="range" name="number" min="1" max="100">
+
+ <br><br><br>
+ <paper-button raised
+ onclick="clickHandler(event)">Submit</paper-button>
+ <button type="submit">Native Submit</button>
+ </form>
+ </div>
+ </div>
+ </div>
+
+ <br><br>
+ <div class="layout vertical center-center">
+ <div>
+ <h4>Submitted form data</h4>
+ <div class="horizontal-section wide">
+ <div id="output"></div>
+ </div>
+ </div>
+ </div>
+
+ <script>
+ document.getElementById('formGet').addEventListener('iron-form-submit', display);
+ document.getElementById('formPost').addEventListener('iron-form-submit', display);
+
+ function display(event) {
+ var output = document.getElementById('output');
+ output.innerHTML = JSON.stringify(event.detail);
+ }
+
+ function clickHandler(event) {
+ Polymer.dom(event).localTarget.parentElement.submit();
+ }
+ </script>
+</body>
+
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-form/index.html b/polymer_1.0.4/bower_components/iron-form/index.html
new file mode 100644
index 0000000..acd7140
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>iron-form</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-form/iron-form.html b/polymer_1.0.4/bower_components/iron-form/iron-form.html
new file mode 100644
index 0000000..1bd36e1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form/iron-form.html
@@ -0,0 +1,243 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-ajax/iron-ajax.html">
+
+<script>
+/*
+``<iron-form>` is an HTML `<form>` element that can validate and submit any custom
+elements that implement `Polymer.IronFormElementBehavior`, as well as any
+native HTML elements.
+
+It supports both `get` and `post` methods, and uses an `iron-ajax` element to
+submit the form data to the action URL.
+
+ Example:
+
+ <form is="iron-form" id="form" method="post" action="/form/handler">
+ <paper-input name="name" label="name"></paper-input>
+ <input name="address">
+ ...
+ </form>
+
+By default, a native `<button>` element will submit this form. However, if you
+want to submit it from a custom element's click handler, you need to explicitly
+call the form's `submit` method.
+
+ Example:
+
+ <paper-button raised onclick="submitForm()">Submit</paper-button>
+
+ function submitForm() {
+ document.getElementById('form').submit();
+ }
+
+@demo demo/index.html
+*/
+
+ Polymer({
+
+ is: 'iron-form',
+
+ extends: 'form',
+
+ properties: {
+ /**
+ * Content type to use when sending data.
+ */
+ contentType: {
+ type: String,
+ value: "application/x-www-form-urlencoded"
+ }
+ },
+ /**
+ * Fired if the form cannot be submitted because it's invalid.
+ *
+ * @event iron-form-invalid
+ */
+
+ /**
+ * Fired after the form is submitted.
+ *
+ * @event iron-form-submit
+ */
+
+ /**
+ * Fired after the form is submitted and a response is received.
+ *
+ * @event iron-form-response
+ */
+
+ /**
+ * Fired after the form is submitted and an error is received.
+ *
+ * @event iron-form-error
+ */
+ listeners: {
+ 'iron-form-element-register': '_registerElement',
+ 'submit': '_onSubmit'
+ },
+
+ ready: function() {
+ // Object that handles the ajax form submission request.
+ this._requestBot = document.createElement('iron-ajax');
+ this._requestBot.addEventListener('response', this._handleFormResponse.bind(this));
+ this._requestBot.addEventListener('error', this._handleFormError.bind(this));
+
+ // Holds all the custom elements registered with this form.
+ this._customElements = [];
+ },
+
+ /**
+ * Called to submit the form.
+ */
+ submit: function() {
+ if (!this.noValidate && !this._validate()) {
+
+ // In order to trigger the native browser invalid-form UI, we need
+ // to do perform a fake form submit.
+ this._doFakeSubmitForValidation();
+ this.fire('iron-form-invalid');
+ return;
+ }
+
+ var json = this.serialize();
+
+ this._requestBot.url = this.action;
+ this._requestBot.method = this.method;
+ this._requestBot.contentType = this.contentType;
+
+ if (this.method.toUpperCase() == 'POST') {
+ this._requestBot.body = JSON.stringify(json);
+ } else {
+ this._requestBot.params = json;
+ }
+
+ this._requestBot.generateRequest();
+ this.fire('iron-form-submit', json);
+ },
+
+ _onSubmit: function(event) {
+ this.submit();
+
+ // Don't perform a page refresh.
+ if (event) {
+ event.preventDefault();
+ }
+
+ return false;
+ },
+
+ /**
+ * Returns a json object containing name/value pairs for all the registered
+ * custom components and native elements of the form. If there are elements
+ * with duplicate names, then their values will get aggregated into an
+ * array of values.
+ */
+ serialize: function() {
+ var json = {};
+
+ function addSerializedElement(el) {
+ // If the name doesn't exist, add it. Otherwise, serialize it to
+ // an array,
+ if (!json[el.name]) {
+ json[el.name] = el.value;
+ } else {
+ if (!Array.isArray(json[el.name])) {
+ json[el.name] = [json[el.name]];
+ }
+ json[el.name].push(el.value);
+ }
+ }
+
+ // Go through all of the registered custom components.
+ for (var el, i = 0; el = this._customElements[i], i < this._customElements.length; i++) {
+ if (el.name) {
+ addSerializedElement(el);
+ }
+ }
+
+ // Also go through the form's native elements.
+ for (var el, i = 0; el = this.elements[i], i < this.elements.length; i++) {
+ // Checkboxes and radio buttons should only use their value if they're checked.
+ // Also, custom elements that extend native elements (like an
+ // `<input is="fancy-input">`) will appear in both lists. Since they
+ // were already added as a custom element, they don't need
+ // to be re-added.
+ if (!el.name || !this._useValue(el) ||
+ (el.hasAttribute('is') && json[el.name])) {
+ continue;
+ }
+ addSerializedElement(el);
+ }
+
+ return json;
+ },
+
+ _handleFormResponse: function (event) {
+ this.fire('iron-form-response', event.detail.response);
+ },
+
+ _handleFormError: function (event) {
+ this.fire('iron-form-error', event.detail);
+ },
+
+ _registerElement: function(e) {
+ this._customElements.push(e.target);
+ },
+
+ _validate: function() {
+ var valid = true;
+
+ // Validate all the custom elements.
+ var validatable;
+ for (var el, i = 0; el = this._customElements[i], i < this._customElements.length; i++) {
+ if (el.required) {
+ validatable = /** @type {{validate: (function() : boolean)}} */ (el);
+ valid = validatable.validate() && valid;
+ }
+ }
+
+ // Validate the form's native elements.
+ for (var el, i = 0; el = this.elements[i], i < this.elements.length; i++) {
+ // Custom elements that extend a native element will also appear in
+ // this list, but they've already been validated.
+ if (!el.hasAttribute('is') && el.willValidate && el.checkValidity) {
+ valid = el.checkValidity() && valid;
+ }
+ }
+
+ return valid;
+ },
+
+ _useValue: function(el) {
+ // Checkboxes and radio buttons should only use their value if they're checked.
+ if (el.type !== 'checkbox' && el.type !== 'radio') {
+ return true;
+ } else {
+ return el.checked;
+ }
+ },
+
+ _doFakeSubmitForValidation: function() {
+ var fakeSubmit = document.createElement('input');
+ fakeSubmit.setAttribute('type', 'submit');
+ fakeSubmit.style.display = 'none';
+ this.appendChild(fakeSubmit);
+
+ fakeSubmit.click();
+
+ this.removeChild(fakeSubmit);
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-form/test/basic.html b/polymer_1.0.4/bower_components/iron-form/test/basic.html
new file mode 100644
index 0000000..24e60ce
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form/test/basic.html
@@ -0,0 +1,259 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>iron-form</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-form.html">
+ <link rel="import" href="simple-element.html">
+
+</head>
+<body>
+
+ <test-fixture id="Basic">
+ <template>
+ <form is="iron-form">
+ <simple-element name="zig" value="zag"></simple-element>
+ <input name="foo" value="bar">
+ </form>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="Dupes">
+ <template>
+ <form is="iron-form">
+ <input name="foo" value="bar">
+ <input name="foo" value="barbar">
+ <simple-element name="zig" value="zig"></simple-element>
+ <simple-element name="zig" value="zag"></simple-element>
+ <simple-element name="zig" value="zug"></simple-element>
+ </form>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="CheckedStates">
+ <template>
+ <form is="iron-form">
+ <input type="checkbox" name="foo" value="bar1" checked>
+ <input type="checkbox" name="foo" value="bar2">
+ <input type="checkbox" name="foo" value="bar3" checked>
+ <input type="checkbox" name="foo" value="bar4">
+ </form>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="FormGet">
+ <template>
+ <form is="iron-form" action="/responds_with_json" method="get">
+ <simple-element name="zig" value="zag"></simple-element>
+ </form>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="FormPost">
+ <template>
+ <form is="iron-form" action="/responds_with_json" method="post">
+ <simple-element name="zig" value="zag"></simple-element>
+ </form>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="InvalidForm">
+ <template>
+ <form is="iron-form" action="/responds_with_json" method="post">
+ <simple-element name="zig"></simple-element>
+ <input name="foo" required>
+ </form>
+ </template>
+ </test-fixture>
+
+
+ <script>
+ suite('serializing', function() {
+ test('serializes both custom and native elements', function() {
+ f = fixture('Basic');
+
+ assert.equal(f._customElements.length, 1);
+ assert.equal(f.elements.length, 1);
+
+ var json = f.serialize();
+ assert.equal(Object.keys(json).length, 2);
+ assert.equal(json['zig'], 'zag');
+ assert.equal(json['foo'], 'bar');
+ });
+
+ test('serializes elements with duplicate names', function() {
+ f = fixture('Dupes');
+
+ assert.equal(f._customElements.length, 3);
+ assert.equal(f.elements.length, 2);
+
+ var json = f.serialize();
+ assert.equal(Object.keys(json).length, 2);
+ assert.equal(json['foo'].length, 2);
+ assert.equal(json['foo'][0], 'bar');
+ assert.equal(json['foo'][1], 'barbar');
+ assert.equal(json['zig'].length, 3);
+ assert.equal(json['zig'][0], 'zig');
+ assert.equal(json['zig'][1], 'zag');
+ assert.equal(json['zig'][2], 'zug');
+ });
+
+ test('serializes elements with checked states', function() {
+ f = fixture('CheckedStates');
+
+ assert.equal(f._customElements.length, 0);
+ assert.equal(f.elements.length, 4);
+
+ var json = f.serialize();
+ assert.equal(Object.keys(json).length, 1);
+ assert.equal(json['foo'].length, 2);
+ assert.equal(json['foo'][0], 'bar1');
+ assert.equal(json['foo'][1], 'bar3');
+ });
+
+ });
+
+ suite('submitting', function () {
+ var server;
+ var form;
+
+ setup(function() {
+ server = sinon.fakeServer.create();
+ server.respondWith(
+ 'GET',
+ /\/responds_with_json.*/,
+ [
+ 200,
+ '{"Content-Type":"application/json"}',
+ '{"success":true}'
+ ]
+ );
+
+ server.respondWith(
+ 'POST',
+ /\/responds_with_json.*/,
+ [
+ 200,
+ '{"Content-Type":"application/json"}',
+ '{"success":true}'
+ ]
+ );
+
+ server.respondWith(
+ 'GET',
+ /\/responds_with_error.*/,
+ [
+ 404,
+ '{"Content-Type":"application/text"}',
+ '{"success":false}'
+ ]
+ );
+ });
+
+ teardown(function() {
+ server.restore();
+ });
+
+ test('does not submit forms with invalid native elements', function(done) {
+ form = fixture('InvalidForm');
+ var nativeElement = form.querySelector('input');
+ var customElement = form.querySelector('simple-element');
+ customElement.value = "foo";
+
+ var submitted = false;
+ form.addEventListener('iron-form-submit', function() {
+ submitted = true;
+ });
+
+ form.addEventListener('iron-form-invalid', function() {
+ expect(submitted).to.be.equal(false);
+ expect(nativeElement.validity.valid).to.be.equal(false);
+ expect(customElement.invalid).to.be.equal(false);
+ done();
+ });
+
+ form.submit();
+ server.respond();
+ });
+
+ test('can submit with method=get', function(done) {
+ form = fixture('FormGet');
+
+ var submitted = false;
+ form.addEventListener('iron-form-submit', function() {
+ submitted = true;
+ });
+
+ form.addEventListener('iron-form-response', function(event) {
+ expect(submitted).to.be.equal(true);
+
+ var response = event.detail;
+ expect(response).to.be.ok;
+ expect(response).to.be.an('object');
+ expect(response.success).to.be.equal(true);
+ done();
+ });
+
+ form.submit();
+ server.respond();
+ });
+
+ test('can submit with method=post', function(done) {
+ form = fixture('FormPost');
+
+ var submitted = false;
+ form.addEventListener('iron-form-submit', function() {
+ submitted = true;
+ });
+
+ form.addEventListener('iron-form-response', function(event) {
+ expect(submitted).to.be.equal(true);
+ var response = event.detail;
+ expect(response).to.be.ok;
+ expect(response).to.be.an('object');
+ expect(response.success).to.be.equal(true);
+ done();
+ });
+
+ form.submit();
+ server.respond();
+ });
+
+ test('can relay errors', function(done) {
+ form = fixture('FormPost');
+ form.action = "/responds_with_error";
+
+ form.addEventListener('iron-form-error', function(event) {
+ var error = event.detail;
+
+ expect(error).to.be.ok;
+ expect(error).to.be.an('object');
+ expect(error.error).to.be.ok;
+ done();
+ });
+
+ form.submit();
+ server.respond();
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-form/test/index.html b/polymer_1.0.4/bower_components/iron-form/test/index.html
new file mode 100644
index 0000000..3b2bada
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form/test/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ </head>
+ <body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-form/test/simple-element.html b/polymer_1.0.4/bower_components/iron-form/test/simple-element.html
new file mode 100644
index 0000000..4b7e21b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-form/test/simple-element.html
@@ -0,0 +1,48 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../../iron-form-element-behavior/iron-form-element-behavior.html">
+
+<dom-module id="simple-element">
+ <template>
+ <span>[[value]]</span>
+ </template>
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'simple-element',
+
+ behaviors: [
+ Polymer.IronFormElementBehavior
+ ],
+
+ properties: {
+ invalid: {
+ type: Boolean,
+ value: false
+ },
+
+ value: {
+ type: String
+ }
+ },
+
+ validate: function() {
+ var valid = this.value ? this.value != '' : false;
+ this.invalid = !valid;
+ return valid;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-icon/.bower.json b/polymer_1.0.4/bower_components/iron-icon/.bower.json
new file mode 100644
index 0000000..7dbfaa0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icon/.bower.json
@@ -0,0 +1,43 @@
+{
+ "name": "iron-icon",
+ "private": true,
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "An element that supports displaying an icon",
+ "main": "iron-icon.html",
+ "author": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "icon"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-icon.git"
+ },
+ "dependencies": {
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "iron-meta": "polymerelements/iron-meta#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "iron-iconset": "polymerelements/iron-iconset#^1.0.0",
+ "iron-icons": "polymerelements/iron-icons#^1.0.0",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-icon",
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "f9246c47ecb1c682f0fb9ea48255d5f7debd1e03"
+ },
+ "_source": "git://github.com/PolymerElements/iron-icon.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-icon"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-icon/.gitignore b/polymer_1.0.4/bower_components/iron-icon/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icon/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-icon/README.md b/polymer_1.0.4/bower_components/iron-icon/README.md
new file mode 100644
index 0000000..27b65c0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icon/README.md
@@ -0,0 +1,56 @@
+iron-icon
+=========
+
+The `iron-icon` element displays an icon. By default an icon renders as a 24px square.
+
+Example using src:
+
+```html
+<iron-icon src="star.png"></iron-icon>
+```
+
+Example setting size to 32px x 32px:
+
+```html
+<iron-icon class="big" src="big_star.png"></iron-icon>
+
+<style>
+ .big {
+ height: 32px;
+ width: 32px;
+ }
+</style>
+```
+
+The iron elements include several sets of icons.
+To use the default set of icons, import `iron-icons.html` and use the `icon` attribute to specify an icon:
+
+```html
+<!-- import default iconset and iron-icon -->
+<link rel="import" href="/components/iron-icons/iron-icons.html">
+
+<iron-icon icon="menu"></iron-icon>
+```
+
+To use a different built-in set of icons, import `iron-icons/<iconset>-icons.html`, and
+specify the icon as `<iconset>:<icon>`. For example:
+
+```html
+<!-- import communication iconset and iron-icon -->
+<link rel="import" href="/components/iron-icons/communication-icons.html">
+
+<iron-icon icon="communication:email"></iron-icon>
+```
+
+You can also create custom icon sets of bitmap or SVG icons.
+
+Example of using an icon named `cherry` from a custom iconset with the ID `fruit`:
+
+```html
+<iron-icon icon="fruit:cherry"></iron-icon>
+```
+
+See [iron-iconset](#iron-iconset) and [iron-iconset-svg](#iron-iconset-svg) for more information about
+how to create a custom iconset.
+
+See [iron-icons](http://www.polymer-project.org/components/iron-icons/demo.html) for the default set of icons.
diff --git a/polymer_1.0.4/bower_components/iron-icon/bower.json b/polymer_1.0.4/bower_components/iron-icon/bower.json
new file mode 100644
index 0000000..9361b56
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icon/bower.json
@@ -0,0 +1,33 @@
+{
+ "name": "iron-icon",
+ "private": true,
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "An element that supports displaying an icon",
+ "main": "iron-icon.html",
+ "author": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "icon"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-icon.git"
+ },
+ "dependencies": {
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "iron-meta": "polymerelements/iron-meta#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "iron-iconset": "polymerelements/iron-iconset#^1.0.0",
+ "iron-icons": "polymerelements/iron-icons#^1.0.0",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-icon/demo/index.html b/polymer_1.0.4/bower_components/iron-icon/demo/index.html
new file mode 100644
index 0000000..ff71239
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icon/demo/index.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>iron-icon demo</title>
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-icon.html">
+ <link rel="import" href="../../iron-iconset/iron-iconset.html">
+ <link href="../../paper-styles/demo-pages.html" rel="import">
+
+ <style is="custom-style">
+ .vertical-section h4 {
+ border-left: 3px solid var(--paper-grey-300);
+ padding-left: 10px;
+ }
+
+ .vertical-section h4:hover {
+ border-left-color: var(--google-blue-700);
+ }
+ </style>
+</head>
+<body>
+ <div class="vertical-section-container centered">
+ <h4>This demo is for a single <iron-icon>. If you're looking for the
+ whole set of available icons, check out the <iron-icons> demo.</h4>
+
+ <div class="vertical-section">
+ <!-- iron-icon using a iron-iconset as its icon source -->
+ <iron-iconset name="example" icons="location" src="location.png" size="24" width="24"></iron-iconset>
+
+ <h4><iron-icon icon="example:location"></h4>
+ <iron-icon icon="example:location"></iron-icon>
+
+ <!-- iron-icon using an image url as its icon source -->
+ <h4><iron-icon src="location.png"></h4>
+ <iron-icon src="location.png"></iron-icon>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-icon/demo/location.png b/polymer_1.0.4/bower_components/iron-icon/demo/location.png
new file mode 100644
index 0000000..9bb7423
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icon/demo/location.png
Binary files differ
diff --git a/polymer_1.0.4/bower_components/iron-icon/hero.svg b/polymer_1.0.4/bower_components/iron-icon/hero.svg
new file mode 100755
index 0000000..f0f5853
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icon/hero.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <circle cx="112" cy="61" r="8"/>
+ <path d="M129,78H95V44h34V78z M97,76h30V46H97V76z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/iron-icon/index.html b/polymer_1.0.4/bower_components/iron-icon/index.html
new file mode 100644
index 0000000..e871f17
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icon/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-icon/iron-icon.html b/polymer_1.0.4/bower_components/iron-icon/iron-icon.html
new file mode 100644
index 0000000..bdb55c7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icon/iron-icon.html
@@ -0,0 +1,179 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-meta/iron-meta.html">
+<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
+
+<!--
+
+The `iron-icon` element displays an icon. By default an icon renders as a 24px square.
+
+Example using src:
+
+ <iron-icon src="star.png"></iron-icon>
+
+Example setting size to 32px x 32px:
+
+ <iron-icon class="big" src="big_star.png"></iron-icon>
+
+ <style is="custom-style">
+ .big {
+ --iron-icon-height: 32px;
+ --iron-icon-width: 32px;
+ }
+ </style>
+
+The iron elements include several sets of icons.
+To use the default set of icons, import `iron-icons.html` and use the `icon` attribute to specify an icon:
+
+ <!-- import default iconset and iron-icon -->
+ <link rel="import" href="/components/iron-icons/iron-icons.html">
+
+ <iron-icon icon="menu"></iron-icon>
+
+To use a different built-in set of icons, import `iron-icons/<iconset>-icons.html`, and
+specify the icon as `<iconset>:<icon>`. For example:
+
+ <!-- import communication iconset and iron-icon -->
+ <link rel="import" href="/components/iron-icons/communication-icons.html">
+
+ <iron-icon icon="communication:email"></iron-icon>
+
+You can also create custom icon sets of bitmap or SVG icons.
+
+Example of using an icon named `cherry` from a custom iconset with the ID `fruit`:
+
+ <iron-icon icon="fruit:cherry"></iron-icon>
+
+See [iron-iconset](#iron-iconset) and [iron-iconset-svg](#iron-iconset-svg) for more information about
+how to create a custom iconset.
+
+See [iron-icons](https://elements.polymer-project.org/elements/iron-icons?view=demo:demo/index.html) for the default set of icons.
+
+
+### Styling
+
+The following custom properties are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--iron-icon-width` | Width of the icon | `24px`
+`--iron-icon-height` | Height of the icon | `24px`
+
+@group Iron Elements
+@element iron-icon
+@demo demo/index.html
+@hero hero.svg
+@homepage polymer.github.io
+-->
+
+<dom-module id="iron-icon">
+
+ <style>
+ :host {
+ @apply(--layout-inline);
+ @apply(--layout-center-center);
+ position: relative;
+
+ vertical-align: middle;
+
+ fill: currentcolor;
+
+ width: var(--iron-icon-width, 24px);
+ height: var(--iron-icon-height, 24px);
+ }
+ </style>
+
+ <template>
+ <iron-meta id="meta" type="iconset"></iron-meta>
+ </template>
+
+ <script>
+
+ Polymer({
+
+ is: 'iron-icon',
+
+ properties: {
+
+ /**
+ * The name of the icon to use. The name should be of the form:
+ * `iconset_name:icon_name`.
+ */
+ icon: {
+ type: String,
+ observer: '_iconChanged'
+ },
+
+ /**
+ * The name of the theme to used, if one is specified by the
+ * iconset.
+ */
+ theme: {
+ type: String,
+ observer: '_updateIcon'
+ },
+
+ /**
+ * If using iron-icon without an iconset, you can set the src to be
+ * the URL of an individual icon image file. Note that this will take
+ * precedence over a given icon attribute.
+ */
+ src: {
+ type: String,
+ observer: '_srcChanged'
+ }
+ },
+
+ _DEFAULT_ICONSET: 'icons',
+
+ _iconChanged: function(icon) {
+ var parts = (icon || '').split(':');
+ this._iconName = parts.pop();
+ this._iconsetName = parts.pop() || this._DEFAULT_ICONSET;
+ this._updateIcon();
+ },
+
+ _srcChanged: function(src) {
+ this._updateIcon();
+ },
+
+ _usesIconset: function() {
+ return this.icon || !this.src;
+ },
+
+ _updateIcon: function() {
+ if (this._usesIconset()) {
+ if (this._iconsetName) {
+ this._iconset = this.$.meta.byKey(this._iconsetName);
+ if (this._iconset) {
+ this._iconset.applyIcon(this, this._iconName, this.theme);
+ } else {
+ this._warn(this._logf('_updateIcon', 'could not find iconset `'
+ + this._iconsetName + '`, did you import the iconset?'));
+ }
+ }
+ } else {
+ if (!this._img) {
+ this._img = document.createElement('img');
+ this._img.style.width = '100%';
+ this._img.style.height = '100%';
+ }
+ this._img.src = this.src;
+ Polymer.dom(this.root).appendChild(this._img);
+ }
+ }
+
+ });
+
+ </script>
+
+</dom-module>
diff --git a/polymer_1.0.4/bower_components/iron-icon/test/index.html b/polymer_1.0.4/bower_components/iron-icon/test/index.html
new file mode 100644
index 0000000..0a56bb7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icon/test/index.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+
+</head>
+<body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'iron-icon.html'
+ ]);
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-icon/test/iron-icon.html b/polymer_1.0.4/bower_components/iron-icon/test/iron-icon.html
new file mode 100644
index 0000000..3b8202f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icon/test/iron-icon.html
@@ -0,0 +1,120 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-icon</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../iron-icon.html">
+ <link rel="import" href="../../iron-iconset/iron-iconset.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+
+</head>
+<body>
+
+ <test-fixture id="TrivialIcon">
+ <template>
+ <iron-icon src="../demo/location.png"></iron-icon>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="IconFromIconset">
+ <template>
+ <iron-iconset name="example" icons="location blank" src="location.png" size="24" width="48"></iron-iconset>
+ <iron-icon icon="example:location"></iron-icon>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="WithoutAnIconSource">
+ <template>
+ <iron-icon icon=""></iron-icon>
+ <iron-icon></iron-icon>
+ <iron-icon src=""></iron-icon>
+ </template>
+ </test-fixture>
+
+ <script>
+function iconElementFor (node) {
+ var nodes = Polymer.dom(node.root).childNodes;
+
+ for (var i = 0; i < nodes.length; ++i) {
+ if (nodes[i].nodeName.match(/DIV|IMG/)) {
+ return nodes[i];
+ }
+ }
+}
+
+function hasIcon (node) {
+ return /png/.test(node.style.backgroundImage);
+}
+
+suite('<iron-icon>', function() {
+ suite('basic behavior', function() {
+ var icon;
+
+ setup(function() {
+ icon = fixture('TrivialIcon');
+ });
+
+ test('can be assigned an icon with the src attribute', function() {
+ expect(iconElementFor(icon)).to.be.ok;
+ expect(iconElementFor(icon).src).to.match(/demo\/location\.png/);
+ });
+
+ test('can change its src dynamically', function() {
+ icon.src = 'foo.png';
+
+ expect(iconElementFor(icon).src).to.match(/foo\.png/);
+ });
+ });
+
+ suite('when paired with an iconset', function() {
+ var icon;
+
+ setup(function() {
+ var elements = fixture('IconFromIconset');
+
+ icon = elements[1];
+ });
+
+ test('can be assigned an icon from the iconset', function() {
+ expect(hasIcon(icon)).to.be.ok;
+ });
+
+ test('can change its icon dynamically', function() {
+ var style = icon.style;
+
+ expect(style.backgroundPosition).to.match(/0(%|px) 0(%|px)/);
+
+ icon.icon = "example:blank";
+
+ expect(style.backgroundPosition).to.match(/-24px 0(%|px)/);
+ });
+ });
+
+ suite('when no icon source is provided', function() {
+ test('will politely wait for an icon source without throwing', function() {
+ document.createElement('iron-icon');
+ fixture('WithoutAnIconSource');
+ });
+ })
+});
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-icons/.bower.json b/polymer_1.0.4/bower_components/iron-icons/.bower.json
new file mode 100644
index 0000000..93ce65e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/.bower.json
@@ -0,0 +1,46 @@
+{
+ "name": "iron-icons",
+ "version": "1.0.3",
+ "description": "A set of icons for use with iron-icon",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "icon"
+ ],
+ "main": "iron-icons.html",
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-icons"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-icons",
+ "dependencies": {
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "iron-iconset-svg": "polymerelements/iron-iconset-svg#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "iron-component-page": "polymerelements/iron-component-page#1.0.0",
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "iron-meta": "polymerelements/iron-meta#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "ignore": [
+ "util",
+ "update-icons.sh"
+ ],
+ "_release": "1.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.3",
+ "commit": "036325be99c33c052ac807a705aacad70be1127f"
+ },
+ "_source": "git://github.com/PolymerElements/iron-icons.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-icons"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-icons/.gitignore b/polymer_1.0.4/bower_components/iron-icons/.gitignore
new file mode 100644
index 0000000..bb1944e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/.gitignore
@@ -0,0 +1,3 @@
+util/node_modules
+material-design-icons
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-icons/README.md b/polymer_1.0.4/bower_components/iron-icons/README.md
new file mode 100644
index 0000000..5502532
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/README.md
@@ -0,0 +1,6 @@
+iron-icons
+=========
+
+## Building
+Running `update-icons.sh` will checkout [material-design-icons](https://github.com/google/material-design-icons), reduce
+the fileset to 24px svgs, and compile the iconsets.
diff --git a/polymer_1.0.4/bower_components/iron-icons/av-icons.html b/polymer_1.0.4/bower_components/iron-icons/av-icons.html
new file mode 100644
index 0000000..0d6ff37
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/av-icons.html
@@ -0,0 +1,73 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-iconset-svg/iron-iconset-svg.html">
+<iron-iconset-svg name="av" size="24">
+<svg><defs>
+<g id="airplay"><defs><path id="a" d="M0 0h24v24H0V0z"/></defs><defs><path id="c" d="M0 0h24v24H0V0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><clipPath id="d" clip-path="url(#b)"><use xlink:href="#c" overflow="visible"/></clipPath><path d="M6 22h12l-6-6zM21 3H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h4v-2H3V5h18v12h-4v2h4c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z" clip-path="url(#d)"/></g>
+<g id="album"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z"/></g>
+<g id="av-timer"><path d="M11 17c0 .55.45 1 1 1s1-.45 1-1-.45-1-1-1-1 .45-1 1zm0-14v4h2V5.08c3.39.49 6 3.39 6 6.92 0 3.87-3.13 7-7 7s-7-3.13-7-7c0-1.68.59-3.22 1.58-4.42L12 13l1.41-1.41-6.8-6.8v.02C4.42 6.45 3 9.05 3 12c0 4.97 4.02 9 9 9 4.97 0 9-4.03 9-9s-4.03-9-9-9h-1zm7 9c0-.55-.45-1-1-1s-1 .45-1 1 .45 1 1 1 1-.45 1-1zM6 12c0 .55.45 1 1 1s1-.45 1-1-.45-1-1-1-1 .45-1 1z"/></g>
+<g id="closed-caption"><path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z"/></g>
+<g id="equalizer"><path d="M10 20h4V4h-4v16zm-6 0h4v-8H4v8zM16 9v11h4V9h-4z"/></g>
+<g id="explicit"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 6h-4v2h4v2h-4v2h4v2H9V7h6v2z"/></g>
+<g id="fast-forward"><path d="M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z"/></g>
+<g id="fast-rewind"><path d="M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z"/></g>
+<g id="forward-10"><defs><path id="a" d="M24 24H0V0h24v24z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path d="M4 13c0 4.4 3.6 8 8 8s8-3.6 8-8h-2c0 3.3-2.7 6-6 6s-6-2.7-6-6 2.7-6 6-6v4l5-5-5-5v4c-4.4 0-8 3.6-8 8zm6.8 3H10v-3.3L9 13v-.7l1.8-.6h.1V16zm4.3-1.8c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1.3.2.5.3.2.3.3.6.1.5.1.8v.7zm-.8-.8v-.5s-.1-.2-.1-.3-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5z" clip-path="url(#b)"/></g>
+<g id="forward-30"><defs><path id="a" d="M24 24H0V0h24v24z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path d="M9.6 13.5h.4c.2 0 .4-.1.5-.2s.2-.2.2-.4v-.2s-.1-.1-.1-.2-.1-.1-.2-.1h-.5s-.1.1-.2.1-.1.1-.1.2v.2h-1c0-.2 0-.3.1-.5s.2-.3.3-.4.3-.2.4-.2.4-.1.5-.1c.2 0 .4 0 .6.1s.3.1.5.2.2.2.3.4.1.3.1.5v.3s-.1.2-.1.3-.1.2-.2.2-.2.1-.3.2c.2.1.4.2.5.4s.2.4.2.6c0 .2 0 .4-.1.5s-.2.3-.3.4-.3.2-.5.2-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.4-.1-.6h.8v.2s.1.1.1.2.1.1.2.1h.5s.1-.1.2-.1.1-.1.1-.2v-.5s-.1-.1-.1-.2-.1-.1-.2-.1h-.6v-.7zm5.7.7c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1.3.2.5.3.2.3.3.6.1.5.1.8v.7zm-.9-.8v-.5s-.1-.2-.1-.3-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5zM4 13c0 4.4 3.6 8 8 8s8-3.6 8-8h-2c0 3.3-2.7 6-6 6s-6-2.7-6-6 2.7-6 6-6v4l5-5-5-5v4c-4.4 0-8 3.6-8 8z" clip-path="url(#b)"/></g>
+<g id="forward-5"><defs><path id="a" d="M24 24H0V0h24v24z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path d="M4 13c0 4.4 3.6 8 8 8s8-3.6 8-8h-2c0 3.3-2.7 6-6 6s-6-2.7-6-6 2.7-6 6-6v4l5-5-5-5v4c-4.4 0-8 3.6-8 8zm6.7.9l.2-2.2h2.4v.7h-1.7l-.1.9s.1 0 .1-.1.1 0 .1-.1.1 0 .2 0h.2c.2 0 .4 0 .5.1s.3.2.4.3.2.3.3.5.1.4.1.6c0 .2 0 .4-.1.5s-.1.3-.3.5-.3.2-.5.3-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.3-.1-.5h.8c0 .2.1.3.2.4s.2.1.4.1c.1 0 .2 0 .3-.1l.2-.2s.1-.2.1-.3v-.6l-.1-.2-.2-.2s-.2-.1-.3-.1h-.2s-.1 0-.2.1-.1 0-.1.1-.1.1-.1.1h-.6z" clip-path="url(#b)"/></g>
+<g id="games"><path d="M15 7.5V2H9v5.5l3 3 3-3zM7.5 9H2v6h5.5l3-3-3-3zM9 16.5V22h6v-5.5l-3-3-3 3zM16.5 9l-3 3 3 3H22V9h-5.5z"/></g>
+<g id="hd"><path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-8 12H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm2-6h4c.55 0 1 .45 1 1v4c0 .55-.45 1-1 1h-4V9zm1.5 4.5h2v-3h-2v3z"/></g>
+<g id="hearing"><path d="M17 20c-.29 0-.56-.06-.76-.15-.71-.37-1.21-.88-1.71-2.38-.51-1.56-1.47-2.29-2.39-3-.79-.61-1.61-1.24-2.32-2.53C9.29 10.98 9 9.93 9 9c0-2.8 2.2-5 5-5s5 2.2 5 5h2c0-3.93-3.07-7-7-7S7 5.07 7 9c0 1.26.38 2.65 1.07 3.9.91 1.65 1.98 2.48 2.85 3.15.81.62 1.39 1.07 1.71 2.05.6 1.82 1.37 2.84 2.73 3.55.51.23 1.07.35 1.64.35 2.21 0 4-1.79 4-4h-2c0 1.1-.9 2-2 2zM7.64 2.64L6.22 1.22C4.23 3.21 3 5.96 3 9s1.23 5.79 3.22 7.78l1.41-1.41C6.01 13.74 5 11.49 5 9s1.01-4.74 2.64-6.36zM11.5 9c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5-1.12-2.5-2.5-2.5-2.5 1.12-2.5 2.5z"/></g>
+<g id="high-quality"><path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 11H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 .55-.45 1-1 1h-.75v1.5h-1.5V15H14c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v4zm-3.5-.5h2v-3h-2v3z"/></g>
+<g id="library-add"><path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9h-4v4h-2v-4H9V9h4V5h2v4h4v2z"/></g>
+<g id="library-books"><path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9H9V9h10v2zm-4 4H9v-2h6v2zm4-8H9V5h10v2z"/></g>
+<g id="library-music"><path d="M20 2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 5h-3v5.5c0 1.38-1.12 2.5-2.5 2.5S10 13.88 10 12.5s1.12-2.5 2.5-2.5c.57 0 1.08.19 1.5.51V5h4v2zM4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6z"/></g>
+<g id="loop"><path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/></g>
+<g id="mic"><path d="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z"/></g>
+<g id="mic-none"><path d="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm-1.2-9.1c0-.66.54-1.2 1.2-1.2.66 0 1.2.54 1.2 1.2l-.01 6.2c0 .66-.53 1.2-1.19 1.2-.66 0-1.2-.54-1.2-1.2V4.9zm6.5 6.1c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z"/></g>
+<g id="mic-off"><path d="M19 11h-1.7c0 .74-.16 1.43-.43 2.05l1.23 1.23c.56-.98.9-2.09.9-3.28zm-4.02.17c0-.06.02-.11.02-.17V5c0-1.66-1.34-3-3-3S9 3.34 9 5v.18l5.98 5.99zM4.27 3L3 4.27l6.01 6.01V11c0 1.66 1.33 3 2.99 3 .22 0 .44-.03.65-.08l1.66 1.66c-.71.33-1.5.52-2.31.52-2.76 0-5.3-2.1-5.3-5.1H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c.91-.13 1.77-.45 2.54-.9L19.73 21 21 19.73 4.27 3z"/></g>
+<g id="movie"><path d="M18 4l2 4h-3l-2-4h-2l2 4h-3l-2-4H8l2 4H7L5 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4h-4z"/></g>
+<g id="new-releases"><path d="M23 12l-2.44-2.78.34-3.68-3.61-.82-1.89-3.18L12 3 8.6 1.54 6.71 4.72l-3.61.81.34 3.68L1 12l2.44 2.78-.34 3.69 3.61.82 1.89 3.18L12 21l3.4 1.46 1.89-3.18 3.61-.82-.34-3.68L23 12zm-10 5h-2v-2h2v2zm0-4h-2V7h2v6z"/></g>
+<g id="not-interested"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8 0-1.85.63-3.55 1.69-4.9L16.9 18.31C15.55 19.37 13.85 20 12 20zm6.31-3.1L7.1 5.69C8.45 4.63 10.15 4 12 4c4.42 0 8 3.58 8 8 0 1.85-.63 3.55-1.69 4.9z"/></g>
+<g id="pause"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></g>
+<g id="pause-circle-filled"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 14H9V8h2v8zm4 0h-2V8h2v8z"/></g>
+<g id="pause-circle-outline"><path d="M9 16h2V8H9v8zm3-14C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm1-4h2V8h-2v8z"/></g>
+<g id="play-arrow"><path d="M8 5v14l11-7z"/></g>
+<g id="play-circle-filled"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 14.5v-9l6 4.5-6 4.5z"/></g>
+<g id="play-circle-outline"><path d="M10 16.5l6-4.5-6-4.5v9zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></g>
+<g id="playlist-add"><path d="M14 10H2v2h12v-2zm0-4H2v2h12V6zm4 8v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zM2 16h8v-2H2v2z"/></g>
+<g id="queue"><path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9h-4v4h-2v-4H9V9h4V5h2v4h4v2z"/></g>
+<g id="queue-music"><path d="M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z"/></g>
+<g id="radio"><path d="M3.24 6.15C2.51 6.43 2 7.17 2 8v12c0 1.1.89 2 2 2h16c1.11 0 2-.9 2-2V8c0-1.11-.89-2-2-2H8.3l8.26-3.34L15.88 1 3.24 6.15zM7 20c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm13-8h-2v-2h-2v2H4V8h16v4z"/></g>
+<g id="recent-actors"><path d="M21 5v14h2V5h-2zm-4 14h2V5h-2v14zM14 5H2c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zM8 7.75c1.24 0 2.25 1.01 2.25 2.25S9.24 12.25 8 12.25 5.75 11.24 5.75 10 6.76 7.75 8 7.75zM12.5 17h-9v-.75c0-1.5 3-2.25 4.5-2.25s4.5.75 4.5 2.25V17z"/></g>
+<g id="repeat"><path d="M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4z"/></g>
+<g id="repeat-one"><path d="M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4zm-4-2V9h-1l-2 1v1h1.5v4H13z"/></g>
+<g id="replay"><path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"/></g>
+<g id="replay-10"><defs><path id="a" d="M0 0h24v24H0V0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path d="M12 5V1L7 6l5 5V7c3.3 0 6 2.7 6 6s-2.7 6-6 6-6-2.7-6-6H4c0 4.4 3.6 8 8 8s8-3.6 8-8-3.6-8-8-8zm-1.1 11H10v-3.3L9 13v-.7l1.8-.6h.1V16zm4.3-1.8c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1c.2.1.3.2.5.3s.2.3.3.6.1.5.1.8v.7zm-.9-.8v-.5s-.1-.2-.1-.3-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5z" clip-path="url(#b)"/></g>
+<g id="replay-30"><defs><path id="a" d="M0 0h24v24H0V0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path d="M12 5V1L7 6l5 5V7c3.3 0 6 2.7 6 6s-2.7 6-6 6-6-2.7-6-6H4c0 4.4 3.6 8 8 8s8-3.6 8-8-3.6-8-8-8zm-2.4 8.5h.4c.2 0 .4-.1.5-.2s.2-.2.2-.4v-.2s-.1-.1-.1-.2-.1-.1-.2-.1h-.5s-.1.1-.2.1-.1.1-.1.2v.2h-1c0-.2 0-.3.1-.5s.2-.3.3-.4.3-.2.4-.2.4-.1.5-.1c.2 0 .4 0 .6.1s.3.1.5.2.2.2.3.4.1.3.1.5v.3s-.1.2-.1.3-.1.2-.2.2-.2.1-.3.2c.2.1.4.2.5.4s.2.4.2.6c0 .2 0 .4-.1.5s-.2.3-.3.4-.3.2-.5.2-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.4-.1-.6h.8v.2s.1.1.1.2.1.1.2.1h.5s.1-.1.2-.1.1-.1.1-.2v-.5s-.1-.1-.1-.2-.1-.1-.2-.1h-.6v-.7zm5.7.7c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1.3.2.5.3.2.3.3.6.1.5.1.8v.7zm-.8-.8v-.5c0-.1-.1-.2-.1-.3s-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5z" clip-path="url(#b)"/></g>
+<g id="replay-5"><defs><path id="a" d="M0 0h24v24H0V0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path d="M12 5V1L7 6l5 5V7c3.3 0 6 2.7 6 6s-2.7 6-6 6-6-2.7-6-6H4c0 4.4 3.6 8 8 8s8-3.6 8-8-3.6-8-8-8zm-1.3 8.9l.2-2.2h2.4v.7h-1.7l-.1.9s.1 0 .1-.1.1 0 .1-.1.1 0 .2 0h.2c.2 0 .4 0 .5.1s.3.2.4.3.2.3.3.5.1.4.1.6c0 .2 0 .4-.1.5s-.1.3-.3.5-.3.2-.4.3-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.3-.1-.5h.8c0 .2.1.3.2.4s.2.1.4.1c.1 0 .2 0 .3-.1l.2-.2s.1-.2.1-.3v-.6l-.1-.2-.2-.2s-.2-.1-.3-.1h-.2s-.1 0-.2.1-.1 0-.1.1-.1.1-.1.1h-.7z" clip-path="url(#b)"/></g>
+<g id="shuffle"><path d="M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z"/></g>
+<g id="skip-next"><path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/></g>
+<g id="skip-previous"><path d="M6 6h2v12H6zm3.5 6l8.5 6V6z"/></g>
+<g id="snooze"><path d="M7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm-3-9h3.63L9 15.2V17h6v-2h-3.63L15 10.8V9H9v2z"/></g>
+<g id="sort-by-alpha"><path d="M14.94 4.66h-4.72l2.36-2.36zm-4.69 14.71h4.66l-2.33 2.33zM6.1 6.27L1.6 17.73h1.84l.92-2.45h5.11l.92 2.45h1.84L7.74 6.27H6.1zm-1.13 7.37l1.94-5.18 1.94 5.18H4.97zm10.76 2.5h6.12v1.59h-8.53v-1.29l5.92-8.56h-5.88v-1.6h8.3v1.26l-5.93 8.6z"/></g>
+<g id="stop"><path d="M6 6h12v12H6z"/></g>
+<g id="subtitles"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM4 12h4v2H4v-2zm10 6H4v-2h10v2zm6 0h-4v-2h4v2zm0-4H10v-2h10v2z"/></g>
+<g id="surround-sound"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM7.76 16.24l-1.41 1.41C4.78 16.1 4 14.05 4 12c0-2.05.78-4.1 2.34-5.66l1.41 1.41C6.59 8.93 6 10.46 6 12s.59 3.07 1.76 4.24zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm5.66 1.66l-1.41-1.41C17.41 15.07 18 13.54 18 12s-.59-3.07-1.76-4.24l1.41-1.41C19.22 7.9 20 9.95 20 12c0 2.05-.78 4.1-2.34 5.66zM12 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></g>
+<g id="video-library"><path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-8 12.5v-9l6 4.5-6 4.5z"/></g>
+<g id="videocam"><path d="M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z"/></g>
+<g id="videocam-off"><path d="M21 6.5l-4 4V7c0-.55-.45-1-1-1H9.82L21 17.18V6.5zM3.27 2L2 3.27 4.73 6H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.21 0 .39-.08.54-.18L19.73 21 21 19.73 3.27 2z"/></g>
+<g id="volume-down"><path d="M18.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM5 9v6h4l5 5V4L9 9H5z"/></g>
+<g id="volume-mute"><path d="M7 9v6h4l5 5V4l-5 5H7z"/></g>
+<g id="volume-off"><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/></g>
+<g id="volume-up"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></g>
+<g id="web"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-5 14H4v-4h11v4zm0-5H4V9h11v4zm5 5h-4V9h4v9z"/></g>
+</defs></svg>
+</iron-iconset-svg>
diff --git a/polymer_1.0.4/bower_components/iron-icons/bower.json b/polymer_1.0.4/bower_components/iron-icons/bower.json
new file mode 100644
index 0000000..8ec25db
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "iron-icons",
+ "version": "1.0.3",
+ "description": "A set of icons for use with iron-icon",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "icon"
+ ],
+ "main": "iron-icons.html",
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-icons"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-icons",
+ "dependencies": {
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "iron-iconset-svg": "polymerelements/iron-iconset-svg#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "iron-component-page": "polymerelements/iron-component-page#1.0.0",
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "iron-meta": "polymerelements/iron-meta#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "ignore": [
+ "util",
+ "update-icons.sh"
+ ]
+}
diff --git a/polymer_1.0.4/bower_components/iron-icons/communication-icons.html b/polymer_1.0.4/bower_components/iron-icons/communication-icons.html
new file mode 100644
index 0000000..ec72704
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/communication-icons.html
@@ -0,0 +1,59 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-iconset-svg/iron-iconset-svg.html">
+<iron-iconset-svg name="communication" size="24">
+<svg><defs>
+<g id="business"><path d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"/></g>
+<g id="call"><path d="M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z"/></g>
+<g id="call-end"><path d="M12 9c-1.6 0-3.15.25-4.6.72v3.1c0 .39-.23.74-.56.9-.98.49-1.87 1.12-2.66 1.85-.18.18-.43.28-.7.28-.28 0-.53-.11-.71-.29L.29 13.08c-.18-.17-.29-.42-.29-.7 0-.28.11-.53.29-.71C3.34 8.78 7.46 7 12 7s8.66 1.78 11.71 4.67c.18.18.29.43.29.71 0 .28-.11.53-.29.71l-2.48 2.48c-.18.18-.43.29-.71.29-.27 0-.52-.11-.7-.28-.79-.74-1.69-1.36-2.67-1.85-.33-.16-.56-.5-.56-.9v-3.1C15.15 9.25 13.6 9 12 9z"/></g>
+<g id="call-made"><path d="M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5z"/></g>
+<g id="call-merge"><path d="M17 20.41L18.41 19 15 15.59 13.59 17 17 20.41zM7.5 8H11v5.59L5.59 19 7 20.41l6-6V8h3.5L12 3.5 7.5 8z"/></g>
+<g id="call-missed"><path d="M19.59 7L12 14.59 6.41 9H11V7H3v8h2v-4.59l7 7 9-9z"/></g>
+<g id="call-received"><path d="M20 5.41L18.59 4 7 15.59V9H5v10h10v-2H8.41z"/></g>
+<g id="call-split"><path d="M14 4l2.29 2.29-2.88 2.88 1.42 1.42 2.88-2.88L20 10V4zm-4 0H4v6l2.29-2.29 4.71 4.7V20h2v-8.41l-5.29-5.3z"/></g>
+<g id="chat"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 9h12v2H6V9zm8 5H6v-2h8v2zm4-6H6V6h12v2z"/></g>
+<g id="chat-bubble"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2z"/></g>
+<g id="chat-bubble-outline"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/></g>
+<g id="clear-all"><path d="M5 13h14v-2H5v2zm-2 4h14v-2H3v2zM7 7v2h14V7H7z"/></g>
+<g id="comment"><path d="M21.99 4c0-1.1-.89-2-1.99-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4-.01-18zM18 14H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/></g>
+<g id="contact-phone"><path d="M22 3H2C.9 3 0 3.9 0 5v14c0 1.1.9 2 2 2h20c1.1 0 1.99-.9 1.99-2L24 5c0-1.1-.9-2-2-2zM8 6c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H2v-1c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1zm3.85-4h1.64L21 16l-1.99 1.99c-1.31-.98-2.28-2.38-2.73-3.99-.18-.64-.28-1.31-.28-2s.1-1.36.28-2c.45-1.62 1.42-3.01 2.73-3.99L21 8l-1.51 2h-1.64c-.22.63-.35 1.3-.35 2s.13 1.37.35 2z"/></g>
+<g id="contacts"><path d="M20 0H4v2h16V0zM4 24h16v-2H4v2zM20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 2.75c1.24 0 2.25 1.01 2.25 2.25s-1.01 2.25-2.25 2.25S9.75 10.24 9.75 9 10.76 6.75 12 6.75zM17 17H7v-1.5c0-1.67 3.33-2.5 5-2.5s5 .83 5 2.5V17z"/></g>
+<g id="dialer-sip"><path d="M17 3h-1v5h1V3zm-2 2h-2V4h2V3h-3v3h2v1h-2v1h3V5zm3-2v5h1V6h2V3h-3zm2 2h-1V4h1v1zm0 10.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.01.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.59l2.2-2.21c.27-.26.35-.65.24-1C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1z"/></g>
+<g id="dialpad"><path d="M12 19c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zM6 1c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12-8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm-6 8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></g>
+<g id="email"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></g>
+<g id="forum"><path d="M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1z"/></g>
+<g id="import-export"><path d="M9 3L5 6.99h3V14h2V6.99h3L9 3zm7 14.01V10h-2v7.01h-3L15 21l4-3.99h-3z"/></g>
+<g id="invert-colors-off"><path d="M20.65 20.87l-2.35-2.35-6.3-6.29-3.56-3.57-1.42-1.41L4.27 4.5 3 5.77l2.78 2.78c-2.55 3.14-2.36 7.76.56 10.69C7.9 20.8 9.95 21.58 12 21.58c1.79 0 3.57-.59 5.03-1.78l2.7 2.7L21 21.23l-.35-.36zM12 19.59c-1.6 0-3.11-.62-4.24-1.76C6.62 16.69 6 15.19 6 13.59c0-1.32.43-2.57 1.21-3.6L12 14.77v4.82zM12 5.1v4.58l7.25 7.26c1.37-2.96.84-6.57-1.6-9.01L12 2.27l-3.7 3.7 1.41 1.41L12 5.1z"/></g>
+<g id="live-help"><path d="M19 2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h4l3 3 3-3h4c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-6 16h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 11.9 13 12.5 13 14h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"/></g>
+<g id="location-off"><path d="M12 6.5c1.38 0 2.5 1.12 2.5 2.5 0 .74-.33 1.39-.83 1.85l3.63 3.63c.98-1.86 1.7-3.8 1.7-5.48 0-3.87-3.13-7-7-7-1.98 0-3.76.83-5.04 2.15l3.19 3.19c.46-.52 1.11-.84 1.85-.84zm4.37 9.6l-4.63-4.63-.11-.11L3.27 3 2 4.27l3.18 3.18C5.07 7.95 5 8.47 5 9c0 5.25 7 13 7 13s1.67-1.85 3.38-4.35L18.73 21 20 19.73l-3.63-3.63z"/></g>
+<g id="location-on"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/></g>
+<g id="mail"><path d="M21 8V7l-3 2-3-2v1l3 2 3-2zm1-5H2C.9 3 0 3.9 0 5v14c0 1.1.9 2 2 2h20c1.1 0 1.99-.9 1.99-2L24 5c0-1.1-.9-2-2-2zM8 6c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H2v-1c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1zm8-6h-8V6h8v6z"/></g>
+<g id="message"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/></g>
+<g id="no-sim"><path d="M18.99 5c0-1.1-.89-2-1.99-2h-7L7.66 5.34 19 16.68 18.99 5zM3.65 3.88L2.38 5.15 5 7.77V19c0 1.1.9 2 2 2h10.01c.35 0 .67-.1.96-.26l1.88 1.88 1.27-1.27L3.65 3.88z"/></g>
+<g id="phone"><path d="M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z"/></g>
+<g id="phonelink-erase"><path d="M13 8.2l-1-1-4 4-4-4-1 1 4 4-4 4 1 1 4-4 4 4 1-1-4-4 4-4zM19 1H9c-1.1 0-2 .9-2 2v3h2V4h10v16H9v-2H7v3c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2z"/></g>
+<g id="phonelink-lock"><path d="M19 1H9c-1.1 0-2 .9-2 2v3h2V4h10v16H9v-2H7v3c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm-8.2 10V9.5C10.8 8.1 9.4 7 8 7S5.2 8.1 5.2 9.5V11c-.6 0-1.2.6-1.2 1.2v3.5c0 .7.6 1.3 1.2 1.3h5.5c.7 0 1.3-.6 1.3-1.2v-3.5c0-.7-.6-1.3-1.2-1.3zm-1.3 0h-3V9.5c0-.8.7-1.3 1.5-1.3s1.5.5 1.5 1.3V11z"/></g>
+<g id="phonelink-ring"><path d="M20.1 7.7l-1 1c1.8 1.8 1.8 4.6 0 6.5l1 1c2.5-2.3 2.5-6.1 0-8.5zM18 9.8l-1 1c.5.7.5 1.6 0 2.3l1 1c1.2-1.2 1.2-3 0-4.3zM14 1H4c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 19H4V4h10v16z"/></g>
+<g id="phonelink-setup"><path d="M11.8 12.5v-1l1.1-.8c.1-.1.1-.2.1-.3l-1-1.7c-.1-.1-.2-.2-.3-.1l-1.3.4c-.3-.2-.6-.4-.9-.5l-.2-1.3c0-.1-.1-.2-.3-.2H7c-.1 0-.2.1-.3.2l-.2 1.3c-.3.1-.6.3-.9.5l-1.3-.5c-.1 0-.2 0-.3.1l-1 1.7c-.1.1 0 .2.1.3l1.1.8v1l-1.1.8c-.1.2-.1.3-.1.4l1 1.7c.1.1.2.2.3.1l1.4-.4c.3.2.6.4.9.5l.2 1.3c-.1.1.1.2.2.2h2c.1 0 .2-.1.3-.2l.2-1.3c.3-.1.6-.3.9-.5l1.3.5c.1 0 .2 0 .3-.1l1-1.7c.1-.1 0-.2-.1-.3l-1.1-.9zM8 14c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM19 1H9c-1.1 0-2 .9-2 2v3h2V4h10v16H9v-2H7v3c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2z"/></g>
+<g id="portable-wifi-off"><path d="M17.56 14.24c.28-.69.44-1.45.44-2.24 0-3.31-2.69-6-6-6-.79 0-1.55.16-2.24.44l1.62 1.62c.2-.03.41-.06.62-.06 2.21 0 4 1.79 4 4 0 .21-.02.42-.05.63l1.61 1.61zM12 4c4.42 0 8 3.58 8 8 0 1.35-.35 2.62-.95 3.74l1.47 1.47C21.46 15.69 22 13.91 22 12c0-5.52-4.48-10-10-10-1.91 0-3.69.55-5.21 1.47l1.46 1.46C9.37 4.34 10.65 4 12 4zM3.27 2.5L2 3.77l2.1 2.1C2.79 7.57 2 9.69 2 12c0 3.7 2.01 6.92 4.99 8.65l1-1.73C5.61 17.53 4 14.96 4 12c0-1.76.57-3.38 1.53-4.69l1.43 1.44C6.36 9.68 6 10.8 6 12c0 2.22 1.21 4.15 3 5.19l1-1.74c-1.19-.7-2-1.97-2-3.45 0-.65.17-1.25.44-1.79l1.58 1.58L10 12c0 1.1.9 2 2 2l.21-.02.01.01 7.51 7.51L21 20.23 4.27 3.5l-1-1z"/></g>
+<g id="present-to-all"><path d="M21 3H3c-1.11 0-2 .89-2 2v14c0 1.11.89 2 2 2h18c1.11 0 2-.89 2-2V5c0-1.11-.89-2-2-2zm0 16.02H3V4.98h18v14.04zM10 12H8l4-4 4 4h-2v4h-4v-4z"/></g>
+<g id="ring-volume"><path d="M23.71 16.67C20.66 13.78 16.54 12 12 12 7.46 12 3.34 13.78.29 16.67c-.18.18-.29.43-.29.71 0 .28.11.53.29.71l2.48 2.48c.18.18.43.29.71.29.27 0 .52-.11.7-.28.79-.74 1.69-1.36 2.66-1.85.33-.16.56-.5.56-.9v-3.1c1.45-.48 3-.73 4.6-.73s3.15.25 4.6.72v3.1c0 .39.23.74.56.9.98.49 1.87 1.12 2.66 1.85.18.18.43.28.7.28.28 0 .53-.11.71-.29l2.48-2.48c.18-.18.29-.43.29-.71 0-.27-.11-.52-.29-.7zM21.16 6.26l-1.41-1.41-3.56 3.55 1.41 1.41s3.45-3.52 3.56-3.55zM13 2h-2v5h2V2zM6.4 9.81L7.81 8.4 4.26 4.84 2.84 6.26c.11.03 3.56 3.55 3.56 3.55z"/></g>
+<g id="speaker-phone"><path d="M7 7.07L8.43 8.5c.91-.91 2.18-1.48 3.57-1.48s2.66.57 3.57 1.48L17 7.07C15.72 5.79 13.95 5 12 5s-3.72.79-5 2.07zM12 1C8.98 1 6.24 2.23 4.25 4.21l1.41 1.41C7.28 4 9.53 3 12 3s4.72 1 6.34 2.62l1.41-1.41C17.76 2.23 15.02 1 12 1zm2.86 9.01L9.14 10C8.51 10 8 10.51 8 11.14v9.71c0 .63.51 1.14 1.14 1.14h5.71c.63 0 1.14-.51 1.14-1.14v-9.71c.01-.63-.5-1.13-1.13-1.13zM15 20H9v-8h6v8z"/></g>
+<g id="stay-current-landscape"><path d="M1.01 7L1 17c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2H3c-1.1 0-1.99.9-1.99 2zM19 7v10H5V7h14z"/></g>
+<g id="stay-current-portrait"><path d="M17 1.01L7 1c-1.1 0-1.99.9-1.99 2v18c0 1.1.89 2 1.99 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z"/></g>
+<g id="stay-primary-landscape"><path d="M1.01 7L1 17c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2H3c-1.1 0-1.99.9-1.99 2zM19 7v10H5V7h14z"/></g>
+<g id="stay-primary-portrait"><path d="M17 1.01L7 1c-1.1 0-1.99.9-1.99 2v18c0 1.1.89 2 1.99 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z"/></g>
+<g id="swap-calls"><path d="M18 4l-4 4h3v7c0 1.1-.9 2-2 2s-2-.9-2-2V8c0-2.21-1.79-4-4-4S5 5.79 5 8v7H2l4 4 4-4H7V8c0-1.1.9-2 2-2s2 .9 2 2v7c0 2.21 1.79 4 4 4s4-1.79 4-4V8h3l-4-4z"/></g>
+<g id="textsms"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM9 11H7V9h2v2zm4 0h-2V9h2v2zm4 0h-2V9h2v2z"/></g>
+<g id="voicemail"><path d="M18.5 6C15.46 6 13 8.46 13 11.5c0 1.33.47 2.55 1.26 3.5H9.74c.79-.95 1.26-2.17 1.26-3.5C11 8.46 8.54 6 5.5 6S0 8.46 0 11.5 2.46 17 5.5 17h13c3.04 0 5.5-2.46 5.5-5.5S21.54 6 18.5 6zm-13 9C3.57 15 2 13.43 2 11.5S3.57 8 5.5 8 9 9.57 9 11.5 7.43 15 5.5 15zm13 0c-1.93 0-3.5-1.57-3.5-3.5S16.57 8 18.5 8 22 9.57 22 11.5 20.43 15 18.5 15z"/></g>
+<g id="vpn-key"><path d="M12.65 10C11.83 7.67 9.61 6 7 6c-3.31 0-6 2.69-6 6s2.69 6 6 6c2.61 0 4.83-1.67 5.65-4H17v4h4v-4h2v-4H12.65zM7 14c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></g>
+</defs></svg>
+</iron-iconset-svg>
diff --git a/polymer_1.0.4/bower_components/iron-icons/demo/index.html b/polymer_1.0.4/bower_components/iron-icons/demo/index.html
new file mode 100644
index 0000000..d5daf8f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/demo/index.html
@@ -0,0 +1,132 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-icons</title>
+
+ <!-- polyfill WebComponents, if needed -->
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <!-- styles for the demo -->
+ <link href="../../paper-styles/demo-pages.html" rel="import">
+
+ <!-- load layout classes -->
+ <link rel="import" href="../../iron-flex-layout/classes/iron-flex-layout.html">
+
+ <!-- load default iconset -->
+ <link rel="import" href="../iron-icons.html">
+
+ <!-- load the rest -->
+ <link rel="import" href="../av-icons.html">
+ <link rel="import" href="../communication-icons.html">
+ <link rel="import" href="../device-icons.html">
+ <link rel="import" href="../editor-icons.html">
+ <link rel="import" href="../hardware-icons.html">
+ <link rel="import" href="../image-icons.html">
+ <link rel="import" href="../maps-icons.html">
+ <link rel="import" href="../notification-icons.html">
+ <link rel="import" href="../social-icons.html">
+
+ <style is="custom-style">
+
+ h2 {
+ text-transform: capitalize;
+ }
+
+ iron-icon {
+ transition: all 0.2s;
+ -webkit-transition: all 0.2s;
+ }
+
+ iron-icon:hover {
+ fill: var(--google-yellow-700);
+ }
+
+ .set {
+ margin: auto;
+ padding: 1em 0;
+ border-bottom: 1px solid silver;
+ }
+
+ .set:last-of-type {
+ border-bottom: none;
+ }
+
+ .set:nth-of-type(4n-3) {
+ color: var(--paper-grey-700);
+ }
+
+ .set:nth-of-type(4n-2) {
+ color: var(--google-yellow-300);
+ }
+
+ .set:nth-of-type(4n-1) {
+ color: var(--google-green-500);
+ }
+
+ .set:nth-of-type(4n) {
+ color: var( --google-blue-500);
+ }
+
+ .container {
+ min-width: 10em;
+ padding: 1em 0.5em;
+ text-align: center;
+ }
+
+ .container > div {
+ margin-top: 0.5em;
+ color: black;
+ font-size: 10px;
+ }
+
+ </style>
+
+</head>
+<body>
+
+
+ <template is="dom-bind">
+
+ <iron-meta type="iconset" list="{{iconsets}}"></iron-meta>
+
+ <template is="dom-repeat" items="{{iconsets}}">
+
+ <h2>{{item.name}}</h2>
+
+ <div class="set horizontal wrap layout">
+
+ <template is="dom-repeat" items="{{getIconNames(item)}}">
+
+ <span class="container vertical center layout flex-1">
+ <iron-icon icon="{{item}}"></iron-icon>
+ <div>{{item}}</div>
+ </span>
+
+ </template>
+
+ </div>
+
+ </template>
+
+ </template>
+
+ <script>
+
+ document.querySelector('[is=dom-bind]').getIconNames = function(iconset) {
+ return iconset.getIconNames();
+ };
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-icons/device-icons.html b/polymer_1.0.4/bower_components/iron-icons/device-icons.html
new file mode 100644
index 0000000..e875a05
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/device-icons.html
@@ -0,0 +1,94 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-iconset-svg/iron-iconset-svg.html">
+<iron-iconset-svg name="device" size="24">
+<svg><defs>
+<g id="access-alarm"><path d="M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12.5 8H11v6l4.75 2.85.75-1.23-4-2.37V8zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></g>
+<g id="access-alarms"><path d="M22 5.7l-4.6-3.9-1.3 1.5 4.6 3.9L22 5.7zM7.9 3.4L6.6 1.9 2 5.7l1.3 1.5 4.6-3.8zM12.5 8H11v6l4.7 2.9.8-1.2-4-2.4V8zM12 4c-5 0-9 4-9 9s4 9 9 9 9-4 9-9-4-9-9-9zm0 16c-3.9 0-7-3.1-7-7s3.1-7 7-7 7 3.1 7 7-3.1 7-7 7z"/></g>
+<g id="access-time"><path fill-opacity=".9" d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zM12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"/></g>
+<g id="add-alarm"><path d="M7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm1-11h-2v3H8v2h3v3h2v-3h3v-2h-3V9z"/></g>
+<g id="airplanemode-active"><path d="M10.18 9"/><path d="M21 16v-2l-8-5V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5V9l-8 5v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-5.5l8 2.5z"/></g>
+<g id="airplanemode-inactive"><path d="M13 9V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5v3.68l7.83 7.83L21 16v-2l-8-5zM3 5.27l4.99 4.99L2 14v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-3.73L18.73 21 20 19.73 4.27 4 3 5.27z"/></g>
+<g id="battery-20"><path d="M7 17v3.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V17H7z"/><path fill-opacity=".3" d="M17 5.33C17 4.6 16.4 4 15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V17h10V5.33z"/></g>
+<g id="battery-30"><path fill-opacity=".3" d="M17 5.33C17 4.6 16.4 4 15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V15h10V5.33z"/><path d="M7 15v5.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V15H7z"/></g>
+<g id="battery-50"><path fill-opacity=".3" d="M17 5.33C17 4.6 16.4 4 15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V13h10V5.33z"/><path d="M7 13v7.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V13H7z"/></g>
+<g id="battery-60"><path fill-opacity=".3" d="M17 5.33C17 4.6 16.4 4 15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V11h10V5.33z"/><path d="M7 11v9.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V11H7z"/></g>
+<g id="battery-80"><path fill-opacity=".3" d="M17 5.33C17 4.6 16.4 4 15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V9h10V5.33z"/><path d="M7 9v11.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V9H7z"/></g>
+<g id="battery-90"><path fill-opacity=".3" d="M17 5.33C17 4.6 16.4 4 15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V8h10V5.33z"/><path d="M7 8v12.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V8H7z"/></g>
+<g id="battery-alert"><path d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v15.33C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V5.33C17 4.6 16.4 4 15.67 4zM13 18h-2v-2h2v2zm0-4h-2V9h2v5z"/></g>
+<g id="battery-charging-20"><path d="M11 20v-3H7v3.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V17h-4.4L11 20z"/><path fill-opacity=".3" d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V17h4v-2.5H9L13 7v5.5h2L12.6 17H17V5.33C17 4.6 16.4 4 15.67 4z"/></g>
+<g id="battery-charging-30"><path fill-opacity=".3" d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v9.17h2L13 7v5.5h2l-1.07 2H17V5.33C17 4.6 16.4 4 15.67 4z"/><path d="M11 20v-5.5H7v6.17C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V14.5h-3.07L11 20z"/></g>
+<g id="battery-charging-50"><path d="M14.47 13.5L11 20v-5.5H9l.53-1H7v7.17C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V13.5h-2.53z"/><path fill-opacity=".3" d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v8.17h2.53L13 7v5.5h2l-.53 1H17V5.33C17 4.6 16.4 4 15.67 4z"/></g>
+<g id="battery-charging-60"><path fill-opacity=".3" d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V11h3.87L13 7v4h4V5.33C17 4.6 16.4 4 15.67 4z"/><path d="M13 12.5h2L11 20v-5.5H9l1.87-3.5H7v9.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V11h-4v1.5z"/></g>
+<g id="battery-charging-80"><path fill-opacity=".3" d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V9h4.93L13 7v2h4V5.33C17 4.6 16.4 4 15.67 4z"/><path d="M13 12.5h2L11 20v-5.5H9L11.93 9H7v11.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V9h-4v3.5z"/></g>
+<g id="battery-charging-90"><path fill-opacity=".3" d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33V8h5.47L13 7v1h4V5.33C17 4.6 16.4 4 15.67 4z"/><path d="M13 12.5h2L11 20v-5.5H9L12.47 8H7v12.67C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V8h-4v4.5z"/></g>
+<g id="battery-charging-full"><path d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v15.33C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V5.33C17 4.6 16.4 4 15.67 4zM11 20v-5.5H9L13 7v5.5h2L11 20z"/></g>
+<g id="battery-full"><path d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v15.33C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V5.33C17 4.6 16.4 4 15.67 4z"/></g>
+<g id="battery-std"><path d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v15.33C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V5.33C17 4.6 16.4 4 15.67 4z"/></g>
+<g id="battery-unknown"><path d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v15.33C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V5.33C17 4.6 16.4 4 15.67 4zm-2.72 13.95h-1.9v-1.9h1.9v1.9zm1.35-5.26s-.38.42-.67.71c-.48.48-.83 1.15-.83 1.6h-1.6c0-.83.46-1.52.93-2l.93-.94c.27-.27.44-.65.44-1.06 0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5H9c0-1.66 1.34-3 3-3s3 1.34 3 3c0 .66-.27 1.26-.7 1.69z"/></g>
+<g id="bluetooth"><path d="M17.71 7.71L12 2h-1v7.59L6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 11 14.41V22h1l5.71-5.71-4.3-4.29 4.3-4.29zM13 5.83l1.88 1.88L13 9.59V5.83zm1.88 10.46L13 18.17v-3.76l1.88 1.88z"/></g>
+<g id="bluetooth-connected"><path d="M7 12l-2-2-2 2 2 2 2-2zm10.71-4.29L12 2h-1v7.59L6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 11 14.41V22h1l5.71-5.71-4.3-4.29 4.3-4.29zM13 5.83l1.88 1.88L13 9.59V5.83zm1.88 10.46L13 18.17v-3.76l1.88 1.88zM19 10l-2 2 2 2 2-2-2-2z"/></g>
+<g id="bluetooth-disabled"><path d="M13 5.83l1.88 1.88-1.6 1.6 1.41 1.41 3.02-3.02L12 2h-1v5.03l2 2v-3.2zM5.41 4L4 5.41 10.59 12 5 17.59 6.41 19 11 14.41V22h1l4.29-4.29 2.3 2.29L20 18.59 5.41 4zM13 18.17v-3.76l1.88 1.88L13 18.17z"/></g>
+<g id="bluetooth-searching"><path d="M14.24 12.01l2.32 2.32c.28-.72.44-1.51.44-2.33 0-.82-.16-1.59-.43-2.31l-2.33 2.32zm5.29-5.3l-1.26 1.26c.63 1.21.98 2.57.98 4.02s-.36 2.82-.98 4.02l1.2 1.2c.97-1.54 1.54-3.36 1.54-5.31-.01-1.89-.55-3.67-1.48-5.19zm-3.82 1L10 2H9v7.59L4.41 5 3 6.41 8.59 12 3 17.59 4.41 19 9 14.41V22h1l5.71-5.71-4.3-4.29 4.3-4.29zM11 5.83l1.88 1.88L11 9.59V5.83zm1.88 10.46L11 18.17v-3.76l1.88 1.88z"/></g>
+<g id="brightness-auto"><path d="M10.85 12.65h2.3L12 9l-1.15 3.65zM20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69zM14.3 16l-.7-2h-3.2l-.7 2H7.8L11 7h2l3.2 9h-1.9z"/></g>
+<g id="brightness-high"><path d="M20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69zM12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6zm0-10c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4z"/></g>
+<g id="brightness-low"><path d="M20 15.31L23.31 12 20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69zM12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6z"/></g>
+<g id="brightness-medium"><path d="M20 15.31L23.31 12 20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69zM12 18V6c3.31 0 6 2.69 6 6s-2.69 6-6 6z"/></g>
+<g id="data-usage"><path d="M13 2.05v3.03c3.39.49 6 3.39 6 6.92 0 .9-.18 1.75-.48 2.54l2.6 1.53c.56-1.24.88-2.62.88-4.07 0-5.18-3.95-9.45-9-9.95zM12 19c-3.87 0-7-3.13-7-7 0-3.53 2.61-6.43 6-6.92V2.05c-5.06.5-9 4.76-9 9.95 0 5.52 4.47 10 9.99 10 3.31 0 6.24-1.61 8.06-4.09l-2.6-1.53C16.17 17.98 14.21 19 12 19z"/></g>
+<g id="developer-mode"><path d="M7 5h10v2h2V3c0-1.1-.9-1.99-2-1.99L7 1c-1.1 0-2 .9-2 2v4h2V5zm8.41 11.59L20 12l-4.59-4.59L14 8.83 17.17 12 14 15.17l1.41 1.42zM10 15.17L6.83 12 10 8.83 8.59 7.41 4 12l4.59 4.59L10 15.17zM17 19H7v-2H5v4c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2v-4h-2v2z"/></g>
+<g id="devices"><path d="M4 6h18V4H4c-1.1 0-2 .9-2 2v11H0v3h14v-3H4V6zm19 2h-6c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1zm-1 9h-4v-7h4v7z"/></g>
+<g id="dvr"><path d="M21 3H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.1-.9-2-2-2zm0 14H3V5h18v12zm-2-9H8v2h11V8zm0 4H8v2h11v-2zM7 8H5v2h2V8zm0 4H5v2h2v-2z"/></g>
+<g id="gps-fixed"><path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm8.94 3c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></g>
+<g id="gps-not-fixed"><path d="M20.94 11c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></g>
+<g id="gps-off"><path d="M20.94 11c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06c-1.13.12-2.19.46-3.16.97l1.5 1.5C10.16 5.19 11.06 5 12 5c3.87 0 7 3.13 7 7 0 .94-.19 1.84-.52 2.65l1.5 1.5c.5-.96.84-2.02.97-3.15H23v-2h-2.06zM3 4.27l2.04 2.04C3.97 7.62 3.25 9.23 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c1.77-.2 3.38-.91 4.69-1.98L19.73 21 21 19.73 4.27 3 3 4.27zm13.27 13.27C15.09 18.45 13.61 19 12 19c-3.87 0-7-3.13-7-7 0-1.61.55-3.09 1.46-4.27l9.81 9.81z"/></g>
+<g id="graphic-eq"><path d="M7 18h2V6H7v12zm4 4h2V2h-2v20zm-8-8h2v-4H3v4zm12 4h2V6h-2v12zm4-8v4h2v-4h-2z"/></g>
+<g id="location-disabled"><path d="M20.94 11c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06c-1.13.12-2.19.46-3.16.97l1.5 1.5C10.16 5.19 11.06 5 12 5c3.87 0 7 3.13 7 7 0 .94-.19 1.84-.52 2.65l1.5 1.5c.5-.96.84-2.02.97-3.15H23v-2h-2.06zM3 4.27l2.04 2.04C3.97 7.62 3.25 9.23 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c1.77-.2 3.38-.91 4.69-1.98L19.73 21 21 19.73 4.27 3 3 4.27zm13.27 13.27C15.09 18.45 13.61 19 12 19c-3.87 0-7-3.13-7-7 0-1.61.55-3.09 1.46-4.27l9.81 9.81z"/></g>
+<g id="location-searching"><path d="M20.94 11c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></g>
+<g id="network-cell"><path fill-opacity=".3" d="M2 22h20V2z"/><path d="M17 7L2 22h15z"/></g>
+<g id="network-wifi"><path fill-opacity=".3" d="M12.01 21.49L23.64 7c-.45-.34-4.93-4-11.64-4C5.28 3 .81 6.66.36 7l11.63 14.49.01.01.01-.01z"/><path d="M3.53 10.95l8.46 10.54.01.01.01-.01 8.46-10.54C20.04 10.62 16.81 8 12 8c-4.81 0-8.04 2.62-8.47 2.95z"/></g>
+<g id="nfc"><path d="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 18H4V4h16v16zM18 6h-5c-1.1 0-2 .9-2 2v2.28c-.6.35-1 .98-1 1.72 0 1.1.9 2 2 2s2-.9 2-2c0-.74-.4-1.38-1-1.72V8h3v8H8V8h2V6H6v12h12V6z"/></g>
+<g id="screen-lock-landscape"><path d="M21 5H3c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-2 12H5V7h14v10zm-9-1h4c.55 0 1-.45 1-1v-3c0-.55-.45-1-1-1v-1c0-1.11-.9-2-2-2-1.11 0-2 .9-2 2v1c-.55 0-1 .45-1 1v3c0 .55.45 1 1 1zm.8-6c0-.66.54-1.2 1.2-1.2.66 0 1.2.54 1.2 1.2v1h-2.4v-1z"/></g>
+<g id="screen-lock-portrait"><path d="M10 16h4c.55 0 1-.45 1-1v-3c0-.55-.45-1-1-1v-1c0-1.11-.9-2-2-2-1.11 0-2 .9-2 2v1c-.55 0-1 .45-1 1v3c0 .55.45 1 1 1zm.8-6c0-.66.54-1.2 1.2-1.2.66 0 1.2.54 1.2 1.2v1h-2.4v-1zM17 1H7c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 18H7V5h10v14z"/></g>
+<g id="screen-lock-rotation"><path d="M23.25 12.77l-2.57-2.57-1.41 1.41 2.22 2.22-5.66 5.66L4.51 8.17l5.66-5.66 2.1 2.1 1.41-1.41L11.23.75c-.59-.59-1.54-.59-2.12 0L2.75 7.11c-.59.59-.59 1.54 0 2.12l12.02 12.02c.59.59 1.54.59 2.12 0l6.36-6.36c.59-.59.59-1.54 0-2.12zM8.47 20.48C5.2 18.94 2.86 15.76 2.5 12H1c.51 6.16 5.66 11 11.95 11l.66-.03-3.81-3.82-1.33 1.33zM16 9h5c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1v-.5C21 1.12 19.88 0 18.5 0S16 1.12 16 2.5V3c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1zm.8-6.5c0-.94.76-1.7 1.7-1.7s1.7.76 1.7 1.7V3h-3.4v-.5z"/></g>
+<g id="screen-rotation"><path d="M16.48 2.52c3.27 1.55 5.61 4.72 5.97 8.48h1.5C23.44 4.84 18.29 0 12 0l-.66.03 3.81 3.81 1.33-1.32zm-6.25-.77c-.59-.59-1.54-.59-2.12 0L1.75 8.11c-.59.59-.59 1.54 0 2.12l12.02 12.02c.59.59 1.54.59 2.12 0l6.36-6.36c.59-.59.59-1.54 0-2.12L10.23 1.75zm4.6 19.44L2.81 9.17l6.36-6.36 12.02 12.02-6.36 6.36zm-7.31.29C4.25 19.94 1.91 16.76 1.55 13H.05C.56 19.16 5.71 24 12 24l.66-.03-3.81-3.81-1.33 1.32z"/></g>
+<g id="sd-storage"><path d="M18 2h-8L4.02 8 4 20c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-6 6h-2V4h2v4zm3 0h-2V4h2v4zm3 0h-2V4h2v4z"/></g>
+<g id="settings-system-daydream"><path d="M9 16h6.5c1.38 0 2.5-1.12 2.5-2.5S16.88 11 15.5 11h-.05c-.24-1.69-1.69-3-3.45-3-1.4 0-2.6.83-3.16 2.02h-.16C7.17 10.18 6 11.45 6 13c0 1.66 1.34 3 3 3zM21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02z"/></g>
+<g id="signal-cellular-0-bar"><path fill-opacity=".3" d="M2 22h20V2z"/></g>
+<g id="signal-cellular-1-bar"><path fill-opacity=".3" d="M2 22h20V2z"/><path d="M12 12L2 22h10z"/></g>
+<g id="signal-cellular-2-bar"><path fill-opacity=".3" d="M2 22h20V2z"/><path d="M14 10L2 22h12z"/></g>
+<g id="signal-cellular-3-bar"><path fill-opacity=".3" d="M2 22h20V2z"/><path d="M17 7L2 22h15z"/></g>
+<g id="signal-cellular-4-bar"><path d="M2 22h20V2z"/></g>
+<g id="signal-cellular-connected-no-internet-0-bar"><path fill-opacity=".3" d="M22 8V2L2 22h16V8z"/><path d="M20 22h2v-2h-2v2zm0-12v8h2v-8h-2z"/></g>
+<g id="signal-cellular-connected-no-internet-1-bar"><path fill-opacity=".3" d="M22 8V2L2 22h16V8z"/><path d="M20 10v8h2v-8h-2zm-8 12V12L2 22h10zm8 0h2v-2h-2v2z"/></g>
+<g id="signal-cellular-connected-no-internet-2-bar"><path fill-opacity=".3" d="M22 8V2L2 22h16V8z"/><path d="M14 22V10L2 22h12zm6-12v8h2v-8h-2zm0 12h2v-2h-2v2z"/></g>
+<g id="signal-cellular-connected-no-internet-3-bar"><path fill-opacity=".3" d="M22 8V2L2 22h16V8z"/><path d="M17 22V7L2 22h15zm3-12v8h2v-8h-2zm0 12h2v-2h-2v2z"/></g>
+<g id="signal-cellular-connected-no-internet-4-bar"><path d="M20 18h2v-8h-2v8zm0 4h2v-2h-2v2zM2 22h16V8h4V2L2 22z"/></g>
+<g id="signal-cellular-no-sim"><path d="M18.99 5c0-1.1-.89-2-1.99-2h-7L7.66 5.34 19 16.68 18.99 5zM3.65 3.88L2.38 5.15 5 7.77V19c0 1.1.9 2 2 2h10.01c.35 0 .67-.1.96-.26l1.88 1.88 1.27-1.27L3.65 3.88z"/></g>
+<g id="signal-cellular-null"><path d="M20 6.83V20H6.83L20 6.83M22 2L2 22h20V2z"/></g>
+<g id="signal-cellular-off"><path d="M21 1l-8.59 8.59L21 18.18V1zM4.77 4.5L3.5 5.77l6.36 6.36L1 21h17.73l2 2L22 21.73 4.77 4.5z"/></g>
+<g id="signal-wifi-0-bar"><path fill-opacity=".3" d="M12.01 21.49L23.64 7c-.45-.34-4.93-4-11.64-4C5.28 3 .81 6.66.36 7l11.63 14.49.01.01.01-.01z"/></g>
+<g id="signal-wifi-1-bar"><path fill-opacity=".3" d="M12.01 21.49L23.64 7c-.45-.34-4.93-4-11.64-4C5.28 3 .81 6.66.36 7l11.63 14.49.01.01.01-.01z"/><path d="M6.67 14.86L12 21.49v.01l.01-.01 5.33-6.63C17.06 14.65 15.03 13 12 13s-5.06 1.65-5.33 1.86z"/></g>
+<g id="signal-wifi-1-bar-lock"><path d="M23 16v-1.5c0-1.4-1.1-2.5-2.5-2.5S18 13.1 18 14.5V16c-.5 0-1 .5-1 1v4c0 .5.5 1 1 1h5c.5 0 1-.5 1-1v-4c0-.5-.5-1-1-1zm-1 0h-3v-1.5c0-.8.7-1.5 1.5-1.5s1.5.7 1.5 1.5V16z"/><path d="M15.5 14.5c0-2.8 2.2-5 5-5 .4 0 .7 0 1 .1L23.6 7c-.4-.3-4.9-4-11.6-4C5.3 3 .8 6.7.4 7L12 21.5l3.5-4.3v-2.7z" opacity=".3"/><path d="M6.7 14.9l5.3 6.6 3.5-4.3v-2.6c0-.2 0-.5.1-.7-.9-.5-2.2-.9-3.6-.9-3 0-5.1 1.7-5.3 1.9z"/></g>
+<g id="signal-wifi-2-bar"><path fill-opacity=".3" d="M12.01 21.49L23.64 7c-.45-.34-4.93-4-11.64-4C5.28 3 .81 6.66.36 7l11.63 14.49.01.01.01-.01z"/><path d="M4.79 12.52l7.2 8.98H12l.01-.01 7.2-8.98C18.85 12.24 16.1 10 12 10s-6.85 2.24-7.21 2.52z"/></g>
+<g id="signal-wifi-2-bar-lock"><path d="M23 16v-1.5c0-1.4-1.1-2.5-2.5-2.5S18 13.1 18 14.5V16c-.5 0-1 .5-1 1v4c0 .5.5 1 1 1h5c.5 0 1-.5 1-1v-4c0-.5-.5-1-1-1zm-1 0h-3v-1.5c0-.8.7-1.5 1.5-1.5s1.5.7 1.5 1.5V16z"/><path d="M15.5 14.5c0-2.8 2.2-5 5-5 .4 0 .7 0 1 .1L23.6 7c-.4-.3-4.9-4-11.6-4C5.3 3 .8 6.7.4 7L12 21.5l3.5-4.3v-2.7z" opacity=".3"/><path d="M4.8 12.5l7.2 9 3.5-4.4v-2.6c0-1.3.5-2.5 1.4-3.4C15.6 10.5 14 10 12 10c-4.1 0-6.8 2.2-7.2 2.5z"/></g>
+<g id="signal-wifi-3-bar"><path fill-opacity=".3" d="M12.01 21.49L23.64 7c-.45-.34-4.93-4-11.64-4C5.28 3 .81 6.66.36 7l11.63 14.49.01.01.01-.01z"/><path d="M3.53 10.95l8.46 10.54.01.01.01-.01 8.46-10.54C20.04 10.62 16.81 8 12 8c-4.81 0-8.04 2.62-8.47 2.95z"/></g>
+<g id="signal-wifi-3-bar-lock"><path opacity=".3" d="M12 3C5.3 3 .8 6.7.4 7l3.2 3.9L12 21.5l3.5-4.3v-2.6c0-2.2 1.4-4 3.3-4.7.3-.1.5-.2.8-.2.3-.1.6-.1.9-.1.4 0 .7 0 1 .1L23.6 7c-.4-.3-4.9-4-11.6-4z"/><path d="M23 16v-1.5c0-1.4-1.1-2.5-2.5-2.5S18 13.1 18 14.5V16c-.5 0-1 .5-1 1v4c0 .5.5 1 1 1h5c.5 0 1-.5 1-1v-4c0-.5-.5-1-1-1zm-1 0h-3v-1.5c0-.8.7-1.5 1.5-1.5s1.5.7 1.5 1.5V16zm-10 5.5l3.5-4.3v-2.6c0-2.2 1.4-4 3.3-4.7C17.3 9 14.9 8 12 8c-4.8 0-8 2.6-8.5 2.9"/></g>
+<g id="signal-wifi-4-bar"><path d="M12.01 21.49L23.64 7c-.45-.34-4.93-4-11.64-4C5.28 3 .81 6.66.36 7l11.63 14.49.01.01.01-.01z"/></g>
+<g id="signal-wifi-4-bar-lock"><path d="M23 16v-1.5c0-1.4-1.1-2.5-2.5-2.5S18 13.1 18 14.5V16c-.5 0-1 .5-1 1v4c0 .5.5 1 1 1h5c.5 0 1-.5 1-1v-4c0-.5-.5-1-1-1zm-1 0h-3v-1.5c0-.8.7-1.5 1.5-1.5s1.5.7 1.5 1.5V16zm-6.5-1.5c0-2.8 2.2-5 5-5 .4 0 .7 0 1 .1L23.6 7c-.4-.3-4.9-4-11.6-4C5.3 3 .8 6.7.4 7L12 21.5l3.5-4.4v-2.6z"/></g>
+<g id="signal-wifi-off"><path d="M23.64 7c-.45-.34-4.93-4-11.64-4-1.5 0-2.89.19-4.15.48L18.18 13.8 23.64 7zm-6.6 8.22L3.27 1.44 2 2.72l2.05 2.06C1.91 5.76.59 6.82.36 7l11.63 14.49.01.01.01-.01 3.9-4.86 3.32 3.32 1.27-1.27-3.46-3.46z"/></g>
+<g id="storage"><path d="M2 20h20v-4H2v4zm2-3h2v2H4v-2zM2 4v4h20V4H2zm4 3H4V5h2v2zm-4 7h20v-4H2v4zm2-3h2v2H4v-2z"/></g>
+<g id="usb"><path d="M15 7v4h1v2h-3V5h2l-3-4-3 4h2v8H8v-2.07c.7-.37 1.2-1.08 1.2-1.93 0-1.21-.99-2.2-2.2-2.2-1.21 0-2.2.99-2.2 2.2 0 .85.5 1.56 1.2 1.93V13c0 1.11.89 2 2 2h3v3.05c-.71.37-1.2 1.1-1.2 1.95 0 1.22.99 2.2 2.2 2.2 1.21 0 2.2-.98 2.2-2.2 0-.85-.49-1.58-1.2-1.95V15h3c1.11 0 2-.89 2-2v-2h1V7h-4z"/></g>
+<g id="wallpaper"><path d="M4 4h7V2H4c-1.1 0-2 .9-2 2v7h2V4zm6 9l-4 5h12l-3-4-2.03 2.71L10 13zm7-4.5c0-.83-.67-1.5-1.5-1.5S14 7.67 14 8.5s.67 1.5 1.5 1.5S17 9.33 17 8.5zM20 2h-7v2h7v7h2V4c0-1.1-.9-2-2-2zm0 18h-7v2h7c1.1 0 2-.9 2-2v-7h-2v7zM4 13H2v7c0 1.1.9 2 2 2h7v-2H4v-7z"/></g>
+<g id="widgets"><path d="M13 13v8h8v-8h-8zM3 21h8v-8H3v8zM3 3v8h8V3H3zm13.66-1.31L11 7.34 16.66 13l5.66-5.66-5.66-5.65z"/></g>
+<g id="wifi-lock"><path d="M20.5 9.5c.28 0 .55.04.81.08L24 6c-3.34-2.51-7.5-4-12-4S3.34 3.49 0 6l12 16 3.5-4.67V14.5c0-2.76 2.24-5 5-5zM23 16v-1.5c0-1.38-1.12-2.5-2.5-2.5S18 13.12 18 14.5V16c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h5c.55 0 1-.45 1-1v-4c0-.55-.45-1-1-1zm-1 0h-3v-1.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V16z"/></g>
+<g id="wifi-tethering"><path d="M12 11c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 2c0-3.31-2.69-6-6-6s-6 2.69-6 6c0 2.22 1.21 4.15 3 5.19l1-1.74c-1.19-.7-2-1.97-2-3.45 0-2.21 1.79-4 4-4s4 1.79 4 4c0 1.48-.81 2.75-2 3.45l1 1.74c1.79-1.04 3-2.97 3-5.19zM12 3C6.48 3 2 7.48 2 13c0 3.7 2.01 6.92 4.99 8.65l1-1.73C5.61 18.53 4 15.96 4 13c0-4.42 3.58-8 8-8s8 3.58 8 8c0 2.96-1.61 5.53-4 6.92l1 1.73c2.99-1.73 5-4.95 5-8.65 0-5.52-4.48-10-10-10z"/></g>
+</defs></svg>
+</iron-iconset-svg>
diff --git a/polymer_1.0.4/bower_components/iron-icons/editor-icons.html b/polymer_1.0.4/bower_components/iron-icons/editor-icons.html
new file mode 100644
index 0000000..7fabfe0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/editor-icons.html
@@ -0,0 +1,70 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-iconset-svg/iron-iconset-svg.html">
+<iron-iconset-svg name="editor" size="24">
+<svg><defs>
+<g id="attach-file"><path d="M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z"/></g>
+<g id="attach-money"><path d="M11.8 10.9c-2.27-.59-3-1.2-3-2.15 0-1.09 1.01-1.85 2.7-1.85 1.78 0 2.44.85 2.5 2.1h2.21c-.07-1.72-1.12-3.3-3.21-3.81V3h-3v2.16c-1.94.42-3.5 1.68-3.5 3.61 0 2.31 1.91 3.46 4.7 4.13 2.5.6 3 1.48 3 2.41 0 .69-.49 1.79-2.7 1.79-2.06 0-2.87-.92-2.98-2.1h-2.2c.12 2.19 1.76 3.42 3.68 3.83V21h3v-2.15c1.95-.37 3.5-1.5 3.5-3.55 0-2.84-2.43-3.81-4.7-4.4z"/></g>
+<g id="border-all"><path d="M3 3v18h18V3H3zm8 16H5v-6h6v6zm0-8H5V5h6v6zm8 8h-6v-6h6v6zm0-8h-6V5h6v6z"/></g>
+<g id="border-bottom"><path d="M9 11H7v2h2v-2zm4 4h-2v2h2v-2zM9 3H7v2h2V3zm4 8h-2v2h2v-2zM5 3H3v2h2V3zm8 4h-2v2h2V7zm4 4h-2v2h2v-2zm-4-8h-2v2h2V3zm4 0h-2v2h2V3zm2 10h2v-2h-2v2zm0 4h2v-2h-2v2zM5 7H3v2h2V7zm14-4v2h2V3h-2zm0 6h2V7h-2v2zM5 11H3v2h2v-2zM3 21h18v-2H3v2zm2-6H3v2h2v-2z"/></g>
+<g id="border-clear"><path d="M7 5h2V3H7v2zm0 8h2v-2H7v2zm0 8h2v-2H7v2zm4-4h2v-2h-2v2zm0 4h2v-2h-2v2zm-8 0h2v-2H3v2zm0-4h2v-2H3v2zm0-4h2v-2H3v2zm0-4h2V7H3v2zm0-4h2V3H3v2zm8 8h2v-2h-2v2zm8 4h2v-2h-2v2zm0-4h2v-2h-2v2zm0 8h2v-2h-2v2zm0-12h2V7h-2v2zm-8 0h2V7h-2v2zm8-6v2h2V3h-2zm-8 2h2V3h-2v2zm4 16h2v-2h-2v2zm0-8h2v-2h-2v2zm0-8h2V3h-2v2z"/></g>
+<g id="border-color"><path d="M17.75 7L14 3.25l-10 10V17h3.75l10-10zm2.96-2.96c.39-.39.39-1.02 0-1.41L18.37.29c-.39-.39-1.02-.39-1.41 0L15 2.25 18.75 6l1.96-1.96z"/><path fill-opacity=".36" d="M0 20h24v4H0z"/></g>
+<g id="border-horizontal"><path d="M3 21h2v-2H3v2zM5 7H3v2h2V7zM3 17h2v-2H3v2zm4 4h2v-2H7v2zM5 3H3v2h2V3zm4 0H7v2h2V3zm8 0h-2v2h2V3zm-4 4h-2v2h2V7zm0-4h-2v2h2V3zm6 14h2v-2h-2v2zm-8 4h2v-2h-2v2zm-8-8h18v-2H3v2zM19 3v2h2V3h-2zm0 6h2V7h-2v2zm-8 8h2v-2h-2v2zm4 4h2v-2h-2v2zm4 0h2v-2h-2v2z"/></g>
+<g id="border-inner"><path d="M3 21h2v-2H3v2zm4 0h2v-2H7v2zM5 7H3v2h2V7zM3 17h2v-2H3v2zM9 3H7v2h2V3zM5 3H3v2h2V3zm12 0h-2v2h2V3zm2 6h2V7h-2v2zm0-6v2h2V3h-2zm-4 18h2v-2h-2v2zM13 3h-2v8H3v2h8v8h2v-8h8v-2h-8V3zm6 18h2v-2h-2v2zm0-4h2v-2h-2v2z"/></g>
+<g id="border-left"><path d="M11 21h2v-2h-2v2zm0-4h2v-2h-2v2zm0-12h2V3h-2v2zm0 4h2V7h-2v2zm0 4h2v-2h-2v2zm-4 8h2v-2H7v2zM7 5h2V3H7v2zm0 8h2v-2H7v2zm-4 8h2V3H3v18zM19 9h2V7h-2v2zm-4 12h2v-2h-2v2zm4-4h2v-2h-2v2zm0-14v2h2V3h-2zm0 10h2v-2h-2v2zm0 8h2v-2h-2v2zm-4-8h2v-2h-2v2zm0-8h2V3h-2v2z"/></g>
+<g id="border-outer"><path d="M13 7h-2v2h2V7zm0 4h-2v2h2v-2zm4 0h-2v2h2v-2zM3 3v18h18V3H3zm16 16H5V5h14v14zm-6-4h-2v2h2v-2zm-4-4H7v2h2v-2z"/></g>
+<g id="border-right"><path d="M7 21h2v-2H7v2zM3 5h2V3H3v2zm4 0h2V3H7v2zm0 8h2v-2H7v2zm-4 8h2v-2H3v2zm8 0h2v-2h-2v2zm-8-8h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm8 8h2v-2h-2v2zm4-4h2v-2h-2v2zm4-10v18h2V3h-2zm-4 18h2v-2h-2v2zm0-16h2V3h-2v2zm-4 8h2v-2h-2v2zm0-8h2V3h-2v2zm0 4h2V7h-2v2z"/></g>
+<g id="border-style"><path d="M15 21h2v-2h-2v2zm4 0h2v-2h-2v2zM7 21h2v-2H7v2zm4 0h2v-2h-2v2zm8-4h2v-2h-2v2zm0-4h2v-2h-2v2zM3 3v18h2V5h16V3H3zm16 6h2V7h-2v2z"/></g>
+<g id="border-top"><path d="M7 21h2v-2H7v2zm0-8h2v-2H7v2zm4 0h2v-2h-2v2zm0 8h2v-2h-2v2zm-8-4h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2v-2H3v2zm0-4h2V7H3v2zm8 8h2v-2h-2v2zm8-8h2V7h-2v2zm0 4h2v-2h-2v2zM3 3v2h18V3H3zm16 14h2v-2h-2v2zm-4 4h2v-2h-2v2zM11 9h2V7h-2v2zm8 12h2v-2h-2v2zm-4-8h2v-2h-2v2z"/></g>
+<g id="border-vertical"><path d="M3 9h2V7H3v2zm0-4h2V3H3v2zm4 16h2v-2H7v2zm0-8h2v-2H7v2zm-4 0h2v-2H3v2zm0 8h2v-2H3v2zm0-4h2v-2H3v2zM7 5h2V3H7v2zm12 12h2v-2h-2v2zm-8 4h2V3h-2v18zm8 0h2v-2h-2v2zm0-8h2v-2h-2v2zm0-10v2h2V3h-2zm0 6h2V7h-2v2zm-4-4h2V3h-2v2zm0 16h2v-2h-2v2zm0-8h2v-2h-2v2z"/></g>
+<g id="format-align-center"><path d="M7 15v2h10v-2H7zm-4 6h18v-2H3v2zm0-8h18v-2H3v2zm4-6v2h10V7H7zM3 3v2h18V3H3z"/></g>
+<g id="format-align-justify"><path d="M3 21h18v-2H3v2zm0-4h18v-2H3v2zm0-4h18v-2H3v2zm0-4h18V7H3v2zm0-6v2h18V3H3z"/></g>
+<g id="format-align-left"><path d="M15 15H3v2h12v-2zm0-8H3v2h12V7zM3 13h18v-2H3v2zm0 8h18v-2H3v2zM3 3v2h18V3H3z"/></g>
+<g id="format-align-right"><path d="M3 21h18v-2H3v2zm6-4h12v-2H9v2zm-6-4h18v-2H3v2zm6-4h12V7H9v2zM3 3v2h18V3H3z"/></g>
+<g id="format-bold"><path d="M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z"/></g>
+<g id="format-clear"><path d="M3.27 5L2 6.27l6.97 6.97L6.5 19h3l1.57-3.66L16.73 21 18 19.73 3.55 5.27 3.27 5zM6 5v.18L8.82 8h2.4l-.72 1.68 2.1 2.1L14.21 8H20V5H6z"/></g>
+<g id="format-color-fill"><path d="M16.56 8.94L7.62 0 6.21 1.41l2.38 2.38-5.15 5.15c-.59.59-.59 1.54 0 2.12l5.5 5.5c.29.29.68.44 1.06.44s.77-.15 1.06-.44l5.5-5.5c.59-.58.59-1.53 0-2.12zM5.21 10L10 5.21 14.79 10H5.21zM19 11.5s-2 2.17-2 3.5c0 1.1.9 2 2 2s2-.9 2-2c0-1.33-2-3.5-2-3.5z"/><path fill-opacity=".36" d="M0 20h24v4H0z"/></g>
+<g id="format-color-reset"><path d="M18 14c0-4-6-10.8-6-10.8s-1.33 1.51-2.73 3.52l8.59 8.59c.09-.42.14-.86.14-1.31zm-.88 3.12L12.5 12.5 5.27 5.27 4 6.55l3.32 3.32C6.55 11.32 6 12.79 6 14c0 3.31 2.69 6 6 6 1.52 0 2.9-.57 3.96-1.5l2.63 2.63 1.27-1.27-2.74-2.74z"/></g>
+<g id="format-color-text"><path fill-opacity=".36" d="M0 20h24v4H0z"/><path d="M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2zm-1.38 9L12 5.67 14.38 12H9.62z"/></g>
+<g id="format-indent-decrease"><path d="M11 17h10v-2H11v2zm-8-5l4 4V8l-4 4zm0 9h18v-2H3v2zM3 3v2h18V3H3zm8 6h10V7H11v2zm0 4h10v-2H11v2z"/></g>
+<g id="format-indent-increase"><path d="M3 21h18v-2H3v2zM3 8v8l4-4-4-4zm8 9h10v-2H11v2zM3 3v2h18V3H3zm8 6h10V7H11v2zm0 4h10v-2H11v2z"/></g>
+<g id="format-italic"><path d="M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z"/></g>
+<g id="format-line-spacing"><path d="M6 7h2.5L5 3.5 1.5 7H4v10H1.5L5 20.5 8.5 17H6V7zm4-2v2h12V5H10zm0 14h12v-2H10v2zm0-6h12v-2H10v2z"/></g>
+<g id="format-list-bulleted"><path d="M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12.17c-.74 0-1.33.6-1.33 1.33s.6 1.33 1.33 1.33 1.33-.6 1.33-1.33-.59-1.33-1.33-1.33zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z"/></g>
+<g id="format-list-numbered"><path d="M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z"/></g>
+<g id="format-paint"><path d="M18 4V3c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V6h1v4H9v11c0 .55.45 1 1 1h2c.55 0 1-.45 1-1v-9h8V4h-3z"/></g>
+<g id="format-quote"><path d="M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z"/></g>
+<g id="format-size"><path d="M9 4v3h5v12h3V7h5V4H9zm-6 8h3v7h3v-7h3V9H3v3z"/></g>
+<g id="format-strikethrough"><path d="M10 19h4v-3h-4v3zM5 4v3h5v3h4V7h5V4H5zM3 14h18v-2H3v2z"/></g>
+<g id="format-textdirection-l-to-r"><path d="M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z"/></g>
+<g id="format-textdirection-r-to-l"><path d="M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zm-2 7v-3l-4 4 4 4v-3h12v-2H8z"/></g>
+<g id="format-underlined"><path d="M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z"/></g>
+<g id="functions"><path d="M18 4H6v2l6.5 6L6 18v2h12v-3h-7l5-5-5-5h7z"/></g>
+<g id="insert-chart"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/></g>
+<g id="insert-comment"><path d="M20 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/></g>
+<g id="insert-drive-file"><path d="M6 2c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6H6zm7 7V3.5L18.5 9H13z"/></g>
+<g id="insert-emoticon"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"/></g>
+<g id="insert-invitation"><path d="M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z"/></g>
+<g id="insert-link"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></g>
+<g id="insert-photo"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/></g>
+<g id="merge-type"><path d="M17 20.41L18.41 19 15 15.59 13.59 17 17 20.41zM7.5 8H11v5.59L5.59 19 7 20.41l6-6V8h3.5L12 3.5 7.5 8z"/></g>
+<g id="mode-comment"><path d="M21.99 4c0-1.1-.89-2-1.99-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4-.01-18z"/></g>
+<g id="mode-edit"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></g>
+<g id="money-off"><path d="M12.5 6.9c1.78 0 2.44.85 2.5 2.1h2.21c-.07-1.72-1.12-3.3-3.21-3.81V3h-3v2.16c-.53.12-1.03.3-1.48.54l1.47 1.47c.41-.17.91-.27 1.51-.27zM5.33 4.06L4.06 5.33 7.5 8.77c0 2.08 1.56 3.21 3.91 3.91l3.51 3.51c-.34.48-1.05.91-2.42.91-2.06 0-2.87-.92-2.98-2.1h-2.2c.12 2.19 1.76 3.42 3.68 3.83V21h3v-2.15c.96-.18 1.82-.55 2.45-1.12l2.22 2.22 1.27-1.27L5.33 4.06z"/></g>
+<g id="publish"><path d="M5 4v2h14V4H5zm0 10h4v6h6v-6h4l-7-7-7 7z"/></g>
+<g id="space-bar"><path d="M18 9v4H6V9H4v6h16V9z"/></g>
+<g id="strikethrough-s"><path d="M5.9 10h6.3c-.8-.3-1.5-.6-2-.9-.7-.4-1-1-1-1.6 0-.3.1-.6.2-.9.1-.3.3-.5.6-.7.3-.2.6-.4 1-.5.4-.1.8-.2 1.4-.2.5 0 1 .1 1.4.2.4.1.7.3 1 .6.3.2.5.5.6.9.1.3.2.7.2 1.1h4c0-.9-.2-1.7-.5-2.4s-.8-1.4-1.4-1.9c-.6-.5-1.4-1-2.3-1.2-1-.4-2-.5-3.1-.5s-2 .1-2.9.4c-.9.3-1.6.6-2.3 1.1-.6.5-1.1 1-1.4 1.7-.4.7-.6 1.4-.6 2.2 0 .8.2 1.6.5 2.2.1.2.2.3.3.4zM23 12H1v2h11.9c.2.1.5.2.7.3.5.2.9.5 1.2.7.3.2.5.5.6.8.1.3.1.6.1.9 0 .3-.1.6-.2.9-.1.3-.3.5-.6.7-.2.2-.6.3-.9.5-.4.1-.8.2-1.4.2-.6 0-1.1-.1-1.6-.2s-.9-.3-1.2-.6c-.3-.3-.6-.6-.8-1-.2-.4-.3-1-.3-1.6h-4c0 .7.1 1.5.3 2.1.2.6.5 1.1.9 1.6s.8.9 1.3 1.2c.5.3 1 .6 1.6.9.6.2 1.2.4 1.8.5.6.1 1.3.2 1.9.2 1.1 0 2-.1 2.9-.4.9-.2 1.6-.6 2.2-1.1.6-.5 1.1-1 1.4-1.7.3-.7.5-1.4.5-2.3 0-.8-.1-1.5-.4-2.2-.1-.2-.1-.3-.2-.4H23v-2z"/></g>
+<g id="vertical-align-bottom"><path d="M16 13h-3V3h-2v10H8l4 4 4-4zM4 19v2h16v-2H4z"/></g>
+<g id="vertical-align-center"><path d="M8 19h3v4h2v-4h3l-4-4-4 4zm8-14h-3V1h-2v4H8l4 4 4-4zM4 11v2h16v-2H4z"/></g>
+<g id="vertical-align-top"><path d="M8 11h3v10h2V11h3l-4-4-4 4zM4 3v2h16V3H4z"/></g>
+<g id="wrap-text"><path d="M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3 3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"/></g>
+</defs></svg>
+</iron-iconset-svg>
diff --git a/polymer_1.0.4/bower_components/iron-icons/hardware-icons.html b/polymer_1.0.4/bower_components/iron-icons/hardware-icons.html
new file mode 100644
index 0000000..670cb07
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/hardware-icons.html
@@ -0,0 +1,61 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-iconset-svg/iron-iconset-svg.html">
+<iron-iconset-svg name="hardware" size="24">
+<svg><defs>
+<g id="cast"><path d="M21 3H3c-1.1 0-2 .9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM1 18v3h3c0-1.66-1.34-3-3-3zm0-4v2c2.76 0 5 2.24 5 5h2c0-3.87-3.13-7-7-7zm0-4v2c4.97 0 9 4.03 9 9h2c0-6.08-4.93-11-11-11z"/></g>
+<g id="cast-connected"><path d="M1 18v3h3c0-1.66-1.34-3-3-3zm0-4v2c2.76 0 5 2.24 5 5h2c0-3.87-3.13-7-7-7zm18-7H5v1.63c3.96 1.28 7.09 4.41 8.37 8.37H19V7zM1 10v2c4.97 0 9 4.03 9 9h2c0-6.08-4.93-11-11-11zm20-7H3c-1.1 0-2 .9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/></g>
+<g id="computer"><path d="M20 18c1.1 0 1.99-.9 1.99-2L22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2H0v2h24v-2h-4zM4 6h16v10H4V6z"/></g>
+<g id="desktop-mac"><path d="M21 2H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7l-2 3v1h8v-1l-2-3h7c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 12H3V4h18v10z"/></g>
+<g id="desktop-windows"><path d="M21 2H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7v2H8v2h8v-2h-2v-2h7c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H3V4h18v12z"/></g>
+<g id="developer-board"><path d="M22 9V7h-2V5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-2h2v-2h-2v-2h2v-2h-2V9h2zm-4 10H4V5h14v14zM6 13h5v4H6zm6-6h4v3h-4zM6 7h5v5H6zm6 4h4v6h-4z"/></g>
+<g id="device-hub"><path d="M17 16l-4-4V8.82C14.16 8.4 15 7.3 15 6c0-1.66-1.34-3-3-3S9 4.34 9 6c0 1.3.84 2.4 2 2.82V12l-4 4H3v5h5v-3.05l4-4.2 4 4.2V21h5v-5h-4z"/></g>
+<g id="dock"><path d="M8 23h8v-2H8v2zm8-21.99L8 1c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM16 15H8V5h8v10z"/></g>
+<g id="gamepad"><path d="M15 7.5V2H9v5.5l3 3 3-3zM7.5 9H2v6h5.5l3-3-3-3zM9 16.5V22h6v-5.5l-3-3-3 3zM16.5 9l-3 3 3 3H22V9h-5.5z"/></g>
+<g id="headset"><path d="M12 1c-4.97 0-9 4.03-9 9v7c0 1.66 1.34 3 3 3h3v-8H5v-2c0-3.87 3.13-7 7-7s7 3.13 7 7v2h-4v8h3c1.66 0 3-1.34 3-3v-7c0-4.97-4.03-9-9-9z"/></g>
+<g id="headset-mic"><path d="M12 1c-4.97 0-9 4.03-9 9v7c0 1.66 1.34 3 3 3h3v-8H5v-2c0-3.87 3.13-7 7-7s7 3.13 7 7v2h-4v8h4v1h-7v2h6c1.66 0 3-1.34 3-3V10c0-4.97-4.03-9-9-9z"/></g>
+<g id="keyboard"><path d="M20 5H4c-1.1 0-1.99.9-1.99 2L2 17c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-9 3h2v2h-2V8zm0 3h2v2h-2v-2zM8 8h2v2H8V8zm0 3h2v2H8v-2zm-1 2H5v-2h2v2zm0-3H5V8h2v2zm9 7H8v-2h8v2zm0-4h-2v-2h2v2zm0-3h-2V8h2v2zm3 3h-2v-2h2v2zm0-3h-2V8h2v2z"/></g>
+<g id="keyboard-arrow-down"><path d="M7.41 7.84L12 12.42l4.59-4.58L18 9.25l-6 6-6-6z"/></g>
+<g id="keyboard-arrow-left"><path d="M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z"/></g>
+<g id="keyboard-arrow-right"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"/></g>
+<g id="keyboard-arrow-up"><path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"/></g>
+<g id="keyboard-backspace"><path d="M21 11H6.83l3.58-3.59L9 6l-6 6 6 6 1.41-1.41L6.83 13H21z"/></g>
+<g id="keyboard-capslock"><path d="M12 8.41L16.59 13 18 11.59l-6-6-6 6L7.41 13 12 8.41zM6 18h12v-2H6v2z"/></g>
+<g id="keyboard-hide"><path d="M20 3H4c-1.1 0-1.99.9-1.99 2L2 15c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-9 3h2v2h-2V6zm0 3h2v2h-2V9zM8 6h2v2H8V6zm0 3h2v2H8V9zm-1 2H5V9h2v2zm0-3H5V6h2v2zm9 7H8v-2h8v2zm0-4h-2V9h2v2zm0-3h-2V6h2v2zm3 3h-2V9h2v2zm0-3h-2V6h2v2zm-7 15l4-4H8l4 4z"/></g>
+<g id="keyboard-return"><path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"/></g>
+<g id="keyboard-tab"><path d="M11.59 7.41L15.17 11H1v2h14.17l-3.59 3.59L13 18l6-6-6-6-1.41 1.41zM20 6v12h2V6h-2z"/></g>
+<g id="keyboard-voice"><path d="M12 15c1.66 0 2.99-1.34 2.99-3L15 6c0-1.66-1.34-3-3-3S9 4.34 9 6v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 15 6.7 12H5c0 3.42 2.72 6.23 6 6.72V22h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z"/></g>
+<g id="laptop"><path d="M20 18c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2H0v2h24v-2h-4zM4 6h16v10H4V6z"/></g>
+<g id="laptop-chromebook"><path d="M22 18V3H2v15H0v2h24v-2h-2zm-8 0h-4v-1h4v1zm6-3H4V5h16v10z"/></g>
+<g id="laptop-mac"><path d="M20 18c1.1 0 1.99-.9 1.99-2L22 5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v11c0 1.1.9 2 2 2H0c0 1.1.9 2 2 2h20c1.1 0 2-.9 2-2h-4zM4 5h16v11H4V5zm8 14c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"/></g>
+<g id="laptop-windows"><path d="M20 18v-1c1.1 0 1.99-.9 1.99-2L22 5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2v1H0v2h24v-2h-4zM4 5h16v10H4V5z"/></g>
+<g id="memory"><path d="M15 9H9v6h6V9zm-2 4h-2v-2h2v2zm8-2V9h-2V7c0-1.1-.9-2-2-2h-2V3h-2v2h-2V3H9v2H7c-1.1 0-2 .9-2 2v2H3v2h2v2H3v2h2v2c0 1.1.9 2 2 2h2v2h2v-2h2v2h2v-2h2c1.1 0 2-.9 2-2v-2h2v-2h-2v-2h2zm-4 6H7V7h10v10z"/></g>
+<g id="mouse"><path d="M13 1.07V9h7c0-4.08-3.05-7.44-7-7.93zM4 15c0 4.42 3.58 8 8 8s8-3.58 8-8v-4H4v4zm7-13.93C7.05 1.56 4 4.92 4 9h7V1.07z"/></g>
+<g id="phone-android"><path d="M16 1H8C6.34 1 5 2.34 5 4v16c0 1.66 1.34 3 3 3h8c1.66 0 3-1.34 3-3V4c0-1.66-1.34-3-3-3zm-2 20h-4v-1h4v1zm3.25-3H6.75V4h10.5v14z"/></g>
+<g id="phone-iphone"><path d="M15.5 1h-8C6.12 1 5 2.12 5 3.5v17C5 21.88 6.12 23 7.5 23h8c1.38 0 2.5-1.12 2.5-2.5v-17C18 2.12 16.88 1 15.5 1zm-4 21c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm4.5-4H7V4h9v14z"/></g>
+<g id="phonelink"><path d="M4 6h18V4H4c-1.1 0-2 .9-2 2v11H0v3h14v-3H4V6zm19 2h-6c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1zm-1 9h-4v-7h4v7z"/></g>
+<g id="phonelink-off"><path d="M22 6V4H6.82l2 2H22zM1.92 1.65L.65 2.92l1.82 1.82C2.18 5.08 2 5.52 2 6v11H0v3h17.73l2.35 2.35 1.27-1.27L3.89 3.62 1.92 1.65zM4 6.27L14.73 17H4V6.27zM23 8h-6c-.55 0-1 .45-1 1v4.18l2 2V10h4v7h-2.18l3 3H23c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1z"/></g>
+<g id="power-input"><path d="M2 9v2h19V9H2zm0 6h5v-2H2v2zm7 0h5v-2H9v2zm7 0h5v-2h-5v2z"/></g>
+<g id="router"><path d="M20.2 5.9l.8-.8C19.6 3.7 17.8 3 16 3s-3.6.7-5 2.1l.8.8C13 4.8 14.5 4.2 16 4.2s3 .6 4.2 1.7zm-.9.8c-.9-.9-2.1-1.4-3.3-1.4s-2.4.5-3.3 1.4l.8.8c.7-.7 1.6-1 2.5-1 .9 0 1.8.3 2.5 1l.8-.8zM19 13h-2V9h-2v4H5c-1.1 0-2 .9-2 2v4c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-4c0-1.1-.9-2-2-2zM8 18H6v-2h2v2zm3.5 0h-2v-2h2v2zm3.5 0h-2v-2h2v2z"/></g>
+<g id="scanner"><path d="M19.8 10.7L4.2 5l-.7 1.9L17.6 12H5c-1.1 0-2 .9-2 2v4c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-5.5c0-.8-.5-1.6-1.2-1.8zM7 17H5v-2h2v2zm12 0H9v-2h10v2z"/></g>
+<g id="security"><path d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 10.99h7c-.53 4.12-3.28 7.79-7 8.94V12H5V6.3l7-3.11v8.8z"/></g>
+<g id="sim-card"><path d="M19.99 4c0-1.1-.89-2-1.99-2h-8L4 8v12c0 1.1.9 2 2 2h12.01c1.1 0 1.99-.9 1.99-2l-.01-16zM9 19H7v-2h2v2zm8 0h-2v-2h2v2zm-8-4H7v-4h2v4zm4 4h-2v-4h2v4zm0-6h-2v-2h2v2zm4 2h-2v-4h2v4z"/></g>
+<g id="smartphone"><path d="M17 1.01L7 1c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z"/></g>
+<g id="speaker"><path d="M17 2H7c-1.1 0-2 .9-2 2v16c0 1.1.9 1.99 2 1.99L17 22c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-5 2c1.1 0 2 .9 2 2s-.9 2-2 2c-1.11 0-2-.9-2-2s.89-2 2-2zm0 16c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></g>
+<g id="speaker-group"><path d="M18.2 1H9.8C8.81 1 8 1.81 8 2.8v14.4c0 .99.81 1.79 1.8 1.79l8.4.01c.99 0 1.8-.81 1.8-1.8V2.8c0-.99-.81-1.8-1.8-1.8zM14 3c1.1 0 2 .89 2 2s-.9 2-2 2-2-.89-2-2 .9-2 2-2zm0 13.5c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z"/><circle cx="14" cy="12.5" r="2.5"/><path d="M6 5H4v16c0 1.1.89 2 2 2h10v-2H6V5z"/></g>
+<g id="tablet"><path d="M21 4H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h18c1.1 0 1.99-.9 1.99-2L23 6c0-1.1-.9-2-2-2zm-2 14H5V6h14v12z"/></g>
+<g id="tablet-android"><path d="M18 0H6C4.34 0 3 1.34 3 3v18c0 1.66 1.34 3 3 3h12c1.66 0 3-1.34 3-3V3c0-1.66-1.34-3-3-3zm-4 22h-4v-1h4v1zm5.25-3H4.75V3h14.5v16z"/></g>
+<g id="tablet-mac"><path d="M18.5 0h-14C3.12 0 2 1.12 2 2.5v19C2 22.88 3.12 24 4.5 24h14c1.38 0 2.5-1.12 2.5-2.5v-19C21 1.12 19.88 0 18.5 0zm-7 23c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm7.5-4H4V3h15v16z"/></g>
+<g id="toys"><path d="M12 12c0-3 2.5-5.5 5.5-5.5S23 9 23 12H12zm0 0c0 3-2.5 5.5-5.5 5.5S1 15 1 12h11zm0 0c-3 0-5.5-2.5-5.5-5.5S9 1 12 1v11zm0 0c3 0 5.5 2.5 5.5 5.5S15 23 12 23V12z"/></g>
+<g id="tv"><path d="M21 3H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.1-.9-2-2-2zm0 14H3V5h18v12z"/></g>
+<g id="watch"><path d="M20 12c0-2.54-1.19-4.81-3.04-6.27L16 0H8l-.95 5.73C5.19 7.19 4 9.45 4 12s1.19 4.81 3.05 6.27L8 24h8l.96-5.73C18.81 16.81 20 14.54 20 12zM6 12c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6-6-2.69-6-6z"/></g>
+</defs></svg>
+</iron-iconset-svg>
diff --git a/polymer_1.0.4/bower_components/iron-icons/hero.svg b/polymer_1.0.4/bower_components/iron-icons/hero.svg
new file mode 100755
index 0000000..167321c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/hero.svg
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <circle cx="73" cy="24" r="4"/>
+ <path d="M82,33H64V15h18V33z M66,31h14V17H66V31z"/>
+ <circle cx="112.5" cy="24" r="4"/>
+ <circle cx="151" cy="24" r="4"/>
+ <path d="M121,33h-18V15h18V33z M105,31h14V17h-14V31z"/>
+ <path d="M160,33h-18V15h18V33z M144,31h14V17h-14V31z"/>
+ <circle cx="73" cy="62" r="4"/>
+ <path d="M82,71H64V53h18V71z M66,69h14V55H66V69z"/>
+ <circle cx="112.5" cy="62" r="4"/>
+ <path d="M121,71h-18V53h18V71z M105,69h14V55h-14V69z"/>
+ <circle cx="151" cy="62" r="4"/>
+ <path d="M160,71h-18V53h18V71z M144,69h14V55h-14V69z"/>
+ <circle cx="73" cy="102" r="4"/>
+ <path d="M82,111H64V93h18V111z M66,109h14V95H66V109z"/>
+ <circle cx="112.5" cy="102" r="4"/>
+ <path d="M121,111h-18V93h18V111z M105,109h14V95h-14V109z"/>
+ <circle cx="151" cy="102" r="4"/>
+ <path d="M160,111h-18V93h18V111z M144,109h14V95h-14V109z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/iron-icons/image-icons.html b/polymer_1.0.4/bower_components/iron-icons/image-icons.html
new file mode 100644
index 0000000..f6c45f5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/image-icons.html
@@ -0,0 +1,164 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-iconset-svg/iron-iconset-svg.html">
+<iron-iconset-svg name="image" size="24">
+<svg><defs>
+<g id="add-to-photos"><path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9h-4v4h-2v-4H9V9h4V5h2v4h4v2z"/></g>
+<g id="adjust"><path d="M12 2C6.49 2 2 6.49 2 12s4.49 10 10 10 10-4.49 10-10S17.51 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm3-8c0 1.66-1.34 3-3 3s-3-1.34-3-3 1.34-3 3-3 3 1.34 3 3z"/></g>
+<g id="assistant"><path d="M19 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h4l3 3 3-3h4c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-5.12 10.88L12 17l-1.88-4.12L6 11l4.12-1.88L12 5l1.88 4.12L18 11l-4.12 1.88z"/></g>
+<g id="assistant-photo"><path d="M14.4 6L14 4H5v17h2v-7h5.6l.4 2h7V6z"/></g>
+<g id="audiotrack"><path d="M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7z"/></g>
+<g id="blur-circular"><path d="M10 9c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0 4c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zM7 9.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm3 7c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm-3-3c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm3-6c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zM14 9c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0-1.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zm3 6c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm0-4c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm2-3.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm0-3.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z"/></g>
+<g id="blur-linear"><path d="M5 17.5c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5-1.5.67-1.5 1.5.67 1.5 1.5 1.5zM9 13c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0-4c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zM3 21h18v-2H3v2zM5 9.5c.83 0 1.5-.67 1.5-1.5S5.83 6.5 5 6.5 3.5 7.17 3.5 8 4.17 9.5 5 9.5zm0 4c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5-1.5.67-1.5 1.5.67 1.5 1.5 1.5zM9 17c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm8-.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zM3 3v2h18V3H3zm14 5.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zm0 4c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zM13 9c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0 4c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0 4c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1z"/></g>
+<g id="blur-off"><path d="M14 7c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm-.2 4.48l.2.02c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5-1.5.67-1.5 1.5l.02.2c.09.67.61 1.19 1.28 1.28zM14 3.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zm-4 0c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zm11 7c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zM10 7c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm8 8c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0-4c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0-4c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm-4 13.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zM2.5 5.27l3.78 3.78L6 9c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1c0-.1-.03-.19-.06-.28l2.81 2.81c-.71.11-1.25.73-1.25 1.47 0 .83.67 1.5 1.5 1.5.74 0 1.36-.54 1.47-1.25l2.81 2.81c-.09-.03-.18-.06-.28-.06-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1c0-.1-.03-.19-.06-.28l3.78 3.78L20 20.23 3.77 4 2.5 5.27zM10 17c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm11-3.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zM6 13c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zM3 9.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm7 11c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zM6 17c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm-3-3.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5z"/></g>
+<g id="blur-on"><path d="M6 13c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0 4c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0-8c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm-3 .5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zM6 5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm15 5.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zM14 7c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0-3.5c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zm-11 10c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm7 7c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm0-17c.28 0 .5-.22.5-.5s-.22-.5-.5-.5-.5.22-.5.5.22.5.5.5zM10 7c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0 5.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm8 .5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0 4c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0-8c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0-4c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm3 8.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zM14 17c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm0 3.5c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm-4-12c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0 8.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1zm4-4.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-4c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z"/></g>
+<g id="brightness-1"><circle cx="12" cy="12" r="10"/></g>
+<g id="brightness-2"><path d="M10 2c-1.82 0-3.53.5-5 1.35C7.99 5.08 10 8.3 10 12s-2.01 6.92-5 8.65C6.47 21.5 8.18 22 10 22c5.52 0 10-4.48 10-10S15.52 2 10 2z"/></g>
+<g id="brightness-3"><path d="M9 2c-1.05 0-2.05.16-3 .46 4.06 1.27 7 5.06 7 9.54 0 4.48-2.94 8.27-7 9.54.95.3 1.95.46 3 .46 5.52 0 10-4.48 10-10S14.52 2 9 2z"/></g>
+<g id="brightness-4"><path d="M20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69zM12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6c3.31 0 6 2.69 6 6s-2.69 6-6 6z"/></g>
+<g id="brightness-5"><path d="M20 15.31L23.31 12 20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69zM12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6z"/></g>
+<g id="brightness-6"><path d="M20 15.31L23.31 12 20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69zM12 18V6c3.31 0 6 2.69 6 6s-2.69 6-6 6z"/></g>
+<g id="brightness-7"><path d="M20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69zM12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6zm0-10c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4z"/></g>
+<g id="broken-image"><path d="M21 5v6.59l-3-3.01-4 4.01-4-4-4 4-3-3.01V5c0-1.1.9-2 2-2h14c1.1 0 2 .9 2 2zm-3 6.42l3 3.01V19c0 1.1-.9 2-2 2H5c-1.1 0-2-.9-2-2v-6.58l3 2.99 4-4 4 4 4-3.99z"/></g>
+<g id="brush"><path d="M7 14c-1.66 0-3 1.34-3 3 0 1.31-1.16 2-2 2 .92 1.22 2.49 2 4 2 2.21 0 4-1.79 4-4 0-1.66-1.34-3-3-3zm13.71-9.37l-1.34-1.34c-.39-.39-1.02-.39-1.41 0L9 12.25 11.75 15l8.96-8.96c.39-.39.39-1.02 0-1.41z"/></g>
+<g id="camera"><path d="M9.4 10.5l4.77-8.26C13.47 2.09 12.75 2 12 2c-2.4 0-4.6.85-6.32 2.25l3.66 6.35.06-.1zM21.54 9c-.92-2.92-3.15-5.26-6-6.34L11.88 9h9.66zm.26 1h-7.49l.29.5 4.76 8.25C21 16.97 22 14.61 22 12c0-.69-.07-1.35-.2-2zM8.54 12l-3.9-6.75C3.01 7.03 2 9.39 2 12c0 .69.07 1.35.2 2h7.49l-1.15-2zm-6.08 3c.92 2.92 3.15 5.26 6 6.34L12.12 15H2.46zm11.27 0l-3.9 6.76c.7.15 1.42.24 2.17.24 2.4 0 4.6-.85 6.32-2.25l-3.66-6.35-.93 1.6z"/></g>
+<g id="camera-alt"><circle cx="12" cy="12" r="3.2"/><path d="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z"/></g>
+<g id="camera-front"><path d="M10 20H5v2h5v2l3-3-3-3v2zm4 0v2h5v-2h-5zM12 8c1.1 0 2-.9 2-2s-.9-2-2-2-1.99.9-1.99 2S10.9 8 12 8zm5-8H7C5.9 0 5 .9 5 2v14c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2zM7 2h10v10.5c0-1.67-3.33-2.5-5-2.5s-5 .83-5 2.5V2z"/></g>
+<g id="camera-rear"><path d="M10 20H5v2h5v2l3-3-3-3v2zm4 0v2h5v-2h-5zm3-20H7C5.9 0 5 .9 5 2v14c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2zm-5 6c-1.11 0-2-.9-2-2s.89-2 1.99-2 2 .9 2 2C14 5.1 13.1 6 12 6z"/></g>
+<g id="camera-roll"><path d="M14 5c0-1.1-.9-2-2-2h-1V2c0-.55-.45-1-1-1H6c-.55 0-1 .45-1 1v1H4c-1.1 0-2 .9-2 2v15c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2h8V5h-8zm-2 13h-2v-2h2v2zm0-9h-2V7h2v2zm4 9h-2v-2h2v2zm0-9h-2V7h2v2zm4 9h-2v-2h2v2zm0-9h-2V7h2v2z"/></g>
+<g id="center-focus-strong"><path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm-7 7H3v4c0 1.1.9 2 2 2h4v-2H5v-4zM5 5h4V3H5c-1.1 0-2 .9-2 2v4h2V5zm14-2h-4v2h4v4h2V5c0-1.1-.9-2-2-2zm0 16h-4v2h4c1.1 0 2-.9 2-2v-4h-2v4z"/></g>
+<g id="center-focus-weak"><path d="M5 15H3v4c0 1.1.9 2 2 2h4v-2H5v-4zM5 5h4V3H5c-1.1 0-2 .9-2 2v4h2V5zm14-2h-4v2h4v4h2V5c0-1.1-.9-2-2-2zm0 16h-4v2h4c1.1 0 2-.9 2-2v-4h-2v4zM12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></g>
+<g id="collections"><path d="M22 16V4c0-1.1-.9-2-2-2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2zm-11-4l2.03 2.71L16 11l4 5H8l3-4zM2 6v14c0 1.1.9 2 2 2h14v-2H4V6H2z"/></g>
+<g id="collections-bookmark"><path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zM20 2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 10l-2.5-1.5L15 12V4h5v8z"/></g>
+<g id="color-lens"><path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></g>
+<g id="colorize"><path d="M20.71 5.63l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-3.12 3.12-1.93-1.91-1.41 1.41 1.42 1.42L3 16.25V21h4.75l8.92-8.92 1.42 1.42 1.41-1.41-1.92-1.92 3.12-3.12c.4-.4.4-1.03.01-1.42zM6.92 19L5 17.08l8.06-8.06 1.92 1.92L6.92 19z"/></g>
+<g id="compare"><path d="M10 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h5v2h2V1h-2v2zm0 15H5l5-6v6zm9-15h-5v2h5v13l-5-6v9h5c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/></g>
+<g id="control-point"><path d="M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.49 2 2 6.49 2 12s4.49 10 10 10 10-4.49 10-10S17.51 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></g>
+<g id="control-point-duplicate"><path d="M16 8h-2v3h-3v2h3v3h2v-3h3v-2h-3zM2 12c0-2.79 1.64-5.2 4.01-6.32V3.52C2.52 4.76 0 8.09 0 12s2.52 7.24 6.01 8.48v-2.16C3.64 17.2 2 14.79 2 12zm13-9c-4.96 0-9 4.04-9 9s4.04 9 9 9 9-4.04 9-9-4.04-9-9-9zm0 16c-3.86 0-7-3.14-7-7s3.14-7 7-7 7 3.14 7 7-3.14 7-7 7z"/></g>
+<g id="crop"><path d="M17 15h2V7c0-1.1-.9-2-2-2H9v2h8v8zM7 17V1H5v4H1v2h4v10c0 1.1.9 2 2 2h10v4h2v-4h4v-2H7z"/></g>
+<g id="crop-16-9"><path d="M19 6H5c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 10H5V8h14v8z"/></g>
+<g id="crop-3-2"><path d="M19 4H5c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H5V6h14v12z"/></g>
+<g id="crop-5-4"><path d="M19 5H5c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 12H5V7h14v10z"/></g>
+<g id="crop-7-5"><path d="M19 7H5c-1.1 0-2 .9-2 2v6c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2zm0 8H5V9h14v6z"/></g>
+<g id="crop-din"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14z"/></g>
+<g id="crop-free"><path d="M3 5v4h2V5h4V3H5c-1.1 0-2 .9-2 2zm2 10H3v4c0 1.1.9 2 2 2h4v-2H5v-4zm14 4h-4v2h4c1.1 0 2-.9 2-2v-4h-2v4zm0-16h-4v2h4v4h2V5c0-1.1-.9-2-2-2z"/></g>
+<g id="crop-landscape"><path d="M19 5H5c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 12H5V7h14v10z"/></g>
+<g id="crop-original"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14zm-5.04-6.71l-2.75 3.54-1.96-2.36L6.5 17h11l-3.54-4.71z"/></g>
+<g id="crop-portrait"><path d="M17 3H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H7V5h10v14z"/></g>
+<g id="crop-square"><path d="M18 4H6c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H6V6h12v12z"/></g>
+<g id="dehaze"><path d="M2 15.5v2h20v-2H2zm0-5v2h20v-2H2zm0-5v2h20v-2H2z"/></g>
+<g id="details"><path d="M3 4l9 16 9-16H3zm3.38 2h11.25L12 16 6.38 6z"/></g>
+<g id="edit"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></g>
+<g id="exposure"><path d="M15 17v2h2v-2h2v-2h-2v-2h-2v2h-2v2h2zm5-15H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM5 5h6v2H5V5zm15 15H4L20 4v16z"/></g>
+<g id="exposure-neg-1"><path d="M4 11v2h8v-2H4zm15 7h-2V7.38L14 8.4V6.7L18.7 5h.3v13z"/></g>
+<g id="exposure-neg-2"><path d="M15.05 16.29l2.86-3.07c.38-.39.72-.79 1.04-1.18.32-.39.59-.78.82-1.17.23-.39.41-.78.54-1.17s.19-.79.19-1.18c0-.53-.09-1.02-.27-1.46-.18-.44-.44-.81-.78-1.11-.34-.31-.77-.54-1.26-.71-.51-.16-1.08-.24-1.72-.24-.69 0-1.31.11-1.85.32-.54.21-1 .51-1.36.88-.37.37-.65.8-.84 1.3-.18.47-.27.97-.28 1.5h2.14c.01-.31.05-.6.13-.87.09-.29.23-.54.4-.75.18-.21.41-.37.68-.49.27-.12.6-.18.96-.18.31 0 .58.05.81.15.23.1.43.25.59.43.16.18.28.4.37.65.08.25.13.52.13.81 0 .22-.03.43-.08.65-.06.22-.15.45-.29.7-.14.25-.32.53-.56.83-.23.3-.52.65-.88 1.03l-4.17 4.55V18H21v-1.71h-5.95zM2 11v2h8v-2H2z"/></g>
+<g id="exposure-plus-1"><path d="M10 7H8v4H4v2h4v4h2v-4h4v-2h-4V7zm10 11h-2V7.38L15 8.4V6.7L19.7 5h.3v13z"/></g>
+<g id="exposure-plus-2"><path d="M16.05 16.29l2.86-3.07c.38-.39.72-.79 1.04-1.18.32-.39.59-.78.82-1.17.23-.39.41-.78.54-1.17.13-.39.19-.79.19-1.18 0-.53-.09-1.02-.27-1.46-.18-.44-.44-.81-.78-1.11-.34-.31-.77-.54-1.26-.71-.51-.16-1.08-.24-1.72-.24-.69 0-1.31.11-1.85.32-.54.21-1 .51-1.36.88-.37.37-.65.8-.84 1.3-.18.47-.27.97-.28 1.5h2.14c.01-.31.05-.6.13-.87.09-.29.23-.54.4-.75.18-.21.41-.37.68-.49.27-.12.6-.18.96-.18.31 0 .58.05.81.15.23.1.43.25.59.43.16.18.28.4.37.65.08.25.13.52.13.81 0 .22-.03.43-.08.65-.06.22-.15.45-.29.7-.14.25-.32.53-.56.83-.23.3-.52.65-.88 1.03l-4.17 4.55V18H22v-1.71h-5.95zM8 7H6v4H2v2h4v4h2v-4h4v-2H8V7z"/></g>
+<g id="exposure-zero"><path d="M16.14 12.5c0 1-.1 1.85-.3 2.55-.2.7-.48 1.27-.83 1.7-.36.44-.79.75-1.3.95-.51.2-1.07.3-1.7.3-.62 0-1.18-.1-1.69-.3-.51-.2-.95-.51-1.31-.95-.36-.44-.65-1.01-.85-1.7-.2-.7-.3-1.55-.3-2.55v-2.04c0-1 .1-1.85.3-2.55.2-.7.48-1.26.84-1.69.36-.43.8-.74 1.31-.93C10.81 5.1 11.38 5 12 5c.63 0 1.19.1 1.7.29.51.19.95.5 1.31.93.36.43.64.99.84 1.69.2.7.3 1.54.3 2.55v2.04zm-2.11-2.36c0-.64-.05-1.18-.13-1.62-.09-.44-.22-.79-.4-1.06-.17-.27-.39-.46-.64-.58-.25-.13-.54-.19-.86-.19-.32 0-.61.06-.86.18s-.47.31-.64.58c-.17.27-.31.62-.4 1.06s-.13.98-.13 1.62v2.67c0 .64.05 1.18.14 1.62.09.45.23.81.4 1.09s.39.48.64.61.54.19.87.19c.33 0 .62-.06.87-.19s.46-.33.63-.61c.17-.28.3-.64.39-1.09.09-.45.13-.99.13-1.62v-2.66z"/></g>
+<g id="filter"><path d="M15.96 10.29l-2.75 3.54-1.96-2.36L8.5 15h11l-3.54-4.71zM3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14z"/></g>
+<g id="filter-1"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm11 10h2V5h-4v2h2v8zm7-14H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14z"/></g>
+<g id="filter-2"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zm-4-4h-4v-2h2c1.1 0 2-.89 2-2V7c0-1.11-.9-2-2-2h-4v2h4v2h-2c-1.1 0-2 .89-2 2v4h6v-2z"/></g>
+<g id="filter-3"><path d="M21 1H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zM3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm14 8v-1.5c0-.83-.67-1.5-1.5-1.5.83 0 1.5-.67 1.5-1.5V7c0-1.11-.9-2-2-2h-4v2h4v2h-2v2h2v2h-4v2h4c1.1 0 2-.89 2-2z"/></g>
+<g id="filter-4"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm12 10h2V5h-2v4h-2V5h-2v6h4v4zm6-14H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14z"/></g>
+<g id="filter-5"><path d="M21 1H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zM3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm14 8v-2c0-1.11-.9-2-2-2h-2V7h4V5h-6v6h4v2h-4v2h4c1.1 0 2-.89 2-2z"/></g>
+<g id="filter-6"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zm-8-2h2c1.1 0 2-.89 2-2v-2c0-1.11-.9-2-2-2h-2V7h4V5h-4c-1.1 0-2 .89-2 2v6c0 1.11.9 2 2 2zm0-4h2v2h-2v-2z"/></g>
+<g id="filter-7"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zm-8-2l4-8V5h-6v2h4l-4 8h2z"/></g>
+<g id="filter-8"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zm-8-2h2c1.1 0 2-.89 2-2v-1.5c0-.83-.67-1.5-1.5-1.5.83 0 1.5-.67 1.5-1.5V7c0-1.11-.9-2-2-2h-2c-1.1 0-2 .89-2 2v1.5c0 .83.67 1.5 1.5 1.5-.83 0-1.5.67-1.5 1.5V13c0 1.11.9 2 2 2zm0-8h2v2h-2V7zm0 4h2v2h-2v-2z"/></g>
+<g id="filter-9"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14zM15 5h-2c-1.1 0-2 .89-2 2v2c0 1.11.9 2 2 2h2v2h-4v2h4c1.1 0 2-.89 2-2V7c0-1.11-.9-2-2-2zm0 4h-2V7h2v2z"/></g>
+<g id="filter-9-plus"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm11 7V8c0-1.11-.9-2-2-2h-1c-1.1 0-2 .89-2 2v1c0 1.11.9 2 2 2h1v1H9v2h3c1.1 0 2-.89 2-2zm-3-3V8h1v1h-1zm10-8H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 8h-2V7h-2v2h-2v2h2v2h2v-2h2v6H7V3h14v6z"/></g>
+<g id="filter-b-and-w"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16l-7-8v8H5l7-8V5h7v14z"/></g>
+<g id="filter-center-focus"><path d="M5 15H3v4c0 1.1.9 2 2 2h4v-2H5v-4zM5 5h4V3H5c-1.1 0-2 .9-2 2v4h2V5zm14-2h-4v2h4v4h2V5c0-1.1-.9-2-2-2zm0 16h-4v2h4c1.1 0 2-.9 2-2v-4h-2v4zM12 9c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></g>
+<g id="filter-drama"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.61 5.64 5.36 8.04 2.35 8.36 0 10.9 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4h2c0-2.76-1.86-5.08-4.4-5.78C8.61 6.88 10.2 6 12 6c3.03 0 5.5 2.47 5.5 5.5v.5H19c1.65 0 3 1.35 3 3s-1.35 3-3 3z"/></g>
+<g id="filter-frames"><path d="M20 4h-4l-4-4-4 4H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H4V6h4.52l3.52-3.5L15.52 6H20v14zM18 8H6v10h12"/></g>
+<g id="filter-hdr"><path d="M14 6l-3.75 5 2.85 3.8-1.6 1.2C9.81 13.75 7 10 7 10l-6 8h22L14 6z"/></g>
+<g id="filter-none"><path d="M3 5H1v16c0 1.1.9 2 2 2h16v-2H3V5zm18-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm0 16H7V3h14v14z"/></g>
+<g id="filter-tilt-shift"><path d="M11 4.07V2.05c-2.01.2-3.84 1-5.32 2.21L7.1 5.69c1.11-.86 2.44-1.44 3.9-1.62zm7.32.19C16.84 3.05 15.01 2.25 13 2.05v2.02c1.46.18 2.79.76 3.9 1.62l1.42-1.43zM19.93 11h2.02c-.2-2.01-1-3.84-2.21-5.32L18.31 7.1c.86 1.11 1.44 2.44 1.62 3.9zM5.69 7.1L4.26 5.68C3.05 7.16 2.25 8.99 2.05 11h2.02c.18-1.46.76-2.79 1.62-3.9zM4.07 13H2.05c.2 2.01 1 3.84 2.21 5.32l1.43-1.43c-.86-1.1-1.44-2.43-1.62-3.89zM15 12c0-1.66-1.34-3-3-3s-3 1.34-3 3 1.34 3 3 3 3-1.34 3-3zm3.31 4.9l1.43 1.43c1.21-1.48 2.01-3.32 2.21-5.32h-2.02c-.18 1.45-.76 2.78-1.62 3.89zM13 19.93v2.02c2.01-.2 3.84-1 5.32-2.21l-1.43-1.43c-1.1.86-2.43 1.44-3.89 1.62zm-7.32-.19C7.16 20.95 9 21.75 11 21.95v-2.02c-1.46-.18-2.79-.76-3.9-1.62l-1.42 1.43z"/></g>
+<g id="filter-vintage"><path d="M18.7 12.4c-.28-.16-.57-.29-.86-.4.29-.11.58-.24.86-.4 1.92-1.11 2.99-3.12 3-5.19-1.79-1.03-4.07-1.11-6 0-.28.16-.54.35-.78.54.05-.31.08-.63.08-.95 0-2.22-1.21-4.15-3-5.19C10.21 1.85 9 3.78 9 6c0 .32.03.64.08.95-.24-.2-.5-.39-.78-.55-1.92-1.11-4.2-1.03-6 0 0 2.07 1.07 4.08 3 5.19.28.16.57.29.86.4-.29.11-.58.24-.86.4-1.92 1.11-2.99 3.12-3 5.19 1.79 1.03 4.07 1.11 6 0 .28-.16.54-.35.78-.54-.05.32-.08.64-.08.96 0 2.22 1.21 4.15 3 5.19 1.79-1.04 3-2.97 3-5.19 0-.32-.03-.64-.08-.95.24.2.5.38.78.54 1.92 1.11 4.2 1.03 6 0-.01-2.07-1.08-4.08-3-5.19zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z"/></g>
+<g id="flare"><path d="M7 11H1v2h6v-2zm2.17-3.24L7.05 5.64 5.64 7.05l2.12 2.12 1.41-1.41zM13 1h-2v6h2V1zm5.36 6.05l-1.41-1.41-2.12 2.12 1.41 1.41 2.12-2.12zM17 11v2h6v-2h-6zm-5-2c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3zm2.83 7.24l2.12 2.12 1.41-1.41-2.12-2.12-1.41 1.41zm-9.19.71l1.41 1.41 2.12-2.12-1.41-1.41-2.12 2.12zM11 23h2v-6h-2v6z"/></g>
+<g id="flash-auto"><path d="M3 2v12h3v9l7-12H9l4-9H3zm16 0h-2l-3.2 9h1.9l.7-2h3.2l.7 2h1.9L19 2zm-2.15 5.65L18 4l1.15 3.65h-2.3z"/></g>
+<g id="flash-off"><path d="M3.27 3L2 4.27l5 5V13h3v9l3.58-6.14L17.73 20 19 18.73 3.27 3zM17 10h-4l4-8H7v2.18l8.46 8.46L17 10z"/></g>
+<g id="flash-on"><path d="M7 2v11h3v9l7-12h-4l4-8z"/></g>
+<g id="flip"><path d="M15 21h2v-2h-2v2zm4-12h2V7h-2v2zM3 5v14c0 1.1.9 2 2 2h4v-2H5V5h4V3H5c-1.1 0-2 .9-2 2zm16-2v2h2c0-1.1-.9-2-2-2zm-8 20h2V1h-2v22zm8-6h2v-2h-2v2zM15 5h2V3h-2v2zm4 8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2z"/></g>
+<g id="gradient"><path d="M11 9h2v2h-2zm-2 2h2v2H9zm4 0h2v2h-2zm2-2h2v2h-2zM7 9h2v2H7zm12-6H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 18H7v-2h2v2zm4 0h-2v-2h2v2zm4 0h-2v-2h2v2zm2-7h-2v2h2v2h-2v-2h-2v2h-2v-2h-2v2H9v-2H7v2H5v-2h2v-2H5V5h14v6z"/></g>
+<g id="grain"><path d="M10 12c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zM6 8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12-8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm-4 8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm4-4c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-4-4c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-4-4c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></g>
+<g id="grid-off"><path d="M8 4v1.45l2 2V4h4v4h-3.45l2 2H14v1.45l2 2V10h4v4h-3.45l2 2H20v1.45l2 2V4c0-1.1-.9-2-2-2H4.55l2 2H8zm8 0h4v4h-4V4zM1.27 1.27L0 2.55l2 2V20c0 1.1.9 2 2 2h15.46l2 2 1.27-1.27L1.27 1.27zM10 12.55L11.45 14H10v-1.45zm-6-6L5.45 8H4V6.55zM8 20H4v-4h4v4zm0-6H4v-4h3.45l.55.55V14zm6 6h-4v-4h3.45l.55.54V20zm2 0v-1.46L17.46 20H16z"/></g>
+<g id="grid-on"><path d="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM8 20H4v-4h4v4zm0-6H4v-4h4v4zm0-6H4V4h4v4zm6 12h-4v-4h4v4zm0-6h-4v-4h4v4zm0-6h-4V4h4v4zm6 12h-4v-4h4v4zm0-6h-4v-4h4v4zm0-6h-4V4h4v4z"/></g>
+<g id="hdr-off"><path d="M17.5 15v-2h1.1l.9 2H21l-.9-2.1c.5-.2.9-.8.9-1.4v-1c0-.8-.7-1.5-1.5-1.5H16v4.9l1.1 1.1h.4zm0-4.5h2v1h-2v-1zm-4.5 0v.4l1.5 1.5v-1.9c0-.8-.7-1.5-1.5-1.5h-1.9l1.5 1.5h.4zm-3.5-1l-7-7-1.1 1L6.9 9h-.4v2h-2V9H3v6h1.5v-2.5h2V15H8v-4.9l1.5 1.5V15h3.4l7.6 7.6 1.1-1.1-12.1-12z"/></g>
+<g id="hdr-on"><path d="M21 11.5v-1c0-.8-.7-1.5-1.5-1.5H16v6h1.5v-2h1.1l.9 2H21l-.9-2.1c.5-.3.9-.8.9-1.4zm-1.5 0h-2v-1h2v1zm-13-.5h-2V9H3v6h1.5v-2.5h2V15H8V9H6.5v2zM13 9H9.5v6H13c.8 0 1.5-.7 1.5-1.5v-3c0-.8-.7-1.5-1.5-1.5zm0 4.5h-2v-3h2v3z"/></g>
+<g id="hdr-strong"><path d="M17 6c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zM5 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></g>
+<g id="hdr-weak"><path d="M5 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm12-2c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm0 10c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z"/></g>
+<g id="healing"><path d="M17.73 12.02l3.98-3.98c.39-.39.39-1.02 0-1.41l-4.34-4.34c-.39-.39-1.02-.39-1.41 0l-3.98 3.98L8 2.29C7.8 2.1 7.55 2 7.29 2c-.25 0-.51.1-.7.29L2.25 6.63c-.39.39-.39 1.02 0 1.41l3.98 3.98L2.25 16c-.39.39-.39 1.02 0 1.41l4.34 4.34c.39.39 1.02.39 1.41 0l3.98-3.98 3.98 3.98c.2.2.45.29.71.29.26 0 .51-.1.71-.29l4.34-4.34c.39-.39.39-1.02 0-1.41l-3.99-3.98zM12 9c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm-4.71 1.96L3.66 7.34l3.63-3.63 3.62 3.62-3.62 3.63zM10 13c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm2 2c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm2-4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm2.66 9.34l-3.63-3.62 3.63-3.63 3.62 3.62-3.62 3.63z"/></g>
+<g id="image"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/></g>
+<g id="image-aspect-ratio"><path d="M16 10h-2v2h2v-2zm0 4h-2v2h2v-2zm-8-4H6v2h2v-2zm4 0h-2v2h2v-2zm8-6H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H4V6h16v12z"/></g>
+<g id="iso"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM5.5 7.5h2v-2H9v2h2V9H9v2H7.5V9h-2V7.5zM19 19H5L19 5v14zm-2-2v-1.5h-5V17h5z"/></g>
+<g id="landscape"><path d="M14 6l-3.75 5 2.85 3.8-1.6 1.2C9.81 13.75 7 10 7 10l-6 8h22L14 6z"/></g>
+<g id="leak-add"><path d="M6 3H3v3c1.66 0 3-1.34 3-3zm8 0h-2c0 4.97-4.03 9-9 9v2c6.08 0 11-4.93 11-11zm-4 0H8c0 2.76-2.24 5-5 5v2c3.87 0 7-3.13 7-7zm0 18h2c0-4.97 4.03-9 9-9v-2c-6.07 0-11 4.93-11 11zm8 0h3v-3c-1.66 0-3 1.34-3 3zm-4 0h2c0-2.76 2.24-5 5-5v-2c-3.87 0-7 3.13-7 7z"/></g>
+<g id="leak-remove"><path d="M10 3H8c0 .37-.04.72-.12 1.06l1.59 1.59C9.81 4.84 10 3.94 10 3zM3 4.27l2.84 2.84C5.03 7.67 4.06 8 3 8v2c1.61 0 3.09-.55 4.27-1.46L8.7 9.97C7.14 11.24 5.16 12 3 12v2c2.71 0 5.19-.99 7.11-2.62l2.5 2.5C10.99 15.81 10 18.29 10 21h2c0-2.16.76-4.14 2.03-5.69l1.43 1.43C14.55 17.91 14 19.39 14 21h2c0-1.06.33-2.03.89-2.84L19.73 21 21 19.73 4.27 3 3 4.27zM14 3h-2c0 1.5-.37 2.91-1.02 4.16l1.46 1.46C13.42 6.98 14 5.06 14 3zm5.94 13.12c.34-.08.69-.12 1.06-.12v-2c-.94 0-1.84.19-2.66.52l1.6 1.6zm-4.56-4.56l1.46 1.46C18.09 12.37 19.5 12 21 12v-2c-2.06 0-3.98.58-5.62 1.56z"/></g>
+<g id="lens"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z"/></g>
+<g id="looks"><path d="M12 10c-3.86 0-7 3.14-7 7h2c0-2.76 2.24-5 5-5s5 2.24 5 5h2c0-3.86-3.14-7-7-7zm0-4C5.93 6 1 10.93 1 17h2c0-4.96 4.04-9 9-9s9 4.04 9 9h2c0-6.07-4.93-11-11-11z"/></g>
+<g id="looks-3"><path d="M19.01 3h-14c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 7.5c0 .83-.67 1.5-1.5 1.5.83 0 1.5.67 1.5 1.5V15c0 1.11-.9 2-2 2h-4v-2h4v-2h-2v-2h2V9h-4V7h4c1.1 0 2 .89 2 2v1.5z"/></g>
+<g id="looks-4"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 14h-2v-4H9V7h2v4h2V7h2v10z"/></g>
+<g id="looks-5"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 6h-4v2h2c1.1 0 2 .89 2 2v2c0 1.11-.9 2-2 2H9v-2h4v-2H9V7h6v2z"/></g>
+<g id="looks-6"><path d="M11 15h2v-2h-2v2zm8-12H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 6h-4v2h2c1.1 0 2 .89 2 2v2c0 1.11-.9 2-2 2h-2c-1.1 0-2-.89-2-2V9c0-1.11.9-2 2-2h4v2z"/></g>
+<g id="looks-one"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14h-2V9h-2V7h4v10z"/></g>
+<g id="looks-two"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4 8c0 1.11-.9 2-2 2h-2v2h4v2H9v-4c0-1.11.9-2 2-2h2V9H9V7h4c1.1 0 2 .89 2 2v2z"/></g>
+<g id="loupe"><path d="M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.49 2 2 6.49 2 12s4.49 10 10 10h8c1.1 0 2-.9 2-2v-8c0-5.51-4.49-10-10-10zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></g>
+<g id="monochrome-photos"><path d="M20 5h-3.2L15 3H9L7.2 5H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 14h-8v-1c-2.8 0-5-2.2-5-5s2.2-5 5-5V7h8v12zm-3-6c0-2.8-2.2-5-5-5v1.8c1.8 0 3.2 1.4 3.2 3.2s-1.4 3.2-3.2 3.2V18c2.8 0 5-2.2 5-5zm-8.2 0c0 1.8 1.4 3.2 3.2 3.2V9.8c-1.8 0-3.2 1.4-3.2 3.2z"/></g>
+<g id="movie-creation"><path d="M18 4l2 4h-3l-2-4h-2l2 4h-3l-2-4H8l2 4H7L5 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4h-4z"/></g>
+<g id="music-note"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></g>
+<g id="nature"><path d="M13 16.12c3.47-.41 6.17-3.36 6.17-6.95 0-3.87-3.13-7-7-7s-7 3.13-7 7c0 3.47 2.52 6.34 5.83 6.89V20H5v2h14v-2h-6v-3.88z"/></g>
+<g id="nature-people"><path d="M22.17 9.17c0-3.87-3.13-7-7-7s-7 3.13-7 7c0 3.47 2.52 6.34 5.83 6.89V20H6v-3h1v-4c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v4h1v5h16v-2h-3v-3.88c3.47-.41 6.17-3.36 6.17-6.95zM4.5 11c.83 0 1.5-.67 1.5-1.5S5.33 8 4.5 8 3 8.67 3 9.5 3.67 11 4.5 11z"/></g>
+<g id="navigate-before"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></g>
+<g id="navigate-next"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></g>
+<g id="palette"><path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></g>
+<g id="panorama"><path d="M23 18V6c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2zM8.5 12.5l2.5 3.01L14.5 11l4.5 6H5l3.5-4.5z"/></g>
+<g id="panorama-fish-eye"><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></g>
+<g id="panorama-horizontal"><path d="M20 6.54v10.91c-2.6-.77-5.28-1.16-8-1.16-2.72 0-5.4.39-8 1.16V6.54c2.6.77 5.28 1.16 8 1.16 2.72.01 5.4-.38 8-1.16M21.43 4c-.1 0-.2.02-.31.06C18.18 5.16 15.09 5.7 12 5.7c-3.09 0-6.18-.55-9.12-1.64-.11-.04-.22-.06-.31-.06-.34 0-.57.23-.57.63v14.75c0 .39.23.62.57.62.1 0 .2-.02.31-.06 2.94-1.1 6.03-1.64 9.12-1.64 3.09 0 6.18.55 9.12 1.64.11.04.21.06.31.06.33 0 .57-.23.57-.63V4.63c0-.4-.24-.63-.57-.63z"/></g>
+<g id="panorama-vertical"><path d="M19.94 21.12c-1.1-2.94-1.64-6.03-1.64-9.12 0-3.09.55-6.18 1.64-9.12.04-.11.06-.22.06-.31 0-.34-.23-.57-.63-.57H4.63c-.4 0-.63.23-.63.57 0 .1.02.2.06.31C5.16 5.82 5.71 8.91 5.71 12c0 3.09-.55 6.18-1.64 9.12-.05.11-.07.22-.07.31 0 .33.23.57.63.57h14.75c.39 0 .63-.24.63-.57-.01-.1-.03-.2-.07-.31zM6.54 20c.77-2.6 1.16-5.28 1.16-8 0-2.72-.39-5.4-1.16-8h10.91c-.77 2.6-1.16 5.28-1.16 8 0 2.72.39 5.4 1.16 8H6.54z"/></g>
+<g id="panorama-wide-angle"><path d="M12 6c2.45 0 4.71.2 7.29.64.47 1.78.71 3.58.71 5.36 0 1.78-.24 3.58-.71 5.36-2.58.44-4.84.64-7.29.64s-4.71-.2-7.29-.64C4.24 15.58 4 13.78 4 12c0-1.78.24-3.58.71-5.36C7.29 6.2 9.55 6 12 6m0-2c-2.73 0-5.22.24-7.95.72l-.93.16-.25.9C2.29 7.85 2 9.93 2 12s.29 4.15.87 6.22l.25.89.93.16c2.73.49 5.22.73 7.95.73s5.22-.24 7.95-.72l.93-.16.25-.89c.58-2.08.87-4.16.87-6.23s-.29-4.15-.87-6.22l-.25-.89-.93-.16C17.22 4.24 14.73 4 12 4z"/></g>
+<g id="photo"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/></g>
+<g id="photo-album"><path d="M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 4h5v8l-2.5-1.5L6 12V4zm0 15l3-3.86 2.14 2.58 3-3.86L18 19H6z"/></g>
+<g id="photo-camera"><circle cx="12" cy="12" r="3.2"/><path d="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z"/></g>
+<g id="photo-library"><path d="M22 16V4c0-1.1-.9-2-2-2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2zm-11-4l2.03 2.71L16 11l4 5H8l3-4zM2 6v14c0 1.1.9 2 2 2h14v-2H4V6H2z"/></g>
+<g id="photo-size-select-actual"><path d="M21 3H3C2 3 1 4 1 5v14c0 1.1.9 2 2 2h18c1 0 2-1 2-2V5c0-1-1-2-2-2zM5 17l3.5-4.5 2.5 3.01L14.5 11l4.5 6H5z"/></g>
+<g id="photo-size-select-large"><path d="M21 15h2v2h-2v-2zm0-4h2v2h-2v-2zm2 8h-2v2c1 0 2-1 2-2zM13 3h2v2h-2V3zm8 4h2v2h-2V7zm0-4v2h2c0-1-1-2-2-2zM1 7h2v2H1V7zm16-4h2v2h-2V3zm0 16h2v2h-2v-2zM3 3C2 3 1 4 1 5h2V3zm6 0h2v2H9V3zM5 3h2v2H5V3zm-4 8v8c0 1.1.9 2 2 2h12V11H1zm2 8l2.5-3.21 1.79 2.15 2.5-3.22L13 19H3z"/></g>
+<g id="photo-size-select-small"><path d="M23 15h-2v2h2v-2zm0-4h-2v2h2v-2zm0 8h-2v2c1 0 2-1 2-2zM15 3h-2v2h2V3zm8 4h-2v2h2V7zm-2-4v2h2c0-1-1-2-2-2zM3 21h8v-6H1v4c0 1.1.9 2 2 2zM3 7H1v2h2V7zm12 12h-2v2h2v-2zm4-16h-2v2h2V3zm0 16h-2v2h2v-2zM3 3C2 3 1 4 1 5h2V3zm0 8H1v2h2v-2zm8-8H9v2h2V3zM7 3H5v2h2V3z"/></g>
+<g id="picture-as-pdf"><path d="M20 2H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-8.5 7.5c0 .83-.67 1.5-1.5 1.5H9v2H7.5V7H10c.83 0 1.5.67 1.5 1.5v1zm5 2c0 .83-.67 1.5-1.5 1.5h-2.5V7H15c.83 0 1.5.67 1.5 1.5v3zm4-3H19v1h1.5V11H19v2h-1.5V7h3v1.5zM9 9.5h1v-1H9v1zM4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm10 5.5h1v-3h-1v3z"/></g>
+<g id="portrait"><path d="M12 12.25c1.24 0 2.25-1.01 2.25-2.25S13.24 7.75 12 7.75 9.75 8.76 9.75 10s1.01 2.25 2.25 2.25zm4.5 4c0-1.5-3-2.25-4.5-2.25s-4.5.75-4.5 2.25V17h9v-.75zM19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14z"/></g>
+<g id="remove-red-eye"><path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></g>
+<g id="rotate-90-degrees-ccw"><path d="M7.34 6.41L.86 12.9l6.49 6.48 6.49-6.48-6.5-6.49zM3.69 12.9l3.66-3.66L11 12.9l-3.66 3.66-3.65-3.66zm15.67-6.26C17.61 4.88 15.3 4 13 4V.76L8.76 5 13 9.24V6c1.79 0 3.58.68 4.95 2.05 2.73 2.73 2.73 7.17 0 9.9C16.58 19.32 14.79 20 13 20c-.97 0-1.94-.21-2.84-.61l-1.49 1.49C10.02 21.62 11.51 22 13 22c2.3 0 4.61-.88 6.36-2.64 3.52-3.51 3.52-9.21 0-12.72z"/></g>
+<g id="rotate-left"><path d="M7.11 8.53L5.7 7.11C4.8 8.27 4.24 9.61 4.07 11h2.02c.14-.87.49-1.72 1.02-2.47zM6.09 13H4.07c.17 1.39.72 2.73 1.62 3.89l1.41-1.42c-.52-.75-.87-1.59-1.01-2.47zm1.01 5.32c1.16.9 2.51 1.44 3.9 1.61V17.9c-.87-.15-1.71-.49-2.46-1.03L7.1 18.32zM13 4.07V1L8.45 5.55 13 10V6.09c2.84.48 5 2.94 5 5.91s-2.16 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93s-3.05-7.44-7-7.93z"/></g>
+<g id="rotate-right"><path d="M15.55 5.55L11 1v3.07C7.06 4.56 4 7.92 4 12s3.05 7.44 7 7.93v-2.02c-2.84-.48-5-2.94-5-5.91s2.16-5.43 5-5.91V10l4.55-4.45zM19.93 11c-.17-1.39-.72-2.73-1.62-3.89l-1.42 1.42c.54.75.88 1.6 1.02 2.47h2.02zM13 17.9v2.02c1.39-.17 2.74-.71 3.9-1.61l-1.44-1.44c-.75.54-1.59.89-2.46 1.03zm3.89-2.42l1.42 1.41c.9-1.16 1.45-2.5 1.62-3.89h-2.02c-.14.87-.48 1.72-1.02 2.48z"/></g>
+<g id="slideshow"><path d="M10 8v8l5-4-5-4zm9-5H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14z"/></g>
+<g id="straighten"><path d="M21 6H3c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 10H3V8h2v4h2V8h2v4h2V8h2v4h2V8h2v4h2V8h2v8z"/></g>
+<g id="style"><path d="M2.53 19.65l1.34.56v-9.03l-2.43 5.86c-.41 1.02.08 2.19 1.09 2.61zm19.5-3.7L17.07 3.98c-.31-.75-1.04-1.21-1.81-1.23-.26 0-.53.04-.79.15L7.1 5.95c-.75.31-1.21 1.03-1.23 1.8-.01.27.04.54.15.8l4.96 11.97c.31.76 1.05 1.22 1.83 1.23.26 0 .52-.05.77-.15l7.36-3.05c1.02-.42 1.51-1.59 1.09-2.6zM7.88 8.75c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-2 11c0 1.1.9 2 2 2h1.45l-3.45-8.34v6.34z"/></g>
+<g id="switch-camera"><path d="M20 4h-3.17L15 2H9L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-5 11.5V13H9v2.5L5.5 12 9 8.5V11h6V8.5l3.5 3.5-3.5 3.5z"/></g>
+<g id="switch-video"><path d="M18 9.5V6c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h14c.55 0 1-.45 1-1v-3.5l4 4v-13l-4 4zm-5 6V13H7v2.5L3.5 12 7 8.5V11h6V8.5l3.5 3.5-3.5 3.5z"/></g>
+<g id="tag-faces"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"/></g>
+<g id="texture"><path d="M19.51 3.08L3.08 19.51c.09.34.27.65.51.9.25.24.56.42.9.51L20.93 4.49c-.19-.69-.73-1.23-1.42-1.41zM11.88 3L3 11.88v2.83L14.71 3h-2.83zM5 3c-1.1 0-2 .9-2 2v2l4-4H5zm14 18c.55 0 1.05-.22 1.41-.59.37-.36.59-.86.59-1.41v-2l-4 4h2zm-9.71 0h2.83L21 12.12V9.29L9.29 21z"/></g>
+<g id="timelapse"><path d="M16.24 7.76C15.07 6.59 13.54 6 12 6v6l-4.24 4.24c2.34 2.34 6.14 2.34 8.49 0 2.34-2.34 2.34-6.14-.01-8.48zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/></g>
+<g id="timer"><path d="M15 1H9v2h6V1zm-4 13h2V8h-2v6zm8.03-6.61l1.42-1.42c-.43-.51-.9-.99-1.41-1.41l-1.42 1.42C16.07 4.74 14.12 4 12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9 9-4.03 9-9c0-2.12-.74-4.07-1.97-5.61zM12 20c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></g>
+<g id="timer-10"><path d="M0 7.72V9.4l3-1V18h2V6h-.25L0 7.72zm23.78 6.65c-.14-.28-.35-.53-.63-.74-.28-.21-.61-.39-1.01-.53s-.85-.27-1.35-.38c-.35-.07-.64-.15-.87-.23-.23-.08-.41-.16-.55-.25-.14-.09-.23-.19-.28-.3-.05-.11-.08-.24-.08-.39 0-.14.03-.28.09-.41.06-.13.15-.25.27-.34.12-.1.27-.18.45-.24s.4-.09.64-.09c.25 0 .47.04.66.11.19.07.35.17.48.29.13.12.22.26.29.42.06.16.1.32.1.49h1.95c0-.39-.08-.75-.24-1.09-.16-.34-.39-.63-.69-.88-.3-.25-.66-.44-1.09-.59C21.49 9.07 21 9 20.46 9c-.51 0-.98.07-1.39.21-.41.14-.77.33-1.06.57-.29.24-.51.52-.67.84-.16.32-.23.65-.23 1.01s.08.69.23.96c.15.28.36.52.64.73.27.21.6.38.98.53.38.14.81.26 1.27.36.39.08.71.17.95.26s.43.19.57.29c.13.1.22.22.27.34.05.12.07.25.07.39 0 .32-.13.57-.4.77-.27.2-.66.29-1.17.29-.22 0-.43-.02-.64-.08-.21-.05-.4-.13-.56-.24-.17-.11-.3-.26-.41-.44-.11-.18-.17-.41-.18-.67h-1.89c0 .36.08.71.24 1.05.16.34.39.65.7.93.31.27.69.49 1.15.66.46.17.98.25 1.58.25.53 0 1.01-.06 1.44-.19.43-.13.8-.31 1.11-.54.31-.23.54-.51.71-.83.17-.32.25-.67.25-1.06-.02-.4-.09-.74-.24-1.02zm-9.96-7.32c-.34-.4-.75-.7-1.23-.88-.47-.18-1.01-.27-1.59-.27-.58 0-1.11.09-1.59.27-.48.18-.89.47-1.23.88-.34.41-.6.93-.79 1.59-.18.65-.28 1.45-.28 2.39v1.92c0 .94.09 1.74.28 2.39.19.66.45 1.19.8 1.6.34.41.75.71 1.23.89.48.18 1.01.28 1.59.28.59 0 1.12-.09 1.59-.28.48-.18.88-.48 1.22-.89.34-.41.6-.94.78-1.6.18-.65.28-1.45.28-2.39v-1.92c0-.94-.09-1.74-.28-2.39-.18-.66-.44-1.19-.78-1.59zm-.92 6.17c0 .6-.04 1.11-.12 1.53-.08.42-.2.76-.36 1.02-.16.26-.36.45-.59.57-.23.12-.51.18-.82.18-.3 0-.58-.06-.82-.18s-.44-.31-.6-.57c-.16-.26-.29-.6-.38-1.02-.09-.42-.13-.93-.13-1.53v-2.5c0-.6.04-1.11.13-1.52.09-.41.21-.74.38-1 .16-.25.36-.43.6-.55.24-.11.51-.17.81-.17.31 0 .58.06.81.17.24.11.44.29.6.55.16.25.29.58.37.99.08.41.13.92.13 1.52v2.51z"/></g>
+<g id="timer-3"><path d="M11.61 12.97c-.16-.24-.36-.46-.62-.65-.25-.19-.56-.35-.93-.48.3-.14.57-.3.8-.5.23-.2.42-.41.57-.64.15-.23.27-.46.34-.71.08-.24.11-.49.11-.73 0-.55-.09-1.04-.28-1.46-.18-.42-.44-.77-.78-1.06-.33-.28-.73-.5-1.2-.64-.45-.13-.97-.2-1.53-.2-.55 0-1.06.08-1.52.24-.47.17-.87.4-1.2.69-.33.29-.6.63-.78 1.03-.2.39-.29.83-.29 1.29h1.98c0-.26.05-.49.14-.69.09-.2.22-.38.38-.52.17-.14.36-.25.58-.33.22-.08.46-.12.73-.12.61 0 1.06.16 1.36.47.3.31.44.75.44 1.32 0 .27-.04.52-.12.74-.08.22-.21.41-.38.57-.17.16-.38.28-.63.37-.25.09-.55.13-.89.13H6.72v1.57H7.9c.34 0 .64.04.91.11.27.08.5.19.69.35.19.16.34.36.44.61.1.24.16.54.16.87 0 .62-.18 1.09-.53 1.42-.35.33-.84.49-1.45.49-.29 0-.56-.04-.8-.13-.24-.08-.44-.2-.61-.36-.17-.16-.3-.34-.39-.56-.09-.22-.14-.46-.14-.72H4.19c0 .55.11 1.03.32 1.45.21.42.5.77.86 1.05s.77.49 1.24.63.96.21 1.48.21c.57 0 1.09-.08 1.58-.23.49-.15.91-.38 1.26-.68.36-.3.64-.66.84-1.1.2-.43.3-.93.3-1.48 0-.29-.04-.58-.11-.86-.08-.25-.19-.51-.35-.76zm9.26 1.4c-.14-.28-.35-.53-.63-.74-.28-.21-.61-.39-1.01-.53s-.85-.27-1.35-.38c-.35-.07-.64-.15-.87-.23-.23-.08-.41-.16-.55-.25-.14-.09-.23-.19-.28-.3-.05-.11-.08-.24-.08-.39s.03-.28.09-.41c.06-.13.15-.25.27-.34.12-.1.27-.18.45-.24s.4-.09.64-.09c.25 0 .47.04.66.11.19.07.35.17.48.29.13.12.22.26.29.42.06.16.1.32.1.49h1.95c0-.39-.08-.75-.24-1.09-.16-.34-.39-.63-.69-.88-.3-.25-.66-.44-1.09-.59-.43-.15-.92-.22-1.46-.22-.51 0-.98.07-1.39.21-.41.14-.77.33-1.06.57-.29.24-.51.52-.67.84-.16.32-.23.65-.23 1.01s.08.68.23.96c.15.28.37.52.64.73.27.21.6.38.98.53.38.14.81.26 1.27.36.39.08.71.17.95.26s.43.19.57.29c.13.1.22.22.27.34.05.12.07.25.07.39 0 .32-.13.57-.4.77-.27.2-.66.29-1.17.29-.22 0-.43-.02-.64-.08-.21-.05-.4-.13-.56-.24-.17-.11-.3-.26-.41-.44-.11-.18-.17-.41-.18-.67h-1.89c0 .36.08.71.24 1.05.16.34.39.65.7.93.31.27.69.49 1.15.66.46.17.98.25 1.58.25.53 0 1.01-.06 1.44-.19.43-.13.8-.31 1.11-.54.31-.23.54-.51.71-.83.17-.32.25-.67.25-1.06-.02-.4-.09-.74-.24-1.02z"/></g>
+<g id="timer-off"><path d="M19.04 4.55l-1.42 1.42C16.07 4.74 14.12 4 12 4c-1.83 0-3.53.55-4.95 1.48l1.46 1.46C9.53 6.35 10.73 6 12 6c3.87 0 7 3.13 7 7 0 1.27-.35 2.47-.94 3.49l1.45 1.45C20.45 16.53 21 14.83 21 13c0-2.12-.74-4.07-1.97-5.61l1.42-1.42-1.41-1.42zM15 1H9v2h6V1zm-4 8.44l2 2V8h-2v1.44zM3.02 4L1.75 5.27 4.5 8.03C3.55 9.45 3 11.16 3 13c0 4.97 4.02 9 9 9 1.84 0 3.55-.55 4.98-1.5l2.5 2.5 1.27-1.27-7.71-7.71L3.02 4zM12 20c-3.87 0-7-3.13-7-7 0-1.28.35-2.48.95-3.52l9.56 9.56c-1.03.61-2.23.96-3.51.96z"/></g>
+<g id="tonality"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.94-.49-7-3.85-7-7.93s3.05-7.44 7-7.93v15.86zm2-15.86c1.03.13 2 .45 2.87.93H13v-.93zM13 7h5.24c.25.31.48.65.68 1H13V7zm0 3h6.74c.08.33.15.66.19 1H13v-1zm0 9.93V19h2.87c-.87.48-1.84.8-2.87.93zM18.24 17H13v-1h5.92c-.2.35-.43.69-.68 1zm1.5-3H13v-1h6.93c-.04.34-.11.67-.19 1z"/></g>
+<g id="transform"><path d="M22 18v-2H8V4h2L7 1 4 4h2v2H2v2h4v8c0 1.1.9 2 2 2h8v2h-2l3 3 3-3h-2v-2h4zM10 8h6v6h2V8c0-1.1-.9-2-2-2h-6v2z"/></g>
+<g id="tune"><path d="M3 17v2h6v-2H3zM3 5v2h10V5H3zm10 16v-2h8v-2h-8v-2h-2v6h2zM7 9v2H3v2h4v2h2V9H7zm14 4v-2H11v2h10zm-6-4h2V7h4V5h-4V3h-2v6z"/></g>
+<g id="view-comfy"><path d="M3 9h4V5H3v4zm0 5h4v-4H3v4zm5 0h4v-4H8v4zm5 0h4v-4h-4v4zM8 9h4V5H8v4zm5-4v4h4V5h-4zm5 9h4v-4h-4v4zM3 19h4v-4H3v4zm5 0h4v-4H8v4zm5 0h4v-4h-4v4zm5 0h4v-4h-4v4zm0-14v4h4V5h-4z"/></g>
+<g id="view-compact"><path d="M3 19h6v-7H3v7zm7 0h12v-7H10v7zM3 5v6h19V5H3z"/></g>
+<g id="vignette"><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-9 15c-4.42 0-8-2.69-8-6s3.58-6 8-6 8 2.69 8 6-3.58 6-8 6z"/></g>
+<g id="wb-auto"><path d="M6.85 12.65h2.3L8 9l-1.15 3.65zM22 7l-1.2 6.29L19.3 7h-1.6l-1.49 6.29L15 7h-.76C12.77 5.17 10.53 4 8 4c-4.42 0-8 3.58-8 8s3.58 8 8 8c3.13 0 5.84-1.81 7.15-4.43l.1.43H17l1.5-6.1L20 16h1.75l2.05-9H22zm-11.7 9l-.7-2H6.4l-.7 2H3.8L7 7h2l3.2 9h-1.9z"/></g>
+<g id="wb-cloudy"><path d="M19.36 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.64-4.96z"/></g>
+<g id="wb-incandescent"><path d="M3.55 18.54l1.41 1.41 1.79-1.8-1.41-1.41-1.79 1.8zM11 22.45h2V19.5h-2v2.95zM4 10.5H1v2h3v-2zm11-4.19V1.5H9v4.81C7.21 7.35 6 9.28 6 11.5c0 3.31 2.69 6 6 6s6-2.69 6-6c0-2.22-1.21-4.15-3-5.19zm5 4.19v2h3v-2h-3zm-2.76 7.66l1.79 1.8 1.41-1.41-1.8-1.79-1.4 1.4z"/></g>
+<g id="wb-iridescent"><path d="M5 14.5h14v-6H5v6zM11 .55V3.5h2V.55h-2zm8.04 2.5l-1.79 1.79 1.41 1.41 1.8-1.79-1.42-1.41zM13 22.45V19.5h-2v2.95h2zm7.45-3.91l-1.8-1.79-1.41 1.41 1.79 1.8 1.42-1.42zM3.55 4.46l1.79 1.79 1.41-1.41-1.79-1.79-1.41 1.41zm1.41 15.49l1.79-1.8-1.41-1.41-1.79 1.79 1.41 1.42z"/></g>
+<g id="wb-sunny"><path d="M6.76 4.84l-1.8-1.79-1.41 1.41 1.79 1.79 1.42-1.41zM4 10.5H1v2h3v-2zm9-9.95h-2V3.5h2V.55zm7.45 3.91l-1.41-1.41-1.79 1.79 1.41 1.41 1.79-1.79zm-3.21 13.7l1.79 1.8 1.41-1.41-1.8-1.79-1.4 1.4zM20 10.5v2h3v-2h-3zm-8-5c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm-1 16.95h2V19.5h-2v2.95zm-7.45-3.91l1.41 1.41 1.79-1.8-1.41-1.41-1.79 1.8z"/></g>
+</defs></svg>
+</iron-iconset-svg>
diff --git a/polymer_1.0.4/bower_components/iron-icons/index.html b/polymer_1.0.4/bower_components/iron-icons/index.html
new file mode 100644
index 0000000..95d1991
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-icons/iron-icons.html b/polymer_1.0.4/bower_components/iron-icons/iron-icons.html
new file mode 100644
index 0000000..922d4d8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/iron-icons.html
@@ -0,0 +1,303 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!--
+`iron-icons` is a utility import that includes the definition for the `iron-icon` element, `iron-iconset-svg` element, as well as an import for the default icon set.
+
+The `iron-icons` directory also includes imports for additional icon sets that can be loaded into your project.
+
+Example loading icon set:
+
+ <link rel="import" href="../iron-icons/maps-icons.html">
+
+To use an icon from one of these sets, first prefix your `iron-icon` with the icon set name, followed by a colon, ":", and then the icon id.
+
+Example using the directions-bus icon from the maps icon set:
+
+ <iron-icon icon="maps:directions-bus"></iron-icon>
+
+
+See [iron-icon](#iron-icon) for more information about working with icons.
+
+See [iron-iconset](#iron-iconset) and [iron-iconset-svg](#iron-iconset-svg) for more information about how to create a custom iconset.
+
+@group Iron Elements
+@element iron-icons
+@demo demo/index.html
+-->
+
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-iconset-svg/iron-iconset-svg.html">
+<iron-iconset-svg name="icons" size="24">
+<svg><defs>
+<g id="3d-rotation"><path d="M7.52 21.48C4.25 19.94 1.91 16.76 1.55 13H.05C.56 19.16 5.71 24 12 24l.66-.03-3.81-3.81-1.33 1.32zm.89-6.52c-.19 0-.37-.03-.52-.08-.16-.06-.29-.13-.4-.24-.11-.1-.2-.22-.26-.37-.06-.14-.09-.3-.09-.47h-1.3c0 .36.07.68.21.95.14.27.33.5.56.69.24.18.51.32.82.41.3.1.62.15.96.15.37 0 .72-.05 1.03-.15.32-.1.6-.25.83-.44s.42-.43.55-.72c.13-.29.2-.61.2-.97 0-.19-.02-.38-.07-.56-.05-.18-.12-.35-.23-.51-.1-.16-.24-.3-.4-.43-.17-.13-.37-.23-.61-.31.2-.09.37-.2.52-.33.15-.13.27-.27.37-.42.1-.15.17-.3.22-.46.05-.16.07-.32.07-.48 0-.36-.06-.68-.18-.96-.12-.28-.29-.51-.51-.69-.2-.19-.47-.33-.77-.43C9.1 8.05 8.76 8 8.39 8c-.36 0-.69.05-1 .16-.3.11-.57.26-.79.45-.21.19-.38.41-.51.67-.12.26-.18.54-.18.85h1.3c0-.17.03-.32.09-.45s.14-.25.25-.34c.11-.09.23-.17.38-.22.15-.05.3-.08.48-.08.4 0 .7.1.89.31.19.2.29.49.29.86 0 .18-.03.34-.08.49-.05.15-.14.27-.25.37-.11.1-.25.18-.41.24-.16.06-.36.09-.58.09H7.5v1.03h.77c.22 0 .42.02.6.07s.33.13.45.23c.12.11.22.24.29.4.07.16.1.35.1.57 0 .41-.12.72-.35.93-.23.23-.55.33-.95.33zm8.55-5.92c-.32-.33-.7-.59-1.14-.77-.43-.18-.92-.27-1.46-.27H12v8h2.3c.55 0 1.06-.09 1.51-.27.45-.18.84-.43 1.16-.76.32-.33.57-.73.74-1.19.17-.47.26-.99.26-1.57v-.4c0-.58-.09-1.1-.26-1.57-.18-.47-.43-.87-.75-1.2zm-.39 3.16c0 .42-.05.79-.14 1.13-.1.33-.24.62-.43.85-.19.23-.43.41-.71.53-.29.12-.62.18-.99.18h-.91V9.12h.97c.72 0 1.27.23 1.64.69.38.46.57 1.12.57 1.99v.4zM12 0l-.66.03 3.81 3.81 1.33-1.33c3.27 1.55 5.61 4.72 5.96 8.48h1.5C23.44 4.84 18.29 0 12 0z"/></g>
+<g id="accessibility"><path d="M12 2c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm9 7h-6v13h-2v-6h-2v6H9V9H3V7h18v2z"/></g>
+<g id="account-balance"><path d="M4 10v7h3v-7H4zm6 0v7h3v-7h-3zM2 22h19v-3H2v3zm14-12v7h3v-7h-3zm-4.5-9L2 6v2h19V6l-9.5-5z"/></g>
+<g id="account-balance-wallet"><path d="M21 18v1c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2V5c0-1.1.89-2 2-2h14c1.1 0 2 .9 2 2v1h-9c-1.11 0-2 .9-2 2v8c0 1.1.89 2 2 2h9zm-9-2h10V8H12v8zm4-2.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></g>
+<g id="account-box"><path d="M3 5v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2H5c-1.11 0-2 .9-2 2zm12 4c0 1.66-1.34 3-3 3s-3-1.34-3-3 1.34-3 3-3 3 1.34 3 3zm-9 8c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1H6v-1z"/></g>
+<g id="account-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"/></g>
+<g id="add"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></g>
+<g id="add-alert"><path d="M10.01 21.01c0 1.1.89 1.99 1.99 1.99s1.99-.89 1.99-1.99h-3.98zm8.87-4.19V11c0-3.25-2.25-5.97-5.29-6.69v-.72C13.59 2.71 12.88 2 12 2s-1.59.71-1.59 1.59v.72C7.37 5.03 5.12 7.75 5.12 11v5.82L3 18.94V20h18v-1.06l-2.12-2.12zM16 13.01h-3v3h-2v-3H8V11h3V8h2v3h3v2.01z"/></g>
+<g id="add-box"><path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"/></g>
+<g id="add-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"/></g>
+<g id="add-circle-outline"><path d="M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></g>
+<g id="add-shopping-cart"><path d="M11 9h2V6h3V4h-3V1h-2v3H8v2h3v3zm-4 9c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zm10 0c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2zm-9.83-3.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.86-7.01L19.42 4h-.01l-1.1 2-2.76 5H8.53l-.13-.27L6.16 6l-.95-2-.94-2H1v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.13 0-.25-.11-.25-.25z"/></g>
+<g id="alarm"><path d="M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12.5 8H11v6l4.75 2.85.75-1.23-4-2.37V8zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></g>
+<g id="alarm-add"><path d="M7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm1-11h-2v3H8v2h3v3h2v-3h3v-2h-3V9z"/></g>
+<g id="alarm-off"><path d="M12 6c3.87 0 7 3.13 7 7 0 .84-.16 1.65-.43 2.4l1.52 1.52c.58-1.19.91-2.51.91-3.92 0-4.97-4.03-9-9-9-1.41 0-2.73.33-3.92.91L9.6 6.43C10.35 6.16 11.16 6 12 6zm10-.28l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM2.92 2.29L1.65 3.57 2.98 4.9l-1.11.93 1.42 1.42 1.11-.94.8.8C3.83 8.69 3 10.75 3 13c0 4.97 4.02 9 9 9 2.25 0 4.31-.83 5.89-2.2l2.2 2.2 1.27-1.27L3.89 3.27l-.97-.98zm13.55 16.1C15.26 19.39 13.7 20 12 20c-3.87 0-7-3.13-7-7 0-1.7.61-3.26 1.61-4.47l9.86 9.86zM8.02 3.28L6.6 1.86l-.86.71 1.42 1.42.86-.71z"/></g>
+<g id="alarm-on"><path d="M22 5.72l-4.6-3.86-1.29 1.53 4.6 3.86L22 5.72zM7.88 3.39L6.6 1.86 2 5.71l1.29 1.53 4.59-3.85zM12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9c4.97 0 9-4.03 9-9s-4.03-9-9-9zm0 16c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7zm-1.46-5.47L8.41 12.4l-1.06 1.06 3.18 3.18 6-6-1.06-1.06-4.93 4.95z"/></g>
+<g id="android"><path d="M6 18c0 .55.45 1 1 1h1v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h2v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h1c.55 0 1-.45 1-1V8H6v10zM3.5 8C2.67 8 2 8.67 2 9.5v7c0 .83.67 1.5 1.5 1.5S5 17.33 5 16.5v-7C5 8.67 4.33 8 3.5 8zm17 0c-.83 0-1.5.67-1.5 1.5v7c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5v-7c0-.83-.67-1.5-1.5-1.5zm-4.97-5.84l1.3-1.3c.2-.2.2-.51 0-.71-.2-.2-.51-.2-.71 0l-1.48 1.48C13.85 1.23 12.95 1 12 1c-.96 0-1.86.23-2.66.63L7.85.15c-.2-.2-.51-.2-.71 0-.2.2-.2.51 0 .71l1.31 1.31C6.97 3.26 6 5.01 6 7h12c0-1.99-.97-3.75-2.47-4.84zM10 5H9V4h1v1zm5 0h-1V4h1v1z"/></g>
+<g id="announcement"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 9h-2V5h2v6zm0 4h-2v-2h2v2z"/></g>
+<g id="apps"><path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z"/></g>
+<g id="archive"><path d="M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z"/></g>
+<g id="arrow-back"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></g>
+<g id="arrow-drop-down"><path d="M7 10l5 5 5-5z"/></g>
+<g id="arrow-drop-down-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 12l-4-4h8l-4 4z"/></g>
+<g id="arrow-drop-up"><path d="M7 14l5-5 5 5z"/></g>
+<g id="arrow-forward"><path d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z"/></g>
+<g id="aspect-ratio"><path d="M19 12h-2v3h-3v2h5v-5zM7 9h3V7H5v5h2V9zm14-6H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02z"/></g>
+<g id="assessment"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/></g>
+<g id="assignment"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm2 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z"/></g>
+<g id="assignment-ind"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm0 4c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H6v-1.4c0-2 4-3.1 6-3.1s6 1.1 6 3.1V19z"/></g>
+<g id="assignment-late"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-6 15h-2v-2h2v2zm0-4h-2V8h2v6zm-1-9c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"/></g>
+<g id="assignment-return"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm4 12h-4v3l-5-5 5-5v3h4v4z"/></g>
+<g id="assignment-returned"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm0 15l-5-5h3V9h4v4h3l-5 5z"/></g>
+<g id="assignment-turned-in"><path d="M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm-2 14l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z"/></g>
+<g id="attachment"><path d="M7.5 18C4.46 18 2 15.54 2 12.5S4.46 7 7.5 7H18c2.21 0 4 1.79 4 4s-1.79 4-4 4H9.5C8.12 15 7 13.88 7 12.5S8.12 10 9.5 10H17v1.5H9.5c-.55 0-1 .45-1 1s.45 1 1 1H18c1.38 0 2.5-1.12 2.5-2.5S19.38 8.5 18 8.5H7.5c-2.21 0-4 1.79-4 4s1.79 4 4 4H17V18H7.5z"/></g>
+<g id="autorenew"><path d="M12 6v3l4-4-4-4v3c-4.42 0-8 3.58-8 8 0 1.57.46 3.03 1.24 4.26L6.7 14.8c-.45-.83-.7-1.79-.7-2.8 0-3.31 2.69-6 6-6zm6.76 1.74L17.3 9.2c.44.84.7 1.79.7 2.8 0 3.31-2.69 6-6 6v-3l-4 4 4 4v-3c4.42 0 8-3.58 8-8 0-1.57-.46-3.03-1.24-4.26z"/></g>
+<g id="backspace"><path d="M22 3H7c-.69 0-1.23.35-1.59.88L0 12l5.41 8.11c.36.53.9.89 1.59.89h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-3 12.59L17.59 17 14 13.41 10.41 17 9 15.59 12.59 12 9 8.41 10.41 7 14 10.59 17.59 7 19 8.41 15.41 12 19 15.59z"/></g>
+<g id="backup"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z"/></g>
+<g id="block"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-4.42 3.58-8 8-8 1.85 0 3.55.63 4.9 1.69L5.69 16.9C4.63 15.55 4 13.85 4 12zm8 8c-1.85 0-3.55-.63-4.9-1.69L18.31 7.1C19.37 8.45 20 10.15 20 12c0 4.42-3.58 8-8 8z"/></g>
+<g id="book"><path d="M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 4h5v8l-2.5-1.5L6 12V4z"/></g>
+<g id="bookmark"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z"/></g>
+<g id="bookmark-border"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2zm0 15l-5-2.18L7 18V5h10v13z"/></g>
+<g id="bug-report"><path d="M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z"/></g>
+<g id="build"><path d="M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z"/></g>
+<g id="cached"><path d="M19 8l-4 4h3c0 3.31-2.69 6-6 6-1.01 0-1.97-.25-2.8-.7l-1.46 1.46C8.97 19.54 10.43 20 12 20c4.42 0 8-3.58 8-8h3l-4-4zM6 12c0-3.31 2.69-6 6-6 1.01 0 1.97.25 2.8.7l1.46-1.46C15.03 4.46 13.57 4 12 4c-4.42 0-8 3.58-8 8H1l4 4 4-4H6z"/></g>
+<g id="camera-enhance"><path d="M9 3L7.17 5H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2h-3.17L15 3H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zM12 17l1.25-2.75L16 13l-2.75-1.25L12 9l-1.25 2.75L8 13l2.75 1.25z"/></g>
+<g id="cancel"><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"/></g>
+<g id="card-giftcard"><path d="M20 6h-2.18c.11-.31.18-.65.18-1 0-1.66-1.34-3-3-3-1.05 0-1.96.54-2.5 1.35l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 11 8.76l1-1.36 1 1.36L15.38 12 17 10.83 14.92 8H20v6z"/></g>
+<g id="card-membership"><path d="M20 2H4c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h4v5l4-2 4 2v-5h4c1.11 0 2-.89 2-2V4c0-1.11-.89-2-2-2zm0 13H4v-2h16v2zm0-5H4V4h16v6z"/></g>
+<g id="card-travel"><path d="M20 6h-3V4c0-1.11-.89-2-2-2H9c-1.11 0-2 .89-2 2v2H4c-1.11 0-2 .89-2 2v11c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zM9 4h6v2H9V4zm11 15H4v-2h16v2zm0-5H4V8h3v2h2V8h6v2h2V8h3v6z"/></g>
+<g id="change-history"><path d="M12 7.77L18.39 18H5.61L12 7.77M12 4L2 20h20L12 4z"/></g>
+<g id="check"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></g>
+<g id="check-box"><path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></g>
+<g id="check-box-outline-blank"><path d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/></g>
+<g id="check-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></g>
+<g id="chevron-left"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></g>
+<g id="chevron-right"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></g>
+<g id="chrome-reader-mode"><path d="M13 12h7v1.5h-7zm0-2.5h7V11h-7zm0 5h7V16h-7zM21 4H3c-1.1 0-2 .9-2 2v13c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 15h-9V6h9v13z"/></g>
+<g id="class"><path d="M18 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 4h5v8l-2.5-1.5L6 12V4z"/></g>
+<g id="clear"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></g>
+<g id="close"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></g>
+<g id="cloud"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96z"/></g>
+<g id="cloud-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.5 14H8c-1.66 0-3-1.34-3-3s1.34-3 3-3l.14.01C8.58 8.28 10.13 7 12 7c2.21 0 4 1.79 4 4h.5c1.38 0 2.5 1.12 2.5 2.5S17.88 16 16.5 16z"/></g>
+<g id="cloud-done"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM10 17l-3.5-3.5 1.41-1.41L10 14.17 15.18 9l1.41 1.41L10 17z"/></g>
+<g id="cloud-download"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM17 13l-5 5-5-5h3V9h4v4h3z"/></g>
+<g id="cloud-off"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4c-1.48 0-2.85.43-4.01 1.17l1.46 1.46C10.21 6.23 11.08 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3 0 1.13-.64 2.11-1.56 2.62l1.45 1.45C23.16 18.16 24 16.68 24 15c0-2.64-2.05-4.78-4.65-4.96zM3 5.27l2.75 2.74C2.56 8.15 0 10.77 0 14c0 3.31 2.69 6 6 6h11.73l2 2L21 20.73 4.27 4 3 5.27zM7.73 10l8 8H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h1.73z"/></g>
+<g id="cloud-queue"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4s1.79-4 4-4h.71C7.37 7.69 9.48 6 12 6c3.04 0 5.5 2.46 5.5 5.5v.5H19c1.66 0 3 1.34 3 3s-1.34 3-3 3z"/></g>
+<g id="cloud-upload"><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z"/></g>
+<g id="code"><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/></g>
+<g id="content-copy"><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></g>
+<g id="content-cut"><path d="M9.64 7.64c.23-.5.36-1.05.36-1.64 0-2.21-1.79-4-4-4S2 3.79 2 6s1.79 4 4 4c.59 0 1.14-.13 1.64-.36L10 12l-2.36 2.36C7.14 14.13 6.59 14 6 14c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4c0-.59-.13-1.14-.36-1.64L12 14l7 7h3v-1L9.64 7.64zM6 8c-1.1 0-2-.89-2-2s.9-2 2-2 2 .89 2 2-.9 2-2 2zm0 12c-1.1 0-2-.89-2-2s.9-2 2-2 2 .89 2 2-.9 2-2 2zm6-7.5c-.28 0-.5-.22-.5-.5s.22-.5.5-.5.5.22.5.5-.22.5-.5.5zM19 3l-6 6 2 2 7-7V3z"/></g>
+<g id="content-paste"><path d="M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z"/></g>
+<g id="create"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></g>
+<g id="credit-card"><path d="M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z"/></g>
+<g id="dashboard"><path d="M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z"/></g>
+<g id="delete"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></g>
+<g id="description"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/></g>
+<g id="dns"><path d="M20 13H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zM7 19c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM20 3H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zM7 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></g>
+<g id="done"><path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"/></g>
+<g id="done-all"><path d="M18 7l-1.41-1.41-6.34 6.34 1.41 1.41L18 7zm4.24-1.41L11.66 16.17 7.48 12l-1.41 1.41L11.66 19l12-12-1.42-1.41zM.41 13.41L6 19l1.41-1.41L1.83 12 .41 13.41z"/></g>
+<g id="drafts"><path d="M21.99 8c0-.72-.37-1.35-.94-1.7L12 1 2.95 6.3C2.38 6.65 2 7.28 2 8v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2l-.01-10zM12 13L3.74 7.84 12 3l8.26 4.84L12 13z"/></g>
+<g id="eject"><path d="M5 17h14v2H5zm7-12L5.33 15h13.34z"/></g>
+<g id="error"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/></g>
+<g id="error-outline"><path d="M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/></g>
+<g id="event"><path d="M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z"/></g>
+<g id="event-seat"><defs><path id="a" d="M0 0h24v24H0V0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path d="M4 18v3h3v-3h10v3h3v-6H4zm15-8h3v3h-3zM2 10h3v3H2zm15 3H7V5c0-1.1.9-2 2-2h6c1.1 0 2 .9 2 2v8z" clip-path="url(#b)"/></g>
+<g id="exit-to-app"><path d="M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/></g>
+<g id="expand-less"><path d="M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z"/></g>
+<g id="expand-more"><path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"/></g>
+<g id="explore"><path d="M12 10.9c-.61 0-1.1.49-1.1 1.1s.49 1.1 1.1 1.1c.61 0 1.1-.49 1.1-1.1s-.49-1.1-1.1-1.1zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm2.19 12.19L6 18l3.81-8.19L18 6l-3.81 8.19z"/></g>
+<g id="extension"><path d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"/></g>
+<g id="face"><path d="M9 11.75c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zm6 0c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8 0-.29.02-.58.05-.86 2.36-1.05 4.23-2.98 5.21-5.37C11.07 8.33 14.05 10 17.42 10c.78 0 1.53-.09 2.25-.26.21.71.33 1.47.33 2.26 0 4.41-3.59 8-8 8z"/></g>
+<g id="favorite"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></g>
+<g id="favorite-border"><path d="M16.5 3c-1.74 0-3.41.81-4.5 2.09C10.91 3.81 9.24 3 7.5 3 4.42 3 2 5.42 2 8.5c0 3.78 3.4 6.86 8.55 11.54L12 21.35l1.45-1.32C18.6 15.36 22 12.28 22 8.5 22 5.42 19.58 3 16.5 3zm-4.4 15.55l-.1.1-.1-.1C7.14 14.24 4 11.39 4 8.5 4 6.5 5.5 5 7.5 5c1.54 0 3.04.99 3.57 2.36h1.87C13.46 5.99 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5 0 2.89-3.14 5.74-7.9 10.05z"/></g>
+<g id="feedback"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 12h-2v-2h2v2zm0-4h-2V6h2v4z"/></g>
+<g id="file-download"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/></g>
+<g id="file-upload"><path d="M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z"/></g>
+<g id="filter-list"><path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/></g>
+<g id="find-in-page"><path d="M20 19.59V8l-6-6H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c.45 0 .85-.15 1.19-.4l-4.43-4.43c-.8.52-1.74.83-2.76.83-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5c0 1.02-.31 1.96-.83 2.75L20 19.59zM9 13c0 1.66 1.34 3 3 3s3-1.34 3-3-1.34-3-3-3-3 1.34-3 3z"/></g>
+<g id="find-replace"><path d="M11 6c1.38 0 2.63.56 3.54 1.46L12 10h6V4l-2.05 2.05C14.68 4.78 12.93 4 11 4c-3.53 0-6.43 2.61-6.92 6H6.1c.46-2.28 2.48-4 4.9-4zm5.64 9.14c.66-.9 1.12-1.97 1.28-3.14H15.9c-.46 2.28-2.48 4-4.9 4-1.38 0-2.63-.56-3.54-1.46L10 12H4v6l2.05-2.05C7.32 17.22 9.07 18 11 18c1.55 0 2.98-.51 4.14-1.36L20 21.49 21.49 20l-4.85-4.86z"/></g>
+<g id="flag"><path d="M14.4 6L14 4H5v17h2v-7h5.6l.4 2h7V6z"/></g>
+<g id="flight-land"><defs><path id="a" d="M0 0h24v24H0V0z"/></defs><defs><path id="c" d="M0 0h24v24H0V0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><clipPath id="d" clip-path="url(#b)"><use xlink:href="#c" overflow="visible"/></clipPath><path d="M2.5 19h19v2h-19zm7.18-5.73l4.35 1.16 5.31 1.42c.8.21 1.62-.26 1.84-1.06.21-.8-.26-1.62-1.06-1.84l-5.31-1.42-2.76-9.02L10.12 2v8.28L5.15 8.95l-.93-2.32-1.45-.39v5.17l1.6.43 5.31 1.43z" clip-path="url(#d)"/></g>
+<g id="flight-takeoff"><defs><path id="a" d="M0 0h24v24H0V0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path d="M2.5 19h19v2h-19zm19.57-9.36c-.21-.8-1.04-1.28-1.84-1.06L14.92 10l-6.9-6.43-1.93.51 4.14 7.17-4.97 1.33-1.97-1.54-1.45.39 1.82 3.16.77 1.33 1.6-.43 5.31-1.42 4.35-1.16L21 11.49c.81-.23 1.28-1.05 1.07-1.85z" clip-path="url(#b)"/></g>
+<g id="flip-to-back"><path d="M9 7H7v2h2V7zm0 4H7v2h2v-2zm0-8c-1.11 0-2 .9-2 2h2V3zm4 12h-2v2h2v-2zm6-12v2h2c0-1.1-.9-2-2-2zm-6 0h-2v2h2V3zM9 17v-2H7c0 1.1.89 2 2 2zm10-4h2v-2h-2v2zm0-4h2V7h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zM5 7H3v12c0 1.1.89 2 2 2h12v-2H5V7zm10-2h2V3h-2v2zm0 12h2v-2h-2v2z"/></g>
+<g id="flip-to-front"><path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm2 4v-2H3c0 1.1.89 2 2 2zM3 9h2V7H3v2zm12 12h2v-2h-2v2zm4-18H9c-1.11 0-2 .9-2 2v10c0 1.1.89 2 2 2h10c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12H9V5h10v10zm-8 6h2v-2h-2v2zm-4 0h2v-2H7v2z"/></g>
+<g id="folder"><path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></g>
+<g id="folder-open"><path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z"/></g>
+<g id="folder-shared"><path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-5 3c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm4 8h-8v-1c0-1.33 2.67-2 4-2s4 .67 4 2v1z"/></g>
+<g id="font-download"><path d="M9.93 13.5h4.14L12 7.98zM20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-4.05 16.5l-1.14-3H9.17l-1.12 3H5.96l5.11-13h1.86l5.11 13h-2.09z"/></g>
+<g id="forward"><path d="M12 8V4l8 8-8 8v-4H4V8z"/></g>
+<g id="fullscreen"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></g>
+<g id="fullscreen-exit"><path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"/></g>
+<g id="gesture"><path d="M4.59 6.89c.7-.71 1.4-1.35 1.71-1.22.5.2 0 1.03-.3 1.52-.25.42-2.86 3.89-2.86 6.31 0 1.28.48 2.34 1.34 2.98.75.56 1.74.73 2.64.46 1.07-.31 1.95-1.4 3.06-2.77 1.21-1.49 2.83-3.44 4.08-3.44 1.63 0 1.65 1.01 1.76 1.79-3.78.64-5.38 3.67-5.38 5.37 0 1.7 1.44 3.09 3.21 3.09 1.63 0 4.29-1.33 4.69-6.1H21v-2.5h-2.47c-.15-1.65-1.09-4.2-4.03-4.2-2.25 0-4.18 1.91-4.94 2.84-.58.73-2.06 2.48-2.29 2.72-.25.3-.68.84-1.11.84-.45 0-.72-.83-.36-1.92.35-1.09 1.4-2.86 1.85-3.52.78-1.14 1.3-1.92 1.3-3.28C8.95 3.69 7.31 3 6.44 3 5.12 3 3.97 4 3.72 4.25c-.36.36-.66.66-.88.93l1.75 1.71zm9.29 11.66c-.31 0-.74-.26-.74-.72 0-.6.73-2.2 2.87-2.76-.3 2.69-1.43 3.48-2.13 3.48z"/></g>
+<g id="get-app"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/></g>
+<g id="gif"><defs><path id="a" d="M24 24H0V0h24v24z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path d="M11.5 9H13v6h-1.5zM9 9H6c-.6 0-1 .5-1 1v4c0 .5.4 1 1 1h3c.6 0 1-.5 1-1v-2H8.5v1.5h-2v-3H10V10c0-.5-.4-1-1-1zm10 1.5V9h-4.5v6H16v-2h2v-1.5h-2v-1z" clip-path="url(#b)"/></g>
+<g id="grade"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></g>
+<g id="group-work"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM8 17.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5zM9.5 8c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5S9.5 9.38 9.5 8zm6.5 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/></g>
+<g id="help"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"/></g>
+<g id="help-outline"><path d="M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z"/></g>
+<g id="highlight-off"><path d="M14.59 8L12 10.59 9.41 8 8 9.41 10.59 12 8 14.59 9.41 16 12 13.41 14.59 16 16 14.59 13.41 12 16 9.41 14.59 8zM12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></g>
+<g id="history"><path opacity=".9" d="M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z"/></g>
+<g id="home"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></g>
+<g id="hourglass-empty"><path d="M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6zm10 14.5V20H8v-3.5l4-4 4 4zm-4-5l-4-4V4h8v3.5l-4 4z"/></g>
+<g id="hourglass-full"><path d="M6 2v6h.01L6 8.01 10 12l-4 4 .01.01H6V22h12v-5.99h-.01L18 16l-4-4 4-3.99-.01-.01H18V2H6z"/></g>
+<g id="http"><path d="M4.5 11h-2V9H1v6h1.5v-2.5h2V15H6V9H4.5v2zm2.5-.5h1.5V15H10v-4.5h1.5V9H7v1.5zm5.5 0H14V15h1.5v-4.5H17V9h-4.5v1.5zm9-1.5H18v6h1.5v-2h2c.8 0 1.5-.7 1.5-1.5v-1c0-.8-.7-1.5-1.5-1.5zm0 2.5h-2v-1h2v1z"/></g>
+<g id="https"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/></g>
+<g id="inbox"><path d="M19 3H4.99c-1.1 0-1.98.9-1.98 2L3 19c0 1.1.89 2 1.99 2H19c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12h-4c0 1.66-1.34 3-3 3s-3-1.34-3-3H4.99V5H19v10zm-3-5h-2V7h-4v3H8l4 4 4-4z"/></g>
+<g id="indeterminate-check-box"><defs><path id="a" d="M0 0h24v24H0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path clip-path="url(#b)" d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10H7v-2h10v2z"/></g>
+<g id="info"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/></g>
+<g id="info-outline"><path d="M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z"/></g>
+<g id="input"><path d="M21 3.01H3c-1.1 0-2 .9-2 2V9h2V4.99h18v14.03H3V15H1v4.01c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98v-14c0-1.11-.9-2-2-2zM11 16l4-4-4-4v3H1v2h10v3z"/></g>
+<g id="invert-colors"><path d="M17.66 7.93L12 2.27 6.34 7.93c-3.12 3.12-3.12 8.19 0 11.31C7.9 20.8 9.95 21.58 12 21.58c2.05 0 4.1-.78 5.66-2.34 3.12-3.12 3.12-8.19 0-11.31zM12 19.59c-1.6 0-3.11-.62-4.24-1.76C6.62 16.69 6 15.19 6 13.59s.62-3.11 1.76-4.24L12 5.1v14.49z"/></g>
+<g id="label"><path d="M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16z"/></g>
+<g id="label-outline"><path d="M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16zM16 17H5V7h11l3.55 5L16 17z"/></g>
+<g id="language"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z"/></g>
+<g id="launch"><path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"/></g>
+<g id="link"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></g>
+<g id="list"><path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"/></g>
+<g id="lock"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/></g>
+<g id="lock-open"><path d="M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6h1.9c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm0 12H6V10h12v10z"/></g>
+<g id="lock-outline"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6-5.1c1.71 0 3.1 1.39 3.1 3.1v2H9V6h-.1c0-1.71 1.39-3.1 3.1-3.1zM18 20H6V10h12v10zm-6-3c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z"/></g>
+<g id="loyalty"><path d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7zm11.77 8.27L13 19.54l-4.27-4.27C8.28 14.81 8 14.19 8 13.5c0-1.38 1.12-2.5 2.5-2.5.69 0 1.32.28 1.77.74l.73.72.73-.73c.45-.45 1.08-.73 1.77-.73 1.38 0 2.5 1.12 2.5 2.5 0 .69-.28 1.32-.73 1.77z"/></g>
+<g id="mail"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></g>
+<g id="markunread"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></g>
+<g id="markunread-mailbox"><path d="M20 6H10v6H8V4h6V0H6v6H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2z"/></g>
+<g id="menu"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/></g>
+<g id="more-horiz"><path d="M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></g>
+<g id="more-vert"><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></g>
+<g id="note-add"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 14h-3v3h-2v-3H8v-2h3v-3h2v3h3v2zm-3-7V3.5L18.5 9H13z"/></g>
+<g id="offline-pin"><defs><path id="a" d="M0 0h24v24H0V0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path clip-path="url(#b)" d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm5 16H7v-2h10v2zm-6.7-4L7 10.7l1.4-1.4 1.9 1.9 5.3-5.3L17 7.3 10.3 14z"/></g>
+<g id="open-in-browser"><path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z"/></g>
+<g id="open-in-new"><path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"/></g>
+<g id="open-with"><path d="M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"/></g>
+<g id="pageview"><path d="M11.5 9C10.12 9 9 10.12 9 11.5s1.12 2.5 2.5 2.5 2.5-1.12 2.5-2.5S12.88 9 11.5 9zM20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-3.21 14.21l-2.91-2.91c-.69.44-1.51.7-2.39.7C9.01 16 7 13.99 7 11.5S9.01 7 11.5 7 16 9.01 16 11.5c0 .88-.26 1.69-.7 2.39l2.91 2.9-1.42 1.42z"/></g>
+<g id="payment"><path d="M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z"/></g>
+<g id="perm-camera-mic"><path d="M20 5h-3.17L15 3H9L7.17 5H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7v-2.09c-2.83-.48-5-2.94-5-5.91h2c0 2.21 1.79 4 4 4s4-1.79 4-4h2c0 2.97-2.17 5.43-5 5.91V21h7c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-6 8c0 1.1-.9 2-2 2s-2-.9-2-2V9c0-1.1.9-2 2-2s2 .9 2 2v4z"/></g>
+<g id="perm-contact-calendar"><path d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm6 12H6v-1c0-2 4-3.1 6-3.1s6 1.1 6 3.1v1z"/></g>
+<g id="perm-data-setting"><path d="M18.99 11.5c.34 0 .67.03 1 .07L20 0 0 20h11.56c-.04-.33-.07-.66-.07-1 0-4.14 3.36-7.5 7.5-7.5zm3.71 7.99c.02-.16.04-.32.04-.49 0-.17-.01-.33-.04-.49l1.06-.83c.09-.08.12-.21.06-.32l-1-1.73c-.06-.11-.19-.15-.31-.11l-1.24.5c-.26-.2-.54-.37-.85-.49l-.19-1.32c-.01-.12-.12-.21-.24-.21h-2c-.12 0-.23.09-.25.21l-.19 1.32c-.3.13-.59.29-.85.49l-1.24-.5c-.11-.04-.24 0-.31.11l-1 1.73c-.06.11-.04.24.06.32l1.06.83c-.02.16-.03.32-.03.49 0 .17.01.33.03.49l-1.06.83c-.09.08-.12.21-.06.32l1 1.73c.06.11.19.15.31.11l1.24-.5c.26.2.54.37.85.49l.19 1.32c.02.12.12.21.25.21h2c.12 0 .23-.09.25-.21l.19-1.32c.3-.13.59-.29.84-.49l1.25.5c.11.04.24 0 .31-.11l1-1.73c.06-.11.03-.24-.06-.32l-1.07-.83zm-3.71 1.01c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></g>
+<g id="perm-device-information"><path d="M13 7h-2v2h2V7zm0 4h-2v6h2v-6zm4-9.99L7 1c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z"/></g>
+<g id="perm-identity"><path d="M12 5.9c1.16 0 2.1.94 2.1 2.1s-.94 2.1-2.1 2.1S9.9 9.16 9.9 8s.94-2.1 2.1-2.1m0 9c2.97 0 6.1 1.46 6.1 2.1v1.1H5.9V17c0-.64 3.13-2.1 6.1-2.1M12 4C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 9c-2.67 0-8 1.34-8 4v3h16v-3c0-2.66-5.33-4-8-4z"/></g>
+<g id="perm-media"><path d="M2 6H0v5h.01L0 20c0 1.1.9 2 2 2h18v-2H2V6zm20-2h-8l-2-2H6c-1.1 0-1.99.9-1.99 2L4 16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM7 15l4.5-6 3.5 4.51 2.5-3.01L21 15H7z"/></g>
+<g id="perm-phone-msg"><path d="M20 15.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.58l2.2-2.21c.28-.27.36-.66.25-1.01C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM12 3v10l3-3h6V3h-9z"/></g>
+<g id="perm-scan-wifi"><path d="M12 3C6.95 3 3.15 4.85 0 7.23L12 22 24 7.25C20.85 4.87 17.05 3 12 3zm1 13h-2v-6h2v6zm-2-8V6h2v2h-2z"/></g>
+<g id="picture-in-picture"><path d="M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z"/></g>
+<g id="play-for-work"><path fill="#010101" d="M11 5v5.59H7.5l4.5 4.5 4.5-4.5H13V5h-2zm-5 9c0 3.31 2.69 6 6 6s6-2.69 6-6h-2c0 2.21-1.79 4-4 4s-4-1.79-4-4H6z"/></g>
+<g id="polymer"><path d="M19 4h-4L7.11 16.63 4.5 12 9 4H5L.5 12 5 20h4l7.89-12.63L19.5 12 15 20h4l4.5-8z"/></g>
+<g id="power-settings-new"><path d="M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z"/></g>
+<g id="print"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/></g>
+<g id="query-builder"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zM12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"/></g>
+<g id="question-answer"><path d="M21 6h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1zm-4 6V3c0-.55-.45-1-1-1H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1z"/></g>
+<g id="radio-button-checked"><path d="M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/></g>
+<g id="radio-button-unchecked"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/></g>
+<g id="receipt"><path d="M18 17H6v-2h12v2zm0-4H6v-2h12v2zm0-4H6V7h12v2zM3 22l1.5-1.5L6 22l1.5-1.5L9 22l1.5-1.5L12 22l1.5-1.5L15 22l1.5-1.5L18 22l1.5-1.5L21 22V2l-1.5 1.5L18 2l-1.5 1.5L15 2l-1.5 1.5L12 2l-1.5 1.5L9 2 7.5 3.5 6 2 4.5 3.5 3 2v20z"/></g>
+<g id="redeem"><path d="M20 6h-2.18c.11-.31.18-.65.18-1 0-1.66-1.34-3-3-3-1.05 0-1.96.54-2.5 1.35l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 11 8.76l1-1.36 1 1.36L15.38 12 17 10.83 14.92 8H20v6z"/></g>
+<g id="redo"><path d="M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16c1.05-3.19 4.05-5.5 7.6-5.5 1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z"/></g>
+<g id="refresh"><path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></g>
+<g id="remove"><path d="M19 13H5v-2h14v2z"/></g>
+<g id="remove-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z"/></g>
+<g id="remove-circle-outline"><path d="M7 11v2h10v-2H7zm5-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></g>
+<g id="reorder"><path d="M3 15h18v-2H3v2zm0 4h18v-2H3v2zm0-8h18V9H3v2zm0-6v2h18V5H3z"/></g>
+<g id="reply"><path d="M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z"/></g>
+<g id="reply-all"><path d="M7 8V5l-7 7 7 7v-3l-4-4 4-4zm6 1V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z"/></g>
+<g id="report"><path d="M15.73 3H8.27L3 8.27v7.46L8.27 21h7.46L21 15.73V8.27L15.73 3zM12 17.3c-.72 0-1.3-.58-1.3-1.3 0-.72.58-1.3 1.3-1.3.72 0 1.3.58 1.3 1.3 0 .72-.58 1.3-1.3 1.3zm1-4.3h-2V7h2v6z"/></g>
+<g id="report-problem"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/></g>
+<g id="restore"><path d="M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z"/></g>
+<g id="room"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/></g>
+<g id="save"><path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"/></g>
+<g id="schedule"><path fill-opacity=".9" d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zM12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"/></g>
+<g id="search"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></g>
+<g id="select-all"><path d="M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2zM7 17h10V7H7v10zm2-8h6v6H9V9z"/></g>
+<g id="send"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></g>
+<g id="settings"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"/></g>
+<g id="settings-applications"><path d="M12 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm7-7H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-1.75 9c0 .23-.02.46-.05.68l1.48 1.16c.13.11.17.3.08.45l-1.4 2.42c-.09.15-.27.21-.43.15l-1.74-.7c-.36.28-.76.51-1.18.69l-.26 1.85c-.03.17-.18.3-.35.3h-2.8c-.17 0-.32-.13-.35-.29l-.26-1.85c-.43-.18-.82-.41-1.18-.69l-1.74.7c-.16.06-.34 0-.43-.15l-1.4-2.42c-.09-.15-.05-.34.08-.45l1.48-1.16c-.03-.23-.05-.46-.05-.69 0-.23.02-.46.05-.68l-1.48-1.16c-.13-.11-.17-.3-.08-.45l1.4-2.42c.09-.15.27-.21.43-.15l1.74.7c.36-.28.76-.51 1.18-.69l.26-1.85c.03-.17.18-.3.35-.3h2.8c.17 0 .32.13.35.29l.26 1.85c.43.18.82.41 1.18.69l1.74-.7c.16-.06.34 0 .43.15l1.4 2.42c.09.15.05.34-.08.45l-1.48 1.16c.03.23.05.46.05.69z"/></g>
+<g id="settings-backup-restore"><path d="M14 12c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2zm-2-9c-4.97 0-9 4.03-9 9H0l4 4 4-4H5c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.51 0-2.91-.49-4.06-1.3l-1.42 1.44C8.04 20.3 9.94 21 12 21c4.97 0 9-4.03 9-9s-4.03-9-9-9z"/></g>
+<g id="settings-bluetooth"><path d="M11 24h2v-2h-2v2zm-4 0h2v-2H7v2zm8 0h2v-2h-2v2zm2.71-18.29L12 0h-1v7.59L6.41 3 5 4.41 10.59 10 5 15.59 6.41 17 11 12.41V20h1l5.71-5.71-4.3-4.29 4.3-4.29zM13 3.83l1.88 1.88L13 7.59V3.83zm1.88 10.46L13 16.17v-3.76l1.88 1.88z"/></g>
+<g id="settings-brightness"><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02zM8 16h2.5l1.5 1.5 1.5-1.5H16v-2.5l1.5-1.5-1.5-1.5V8h-2.5L12 6.5 10.5 8H8v2.5L6.5 12 8 13.5V16zm4-7c1.66 0 3 1.34 3 3s-1.34 3-3 3V9z"/></g>
+<g id="settings-cell"><path d="M7 24h2v-2H7v2zm4 0h2v-2h-2v2zm4 0h2v-2h-2v2zM16 .01L8 0C6.9 0 6 .9 6 2v16c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V2c0-1.1-.9-1.99-2-1.99zM16 16H8V4h8v12z"/></g>
+<g id="settings-ethernet"><path d="M7.77 6.76L6.23 5.48.82 12l5.41 6.52 1.54-1.28L3.42 12l4.35-5.24zM7 13h2v-2H7v2zm10-2h-2v2h2v-2zm-6 2h2v-2h-2v2zm6.77-7.52l-1.54 1.28L20.58 12l-4.35 5.24 1.54 1.28L23.18 12l-5.41-6.52z"/></g>
+<g id="settings-input-antenna"><path d="M12 5c-3.87 0-7 3.13-7 7h2c0-2.76 2.24-5 5-5s5 2.24 5 5h2c0-3.87-3.13-7-7-7zm1 9.29c.88-.39 1.5-1.26 1.5-2.29 0-1.38-1.12-2.5-2.5-2.5S9.5 10.62 9.5 12c0 1.02.62 1.9 1.5 2.29v3.3L7.59 21 9 22.41l3-3 3 3L16.41 21 13 17.59v-3.3zM12 1C5.93 1 1 5.93 1 12h2c0-4.97 4.03-9 9-9s9 4.03 9 9h2c0-6.07-4.93-11-11-11z"/></g>
+<g id="settings-input-component"><path d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"/></g>
+<g id="settings-input-composite"><path d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"/></g>
+<g id="settings-input-hdmi"><path d="M18 7V4c0-1.1-.9-2-2-2H8c-1.1 0-2 .9-2 2v3H5v6l3 6v3h8v-3l3-6V7h-1zM8 4h8v3h-2V5h-1v2h-2V5h-1v2H8V4z"/></g>
+<g id="settings-input-svideo"><path d="M8 11.5c0-.83-.67-1.5-1.5-1.5S5 10.67 5 11.5 5.67 13 6.5 13 8 12.33 8 11.5zm7-5c0-.83-.67-1.5-1.5-1.5h-3C9.67 5 9 5.67 9 6.5S9.67 8 10.5 8h3c.83 0 1.5-.67 1.5-1.5zM8.5 15c-.83 0-1.5.67-1.5 1.5S7.67 18 8.5 18s1.5-.67 1.5-1.5S9.33 15 8.5 15zM12 1C5.93 1 1 5.93 1 12s4.93 11 11 11 11-4.93 11-11S18.07 1 12 1zm0 20c-4.96 0-9-4.04-9-9s4.04-9 9-9 9 4.04 9 9-4.04 9-9 9zm5.5-11c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm-2 5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z"/></g>
+<g id="settings-overscan"><path d="M12.01 5.5L10 8h4l-1.99-2.5zM18 10v4l2.5-1.99L18 10zM6 10l-2.5 2.01L6 14v-4zm8 6h-4l2.01 2.5L14 16zm7-13H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16.01H3V4.99h18v14.02z"/></g>
+<g id="settings-phone"><path d="M13 9h-2v2h2V9zm4 0h-2v2h2V9zm3 6.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.58l2.2-2.21c.28-.27.36-.66.25-1.01C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM19 9v2h2V9h-2z"/></g>
+<g id="settings-power"><path d="M7 24h2v-2H7v2zm4 0h2v-2h-2v2zm2-22h-2v10h2V2zm3.56 2.44l-1.45 1.45C16.84 6.94 18 8.83 18 11c0 3.31-2.69 6-6 6s-6-2.69-6-6c0-2.17 1.16-4.06 2.88-5.12L7.44 4.44C5.36 5.88 4 8.28 4 11c0 4.42 3.58 8 8 8s8-3.58 8-8c0-2.72-1.36-5.12-3.44-6.56zM15 24h2v-2h-2v2z"/></g>
+<g id="settings-remote"><path d="M15 9H9c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V10c0-.55-.45-1-1-1zm-3 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM7.05 6.05l1.41 1.41C9.37 6.56 10.62 6 12 6s2.63.56 3.54 1.46l1.41-1.41C15.68 4.78 13.93 4 12 4s-3.68.78-4.95 2.05zM12 0C8.96 0 6.21 1.23 4.22 3.22l1.41 1.41C7.26 3.01 9.51 2 12 2s4.74 1.01 6.36 2.64l1.41-1.41C17.79 1.23 15.04 0 12 0z"/></g>
+<g id="settings-voice"><path d="M7 24h2v-2H7v2zm5-11c1.66 0 2.99-1.34 2.99-3L15 4c0-1.66-1.34-3-3-3S9 2.34 9 4v6c0 1.66 1.34 3 3 3zm-1 11h2v-2h-2v2zm4 0h2v-2h-2v2zm4-14h-1.7c0 3-2.54 5.1-5.3 5.1S6.7 13 6.7 10H5c0 3.41 2.72 6.23 6 6.72V20h2v-3.28c3.28-.49 6-3.31 6-6.72z"/></g>
+<g id="shop"><path d="M16 6V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H2v13c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6h-6zm-6-2h4v2h-4V4zM9 18V9l7.5 4L9 18z"/></g>
+<g id="shop-two"><path d="M3 9H1v11c0 1.11.89 2 2 2h14c1.11 0 2-.89 2-2H3V9zm15-4V3c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H5v11c0 1.11.89 2 2 2h14c1.11 0 2-.89 2-2V5h-5zm-6-2h4v2h-4V3zm0 12V8l5.5 3-5.5 4z"/></g>
+<g id="shopping-basket"><path d="M17.21 9l-4.38-6.56c-.19-.28-.51-.42-.83-.42-.32 0-.64.14-.83.43L6.79 9H2c-.55 0-1 .45-1 1 0 .09.01.18.04.27l2.54 9.27c.23.84 1 1.46 1.92 1.46h13c.92 0 1.69-.62 1.93-1.46l2.54-9.27L23 10c0-.55-.45-1-1-1h-4.79zM9 9l3-4.4L15 9H9zm3 8c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></g>
+<g id="shopping-cart"><path d="M7 18c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zM1 2v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.14 0-.25-.11-.25-.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.58-6.49c.08-.14.12-.31.12-.48 0-.55-.45-1-1-1H5.21l-.94-2H1zm16 16c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2z"/></g>
+<g id="sort"><path d="M3 18h6v-2H3v2zM3 6v2h18V6H3zm0 7h12v-2H3v2z"/></g>
+<g id="speaker-notes"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM8 14H6v-2h2v2zm0-3H6V9h2v2zm0-3H6V6h2v2zm7 6h-5v-2h5v2zm3-3h-8V9h8v2zm0-3h-8V6h8v2z"/></g>
+<g id="spellcheck"><path d="M12.45 16h2.09L9.43 3H7.57L2.46 16h2.09l1.12-3h5.64l1.14 3zm-6.02-5L8.5 5.48 10.57 11H6.43zm15.16.59l-8.09 8.09L9.83 16l-1.41 1.41 5.09 5.09L23 13l-1.41-1.41z"/></g>
+<g id="star"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></g>
+<g id="star-border"><path d="M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4l-3.76 2.27 1-4.28-3.32-2.88 4.38-.38L12 6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z"/></g>
+<g id="star-half"><path d="M22 9.74l-7.19-.62L12 2.5 9.19 9.13 2 9.74l5.46 4.73-1.64 7.03L12 17.77l6.18 3.73-1.63-7.03L22 9.74zM12 15.9V6.6l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.9z"/></g>
+<g id="stars"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm4.24 16L12 15.45 7.77 18l1.12-4.81-3.73-3.23 4.92-.42L12 5l1.92 4.53 4.92.42-3.73 3.23L16.23 18z"/></g>
+<g id="store"><path d="M20 4H4v2h16V4zm1 10v-2l-1-5H4l-1 5v2h1v6h10v-6h4v6h2v-6h1zm-9 4H6v-4h6v4z"/></g>
+<g id="subject"><path d="M14 17H4v2h10v-2zm6-8H4v2h16V9zM4 15h16v-2H4v2zM4 5v2h16V5H4z"/></g>
+<g id="supervisor-account"><path d="M16.5 12c1.38 0 2.49-1.12 2.49-2.5S17.88 7 16.5 7C15.12 7 14 8.12 14 9.5s1.12 2.5 2.5 2.5zM9 11c1.66 0 2.99-1.34 2.99-3S10.66 5 9 5C7.34 5 6 6.34 6 8s1.34 3 3 3zm7.5 3c-1.83 0-5.5.92-5.5 2.75V19h11v-2.25c0-1.83-3.67-2.75-5.5-2.75zM9 13c-2.33 0-7 1.17-7 3.5V19h7v-2.25c0-.85.33-2.34 2.37-3.47C10.5 13.1 9.66 13 9 13z"/></g>
+<g id="swap-horiz"><path d="M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z"/></g>
+<g id="swap-vert"><path d="M16 17.01V10h-2v7.01h-3L15 21l4-3.99h-3zM9 3L5 6.99h3V14h2V6.99h3L9 3z"/></g>
+<g id="swap-vertical-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM6.5 9L10 5.5 13.5 9H11v4H9V9H6.5zm11 6L14 18.5 10.5 15H13v-4h2v4h2.5z"/></g>
+<g id="system-update-alt"><path d="M12 16.5l4-4h-3v-9h-2v9H8l4 4zm9-13h-6v1.99h6v14.03H3V5.49h6V3.5H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2v-14c0-1.1-.9-2-2-2z"/></g>
+<g id="tab"><path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h10v4h8v10z"/></g>
+<g id="tab-unselected"><path d="M1 9h2V7H1v2zm0 4h2v-2H1v2zm0-8h2V3c-1.1 0-2 .9-2 2zm8 16h2v-2H9v2zm-8-4h2v-2H1v2zm2 4v-2H1c0 1.1.9 2 2 2zM21 3h-8v6h10V5c0-1.1-.9-2-2-2zm0 14h2v-2h-2v2zM9 5h2V3H9v2zM5 21h2v-2H5v2zM5 5h2V3H5v2zm16 16c1.1 0 2-.9 2-2h-2v2zm0-8h2v-2h-2v2zm-8 8h2v-2h-2v2zm4 0h2v-2h-2v2z"/></g>
+<g id="text-format"><path d="M5 17v2h14v-2H5zm4.5-4.2h5l.9 2.2h2.1L12.75 4h-1.5L6.5 15h2.1l.9-2.2zM12 5.98L13.87 11h-3.74L12 5.98z"/></g>
+<g id="theaters"><path d="M18 3v2h-2V3H8v2H6V3H4v18h2v-2h2v2h8v-2h2v2h2V3h-2zM8 17H6v-2h2v2zm0-4H6v-2h2v2zm0-4H6V7h2v2zm10 8h-2v-2h2v2zm0-4h-2v-2h2v2zm0-4h-2V7h2v2z"/></g>
+<g id="thumb-down"><path d="M15 3H6c-.83 0-1.54.5-1.84 1.22l-3.02 7.05c-.09.23-.14.47-.14.73v1.91l.01.01L1 14c0 1.1.9 2 2 2h6.31l-.95 4.57-.03.32c0 .41.17.79.44 1.06L9.83 23l6.59-6.59c.36-.36.58-.86.58-1.41V5c0-1.1-.9-2-2-2zm4 0v12h4V3h-4z"/></g>
+<g id="thumb-up"><path d="M1 21h4V9H1v12zm22-11c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-1.91l-.01-.01L23 10z"/></g>
+<g id="thumbs-up-down"><path d="M12 6c0-.55-.45-1-1-1H5.82l.66-3.18.02-.23c0-.31-.13-.59-.33-.8L5.38 0 .44 4.94C.17 5.21 0 5.59 0 6v6.5c0 .83.67 1.5 1.5 1.5h6.75c.62 0 1.15-.38 1.38-.91l2.26-5.29c.07-.17.11-.36.11-.55V6zm10.5 4h-6.75c-.62 0-1.15.38-1.38.91l-2.26 5.29c-.07.17-.11.36-.11.55V18c0 .55.45 1 1 1h5.18l-.66 3.18-.02.24c0 .31.13.59.33.8l.79.78 4.94-4.94c.27-.27.44-.65.44-1.06v-6.5c0-.83-.67-1.5-1.5-1.5z"/></g>
+<g id="toc"><path d="M3 9h14V7H3v2zm0 4h14v-2H3v2zm0 4h14v-2H3v2zm16 0h2v-2h-2v2zm0-10v2h2V7h-2zm0 6h2v-2h-2v2z"/></g>
+<g id="today"><path d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z"/></g>
+<g id="toll"><path d="M15 4c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6zM3 12c0-2.61 1.67-4.83 4-5.65V4.26C3.55 5.15 1 8.27 1 12s2.55 6.85 6 7.74v-2.09c-2.33-.82-4-3.04-4-5.65z"/></g>
+<g id="track-changes"><path fill="#231F20" d="M19.07 4.93l-1.41 1.41C19.1 7.79 20 9.79 20 12c0 4.42-3.58 8-8 8s-8-3.58-8-8c0-4.08 3.05-7.44 7-7.93v2.02C8.16 6.57 6 9.03 6 12c0 3.31 2.69 6 6 6s6-2.69 6-6c0-1.66-.67-3.16-1.76-4.24l-1.41 1.41C15.55 9.9 16 10.9 16 12c0 2.21-1.79 4-4 4s-4-1.79-4-4c0-1.86 1.28-3.41 3-3.86v2.14c-.6.35-1 .98-1 1.72 0 1.1.9 2 2 2s2-.9 2-2c0-.74-.4-1.38-1-1.72V2h-1C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10c0-2.76-1.12-5.26-2.93-7.07z"/></g>
+<g id="translate"><path d="M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"/></g>
+<g id="trending-down"><path d="M16 18l2.29-2.29-4.88-4.88-4 4L2 7.41 3.41 6l6 6 4-4 6.3 6.29L22 12v6z"/></g>
+<g id="trending-flat"><path d="M22 12l-4-4v3H3v2h15v3z"/></g>
+<g id="trending-up"><path d="M16 6l2.29 2.29-4.88 4.88-4-4L2 16.59 3.41 18l6-6 4 4 6.3-6.29L22 12V6z"/></g>
+<g id="turned-in"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z"/></g>
+<g id="turned-in-not"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2zm0 15l-5-2.18L7 18V5h10v13z"/></g>
+<g id="undo"><path d="M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z"/></g>
+<g id="unfold-less"><path d="M7.41 18.59L8.83 20 12 16.83 15.17 20l1.41-1.41L12 14l-4.59 4.59zm9.18-13.18L15.17 4 12 7.17 8.83 4 7.41 5.41 12 10l4.59-4.59z"/></g>
+<g id="unfold-more"><path d="M12 5.83L15.17 9l1.41-1.41L12 3 7.41 7.59 8.83 9 12 5.83zm0 12.34L8.83 15l-1.41 1.41L12 21l4.59-4.59L15.17 15 12 18.17z"/></g>
+<g id="verified-user"><path d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm-2 16l-4-4 1.41-1.41L10 14.17l6.59-6.59L18 9l-8 8z"/></g>
+<g id="view-agenda"><path d="M20 13H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zm0-10H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1z"/></g>
+<g id="view-array"><path d="M4 18h3V5H4v13zM18 5v13h3V5h-3zM8 18h9V5H8v13z"/></g>
+<g id="view-carousel"><path d="M7 19h10V4H7v15zm-5-2h4V6H2v11zM18 6v11h4V6h-4z"/></g>
+<g id="view-column"><path d="M10 18h5V5h-5v13zm-6 0h5V5H4v13zM16 5v13h5V5h-5z"/></g>
+<g id="view-day"><path d="M2 21h19v-3H2v3zM20 8H3c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h17c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1zM2 3v3h19V3H2z"/></g>
+<g id="view-headline"><path d="M4 15h16v-2H4v2zm0 4h16v-2H4v2zm0-8h16V9H4v2zm0-6v2h16V5H4z"/></g>
+<g id="view-list"><path d="M4 14h4v-4H4v4zm0 5h4v-4H4v4zM4 9h4V5H4v4zm5 5h12v-4H9v4zm0 5h12v-4H9v4zM9 5v4h12V5H9z"/></g>
+<g id="view-module"><path d="M4 11h5V5H4v6zm0 7h5v-6H4v6zm6 0h5v-6h-5v6zm6 0h5v-6h-5v6zm-6-7h5V5h-5v6zm6-6v6h5V5h-5z"/></g>
+<g id="view-quilt"><path d="M10 18h5v-6h-5v6zm-6 0h5V5H4v13zm12 0h5v-6h-5v6zM10 5v6h11V5H10z"/></g>
+<g id="view-stream"><path d="M4 18h17v-6H4v6zM4 5v6h17V5H4z"/></g>
+<g id="view-week"><path d="M6 5H3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zm14 0h-3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zm-7 0h-3c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h3c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1z"/></g>
+<g id="visibility"><path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></g>
+<g id="visibility-off"><path d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"/></g>
+<g id="warning"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/></g>
+<g id="work"><path d="M20 6h-4V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-6 0h-4V4h4v2z"/></g>
+<g id="youtube-searched-for"><path d="M17.01 14h-.8l-.27-.27c.98-1.14 1.57-2.61 1.57-4.23 0-3.59-2.91-6.5-6.5-6.5s-6.5 3-6.5 6.5H2l3.84 4 4.16-4H6.51C6.51 7 8.53 5 11.01 5s4.5 2.01 4.5 4.5c0 2.48-2.02 4.5-4.5 4.5-.65 0-1.26-.14-1.82-.38L7.71 15.1c.97.57 2.09.9 3.3.9 1.61 0 3.08-.59 4.22-1.57l.27.27v.79l5.01 4.99L22 19l-4.99-5z"/></g>
+<g id="zoom-in"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z"/></g>
+<g id="zoom-out"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM7 9h5v1H7z"/></g>
+</defs></svg>
+</iron-iconset-svg>
diff --git a/polymer_1.0.4/bower_components/iron-icons/maps-icons.html b/polymer_1.0.4/bower_components/iron-icons/maps-icons.html
new file mode 100644
index 0000000..008a0ef
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/maps-icons.html
@@ -0,0 +1,71 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-iconset-svg/iron-iconset-svg.html">
+<iron-iconset-svg name="maps" size="24">
+<svg><defs>
+<g id="beenhere"><path d="M19 1H5c-1.1 0-1.99.9-1.99 2L3 15.93c0 .69.35 1.3.88 1.66L12 23l8.11-5.41c.53-.36.88-.97.88-1.66L21 3c0-1.1-.9-2-2-2zm-9 15l-5-5 1.41-1.41L10 13.17l7.59-7.59L19 7l-9 9z"/></g>
+<g id="directions"><path d="M21.71 11.29l-9-9c-.39-.39-1.02-.39-1.41 0l-9 9c-.39.39-.39 1.02 0 1.41l9 9c.39.39 1.02.39 1.41 0l9-9c.39-.38.39-1.01 0-1.41zM14 14.5V12h-4v3H8v-4c0-.55.45-1 1-1h5V7.5l3.5 3.5-3.5 3.5z"/></g>
+<g id="directions-bike"><path d="M15.5 5.5c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zM5 12c-2.8 0-5 2.2-5 5s2.2 5 5 5 5-2.2 5-5-2.2-5-5-5zm0 8.5c-1.9 0-3.5-1.6-3.5-3.5s1.6-3.5 3.5-3.5 3.5 1.6 3.5 3.5-1.6 3.5-3.5 3.5zm5.8-10l2.4-2.4.8.8c1.3 1.3 3 2.1 5.1 2.1V9c-1.5 0-2.7-.6-3.6-1.5l-1.9-1.9c-.5-.4-1-.6-1.6-.6s-1.1.2-1.4.6L7.8 8.4c-.4.4-.6.9-.6 1.4 0 .6.2 1.1.6 1.4L11 14v5h2v-6.2l-2.2-2.3zM19 12c-2.8 0-5 2.2-5 5s2.2 5 5 5 5-2.2 5-5-2.2-5-5-5zm0 8.5c-1.9 0-3.5-1.6-3.5-3.5s1.6-3.5 3.5-3.5 3.5 1.6 3.5 3.5-1.6 3.5-3.5 3.5z"/></g>
+<g id="directions-boat"><path d="M20 21c-1.39 0-2.78-.47-4-1.32-2.44 1.71-5.56 1.71-8 0C6.78 20.53 5.39 21 4 21H2v2h2c1.38 0 2.74-.35 4-.99 2.52 1.29 5.48 1.29 8 0 1.26.65 2.62.99 4 .99h2v-2h-2zM3.95 19H4c1.6 0 3.02-.88 4-2 .98 1.12 2.4 2 4 2s3.02-.88 4-2c.98 1.12 2.4 2 4 2h.05l1.89-6.68c.08-.26.06-.54-.06-.78s-.34-.42-.6-.5L20 10.62V6c0-1.1-.9-2-2-2h-3V1H9v3H6c-1.1 0-2 .9-2 2v4.62l-1.29.42c-.26.08-.48.26-.6.5s-.15.52-.06.78L3.95 19zM6 6h12v3.97L12 8 6 9.97V6z"/></g>
+<g id="directions-bus"><path d="M4 16c0 .88.39 1.67 1 2.22V20c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h8v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1.78c.61-.55 1-1.34 1-2.22V6c0-3.5-3.58-4-8-4s-8 .5-8 4v10zm3.5 1c-.83 0-1.5-.67-1.5-1.5S6.67 14 7.5 14s1.5.67 1.5 1.5S8.33 17 7.5 17zm9 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm1.5-6H6V6h12v5z"/></g>
+<g id="directions-car"><path d="M18.92 6.01C18.72 5.42 18.16 5 17.5 5h-11c-.66 0-1.21.42-1.42 1.01L3 12v8c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-8l-2.08-5.99zM6.5 16c-.83 0-1.5-.67-1.5-1.5S5.67 13 6.5 13s1.5.67 1.5 1.5S7.33 16 6.5 16zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 11l1.5-4.5h11L19 11H5z"/></g>
+<g id="directions-railway"><path d="M4 15.5C4 17.43 5.57 19 7.5 19L6 20.5v.5h12v-.5L16.5 19c1.93 0 3.5-1.57 3.5-3.5V5c0-3.5-3.58-4-8-4s-8 .5-8 4v10.5zm8 1.5c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm6-7H6V5h12v5z"/></g>
+<g id="directions-run"><path d="M13.49 5.48c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm-3.6 13.9l1-4.4 2.1 2v6h2v-7.5l-2.1-2 .6-3c1.3 1.5 3.3 2.5 5.5 2.5v-2c-1.9 0-3.5-1-4.3-2.4l-1-1.6c-.4-.6-1-1-1.7-1-.3 0-.5.1-.8.1l-5.2 2.2v4.7h2v-3.4l1.8-.7-1.6 8.1-4.9-1-.4 2 7 1.4z"/></g>
+<g id="directions-subway"><path d="M12 2c-4.42 0-8 .5-8 4v9.5C4 17.43 5.57 19 7.5 19L6 20.5v.5h12v-.5L16.5 19c1.93 0 3.5-1.57 3.5-3.5V6c0-3.5-3.58-4-8-4zM7.5 17c-.83 0-1.5-.67-1.5-1.5S6.67 14 7.5 14s1.5.67 1.5 1.5S8.33 17 7.5 17zm3.5-6H6V6h5v5zm5.5 6c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm1.5-6h-5V6h5v5z"/></g>
+<g id="directions-transit"><path d="M12 2c-4.42 0-8 .5-8 4v9.5C4 17.43 5.57 19 7.5 19L6 20.5v.5h12v-.5L16.5 19c1.93 0 3.5-1.57 3.5-3.5V6c0-3.5-3.58-4-8-4zM7.5 17c-.83 0-1.5-.67-1.5-1.5S6.67 14 7.5 14s1.5.67 1.5 1.5S8.33 17 7.5 17zm3.5-6H6V6h5v5zm5.5 6c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm1.5-6h-5V6h5v5z"/></g>
+<g id="directions-walk"><path d="M13.5 5.5c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zM9.8 8.9L7 23h2.1l1.8-8 2.1 2v6h2v-7.5l-2.1-2 .6-3C14.8 12 16.8 13 19 13v-2c-1.9 0-3.5-1-4.3-2.4l-1-1.6c-.4-.6-1-1-1.7-1-.3 0-.5.1-.8.1L6 8.3V13h2V9.6l1.8-.7"/></g>
+<g id="flight"><path d="M10.18 9"/><path d="M21 16v-2l-8-5V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5V9l-8 5v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-5.5l8 2.5z"/></g>
+<g id="hotel"><path d="M7 13c1.66 0 3-1.34 3-3S8.66 7 7 7s-3 1.34-3 3 1.34 3 3 3zm12-6h-8v7H3V5H1v15h2v-3h18v3h2v-9c0-2.21-1.79-4-4-4z"/></g>
+<g id="layers"><path d="M11.99 18.54l-7.37-5.73L3 14.07l9 7 9-7-1.63-1.27-7.38 5.74zM12 16l7.36-5.73L21 9l-9-7-9 7 1.63 1.27L12 16z"/></g>
+<g id="layers-clear"><path d="M19.81 14.99l1.19-.92-1.43-1.43-1.19.92 1.43 1.43zm-.45-4.72L21 9l-9-7-2.91 2.27 7.87 7.88 2.4-1.88zM3.27 1L2 2.27l4.22 4.22L3 9l1.63 1.27L12 16l2.1-1.63 1.43 1.43L12 18.54l-7.37-5.73L3 14.07l9 7 4.95-3.85L20.73 21 22 19.73 3.27 1z"/></g>
+<g id="local-activity"><path d="M20 12c0-1.1.9-2 2-2V6c0-1.1-.9-2-2-2H4c-1.1 0-1.99.9-1.99 2v4c1.1 0 1.99.9 1.99 2s-.89 2-2 2v4c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2v-4c-1.1 0-2-.9-2-2zm-4.42 4.8L12 14.5l-3.58 2.3 1.08-4.12-3.29-2.69 4.24-.25L12 5.8l1.54 3.95 4.24.25-3.29 2.69 1.09 4.11z"/></g>
+<g id="local-airport"><path d="M21 16v-2l-8-5V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5V9l-8 5v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-5.5l8 2.5z"/></g>
+<g id="local-atm"><path d="M11 17h2v-1h1c.55 0 1-.45 1-1v-3c0-.55-.45-1-1-1h-3v-1h4V8h-2V7h-2v1h-1c-.55 0-1 .45-1 1v3c0 .55.45 1 1 1h3v1H9v2h2v1zm9-13H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4V6h16v12z"/></g>
+<g id="local-bar"><path d="M11 13v6H6v2h12v-2h-5v-6l8-8V3H3v2l8 8zM7.5 7l-2-2h13l-2 2h-9z"/></g>
+<g id="local-cafe"><path d="M20 3H4v10c0 2.21 1.79 4 4 4h6c2.21 0 4-1.79 4-4v-3h2c1.11 0 2-.89 2-2V5c0-1.11-.89-2-2-2zm0 5h-2V5h2v3zM2 21h18v-2H2v2z"/></g>
+<g id="local-car-wash"><path d="M17 5c.83 0 1.5-.67 1.5-1.5 0-1-1.5-2.7-1.5-2.7s-1.5 1.7-1.5 2.7c0 .83.67 1.5 1.5 1.5zm-5 0c.83 0 1.5-.67 1.5-1.5 0-1-1.5-2.7-1.5-2.7s-1.5 1.7-1.5 2.7c0 .83.67 1.5 1.5 1.5zM7 5c.83 0 1.5-.67 1.5-1.5C8.5 2.5 7 .8 7 .8S5.5 2.5 5.5 3.5C5.5 4.33 6.17 5 7 5zm11.92 3.01C18.72 7.42 18.16 7 17.5 7h-11c-.66 0-1.21.42-1.42 1.01L3 14v8c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-8l-2.08-5.99zM6.5 18c-.83 0-1.5-.67-1.5-1.5S5.67 15 6.5 15s1.5.67 1.5 1.5S7.33 18 6.5 18zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 13l1.5-4.5h11L19 13H5z"/></g>
+<g id="local-convenience-store"><path d="M19 7V4H5v3H2v13h8v-4h4v4h8V7h-3zm-8 3H9v1h2v1H8V9h2V8H8V7h3v3zm5 2h-1v-2h-2V7h1v2h1V7h1v5z"/></g>
+<g id="local-dining"><path d="M8.1 13.34l2.83-2.83L3.91 3.5c-1.56 1.56-1.56 4.09 0 5.66l4.19 4.18zm6.78-1.81c1.53.71 3.68.21 5.27-1.38 1.91-1.91 2.28-4.65.81-6.12-1.46-1.46-4.2-1.1-6.12.81-1.59 1.59-2.09 3.74-1.38 5.27L3.7 19.87l1.41 1.41L12 14.41l6.88 6.88 1.41-1.41L13.41 13l1.47-1.47z"/></g>
+<g id="local-drink"><path d="M3 2l2.01 18.23C5.13 21.23 5.97 22 7 22h10c1.03 0 1.87-.77 1.99-1.77L21 2H3zm9 17c-1.66 0-3-1.34-3-3 0-2 3-5.4 3-5.4s3 3.4 3 5.4c0 1.66-1.34 3-3 3zm6.33-11H5.67l-.44-4h13.53l-.43 4z"/></g>
+<g id="local-florist"><path d="M12 22c4.97 0 9-4.03 9-9-4.97 0-9 4.03-9 9zM5.6 10.25c0 1.38 1.12 2.5 2.5 2.5.53 0 1.01-.16 1.42-.44l-.02.19c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5l-.02-.19c.4.28.89.44 1.42.44 1.38 0 2.5-1.12 2.5-2.5 0-1-.59-1.85-1.43-2.25.84-.4 1.43-1.25 1.43-2.25 0-1.38-1.12-2.5-2.5-2.5-.53 0-1.01.16-1.42.44l.02-.19C14.5 2.12 13.38 1 12 1S9.5 2.12 9.5 3.5l.02.19c-.4-.28-.89-.44-1.42-.44-1.38 0-2.5 1.12-2.5 2.5 0 1 .59 1.85 1.43 2.25-.84.4-1.43 1.25-1.43 2.25zM12 5.5c1.38 0 2.5 1.12 2.5 2.5s-1.12 2.5-2.5 2.5S9.5 9.38 9.5 8s1.12-2.5 2.5-2.5zM3 13c0 4.97 4.03 9 9 9 0-4.97-4.03-9-9-9z"/></g>
+<g id="local-gas-station"><path d="M19.77 7.23l.01-.01-3.72-3.72L15 4.56l2.11 2.11c-.94.36-1.61 1.26-1.61 2.33 0 1.38 1.12 2.5 2.5 2.5.36 0 .69-.08 1-.21v7.21c0 .55-.45 1-1 1s-1-.45-1-1V14c0-1.1-.9-2-2-2h-1V5c0-1.1-.9-2-2-2H6c-1.1 0-2 .9-2 2v16h10v-7.5h1.5v5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V9c0-.69-.28-1.32-.73-1.77zM12 10H6V5h6v5zm6 0c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"/></g>
+<g id="local-grocery-store"><path d="M7 18c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zM1 2v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.14 0-.25-.11-.25-.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.58-6.49c.08-.14.12-.31.12-.48 0-.55-.45-1-1-1H5.21l-.94-2H1zm16 16c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2z"/></g>
+<g id="local-hospital"><path d="M19 3H5c-1.1 0-1.99.9-1.99 2L3 19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 11h-4v4h-4v-4H6v-4h4V6h4v4h4v4z"/></g>
+<g id="local-hotel"><path d="M7 13c1.66 0 3-1.34 3-3S8.66 7 7 7s-3 1.34-3 3 1.34 3 3 3zm12-6h-8v7H3V5H1v15h2v-3h18v3h2v-9c0-2.21-1.79-4-4-4z"/></g>
+<g id="local-laundry-service"><path d="M9.17 16.83c1.56 1.56 4.1 1.56 5.66 0 1.56-1.56 1.56-4.1 0-5.66l-5.66 5.66zM18 2.01L6 2c-1.11 0-2 .89-2 2v16c0 1.11.89 2 2 2h12c1.11 0 2-.89 2-2V4c0-1.11-.89-1.99-2-1.99zM10 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM7 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm5 16c-3.31 0-6-2.69-6-6s2.69-6 6-6 6 2.69 6 6-2.69 6-6 6z"/></g>
+<g id="local-library"><path d="M12 11.55C9.64 9.35 6.48 8 3 8v11c3.48 0 6.64 1.35 9 3.55 2.36-2.19 5.52-3.55 9-3.55V8c-3.48 0-6.64 1.35-9 3.55zM12 8c1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3 1.34 3 3 3z"/></g>
+<g id="local-mall"><path d="M19 6h-2c0-2.76-2.24-5-5-5S7 3.24 7 6H5c-1.1 0-1.99.9-1.99 2L3 20c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-7-3c1.66 0 3 1.34 3 3H9c0-1.66 1.34-3 3-3zm0 10c-2.76 0-5-2.24-5-5h2c0 1.66 1.34 3 3 3s3-1.34 3-3h2c0 2.76-2.24 5-5 5z"/></g>
+<g id="local-movies"><path d="M18 3v2h-2V3H8v2H6V3H4v18h2v-2h2v2h8v-2h2v2h2V3h-2zM8 17H6v-2h2v2zm0-4H6v-2h2v2zm0-4H6V7h2v2zm10 8h-2v-2h2v2zm0-4h-2v-2h2v2zm0-4h-2V7h2v2z"/></g>
+<g id="local-offer"><path d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/></g>
+<g id="local-parking"><path d="M13 3H6v18h4v-6h3c3.31 0 6-2.69 6-6s-2.69-6-6-6zm.2 8H10V7h3.2c1.1 0 2 .9 2 2s-.9 2-2 2z"/></g>
+<g id="local-pharmacy"><path d="M21 5h-2.64l1.14-3.14L17.15 1l-1.46 4H3v2l2 6-2 6v2h18v-2l-2-6 2-6V5zm-5 9h-3v3h-2v-3H8v-2h3V9h2v3h3v2z"/></g>
+<g id="local-phone"><path d="M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z"/></g>
+<g id="local-pizza"><path d="M12 2C8.43 2 5.23 3.54 3.01 6L12 22l8.99-16C18.78 3.55 15.57 2 12 2zM7 7c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2zm5 8c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></g>
+<g id="local-play"><path d="M20 12c0-1.1.9-2 2-2V6c0-1.1-.9-2-2-2H4c-1.1 0-1.99.9-1.99 2v4c1.1 0 1.99.9 1.99 2s-.89 2-2 2v4c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2v-4c-1.1 0-2-.9-2-2zm-4.42 4.8L12 14.5l-3.58 2.3 1.08-4.12-3.29-2.69 4.24-.25L12 5.8l1.54 3.95 4.24.25-3.29 2.69 1.09 4.11z"/></g>
+<g id="local-post-office"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></g>
+<g id="local-printshop"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/></g>
+<g id="local-see"><circle cx="12" cy="12" r="3.2"/><path d="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z"/></g>
+<g id="local-shipping"><path d="M20 8h-3V4H3c-1.1 0-2 .9-2 2v11h2c0 1.66 1.34 3 3 3s3-1.34 3-3h6c0 1.66 1.34 3 3 3s3-1.34 3-3h2v-5l-3-4zM6 18.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm13.5-9l1.96 2.5H17V9.5h2.5zm-1.5 9c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></g>
+<g id="local-taxi"><path d="M18.92 6.01C18.72 5.42 18.16 5 17.5 5H15V3H9v2H6.5c-.66 0-1.21.42-1.42 1.01L3 12v8c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-8l-2.08-5.99zM6.5 16c-.83 0-1.5-.67-1.5-1.5S5.67 13 6.5 13s1.5.67 1.5 1.5S7.33 16 6.5 16zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 11l1.5-4.5h11L19 11H5z"/></g>
+<g id="map"><path d="M20.5 3l-.16.03L15 5.1 9 3 3.36 4.9c-.21.07-.36.25-.36.48V20.5c0 .28.22.5.5.5l.16-.03L9 18.9l6 2.1 5.64-1.9c.21-.07.36-.25.36-.48V3.5c0-.28-.22-.5-.5-.5zM15 19l-6-2.11V5l6 2.11V19z"/></g>
+<g id="my-location"><path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm8.94 3c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></g>
+<g id="navigation"><path d="M12 2L4.5 20.29l.71.71L12 18l6.79 3 .71-.71z"/></g>
+<g id="person-pin"><path d="M19 2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h4l3 3 3-3h4c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 3.3c1.49 0 2.7 1.21 2.7 2.7 0 1.49-1.21 2.7-2.7 2.7-1.49 0-2.7-1.21-2.7-2.7 0-1.49 1.21-2.7 2.7-2.7zM18 16H6v-.9c0-2 4-3.1 6-3.1s6 1.1 6 3.1v.9z"/></g>
+<g id="pin-drop"><path d="M18 8c0-3.31-2.69-6-6-6S6 4.69 6 8c0 4.5 6 11 6 11s6-6.5 6-11zm-8 0c0-1.1.9-2 2-2s2 .9 2 2-.89 2-2 2c-1.1 0-2-.9-2-2zM5 20v2h14v-2H5z"/></g>
+<g id="place"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/></g>
+<g id="rate-review"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 14v-2.47l6.88-6.88c.2-.2.51-.2.71 0l1.77 1.77c.2.2.2.51 0 .71L8.47 14H6zm12 0h-7.5l2-2H18v2z"/></g>
+<g id="restaurant-menu"><path d="M8.1 13.34l2.83-2.83L3.91 3.5c-1.56 1.56-1.56 4.09 0 5.66l4.19 4.18zm6.78-1.81c1.53.71 3.68.21 5.27-1.38 1.91-1.91 2.28-4.65.81-6.12-1.46-1.46-4.2-1.1-6.12.81-1.59 1.59-2.09 3.74-1.38 5.27L3.7 19.87l1.41 1.41L12 14.41l6.88 6.88 1.41-1.41L13.41 13l1.47-1.47z"/></g>
+<g id="satellite"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM5 4.99h3C8 6.65 6.66 8 5 8V4.99zM5 12v-2c2.76 0 5-2.25 5-5.01h2C12 8.86 8.87 12 5 12zm0 6l3.5-4.5 2.5 3.01L14.5 12l4.5 6H5z"/></g>
+<g id="store-mall-directory"><path d="M20 4H4v2h16V4zm1 10v-2l-1-5H4l-1 5v2h1v6h10v-6h4v6h2v-6h1zm-9 4H6v-4h6v4z"/></g>
+<g id="terrain"><path d="M14 6l-3.75 5 2.85 3.8-1.6 1.2C9.81 13.75 7 10 7 10l-6 8h22L14 6z"/></g>
+<g id="traffic"><path d="M20 10h-3V8.86c1.72-.45 3-2 3-3.86h-3V4c0-.55-.45-1-1-1H8c-.55 0-1 .45-1 1v1H4c0 1.86 1.28 3.41 3 3.86V10H4c0 1.86 1.28 3.41 3 3.86V15H4c0 1.86 1.28 3.41 3 3.86V20c0 .55.45 1 1 1h8c.55 0 1-.45 1-1v-1.14c1.72-.45 3-2 3-3.86h-3v-1.14c1.72-.45 3-2 3-3.86zm-8 9c-1.11 0-2-.9-2-2s.89-2 2-2c1.1 0 2 .9 2 2s-.89 2-2 2zm0-5c-1.11 0-2-.9-2-2s.89-2 2-2c1.1 0 2 .9 2 2s-.89 2-2 2zm0-5c-1.11 0-2-.9-2-2 0-1.11.89-2 2-2 1.1 0 2 .89 2 2 0 1.1-.89 2-2 2z"/></g>
+</defs></svg>
+</iron-iconset-svg>
diff --git a/polymer_1.0.4/bower_components/iron-icons/notification-icons.html b/polymer_1.0.4/bower_components/iron-icons/notification-icons.html
new file mode 100644
index 0000000..39db434
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/notification-icons.html
@@ -0,0 +1,62 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-iconset-svg/iron-iconset-svg.html">
+<iron-iconset-svg name="notification" size="24">
+<svg><defs>
+<g id="adb"><path d="M5 16c0 3.87 3.13 7 7 7s7-3.13 7-7v-4H5v4zM16.12 4.37l2.1-2.1-.82-.83-2.3 2.31C14.16 3.28 13.12 3 12 3s-2.16.28-3.09.75L6.6 1.44l-.82.83 2.1 2.1C6.14 5.64 5 7.68 5 10v1h14v-1c0-2.32-1.14-4.36-2.88-5.63zM9 9c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm6 0c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z"/></g>
+<g id="airline-seat-flat"><path d="M22 11v2H9V7h9c2.21 0 4 1.79 4 4zM2 14v2h6v2h8v-2h6v-2H2zm5.14-1.9c1.16-1.19 1.14-3.08-.04-4.24-1.19-1.16-3.08-1.14-4.24.04-1.16 1.19-1.14 3.08.04 4.24 1.19 1.16 3.08 1.14 4.24-.04z"/></g>
+<g id="airline-seat-flat-angled"><path d="M22.25 14.29l-.69 1.89L9.2 11.71l2.08-5.66 8.56 3.09c2.1.76 3.18 3.06 2.41 5.15zM1.5 12.14L8 14.48V19h8v-1.63L20.52 19l.69-1.89-19.02-6.86-.69 1.89zm5.8-1.94c1.49-.72 2.12-2.51 1.41-4C7.99 4.71 6.2 4.08 4.7 4.8c-1.49.71-2.12 2.5-1.4 4 .71 1.49 2.5 2.12 4 1.4z"/></g>
+<g id="airline-seat-individual-suite"><path d="M7 13c1.65 0 3-1.35 3-3S8.65 7 7 7s-3 1.35-3 3 1.35 3 3 3zm12-6h-8v7H3V7H1v10h22v-6c0-2.21-1.79-4-4-4z"/></g>
+<g id="airline-seat-legroom-extra"><path d="M4 12V3H2v9c0 2.76 2.24 5 5 5h6v-2H7c-1.66 0-3-1.34-3-3zm18.83 5.24c-.38-.72-1.29-.97-2.03-.63l-1.09.5-3.41-6.98c-.34-.68-1.03-1.12-1.79-1.12L11 9V3H5v8c0 1.66 1.34 3 3 3h7l3.41 7 3.72-1.7c.77-.36 1.1-1.3.7-2.06z"/></g>
+<g id="airline-seat-legroom-normal"><path d="M5 12V3H3v9c0 2.76 2.24 5 5 5h6v-2H8c-1.66 0-3-1.34-3-3zm15.5 6H19v-7c0-1.1-.9-2-2-2h-5V3H6v8c0 1.65 1.35 3 3 3h7v7h4.5c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5z"/></g>
+<g id="airline-seat-legroom-reduced"><path d="M19.97 19.2c.18.96-.55 1.8-1.47 1.8H14v-3l1-4H9c-1.65 0-3-1.35-3-3V3h6v6h5c1.1 0 2 .9 2 2l-2 7h1.44c.73 0 1.39.49 1.53 1.2zM5 12V3H3v9c0 2.76 2.24 5 5 5h4v-2H8c-1.66 0-3-1.34-3-3z"/></g>
+<g id="airline-seat-recline-extra"><path d="M5.35 5.64c-.9-.64-1.12-1.88-.49-2.79.63-.9 1.88-1.12 2.79-.49.9.64 1.12 1.88.49 2.79-.64.9-1.88 1.12-2.79.49zM16 19H8.93c-1.48 0-2.74-1.08-2.96-2.54L4 7H2l1.99 9.76C4.37 19.2 6.47 21 8.94 21H16v-2zm.23-4h-4.88l-1.03-4.1c1.58.89 3.28 1.54 5.15 1.22V9.99c-1.63.31-3.44-.27-4.69-1.25L9.14 7.47c-.23-.18-.49-.3-.76-.38-.32-.09-.66-.12-.99-.06h-.02c-1.23.22-2.05 1.39-1.84 2.61l1.35 5.92C7.16 16.98 8.39 18 9.83 18h6.85l3.82 3 1.5-1.5-5.77-4.5z"/></g>
+<g id="airline-seat-recline-normal"><path d="M7.59 5.41c-.78-.78-.78-2.05 0-2.83.78-.78 2.05-.78 2.83 0 .78.78.78 2.05 0 2.83-.79.79-2.05.79-2.83 0zM6 16V7H4v9c0 2.76 2.24 5 5 5h6v-2H9c-1.66 0-3-1.34-3-3zm14 4.07L14.93 15H11.5v-3.68c1.4 1.15 3.6 2.16 5.5 2.16v-2.16c-1.66.02-3.61-.87-4.67-2.04l-1.4-1.55c-.19-.21-.43-.38-.69-.5-.29-.14-.62-.23-.96-.23h-.03C8.01 7 7 8.01 7 9.25V15c0 1.66 1.34 3 3 3h5.07l3.5 3.5L20 20.07z"/></g>
+<g id="bluetooth-audio"><path d="M14.24 12.01l2.32 2.32c.28-.72.44-1.51.44-2.33 0-.82-.16-1.59-.43-2.31l-2.33 2.32zm5.29-5.3l-1.26 1.26c.63 1.21.98 2.57.98 4.02s-.36 2.82-.98 4.02l1.2 1.2c.97-1.54 1.54-3.36 1.54-5.31-.01-1.89-.55-3.67-1.48-5.19zm-3.82 1L10 2H9v7.59L4.41 5 3 6.41 8.59 12 3 17.59 4.41 19 9 14.41V22h1l5.71-5.71-4.3-4.29 4.3-4.29zM11 5.83l1.88 1.88L11 9.59V5.83zm1.88 10.46L11 18.17v-3.76l1.88 1.88z"/></g>
+<g id="confirmation-number"><defs><path id="a" d="M0 0h24v24H0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path d="M22 10V6c0-1.11-.9-2-2-2H4c-1.1 0-1.99.89-1.99 2v4c1.1 0 1.99.9 1.99 2s-.89 2-2 2v4c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2v-4c-1.1 0-2-.9-2-2s.9-2 2-2zm-9 7.5h-2v-2h2v2zm0-4.5h-2v-2h2v2zm0-4.5h-2v-2h2v2z" clip-path="url(#b)"/></g>
+<g id="disc-full"><path d="M20 16h2v-2h-2v2zm0-9v5h2V7h-2zM10 4c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm0 10c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></g>
+<g id="do-not-disturb"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8 0-1.85.63-3.55 1.69-4.9L16.9 18.31C15.55 19.37 13.85 20 12 20zm6.31-3.1L7.1 5.69C8.45 4.63 10.15 4 12 4c4.42 0 8 3.58 8 8 0 1.85-.63 3.55-1.69 4.9z"/></g>
+<g id="do-not-disturb-alt"><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zM4 12c0-4.4 3.6-8 8-8 1.8 0 3.5.6 4.9 1.7L5.7 16.9C4.6 15.5 4 13.8 4 12zm8 8c-1.8 0-3.5-.6-4.9-1.7L18.3 7.1C19.4 8.5 20 10.2 20 12c0 4.4-3.6 8-8 8z"/></g>
+<g id="drive-eta"><path d="M18.92 5.01C18.72 4.42 18.16 4 17.5 4h-11c-.66 0-1.21.42-1.42 1.01L3 11v8c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-8l-2.08-5.99zM6.5 15c-.83 0-1.5-.67-1.5-1.5S5.67 12 6.5 12s1.5.67 1.5 1.5S7.33 15 6.5 15zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 10l1.5-4.5h11L19 10H5z"/></g>
+<g id="event-available"><path d="M16.53 11.06L15.47 10l-4.88 4.88-2.12-2.12-1.06 1.06L10.59 17l5.94-5.94zM19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11z"/></g>
+<g id="event-busy"><path d="M9.31 17l2.44-2.44L14.19 17l1.06-1.06-2.44-2.44 2.44-2.44L14.19 10l-2.44 2.44L9.31 10l-1.06 1.06 2.44 2.44-2.44 2.44L9.31 17zM19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11z"/></g>
+<g id="event-note"><path d="M17 10H7v2h10v-2zm2-7h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zm-5-5H7v2h7v-2z"/></g>
+<g id="folder-special"><path d="M20 6h-8l-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-6.42 12L10 15.9 6.42 18l.95-4.07-3.16-2.74 4.16-.36L10 7l1.63 3.84 4.16.36-3.16 2.74.95 4.06z"/></g>
+<g id="live-tv"><path d="M21 6h-7.59l3.29-3.29L16 2l-4 4-4-4-.71.71L10.59 6H3c-1.1 0-2 .89-2 2v12c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V8c0-1.11-.9-2-2-2zm0 14H3V8h18v12zM9 10v8l7-4z"/></g>
+<g id="mms"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM5 14l3.5-4.5 2.5 3.01L14.5 8l4.5 6H5z"/></g>
+<g id="more"><path d="M22 3H7c-.69 0-1.23.35-1.59.88L0 12l5.41 8.11c.36.53.97.89 1.66.89H22c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 13.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm5 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm5 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></g>
+<g id="network-locked"><path d="M19.5 10c.17 0 .33.03.5.05V1L1 20h13v-3c0-.89.39-1.68 1-2.23v-.27c0-2.48 2.02-4.5 4.5-4.5zm2.5 6v-1.5c0-1.38-1.12-2.5-2.5-2.5S17 13.12 17 14.5V16c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h5c.55 0 1-.45 1-1v-4c0-.55-.45-1-1-1zm-1 0h-3v-1.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V16z"/></g>
+<g id="ondemand-video"><path d="M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-6l-7 4V7z"/></g>
+<g id="personal-video"><path d="M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12z"/></g>
+<g id="phone-bluetooth-speaker"><path d="M14.71 9.5L17 7.21V11h.5l2.85-2.85L18.21 6l2.15-2.15L17.5 1H17v3.79L14.71 2.5l-.71.71L16.79 6 14 8.79l.71.71zM18 2.91l.94.94-.94.94V2.91zm0 4.3l.94.94-.94.94V7.21zm2 8.29c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.59l2.2-2.21c.28-.26.36-.65.25-1C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1z"/></g>
+<g id="phone-forwarded"><path d="M18 11l5-5-5-5v3h-4v4h4v3zm2 4.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.59l2.2-2.21c.28-.26.36-.65.25-1C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1z"/></g>
+<g id="phone-in-talk"><path d="M20 15.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.59l2.2-2.21c.28-.26.36-.65.25-1C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM19 12h2c0-4.97-4.03-9-9-9v2c3.87 0 7 3.13 7 7zm-4 0h2c0-2.76-2.24-5-5-5v2c1.66 0 3 1.34 3 3z"/></g>
+<g id="phone-locked"><path d="M20 15.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.59l2.2-2.21c.28-.26.36-.65.25-1C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM20 4v-.5C20 2.12 18.88 1 17.5 1S15 2.12 15 3.5V4c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h5c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zm-.8 0h-3.4v-.5c0-.94.76-1.7 1.7-1.7s1.7.76 1.7 1.7V4z"/></g>
+<g id="phone-missed"><path d="M6.5 5.5L12 11l7-7-1-1-6 6-4.5-4.5H11V3H5v6h1.5V5.5zm17.21 11.17C20.66 13.78 16.54 12 12 12 7.46 12 3.34 13.78.29 16.67c-.18.18-.29.43-.29.71s.11.53.29.71l2.48 2.48c.18.18.43.29.71.29.27 0 .52-.11.7-.28.79-.74 1.69-1.36 2.66-1.85.33-.16.56-.5.56-.9v-3.1c1.45-.48 3-.73 4.6-.73 1.6 0 3.15.25 4.6.72v3.1c0 .39.23.74.56.9.98.49 1.87 1.12 2.67 1.85.18.18.43.28.7.28.28 0 .53-.11.71-.29l2.48-2.48c.18-.18.29-.43.29-.71s-.12-.52-.3-.7z"/></g>
+<g id="phone-paused"><path d="M17 3h-2v7h2V3zm3 12.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.59l2.2-2.21c.28-.26.36-.65.25-1C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM19 3v7h2V3h-2z"/></g>
+<g id="power"><path d="M16.01 7L16 3h-2v4h-4V3H8v4h-.01C7 6.99 6 7.99 6 8.99v5.49L9.5 18v3h5v-3l3.5-3.51v-5.5c0-1-1-2-1.99-1.99z"/></g>
+<g id="sd-card"><path d="M18 2h-8L4.02 8 4 20c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-6 6h-2V4h2v4zm3 0h-2V4h2v4zm3 0h-2V4h2v4z"/></g>
+<g id="sim-card-alert"><path d="M18 2h-8L4.02 8 4 20c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-5 15h-2v-2h2v2zm0-4h-2V8h2v5z"/></g>
+<g id="sms"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM9 11H7V9h2v2zm4 0h-2V9h2v2zm4 0h-2V9h2v2z"/></g>
+<g id="sms-failed"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 12h-2v-2h2v2zm0-4h-2V6h2v4z"/></g>
+<g id="sync"><path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/></g>
+<g id="sync-disabled"><path d="M10 6.35V4.26c-.8.21-1.55.54-2.23.96l1.46 1.46c.25-.12.5-.24.77-.33zm-7.14-.94l2.36 2.36C4.45 8.99 4 10.44 4 12c0 2.21.91 4.2 2.36 5.64L4 20h6v-6l-2.24 2.24C6.68 15.15 6 13.66 6 12c0-1 .25-1.94.68-2.77l8.08 8.08c-.25.13-.5.25-.77.34v2.09c.8-.21 1.55-.54 2.23-.96l2.36 2.36 1.27-1.27L4.14 4.14 2.86 5.41zM20 4h-6v6l2.24-2.24C17.32 8.85 18 10.34 18 12c0 1-.25 1.94-.68 2.77l1.46 1.46C19.55 15.01 20 13.56 20 12c0-2.21-.91-4.2-2.36-5.64L20 4z"/></g>
+<g id="sync-problem"><path d="M3 12c0 2.21.91 4.2 2.36 5.64L3 20h6v-6l-2.24 2.24C5.68 15.15 5 13.66 5 12c0-2.61 1.67-4.83 4-5.65V4.26C5.55 5.15 3 8.27 3 12zm8 5h2v-2h-2v2zM21 4h-6v6l2.24-2.24C18.32 8.85 19 10.34 19 12c0 2.61-1.67 4.83-4 5.65v2.09c3.45-.89 6-4.01 6-7.74 0-2.21-.91-4.2-2.36-5.64L21 4zm-10 9h2V7h-2v6z"/></g>
+<g id="system-update"><path d="M17 1.01L7 1c-1.1 0-2 .9-2 2v18c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14zm-1-6h-3V8h-2v5H8l4 4 4-4z"/></g>
+<g id="tap-and-play"><path d="M2 16v2c2.76 0 5 2.24 5 5h2c0-3.87-3.13-7-7-7zm0 4v3h3c0-1.66-1.34-3-3-3zm0-8v2c4.97 0 9 4.03 9 9h2c0-6.08-4.92-11-11-11zM17 1.01L7 1c-1.1 0-2 .9-2 2v7.37c.69.16 1.36.37 2 .64V5h10v13h-3.03c.52 1.25.84 2.59.95 4H17c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99z"/></g>
+<g id="time-to-leave"><path d="M18.92 5.01C18.72 4.42 18.16 4 17.5 4h-11c-.66 0-1.21.42-1.42 1.01L3 11v8c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-8l-2.08-5.99zM6.5 15c-.83 0-1.5-.67-1.5-1.5S5.67 12 6.5 12s1.5.67 1.5 1.5S7.33 15 6.5 15zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 10l1.5-4.5h11L19 10H5z"/></g>
+<g id="vibration"><path d="M0 15h2V9H0v6zm3 2h2V7H3v10zm19-8v6h2V9h-2zm-3 8h2V7h-2v10zM16.5 3h-9C6.67 3 6 3.67 6 4.5v15c0 .83.67 1.5 1.5 1.5h9c.83 0 1.5-.67 1.5-1.5v-15c0-.83-.67-1.5-1.5-1.5zM16 19H8V5h8v14z"/></g>
+<g id="voice-chat"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12l-4-3.2V14H6V6h8v3.2L18 6v8z"/></g>
+<g id="vpn-lock"><path d="M22 4v-.5C22 2.12 20.88 1 19.5 1S17 2.12 17 3.5V4c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h5c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zm-.8 0h-3.4v-.5c0-.94.76-1.7 1.7-1.7s1.7.76 1.7 1.7V4zm-2.28 8c.04.33.08.66.08 1 0 2.08-.8 3.97-2.1 5.39-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H7v-2h2c.55 0 1-.45 1-1V8h2c1.1 0 2-.9 2-2V3.46c-.95-.3-1.95-.46-3-.46C5.48 3 1 7.48 1 13s4.48 10 10 10 10-4.48 10-10c0-.34-.02-.67-.05-1h-2.03zM10 20.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L8 16v1c0 1.1.9 2 2 2v1.93z"/></g>
+<g id="wc"><path d="M5.5 22v-7.5H4V9c0-1.1.9-2 2-2h3c1.1 0 2 .9 2 2v5.5H9.5V22h-4zM18 22v-6h3l-2.54-7.63C18.18 7.55 17.42 7 16.56 7h-.12c-.86 0-1.63.55-1.9 1.37L12 16h3v6h3zM7.5 6c1.11 0 2-.89 2-2s-.89-2-2-2-2 .89-2 2 .89 2 2 2zm9 0c1.11 0 2-.89 2-2s-.89-2-2-2-2 .89-2 2 .89 2 2 2z"/></g>
+<g id="wifi"><path d="M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.08 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z"/></g>
+</defs></svg>
+</iron-iconset-svg>
diff --git a/polymer_1.0.4/bower_components/iron-icons/social-icons.html b/polymer_1.0.4/bower_components/iron-icons/social-icons.html
new file mode 100644
index 0000000..5553caa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-icons/social-icons.html
@@ -0,0 +1,40 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-iconset-svg/iron-iconset-svg.html">
+<iron-iconset-svg name="social" size="24">
+<svg><defs>
+<g id="cake"><path d="M12 6c1.11 0 2-.9 2-2 0-.38-.1-.73-.29-1.03L12 0l-1.71 2.97c-.19.3-.29.65-.29 1.03 0 1.1.9 2 2 2zm4.6 9.99l-1.07-1.07-1.08 1.07c-1.3 1.3-3.58 1.31-4.89 0l-1.07-1.07-1.09 1.07C6.75 16.64 5.88 17 4.96 17c-.73 0-1.4-.23-1.96-.61V21c0 .55.45 1 1 1h16c.55 0 1-.45 1-1v-4.61c-.56.38-1.23.61-1.96.61-.92 0-1.79-.36-2.44-1.01zM18 9h-5V7h-2v2H6c-1.66 0-3 1.34-3 3v1.54c0 1.08.88 1.96 1.96 1.96.52 0 1.02-.2 1.38-.57l2.14-2.13 2.13 2.13c.74.74 2.03.74 2.77 0l2.14-2.13 2.13 2.13c.37.37.86.57 1.38.57 1.08 0 1.96-.88 1.96-1.96V12C21 10.34 19.66 9 18 9z"/></g>
+<g id="domain"><path d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"/></g>
+<g id="group"><path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"/></g>
+<g id="group-add"><path d="M8 10H5V7H3v3H0v2h3v3h2v-3h3v-2zm10 1c1.66 0 2.99-1.34 2.99-3S19.66 5 18 5c-.32 0-.63.05-.91.14.57.81.9 1.79.9 2.86s-.34 2.04-.9 2.86c.28.09.59.14.91.14zm-5 0c1.66 0 2.99-1.34 2.99-3S14.66 5 13 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm6.62 2.16c.83.73 1.38 1.66 1.38 2.84v2h3v-2c0-1.54-2.37-2.49-4.38-2.84zM13 13c-2 0-6 1-6 3v2h12v-2c0-2-4-3-6-3z"/></g>
+<g id="location-city"><path d="M15 11V5l-3-3-3 3v2H3v14h18V11h-6zm-8 8H5v-2h2v2zm0-4H5v-2h2v2zm0-4H5V9h2v2zm6 8h-2v-2h2v2zm0-4h-2v-2h2v2zm0-4h-2V9h2v2zm0-4h-2V5h2v2zm6 12h-2v-2h2v2zm0-4h-2v-2h2v2z"/></g>
+<g id="mood"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"/></g>
+<g id="mood-bad"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 3c-2.33 0-4.31 1.46-5.11 3.5h10.22c-.8-2.04-2.78-3.5-5.11-3.5z"/></g>
+<g id="notifications"><path d="M11.5 22c1.1 0 2-.9 2-2h-4c0 1.1.9 2 2 2zm6.5-6v-5.5c0-3.07-2.13-5.64-5-6.32V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5v.68c-2.87.68-5 3.25-5 6.32V16l-2 2v1h17v-1l-2-2z"/></g>
+<g id="notifications-active"><path d="M6.58 3.58L5.15 2.15C2.76 3.97 1.18 6.8 1.03 10h2c.15-2.65 1.51-4.97 3.55-6.42zM19.97 10h2c-.15-3.2-1.73-6.03-4.13-7.85l-1.43 1.43c2.05 1.45 3.41 3.77 3.56 6.42zm-1.97.5c0-3.07-2.13-5.64-5-6.32V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5v.68c-2.87.68-5 3.25-5 6.32V16l-2 2v1h17v-1l-2-2v-5.5zM11.5 22c.14 0 .27-.01.4-.04.65-.13 1.19-.58 1.44-1.18.1-.24.16-.5.16-.78h-4c0 1.1.9 2 2 2z"/></g>
+<g id="notifications-none"><path d="M11.5 22c1.1 0 2-.9 2-2h-4c0 1.1.9 2 2 2zm6.5-6v-5.5c0-3.07-2.13-5.64-5-6.32V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5v.68c-2.87.68-5 3.25-5 6.32V16l-2 2v1h17v-1l-2-2zm-2 1H7v-6.5C7 8.01 9.01 6 11.5 6S16 8.01 16 10.5V17z"/></g>
+<g id="notifications-off"><path d="M11.5 22c1.1 0 2-.9 2-2h-4c0 1.1.9 2 2 2zM18 10.5c0-3.07-2.13-5.64-5-6.32V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5v.68c-.51.12-.99.32-1.45.56L18 14.18V10.5zm-.27 8.5l2 2L21 19.73 4.27 3 3 4.27l2.92 2.92C5.34 8.16 5 9.29 5 10.5V16l-2 2v1h14.73z"/></g>
+<g id="notifications-paused"><path d="M11.5 22c1.1 0 2-.9 2-2h-4c0 1.1.9 2 2 2zm6.5-6v-5.5c0-3.07-2.13-5.64-5-6.32V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5v.68c-2.87.68-5 3.25-5 6.32V16l-2 2v1h17v-1l-2-2zm-4-6.2l-2.8 3.4H14V15H9v-1.8l2.8-3.4H9V8h5v1.8z"/></g>
+<g id="pages"><path d="M3 5v6h5L7 7l4 1V3H5c-1.1 0-2 .9-2 2zm5 8H3v6c0 1.1.9 2 2 2h6v-5l-4 1 1-4zm9 4l-4-1v5h6c1.1 0 2-.9 2-2v-6h-5l1 4zm2-14h-6v5l4-1-1 4h5V5c0-1.1-.9-2-2-2z"/></g>
+<g id="party-mode"><path d="M20 4h-3.17L15 2H9L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 3c1.63 0 3.06.79 3.98 2H12c-1.66 0-3 1.34-3 3 0 .35.07.69.18 1H7.1c-.06-.32-.1-.66-.1-1 0-2.76 2.24-5 5-5zm0 10c-1.63 0-3.06-.79-3.98-2H12c1.66 0 3-1.34 3-3 0-.35-.07-.69-.18-1h2.08c.07.32.1.66.1 1 0 2.76-2.24 5-5 5z"/></g>
+<g id="people"><path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"/></g>
+<g id="people-outline"><path d="M16.5 13c-1.2 0-3.07.34-4.5 1-1.43-.67-3.3-1-4.5-1C5.33 13 1 14.08 1 16.25V19h22v-2.75c0-2.17-4.33-3.25-6.5-3.25zm-4 4.5h-10v-1.25c0-.54 2.56-1.75 5-1.75s5 1.21 5 1.75v1.25zm9 0H14v-1.25c0-.46-.2-.86-.52-1.22.88-.3 1.96-.53 3.02-.53 2.44 0 5 1.21 5 1.75v1.25zM7.5 12c1.93 0 3.5-1.57 3.5-3.5S9.43 5 7.5 5 4 6.57 4 8.5 5.57 12 7.5 12zm0-5.5c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm9 5.5c1.93 0 3.5-1.57 3.5-3.5S18.43 5 16.5 5 13 6.57 13 8.5s1.57 3.5 3.5 3.5zm0-5.5c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2z"/></g>
+<g id="person"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></g>
+<g id="person-add"><path d="M15 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm-9-2V7H4v3H1v2h3v3h2v-3h3v-2H6zm9 4c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></g>
+<g id="person-outline"><path d="M12 5.9c1.16 0 2.1.94 2.1 2.1s-.94 2.1-2.1 2.1S9.9 9.16 9.9 8s.94-2.1 2.1-2.1m0 9c2.97 0 6.1 1.46 6.1 2.1v1.1H5.9V17c0-.64 3.13-2.1 6.1-2.1M12 4C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 9c-2.67 0-8 1.34-8 4v3h16v-3c0-2.66-5.33-4-8-4z"/></g>
+<g id="plus-one"><path d="M10 8H8v4H4v2h4v4h2v-4h4v-2h-4zm4.5-1.92V7.9l2.5-.5V18h2V5z"/></g>
+<g id="poll"><path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/></g>
+<g id="public"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/></g>
+<g id="school"><path d="M5 13.18v4L12 21l7-3.82v-4L12 17l-7-3.82zM12 3L1 9l11 6 9-4.91V17h2V9L12 3z"/></g>
+<g id="share"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/></g>
+<g id="whatshot"><path d="M13.5.67s.74 2.65.74 4.8c0 2.06-1.35 3.73-3.41 3.73-2.07 0-3.63-1.67-3.63-3.73l.03-.36C5.21 7.51 4 10.62 4 14c0 4.42 3.58 8 8 8s8-3.58 8-8C20 8.61 17.41 3.8 13.5.67zM11.71 19c-1.78 0-3.22-1.4-3.22-3.14 0-1.62 1.05-2.76 2.81-3.12 1.77-.36 3.6-1.21 4.62-2.58.39 1.29.59 2.65.59 4.04 0 2.65-2.15 4.8-4.8 4.8z"/></g>
+</defs></svg>
+</iron-iconset-svg>
diff --git a/polymer_1.0.4/bower_components/iron-iconset-svg/.bower.json b/polymer_1.0.4/bower_components/iron-iconset-svg/.bower.json
new file mode 100644
index 0000000..8fdd25a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset-svg/.bower.json
@@ -0,0 +1,41 @@
+{
+ "name": "iron-iconset-svg",
+ "description": "Manages a set of svg icons",
+ "version": "1.0.4",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "icon"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-iconset-svg.git"
+ },
+ "dependencies": {
+ "polymer": "polymer/polymer#^1.0.0",
+ "iron-meta": "polymerelements/iron-meta#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "web-component-tester": "*"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-iconset-svg",
+ "_release": "1.0.4",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.4",
+ "commit": "795aa82ac22971421bc4375efbd2419ebba9099f"
+ },
+ "_source": "git://github.com/PolymerElements/iron-iconset-svg.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-iconset-svg"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-iconset-svg/.gitignore b/polymer_1.0.4/bower_components/iron-iconset-svg/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset-svg/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-iconset-svg/README.md b/polymer_1.0.4/bower_components/iron-iconset-svg/README.md
new file mode 100644
index 0000000..37d603a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset-svg/README.md
@@ -0,0 +1,4 @@
+iron-iconset-svg
+=========
+
+See the [component page](http://polymer-project.org/docs/elements/iron-elements.html#iron-iconset-svg) for more information.
diff --git a/polymer_1.0.4/bower_components/iron-iconset-svg/bower.json b/polymer_1.0.4/bower_components/iron-iconset-svg/bower.json
new file mode 100644
index 0000000..b58569c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset-svg/bower.json
@@ -0,0 +1,31 @@
+{
+ "name": "iron-iconset-svg",
+ "description": "Manages a set of svg icons",
+ "version": "1.0.4",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "icon"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-iconset-svg.git"
+ },
+ "dependencies": {
+ "polymer": "polymer/polymer#^1.0.0",
+ "iron-meta": "polymerelements/iron-meta#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "web-component-tester": "*"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-iconset-svg/demo/index.html b/polymer_1.0.4/bower_components/iron-iconset-svg/demo/index.html
new file mode 100644
index 0000000..efe8478
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset-svg/demo/index.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-iconset-svg</title>
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link href="../../paper-styles/demo-pages.html" rel="import">
+
+ <link rel="import" href="svg-sample-icons.html">
+ <style is="custom-style">
+
+ .centered {
+ text-align: center;
+ }
+
+ iron-icon {
+ height: 64px;
+ width: 64px;
+ margin: auto 1em;
+ }
+
+ iron-icon:nth-of-type(1) {
+ fill: orange;
+ }
+
+ iron-icon:nth-of-type(2) {
+ fill: green;
+ }
+
+ iron-icon:nth-of-type(3) {
+ fill: navy;
+ }
+
+ iron-icon {
+ transition: all 0.5s;
+ -webkit-transition: all 0.5s;
+ }
+
+ iron-icon:hover {
+ -webkit-filter: drop-shadow( 2px 2px 2px var(--google-grey-700) );
+ filter: drop-shadow( 2px 2px 2px var(--google-grey-700) );
+ }
+ </style>
+</head>
+<body>
+
+ <div class="vertical-section vertical-section-container centered">
+ <iron-icon icon="svg-sample-icons:codepen"></iron-icon>
+ <iron-icon icon="svg-sample-icons:twitter"></iron-icon>
+ <iron-icon icon="svg-sample-icons:youtube"></iron-icon>
+ </div>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-iconset-svg/demo/svg-sample-icons.html b/polymer_1.0.4/bower_components/iron-iconset-svg/demo/svg-sample-icons.html
new file mode 100644
index 0000000..94c930d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset-svg/demo/svg-sample-icons.html
@@ -0,0 +1,69 @@
+
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-iconset-svg.html">
+
+<iron-iconset-svg name="svg-sample-icons" size="100">
+ <svg>
+ <defs>
+ <g id="codepen">
+ <path class="outer-ring" d="M50,0C22.385,0,0,22.385,0,50c0,27.615,22.385,50,50,50c27.614,0,50-22.385,50-50C100,22.385,77.615,0,50,0z M50,91.789
+ C26.958,91.789,8.212,73.042,8.212,50C8.212,26.958,26.958,8.212,50,8.212c23.042,0,41.788,18.747,41.788,41.789
+ C91.788,73.042,73.042,91.789,50,91.789z"></path>
+ <path class="inner-logo" d="M80.893,40.234c-0.006-0.039-0.016-0.076-0.022-0.115c-0.013-0.075-0.027-0.15-0.046-0.223
+ c-0.012-0.044-0.028-0.086-0.042-0.128c-0.021-0.065-0.042-0.13-0.068-0.193c-0.018-0.044-0.039-0.088-0.059-0.13
+ c-0.028-0.06-0.057-0.119-0.09-0.175c-0.024-0.042-0.051-0.083-0.076-0.124c-0.036-0.055-0.073-0.109-0.112-0.161
+ c-0.029-0.039-0.06-0.078-0.091-0.115c-0.042-0.049-0.086-0.098-0.132-0.143c-0.035-0.036-0.069-0.072-0.106-0.104
+ c-0.049-0.044-0.099-0.086-0.15-0.127c-0.04-0.031-0.079-0.062-0.12-0.091c-0.016-0.01-0.029-0.023-0.044-0.033L51.474,19.531
+ c-0.893-0.595-2.055-0.595-2.947,0L20.267,38.371c-0.015,0.01-0.028,0.023-0.044,0.033c-0.042,0.029-0.081,0.06-0.12,0.091
+ c-0.052,0.041-0.102,0.083-0.15,0.127c-0.037,0.032-0.071,0.068-0.106,0.104c-0.046,0.045-0.09,0.094-0.132,0.143
+ c-0.031,0.038-0.062,0.077-0.092,0.115c-0.039,0.052-0.076,0.106-0.111,0.161c-0.027,0.041-0.052,0.082-0.076,0.124
+ c-0.033,0.057-0.062,0.115-0.09,0.175c-0.021,0.042-0.042,0.086-0.06,0.13c-0.026,0.063-0.047,0.128-0.068,0.193
+ c-0.014,0.042-0.029,0.084-0.042,0.128c-0.02,0.073-0.032,0.148-0.046,0.223c-0.006,0.039-0.016,0.076-0.021,0.115
+ c-0.016,0.114-0.024,0.229-0.024,0.346V59.42c0,0.117,0.009,0.233,0.024,0.348c0.005,0.038,0.015,0.077,0.021,0.114
+ c0.014,0.075,0.027,0.149,0.046,0.223c0.012,0.043,0.028,0.086,0.042,0.128c0.021,0.065,0.042,0.13,0.068,0.195
+ c0.018,0.044,0.039,0.086,0.06,0.129c0.028,0.06,0.058,0.118,0.09,0.177c0.024,0.041,0.049,0.082,0.076,0.122
+ c0.035,0.056,0.072,0.109,0.111,0.161c0.029,0.041,0.061,0.078,0.092,0.115c0.042,0.049,0.086,0.098,0.132,0.144
+ c0.035,0.036,0.069,0.071,0.106,0.104c0.048,0.044,0.099,0.086,0.15,0.127c0.039,0.031,0.078,0.062,0.12,0.091
+ c0.016,0.01,0.029,0.023,0.044,0.032l28.259,18.84c0.446,0.297,0.96,0.447,1.474,0.447c0.513,0,1.027-0.149,1.473-0.447
+ l28.259-18.84c0.015-0.009,0.028-0.022,0.044-0.032c0.042-0.029,0.081-0.06,0.12-0.091c0.051-0.041,0.102-0.083,0.15-0.127
+ c0.037-0.033,0.071-0.068,0.106-0.104c0.046-0.046,0.09-0.095,0.132-0.144c0.031-0.037,0.062-0.075,0.091-0.115
+ c0.04-0.052,0.076-0.105,0.112-0.161c0.025-0.041,0.051-0.081,0.076-0.122c0.033-0.059,0.062-0.117,0.09-0.177
+ c0.02-0.042,0.041-0.085,0.059-0.129c0.026-0.065,0.047-0.13,0.068-0.195c0.014-0.042,0.03-0.085,0.042-0.128
+ c0.02-0.074,0.033-0.148,0.046-0.223c0.006-0.037,0.016-0.076,0.022-0.114c0.014-0.115,0.023-0.231,0.023-0.348V40.581
+ C80.916,40.464,80.907,40.348,80.893,40.234z M52.657,26.707l20.817,13.877l-9.298,6.221l-11.519-7.706V26.707z M47.343,26.707
+ v12.393l-11.518,7.706l-9.299-6.221L47.343,26.707z M24.398,45.554L31.046,50l-6.648,4.446V45.554z M47.343,73.294L26.525,59.417
+ l9.299-6.219l11.518,7.704V73.294z M50,56.286L40.603,50L50,43.715L59.397,50L50,56.286z M52.657,73.294V60.902l11.519-7.704
+ l9.298,6.219L52.657,73.294z M75.602,54.447L68.955,50l6.647-4.446V54.447z"></path>
+ </g>
+
+ <path id="twitter" d="M100.001,17.942c-3.681,1.688-7.633,2.826-11.783,3.339
+ c4.236-2.624,7.49-6.779,9.021-11.73c-3.965,2.432-8.354,4.193-13.026,5.146C80.47,10.575,75.138,8,69.234,8
+ c-11.33,0-20.518,9.494-20.518,21.205c0,1.662,0.183,3.281,0.533,4.833c-17.052-0.884-32.168-9.326-42.288-22.155
+ c-1.767,3.133-2.778,6.773-2.778,10.659c0,7.357,3.622,13.849,9.127,17.65c-3.363-0.109-6.525-1.064-9.293-2.651
+ c-0.002,0.089-0.002,0.178-0.002,0.268c0,10.272,7.072,18.845,16.458,20.793c-1.721,0.484-3.534,0.744-5.405,0.744
+ c-1.322,0-2.606-0.134-3.859-0.379c2.609,8.424,10.187,14.555,19.166,14.726c-7.021,5.688-15.867,9.077-25.48,9.077
+ c-1.656,0-3.289-0.102-4.895-0.297C9.08,88.491,19.865,92,31.449,92c37.737,0,58.374-32.312,58.374-60.336
+ c0-0.92-0.02-1.834-0.059-2.743C93.771,25.929,97.251,22.195,100.001,17.942L100.001,17.942z"></path>
+
+ <g id="youtube">
+ <path class="youtube" d="M98.77,27.492c-1.225-5.064-5.576-8.799-10.811-9.354C75.561,16.818,63.01,15.993,50.514,16
+ c-12.495-0.007-25.045,0.816-37.446,2.139c-5.235,0.557-9.583,4.289-10.806,9.354C0.522,34.704,0.5,42.574,0.5,50.001
+ c0,7.426,0,15.296,1.741,22.509c1.224,5.061,5.572,8.799,10.807,9.352c12.399,1.32,24.949,2.145,37.446,2.14
+ c12.494,0.005,25.047-0.817,37.443-2.14c5.234-0.555,9.586-4.291,10.81-9.352c1.741-7.213,1.753-15.083,1.753-22.509
+ S100.51,34.704,98.77,27.492 M67.549,52.203L43.977,64.391c-2.344,1.213-4.262,0.119-4.262-2.428V38.036
+ c0-2.548,1.917-3.644,4.262-2.429l23.572,12.188C69.896,49.008,69.896,50.992,67.549,52.203"></path>
+ </g>
+
+ </defs>
+ </svg>
+</iron-iconset-svg>
diff --git a/polymer_1.0.4/bower_components/iron-iconset-svg/index.html b/polymer_1.0.4/bower_components/iron-iconset-svg/index.html
new file mode 100644
index 0000000..e871f17
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset-svg/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-iconset-svg/iron-iconset-svg.html b/polymer_1.0.4/bower_components/iron-iconset-svg/iron-iconset-svg.html
new file mode 100644
index 0000000..3cebc2c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset-svg/iron-iconset-svg.html
@@ -0,0 +1,192 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-meta/iron-meta.html">
+
+<script>
+ /**
+ * The `iron-iconset-svg` element allows users to define their own icon sets
+ * that contain svg icons. The svg icon elements should be children of the
+ * `iron-iconset-svg` element. Multiple icons should be given distinct id's.
+ *
+ * Using svg elements to create icons has a few advantages over traditional
+ * bitmap graphics like jpg or png. Icons that use svg are vector based so they
+ * are resolution independent and should look good on any device. They are
+ * stylable via css. Icons can be themed, colorized, and even animated.
+ *
+ * Example:
+ *
+ * <iron-iconset-svg name="my-svg-icons" size="24">
+ * <svg>
+ * <defs>
+ * <g id="shape">
+ * <rect x="50" y="50" width="50" height="50" />
+ * <circle cx="50" cy="50" r="50" />
+ * </g>
+ * </defs>
+ * </svg>
+ * </iron-iconset-svg>
+ *
+ * This will automatically register the icon set "my-svg-icons" to the iconset
+ * database. To use these icons from within another element, make a
+ * `iron-iconset` element and call the `byId` method
+ * to retrieve a given iconset. To apply a particular icon inside an
+ * element use the `applyIcon` method. For example:
+ *
+ * iconset.applyIcon(iconNode, 'car');
+ *
+ * @element iron-iconset-svg
+ * @demo demo/index.html
+ */
+ Polymer({
+
+ is: 'iron-iconset-svg',
+
+ properties: {
+
+ /**
+ * The name of the iconset.
+ *
+ * @attribute name
+ * @type string
+ */
+ name: {
+ type: String,
+ observer: '_nameChanged'
+ },
+
+ /**
+ * The size of an individual icon. Note that icons must be square.
+ *
+ * @attribute iconSize
+ * @type number
+ * @default 24
+ */
+ size: {
+ type: Number,
+ value: 24
+ }
+
+ },
+
+ /**
+ * Construct an array of all icon names in this iconset.
+ *
+ * @return {!Array} Array of icon names.
+ */
+ getIconNames: function() {
+ this._icons = this._createIconMap();
+ return Object.keys(this._icons).map(function(n) {
+ return this.name + ':' + n;
+ }, this);
+ },
+
+ /**
+ * Applies an icon to the given element.
+ *
+ * An svg icon is prepended to the element's shadowRoot if it exists,
+ * otherwise to the element itself.
+ *
+ * @method applyIcon
+ * @param {Element} element Element to which the icon is applied.
+ * @param {string} iconName Name of the icon to apply.
+ * @return {Element} The svg element which renders the icon.
+ */
+ applyIcon: function(element, iconName) {
+ // insert svg element into shadow root, if it exists
+ element = element.root || element;
+ // Remove old svg element
+ this.removeIcon(element);
+ // install new svg element
+ var svg = this._cloneIcon(iconName);
+ if (svg) {
+ var pde = Polymer.dom(element);
+ pde.insertBefore(svg, pde.childNodes[0]);
+ return element._svgIcon = svg;
+ }
+ return null;
+ },
+
+ /**
+ * Remove an icon from the given element by undoing the changes effected
+ * by `applyIcon`.
+ *
+ * @param {Element} element The element from which the icon is removed.
+ */
+ removeIcon: function(element) {
+ // Remove old svg element
+ if (element._svgIcon) {
+ Polymer.dom(element).removeChild(element._svgIcon);
+ element._svgIcon = null;
+ }
+ },
+
+ /**
+ *
+ * When name is changed, register iconset metadata
+ *
+ */
+ _nameChanged: function() {
+ new Polymer.IronMeta({type: 'iconset', key: this.name, value: this});
+ },
+
+ /**
+ * Create a map of child SVG elements by id.
+ *
+ * @return {!Object} Map of id's to SVG elements.
+ */
+ _createIconMap: function() {
+ // Objects chained to Object.prototype (`{}`) have members. Specifically,
+ // on FF there is a `watch` method that confuses the icon map, so we
+ // need to use a null-based object here.
+ var icons = Object.create(null);
+ Polymer.dom(this).querySelectorAll('[id]')
+ .forEach(function(icon) {
+ icons[icon.id] = icon;
+ });
+ return icons;
+ },
+
+ /**
+ * Produce installable clone of the SVG element matching `id` in this
+ * iconset, or `undefined` if there is no matching element.
+ *
+ * @return {Element} Returns an installable clone of the SVG element
+ * matching `id`.
+ */
+ _cloneIcon: function(id) {
+ // create the icon map on-demand, since the iconset itself has no discrete
+ // signal to know when it's children are fully parsed
+ this._icons = this._icons || this._createIconMap();
+ return this._prepareSvgClone(this._icons[id], this.size);
+ },
+
+ /**
+ * @param {Element} sourceSvg
+ * @param {number} size
+ * @return {Element}
+ */
+ _prepareSvgClone: function(sourceSvg, size) {
+ if (sourceSvg) {
+ var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+ svg.setAttribute('viewBox', ['0', '0', size, size].join(' '));
+ svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
+ // TODO(dfreedm): `pointer-events: none` works around https://crbug.com/370136
+ // TODO(sjmiles): inline style may not be ideal, but avoids requiring a shadow-root
+ svg.style.cssText = 'pointer-events: none; display: block; width: 100%; height: 100%;';
+ svg.appendChild(sourceSvg.cloneNode(true)).removeAttribute('id');
+ return svg;
+ }
+ return null;
+ }
+
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-iconset-svg/test/index.html b/polymer_1.0.4/bower_components/iron-iconset-svg/test/index.html
new file mode 100644
index 0000000..db4a3f6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset-svg/test/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+
+</head>
+<body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'iron-iconset-svg.html'
+ ]);
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-iconset-svg/test/iron-iconset-svg.html b/polymer_1.0.4/bower_components/iron-iconset-svg/test/iron-iconset-svg.html
new file mode 100644
index 0000000..4af6f8b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset-svg/test/iron-iconset-svg.html
@@ -0,0 +1,107 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-iconset-svg</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../iron-iconset-svg.html">
+ <link rel="import" href="../../iron-meta/iron-meta.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+
+</head>
+<body>
+
+ <test-fixture id="TrivialIconsetSvg">
+ <template>
+ <iron-iconset-svg name="foo"></iron-iconset-svg>
+ <iron-meta type="iconset"></iron-meta>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="StandardIconsetSvg">
+ <template>
+ <iron-iconset-svg name="my-icons" size="20">
+ <svg>
+ <defs>
+ <circle id="circle" cx="20" cy="20" r="10"></circle>
+ <rect id="square" x="0" y="0" width="20" height="20"></rect>
+ </defs>
+ </svg>
+ </iron-iconset-svg>
+ <div></div>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('<iron-iconset>', function () {
+
+ suite('basic behavior', function () {
+ var iconset;
+ var meta;
+
+ setup(function () {
+ var elements = fixture('TrivialIconsetSvg');
+ iconset = elements[0];
+ meta = elements[1];
+ });
+
+ test('it can be accessed via iron-meta', function () {
+ expect(meta.byKey('foo')).to.be.equal(iconset);
+ });
+ });
+
+ suite('when paired with a size and SVG definition', function () {
+ var iconset;
+ var div;
+
+ setup(function () {
+ var elements = fixture('StandardIconsetSvg');
+ iconset = elements[0];
+ div = elements[1];
+ });
+
+ test('appends a child to the target element', function () {
+ expect(div.firstElementChild).to.not.be.ok;
+ iconset.applyIcon(div, 'circle');
+ expect(div.firstElementChild).to.be.ok;
+ });
+
+ test('can be queried for all available icons', function () {
+ expect(iconset.getIconNames()).to.deep.eql(['my-icons:circle', 'my-icons:square']);
+ });
+
+ test('supports any icon defined in the svg', function () {
+ var lastSvgIcon;
+
+ iconset.getIconNames().forEach(function (iconName) {
+ iconset.applyIcon(div, iconName.split(':').pop());
+ expect(div.firstElementChild).to.not.be.equal(lastSvgIcon);
+ lastSvgIcon = div.firstElementChild;
+ });
+ });
+
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-iconset/.bower.json b/polymer_1.0.4/bower_components/iron-iconset/.bower.json
new file mode 100644
index 0000000..a157981
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset/.bower.json
@@ -0,0 +1,40 @@
+{
+ "name": "iron-iconset",
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Represents a set of icons",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "icon"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-iconset.git"
+ },
+ "private": true,
+ "dependencies": {
+ "iron-meta": "PolymerElements/iron-meta#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-iconset",
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "1d8d671d274ac99f990c92886c9b9f050f057264"
+ },
+ "_source": "git://github.com/PolymerElements/iron-iconset.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-iconset"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-iconset/.gitignore b/polymer_1.0.4/bower_components/iron-iconset/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-iconset/README.md b/polymer_1.0.4/bower_components/iron-iconset/README.md
new file mode 100644
index 0000000..53a245b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset/README.md
@@ -0,0 +1,51 @@
+iron-iconset
+============
+
+The `iron-iconset` element allows users to define their own icon sets.
+The `src` property specifies the url of the icon image. Multiple icons may
+be included in this image and they may be organized into rows.
+The `icons` property is a space separated list of names corresponding to the
+icons. The names must be ordered as the icons are ordered in the icon image.
+Icons are expected to be square and are the size specified by the `size`
+property. The `width` property corresponds to the width of the icon image
+and must be specified if icons are arranged into multiple rows in the image.
+
+All `iron-iconset` elements are available for use by other `iron-iconset`
+elements via a database keyed by id. Typically, an element author that wants
+to support a set of custom icons uses a `iron-iconset` to retrieve
+and use another, user-defined iconset.
+
+Example:
+
+```html
+<iron-iconset id="my-icons" src="my-icons.png" width="96" size="24"
+ icons="location place starta stopb bus car train walk">
+</iron-iconset>
+```
+
+This will automatically register the icon set "my-icons" to the iconset
+database. To use these icons from within another element, make a
+`iron-iconset` element and call the `byId` method to retrieve a
+given iconset. To apply a particular icon to an element, use the
+`applyIcon` method. For example:
+
+```javascript
+iconset.applyIcon(iconNode, 'car');
+```
+
+Themed icon sets are also supported. The `iron-iconset` can contain child
+`property` elements that specify a theme with an offsetX and offsetY of the
+theme within the icon resource. For example.
+
+```html
+<iron-iconset id="my-icons" src="my-icons.png" width="96" size="24"
+ icons="location place starta stopb bus car train walk">
+ <property theme="special" offsetX="256" offsetY="24"></property>
+</iron-iconset>
+```
+
+Then a themed icon can be applied like this:
+
+```javascript
+iconset.applyIcon(iconNode, 'car', 'special');
+```
diff --git a/polymer_1.0.4/bower_components/iron-iconset/bower.json b/polymer_1.0.4/bower_components/iron-iconset/bower.json
new file mode 100644
index 0000000..27e48d2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset/bower.json
@@ -0,0 +1,30 @@
+{
+ "name": "iron-iconset",
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Represents a set of icons",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "icon"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-iconset.git"
+ },
+ "private": true,
+ "dependencies": {
+ "iron-meta": "PolymerElements/iron-meta#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-iconset/demo/index.html b/polymer_1.0.4/bower_components/iron-iconset/demo/index.html
new file mode 100644
index 0000000..bcb1bc0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset/demo/index.html
@@ -0,0 +1,63 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-iconset</title>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-iconset.html">
+ <link rel="import" href="../../iron-icon/iron-icon.html">
+
+</head>
+<body>
+
+ <!-- Register an icon set; you can do this anywhere, including an HTMLImport! -->
+ <iron-iconset name="my-icons" src="my-icons.png" width="96" size="24"
+ icons="location place starta stopb bus car train walk">
+ </iron-iconset>
+
+ <iron-iconset name="my-icons-big" src="my-icons-big.png" width="192" size="48"
+ icons="location place starta stopb bus car train walk">
+ </iron-iconset>
+
+ <!-- Now create a bunch of icons using our iconset -->
+ <iron-icon icon="my-icons:location"></iron-icon>
+ <iron-icon icon="my-icons:place"></iron-icon>
+ <iron-icon icon="my-icons:starta"></iron-icon>
+ <iron-icon icon="my-icons:stopb"></iron-icon>
+ <iron-icon icon="my-icons:bus"></iron-icon>
+ <iron-icon icon="my-icons:car"></iron-icon>
+ <iron-icon icon="my-icons:train"></iron-icon>
+ <iron-icon icon="my-icons:walk"></iron-icon>
+ <br>
+ <!-- icons may also be specified by index -->
+ <style>
+ .embiggen iron-icon {
+ width: 48px;
+ height: 48px;
+ }
+ </style>
+
+ <div class="embiggen">
+ <iron-icon icon="my-icons-big:0"></iron-icon>
+ <iron-icon icon="my-icons-big:1"></iron-icon>
+ <iron-icon icon="my-icons-big:2"></iron-icon>
+ <iron-icon icon="my-icons-big:3"></iron-icon>
+ <iron-icon icon="my-icons-big:4"></iron-icon>
+ <iron-icon icon="my-icons-big:5"></iron-icon>
+ <iron-icon icon="my-icons-big:6"></iron-icon>
+ <iron-icon icon="my-icons-big:7"></iron-icon>
+ </div>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-iconset/demo/my-icons-big.png b/polymer_1.0.4/bower_components/iron-iconset/demo/my-icons-big.png
new file mode 100644
index 0000000..f019f3f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset/demo/my-icons-big.png
Binary files differ
diff --git a/polymer_1.0.4/bower_components/iron-iconset/demo/my-icons.png b/polymer_1.0.4/bower_components/iron-iconset/demo/my-icons.png
new file mode 100644
index 0000000..a7d223b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset/demo/my-icons.png
Binary files differ
diff --git a/polymer_1.0.4/bower_components/iron-iconset/index.html b/polymer_1.0.4/bower_components/iron-iconset/index.html
new file mode 100644
index 0000000..64e80d5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset/index.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <title>iron-iconset</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-iconset/iron-iconset.html b/polymer_1.0.4/bower_components/iron-iconset/iron-iconset.html
new file mode 100644
index 0000000..fc21d99
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset/iron-iconset.html
@@ -0,0 +1,336 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-meta/iron-meta.html">
+
+<!--
+The `iron-iconset` element allows users to define their own icon sets.
+The `src` property specifies the url of the icon image. Multiple icons may
+be included in this image and they may be organized into rows.
+The `icons` property is a space separated list of names corresponding to the
+icons. The names must be ordered as the icons are ordered in the icon image.
+Icons are expected to be square and are the size specified by the `size`
+property. The `width` property corresponds to the width of the icon image
+and must be specified if icons are arranged into multiple rows in the image.
+
+All `iron-iconset` elements are available for use by other `iron-iconset`
+elements via a database keyed by id. Typically, an element author that wants
+to support a set of custom icons uses a `iron-iconset` to retrieve
+and use another, user-defined iconset.
+
+Example:
+
+ <iron-iconset id="my-icons" src="my-icons.png" width="96" size="24"
+ icons="location place starta stopb bus car train walk">
+ </iron-iconset>
+
+This will automatically register the icon set "my-icons" to the iconset
+database. To use these icons from within another element, make a
+`iron-iconset` element and call the `byId` method to retrieve a
+given iconset. To apply a particular icon to an element, use the
+`applyIcon` method. For example:
+
+ iconset.applyIcon(iconNode, 'car');
+
+Themed icon sets are also supported. The `iron-iconset` can contain child
+`property` elements that specify a theme with an offsetX and offsetY of the
+theme within the icon resource. For example.
+
+ <iron-iconset id="my-icons" src="my-icons.png" width="96" size="24"
+ icons="location place starta stopb bus car train walk">
+ <property theme="special" offsetX="256" offsetY="24"></property>
+ </iron-iconset>
+
+Then a themed icon can be applied like this:
+
+ iconset.applyIcon(iconNode, 'car', 'special');
+
+@element iron-iconset
+@demo demo/index.html
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'iron-iconset',
+
+ properties: {
+
+ /**
+ * The URL of the iconset image.
+ *
+ * @attribute src
+ * @type string
+ * @default ''
+ */
+ src: {
+ type: String,
+ observer: '_srcChanged'
+ },
+
+ /**
+ * The name of the iconset.
+ *
+ * @attribute name
+ * @type string
+ * @default 'no-name'
+ */
+ name: {
+ type: String,
+ observer: '_nameChanged'
+ },
+
+ /**
+ * The width of the iconset image. This must only be specified if the
+ * icons are arranged into separate rows inside the image.
+ *
+ * @attribute width
+ * @type number
+ * @default 0
+ */
+ width: {
+ type: Number,
+ value: 0
+ },
+
+ /**
+ * A space separated list of names corresponding to icons in the iconset
+ * image file. This list must be ordered the same as the icon images
+ * in the image file.
+ *
+ * @attribute icons
+ * @type string
+ * @default ''
+ */
+ icons: {
+ type: String
+ },
+
+ /**
+ * The size of an individual icon. Note that icons must be square.
+ *
+ * @attribute size
+ * @type number
+ * @default 24
+ */
+ size: {
+ type: Number,
+ value: 24
+ },
+
+ /**
+ * The horizontal offset of the icon images in the inconset src image.
+ * This is typically used if the image resource contains additional images
+ * beside those intended for the iconset.
+ *
+ * @attribute offset-x
+ * @type number
+ * @default 0
+ */
+ _offsetX: {
+ type: Number,
+ value: 0
+ },
+
+ /**
+ * The vertical offset of the icon images in the inconset src image.
+ * This is typically used if the image resource contains additional images
+ * beside those intended for the iconset.
+ *
+ * @attribute offset-y
+ * @type number
+ * @default 0
+ */
+ _offsetY: {
+ type: Number,
+ value: 0
+ },
+
+ /**
+ * Array of fully-qualified names of icons in this set.
+ */
+ iconNames: {
+ type: Array,
+ notify: true
+ }
+
+ },
+
+ hostAttributes: {
+ // non-visual
+ style: 'display: none;'
+ },
+
+ ready: function() {
+ // theme data must exist at ready-time
+ this._themes = this._mapThemes();
+ },
+
+ /**
+ * Applies an icon to the given element as a css background image. This
+ * method does not size the element, and it's usually necessary to set
+ * the element's height and width so that the background image is visible.
+ *
+ * @method applyIcon
+ * @param {Element} element The element to which the icon is applied.
+ * @param {String|Number} icon The name or index of the icon to apply.
+ * @param {String} theme (optional) The name or index of the icon to apply.
+ * @param {Number} scale (optional, defaults to 1) Icon scaling factor.
+ */
+ applyIcon: function(element, icon, theme, scale) {
+ this._validateIconMap();
+ var offset = this._getThemedOffset(icon, theme);
+ if (element && offset) {
+ this._addIconStyles(element, this._srcUrl, offset, scale || 1,
+ this.size, this.width);
+ }
+ },
+
+ /**
+ * Remove an icon from the given element by undoing the changes effected
+ * by `applyIcon`.
+ *
+ * @param {Element} element The element from which the icon is removed.
+ */
+ removeIcon: function(element) {
+ this._removeIconStyles(element.style);
+ },
+
+ _mapThemes: function() {
+ var themes = Object.create(null);
+ Polymer.dom(this).querySelectorAll('property[theme]')
+ .forEach(function(property) {
+ var offsetX = window.parseInt(
+ property.getAttribute('offset-x'), 10
+ ) || 0;
+ var offsetY = window.parseInt(
+ property.getAttribute('offset-y'), 10
+ ) || 0;
+ themes[property.getAttribute('theme')] = {
+ offsetX: offsetX,
+ offsetY: offsetY
+ };
+ });
+ return themes;
+ },
+
+ _srcChanged: function(src) {
+ // ensure `srcUrl` is always relative to the main document
+ this._srcUrl = this.ownerDocument !== document
+ ? this.resolveUrl(src) : src;
+ this._prepareIconset();
+ },
+
+ _nameChanged: function(name) {
+ this._prepareIconset();
+ },
+
+ _prepareIconset: function() {
+ new Polymer.IronMeta({type: 'iconset', key: this.name, value: this});
+ },
+
+ _invalidateIconMap: function() {
+ this._iconMapValid = false;
+ },
+
+ _validateIconMap: function() {
+ if (!this._iconMapValid) {
+ this._recomputeIconMap();
+ this._iconMapValid = true;
+ }
+ },
+
+ _recomputeIconMap: function() {
+ this.iconNames = this._computeIconNames(this.icons);
+ this.iconMap = this._computeIconMap(this._offsetX, this._offsetY,
+ this.size, this.width, this.iconNames);
+ },
+
+ _computeIconNames: function(icons) {
+ return icons.split(/\s+/g);
+ },
+
+ _computeIconMap: function(offsetX, offsetY, size, width, iconNames) {
+ var iconMap = {};
+ if (offsetX !== undefined && offsetY !== undefined) {
+ var x0 = offsetX;
+ iconNames.forEach(function(iconName) {
+ iconMap[iconName] = {
+ offsetX: offsetX,
+ offsetY: offsetY
+ };
+ if ((offsetX + size) < width) {
+ offsetX += size;
+ } else {
+ offsetX = x0;
+ offsetY += size;
+ }
+ }, this);
+ }
+ return iconMap;
+ },
+
+ /**
+ * Returns an object containing `offsetX` and `offsetY` properties which
+ * specify the pixel location in the iconset's src file for the given
+ * `icon` and `theme`. It's uncommon to call this method. It is useful,
+ * for example, to manually position a css backgroundImage to the proper
+ * offset. It's more common to use the `applyIcon` method.
+ *
+ * @method getThemedOffset
+ * @param {String|Number} identifier The name of the icon or the index of
+ * the icon within in the icon image.
+ * @param {String} theme The name of the theme.
+ * @returns {Object} An object specifying the offset of the given icon
+ * within the icon resource file; `offsetX` is the horizontal offset and
+ * `offsetY` is the vertical offset. Both values are in pixel units.
+ */
+ _getThemedOffset: function(identifier, theme) {
+ var iconOffset = this._getIconOffset(identifier);
+ var themeOffset = this._themes[theme];
+ if (iconOffset && themeOffset) {
+ return {
+ offsetX: iconOffset.offsetX + themeOffset.offsetX,
+ offsetY: iconOffset.offsetY + themeOffset.offsetY
+ };
+ }
+ return iconOffset;
+ },
+
+ _getIconOffset: function(identifier) {
+ // TODO(sjmiles): consider creating offsetArray (indexed by Number)
+ // and having iconMap map names to indices, then and index is just
+ // iconMap[identifier] || identifier (be careful of zero, store indices
+ // as 1-based)
+ return this.iconMap[identifier] ||
+ this.iconMap[this.iconNames[Number(identifier)]];
+ },
+
+ _addIconStyles: function(element, url, offset, scale, size, width) {
+ var style = element.style;
+ style.backgroundImage = 'url(' + url + ')';
+ style.backgroundPosition =
+ (-offset.offsetX * scale + 'px') + ' ' +
+ (-offset.offsetY * scale + 'px');
+ style.backgroundSize = (scale === 1) ? 'auto' : width * scale + 'px';
+ style.width = size + 'px';
+ style.height = size + 'px';
+ element.setAttribute('role', 'img');
+ },
+
+ _removeIconStyles: function(style) {
+ style.background = '';
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-iconset/test/index.html b/polymer_1.0.4/bower_components/iron-iconset/test/index.html
new file mode 100644
index 0000000..dc00be0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset/test/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+
+</head>
+<body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'iron-iconset.html'
+ ]);
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-iconset/test/iron-iconset.html b/polymer_1.0.4/bower_components/iron-iconset/test/iron-iconset.html
new file mode 100644
index 0000000..74d4a0b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-iconset/test/iron-iconset.html
@@ -0,0 +1,149 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-iconset</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../iron-iconset.html">
+ <link rel="import" href="../../iron-meta/iron-meta.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+
+</head>
+<body>
+
+ <test-fixture id="TrivialIconset">
+ <template>
+ <iron-iconset name="foo" src="../demo/my-icons.png"></iron-iconset>
+ <iron-meta type="iconset"></iron-meta>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="StandardIconset">
+ <template>
+ <iron-iconset name="my-icons"
+ src="../demo/my-icons.png"
+ width="96"
+ size="24"
+ icons="location place starta stopb bus car train walk"></iron-iconset>
+ <div></div>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="ThemedIconset">
+ <template>
+ <iron-iconset name="my-icons"
+ src="../demo/my-icons.png"
+ width="96"
+ size="24"
+ icons="location place starta stopb bus car train walk">
+ <property theme="large" offset-x="10" offset-y="10"></property>
+ </iron-iconset>
+ <div></div>
+ </template>
+ </test-fixture>
+
+ <script>
+suite('<iron-iconset>', function () {
+ suite('basic behavior', function () {
+ var iconset;
+ var meta;
+
+ setup(function () {
+ var elements = fixture('TrivialIconset');
+
+ iconset = elements[0];
+ meta = elements[1];
+ });
+
+ test('it can be accessed via iron-meta', function () {
+ expect(meta.byKey('foo')).to.be.equal(iconset);
+ });
+ });
+
+ suite('when src, width, iconSize and icons are assigned', function () {
+ var iconset;
+ var div;
+
+ setup(function () {
+ var elements = fixture('StandardIconset');
+
+ iconset = elements[0];
+ div = elements[1];
+ });
+
+/*
+ test('appends a child to the target element', function () {
+ expect(div.firstElementChild).to.not.be.ok;
+
+ iconset.applyIcon(div, 'location');
+
+ expect(div.firstElementChild).to.be.ok;
+ });
+*/
+
+ test('sets the background image of the target element', function () {
+ var iconStyle;
+
+ iconset.applyIcon(div, 'location');
+ iconStyle = window.getComputedStyle(div);
+
+ expect(iconStyle.backgroundImage).to.match(/url\(.*demo\/my-icons.png["']?\)/);
+ });
+
+ test('offsets the background image to the icon\'s position', function () {
+ var iconStyle;
+
+ iconset.applyIcon(div, 'bus');
+ iconStyle = window.getComputedStyle(div);
+
+ expect(iconStyle.backgroundPosition).to.match(/0(px|%) -24px/);
+ });
+ });
+
+ suite('when an iconset is themed', function () {
+ var iconset;
+ var div;
+
+ setup(function () {
+ var elements = fixture('ThemedIconset');
+
+ iconset = elements[0];
+ div = elements[1];
+ });
+
+ test('can use a theme when applying icon', function () {
+ iconset.applyIcon(div, 'bus', 'large');
+
+ expect(div).to.be.ok;
+ });
+
+ test('adjusts the icon by the theme offset', function () {
+ var iconStyle;
+
+ iconset.applyIcon(div, 'bus', 'large');
+ iconStyle = window.getComputedStyle(div);
+
+ expect(iconStyle.backgroundPosition).to.match(/-10px -34px/);
+ });
+ });
+});
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-image/.bower.json b/polymer_1.0.4/bower_components/iron-image/.bower.json
new file mode 100644
index 0000000..6431717
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-image/.bower.json
@@ -0,0 +1,40 @@
+{
+ "name": "iron-image",
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "An image-displaying element with lots of convenient features",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "media"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-image.git"
+ },
+ "dependencies": {
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.4",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-image",
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "f3d3090dc9a59b662f67c9c7dd1fc61e716f353d"
+ },
+ "_source": "git://github.com/PolymerElements/iron-image.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-image"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-image/.gitignore b/polymer_1.0.4/bower_components/iron-image/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-image/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-image/README.md b/polymer_1.0.4/bower_components/iron-image/README.md
new file mode 100644
index 0000000..04fda7a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-image/README.md
@@ -0,0 +1,60 @@
+iron-image
+==========
+
+`iron-image` is an element for displaying an image that provides useful sizing and
+preloading options not found on the standard `<img>` tag.
+
+The `sizing` option allows the image to be either cropped (`cover`) or
+letterboxed (`contain`) to fill a fixed user-size placed on the element.
+
+The `preload` option prevents the browser from rendering the image until the
+image is fully loaded. In the interim, either the element's CSS `background-color`
+can be be used as the placeholder, or the `placeholder` property can be
+set to a URL (preferably a data-URI, for instant rendering) for an
+placeholder image.
+
+The `fade` option (only valid when `preload` is set) will cause the placeholder
+image/color to be faded out once the image is rendered.
+
+Examples:
+
+Basically identical to `<img src="...">` tag:
+
+```html
+<iron-image src="http://lorempixel.com/400/400"></iron-image>
+```
+
+Will letterbox the image to fit:
+
+```html
+<iron-image style="width:400px; height:400px;" sizing="contain"
+ src="http://lorempixel.com/600/400"></iron-image>
+```
+
+Will crop the image to fit:
+
+```html
+<iron-image style="width:400px; height:400px;" sizing="cover"
+ src="http://lorempixel.com/600/400"></iron-image>
+```
+
+Will show light-gray background until the image loads:
+
+```html
+<iron-image style="width:400px; height:400px; background-color: lightgray;"
+ sizing="cover" preload src="http://lorempixel.com/600/400"></iron-image>
+```
+
+Will show a base-64 encoded placeholder image until the image loads:
+
+```html
+<iron-image style="width:400px; height:400px;" placeholder="data:image/gif;base64,..."
+ sizing="cover" preload src="http://lorempixel.com/600/400"></iron-image>
+```
+
+Will fade the light-gray background out once the image is loaded:
+
+```html
+<iron-image style="width:400px; height:400px; background-color: lightgray;"
+ sizing="cover" preload fade src="http://lorempixel.com/600/400"></iron-image>
+```
diff --git a/polymer_1.0.4/bower_components/iron-image/bower.json b/polymer_1.0.4/bower_components/iron-image/bower.json
new file mode 100644
index 0000000..8e3d0ac
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-image/bower.json
@@ -0,0 +1,30 @@
+{
+ "name": "iron-image",
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "An image-displaying element with lots of convenient features",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "media"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-image.git"
+ },
+ "dependencies": {
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.4",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-image/demo/index.html b/polymer_1.0.4/bower_components/iron-image/demo/index.html
new file mode 100644
index 0000000..b29f9cb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-image/demo/index.html
@@ -0,0 +1,183 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>iron-image</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+ <link rel="import" href="../iron-image.html">
+
+ <style>
+ .sized {
+ width: 200px;
+ height: 200px;
+ }
+ .gray {
+ background-color: lightgray;
+ }
+ .group {
+ display: inline-block;
+ vertical-align: top;
+ }
+
+ [hidden] {
+ display: none;
+ }
+
+ .controls {
+ display: block;
+ margin-bottom: 1em;
+ }
+ </style>
+
+ </head>
+ <body unresolved>
+
+ <template is="dom-bind">
+ <h3>Sizing: none (naturally sized)</h3>
+ <iron-image src="./polymer.svg"></iron-image>
+
+ <h3>Sizing: cover</h3>
+ <iron-image class="sized" sizing="cover" src="./polymer.svg"></iron-image>
+ <iron-image class="sized" sizing="cover" src="./polymer.svg"></iron-image>
+
+ <h3>Sizing: contain</h3>
+ <iron-image class="sized gray" sizing="contain" src="./polymer.svg"></iron-image>
+ <iron-image class="sized gray" sizing="contain" src="./polymer.svg"></iron-image>
+
+ <h3>Preload: none</h3>
+ <div class="group">
+ <div>No sizing</div>
+ <div class="controls">
+ <button on-click="preload" target="preload1a">Load image</button>
+ </div>
+ <iron-image id="preload1a" class="sized gray" ></iron-image>
+ </div>
+ <div class="group">
+ <div>Cover</div>
+ <div class="controls"><button on-click="preload" target="preload1b">Load image</button></div>
+ <iron-image id="preload1b" class="sized gray" sizing="cover" ></iron-image>
+ </div>
+ <div class="group">
+ <div>Contain</div>
+ <div class="controls"><button on-click="preload" target="preload1c">Load image</button></div>
+ <iron-image id="preload1c" class="sized gray" sizing="contain" ></iron-image>
+ </div>
+
+ <h3>Preload: color as placeholder</h3>
+ <div class="group">
+ <div>No sizing</div>
+ <div class="controls"><button on-click="preload" target="preload2a">Load image</button>
+ <span hidden$="[[!loading2a]]">Loading...</span></div>
+
+ <iron-image loading="{{loading2a}}" id="preload2a" class="sized gray" preload></iron-image>
+ </div>
+ <div class="group">
+ <div>Cover</div>
+ <div class="controls"><button on-click="preload" target="preload2b">Load image</button>
+ <span hidden$="[[!loading2b]]">Loading...</span></div>
+
+ <iron-image loading="{{loading2b}}" id="preload2b" class="sized gray" sizing="cover" preload ></iron-image>
+ </div>
+ <div class="group">
+ <div>Contain</div>
+ <div class="controls"><button on-click="preload" target="preload2c">Load image</button>
+ <span hidden$="[[!loading2c]]">Loading...</span></div>
+
+ <iron-image loading="{{loading2c}}" id="preload2c" class="sized gray" sizing="contain" preload ></iron-image>
+ </div>
+
+ <h3>Preload: image as placeholder</h3>
+ <div class="group">
+ <div>No sizing</div>
+ <div class="controls"><button on-click="preload" target="preload3a">Load image</button>
+ <span hidden$="[[!loading3a]]">Loading...</span></div>
+
+ <iron-image loading="{{loading3a}}" id="preload3a" class="sized gray" preload placeholder="data:image/gif;base64,R0lGODdhyADIAOMAAO7u/5aWlqGho9jY5OPj8cLCyqyssLe3vc3N1wAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAyADIAAAE/hDISau9OOvNu/9gKI5kaZ5oqq5s675wLM90bd94ru987//AoHBILBqPyKRyyWw6n9CodEqtWq/YrHbL7Xq/4LB4TC6bz+i0es1uu9/wuHxOr9vv+Lx+z+/7/4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0NHS06kB1tYqA9cUBQEFrgLWAgIqBOEBFNuu1gMs2ugT3d/rAe0r77bsFwMGAQLzEggc8AcQAIJwA+EBuKbQmgF+3iocDHBAXiZ9Fd6dAxhuo4R3/gwnGDgnkqE1BBM0XrN3CSOFgQYM+ouHEsFMAP1i2lQIAN8EhwS6kZPQ74BMnpZcTgiHkoA1AhKxAWDaU+pHqwvrVVVI1ScmpRIwYjxwTqo+r1vTafV6FmtSrRXEak0ooB+8tjzR4v251m0llwSgUnUaAOrJtFMDoESrty9XxYi/wk0sMEBMoRKo7iRK8SiFxu285vQMoIDR0qdNN+rmbxxJlRFLi7u22OG1mDjP4bYb2uFVf+r0CZ+cyOS1oRD/cUM4cN5EA3bDhszqWOHEhBLIZh+qHdnmaFABwIwm9BxLZxAtn6fGvr379/Djy59Pv779+/jz69/Pv7///wAGQyjggAQWaOCBCCao4IIMNujggxBGKOGEFFZo4YUYZqjhhhx26OGHIIYo4ogklmjiiSimqOKKLLbo4oswxijjjDRKEQEAOw=="></iron-image>
+ </div>
+
+ <div class="group">
+ <div>Cover</div>
+ <div class="controls"><button on-click="preload" target="preload3b">Load image</button>
+ <span hidden$="[[!loading3b]]">Loading...</span></div>
+
+ <iron-image loading="{{loading3b}}" id="preload3b" class="sized gray" sizing="cover" preload placeholder="data:image/gif;base64,R0lGODdhyADIAOMAAO7u/5aWlqGho9jY5OPj8cLCyqyssLe3vc3N1wAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAyADIAAAE/hDISau9OOvNu/9gKI5kaZ5oqq5s675wLM90bd94ru987//AoHBILBqPyKRyyWw6n9CodEqtWq/YrHbL7Xq/4LB4TC6bz+i0es1uu9/wuHxOr9vv+Lx+z+/7/4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0NHS06kB1tYqA9cUBQEFrgLWAgIqBOEBFNuu1gMs2ugT3d/rAe0r77bsFwMGAQLzEggc8AcQAIJwA+EBuKbQmgF+3iocDHBAXiZ9Fd6dAxhuo4R3/gwnGDgnkqE1BBM0XrN3CSOFgQYM+ouHEsFMAP1i2lQIAN8EhwS6kZPQ74BMnpZcTgiHkoA1AhKxAWDaU+pHqwvrVVVI1ScmpRIwYjxwTqo+r1vTafV6FmtSrRXEak0ooB+8tjzR4v251m0llwSgUnUaAOrJtFMDoESrty9XxYi/wk0sMEBMoRKo7iRK8SiFxu285vQMoIDR0qdNN+rmbxxJlRFLi7u22OG1mDjP4bYb2uFVf+r0CZ+cyOS1oRD/cUM4cN5EA3bDhszqWOHEhBLIZh+qHdnmaFABwIwm9BxLZxAtn6fGvr379/Djy59Pv779+/jz69/Pv7///wAGQyjggAQWaOCBCCao4IIMNujggxBGKOGEFFZo4YUYZqjhhhx26OGHIIYo4ogklmjiiSimqOKKLLbo4oswxijjjDRKEQEAOw=="></iron-image>
+ </div>
+
+ <div class="group">
+ <div>Contain</div>
+ <div class="controls"><button on-click="preload" target="preload3c">Load image</button>
+ <span hidden$="[[!loading3c]]">Loading...</span></div>
+
+ <iron-image loading="{{loading3c}}" id="preload3c" class="sized gray" sizing="contain" preload placeholder="data:image/gif;base64,R0lGODdhyADIAOMAAO7u/5aWlqGho9jY5OPj8cLCyqyssLe3vc3N1wAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAyADIAAAE/hDISau9OOvNu/9gKI5kaZ5oqq5s675wLM90bd94ru987//AoHBILBqPyKRyyWw6n9CodEqtWq/YrHbL7Xq/4LB4TC6bz+i0es1uu9/wuHxOr9vv+Lx+z+/7/4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0NHS06kB1tYqA9cUBQEFrgLWAgIqBOEBFNuu1gMs2ugT3d/rAe0r77bsFwMGAQLzEggc8AcQAIJwA+EBuKbQmgF+3iocDHBAXiZ9Fd6dAxhuo4R3/gwnGDgnkqE1BBM0XrN3CSOFgQYM+ouHEsFMAP1i2lQIAN8EhwS6kZPQ74BMnpZcTgiHkoA1AhKxAWDaU+pHqwvrVVVI1ScmpRIwYjxwTqo+r1vTafV6FmtSrRXEak0ooB+8tjzR4v251m0llwSgUnUaAOrJtFMDoESrty9XxYi/wk0sMEBMoRKo7iRK8SiFxu285vQMoIDR0qdNN+rmbxxJlRFLi7u22OG1mDjP4bYb2uFVf+r0CZ+cyOS1oRD/cUM4cN5EA3bDhszqWOHEhBLIZh+qHdnmaFABwIwm9BxLZxAtn6fGvr379/Djy59Pv779+/jz69/Pv7///wAGQyjggAQWaOCBCCao4IIMNujggxBGKOGEFFZo4YUYZqjhhhx26OGHIIYo4ogklmjiiSimqOKKLLbo4oswxijjjDRKEQEAOw=="></iron-image>
+ </div>
+
+ <h3>Preload: color as placeholder, with Fade-in</h3>
+ <div class="group">
+ <div>No sizing</div>
+ <div class="controls"><button on-click="preload" target="preload2afade">Load image</button>
+ <span hidden$="[[!loading2aFade]]">Loading...</span></div>
+
+ <iron-image loading="{{loading2aFade}}" id="preload2afade" class="sized gray" preload fade></iron-image>
+ </div>
+ <div class="group">
+ <div>Cover</div>
+ <div class="controls"><button on-click="preload" target="preload2bfade">Load image</button>
+ <span hidden$="[[!loading2bFade]]">Loading...</span></div>
+
+ <iron-image loading="{{loading2bFade}}" id="preload2bfade" class="sized gray" sizing="cover" preload fade></iron-image>
+ </div>
+ <div class="group">
+ <div>Contain</div>
+ <div class="controls"><button on-click="preload" target="preload2cfade">Load image</button>
+ <span hidden$="[[!loading2cFade]]">Loading...</span></div>
+
+ <iron-image loading="{{loading2cFade}}" id="preload2cfade" class="sized gray" sizing="contain" preload fade></iron-image>
+ </div>
+
+ <h3>Preload: image as placeholder, with Fade-in</h3>
+ <div class="group">
+ <div>No sizing</div>
+ <div class="controls"><button on-click="preload" target="preload3afade">Load image</button>
+ <span hidden$="[[!loading3aFade]]">Loading...</span></div>
+
+ <iron-image loading="{{loading3aFade}}" id="preload3afade" class="sized gray" preload placeholder="data:image/gif;base64,R0lGODdhyADIAOMAAO7u/5aWlqGho9jY5OPj8cLCyqyssLe3vc3N1wAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAyADIAAAE/hDISau9OOvNu/9gKI5kaZ5oqq5s675wLM90bd94ru987//AoHBILBqPyKRyyWw6n9CodEqtWq/YrHbL7Xq/4LB4TC6bz+i0es1uu9/wuHxOr9vv+Lx+z+/7/4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0NHS06kB1tYqA9cUBQEFrgLWAgIqBOEBFNuu1gMs2ugT3d/rAe0r77bsFwMGAQLzEggc8AcQAIJwA+EBuKbQmgF+3iocDHBAXiZ9Fd6dAxhuo4R3/gwnGDgnkqE1BBM0XrN3CSOFgQYM+ouHEsFMAP1i2lQIAN8EhwS6kZPQ74BMnpZcTgiHkoA1AhKxAWDaU+pHqwvrVVVI1ScmpRIwYjxwTqo+r1vTafV6FmtSrRXEak0ooB+8tjzR4v251m0llwSgUnUaAOrJtFMDoESrty9XxYi/wk0sMEBMoRKo7iRK8SiFxu285vQMoIDR0qdNN+rmbxxJlRFLi7u22OG1mDjP4bYb2uFVf+r0CZ+cyOS1oRD/cUM4cN5EA3bDhszqWOHEhBLIZh+qHdnmaFABwIwm9BxLZxAtn6fGvr379/Djy59Pv779+/jz69/Pv7///wAGQyjggAQWaOCBCCao4IIMNujggxBGKOGEFFZo4YUYZqjhhhx26OGHIIYo4ogklmjiiSimqOKKLLbo4oswxijjjDRKEQEAOw==" fade></iron-image>
+ </div>
+ <div class="group">
+ <div>Cover</div>
+ <div class="controls"><button on-click="preload" target="preload3bfade">Load image</button>
+ <span hidden$="[[!loading3bFade]]">Loading...</span></div>
+
+ <iron-image loading="{{loading3bFade}}" id="preload3bfade" class="sized gray" sizing="cover" preload placeholder="data:image/gif;base64,R0lGODdhyADIAOMAAO7u/5aWlqGho9jY5OPj8cLCyqyssLe3vc3N1wAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAyADIAAAE/hDISau9OOvNu/9gKI5kaZ5oqq5s675wLM90bd94ru987//AoHBILBqPyKRyyWw6n9CodEqtWq/YrHbL7Xq/4LB4TC6bz+i0es1uu9/wuHxOr9vv+Lx+z+/7/4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0NHS06kB1tYqA9cUBQEFrgLWAgIqBOEBFNuu1gMs2ugT3d/rAe0r77bsFwMGAQLzEggc8AcQAIJwA+EBuKbQmgF+3iocDHBAXiZ9Fd6dAxhuo4R3/gwnGDgnkqE1BBM0XrN3CSOFgQYM+ouHEsFMAP1i2lQIAN8EhwS6kZPQ74BMnpZcTgiHkoA1AhKxAWDaU+pHqwvrVVVI1ScmpRIwYjxwTqo+r1vTafV6FmtSrRXEak0ooB+8tjzR4v251m0llwSgUnUaAOrJtFMDoESrty9XxYi/wk0sMEBMoRKo7iRK8SiFxu285vQMoIDR0qdNN+rmbxxJlRFLi7u22OG1mDjP4bYb2uFVf+r0CZ+cyOS1oRD/cUM4cN5EA3bDhszqWOHEhBLIZh+qHdnmaFABwIwm9BxLZxAtn6fGvr379/Djy59Pv779+/jz69/Pv7///wAGQyjggAQWaOCBCCao4IIMNujggxBGKOGEFFZo4YUYZqjhhhx26OGHIIYo4ogklmjiiSimqOKKLLbo4oswxijjjDRKEQEAOw==" fade></iron-image>
+ </div>
+ <div class="group">
+ <div>Contain</div>
+ <div class="controls"><button on-click="preload" target="preload3cfade">Load image</button>
+ <span hidden$="[[!loading3cFade]]">Loading...</span></div>
+
+ <iron-image loading="{{loading3cFade}}" id="preload3cfade" class="sized gray" sizing="contain" preload placeholder="data:image/gif;base64,R0lGODdhyADIAOMAAO7u/5aWlqGho9jY5OPj8cLCyqyssLe3vc3N1wAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAyADIAAAE/hDISau9OOvNu/9gKI5kaZ5oqq5s675wLM90bd94ru987//AoHBILBqPyKRyyWw6n9CodEqtWq/YrHbL7Xq/4LB4TC6bz+i0es1uu9/wuHxOr9vv+Lx+z+/7/4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0NHS06kB1tYqA9cUBQEFrgLWAgIqBOEBFNuu1gMs2ugT3d/rAe0r77bsFwMGAQLzEggc8AcQAIJwA+EBuKbQmgF+3iocDHBAXiZ9Fd6dAxhuo4R3/gwnGDgnkqE1BBM0XrN3CSOFgQYM+ouHEsFMAP1i2lQIAN8EhwS6kZPQ74BMnpZcTgiHkoA1AhKxAWDaU+pHqwvrVVVI1ScmpRIwYjxwTqo+r1vTafV6FmtSrRXEak0ooB+8tjzR4v251m0llwSgUnUaAOrJtFMDoESrty9XxYi/wk0sMEBMoRKo7iRK8SiFxu285vQMoIDR0qdNN+rmbxxJlRFLi7u22OG1mDjP4bYb2uFVf+r0CZ+cyOS1oRD/cUM4cN5EA3bDhszqWOHEhBLIZh+qHdnmaFABwIwm9BxLZxAtn6fGvr379/Djy59Pv779+/jz69/Pv7///wAGQyjggAQWaOCBCCao4IIMNujggxBGKOGEFFZo4YUYZqjhhhx26OGHIIYo4ogklmjiiSimqOKKLLbo4oswxijjjDRKEQEAOw==" fade></iron-image>
+ </div>
+ </template>
+
+ <script>
+ var scope = document.querySelector('template[is=dom-bind]');
+
+ scope.preload = function(e) {
+ var img = document.querySelector('#' + e.target.getAttribute('target'));
+ img.src = './polymer.svg?' + Math.random();
+ e.target.textContent = 'Reload image';
+ };
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-image/demo/polymer.svg b/polymer_1.0.4/bower_components/iron-image/demo/polymer.svg
new file mode 100644
index 0000000..fbf8a7c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-image/demo/polymer.svg
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="416px" height="286px" viewBox="0 0 416 286" enable-background="new 0 0 416 286" xml:space="preserve">
+<g>
+ <g>
+ <polygon fill="#303F9F" points="84.157,143 42.878,214.5 84.157,286 125.436,214.5 "/>
+ <polygon fill="#3F51B5" points="331.842,0 290.561,71.5 331.842,143 373.121,71.5 "/>
+ <polygon fill="#7986CB" points="373.121,71.5 249.278,286 331.842,286 414.4,143 "/>
+ <polygon fill="#FF4081" points="249.278,0 84.157,286 166.721,286 331.842,0 "/>
+ <polygon fill="#536DFE" points="84.157,0 1.596,143 42.878,214.5 166.721,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.2" points="249.278,0 290.561,71.5 331.842,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.1" points="208,71.5 249.278,0 290.561,71.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="208,71.5 249.278,143 290.561,71.5 "/>
+ <polygon fill-opacity="0.1" points="166.721,143 208,71.5 249.278,143 "/>
+ <polygon fill-opacity="0.2" points="166.721,143 208,214.5 249.278,143 "/>
+ <polygon fill-opacity="0.3" points="125.438,214.5 166.721,143 208,214.5 "/>
+ <polygon fill-opacity="0.4" points="125.438,214.5 166.721,286 208,214.5 "/>
+ <polygon fill-opacity="0.5" points="84.157,286 125.438,214.5 166.721,286 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.2" points="84.157,0 125.438,71.5 166.721,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.1" points="42.878,71.5 84.157,0 125.438,71.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="42.878,71.5 84.157,143 125.438,71.5 "/>
+ <polygon fill-opacity="0.1" points="1.598,143 42.878,71.5 84.157,143 "/>
+ <polygon fill-opacity="0.2" points="1.598,143 42.878,214.5 84.157,143 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="125.438,214.5 84.157,143 42.878,214.5 "/>
+ <polygon fill-opacity="0.2" points="125.438,214.5 84.157,286 42.878,214.5 "/>
+ <polygon fill-opacity="0.2" points="373.121,71.5 331.842,0 290.561,71.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="373.121,71.5 331.842,143 290.561,71.5 "/>
+ <g>
+ <polygon fill="#FFFFFF" fill-opacity="0.2" points="331.842,143 373.121,71.5 414.4,143 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.1" points="331.842,143 373.121,214.5 414.4,143 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="290.561,214.5 331.842,143 373.121,214.5 "/>
+ <polygon fill-opacity="0.1" points="290.561,214.5 331.842,286 373.121,214.5 "/>
+ <polygon fill-opacity="0.2" points="249.278,286 290.561,214.5 331.842,286 "/>
+ </g>
+ </g>
+ <rect y="-65" fill="none" width="416" height="416"/>
+</g>
+<g display="none">
+ <g display="inline">
+ <polygon fill="#303F9F" points="84.157,143 42.878,214.5 84.157,286 166.721,286 "/>
+ <polygon fill="#3F51B5" points="331.842,0 249.278,0 331.842,143 373.121,71.5 "/>
+ <polygon fill="#7986CB" points="373.121,71.5 249.278,286 331.842,286 414.4,143 "/>
+ <polygon fill="#536DFE" points="84.157,0 1.596,143 42.878,214.5 166.721,0 "/>
+ <polygon fill-opacity="0.5" points="249.278,0 290.561,71.5 331.842,0 "/>
+ <polygon fill-opacity="0.5" points="84.157,286 125.438,214.5 166.721,286 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.2" points="84.157,0 125.438,71.5 166.721,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.1" points="42.878,71.5 84.157,0 125.438,71.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="42.878,71.5 84.157,143 125.438,71.5 "/>
+ <polygon fill-opacity="0.1" points="1.598,143 42.878,71.5 84.157,143 "/>
+ <polygon fill-opacity="0.2" points="1.598,143 42.878,214.5 84.157,143 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="125.438,214.5 84.157,143 42.878,214.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="373.121,71.5 331.842,143 290.561,71.5 "/>
+ <g>
+ <polygon fill="#FFFFFF" fill-opacity="0.2" points="331.842,143 373.121,71.5 414.4,143 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.1" points="331.842,143 373.121,214.5 414.4,143 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="290.561,214.5 331.842,143 373.121,214.5 "/>
+ <polygon fill-opacity="0.1" points="290.561,214.5 331.842,286 373.121,214.5 "/>
+ <polygon fill-opacity="0.2" points="249.278,286 290.561,214.5 331.842,286 "/>
+ </g>
+ <polygon fill-opacity="0.2" points="125.438,214.5 84.157,286 42.878,214.5 "/>
+ <polygon fill-opacity="0.2" points="373.121,71.5 331.842,0 290.561,71.5 "/>
+ </g>
+ <rect y="-65" display="inline" fill="none" width="416" height="416"/>
+</g>
+<g display="none">
+ <g display="inline">
+ <polygon fill="#FF4081" points="249.279,0 84.157,286 166.721,286 331.843,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.2" points="249.279,0 290.558,71.5 331.843,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.1" points="208,71.5 249.279,0 290.558,71.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="208,71.5 249.279,143 290.558,71.5 "/>
+ <polygon fill-opacity="0.2" points="166.721,143 208,214.5 249.279,143 "/>
+ <polygon fill-opacity="0.3" points="125.439,214.5 166.721,143 208,214.5 "/>
+ <polygon fill-opacity="0.4" points="125.439,214.5 166.721,286 208,214.5 "/>
+ <polygon fill-opacity="0.5" points="84.157,286 125.439,214.5 166.721,286 "/>
+ <polygon fill-opacity="0.1" points="166.721,143 208,71.5 249.279,143 "/>
+ </g>
+ <g display="inline">
+ <polygon fill="#FF4081" points="331.84,0 166.718,286 249.279,286 373.121,71.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.1" points="290.558,71.5 331.84,0 373.121,71.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="290.558,71.5 331.84,143 373.121,71.5 "/>
+ <polygon fill-opacity="0.2" points="249.279,143 290.558,214.5 331.84,143 "/>
+ <polygon fill-opacity="0.3" points="208,214.5 249.279,143 290.558,214.5 "/>
+ <polygon fill-opacity="0.4" points="208,214.5 249.279,286 290.558,214.5 "/>
+ <polygon fill-opacity="0.5" points="166.718,286 208,214.5 249.279,286 "/>
+ <polygon fill-opacity="0.1" points="249.279,143 290.558,71.5 331.84,143 "/>
+ </g>
+ <g display="inline">
+ <polygon fill="#FF4081" points="166.718,0 42.878,214.5 84.16,286 249.279,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.2" points="166.718,0 208,71.5 249.279,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.1" points="125.439,71.5 166.718,0 208,71.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="125.439,71.5 166.718,143 208,71.5 "/>
+ <polygon fill-opacity="0.2" points="84.16,143 125.439,214.5 166.718,143 "/>
+ <polygon fill-opacity="0.3" points="42.878,214.5 84.16,143 125.439,214.5 "/>
+ <polygon fill-opacity="0.4" points="42.878,214.5 84.16,286 125.439,214.5 "/>
+ <polygon fill-opacity="0.1" points="84.16,143 125.439,71.5 166.718,143 "/>
+ </g>
+ <rect y="-65" display="inline" fill="none" width="416" height="416"/>
+ <g display="inline">
+ <polygon fill="#303F9F" points="84.157,143 42.878,214.5 84.157,286 166.721,286 "/>
+ <polygon fill="#3F51B5" points="331.843,0 249.279,0 331.843,143 373.121,71.5 "/>
+ <polygon fill="#7986CB" points="373.121,71.5 249.279,286 331.843,286 414.4,143 "/>
+ <polygon fill="#536DFE" points="84.157,0 1.597,143 42.878,214.5 166.721,0 "/>
+ <polygon fill-opacity="0.5" points="249.279,0 290.558,71.5 331.843,0 "/>
+ <polygon fill-opacity="0.5" points="84.157,286 125.439,214.5 166.721,286 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.2" points="84.157,0 125.439,71.5 166.721,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.1" points="42.878,71.5 84.157,0 125.439,71.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="42.878,71.5 84.157,143 125.439,71.5 "/>
+ <polygon fill-opacity="0.1" points="1.6,143 42.878,71.5 84.157,143 "/>
+ <polygon fill-opacity="0.2" points="1.6,143 42.878,214.5 84.157,143 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="125.439,214.5 84.157,143 42.878,214.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="373.121,71.5 331.843,143 290.558,71.5 "/>
+ <g>
+ <polygon fill="#FFFFFF" fill-opacity="0.2" points="331.843,143 373.121,71.5 414.4,143 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.1" points="331.843,143 373.121,214.5 414.4,143 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="290.558,214.5 331.843,143 373.121,214.5 "/>
+ <polygon fill-opacity="0.1" points="290.558,214.5 331.843,286 373.121,214.5 "/>
+ <polygon fill-opacity="0.2" points="249.279,286 290.558,214.5 331.843,286 "/>
+ </g>
+ <polygon fill-opacity="0.2" points="125.439,214.5 84.157,286 42.878,214.5 "/>
+ <polygon fill-opacity="0.2" points="373.121,71.5 331.843,0 290.558,71.5 "/>
+ </g>
+</g>
+<g display="none">
+ <g display="inline">
+ <polygon fill="#9F499B" points="249.279,0 84.157,286 166.721,286 331.843,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.2" points="249.279,0 290.558,71.5 331.843,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.1" points="208,71.5 249.279,0 290.558,71.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="208,71.5 249.279,143 290.558,71.5 "/>
+ <polygon fill-opacity="0.2" points="166.721,143 208,214.5 249.279,143 "/>
+ <polygon fill-opacity="0.3" points="125.439,214.5 166.721,143 208,214.5 "/>
+ <polygon fill-opacity="0.4" points="125.439,214.5 166.721,286 208,214.5 "/>
+ <polygon fill-opacity="0.5" points="84.157,286 125.439,214.5 166.721,286 "/>
+ <polygon fill-opacity="0.1" points="166.721,143 208,71.5 249.279,143 "/>
+ </g>
+ <g display="inline">
+ <polygon fill="#9F499B" points="331.84,0 166.718,286 249.279,286 373.121,71.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.1" points="290.558,71.5 331.84,0 373.121,71.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="290.558,71.5 331.84,143 373.121,71.5 "/>
+ <polygon fill-opacity="0.2" points="249.279,143 290.558,214.5 331.84,143 "/>
+ <polygon fill-opacity="0.3" points="208,214.5 249.279,143 290.558,214.5 "/>
+ <polygon fill-opacity="0.4" points="208,214.5 249.279,286 290.558,214.5 "/>
+ <polygon fill-opacity="0.5" points="166.718,286 208,214.5 249.279,286 "/>
+ <polygon fill-opacity="0.1" points="249.279,143 290.558,71.5 331.84,143 "/>
+ </g>
+ <g display="inline">
+ <polygon fill="#9F499B" points="373.121,71.5 249.279,286 331.843,286 414.4,143 "/>
+ <polygon fill-opacity="0.2" points="331.843,143 373.121,214.5 414.4,143 "/>
+ <polygon fill-opacity="0.3" points="290.558,214.5 331.843,143 373.121,214.5 "/>
+ <polygon fill-opacity="0.4" points="290.558,214.5 331.843,286 373.121,214.5 "/>
+ <polygon fill-opacity="0.5" points="249.279,286 290.558,214.5 331.843,286 "/>
+ <polygon fill-opacity="0.1" points="331.843,143 373.121,71.5 414.4,143 "/>
+ </g>
+ <g display="inline">
+ <polygon fill="#9F499B" points="166.718,0 42.878,214.5 84.16,286 249.279,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.2" points="166.718,0 208,71.5 249.279,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.1" points="125.439,71.5 166.718,0 208,71.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="125.439,71.5 166.718,143 208,71.5 "/>
+ <polygon fill-opacity="0.2" points="84.16,143 125.439,214.5 166.718,143 "/>
+ <polygon fill-opacity="0.3" points="42.878,214.5 84.16,143 125.439,214.5 "/>
+ <polygon fill-opacity="0.4" points="42.878,214.5 84.16,286 125.439,214.5 "/>
+ <polygon fill-opacity="0.1" points="84.16,143 125.439,71.5 166.718,143 "/>
+ </g>
+ <g display="inline">
+ <polygon fill="#9F499B" points="84.157,0 1.6,143 42.878,214.5 166.721,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.2" points="84.157,0 125.439,71.5 166.721,0 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0.1" points="42.878,71.5 84.157,0 125.439,71.5 "/>
+ <polygon fill="#FFFFFF" fill-opacity="0" points="42.878,71.5 84.157,143 125.439,71.5 "/>
+ <polygon fill-opacity="0.2" points="1.6,143 42.878,214.5 84.157,143 "/>
+ <polygon fill-opacity="0.1" points="1.6,143 42.878,71.5 84.157,143 "/>
+ </g>
+ <rect y="-65" display="inline" fill="none" width="416" height="416"/>
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/iron-image/index.html b/polymer_1.0.4/bower_components/iron-image/index.html
new file mode 100644
index 0000000..b12d417
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-image/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <title>iron-image</title>
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-image/iron-image.html b/polymer_1.0.4/bower_components/iron-image/iron-image.html
new file mode 100644
index 0000000..7eba73f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-image/iron-image.html
@@ -0,0 +1,354 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+
+<!--
+`iron-image` is an element for displaying an image that provides useful sizing and
+preloading options not found on the standard `<img>` tag.
+
+The `sizing` option allows the image to be either cropped (`cover`) or
+letterboxed (`contain`) to fill a fixed user-size placed on the element.
+
+The `preload` option prevents the browser from rendering the image until the
+image is fully loaded. In the interim, either the element's CSS `background-color`
+can be be used as the placeholder, or the `placeholder` property can be
+set to a URL (preferably a data-URI, for instant rendering) for an
+placeholder image.
+
+The `fade` option (only valid when `preload` is set) will cause the placeholder
+image/color to be faded out once the image is rendered.
+
+Examples:
+
+ Basically identical to <img src="..."> tag:
+
+ <iron-image src="http://lorempixel.com/400/400"></iron-image>
+
+ Will letterbox the image to fit:
+
+ <iron-image style="width:400px; height:400px;" sizing="contain"
+ src="http://lorempixel.com/600/400"></iron-image>
+
+ Will crop the image to fit:
+
+ <iron-image style="width:400px; height:400px;" sizing="cover"
+ src="http://lorempixel.com/600/400"></iron-image>
+
+ Will show light-gray background until the image loads:
+
+ <iron-image style="width:400px; height:400px; background-color: lightgray;"
+ sizing="cover" preload src="http://lorempixel.com/600/400"></iron-image>
+
+ Will show a base-64 encoded placeholder image until the image loads:
+
+ <iron-image style="width:400px; height:400px;" placeholder="data:image/gif;base64,..."
+ sizing="cover" preload src="http://lorempixel.com/600/400"></iron-image>
+
+ Will fade the light-gray background out once the image is loaded:
+
+ <iron-image style="width:400px; height:400px; background-color: lightgray;"
+ sizing="cover" preload fade src="http://lorempixel.com/600/400"></iron-image>
+
+
+@group Iron Elements
+@element iron-image
+@demo demo/index.html
+-->
+
+<dom-module id="iron-image">
+
+ <style>
+
+ :host {
+ display: inline-block;
+ overflow: hidden;
+ position: relative;
+ }
+
+ :host([sizing]) #img {
+ display: none;
+ }
+
+ #placeholder {
+ background-color: inherit;
+ opacity: 1;
+ }
+
+ #placeholder.faded-out {
+ transition: opacity 0.5s linear;
+ opacity: 0;
+ }
+
+ </style>
+
+ <template>
+
+ <img id="img" role="none" hidden$="[[_computeImageVisibility(sizing)]]">
+ <div id="placeholder" hidden$="[[_computePlaceholderVisibility(fade,loaded,preload)]]" class$="[[_computePlaceholderClassName(fade,loaded,preload)]]"></div>
+ <content></content>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'iron-image',
+
+ properties: {
+ /**
+ * The URL of an image.
+ */
+ src: {
+ observer: '_srcChanged',
+ type: String,
+ value: ''
+ },
+
+ /**
+ * When true, the image is prevented from loading and any placeholder is
+ * shown. This may be useful when a binding to the src property is known to
+ * be invalid, to prevent 404 requests.
+ */
+ preventLoad: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Sets a sizing option for the image. Valid values are `contain` (full
+ * aspect ratio of the image is contained within the element and
+ * letterboxed) or `cover` (image is cropped in order to fully cover the
+ * bounds of the element), or `null` (default: image takes natural size).
+ */
+ sizing: {
+ type: String,
+ value: null
+ },
+
+ /**
+ * When a sizing option is uzed (`cover` or `contain`), this determines
+ * how the image is aligned within the element bounds.
+ */
+ position: {
+ type: String,
+ value: 'center'
+ },
+
+ /**
+ * When `true`, any change to the `src` property will cause the `placeholder`
+ * image to be shown until the
+ */
+ preload: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * This image will be used as a background/placeholder until the src image has
+ * loaded. Use of a data-URI for placeholder is encouraged for instant rendering.
+ */
+ placeholder: {
+ type: String,
+ value: null
+ },
+
+ /**
+ * When `preload` is true, setting `fade` to true will cause the image to
+ * fade into place.
+ */
+ fade: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Read-only value that is true when the image is loaded.
+ */
+ loaded: {
+ notify: true,
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Read-only value that tracks the loading state of the image when the `preload`
+ * option is used.
+ */
+ loading: {
+ notify: true,
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Can be used to set the width of image (e.g. via binding); size may also be
+ * set via CSS.
+ */
+ width: {
+ observer: '_widthChanged',
+ type: Number,
+ value: null
+ },
+
+ /**
+ * Can be used to set the height of image (e.g. via binding); size may also be
+ * set via CSS.
+ *
+ * @attribute height
+ * @type number
+ * @default null
+ */
+ height: {
+ observer: '_heightChanged',
+ type: Number,
+ value: null
+ },
+
+ _placeholderBackgroundUrl: {
+ type: String,
+ computed: '_computePlaceholderBackgroundUrl(preload,placeholder)',
+ observer: '_placeholderBackgroundUrlChanged'
+ },
+
+ requiresPreload: {
+ type: Boolean,
+ computed: '_computeRequiresPreload(preload,loaded)'
+ },
+
+ canLoad: {
+ type: Boolean,
+ computed: '_computeCanLoad(preventLoad, src)'
+ }
+
+ },
+
+ observers: [
+ '_transformChanged(sizing, position)',
+ '_loadBehaviorChanged(canLoad, preload, loaded)',
+ '_loadStateChanged(src, preload, loaded)',
+ ],
+
+ ready: function() {
+ if (!this.hasAttribute('role')) {
+ this.setAttribute('role', 'img');
+ }
+ },
+
+ _computeImageVisibility: function() {
+ return !!this.sizing;
+ },
+
+ _computePlaceholderVisibility: function() {
+ return !this.preload || (this.loaded && !this.fade);
+ },
+
+ _computePlaceholderClassName: function() {
+ if (!this.preload) {
+ return '';
+ }
+
+ var className = 'fit';
+ if (this.loaded && this.fade) {
+ className += ' faded-out';
+ }
+ return className;
+ },
+
+ _computePlaceholderBackgroundUrl: function() {
+ if (this.preload && this.placeholder) {
+ return 'url(' + this.placeholder + ')';
+ }
+
+ return null;
+ },
+
+ _computeRequiresPreload: function() {
+ return this.preload && !this.loaded;
+ },
+
+ _computeCanLoad: function() {
+ return Boolean(!this.preventLoad && this.src);
+ },
+
+ _widthChanged: function() {
+ this.style.width = isNaN(this.width) ? this.width : this.width + 'px';
+ },
+
+ _heightChanged: function() {
+ this.style.height = isNaN(this.height) ? this.height : this.height + 'px';
+ },
+
+ _srcChanged: function(newSrc, oldSrc) {
+ if (newSrc !== oldSrc) {
+ this.loaded = false;
+ }
+ },
+
+ _placeholderBackgroundUrlChanged: function() {
+ this.$.placeholder.style.backgroundImage =
+ this._placeholderBackgroundUrl;
+ },
+
+ _transformChanged: function() {
+ var placeholderStyle = this.$.placeholder.style;
+
+ this.style.backgroundSize =
+ placeholderStyle.backgroundSize = this.sizing;
+
+ this.style.backgroundPosition =
+ placeholderStyle.backgroundPosition =
+ this.sizing ? this.position : '';
+
+ this.style.backgroundRepeat =
+ placeholderStyle.backgroundRepeat =
+ this.sizing ? 'no-repeat' : '';
+ },
+
+ _loadBehaviorChanged: function() {
+ var img;
+
+ if (!this.canLoad) {
+ return;
+ }
+
+ if (this.requiresPreload) {
+ img = new Image();
+ img.src = this.src;
+
+ this.loading = true;
+
+ img.onload = function() {
+ this.loading = false;
+ this.loaded = true;
+ }.bind(this);
+ } else {
+ this.loaded = true;
+ }
+ },
+
+ _loadStateChanged: function() {
+ if (this.requiresPreload) {
+ return;
+ }
+
+ if (this.sizing) {
+ this.style.backgroundImage = this.src ? 'url(' + this.src + ')': '';
+ } else {
+ this.$.img.src = this.src || '';
+ }
+ }
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-image/test/index.html b/polymer_1.0.4/bower_components/iron-image/test/index.html
new file mode 100644
index 0000000..fa31e17
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-image/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+ <meta charset="utf-8">
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ </head>
+ <body>
+ <script>
+ WCT.loadSuites([
+ 'iron-image.html'
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-image/test/iron-image.html b/polymer_1.0.4/bower_components/iron-image/test/iron-image.html
new file mode 100644
index 0000000..0e06fe3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-image/test/iron-image.html
@@ -0,0 +1,78 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>iron-image</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-image.html">
+ </head>
+ <body>
+ <test-fixture id="TrivialImage">
+ <template>
+ <iron-image></iron-image>
+ </template>
+ </test-fixture>
+ <script>
+ suite('<iron-image>', function() {
+ function randomImageUrl () {
+ return '../demo/polymer.svg?' + Math.random();
+ }
+
+ var image;
+
+ suite('basic behavior', function() {
+ setup(function() {
+ image = fixture('TrivialImage');
+ });
+
+ test('can load images given a src', function(done) {
+ image.addEventListener('loaded-changed', function onLoadedChanged() {
+ image.removeEventListener('loaded-changed', onLoadedChanged);
+
+ try {
+ expect(image.loaded).to.be.eql(true);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ });
+ image.src = randomImageUrl();
+ });
+
+ test('will reload images when src changes', function(done) {
+ var loadCount = 0;
+
+ image.addEventListener('loaded-changed', function onLoadedChanged() {
+ if (image.loaded === true) {
+ loadCount++;
+
+ if (loadCount === 2) {
+ done();
+ } else {
+ image.src = randomImageUrl();
+ image.removeEventListener('loaded-changed', onLoadedChanged);
+ }
+ }
+ });
+
+ image.src = randomImageUrl();
+ });
+ });
+ });
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-input/.bower.json b/polymer_1.0.4/bower_components/iron-input/.bower.json
new file mode 100644
index 0000000..1383a44
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-input/.bower.json
@@ -0,0 +1,45 @@
+{
+ "name": "iron-input",
+ "version": "1.0.3",
+ "description": "An input element with data binding",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "input"
+ ],
+ "main": [
+ "iron-input.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-input",
+ "ignore": [],
+ "dependencies": {
+ "iron-validatable-behavior": "PolymerElements/iron-validatable-behavior#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.3",
+ "commit": "edb505f41d67120cb505deedb92aa69e90078d2f"
+ },
+ "_source": "git://github.com/PolymerElements/iron-input.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-input"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-input/.gitignore b/polymer_1.0.4/bower_components/iron-input/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-input/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-input/README.md b/polymer_1.0.4/bower_components/iron-input/README.md
new file mode 100644
index 0000000..05a74b7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-input/README.md
@@ -0,0 +1,16 @@
+# iron-input
+
+An input with data binding.
+
+By default you can only get notified of changes to an `input`'s `value` due to user input:
+
+```html
+<input value="{{myValue::input}}">
+```
+
+`iron-input` adds the `bind-value` property that mirrors the `value` property, and can be used
+for two-way data binding. `bind-value` will notify if it is changed either by user input or by script.
+
+```html
+<input is="iron-input" bind-value="{{myValue}}">
+```
diff --git a/polymer_1.0.4/bower_components/iron-input/bower.json b/polymer_1.0.4/bower_components/iron-input/bower.json
new file mode 100644
index 0000000..c4c8951
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-input/bower.json
@@ -0,0 +1,36 @@
+{
+ "name": "iron-input",
+ "version": "1.0.3",
+ "description": "An input element with data binding",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "input"
+ ],
+ "main": [
+ "iron-input.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-input",
+ "ignore": [],
+ "dependencies": {
+ "iron-validatable-behavior": "PolymerElements/iron-validatable-behavior#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-input/demo/index.html b/polymer_1.0.4/bower_components/iron-input/demo/index.html
new file mode 100644
index 0000000..8d4d879
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-input/demo/index.html
@@ -0,0 +1,87 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>iron-input demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../iron-input.html">
+
+ <link href="../../paper-styles/paper-styles.html" rel="import">
+ <link href="../../paper-styles/demo-pages.html" rel="import">
+
+ <style is="custom-style">
+
+ .vertical-section {
+ @apply(--paper-font-body1);
+
+ line-height: 40px;
+ }
+
+ code {
+ color: var(--google-grey-700);
+ }
+
+ input[is=iron-input] {
+ width: 100%;
+ box-sizing: border-box;
+ }
+
+ input, button {
+ font-size: 20px;
+ padding: 0.2em;
+ }
+
+ </style>
+</head>
+<body>
+
+ <div class="vertical-section vertical-section-container centered">
+ <template is="dom-bind">
+ <p>
+ <input is="iron-input" bind-value="{{bindValue}}" value="{{value::input}}">
+ <br>
+ bind to <code>bind-value</code>: <b>[[bindValue]]</b>
+ <br>
+ bind to <code>value::input</code>: <b>{{value}}</b>
+ </p>
+
+ <p on-click="setValue">
+ set bind-value to: <input> <button is="paper-button" value="bindValue">set</button>
+ <br>
+ set value to: <input> <button value="value">set</button>
+ </p>
+ </template>
+ <p>only allows these characters:
+ <code>!@#0123456789</code></p>
+ <input is="iron-input" allowed-pattern="[!@#0-9]" prevent-invalid-input>
+
+ </div>
+
+ <script>
+ var scope = document.querySelector('template[is=dom-bind]');
+
+ scope.setValue = function(event) {
+ if (!(event.target instanceof HTMLButtonElement)) {
+ return;
+ }
+ document.querySelector('input[is=iron-input]')[event.target.value] = event.target.previousElementSibling.value;
+ }
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-input/hero.svg b/polymer_1.0.4/bower_components/iron-input/hero.svg
new file mode 100755
index 0000000..146ffea
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-input/hero.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <rect x="49" y="53" width="2" height="18"/>
+ <path d="M188,78H37V44h151V78z M39,76h147V46H39V76z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/iron-input/index.html b/polymer_1.0.4/bower_components/iron-input/index.html
new file mode 100644
index 0000000..ca0dac0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-input/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>iron-input</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-input/iron-input.html b/polymer_1.0.4/bower_components/iron-input/iron-input.html
new file mode 100644
index 0000000..3d8cccb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-input/iron-input.html
@@ -0,0 +1,237 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-validatable-behavior/iron-validatable-behavior.html">
+
+<script>
+
+/*
+`<iron-input>` adds two-way binding and custom validators using `Polymer.IronValidatorBehavior`
+to `<input>`.
+
+### Two-way binding
+
+By default you can only get notified of changes to an `input`'s `value` due to user input:
+
+ <input value="{{myValue::input}}">
+
+`iron-input` adds the `bind-value` property that mirrors the `value` property, and can be used
+for two-way data binding. `bind-value` will notify if it is changed either by user input or by script.
+
+ <input is="iron-input" bind-value="{{myValue}}">
+
+### Custom validators
+
+You can use custom validators that implement `Polymer.IronValidatorBehavior` with `<iron-input>`.
+
+ <input is="iron-input" validator="my-custom-validator">
+
+### Stopping invalid input
+
+It may be desirable to only allow users to enter certain characters. You can use the
+`prevent-invalid-input` and `allowed-pattern` attributes together to accomplish this. This feature
+is separate from validation, and `allowed-pattern` does not affect how the input is validated.
+
+ <!-- only allow characters that match [0-9] -->
+ <input is="iron-input" prevent-invaild-input allowed-pattern="[0-9]">
+
+@hero hero.svg
+@demo demo/index.html
+*/
+
+ Polymer({
+
+ is: 'iron-input',
+
+ extends: 'input',
+
+ behaviors: [
+ Polymer.IronValidatableBehavior
+ ],
+
+ properties: {
+
+ /**
+ * Use this property instead of `value` for two-way data binding.
+ */
+ bindValue: {
+ observer: '_bindValueChanged',
+ type: String
+ },
+
+ /**
+ * Set to true to prevent the user from entering invalid input. The new input characters are
+ * matched with `allowedPattern` if it is set, otherwise it will use the `pattern` attribute if
+ * set, or the `type` attribute (only supported for `type=number`).
+ */
+ preventInvalidInput: {
+ type: Boolean
+ },
+
+ /**
+ * Regular expression to match valid input characters.
+ */
+ allowedPattern: {
+ type: String
+ },
+
+ _previousValidInput: {
+ type: String,
+ value: ''
+ },
+
+ _patternAlreadyChecked: {
+ type: Boolean,
+ value: false
+ }
+
+ },
+
+ listeners: {
+ 'input': '_onInput',
+ 'keypress': '_onKeypress'
+ },
+
+ get _patternRegExp() {
+ var pattern;
+ if (this.allowedPattern) {
+ pattern = new RegExp(this.allowedPattern);
+ } else if (this.pattern) {
+ pattern = new RegExp(this.pattern);
+ } else {
+ switch (this.type) {
+ case 'number':
+ pattern = /[0-9.,e-]/;
+ break;
+ }
+ }
+ return pattern;
+ },
+
+ ready: function() {
+ this.bindValue = this.value;
+ },
+
+ _bindValueChanged: function() {
+ if (this.value !== this.bindValue) {
+ this.value = !this.bindValue ? '' : this.bindValue;
+ }
+ // manually notify because we don't want to notify until after setting value
+ this.fire('bind-value-changed', {value: this.bindValue});
+ },
+
+ _onInput: function() {
+ // Need to validate each of the characters pasted if they haven't
+ // been validated inside `_onKeypress` already.
+ if (this.preventInvalidInput && !this._patternAlreadyChecked) {
+ var valid = this._checkPatternValidity();
+ if (!valid) {
+ this.value = this._previousValidInput;
+ }
+ }
+
+ this.bindValue = this.value;
+ this._previousValidInput = this.value;
+ this._patternAlreadyChecked = false;
+ },
+
+ _isPrintable: function(event) {
+ // What a control/printable character is varies wildly based on the browser.
+ // - most control characters (arrows, backspace) do not send a `keypress` event
+ // in Chrome, but the *do* on Firefox
+ // - in Firefox, when they do send a `keypress` event, control chars have
+ // a charCode = 0, keyCode = xx (for ex. 40 for down arrow)
+ // - printable characters always send a keypress event.
+ // - in Firefox, printable chars always have a keyCode = 0. In Chrome, the keyCode
+ // always matches the charCode.
+ // None of this makes any sense.
+
+ var nonPrintable =
+ (event.keyCode == 8) || // backspace
+ (event.keyCode == 19) || // pause
+ (event.keyCode == 20) || // caps lock
+ (event.keyCode == 27) || // escape
+ (event.keyCode == 45) || // insert
+ (event.keyCode == 46) || // delete
+ (event.keyCode == 144) || // num lock
+ (event.keyCode == 145) || // scroll lock
+ (event.keyCode > 32 && event.keyCode < 41) || // page up/down, end, home, arrows
+ (event.keyCode > 111 && event.keyCode < 124); // fn keys
+
+ return !(event.charCode == 0 && nonPrintable);
+ },
+
+ _onKeypress: function(event) {
+ if (!this.preventInvalidInput && this.type !== 'number') {
+ return;
+ }
+ var regexp = this._patternRegExp;
+ if (!regexp) {
+ return;
+ }
+
+ // Handle special keys and backspace
+ if (event.metaKey || event.ctrlKey || event.altKey)
+ return;
+
+ // Check the pattern either here or in `_onInput`, but not in both.
+ this._patternAlreadyChecked = true;
+
+ var thisChar = String.fromCharCode(event.charCode);
+ if (this._isPrintable(event) && !regexp.test(thisChar)) {
+ event.preventDefault();
+ }
+ },
+
+ _checkPatternValidity: function() {
+ var regexp = this._patternRegExp;
+ if (!regexp) {
+ return true;
+ }
+ for (var i = 0; i < this.value.length; i++) {
+ if (!regexp.test(this.value[i])) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /**
+ * Returns true if `value` is valid. The validator provided in `validator` will be used first,
+ * then any constraints.
+ * @return {boolean} True if the value is valid.
+ */
+ validate: function() {
+ // Empty, non-required input is valid.
+ if (!this.required && this.value == '') {
+ this.invalid = false;
+ return true;
+ }
+
+ var valid;
+ if (this.hasValidator()) {
+ valid = Polymer.IronValidatableBehavior.validate.call(this, this.value);
+ } else {
+ this.invalid = !this.validity.valid;
+ valid = this.validity.valid;
+ }
+ this.fire('iron-input-validate');
+ return valid;
+ }
+
+ });
+
+ /*
+ The `iron-input-validate` event is fired whenever `validate()` is called.
+ @event iron-input-validate
+ */
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-input/test/index.html b/polymer_1.0.4/bower_components/iron-input/test/index.html
new file mode 100644
index 0000000..839cc3f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-input/test/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>iron-input ests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'iron-input.html',
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-input/test/iron-input.html b/polymer_1.0.4/bower_components/iron-input/test/iron-input.html
new file mode 100644
index 0000000..b0ccb8f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-input/test/iron-input.html
@@ -0,0 +1,139 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>iron-input tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-input.html">
+ <link rel="import" href="letters-only.html">
+
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <input is="iron-input">
+ </template>
+ </test-fixture>
+
+ <test-fixture id="has-value">
+ <template>
+ <input is="iron-input" value="foobar">
+ </template>
+ </test-fixture>
+
+ <test-fixture id="has-bind-value">
+ <template>
+ <input is="iron-input" bind-value="foobar">
+ </template>
+ </test-fixture>
+
+ <test-fixture id="prevent-invalid-input">
+ <template>
+ <input is="iron-input" prevent-invalid-input pattern="[0-9]">
+ </template>
+ </test-fixture>
+
+ <test-fixture id="prevent-invalid-input-has-value">
+ <template>
+ <input is="iron-input" prevent-invalid-input pattern="[0-9]*" value="foobar">
+ </template>
+ </test-fixture>
+
+ <test-fixture id="prevent-invalid-input-has-bind-value">
+ <template>
+ <input is="iron-input" prevent-invalid-input pattern="[0-9]*" bind-value="foobar">
+ </template>
+ </test-fixture>
+
+ <test-fixture id="has-validator">
+ <template>
+ <letters-only></letters-only>
+ <input is="iron-input" validator="letters-only" pattern="[0-9]*">
+ </template>
+ </test-fixture>
+
+ <template is="dom-bind" id="bind-to-object">
+ <input is="iron-input" id="input" bind-value="{{foo}}">
+ </template>
+
+ <script>
+
+ suite('basic', function() {
+
+ test('setting bindValue sets value', function() {
+ var input = fixture('basic');
+ input.bindValue = 'foobar';
+ assert.equal(input.value, input.bindValue, 'value equals to bindValue');
+ });
+
+ test('changing the input triggers an event', function(done) {
+ var input = fixture('basic');
+
+ input.addEventListener('bind-value-changed', function(value) {
+ assert.equal(input.value, input.bindValue, 'value equals to bindValue');
+ done();
+ });
+
+ input.value = "foo";
+ input._onInput();
+ });
+
+ test('default value sets bindValue', function() {
+ var input = fixture('has-value');
+ assert.equal(input.bindValue, input.value, 'bindValue equals value');
+ });
+
+ test('default bindValue sets value', function() {
+ var input = fixture('has-bind-value');
+ assert.equal(input.value, input.bindValue, 'value equals to bindValue');
+ });
+
+ test('set bindValue to undefined', function() {
+ var scope = document.getElementById('bind-to-object');
+ scope.foo = undefined;
+ assert.ok(!scope.$.input.bindValue, 'bindValue is falsy');
+ assert.ok(!scope.$.input.value, 'value is falsy');
+ });
+
+ test('validator used instead of constraints api if provided', function() {
+ var input = fixture('has-validator')[1];
+ input.value = '123';
+ input.validate();
+ assert.isTrue(input.invalid, 'input is invalid');
+ });
+
+ test('prevent invalid input works in _onInput', function() {
+ var input = fixture('prevent-invalid-input');
+ input.value = '123';
+ input._onInput();
+ assert.equal(input.bindValue, '123');
+
+ input.value = '123foo';
+ input._onInput();
+ assert.equal(input.bindValue, '123');
+ });
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-input/test/letters-only.html b/polymer_1.0.4/bower_components/iron-input/test/letters-only.html
new file mode 100644
index 0000000..bfc301c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-input/test/letters-only.html
@@ -0,0 +1,30 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../../iron-validator-behavior/iron-validator-behavior.html">
+
+<script>
+
+ Polymer({
+
+ is: 'letters-only',
+
+ behaviors: [
+ Polymer.IronValidatorBehavior
+ ],
+
+ validate: function(value) {
+ return !value || value.match(/^[a-zA-Z]*$/) !== null;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-jsonp-library/.bower.json b/polymer_1.0.4/bower_components/iron-jsonp-library/.bower.json
new file mode 100644
index 0000000..4772208
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-jsonp-library/.bower.json
@@ -0,0 +1,44 @@
+{
+ "name": "iron-jsonp-library",
+ "version": "1.0.2",
+ "description": "Loads jsonp libraries",
+ "authors": [
+ "Aleks Totic <a@totic.org>",
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-component",
+ "polymer",
+ "behavior"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-jsonp-library.git"
+ },
+ "main": "iron-jsonp-library.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-jsonp-library/",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.2",
+ "paper-spinner": "PolymerElements/paper-spinner#^1.0.1"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "0fe9e824e856c6f611305ecbbc8c030c87972111"
+ },
+ "_source": "git://github.com/PolymerElements/iron-jsonp-library.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-jsonp-library"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-jsonp-library/README.md b/polymer_1.0.4/bower_components/iron-jsonp-library/README.md
new file mode 100644
index 0000000..d1b3206
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-jsonp-library/README.md
@@ -0,0 +1,10 @@
+# iron-jsonp-library
+
+`Polymer.IronJsonpLibraryBehavior` loads a jsonp library.
+Multiple components can request same library, only one copy will load.
+
+Some libraries require a specific global function be defined.
+If this is the case, specify the `callbackName` property.
+
+You should use an HTML Import to load library dependencies
+when possible instead of using this element.
diff --git a/polymer_1.0.4/bower_components/iron-jsonp-library/bower.json b/polymer_1.0.4/bower_components/iron-jsonp-library/bower.json
new file mode 100644
index 0000000..b40c1a0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-jsonp-library/bower.json
@@ -0,0 +1,35 @@
+{
+ "name": "iron-jsonp-library",
+ "version": "1.0.2",
+ "description": "Loads jsonp libraries",
+ "authors": [
+ "Aleks Totic <a@totic.org>",
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-component",
+ "polymer",
+ "behavior"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-jsonp-library.git"
+ },
+ "main": "iron-jsonp-library.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-jsonp-library/",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.2",
+ "paper-spinner": "PolymerElements/paper-spinner#^1.0.1"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-jsonp-library/demo/index.html b/polymer_1.0.4/bower_components/iron-jsonp-library/demo/index.html
new file mode 100644
index 0000000..764af63
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-jsonp-library/demo/index.html
@@ -0,0 +1,89 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>iron-jsonp-library Demo</title>
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../../paper-spinner/paper-spinner.html">
+ <link rel="import" href="../iron-jsonp-library.html">
+ <style is="custom-style">
+
+ .loading {
+ color: var(--google-grey-500);
+ }
+
+ .success {
+ color: var(--paper-green-800);
+ }
+
+ .failure {
+ color: var(--paper-red-800);
+ }
+
+ paper-spinner {
+ --paper-spinner-layer-1-color: var(--google-grey-500);
+ --paper-spinner-layer-2-color: var(--google-grey-500);
+ --paper-spinner-layer-3-color: var(--google-grey-500);
+ --paper-spinner-layer-4-color: var(--google-grey-500);
+ }
+ </style>
+ </head>
+ <body>
+
+ <div class="vertical-section vertical-section-container centered">
+ <h1><iron-jsonp-library></h1>
+ <template is="dom-bind">
+ <h3>Good loader</h3>
+ <iron-jsonp-library
+ library-url="https://apis.google.com/js/plusone.js?onload=%%callback%%"
+ notify-event="api-load"
+ library-loaded="{{loaded}}"
+ library-error-message="{{errorMessage}}"></iron-jsonp-library>
+ <template is="dom-if" if="{{loaded}}">
+ <p class="success">The <code>Google+ API</code> has been loaded</p>
+ </template>
+ <template is="dom-if" if="{{!loaded}}">
+ <template is="dom-if" if="{{errorMessage}}">
+ <p class="failure">{{errorMessage}}</p>
+ </template>
+ <template is="dom-if" if="{{!errorMessage}}">
+ <p class="loading">Loading...</p>
+ </template>
+ </template>
+ </template>
+ <hr>
+ <template is="dom-bind">
+ <h3>Bad loader</h3>
+ <iron-jsonp-library
+ library-url="https://badapis.google.com/js/plusone.js?onload=%%callback%%"
+ notify-event="api-load"
+ library-loaded="{{loaded}}"
+ library-error-message="{{errorMessage}}"></iron-jsonp-library>
+ <template is="dom-if" if="{{loaded}}">
+ <p><code>badapis</code> has been loaded</p>
+ </template>
+ <template is="dom-if" if="{{!loaded}}">
+ <template is="dom-if" if="{{errorMessage}}">
+ <p class="failure">{{errorMessage}}</p>
+ </template>
+ <template is="dom-if" if="{{!errorMessage}}">
+ <p class="loading">Loading...</p>
+ </template>
+ </template>
+ </template>
+ </div>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-jsonp-library/hero.svg b/polymer_1.0.4/bower_components/iron-jsonp-library/hero.svg
new file mode 100755
index 0000000..d6c1c13
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-jsonp-library/hero.svg
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <circle cx="112" cy="36" r="4"/>
+ <circle cx="112" cy="90" r="4"/>
+ <circle cx="91" cy="98" r="4"/>
+ <circle cx="91" cy="29" r="4"/>
+ <circle cx="133" cy="29" r="4"/>
+ <circle cx="133" cy="97" r="4"/>
+ <circle cx="56" cy="63" r="4"/>
+ <circle cx="168" cy="63" r="4"/>
+ <circle cx="99" cy="63" r="4"/>
+ <circle cx="125" cy="63" r="4"/>
+ <path d="M90.8,98.5c-19.6,0-35.5-15.9-35.5-35.5s15.9-35.5,35.5-35.5s35.5,15.9,35.5,35.5S110.3,98.5,90.8,98.5z M90.8,29.5
+ c-18.5,0-33.5,15-33.5,33.5s15,33.5,33.5,33.5s33.5-15,33.5-33.5S109.2,29.5,90.8,29.5z"/>
+ <path d="M133.2,98.5c-19.6,0-35.5-15.9-35.5-35.5s15.9-35.5,35.5-35.5s35.5,15.9,35.5,35.5S152.8,98.5,133.2,98.5z M133.2,29.5
+ c-18.5,0-33.5,15-33.5,33.5s15,33.5,33.5,33.5s33.5-15,33.5-33.5S151.7,29.5,133.2,29.5z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/iron-jsonp-library/index.html b/polymer_1.0.4/bower_components/iron-jsonp-library/index.html
new file mode 100644
index 0000000..487bb5c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-jsonp-library/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-jsonp-library/iron-jsonp-library.html b/polymer_1.0.4/bower_components/iron-jsonp-library/iron-jsonp-library.html
new file mode 100644
index 0000000..63c60a3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-jsonp-library/iron-jsonp-library.html
@@ -0,0 +1,259 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+(function() {
+ "use strict";
+ /**
+ `Polymer.IronJsonpLibraryBehavior` loads a jsonp library.
+ Multiple components can request same library, only one copy will load.
+
+ Some libraries require a specific global function be defined.
+ If this is the case, specify the `callbackName` property.
+
+ You should use an HTML Import to load library dependencies
+ when possible instead of using this element.
+
+ @hero hero.svg
+ @demo demo/index.html
+ @polymerBehavior
+ */
+ Polymer.IronJsonpLibraryBehavior = {
+
+ properties: {
+ /**
+ * True if library has been successfully loaded
+ */
+ libraryLoaded: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ readOnly: true
+ },
+ /**
+ * Not null if library has failed to load
+ */
+ libraryErrorMessage: {
+ type: String,
+ value: null,
+ notify: true,
+ readOnly: true
+ }
+ // Following properties are to be set by behavior users
+ /**
+ * Library url. Must contain string `%%callback_name%%`.
+ *
+ * `%%callback_name%%` is a placeholder for jsonp wrapper function name
+ *
+ * Ex: https://maps.googleapis.com/maps/api/js?callback=%%callback%%
+ * @property libraryUrl
+ */
+ /**
+ * Set if library requires specific callback name.
+ * Name will be automatically generated if not set.
+ * @property callbackName
+ */
+ /**
+ * name of event to be emitted when library loads. Standard is `api-load`
+ * @property notifyEvent
+ */
+ /**
+ * event with name specified in `notifyEvent` attribute
+ * will fire upon successful load2
+ * @event `notifyEvent`
+ */
+ },
+
+ _libraryLoadCallback: function(err, result) {
+ if (err) {
+ console.warn("Library load failed:", err.message);
+ this._setLibraryErrorMessage(err.message);
+ }
+ else {
+ this._setLibraryErrorMessage(null);
+ this._setLibraryLoaded(true);
+ if (this.notifyEvent)
+ this.fire( this.notifyEvent, result);
+ }
+ },
+
+ /** loads the library, and fires this.notifyEvent upon completion */
+ _loadLibrary: function() {
+ LoaderMap.require(
+ this.libraryUrl,
+ this._libraryLoadCallback.bind(this),
+ this.callbackName
+ );
+ },
+
+ ready: function() {
+ this._loadLibrary();
+ }
+ };
+
+ /**
+ * LoaderMap keeps track of all Loaders
+ */
+ var LoaderMap = {
+ apiMap: {}, // { hash -> Loader }
+
+ /**
+ * @param {Function} notifyCallback loaded callback fn(result)
+ * @param {string} jsonpCallbackName name of jsonpcallback. If API does not provide it, leave empty. Optional.
+ */
+ require: function(url, notifyCallback, jsonpCallbackName) {
+
+ // make hashable string form url
+ var name = this.nameFromUrl(url);
+
+ // create a loader as needed
+ if (!this.apiMap[name])
+ this.apiMap[name] = new Loader(name, url, jsonpCallbackName);
+
+ // ask for notification
+ this.apiMap[name].requestNotify(notifyCallback);
+ },
+
+ nameFromUrl: function(url) {
+ return url.replace(/[\:\/\%\?\&\.\=\-\,]/g, '_') + '_api';
+ }
+ };
+
+ /** @constructor */
+ var Loader = function(name, url, callbackName) {
+ this.notifiers = []; // array of notifyFn [ notifyFn* ]
+
+ // callback is specified either as callback name
+ // or computed dynamically if url has callbackMacro in it
+ if (!callbackName) {
+ if (url.indexOf(this.callbackMacro) >= 0) {
+ callbackName = name + '_loaded';
+ url = url.replace(this.callbackMacro, callbackName);
+ } else {
+ this.error = new Error('IronJsonpLibraryBehavior a %%callback_name%% parameter is required in libraryUrl');
+ // TODO(sjmiles): we should probably fallback to listening to script.load
+ return;
+ }
+ }
+ this.callbackName = callbackName;
+ window[this.callbackName] = this.success.bind(this);
+ this.addScript(url);
+ };
+
+ Loader.prototype = {
+
+ callbackMacro: '%%callback%%',
+ loaded: false,
+
+ addScript: function(src) {
+ var script = document.createElement('script');
+ script.src = src;
+ script.onerror = this.handleError.bind(this);
+ var s = document.querySelector('script') || document.body;
+ s.parentNode.insertBefore(script, s);
+ this.script = script;
+ },
+
+ removeScript: function() {
+ if (this.script.parentNode) {
+ this.script.parentNode.removeChild(this.script);
+ }
+ this.script = null;
+ },
+
+ handleError: function(ev) {
+ this.error = new Error("Library failed to load");
+ this.notifyAll();
+ this.cleanup();
+ },
+
+ success: function() {
+ this.loaded = true;
+ this.result = Array.prototype.slice.call(arguments);
+ this.notifyAll();
+ this.cleanup();
+ },
+
+ cleanup: function() {
+ delete window[this.callbackName];
+ },
+
+ notifyAll: function() {
+ this.notifiers.forEach( function(notifyCallback) {
+ notifyCallback(this.error, this.result);
+ }.bind(this));
+ this.notifiers = [];
+ },
+
+ requestNotify: function(notifyCallback) {
+ if (this.loaded || this.error) {
+ notifyCallback( this.error, this.result);
+ } else {
+ this.notifiers.push(notifyCallback);
+ }
+ }
+ };
+})();
+</script>
+
+<!--
+ Loads specified jsonp library.
+
+ Example:
+
+ <iron-jsonp-library
+ library-url="https://apis.google.com/js/plusone.js?onload=%%callback%%"
+ notify-event="api-load"
+ library-loaded="{{loaded}}"></iron-jsonp-library>
+
+ Will emit 'api-load' event when loaded, and set 'loaded' to true
+
+ Implemented by Polymer.IronJsonpLibraryBehavior. Use it
+ to create specific library loader elements.
+
+ @demo
+-->
+<script>
+ Polymer({
+
+ is: 'iron-jsonp-library',
+
+ behaviors: [ Polymer.IronJsonpLibraryBehavior ],
+
+ properties: {
+ /**
+ * Library url. Must contain string `%%callback_name%%`.
+ *
+ * `%%callback_name%%` is a placeholder for jsonp wrapper function name
+ *
+ * Ex: https://maps.googleapis.com/maps/api/js?callback=%%callback%%
+ */
+ libraryUrl: String,
+ /**
+ * Set if library requires specific callback name.
+ * Name will be automatically generated if not set.
+ */
+ callbackName: String,
+ /**
+ * event with name specified in 'notifyEvent' attribute
+ * will fire upon successful load
+ */
+ notifyEvent: String
+ /**
+ * event with name specified in 'notifyEvent' attribute
+ * will fire upon successful load
+ * @event `notifyEvent`
+ */
+
+ }
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-localstorage/.bower.json b/polymer_1.0.4/bower_components/iron-localstorage/.bower.json
new file mode 100644
index 0000000..2de9f2c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-localstorage/.bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "iron-localstorage",
+ "version": "1.0.3",
+ "description": "Provides access to local storage",
+ "keywords": [
+ "web-component",
+ "polymer",
+ "storage"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-localstorage.git"
+ },
+ "main": "iron-localstorage.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-localstorage/",
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.2",
+ "paper-checkbox": "PolymerElements/paper-checkbox#^1.0.1"
+ },
+ "_release": "1.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.3",
+ "commit": "8bf2b108050b61c337270ecc73565ab5b17a6c84"
+ },
+ "_source": "git://github.com/PolymerElements/iron-localstorage.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-localstorage"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-localstorage/.gitignore b/polymer_1.0.4/bower_components/iron-localstorage/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-localstorage/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-localstorage/README.md b/polymer_1.0.4/bower_components/iron-localstorage/README.md
new file mode 100644
index 0000000..f3e1acd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-localstorage/README.md
@@ -0,0 +1,13 @@
+iron-localstorage
+=================
+
+Element access to localStorage. The "name" property
+is the key to the data ("value" property) stored in localStorage.
+
+`iron-localstorage` automatically saves the value to localStorage when
+value is changed. Note that if value is an object auto-save will be
+triggered only when value is a different instance.
+
+```html
+<iron-localstorage name="my-app-storage" value="{{value}}"></iron-localstorage>
+```
diff --git a/polymer_1.0.4/bower_components/iron-localstorage/bower.json b/polymer_1.0.4/bower_components/iron-localstorage/bower.json
new file mode 100644
index 0000000..2b2f65d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-localstorage/bower.json
@@ -0,0 +1,28 @@
+{
+ "name": "iron-localstorage",
+ "version": "1.0.3",
+ "description": "Provides access to local storage",
+ "keywords": [
+ "web-component",
+ "polymer",
+ "storage"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-localstorage.git"
+ },
+ "main": "iron-localstorage.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-localstorage/",
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.2",
+ "paper-checkbox": "PolymerElements/paper-checkbox#^1.0.1"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-localstorage/demo/index.html b/polymer_1.0.4/bower_components/iron-localstorage/demo/index.html
new file mode 100644
index 0000000..abf5008
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-localstorage/demo/index.html
@@ -0,0 +1,62 @@
+
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>iron-localstorage</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../../paper-checkbox/paper-checkbox.html">
+
+ <link rel="import" href="../iron-localstorage.html">
+ <style is="custom-style">
+ input {
+ padding: 0.4em;
+ font-size: 16px;
+ margin: 15px 0;
+ }
+ </style>
+</head>
+<body>
+
+ <div class="vertical-section vertical-section-container centered">
+
+ <template is="dom-bind">
+ <iron-localstorage
+ name="polymer-localstorage-x-test1"
+ value="{{value}}"
+ on-iron-localstorage-load-empty="initializeDefaultValue"
+ ></iron-localstorage>
+ <p>Form element below will be kept in sync with <code>localStorage</code>.</p>
+ <p>Demo source also shows how to initialize storage to default value</p>
+ <p>If you open another window with this test, changes in one window will propagate to
+ the other immediately.</p>
+ <p>Name: <input value="{{value.name::change}}" placeholder="Enter words"></p>
+ <paper-checkbox checked="{{value.hasEars::change}}">Has ears</paper-checkbox>
+ </template>
+
+ </div>
+
+ <script>
+ document.querySelector('template').initializeDefaultValue = function(ev) {
+ console.log("initializeTemplate");
+ this.value = {
+ name: "Mickey",
+ hasEars: true
+ }
+ }
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-localstorage/hero.svg b/polymer_1.0.4/bower_components/iron-localstorage/hero.svg
new file mode 100755
index 0000000..0c0ec6b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-localstorage/hero.svg
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <path d="M124,45.3c-0.5-0.6-4.7-1.6-12-1.6s-11.5,1.1-12,1.6c0,0,0.1-0.3,0.1-0.3h-2c0-3,10.7-3.4,14-3.4s14,0.4,14,3.4h-2
+ C124,45,124,45.3,124,45.3z"/>
+ <path d="M112,83c-3.3,0-14-0.2-14-3.4l0-7.6l0-1.6l2,0c0-0.2-0.1-0.3-0.1-0.3c0.5,0.6,4.7,1.6,12,1.6s11.5-1.1,12-1.6
+ c0,0-0.1,0.1-0.1,0.3l2,0l0,1.5l0,7.7C126,82.8,115.3,83,112,83z M100,79.4c0.8,0.6,4.9,1.6,12,1.6s11.2-1,12-1.6l0-7
+ c-3.2,1.3-9.6,1.4-12,1.4c-2.4,0-8.8-0.1-12-1.4L100,79.4z"/>
+ <path d="M112,70c-3.3,0-14-0.2-14-3.4l0-7.6l0-1.6l2,0c0-0.2-0.1-0.3-0.1-0.3c0.5,0.6,4.7,1.6,12,1.6s11.5-1.1,12-1.6
+ c0,0-0.1,0.1-0.1,0.3l2,0l0,1.5l0,7.7C126,69.8,115.3,70,112,70z M100,66.4c0.8,0.6,4.9,1.6,12,1.6s11.2-1,12-1.6l0-7
+ c-3.2,1.3-9.6,1.4-12,1.4c-2.4,0-8.8-0.1-12-1.4L100,66.4z"/>
+ <path d="M112,57c-3.3,0-14-0.2-14-3.4l0-7.6l0-1.6l2,0c0-0.2-0.1-0.3-0.1-0.3c0.5,0.6,4.7,1.6,12,1.6s11.5-1.1,12-1.6
+ c0,0-0.1,0.1-0.1,0.3l2,0l0,1.5l0,7.7C126,56.8,115.3,57,112,57z M100,53.4c0.8,0.6,4.9,1.6,12,1.6s11.2-1,12-1.6l0-7
+ c-3.2,1.3-9.6,1.4-12,1.4c-2.4,0-8.8-0.1-12-1.4L100,53.4z"/>
+ <path d="M151,99H73V27h78V99z M75,97h74V29H75V97z"/>
+ <circle cx="74" cy="28" r="4"/>
+ <circle cx="150" cy="28" r="4"/>
+ <circle cx="150" cy="98" r="4"/>
+ <circle cx="74" cy="98" r="4"/>
+ <circle cx="113" cy="98" r="4"/>
+ <circle cx="113" cy="28" r="4"/>
+ <circle cx="74" cy="63" r="4"/>
+ <circle cx="150" cy="63" r="4"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/iron-localstorage/index.html b/polymer_1.0.4/bower_components/iron-localstorage/index.html
new file mode 100644
index 0000000..246af10
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-localstorage/index.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-localstorage/iron-localstorage.html b/polymer_1.0.4/bower_components/iron-localstorage/iron-localstorage.html
new file mode 100644
index 0000000..d231a6b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-localstorage/iron-localstorage.html
@@ -0,0 +1,245 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<!--
+Element access to Web Storage API (window.localStorage).
+
+Keeps `value` property in sync with localStorage.
+
+Value is saved as json by default.
+
+###Usage:
+
+`ls-sample` will automatically save changes to its value.
+
+ <dom-module id="ls-sample">
+ <iron-localstorage name="my-app-storage"
+ value="{{cartoon}}"
+ on-iron-localstorage-load-empty="initializeDefaultCartoon"
+ ></iron-localstorage>
+ </dom-module>
+
+ <script>
+ Polymer({
+ is: 'ls-sample',
+ properties: {
+ cartoon: {
+ type: Object
+ }
+ },
+ // initializes default if nothing has been stored
+ initializeDefaultCartoon: function() {
+ this.cartoon = {
+ name: "Mickey",
+ hasEars: true
+ }
+ },
+ // use path set api to propagate changes to localstorage
+ makeModifications: function() {
+ this.set('cartoon.name', "Minions");
+ this.set('cartoon.hasEars', false);
+ }
+ });
+ </script>
+
+###Tech notes:
+
+* * `value.*` is observed, and saved on modifications. You must use
+property notification methods to modify value for changes to be observed.
+
+* * Set `auto-save-disabled` to prevent automatic saving.
+
+* * Value is saved as JSON by default.
+
+* * To delete a key, set value to null
+
+* Element listens to StorageAPI `storage` event, and will reload upon receiving it.
+
+* **Warning**: do not bind value to sub-properties until Polymer
+[bug 1550](https://github.com/Polymer/polymer/issues/1550)
+is resolved. Local storage will be blown away.
+`<iron-localstorage value="{{foo.bar}}"` will cause **data loss**.
+
+@demo demo/index.html
+@hero hero.svg
+-->
+<dom-module id="iron-localstorage"></dom-module>
+<script>
+
+ Polymer({
+ is: 'iron-localstorage',
+
+ /**
+ * Fired when value loads from localStorage.
+ *
+ * @event iron-localstorage-load
+ * @param {{externalChange:boolean}} detail -
+ * externalChange: true if change occured in different window.
+ */
+
+ /**
+ * Fired when loaded value does not exist.
+ * Event handler can be used to initialize default value.
+ *
+ * @event iron-localstorage-load-empty
+ * @param {{externalChange:boolean}} detail -
+ * externalChange: true if change occured in different window.
+ */
+ properties: {
+ /**
+ * localStorage item key
+ */
+ name: {
+ type: String,
+ value: ''
+ },
+ /**
+ * The data associated with this storage.
+ * If set to null item will be deleted.
+ * @type {*}
+ */
+ value: {
+ type: Object,
+ notify: true
+ },
+
+ /**
+ * If true: do not convert value to JSON on save/load
+ */
+ useRaw: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Value will not be saved automatically if true. You'll have to do it manually with `save()`
+ */
+ autoSaveDisabled: {
+ type: Boolean,
+ value: false
+ },
+ /**
+ * Last error encountered while saving/loading items
+ */
+ errorMessage: {
+ type: String,
+ notify: true
+ },
+
+ /** True if value has been loaded */
+ _loaded: {
+ type: Boolean,
+ value: false
+ }
+ },
+
+ observers: [
+ '_debounceReload(name,useRaw)',
+ '_trySaveValue(autoSaveDisabled)',
+ '_trySaveValue(value.*)'
+ ],
+
+ ready: function() {
+ this._boundHandleStorage = this._handleStorage.bind(this);
+ },
+
+ attached: function() {
+ window.addEventListener('storage', this._boundHandleStorage);
+ },
+
+ detached: function() {
+ window.removeEventListener('storage', this._boundHandleStorage);
+ },
+
+ _handleStorage: function(ev) {
+ if (ev.key == this.name) {
+ this._load(true);
+ }
+ },
+
+ _trySaveValue: function() {
+ if (this._doNotSave) {
+ return;
+ }
+ if (this._loaded && !this.autoSaveDisabled) {
+ this.debounce('save', this.save);
+ }
+ },
+
+ _debounceReload: function() {
+ this.debounce('reload', this.reload);
+ },
+
+ /**
+ * Loads the value again. Use if you modify
+ * localStorage using DOM calls, and want to
+ * keep this element in sync.
+ */
+ reload: function() {
+ this._loaded = false;
+ this._load();
+ },
+
+ /**
+ * loads value from local storage
+ * @param {boolean=} externalChange true if loading changes from a different window
+ */
+ _load: function(externalChange) {
+ var v = window.localStorage.getItem(this.name);
+
+ if (v === null) {
+ this._loaded = true;
+ this._doNotSave = true; // guard for save watchers
+ this.value = null;
+ this._doNotSave = false;
+ this.fire('iron-localstorage-load-empty', { externalChange: externalChange});
+ } else {
+ if (!this.useRaw) {
+ try { // parse value as JSON
+ v = JSON.parse(v);
+ } catch(x) {
+ this.errorMessage = "Could not parse local storage value";
+ console.error("could not parse local storage value", v);
+ v = null;
+ }
+ }
+ this._loaded = true;
+ this._doNotSave = true;
+ this.value = v;
+ this._doNotSave = false;
+ this.fire('iron-localstorage-load', { externalChange: externalChange});
+ }
+ },
+
+ /**
+ * Saves the value to localStorage. Call to save if autoSaveDisabled is set.
+ * If `value` is null, deletes localStorage.
+ */
+ save: function() {
+ var v = this.useRaw ? this.value : JSON.stringify(this.value);
+ try {
+ if (this.value === null) {
+ window.localStorage.removeItem(this.name);
+ } else {
+ window.localStorage.setItem(this.name, /** @type {string} */ (v));
+ }
+ }
+ catch(ex) {
+ // Happens in Safari incognito mode,
+ this.errorMessage = ex.message;
+ console.error("localStorage could not be saved. Safari incoginito mode?", ex);
+ }
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-localstorage/test/basic.html b/polymer_1.0.4/bower_components/iron-localstorage/test/basic.html
new file mode 100644
index 0000000..dd4b169
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-localstorage/test/basic.html
@@ -0,0 +1,120 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>iron-localstorage-basic</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-localstorage.html">
+
+</head>
+<body>
+
+ <test-fixture id="fixture">
+ <template>
+ <iron-localstorage id="localstorage" name="iron-localstorage-test"></iron-localstorage>
+ </template>
+ </test-fixture>
+
+ <template id="boundTemplate" is="dom-bind">
+ <iron-localstorage id="boundLocal" name="iron-localstorage-test" value="{{value}}"></iron-localstorage>
+ </template>
+
+ <script>
+ var storage;
+
+ suite('basic', function() {
+
+ setup(function() {
+ window.localStorage.setItem('iron-localstorage-test', '{"foo":"bar"}');
+ storage = document.getElementById('fixture').create();
+ storage.flushDebouncer('reload');
+ });
+
+ teardown(function() {
+ window.localStorage.removeItem('iron-localstorage-test');
+ });
+
+ test('load', function() {
+ assert.isNotNull(storage.value);
+ assert.equal(storage.value.foo, 'bar');
+ });
+
+ test('save', function() {
+ var newValue = {'foo': 'zot'};
+ storage.value = newValue;
+ storage.flushDebouncer('save');
+ var v = window.localStorage.getItem(storage.name);
+ v = JSON.parse(v);
+ assert.equal(v.foo, newValue.foo);
+ });
+
+ test('delete', function() {
+ storage.value = null;
+ storage.flushDebouncer('save');
+ var v = window.localStorage.getItem(storage.name);
+ assert.isNull(v);
+ });
+
+ test('event iron-localstorage-load', function(done) {
+ var ls = document.createElement('iron-localstorage');
+ ls.addEventListener('iron-localstorage-load', function() {
+ done();
+ });
+ ls.name = 'iron-localstorage-test';
+ });
+
+ test('event iron-localstorage-load-empty', function(done) {
+ window.localStorage.removeItem('iron-localstorage-test');
+
+ var ls = document.createElement('iron-localstorage');
+ ls.addEventListener('iron-localstorage-load-empty', function() {
+ // testing recommended way to initialize localstorage
+ ls.value = "Yo";
+ ls.flushDebouncer('save');
+ assert.equal("Yo", JSON.parse( window.localStorage.getItem('iron-localstorage-test')));
+ done();
+ });
+ ls.name = 'iron-localstorage-test';
+ });
+
+ test('auto-save sub-properties', function() {
+ var t = document.querySelector('#boundTemplate');
+ var ls = document.querySelector('#boundLocal');
+ var value = { foo: 'FOO', bar: 'BAR' };
+ t.value = value;
+ assert.equal('FOO', ls.value.foo); // value has propagated from template to storage
+
+ ls.flushDebouncer('save');
+ t.value.foo = "Yo";
+ ls.flushDebouncer('save');
+ var item = JSON.parse( window.localStorage.getItem('iron-localstorage-test'));
+ assert.notEqual('Yo', item.foo); // did not propagate because did not use setters
+
+ t.set('value.foo', 'BAZ!');
+ ls.flushDebouncer('save');
+ var item = JSON.parse( window.localStorage.getItem('iron-localstorage-test'));
+ assert.equal('BAZ!', item.foo); // did propagate
+ ls.value = null;
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-localstorage/test/index.html b/polymer_1.0.4/bower_components/iron-localstorage/test/index.html
new file mode 100644
index 0000000..944cb3d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-localstorage/test/index.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>iron-localstorage tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html',
+ 'raw.html',
+ 'value-binding.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-localstorage/test/raw.html b/polymer_1.0.4/bower_components/iron-localstorage/test/raw.html
new file mode 100644
index 0000000..3c786fd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-localstorage/test/raw.html
@@ -0,0 +1,68 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>iron-localstorage-raw</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-localstorage.html">
+
+</head>
+<body>
+
+
+ <test-fixture id="fixture">
+ <template>
+ <iron-localstorage id="localstorage" name="iron-localstorage-test" use-raw></iron-localstorage>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ var storage;
+
+ suite('raw', function() {
+
+ setup(function() {
+ window.localStorage.setItem('iron-localstorage-test', 'hello world');
+ document.getElementById('fixture').create();
+ storage = document.getElementById('localstorage');
+ storage.flushDebouncer('reload');
+ });
+
+ teardown(function() {
+ window.localStorage.removeItem('iron-localstorage-test');
+ });
+
+ test('load', function() {
+ assert.equal(storage.value, 'hello world');
+ });
+
+ test('save', function() {
+ var m = 'goodbye';
+ storage.value = m;
+ storage.flushDebouncer('save');
+ var v = window.localStorage.getItem(storage.name);
+ assert.equal(v, m);
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-localstorage/test/value-binding.html b/polymer_1.0.4/bower_components/iron-localstorage/test/value-binding.html
new file mode 100644
index 0000000..acce381
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-localstorage/test/value-binding.html
@@ -0,0 +1,104 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>iron-localstorage-value-binding</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-localstorage.html">
+
+</head>
+<body>
+
+ <dom-module id="x-foo">
+ <template>
+ <div>{{value.foo}}</div>
+ </template>
+ </dom-module>
+
+ <dom-module id="x-test">
+ <template>
+ <x-foo value="{{value}}"></x-foo>
+ <iron-localstorage id="localstorage" name="iron-localstorage-test" value="{{value}}"></iron-localstorage>
+ </template>
+ </dom-module>
+
+ <x-test></x-test>
+
+ <script>
+
+ window.localStorage.setItem('iron-localstorage-test', '{"foo":"bar"}');
+ var xtest;
+
+ suite('basic', function() {
+
+ suiteSetup(function() {
+ Polymer({
+ is: 'x-foo',
+ properties: {
+ 'value': {
+ type: Object,
+ notify: true
+ }
+ }
+ });
+ Polymer({
+ is: 'x-test',
+ properties: {
+ 'value': {
+ type: Object,
+ notify: true
+ }
+ }
+ });
+ window.localStorage.setItem('iron-localstorage-test', '{"foo":"bar"}');
+ xtest = document.querySelector('x-test');
+ xtest.$.localstorage.reload();
+ });
+
+ suiteTeardown(function() {
+ window.localStorage.removeItem('iron-localstorage-test');
+ });
+
+ test('initial value', function() {
+ assert.isNotNull(xtest.value);
+ assert.equal(xtest.value.foo, 'bar');
+ });
+
+ test('set value', function() {
+ var newValue = {'foo': 'zot'};
+ xtest.value = newValue;
+ xtest.$.localstorage.flushDebouncer('save');
+ var v = window.localStorage.getItem(xtest.$.localstorage.name);
+ v = JSON.parse(v);
+ assert.equal(v.foo, newValue.foo);
+ });
+
+ test('save', function() {
+ xtest.value.foo = 'quux';
+ xtest.$.localstorage.save();
+ var v = window.localStorage.getItem(xtest.$.localstorage.name);
+ v = JSON.parse(v);
+ assert.equal(v.foo, 'quux');
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-media-query/.bower.json b/polymer_1.0.4/bower_components/iron-media-query/.bower.json
new file mode 100644
index 0000000..ce32680
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-media-query/.bower.json
@@ -0,0 +1,40 @@
+{
+ "name": "iron-media-query",
+ "version": "1.0.2",
+ "description": "Lets you bind to a CSS media query",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "media"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-media-query"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-media-query",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "web-component-tester": "*",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "34abf0a3b8bf9e9e478352dbb3d9e6a76bf3669a"
+ },
+ "_source": "git://github.com/PolymerElements/iron-media-query.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-media-query"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-media-query/.gitignore b/polymer_1.0.4/bower_components/iron-media-query/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-media-query/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-media-query/README.md b/polymer_1.0.4/bower_components/iron-media-query/README.md
new file mode 100644
index 0000000..f577b3c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-media-query/README.md
@@ -0,0 +1,11 @@
+# iron-media-query
+
+`iron-media-query` can be used to data bind to a CSS media query.
+The `query` property is a bare CSS media query.
+The `query-matches` property is a boolean representing if the page matches that media query.
+
+Example:
+
+```html
+<iron-media-query query="(min-width: 600px)" query-matches="{{queryMatches}}"></iron-media-query>
+```
diff --git a/polymer_1.0.4/bower_components/iron-media-query/bower.json b/polymer_1.0.4/bower_components/iron-media-query/bower.json
new file mode 100644
index 0000000..48c342a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-media-query/bower.json
@@ -0,0 +1,31 @@
+{
+ "name": "iron-media-query",
+ "version": "1.0.2",
+ "description": "Lets you bind to a CSS media query",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "media"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-media-query"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-media-query",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "web-component-tester": "*",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-media-query/demo/index.html b/polymer_1.0.4/bower_components/iron-media-query/demo/index.html
new file mode 100644
index 0000000..2f3856f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-media-query/demo/index.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>iron-media-query demo</title>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../iron-media-query.html">
+
+ </head>
+ <body>
+
+ <div class="vertical-section vertical-section-container centered">
+ <h1><iron-media-query></h1>
+
+ <template is="dom-bind">
+ <iron-media-query query="(min-width: 600px)" query-matches="{{queryMatches}}"></iron-media-query>
+
+ <template is="dom-if" if="{{queryMatches}}">
+ <p>The viewport’s width is greater than <code>600px</code></p>
+ </template>
+
+ <template is="dom-if" if="{{!queryMatches}}">
+ <p>The viewport’s width is less than <code>600px</code></p>
+ </template>
+ </template>
+ </div>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-media-query/hero.svg b/polymer_1.0.4/bower_components/iron-media-query/hero.svg
new file mode 100755
index 0000000..9b5e2a6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-media-query/hero.svg
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <path d="M173,99H91V41h82V99z M93,97h78V43H93V97z"/>
+ <path d="M77,89H51V42h26V89z M53,87h22V44H53V87z"/>
+ <rect x="52" y="56" width="24" height="2"/>
+ <rect x="92" y="58" width="80" height="2"/>
+ <path d="M65.3,42h-2c0-10,8.7-18.7,18.7-18.7v2C73,25.3,65.3,33,65.3,42z"/>
+ <path d="M105.3,42h-2c0-9-7.3-16.7-16.3-16.7v-2C97,23.3,105.3,32,105.3,42z"/>
+ <circle cx="84.3" cy="24.3" r="4"/>
+ <circle cx="69.3" cy="80.3" r="4"/>
+ <circle cx="160.3" cy="59.3" r="4"/>
+ <path d="M49,41v49c0,1.1,0.9,2,2,2h26c1.1,0,2-0.9,2-2V41c0-1.1-0.9-2-2-2H51C49.9,39,49,39.9,49,41z M76,88H52V43h24V88z"/>
+ <path d="M88.9,40.7v59c0,1.1,0.9,2,2,2h82c1.1,0,2-0.9,2-2v-59c0-1.1-0.9-2-2-2h-82C89.8,38.7,88.9,39.6,88.9,40.7z M172,98H93V42
+ h79V98z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/iron-media-query/index.html b/polymer_1.0.4/bower_components/iron-media-query/index.html
new file mode 100644
index 0000000..7aee5c1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-media-query/index.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+ <head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>iron-media-query</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+ </head>
+ <body>
+
+ <iron-component-page></iron-component-page>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-media-query/iron-media-query.html b/polymer_1.0.4/bower_components/iron-media-query/iron-media-query.html
new file mode 100644
index 0000000..8325eb2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-media-query/iron-media-query.html
@@ -0,0 +1,77 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<!--
+`iron-media-query` can be used to data bind to a CSS media query.
+The `query` property is a bare CSS media query.
+The `query-matches` property is a boolean representing whether the page matches that media query.
+
+Example:
+
+ <iron-media-query query="(min-width: 600px)" query-matches="{{queryMatches}}"></iron-media-query>
+
+@group Iron Elements
+@demo demo/index.html
+@hero hero.svg
+@element iron-media-query
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'iron-media-query',
+
+ properties: {
+
+ /**
+ * The Boolean return value of the media query.
+ */
+ queryMatches: {
+ type: Boolean,
+ value: false,
+ readOnly: true,
+ notify: true
+ },
+
+ /**
+ * The CSS media query to evaluate.
+ */
+ query: {
+ type: String,
+ observer: 'queryChanged'
+ }
+
+ },
+
+ created: function() {
+ this._mqHandler = this.queryHandler.bind(this);
+ },
+
+ queryChanged: function(query) {
+ if (this._mq) {
+ this._mq.removeListener(this._mqHandler);
+ }
+ if (query[0] !== '(') {
+ query = '(' + query + ')';
+ }
+ this._mq = window.matchMedia(query);
+ this._mq.addListener(this._mqHandler);
+ this.queryHandler(this._mq);
+ },
+
+ queryHandler: function(mq) {
+ this._setQueryMatches(mq.matches);
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-media-query/test/basic.html b/polymer_1.0.4/bower_components/iron-media-query/test/basic.html
new file mode 100644
index 0000000..34346c2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-media-query/test/basic.html
@@ -0,0 +1,71 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <title>iron-media-query-basic</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../iron-media-query.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="basic">
+ <template>
+ <iron-media-query></iron-media-query>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+ var mq;
+
+ suite('set query with different values', function() {
+ setup(function () {
+ mq = fixture('basic');
+ });
+
+ test('small min-width value', function() {
+ mq.query = '(min-width: 1px)';
+ assert.equal(mq.queryMatches, true);
+ });
+
+ test('large min-width value', function() {
+ mq.query = '(min-width: 10000px)';
+ assert.equal(mq.queryMatches, false);
+ });
+
+ test('small max-width value', function() {
+ mq.query = '(max-width: 1px)';
+ assert.equal(mq.queryMatches, false);
+ });
+
+ test('large max-width value', function() {
+ mq.query = '(max-width: 10000px)';
+ assert.equal(mq.queryMatches, true);
+ });
+
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-media-query/test/index.html b/polymer_1.0.4/bower_components/iron-media-query/test/index.html
new file mode 100644
index 0000000..7baa57f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-media-query/test/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <meta charset="utf-8">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/.bower.json b/polymer_1.0.4/bower_components/iron-menu-behavior/.bower.json
new file mode 100644
index 0000000..7ca24d4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/.bower.json
@@ -0,0 +1,41 @@
+{
+ "name": "iron-menu-behavior",
+ "version": "1.0.1",
+ "description": "Provides accessible menu behavior",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "behavior",
+ "menu"
+ ],
+ "main": "iron-menu-behavior.html",
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-menu-behavior"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-menu-behavior",
+ "ignore": [],
+ "dependencies": {
+ "iron-selector": "PolymerElements/iron-selector#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-a11y-keys-behavior": "polymerelements/iron-a11y-keys-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "3809f0eb7461c8ca63640aaa238775b3a25aa578"
+ },
+ "_source": "git://github.com/PolymerElements/iron-menu-behavior.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-menu-behavior"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/.gitignore b/polymer_1.0.4/bower_components/iron-menu-behavior/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/README.md b/polymer_1.0.4/bower_components/iron-menu-behavior/README.md
new file mode 100644
index 0000000..42ab7fa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/README.md
@@ -0,0 +1,3 @@
+# iron-menu-behavior
+
+`Polymer.IronMenuBehavior` implements accessible menu behavior.
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/bower.json b/polymer_1.0.4/bower_components/iron-menu-behavior/bower.json
new file mode 100644
index 0000000..f0d453c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/bower.json
@@ -0,0 +1,32 @@
+{
+ "name": "iron-menu-behavior",
+ "version": "1.0.1",
+ "description": "Provides accessible menu behavior",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "behavior",
+ "menu"
+ ],
+ "main": "iron-menu-behavior.html",
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-menu-behavior"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-menu-behavior",
+ "ignore": [],
+ "dependencies": {
+ "iron-selector": "PolymerElements/iron-selector#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-a11y-keys-behavior": "polymerelements/iron-a11y-keys-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/demo/index.html b/polymer_1.0.4/bower_components/iron-menu-behavior/demo/index.html
new file mode 100644
index 0000000..6e64d2a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/demo/index.html
@@ -0,0 +1,100 @@
+<!doctype html>
+<!--
+ @license
+ Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ Code distributed by Google as part of the polymer project is also
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>iron-menu-behavior demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="simple-menu.html">
+ <link rel="import" href="simple-menubar.html">
+
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+
+ <style>
+
+ .list {
+ display: inline-block;
+ border: 1px solid #ccc;
+ padding: 8px 0;
+ }
+
+ .list li {
+ display: block;
+ padding: 8px;
+ }
+
+ .list li[disabled] {
+ color: #ccc;
+ }
+
+ </style>
+</head>
+<body>
+
+ <section>
+
+ <div>Simple menu</div>
+
+ <simple-menu class="list">
+ <li>item 0</li>
+ <li>item 1</li>
+ <li disabled>item 2</li>
+ <li>item 3</li>
+ </simple-menu>
+
+ </section>
+
+ <section>
+
+ <div>Multi-select menu</div>
+
+ <simple-menu class="list" multi>
+ <li>item 0</li>
+ <li>item 1</li>
+ <li>item 2</li>
+ <li>item 3</li>
+ <li>item 4</li>
+ </simple-menu>
+
+ </section>
+
+ <section>
+
+ <div>Simple menubar</div>
+
+ <simple-menubar class="list">
+ <li>item 0</li>
+ <li>item 1</li>
+ <li disabled>item 2</li>
+ <li>item 3</li>
+ </simple-menubar>
+
+ </section>
+
+ <section>
+ <div>Multi-select menubar</div>
+
+ <simple-menubar class="list" multi>
+ <li>item 0</li>
+ <li>item 1</li>
+ <li>item 2</li>
+ <li>item 3</li>
+ <li>item 4</li>
+ </simple-menubar>
+ </section>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/demo/simple-menu.html b/polymer_1.0.4/bower_components/iron-menu-behavior/demo/simple-menu.html
new file mode 100644
index 0000000..cd1c7cf
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/demo/simple-menu.html
@@ -0,0 +1,50 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../iron-menu-behavior.html">
+
+<dom-module id="simple-menu">
+
+ <style>
+
+ .content ::content > .iron-selected {
+ color: red;
+ }
+
+ </style>
+
+ <template>
+
+ <div class="content">
+ <content></content>
+ </div>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'simple-menu',
+
+ behaviors: [
+ Polymer.IronMenuBehavior
+ ]
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/demo/simple-menubar.html b/polymer_1.0.4/bower_components/iron-menu-behavior/demo/simple-menubar.html
new file mode 100644
index 0000000..ad38ecf
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/demo/simple-menubar.html
@@ -0,0 +1,54 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../iron-menubar-behavior.html">
+
+<dom-module id="simple-menubar">
+
+ <style>
+
+ .content ::content > .iron-selected {
+ color: red;
+ }
+
+ .content ::content > * {
+ display: inline-block;
+ }
+
+ </style>
+
+ <template>
+
+ <div class="content">
+ <content></content>
+ </div>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'simple-menubar',
+
+ behaviors: [
+ Polymer.IronMenubarBehavior
+ ]
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/index.html b/polymer_1.0.4/bower_components/iron-menu-behavior/index.html
new file mode 100644
index 0000000..2c643c4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>iron-menu-behavior</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page src="iron-menubar-behavior.html"></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/iron-menu-behavior.html b/polymer_1.0.4/bower_components/iron-menu-behavior/iron-menu-behavior.html
new file mode 100644
index 0000000..aa58c7f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/iron-menu-behavior.html
@@ -0,0 +1,214 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-selector/iron-multi-selectable.html">
+<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
+
+<script>
+
+ /**
+ * `Polymer.IronMenuBehavior` implements accessible menu behavior.
+ *
+ * @demo demo/index.html
+ * @polymerBehavior Polymer.IronMenuBehavior
+ */
+ Polymer.IronMenuBehaviorImpl = {
+
+ properties: {
+
+ /**
+ * Returns the currently focused item.
+ *
+ * @attribute focusedItem
+ * @type Object
+ */
+ focusedItem: {
+ observer: '_focusedItemChanged',
+ readOnly: true,
+ type: Object
+ },
+
+ /**
+ * The attribute to use on menu items to look up the item title. Typing the first
+ * letter of an item when the menu is open focuses that item. If unset, `textContent`
+ * will be used.
+ *
+ * @attribute attrForItemTitle
+ * @type String
+ */
+ attrForItemTitle: {
+ type: String
+ }
+ },
+
+ hostAttributes: {
+ 'role': 'menu',
+ 'tabindex': '0'
+ },
+
+ observers: [
+ '_updateMultiselectable(multi)'
+ ],
+
+ listeners: {
+ 'focus': '_onFocus',
+ 'keydown': '_onKeydown'
+ },
+
+ keyBindings: {
+ 'up': '_onUpKey',
+ 'down': '_onDownKey',
+ 'esc': '_onEscKey',
+ 'enter': '_onEnterKey',
+ 'shift+tab:keydown': '_onShiftTabDown'
+ },
+
+ _updateMultiselectable: function(multi) {
+ if (multi) {
+ this.setAttribute('aria-multiselectable', 'true');
+ } else {
+ this.removeAttribute('aria-multiselectable');
+ }
+ },
+
+ _onShiftTabDown: function() {
+ var oldTabIndex;
+
+ Polymer.IronMenuBehaviorImpl._shiftTabPressed = true;
+
+ oldTabIndex = this.getAttribute('tabindex');
+
+ this.setAttribute('tabindex', '-1');
+
+ this.async(function() {
+ this.setAttribute('tabindex', oldTabIndex);
+ Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
+ // Note: polymer/polymer#1305
+ }, 1);
+ },
+
+ _applySelection: function(item, isSelected) {
+ if (isSelected) {
+ item.setAttribute('aria-selected', 'true');
+ } else {
+ item.removeAttribute('aria-selected');
+ }
+
+ Polymer.IronSelectableBehavior._applySelection.apply(this, arguments);
+ },
+
+ _focusedItemChanged: function(focusedItem, old) {
+ old && old.setAttribute('tabindex', '-1');
+ if (focusedItem) {
+ focusedItem.setAttribute('tabindex', '0');
+ focusedItem.focus();
+ }
+ },
+
+ select: function(value) {
+ if (this._defaultFocusAsync) {
+ this.cancelAsync(this._defaultFocusAsync);
+ this._defaultFocusAsync = null;
+ }
+ var item = this._valueToItem(value);
+ this._setFocusedItem(item);
+ Polymer.IronMultiSelectableBehaviorImpl.select.apply(this, arguments);
+ },
+
+ _onFocus: function(event) {
+ if (Polymer.IronMenuBehaviorImpl._shiftTabPressed) {
+ return;
+ }
+ // do not focus the menu itself
+ this.blur();
+ // clear the cached focus item
+ this._setFocusedItem(null);
+ this._defaultFocusAsync = this.async(function() {
+ // focus the selected item when the menu receives focus, or the first item
+ // if no item is selected
+ var selectedItem = this.multi ? (this.selectedItems && this.selectedItems[0]) : this.selectedItem;
+ if (selectedItem) {
+ this._setFocusedItem(selectedItem);
+ } else {
+ this._setFocusedItem(this.items[0]);
+ }
+ // async 100ms to wait for `select` to get called from `_itemActivate`
+ }, 100);
+ },
+
+ _onUpKey: function() {
+ // up and down arrows moves the focus
+ this._focusPrevious();
+ },
+
+ _onDownKey: function() {
+ this._focusNext();
+ },
+
+ _onEscKey: function() {
+ // esc blurs the control
+ this.focusedItem.blur();
+ },
+
+ _onEnterKey: function(event) {
+ // enter activates the item unless it is disabled
+ this._activateFocused(event.detail.keyboardEvent);
+ },
+
+ _onKeydown: function(event) {
+ if (this.keyboardEventMatchesKeys(event, 'up down esc enter')) {
+ return;
+ }
+
+ // all other keys focus the menu item starting with that character
+ this._focusWithKeyboardEvent(event);
+ },
+
+ _focusWithKeyboardEvent: function(event) {
+ for (var i = 0, item; item = this.items[i]; i++) {
+ var attr = this.attrForItemTitle || 'textContent';
+ var title = item[attr] || item.getAttribute(attr);
+ if (title && title.trim().charAt(0).toLowerCase() === String.fromCharCode(event.keyCode).toLowerCase()) {
+ this._setFocusedItem(item);
+ break;
+ }
+ }
+ },
+
+ _activateFocused: function(event) {
+ if (!this.focusedItem.hasAttribute('disabled')) {
+ this._activateHandler(event);
+ }
+ },
+
+ _focusPrevious: function() {
+ var length = this.items.length;
+ var index = (Number(this.indexOf(this.focusedItem)) - 1 + length) % length;
+ this._setFocusedItem(this.items[index]);
+ },
+
+ _focusNext: function() {
+ var index = (Number(this.indexOf(this.focusedItem)) + 1) % this.items.length;
+ this._setFocusedItem(this.items[index]);
+ }
+
+ };
+
+ Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
+
+ /** @polymerBehavior Polymer.IronMenuBehavior */
+ Polymer.IronMenuBehavior = [
+ Polymer.IronMultiSelectableBehavior,
+ Polymer.IronA11yKeysBehavior,
+ Polymer.IronMenuBehaviorImpl
+ ];
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/iron-menubar-behavior.html b/polymer_1.0.4/bower_components/iron-menu-behavior/iron-menubar-behavior.html
new file mode 100644
index 0000000..e25304a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/iron-menubar-behavior.html
@@ -0,0 +1,65 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="iron-menu-behavior.html">
+
+<script>
+
+ /**
+ * `Polymer.IronMenubarBehavior` implements accessible menubar behavior.
+ *
+ * @polymerBehavior Polymer.IronMenubarBehavior
+ */
+ Polymer.IronMenubarBehaviorImpl = {
+
+ hostAttributes: {
+ 'role': 'menubar'
+ },
+
+ keyBindings: {
+ 'left': '_onLeftKey',
+ 'right': '_onRightKey'
+ },
+
+ _onUpKey: function(event) {
+ this._activateFocused(event.detail.keyboardEvent);
+ },
+
+ _onDownKey: function(event) {
+ this._activateFocused(event.detail.keyboardEvent);
+ },
+
+ _onLeftKey: function() {
+ this._focusPrevious();
+ },
+
+ _onRightKey: function() {
+ this._focusNext();
+ },
+
+ _onKeydown: function(event) {
+ if (this.keyboardEventMatchesKeys(event, 'up down left right esc enter')) {
+ return;
+ }
+
+ // all other keys focus the menu item starting with that character
+ this._focusWithKeyboardEvent(event);
+ }
+
+ };
+
+ /** @polymerBehavior Polymer.IronMenubarBehavior */
+ Polymer.IronMenubarBehavior = [
+ Polymer.IronMenuBehavior,
+ Polymer.IronMenubarBehaviorImpl
+ ];
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/test/index.html b/polymer_1.0.4/bower_components/iron-menu-behavior/test/index.html
new file mode 100644
index 0000000..4b1c82f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/test/index.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>iron-menu-behavior tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'iron-menu-behavior.html',
+ 'iron-menubar-behavior.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/test/iron-menu-behavior.html b/polymer_1.0.4/bower_components/iron-menu-behavior/test/iron-menu-behavior.html
new file mode 100644
index 0000000..309dbb1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/test/iron-menu-behavior.html
@@ -0,0 +1,108 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>iron-menu-behavior tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="test-menu.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="basic">
+ <template>
+ <test-menu>
+ <div>item 1</div>
+ <div>item 2</div>
+ <div>item 3</div>
+ </test-menu>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="multi">
+ <template>
+ <test-menu multi>
+ <div>item 1</div>
+ <div>item 2</div>
+ <div>item 3</div>
+ </test-menu>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('menu a11y tests', function() {
+
+ test('menu has role="menu"', function() {
+ var menu = fixture('basic');
+ assert.equal(menu.getAttribute('role'), 'menu', 'has role="menu"');
+ });
+
+ test('first item gets focus when menu is focused', function(done) {
+ var menu = fixture('basic');
+ menu.focus();
+ setTimeout(function() {
+ assert.equal(document.activeElement, menu.firstElementChild, 'document.activeElement is first item')
+ done();
+ // wait for async in _onFocus
+ }, 200);
+ });
+
+ test('selected item gets focus when menu is focused', function(done) {
+ var menu = fixture('basic');
+ menu.selected = 1;
+ menu.focus();
+ setTimeout(function() {
+ assert.equal(document.activeElement, menu.selectedItem, 'document.activeElement is selected item');
+ done();
+ // wait for async in _onFocus
+ }, 200);
+ });
+
+ test('last activated item in a multi select menu is focused', function(done) {
+ var menu = fixture('multi');
+ menu.selected = 0;
+ menu.items[1].click();
+ setTimeout(function() {
+ assert.equal(document.activeElement, menu.items[1], 'document.activeElement is last activated item');
+ done();
+ // wait for async in _onFocus
+ }, 200);
+ });
+
+ test('deselection in a multi select menu focuses deselected item', function(done) {
+ var menu = fixture('multi');
+ menu.selected = 0;
+ menu.items[0].click();
+ setTimeout(function() {
+ assert.equal(document.activeElement, menu.items[0], 'document.activeElement is last activated item');
+ done();
+ // wait for async in _onFocus
+ }, 200);
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/test/iron-menubar-behavior.html b/polymer_1.0.4/bower_components/iron-menu-behavior/test/iron-menubar-behavior.html
new file mode 100644
index 0000000..b007b1c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/test/iron-menubar-behavior.html
@@ -0,0 +1,108 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>iron-menubar-behavior tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="test-menubar.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="basic">
+ <template>
+ <test-menubar>
+ <div>item 1</div>
+ <div>item 2</div>
+ <div>item 3</div>
+ </test-menubar>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="multi">
+ <template>
+ <test-menubar multi>
+ <div>item 1</div>
+ <div>item 2</div>
+ <div>item 3</div>
+ </test-menubar>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('menubar a11y tests', function() {
+
+ test('menubar has role="menubar"', function() {
+ var menubar = fixture('basic');
+ assert.equal(menubar.getAttribute('role'), 'menubar', 'has role="menubar"');
+ });
+
+ test('first item gets focus when menubar is focused', function(done) {
+ var menubar = fixture('basic');
+ menubar.focus();
+ setTimeout(function() {
+ assert.equal(document.activeElement, menubar.firstElementChild, 'document.activeElement is first item')
+ done();
+ // wait for async in _onFocus
+ }, 200);
+ });
+
+ test('selected item gets focus when menubar is focused', function(done) {
+ var menubar = fixture('basic');
+ menubar.selected = 1;
+ menubar.focus();
+ setTimeout(function() {
+ assert.equal(document.activeElement, menubar.selectedItem, 'document.activeElement is selected item');
+ done();
+ // wait for async in _onFocus
+ }, 200);
+ });
+
+ test('last activated item in a multi select menubar is focused', function(done) {
+ var menubar = fixture('multi');
+ menubar.selected = 0;
+ menubar.items[1].click();
+ setTimeout(function() {
+ assert.equal(document.activeElement, menubar.items[1], 'document.activeElement is last activated item');
+ done();
+ // wait for async in _onFocus
+ }, 200);
+ });
+
+ test('deselection in a multi select menubar focuses deselected item', function(done) {
+ var menubar = fixture('multi');
+ menubar.selected = 0;
+ menubar.items[0].click();
+ setTimeout(function() {
+ assert.equal(document.activeElement, menubar.items[0], 'document.activeElement is last activated item');
+ done();
+ // wait for async in _onFocus
+ }, 200);
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/test/test-menu.html b/polymer_1.0.4/bower_components/iron-menu-behavior/test/test-menu.html
new file mode 100644
index 0000000..19b1662
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/test/test-menu.html
@@ -0,0 +1,40 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../iron-menu-behavior.html">
+
+<dom-module id="test-menu">
+
+ <template>
+
+ <content></content>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'test-menu',
+
+ behaviors: [
+ Polymer.IronMenuBehavior
+ ]
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-menu-behavior/test/test-menubar.html b/polymer_1.0.4/bower_components/iron-menu-behavior/test/test-menubar.html
new file mode 100644
index 0000000..5f7ecbc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-menu-behavior/test/test-menubar.html
@@ -0,0 +1,40 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../iron-menubar-behavior.html">
+
+<dom-module id="test-menubar">
+
+ <template>
+
+ <content></content>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'test-menubar',
+
+ behaviors: [
+ Polymer.IronMenubarBehavior
+ ]
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-meta/.bower.json b/polymer_1.0.4/bower_components/iron-meta/.bower.json
new file mode 100644
index 0000000..9e65079
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-meta/.bower.json
@@ -0,0 +1,38 @@
+{
+ "name": "iron-meta",
+ "version": "1.0.3",
+ "keywords": [
+ "web-components",
+ "polymer"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Useful for sharing information across a DOM tree",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-meta.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.4",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-meta",
+ "_release": "1.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.3",
+ "commit": "91529259262b0d8f33fed44bc3fd47aedf35cb04"
+ },
+ "_source": "git://github.com/PolymerElements/iron-meta.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-meta"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-meta/.gitignore b/polymer_1.0.4/bower_components/iron-meta/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-meta/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-meta/README.md b/polymer_1.0.4/bower_components/iron-meta/README.md
new file mode 100644
index 0000000..26e2ddf
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-meta/README.md
@@ -0,0 +1,46 @@
+iron-meta
+=========
+
+`iron-meta` is a generic element you can use for sharing information across the DOM tree.
+It uses [monostate pattern](http://c2.com/cgi/wiki?MonostatePattern) such that any
+instance of iron-meta has access to the shared
+information. You can use `iron-meta` to share whatever you want (or create an extension
+[like x-meta] for enhancements).
+
+The `iron-meta` instances containing your actual data can be loaded in an import,
+or constructed in any way you see fit. The only requirement is that you create them
+before you try to access them.
+
+Examples:
+
+If I create an instance like this:
+
+```html
+<iron-meta key="info" value="foo/bar"></iron-meta>
+```
+
+Note that value="foo/bar" is the metadata I've defined. I could define more
+attributes or use child nodes to define additional metadata.
+
+Now I can access that element (and it's metadata) from any iron-meta instance
+via the byKey method, e.g.
+
+```javascript
+meta.byKey('info').getAttribute('value');
+```
+
+Pure imperative form would be like:
+
+```javascript
+document.createElement('iron-meta').byKey('info').getAttribute('value');
+```
+
+Or, in a Polymer element, you can include a meta in your template:
+
+```html
+<iron-meta id="meta"></iron-meta>
+```
+
+```javascript
+this.$.meta.byKey('info').getAttribute('value');
+```
diff --git a/polymer_1.0.4/bower_components/iron-meta/bower.json b/polymer_1.0.4/bower_components/iron-meta/bower.json
new file mode 100644
index 0000000..65a1f8f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-meta/bower.json
@@ -0,0 +1,28 @@
+{
+ "name": "iron-meta",
+ "version": "1.0.3",
+ "keywords": [
+ "web-components",
+ "polymer"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Useful for sharing information across a DOM tree",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-meta.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.4",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-meta/demo/index.html b/polymer_1.0.4/bower_components/iron-meta/demo/index.html
new file mode 100644
index 0000000..3deee3c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-meta/demo/index.html
@@ -0,0 +1,46 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <title>iron-meta</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../iron-meta.html">
+</head>
+<body>
+
+ <div class="vertical-section vertical-section-container centered">
+ <h1><iron-meta></h1>
+ <iron-meta key="info" value="foo/bar"></iron-meta>
+ The <code>value</code> stored at <code>key="info"</code> is <code><meta-test></meta-test></code>.
+ </div>
+
+ <script>
+
+ Polymer({
+
+ is: 'meta-test',
+
+ ready: function() {
+ this.textContent = new Polymer.IronMetaQuery({key: 'info'}).value;
+ }
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-meta/hero.svg b/polymer_1.0.4/bower_components/iron-meta/hero.svg
new file mode 100755
index 0000000..ea8548d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-meta/hero.svg
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <circle cx="22" cy="85" r="4"/>
+ <circle cx="88" cy="98" r="4"/>
+ <path d="M87.5,100c-3.8-0.3-5.5-2.8-7-5c-1.4-2.1-2.7-3.9-5.5-4.2c-2.8-0.3-4.4,1.3-6.2,3.1c-1.9,1.9-4,4-7.8,3.7
+ c-3.8-0.3-5.5-2.8-7-5c-1.4-2.1-2.7-3.9-5.5-4.2c-2.8-0.3-4.4,1.3-6.2,3.1c-1.9,1.9-4,4-7.8,3.7c-3.8-0.3-5.5-2.8-7-5
+ c-1.4-2.1-2.7-3.9-5.5-4.2l0.2-2c3.8,0.3,5.5,2.8,7,5c1.4,2.1,2.7,3.9,5.5,4.2c2.8,0.3,4.4-1.3,6.2-3.1c1.9-1.9,4-4,7.8-3.7
+ c3.8,0.3,5.5,2.8,7,5c1.4,2.1,2.7,3.9,5.5,4.2c2.8,0.3,4.4-1.3,6.2-3.1c1.9-1.9,4-4,7.8-3.7c3.8,0.3,5.5,2.8,7,5
+ c1.4,2.1,2.7,3.9,5.5,4.2L87.5,100z"/>
+ <circle cx="96" cy="86" r="4"/>
+ <circle cx="162" cy="98" r="4"/>
+ <rect x="95.5" y="91" transform="matrix(0.9839 0.1789 -0.1789 0.9839 18.5382 -21.5923)" width="67.1" height="2"/>
+ <g>
+ <path d="M27,41.5l4.5,13.4l4.9-13.4h5.4v32h-4.4V61l0.4-13.4l-5.4,14.5h-2L25.6,48L26,61v12.5h-4.4v-32H27z"/>
+ <path d="M67.5,58.7H53.4V70h16.4v3.5H49v-32h20.6V45H53.4v10.2h14.2V58.7z"/>
+ <path d="M98.5,45H88.3v28.5h-4.4V45H73.6v-3.5h24.9V45z"/>
+ <path d="M116.2,65.3H105l-2.6,8.2h-4.5l10.9-32h3.8l10.6,32h-4.5L116.2,65.3z M106.2,61.6h8.9l-4.4-14.2L106.2,61.6z"/>
+ </g>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/iron-meta/index.html b/polymer_1.0.4/bower_components/iron-meta/index.html
new file mode 100644
index 0000000..c70dc6e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-meta/index.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>iron-meta</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-meta/iron-meta.html b/polymer_1.0.4/bower_components/iron-meta/iron-meta.html
new file mode 100644
index 0000000..4b34311
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-meta/iron-meta.html
@@ -0,0 +1,317 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<!--
+`iron-meta` is a generic element you can use for sharing information across the DOM tree.
+It uses [monostate pattern](http://c2.com/cgi/wiki?MonostatePattern) such that any
+instance of iron-meta has access to the shared
+information. You can use `iron-meta` to share whatever you want (or create an extension
+[like x-meta] for enhancements).
+
+The `iron-meta` instances containing your actual data can be loaded in an import,
+or constructed in any way you see fit. The only requirement is that you create them
+before you try to access them.
+
+Examples:
+
+If I create an instance like this:
+
+ <iron-meta key="info" value="foo/bar"></iron-meta>
+
+Note that value="foo/bar" is the metadata I've defined. I could define more
+attributes or use child nodes to define additional metadata.
+
+Now I can access that element (and it's metadata) from any iron-meta instance
+via the byKey method, e.g.
+
+ meta.byKey('info').getAttribute('value').
+
+Pure imperative form would be like:
+
+ document.createElement('iron-meta').byKey('info').getAttribute('value');
+
+Or, in a Polymer element, you can include a meta in your template:
+
+ <iron-meta id="meta"></iron-meta>
+ ...
+ this.$.meta.byKey('info').getAttribute('value');
+
+@group Iron Elements
+@demo demo/index.html
+@hero hero.svg
+@element iron-meta
+-->
+
+<script>
+
+ (function() {
+
+ // monostate data
+ var metaDatas = {};
+ var metaArrays = {};
+
+ Polymer.IronMeta = Polymer({
+
+ is: 'iron-meta',
+
+ properties: {
+
+ /**
+ * The type of meta-data. All meta-data of the same type is stored
+ * together.
+ */
+ type: {
+ type: String,
+ value: 'default',
+ observer: '_typeChanged'
+ },
+
+ /**
+ * The key used to store `value` under the `type` namespace.
+ */
+ key: {
+ type: String,
+ observer: '_keyChanged'
+ },
+
+ /**
+ * The meta-data to store or retrieve.
+ */
+ value: {
+ type: Object,
+ notify: true,
+ observer: '_valueChanged'
+ },
+
+ /**
+ * If true, `value` is set to the iron-meta instance itself.
+ */
+ self: {
+ type: Boolean,
+ observer: '_selfChanged'
+ },
+
+ /**
+ * Array of all meta-data values for the given type.
+ */
+ list: {
+ type: Array,
+ notify: true
+ }
+
+ },
+
+ /**
+ * Only runs if someone invokes the factory/constructor directly
+ * e.g. `new Polymer.IronMeta()`
+ */
+ factoryImpl: function(config) {
+ if (config) {
+ for (var n in config) {
+ switch(n) {
+ case 'type':
+ case 'key':
+ case 'value':
+ this[n] = config[n];
+ break;
+ }
+ }
+ }
+ },
+
+ created: function() {
+ // TODO(sjmiles): good for debugging?
+ this._metaDatas = metaDatas;
+ this._metaArrays = metaArrays;
+ },
+
+ _keyChanged: function(key, old) {
+ this._resetRegistration(old);
+ },
+
+ _valueChanged: function(value) {
+ this._resetRegistration(this.key);
+ },
+
+ _selfChanged: function(self) {
+ if (self) {
+ this.value = this;
+ }
+ },
+
+ _typeChanged: function(type) {
+ this._unregisterKey(this.key);
+ if (!metaDatas[type]) {
+ metaDatas[type] = {};
+ }
+ this._metaData = metaDatas[type];
+ if (!metaArrays[type]) {
+ metaArrays[type] = [];
+ }
+ this.list = metaArrays[type];
+ this._registerKeyValue(this.key, this.value);
+ },
+
+ /**
+ * Retrieves meta data value by key.
+ *
+ * @method byKey
+ * @param {string} key The key of the meta-data to be returned.
+ * @return {*}
+ */
+ byKey: function(key) {
+ return this._metaData && this._metaData[key];
+ },
+
+ _resetRegistration: function(oldKey) {
+ this._unregisterKey(oldKey);
+ this._registerKeyValue(this.key, this.value);
+ },
+
+ _unregisterKey: function(key) {
+ this._unregister(key, this._metaData, this.list);
+ },
+
+ _registerKeyValue: function(key, value) {
+ this._register(key, value, this._metaData, this.list);
+ },
+
+ _register: function(key, value, data, list) {
+ if (key && data && value !== undefined) {
+ data[key] = value;
+ list.push(value);
+ }
+ },
+
+ _unregister: function(key, data, list) {
+ if (key && data) {
+ if (key in data) {
+ var value = data[key];
+ delete data[key];
+ this.arrayDelete(list, value);
+ }
+ }
+ }
+
+ });
+
+ /**
+ `iron-meta-query` can be used to access infomation stored in `iron-meta`.
+
+ Examples:
+
+ If I create an instance like this:
+
+ <iron-meta key="info" value="foo/bar"></iron-meta>
+
+ Note that value="foo/bar" is the metadata I've defined. I could define more
+ attributes or use child nodes to define additional metadata.
+
+ Now I can access that element (and it's metadata) from any `iron-meta-query` instance:
+
+ var value = new Polymer.IronMetaQuery({key: 'info'}).value;
+
+ @group Polymer Iron Elements
+ @element iron-meta-query
+ */
+ Polymer.IronMetaQuery = Polymer({
+
+ is: 'iron-meta-query',
+
+ properties: {
+
+ /**
+ * The type of meta-data. All meta-data of the same type is stored
+ * together.
+ */
+ type: {
+ type: String,
+ value: 'default',
+ observer: '_typeChanged'
+ },
+
+ /**
+ * Specifies a key to use for retrieving `value` from the `type`
+ * namespace.
+ */
+ key: {
+ type: String,
+ observer: '_keyChanged'
+ },
+
+ /**
+ * The meta-data to store or retrieve.
+ */
+ value: {
+ type: Object,
+ notify: true,
+ readOnly: true
+ },
+
+ /**
+ * Array of all meta-data values for the given type.
+ */
+ list: {
+ type: Array,
+ notify: true
+ }
+
+ },
+
+ /**
+ * Actually a factory method, not a true constructor. Only runs if
+ * someone invokes it directly (via `new Polymer.IronMeta()`);
+ */
+ factoryImpl: function(config) {
+ if (config) {
+ for (var n in config) {
+ switch(n) {
+ case 'type':
+ case 'key':
+ this[n] = config[n];
+ break;
+ }
+ }
+ }
+ },
+
+ created: function() {
+ // TODO(sjmiles): good for debugging?
+ this._metaDatas = metaDatas;
+ this._metaArrays = metaArrays;
+ },
+
+ _keyChanged: function(key) {
+ this._setValue(this._metaData && this._metaData[key]);
+ },
+
+ _typeChanged: function(type) {
+ this._metaData = metaDatas[type];
+ this.list = metaArrays[type];
+ if (this.key) {
+ this._keyChanged(this.key);
+ }
+ },
+
+ /**
+ * Retrieves meta data value by key.
+ * @param {string} key The key of the meta-data to be returned.
+ * @return {*}
+ */
+ byKey: function(key) {
+ return this._metaData && this._metaData[key];
+ }
+
+ });
+
+ })();
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-meta/test/basic.html b/polymer_1.0.4/bower_components/iron-meta/test/basic.html
new file mode 100644
index 0000000..c561dc3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-meta/test/basic.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-meta-basic</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+
+ <link rel="import" href="../iron-meta.html">
+
+</head>
+<body>
+
+ <iron-meta key="info" value="foo/bar"></iron-meta>
+
+ <script>
+
+ suite('basic', function() {
+
+ test('byKey', function() {
+ var meta = document.createElement('iron-meta');
+ assert.equal(meta.byKey('info'), 'foo/bar');
+ });
+
+ test('list', function() {
+ var meta = document.createElement('iron-meta');
+ assert.equal(meta.list.length, 1);
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-meta/test/index.html b/polymer_1.0.4/bower_components/iron-meta/test/index.html
new file mode 100644
index 0000000..2b9541b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-meta/test/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+
+</head>
+<body>
+
+ <script>
+ WCT.loadSuites([
+ 'basic.html',
+ 'iron-meta.html'
+ ]);
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-meta/test/iron-meta.html b/polymer_1.0.4/bower_components/iron-meta/test/iron-meta.html
new file mode 100644
index 0000000..c1a4028
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-meta/test/iron-meta.html
@@ -0,0 +1,186 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <title>iron-meta</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../iron-meta.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="TrivialMeta">
+ <template>
+ <iron-meta self key="info"></iron-meta>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="ManyMetas">
+ <template>
+ <iron-meta self key="default1"></iron-meta>
+ <iron-meta self key="default2"></iron-meta>
+ <iron-meta self key="default3"></iron-meta>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="DifferentTypedMetas">
+ <template>
+ <iron-meta self type="foo" key="foobarKey"></iron-meta>
+ <iron-meta self type="bar" key="foobarKey"></iron-meta>
+ <iron-meta self key="defaultKey"></iron-meta>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="ClashingMetas">
+ <template>
+ <iron-meta self key="baz"></iron-meta>
+ <iron-meta self key="baz"></iron-meta>
+ </template>
+ </test-fixture>
+
+ <script>
+suite('<iron-meta>', function () {
+ suite('basic behavior', function () {
+ var meta;
+
+ setup(function () {
+ meta = fixture('TrivialMeta');
+ });
+
+ teardown(function () {
+ meta.key = null;
+ });
+
+ test('uses itself as the default value', function () {
+ expect(meta.value).to.be.equal(meta);
+ });
+
+ test('can be assigned alternative values', function () {
+ meta.value = 'foobar';
+
+ expect(meta.list[0]).to.be.equal('foobar');
+ });
+
+ test('can access same-type meta values by key', function () {
+ expect(meta.byKey(meta.key)).to.be.equal(meta.value);
+ });
+
+ test('yields a list of same-type meta data', function () {
+ expect(meta.list).to.be.ok;
+ expect(meta.list.length).to.be.equal(1);
+ expect(meta.list[0]).to.be.equal(meta);
+ });
+ });
+
+ suite('many same-typed metas', function () {
+ var metas;
+
+ setup(function () {
+ metas = fixture('ManyMetas');
+ });
+
+ teardown(function () {
+ metas.forEach(function (meta) {
+ meta.key = null;
+ });
+ });
+
+ test('all cache all meta values', function () {
+ metas.forEach(function (meta, index) {
+ expect(meta.list.length).to.be.equal(metas.length);
+ expect(meta.list[index].value).to.be.equal(meta.value);
+ });
+ });
+
+ test('can be unregistered individually', function () {
+ metas[0].key = null;
+
+ expect(metas[0].list.length).to.be.equal(2);
+ expect(metas[0].list).to.be.deep.equal([metas[1], metas[2]])
+ });
+
+ test('can access each others value by key', function () {
+ expect(metas[0].byKey('default2')).to.be.equal(metas[1].value);
+ });
+ });
+
+ suite('different-typed metas', function () {
+ var metas;
+
+ setup(function () {
+ metas = fixture('DifferentTypedMetas');
+ });
+
+ teardown(function () {
+ metas.forEach(function (meta) {
+ meta.key = null;
+ });
+ });
+
+ test('cache their values separately', function () {
+ var fooMeta = metas[0];
+ var barMeta = metas[1];
+
+ expect(fooMeta.value).to.not.be.equal(barMeta.value);
+ expect(fooMeta.byKey('foobarKey')).to.be.equal(fooMeta.value);
+ expect(barMeta.byKey('foobarKey')).to.be.equal(barMeta.value);
+ });
+
+ test('cannot access values of other types', function () {
+ var defaultMeta = metas[2];
+
+ expect(defaultMeta.byKey('foobarKey')).to.be.equal(undefined);
+ });
+
+ test('only list values of their type', function () {
+ metas.forEach(function (meta) {
+ expect(meta.list.length).to.be.equal(1);
+ expect(meta.list[0]).to.be.equal(meta.value);
+ })
+ });
+ });
+
+ suite('metas with clashing keys', function () {
+ var metaPair;
+
+ setup(function () {
+ metaPair = fixture('ClashingMetas');
+ });
+
+ teardown(function () {
+ metaPair.forEach(function (meta) {
+ meta.key = null;
+ });
+ });
+
+ test('let the last value win registration against the key', function () {
+ var registeredValue = metaPair[0].byKey(metaPair[0].key);
+ var firstValue = metaPair[0].value;
+ var secondValue = metaPair[1].value;
+
+ expect(registeredValue).to.not.be.equal(firstValue);
+ expect(registeredValue).to.be.equal(secondValue);
+ });
+ });
+});
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-overlay-behavior/.bower.json b/polymer_1.0.4/bower_components/iron-overlay-behavior/.bower.json
new file mode 100644
index 0000000..861424d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-overlay-behavior/.bower.json
@@ -0,0 +1,47 @@
+{
+ "name": "iron-overlay-behavior",
+ "version": "1.0.4",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Provides a behavior for making an element an overlay",
+ "private": true,
+ "main": [
+ "iron-overlay-behavior.html"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "behavior",
+ "overlay"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-overlay-behavior.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-fit-behavior": "PolymerElements/iron-fit-behavior#^1.0.0",
+ "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-overlay-behavior",
+ "_release": "1.0.4",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.4",
+ "commit": "7939cabf4f23467a0d02b572094ef05d35ad0dcc"
+ },
+ "_source": "git://github.com/PolymerElements/iron-overlay-behavior.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-overlay-behavior"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-overlay-behavior/.gitignore b/polymer_1.0.4/bower_components/iron-overlay-behavior/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-overlay-behavior/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-overlay-behavior/README.md b/polymer_1.0.4/bower_components/iron-overlay-behavior/README.md
new file mode 100644
index 0000000..17df695
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-overlay-behavior/README.md
@@ -0,0 +1,11 @@
+# iron-overlay-behavior
+Makes an element an overlay with an optional backdrop.
+
+`iron-overlay-behavior` displays an element on top of other content. It starts out hidden and is
+displayed by calling `open()` or setting the `opened` property to `true`. It may be closed by
+calling `close()` or `cancel()`, or by setting the `opened` property to `true`.
+
+The difference between `close()` and `cancel()` is user intent. `close()` generally implies that
+the user acknowledged the content of the overlay. By default, it will cancel whenever the user taps
+outside it or presses the escape key. This behavior can be turned off via the `no-cancel-on-esc-key`
+and the `no-cancel-on-outside-click` properties.
diff --git a/polymer_1.0.4/bower_components/iron-overlay-behavior/bower.json b/polymer_1.0.4/bower_components/iron-overlay-behavior/bower.json
new file mode 100644
index 0000000..3ee071c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-overlay-behavior/bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "iron-overlay-behavior",
+ "version": "1.0.4",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Provides a behavior for making an element an overlay",
+ "private": true,
+ "main": [
+ "iron-overlay-behavior.html"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "behavior",
+ "overlay"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-overlay-behavior.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-fit-behavior": "PolymerElements/iron-fit-behavior#^1.0.0",
+ "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-overlay-behavior/demo/index.html b/polymer_1.0.4/bower_components/iron-overlay-behavior/demo/index.html
new file mode 100644
index 0000000..4fc6bb0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-overlay-behavior/demo/index.html
@@ -0,0 +1,149 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>simple-overlay demo</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../iron-flex-layout/classes/iron-flex-layout.html">
+ <!-- <link rel="import" href="../core-transition/core-transition-css.html"> -->
+ <link rel="import" href="simple-overlay.html">
+
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+
+ <style>
+
+ .with-margin {
+ margin: 24px 40px;
+ }
+
+ .full-height {
+ height: 100%;
+ }
+
+ .scrollable {
+ overflow: auto;
+ }
+
+ </style>
+
+ </head>
+ <body onclick="clickHandler(event);">
+
+ <div class="vertical-section centered">
+ <button data-dialog="plain">plain</button>
+
+ <simple-overlay id="plain">
+ Hello world!
+ </simple-overlay>
+
+ <button data-dialog="scrolling">scrolling</button>
+
+ <simple-overlay id="scrolling" class="with-margin scrollable">
+ <p>This dialog scrolls internally.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ </simple-overlay>
+
+ <button data-dialog="scrolling-2">scrolling 2</button>
+
+ <simple-overlay id="scrolling-2" class="with-margin full-height layout vertical">
+ <p>This dialog has a scrolling child.</p>
+ <div class="flex scrollable">
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ </div>
+ </simple-overlay>
+
+ <button data-dialog="multiple">multiple</button>
+
+ <simple-overlay id="multiple">
+ <p>click to open another overlay</p>
+ <p><button data-dialog="multiple2">click</button></p>
+ </simple-overlay>
+
+ <simple-overlay id="multiple2">
+ Hi!
+ </simple-overlay>
+
+ <button data-dialog="backdrop">backdrop</button>
+
+ <simple-overlay id="backdrop" with-backdrop>
+ Hello world!
+ </simple-overlay>
+
+ <button data-dialog="autofocus">autofocus</button>
+
+ <simple-overlay id="autofocus">
+ <p>Hello world!</p>
+ <button>cancel</button>
+ <button autofocus>autofocus</button>
+ </simple-overlay>
+
+ </div>
+
+ <script>
+
+ function clickHandler(e) {
+ if (!e.target.hasAttribute('data-dialog')) {
+ return;
+ }
+
+ var id = e.target.getAttribute('data-dialog');
+ var dialog = document.getElementById(id);
+ if (dialog) {
+ dialog.open();
+ }
+ }
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-overlay-behavior/demo/simple-overlay.html b/polymer_1.0.4/bower_components/iron-overlay-behavior/demo/simple-overlay.html
new file mode 100644
index 0000000..fbf305e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-overlay-behavior/demo/simple-overlay.html
@@ -0,0 +1,50 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+
+<link rel="import" href="../iron-overlay-behavior.html">
+
+<dom-module id="simple-overlay">
+
+ <style>
+
+ :host {
+ background: white;
+ color: black;
+ padding: 24px;
+ box-shadow: rgba(0, 0, 0, 0.24) -2.3408942051048403px 5.524510324047423px 12.090680100755666px 0px, rgba(0, 0, 0, 0.12) 0px 0px 12px 0px;
+ }
+
+ </style>
+
+ <template>
+ <content></content>
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'simple-overlay',
+
+ behaviors: [
+ Polymer.IronOverlayBehavior
+ ]
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-overlay-behavior/index.html b/polymer_1.0.4/bower_components/iron-overlay-behavior/index.html
new file mode 100644
index 0000000..d69e304
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-overlay-behavior/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>iron-overlay-behavior</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-overlay-behavior/iron-overlay-backdrop.html b/polymer_1.0.4/bower_components/iron-overlay-behavior/iron-overlay-backdrop.html
new file mode 100644
index 0000000..5682c28
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-overlay-behavior/iron-overlay-backdrop.html
@@ -0,0 +1,132 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="iron-overlay-manager.html">
+
+<!--
+`iron-overlay-backdrop` is a backdrop used by `Polymer.IronOverlayBehavior`. It should be a
+singleton.
+
+### Styling
+
+The following custom properties and mixins are available for styling.
+
+Custom property | Description | Default
+-------------------------------------------|------------------------|---------
+`--iron-overlay-backdrop-background-color` | Backdrop background color | #000
+`--iron-overlay-backdrop-opacity` | Backdrop opacity | 0.6
+`--iron-overlay-backdrop` | Mixin applied to `iron-overlay-backdrop`. | {}
+`--iron-overlay-backdrop-opened` | Mixin applied to `iron-overlay-backdrop` when it is displayed | {}
+-->
+
+<dom-module id="iron-overlay-backdrop">
+
+ <style>
+
+ :host {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+ background-color: var(--iron-overlay-backdrop-background-color, #000);
+ opacity: 0;
+ transition: opacity 0.2s;
+
+ @apply(--iron-overlay-backdrop);
+ }
+
+ :host([opened]) {
+ opacity: var(--iron-overlay-backdrop-opacity, 0.6);
+
+ @apply(--iron-overlay-backdrop-opened);
+ }
+
+ </style>
+
+ <template>
+ <content></content>
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'iron-overlay-backdrop',
+
+ properties: {
+
+ /**
+ * Returns true if the backdrop is opened.
+ */
+ opened: {
+ readOnly: true,
+ reflectToAttribute: true,
+ type: Boolean,
+ value: false
+ },
+
+ _manager: {
+ type: Object,
+ value: Polymer.IronOverlayManager
+ }
+
+ },
+
+ /**
+ * Appends the backdrop to document body and sets its `z-index` to be below the latest overlay.
+ */
+ prepare: function() {
+ if (!this.parentNode) {
+ Polymer.dom(document.body).appendChild(this);
+ this.style.zIndex = this._manager.currentOverlayZ() - 1;
+ }
+ },
+
+ /**
+ * Shows the backdrop if needed.
+ */
+ open: function() {
+ // only need to make the backdrop visible if this is called by the first overlay with a backdrop
+ if (this._manager.getBackdrops().length < 2) {
+ this._setOpened(true);
+ }
+ },
+
+ /**
+ * Hides the backdrop if needed.
+ */
+ close: function() {
+ // only need to make the backdrop invisible if this is called by the last overlay with a backdrop
+ if (this._manager.getBackdrops().length < 2) {
+ this._setOpened(false);
+ }
+ },
+
+ /**
+ * Removes the backdrop from document body if needed.
+ */
+ complete: function() {
+ // only remove the backdrop if there are no more overlays with backdrops
+ if (this._manager.getBackdrops().length === 0 && this.parentNode) {
+ Polymer.dom(this.parentNode).removeChild(this);
+ }
+ }
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-overlay-behavior/iron-overlay-behavior.html b/polymer_1.0.4/bower_components/iron-overlay-behavior/iron-overlay-behavior.html
new file mode 100644
index 0000000..4bc044d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-overlay-behavior/iron-overlay-behavior.html
@@ -0,0 +1,434 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-fit-behavior/iron-fit-behavior.html">
+<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html">
+<link rel="import" href="iron-overlay-backdrop.html">
+<link rel="import" href="iron-overlay-manager.html">
+
+<script>
+
+/**
+Use `Polymer.IronOverlayBehavior` to implement an element that can be hidden or shown, and displays
+on top of other content. It includes an optional backdrop, and can be used to implement a variety
+of UI controls including dialogs and drop downs. Multiple overlays may be displayed at once.
+
+### Closing and canceling
+
+A dialog may be hidden by closing or canceling. The difference between close and cancel is user
+intent. Closing generally implies that the user acknowledged the content on the overlay. By default,
+it will cancel whenever the user taps outside it or presses the escape key. This behavior is
+configurable with the `no-cancel-on-esc-key` and the `no-cancel-on-outside-click` properties.
+`close()` should be called explicitly by the implementer when the user interacts with a control
+in the overlay element.
+
+### Positioning
+
+By default the element is sized and positioned to fit and centered inside the window. You can
+position and size it manually using CSS. See `Polymer.IronFitBehavior`.
+
+### Backdrop
+
+Set the `with-backdrop` attribute to display a backdrop behind the overlay. The backdrop is
+appended to `<body>` and is of type `<iron-overlay-backdrop>`. See its doc page for styling
+options.
+
+### Limitations
+
+The element is styled to appear on top of other content by setting its `z-index` property. You
+must ensure no element has a stacking context with a higher `z-index` than its parent stacking
+context. You should place this element as a child of `<body>` whenever possible.
+
+@demo demo/index.html
+@polymerBehavior Polymer.IronOverlayBehavior
+*/
+
+ Polymer.IronOverlayBehaviorImpl = {
+
+ properties: {
+
+ /**
+ * True if the overlay is currently displayed.
+ */
+ opened: {
+ observer: '_openedChanged',
+ type: Boolean,
+ value: false,
+ notify: true
+ },
+
+ /**
+ * True if the overlay was canceled when it was last closed.
+ */
+ canceled: {
+ observer: '_canceledChanged',
+ readOnly: true,
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to display a backdrop behind the overlay.
+ */
+ withBackdrop: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to disable auto-focusing the overlay or child nodes with
+ * the `autofocus` attribute` when the overlay is opened.
+ */
+ noAutoFocus: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to disable canceling the overlay with the ESC key.
+ */
+ noCancelOnEscKey: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to disable canceling the overlay by clicking outside it.
+ */
+ noCancelOnOutsideClick: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Returns the reason this dialog was last closed.
+ */
+ closingReason: {
+ // was a getter before, but needs to be a property so other
+ // behaviors can override this.
+ type: Object
+ },
+
+ _manager: {
+ type: Object,
+ value: Polymer.IronOverlayManager
+ },
+
+ _boundOnCaptureClick: {
+ type: Function,
+ value: function() {
+ return this._onCaptureClick.bind(this);
+ }
+ },
+
+ _boundOnCaptureKeydown: {
+ type: Function,
+ value: function() {
+ return this._onCaptureKeydown.bind(this);
+ }
+ }
+
+ },
+
+/**
+ * Fired after the `iron-overlay` opens.
+ * @event iron-overlay-opened
+ */
+
+/**
+ * Fired after the `iron-overlay` closes.
+ * @event iron-overlay-closed {{canceled: boolean}} detail -
+ * canceled: True if the overlay was canceled.
+ */
+
+ listeners: {
+ 'click': '_onClick',
+ 'iron-resize': '_onIronResize'
+ },
+
+ /**
+ * The backdrop element.
+ * @type Node
+ */
+ get backdropElement() {
+ return this._backdrop;
+ },
+
+ get _focusNode() {
+ return Polymer.dom(this).querySelector('[autofocus]') || this;
+ },
+
+ registered: function() {
+ this._backdrop = document.createElement('iron-overlay-backdrop');
+ },
+
+ ready: function() {
+ this._ensureSetup();
+ if (this._callOpenedWhenReady) {
+ this._openedChanged();
+ }
+ },
+
+ detached: function() {
+ this.opened = false;
+ this._completeBackdrop();
+ this._manager.removeOverlay(this);
+ },
+
+ /**
+ * Toggle the opened state of the overlay.
+ */
+ toggle: function() {
+ this.opened = !this.opened;
+ },
+
+ /**
+ * Open the overlay.
+ */
+ open: function() {
+ this.opened = true;
+ this.closingReason = {canceled: false};
+ },
+
+ /**
+ * Close the overlay.
+ */
+ close: function() {
+ this.opened = false;
+ this._setCanceled(false);
+ },
+
+ /**
+ * Cancels the overlay.
+ */
+ cancel: function() {
+ this.opened = false,
+ this._setCanceled(true);
+ },
+
+ _ensureSetup: function() {
+ if (this._overlaySetup) {
+ return;
+ }
+ this._overlaySetup = true;
+ this.style.outline = 'none';
+ this.style.display = 'none';
+ },
+
+ _openedChanged: function() {
+ if (this.opened) {
+ this.removeAttribute('aria-hidden');
+ } else {
+ this.setAttribute('aria-hidden', 'true');
+ }
+
+ // wait to call after ready only if we're initially open
+ if (!this._overlaySetup) {
+ this._callOpenedWhenReady = this.opened;
+ return;
+ }
+ if (this._openChangedAsync) {
+ this.cancelAsync(this._openChangedAsync);
+ }
+
+ this._toggleListeners();
+
+ if (this.opened) {
+ this._prepareRenderOpened();
+ }
+
+ // async here to allow overlay layer to become visible.
+ this._openChangedAsync = this.async(function() {
+ // overlay becomes visible here
+ this.style.display = '';
+ // force layout to ensure transitions will go
+ this.offsetWidth;
+ if (this.opened) {
+ this._renderOpened();
+ } else {
+ this._renderClosed();
+ }
+ this._openChangedAsync = null;
+ });
+
+ },
+
+ _canceledChanged: function() {
+ this.closingReason = this.closingReason || {};
+ this.closingReason.canceled = this.canceled;
+ },
+
+ _toggleListener: function(enable, node, event, boundListener, capture) {
+ if (enable) {
+ node.addEventListener(event, boundListener, capture);
+ } else {
+ node.removeEventListener(event, boundListener, capture);
+ }
+ },
+
+ _toggleListeners: function() {
+ if (this._toggleListenersAsync) {
+ this.cancelAsync(this._toggleListenersAsync);
+ }
+ // async so we don't auto-close immediately via a click.
+ this._toggleListenersAsync = this.async(function() {
+ this._toggleListener(this.opened, document, 'click', this._boundOnCaptureClick, true);
+ this._toggleListener(this.opened, document, 'keydown', this._boundOnCaptureKeydown, true);
+ this._toggleListenersAsync = null;
+ });
+ },
+
+ // tasks which must occur before opening; e.g. making the element visible
+ _prepareRenderOpened: function() {
+ this._manager.addOverlay(this);
+
+ if (this.withBackdrop) {
+ this.backdropElement.prepare();
+ this._manager.trackBackdrop(this);
+ }
+
+ this._preparePositioning();
+ this.fit();
+ this._finishPositioning();
+ },
+
+ // tasks which cause the overlay to actually open; typically play an
+ // animation
+ _renderOpened: function() {
+ if (this.withBackdrop) {
+ this.backdropElement.open();
+ }
+ this._finishRenderOpened();
+ },
+
+ _renderClosed: function() {
+ if (this.withBackdrop) {
+ this.backdropElement.close();
+ }
+ this._finishRenderClosed();
+ },
+
+ _onTransitionend: function(event) {
+ // make sure this is our transition event.
+ if (event && event.target !== this) {
+ return;
+ }
+ if (this.opened) {
+ this._finishRenderOpened();
+ } else {
+ this._finishRenderClosed();
+ }
+ },
+
+ _finishRenderOpened: function() {
+ // focus the child node with [autofocus]
+ if (!this.noAutoFocus) {
+ this._focusNode.focus();
+ }
+
+ this.fire('iron-overlay-opened');
+
+ this._squelchNextResize = true;
+ this.async(this.notifyResize);
+ },
+
+ _finishRenderClosed: function() {
+ // hide the overlay and remove the backdrop
+ this.resetFit();
+ this.style.display = 'none';
+ this._completeBackdrop();
+ this._manager.removeOverlay(this);
+
+ this._focusNode.blur();
+ // focus the next overlay, if there is one
+ this._manager.focusOverlay();
+
+ this.fire('iron-overlay-closed', this.closingReason);
+
+ this._squelchNextResize = true;
+ this.async(this.notifyResize);
+ },
+
+ _completeBackdrop: function() {
+ if (this.withBackdrop) {
+ this._manager.trackBackdrop(this);
+ this.backdropElement.complete();
+ }
+ },
+
+ _preparePositioning: function() {
+ this.style.transition = this.style.webkitTransition = 'none';
+ this.style.transform = this.style.webkitTransform = 'none';
+ this.style.display = '';
+ },
+
+ _finishPositioning: function() {
+ this.style.display = 'none';
+ this.style.transform = this.style.webkitTransform = '';
+ // force layout to avoid application of transform
+ this.offsetWidth;
+ this.style.transition = this.style.webkitTransition = '';
+ },
+
+ _applyFocus: function() {
+ if (this.opened) {
+ if (!this.noAutoFocus) {
+ this._focusNode.focus();
+ }
+ } else {
+ this._focusNode.blur();
+ this._manager.focusOverlay();
+ }
+ },
+
+ _onCaptureClick: function(event) {
+ // attempt to close asynchronously and prevent the close of a tap event is immediately heard
+ // on target. This is because in shadow dom due to event retargetting event.target is not
+ // useful.
+ if (!this.noCancelOnOutsideClick && (this._manager.currentOverlay() == this)) {
+ this._cancelJob = this.async(function() {
+ this.cancel();
+ }, 10);
+ }
+ },
+
+ _onClick: function(event) {
+ if (this._cancelJob) {
+ this.cancelAsync(this._cancelJob);
+ this._cancelJob = null;
+ }
+ },
+
+ _onCaptureKeydown: function(event) {
+ var ESC = 27;
+ if (!this.noCancelOnEscKey && (event.keyCode === ESC)) {
+ this.cancel();
+ event.stopPropagation();
+ }
+ },
+
+ _onIronResize: function() {
+ if (this._squelchNextResize) {
+ this._squelchNextResize = false;
+ return;
+ }
+ if (this.opened) {
+ this.refit();
+ }
+ }
+
+ };
+
+ /** @polymerBehavior */
+ Polymer.IronOverlayBehavior = [Polymer.IronFitBehavior, Polymer.IronResizableBehavior, Polymer.IronOverlayBehaviorImpl];
+
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-overlay-behavior/iron-overlay-manager.html b/polymer_1.0.4/bower_components/iron-overlay-behavior/iron-overlay-manager.html
new file mode 100644
index 0000000..c66f9aa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-overlay-behavior/iron-overlay-manager.html
@@ -0,0 +1,107 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+
+ Polymer.IronOverlayManager = (function() {
+
+ var overlays = [];
+ var DEFAULT_Z = 10;
+ var backdrops = [];
+
+ // track overlays for z-index and focus managemant
+ function addOverlay(overlay) {
+ var z0 = currentOverlayZ();
+ overlays.push(overlay);
+ var z1 = currentOverlayZ();
+ if (z1 <= z0) {
+ applyOverlayZ(overlay, z0);
+ }
+ }
+
+ function removeOverlay(overlay) {
+ var i = overlays.indexOf(overlay);
+ if (i >= 0) {
+ overlays.splice(i, 1);
+ setZ(overlay, '');
+ }
+ }
+
+ function applyOverlayZ(overlay, aboveZ) {
+ setZ(overlay, aboveZ + 2);
+ }
+
+ function setZ(element, z) {
+ element.style.zIndex = z;
+ }
+
+ function currentOverlay() {
+ return overlays[overlays.length-1];
+ }
+
+ function currentOverlayZ() {
+ var z;
+ var current = currentOverlay();
+ if (current) {
+ var z1 = window.getComputedStyle(current).zIndex;
+ if (!isNaN(z1)) {
+ z = Number(z1);
+ }
+ }
+ return z || DEFAULT_Z;
+ }
+
+ function focusOverlay() {
+ var current = currentOverlay();
+ // We have to be careful to focus the next overlay _after_ any current
+ // transitions are complete (due to the state being toggled prior to the
+ // transition). Otherwise, we risk infinite recursion when a transitioning
+ // (closed) overlay becomes the current overlay.
+ //
+ // NOTE: We make the assumption that any overlay that completes a transition
+ // will call into focusOverlay to kick the process back off. Currently:
+ // transitionend -> _applyFocus -> focusOverlay.
+ if (current && !current.transitioning) {
+ current._applyFocus();
+ }
+ }
+
+ function trackBackdrop(element) {
+ // backdrops contains the overlays with a backdrop that are currently
+ // visible
+ if (element.opened) {
+ backdrops.push(element);
+ } else {
+ var index = backdrops.indexOf(element);
+ if (index >= 0) {
+ backdrops.splice(index, 1);
+ }
+ }
+ }
+
+ function getBackdrops() {
+ return backdrops;
+ }
+
+ return {
+ addOverlay: addOverlay,
+ removeOverlay: removeOverlay,
+ currentOverlay: currentOverlay,
+ currentOverlayZ: currentOverlayZ,
+ focusOverlay: focusOverlay,
+ trackBackdrop: trackBackdrop,
+ getBackdrops: getBackdrops
+ };
+
+ })();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-overlay-behavior/test/index.html b/polymer_1.0.4/bower_components/iron-overlay-behavior/test/index.html
new file mode 100644
index 0000000..9041313
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-overlay-behavior/test/index.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>iron-overlay-behavior tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'iron-overlay-behavior.html',
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-overlay-behavior/test/iron-overlay-behavior.html b/polymer_1.0.4/bower_components/iron-overlay-behavior/test/iron-overlay-behavior.html
new file mode 100644
index 0000000..4829439
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-overlay-behavior/test/iron-overlay-behavior.html
@@ -0,0 +1,314 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>iron-overlay-behavior tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+ <script src="../../iron-test-helpers/test-helpers.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="test-overlay.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="basic">
+ <template>
+ <test-overlay>
+ Basic Overlay
+ </test-overlay>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="opened">
+ <template>
+ <test-overlay opened>
+ Basic Overlay
+ </test-overlay>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="autofocus">
+ <template>
+ <test-overlay>
+ Autofocus
+ <button autofocus>button</button>
+ </test-overlay>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="multiple">
+ <template>
+ <test-overlay class="overlay-1">
+ Overlay 1
+ </test-overlay>
+ <test-overlay class="overlay-2">
+ Overlay 2
+ </test-overlay>
+ <test-overlay class="overlay-3">
+ Overlay 3
+ </test-overlay>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="backdrop-multiple">
+ <template>
+ <test-overlay with-backdrop class="overlay-1">
+ Overlay 1 with backdrop
+ </test-overlay>
+ <test-overlay with-backdrop class="overlay-2">
+ Overlay 2 with backdrop
+ </test-overlay>
+ <test-overlay with-backdrop class="overlay-3">
+ Overlay 3 with backdrop
+ </test-overlay>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ function runAfterOpen(overlay, cb) {
+ overlay.addEventListener('iron-overlay-opened', function() {
+ cb();
+ });
+ overlay.open();
+ }
+
+ suite('basic overlay tests', function() {
+ var overlay;
+
+ setup(function() {
+ overlay = fixture('basic');
+ });
+
+ test('overlay starts hidden', function() {
+ assert.isFalse(overlay.opened, 'overlay starts closed');
+ assert.equal(getComputedStyle(overlay).display, 'none', 'overlay starts hidden');
+ });
+
+ test('overlay open by default', function() {
+ overlay = fixture('opened');
+ runAfterOpen(overlay, function() {
+ assert.isTrue(overlay.opened, 'overlay starts opened');
+ assert.notEqual(getComputedStyle(overlay).display, 'none', 'overlay starts showing');
+ });
+ });
+
+ test('overlay open/close events', function(done) {
+ var nevents = 0;
+
+ overlay.addEventListener('iron-overlay-opened', function() {
+ nevents += 1;
+ overlay.opened = false;
+ });
+
+ overlay.addEventListener('iron-overlay-closed', function() {
+ nevents += 1;
+ assert.equal(nevents, 2, 'opened and closed events fired');
+ done();
+ });
+
+ overlay.opened = true;
+ });
+
+ test('close an overlay quickly after open', function(done) {
+ // first, open the overlay
+ overlay.open();
+ overlay.async(function() {
+ // during the opening transition, close the overlay
+ this.close();
+ // wait for any exceptions to be thrown until the transition is done
+ this.async(function() {
+ done();
+ }, 300);
+ });
+ });
+
+ test('clicking an overlay does not close it', function(done) {
+ runAfterOpen(overlay, function() {
+ overlay.addEventListener('iron-overlay-closed', function() {
+ assert('iron-overlay-closed should not fire');
+ });
+ overlay.fire('click');
+ setTimeout(function() {
+ done();
+ }, 10);
+ });
+ });
+
+ test('node with autofocus is focused', function(done) {
+ overlay = fixture('autofocus');
+ runAfterOpen(overlay, function() {
+ assert.equal(Polymer.dom(overlay).querySelector('[autofocus]'), document.activeElement, '<button autofocus> is focused');
+ done();
+ });
+ });
+
+ test('cancel an overlay by clicking outside', function(done) {
+ runAfterOpen(overlay, function() {
+ overlay.addEventListener('iron-overlay-closed', function(event) {
+ assert.isTrue(event.detail.canceled, 'overlay is canceled');
+ done();
+ });
+ Polymer.Base.fire.call(document, 'click');
+ });
+ });
+
+ test('cancel an overlay with esc key', function(done) {
+ runAfterOpen(overlay, function() {
+ overlay.addEventListener('iron-overlay-closed', function(event) {
+ assert.isTrue(event.detail.canceled, 'overlay is canceled');
+ done();
+ });
+ fireEvent('keydown', {
+ keyCode: 27
+ }, document);
+ });
+ });
+
+ test('no-cancel-on-outside-click property', function(done) {
+ overlay.noCancelOnOutsideClick = true;
+ runAfterOpen(overlay, function() {
+ overlay.addEventListener('iron-overlay-closed', function() {
+ assert('iron-overlay-closed should not fire');
+ });
+ Polymer.Base.fire.call(document, 'click');
+ setTimeout(function() {
+ done();
+ }, 10);
+ });
+ });
+
+ test('no-cancel-on-esc-key property', function(done) {
+ overlay.noCancelOnEscKey = true;
+ runAfterOpen(overlay, function() {
+ overlay.addEventListener('iron-overlay-closed', function() {
+ assert('iron-overlay-cancel should not fire');
+ });
+ fireEvent('keydown', {
+ keyCode: 27
+ }, document);
+ setTimeout(function() {
+ done();
+ }, 10);
+ });
+ });
+
+ });
+
+ suite('multiple overlays', function() {
+ var overlays;
+
+ setup(function() {
+ overlays = fixture('multiple');
+ });
+
+ test('new overlays appear on top', function(done) {
+ runAfterOpen(overlays[0], function() {
+ runAfterOpen(overlays[1], function() {
+ var styleZ = parseInt(window.getComputedStyle(overlays[0]).zIndex, 10);
+ var styleZ1 = parseInt(window.getComputedStyle(overlays[1]).zIndex, 10);
+ assert.isTrue(styleZ1 > styleZ, 'overlays[1] has higher z-index than overlays[0]');
+ done();
+ });
+ });
+ });
+ });
+
+ suite('overlays with backdrop', function() {
+ var overlays;
+
+ setup(function() {
+ overlays = fixture('backdrop-multiple');
+ });
+
+ test('backdrop appears behind the overlay', function(done) {
+ runAfterOpen(overlays[0], function() {
+ assert.isDefined(overlays[0].backdropElement, 'backdrop is defined');
+ assert.isDefined(overlays[0].backdropElement.parentNode, 'backdrop is inserted in the DOM');
+
+ styleZ = parseInt(window.getComputedStyle(overlays[0]).zIndex, 10);
+ backdropStyleZ = parseInt(window.getComputedStyle(overlays[0].backdropElement).zIndex, 10);
+ assert.isTrue(styleZ > backdropStyleZ, 'overlay has higher z-index than backdrop');
+ done();
+ });
+ });
+
+ test('backdrop is removed when the element is removed from DOM', function(done) {
+ runAfterOpen(overlays[0], function() {
+ var backdrop = overlays[0].backdropElement;
+ Polymer.dom(backdrop.parentNode).removeChild(backdrop);
+ Polymer.dom.flush();
+ assert.isNull(backdrop.parentNode, 'backdrop is removed from DOM');
+ done();
+ });
+ });
+
+ test('backdrop is opened when iron-overlay-open-completed fires', function(done) {
+ runAfterOpen(overlays[0], function() {
+ assert.isTrue(overlays[0].backdropElement.opened, 'backdrop is opened');
+ done();
+ });
+ });
+ });
+
+ suite('multiple overlays with backdrop', function() {
+ var overlays;
+
+ setup(function() {
+ overlays = fixture('backdrop-multiple');
+ });
+
+ test('multiple overlays share the same backdrop', function() {
+ assert.isTrue(overlays[0].backdropElement === overlays[1].backdropElement, 'overlays[0] has the same backdrop element as overlays[1]');
+ });
+
+ test('newest overlay appear on top', function(done) {
+ runAfterOpen(overlays[0], function() {
+ runAfterOpen(overlays[1], function() {
+ var styleZ = parseInt(window.getComputedStyle(overlays[0]).zIndex, 10);
+ var style1Z = parseInt(window.getComputedStyle(overlays[1]).zIndex, 10);
+ var bgStyleZ = parseInt(window.getComputedStyle(overlays[0].backdropElement).zIndex, 10);
+ assert.isTrue(style1Z > styleZ, 'overlays[1] has higher z-index than overlays[0]');
+ assert.isTrue(styleZ > bgStyleZ, 'overlays[0] has higher z-index than backdrop');
+ done();
+ });
+ });
+ });
+
+ });
+
+ suite('a11y', function() {
+
+ test('overlay has aria-hidden=true when opened', function() {
+ var overlay = fixture('basic');
+ assert.equal(overlay.getAttribute('aria-hidden'), 'true', 'overlay has aria-hidden="true"');
+ overlay.open();
+ assert.isFalse(overlay.hasAttribute('aria-hidden'), 'overlay does not have aria-hidden attribute');
+ overlay.close();
+ assert.equal(overlay.getAttribute('aria-hidden'), 'true', 'overlay has aria-hidden="true"');
+ });
+
+ })
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-overlay-behavior/test/test-overlay.html b/polymer_1.0.4/bower_components/iron-overlay-behavior/test/test-overlay.html
new file mode 100644
index 0000000..96adc56
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-overlay-behavior/test/test-overlay.html
@@ -0,0 +1,49 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+
+<link rel="import" href="../iron-overlay-behavior.html">
+
+<dom-module id="test-overlay">
+
+ <style>
+
+ :host {
+ background: white;
+ color: black;
+ border: 1px solid black;
+ }
+
+ </style>
+
+ <template>
+ <content></content>
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'test-overlay',
+
+ behaviors: [
+ Polymer.IronOverlayBehavior
+ ]
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-pages/.bower.json b/polymer_1.0.4/bower_components/iron-pages/.bower.json
new file mode 100644
index 0000000..7bf8124
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-pages/.bower.json
@@ -0,0 +1,42 @@
+{
+ "name": "iron-pages",
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Organizes a set of pages and shows one at a time",
+ "main": "iron-pages.html",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-pages.git"
+ },
+ "keywords": [
+ "web-components",
+ "polymer",
+ "container"
+ ],
+ "dependencies": {
+ "iron-resizable-behavior": "polymerelements/iron-resizable-behavior#^1.0.0",
+ "iron-selector": "polymerelements/iron-selector#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-pages",
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "061e9ea95b58880f0f992b081c52a06665b553c9"
+ },
+ "_source": "git://github.com/PolymerElements/iron-pages.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-pages"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-pages/.gitignore b/polymer_1.0.4/bower_components/iron-pages/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-pages/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-pages/README.md b/polymer_1.0.4/bower_components/iron-pages/README.md
new file mode 100644
index 0000000..716ccc3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-pages/README.md
@@ -0,0 +1,22 @@
+iron-pages
+==========
+
+`iron-pages` is used to select one of its children to show. One use is to cycle through a list of
+children "pages".
+
+Example:
+
+```html
+<iron-pages selected="0">
+ <div>One</div>
+ <div>Two</div>
+ <div>Three</div>
+</iron-pages>
+
+<script>
+ document.addEventListener('click', function(e) {
+ var pages = document.querySelector('iron-pages');
+ pages.selectNext();
+ });
+</script>
+```
diff --git a/polymer_1.0.4/bower_components/iron-pages/bower.json b/polymer_1.0.4/bower_components/iron-pages/bower.json
new file mode 100644
index 0000000..c41be27
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-pages/bower.json
@@ -0,0 +1,32 @@
+{
+ "name": "iron-pages",
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Organizes a set of pages and shows one at a time",
+ "main": "iron-pages.html",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-pages.git"
+ },
+ "keywords": [
+ "web-components",
+ "polymer",
+ "container"
+ ],
+ "dependencies": {
+ "iron-resizable-behavior": "polymerelements/iron-resizable-behavior#^1.0.0",
+ "iron-selector": "polymerelements/iron-selector#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.2",
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-pages/demo/index.html b/polymer_1.0.4/bower_components/iron-pages/demo/index.html
new file mode 100644
index 0000000..68425e8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-pages/demo/index.html
@@ -0,0 +1,77 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-pages</title>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link href="../../paper-styles/paper-styles.html" rel="import">
+ <link rel="import" href="../iron-pages.html">
+
+ <style is="custom-style">
+ iron-pages {
+ @apply(--layout-fit);
+
+ color: white;
+ margin: auto;
+ cursor: default;
+ }
+
+ iron-pages div {
+ @apply(--layout);
+ @apply(--layout-center);
+ @apply(--layout-center-justified);
+ @apply(--paper-font-display1);
+
+ width: 100%;
+ height: 100%;
+ font-size: 50px;
+ }
+
+ iron-pages div:nth-child(1) {
+ background-color: var(--google-blue-500);
+ }
+
+ iron-pages div:nth-child(2) {
+ background-color: var(--google-red-500);
+ }
+
+ iron-pages div:nth-child(3) {
+ background-color: var(--google-green-500);
+ }
+
+ </style>
+</head>
+<body class="fullbleed" unresolved>
+
+ <iron-pages selected="0">
+ <div>Page One</div>
+ <div>Page Two</div>
+ <div>Page Three</div>
+ </iron-pages>
+
+ <script>
+
+ document.addEventListener('click', function(e) {
+ var pages = document.querySelector('iron-pages');
+ pages.selectNext();
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-pages/hero.svg b/polymer_1.0.4/bower_components/iron-pages/hero.svg
new file mode 100755
index 0000000..fa12783
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-pages/hero.svg
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <path d="M143.3,73.6H51.7V26.7h91.6V73.6z M53.7,71.6h87.6V28.7H53.7V71.6z"/>
+ <path d="M158.3,85.4H66.7V38.6h91.6V85.4z M68.7,83.4h87.6V40.6H68.7V83.4z"/>
+ <path d="M172,99H80.4V52.1H172V99z M82.4,97H170V54.1H82.4V97z"/>
+ <circle cx="53" cy="28" r="4"/>
+ <circle cx="171" cy="98" r="4"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/iron-pages/index.html b/polymer_1.0.4/bower_components/iron-pages/index.html
new file mode 100644
index 0000000..67ae088
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-pages/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+ <title>iron-pages</title>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-pages/iron-pages.html b/polymer_1.0.4/bower_components/iron-pages/iron-pages.html
new file mode 100644
index 0000000..1753f0e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-pages/iron-pages.html
@@ -0,0 +1,95 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html">
+<link rel="import" href="../iron-selector/iron-selectable.html">
+
+<!--
+`iron-pages` is used to select one of its children to show. One use is to cycle through a list of
+children "pages".
+
+Example:
+
+ <iron-pages selected="0">
+ <div>One</div>
+ <div>Two</div>
+ <div>Three</div>
+ </iron-pages>
+
+ <script>
+ document.addEventListener('click', function(e) {
+ var pages = document.querySelector('iron-pages');
+ pages.selectNext();
+ });
+ </script>
+
+@group Iron Elements
+@class iron-pages
+@hero hero.svg
+@demo demo/index.html
+@extends iron-selector
+-->
+
+<dom-module id="iron-pages">
+
+ <style>
+
+ :host {
+ display: block;
+ }
+
+ :host > ::content > :not(.iron-selected) {
+ display: none !important;
+ }
+
+ </style>
+
+ <template>
+
+ <content></content>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'iron-pages',
+
+ behaviors: [
+ Polymer.IronResizableBehavior,
+ Polymer.IronSelectableBehavior
+ ],
+
+ properties: {
+
+ // as the selected page is the only one visible, activateEvent
+ // is both non-sensical and problematic; e.g. in cases where a user
+ // handler attempts to change the page and the activateEvent
+ // handler immediately changes it back
+ activateEvent: {
+ value: null
+ }
+
+ },
+
+ observers: [
+ '_selectedPageChanged(selected)'
+ ],
+
+ _selectedPageChanged: function(selected, old) {
+ this.async(this.notifyResize);
+ }
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-pages/test/attr-for-selected.html b/polymer_1.0.4/bower_components/iron-pages/test/attr-for-selected.html
new file mode 100644
index 0000000..22fe162
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-pages/test/attr-for-selected.html
@@ -0,0 +1,91 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <title>iron-pages-attr-for-selected</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../iron-pages.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="basic">
+ <template>
+ <iron-pages attr-for-selected="name" selected="page0">
+ <div name="page0">Page 0</div>
+ <div name="page1">Page 1</div>
+ <div name="page2">Page 2</div>
+ <div name="page3">Page 3</div>
+ </iron-pages>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+ var pages;
+
+ suite('honor the selected attribute', function() {
+ setup(function () {
+ pages = fixture('basic');
+ });
+
+ test('selected value', function() {
+ assert.equal(pages.selected, 'page0');
+ });
+
+ test('selected item', function() {
+ assert.equal(pages.selectedItem, pages.items[0]);
+ });
+
+ test('selected item is display:block and all others are display:none', function() {
+ pages.items.forEach(function(p) {
+ assert.equal(getComputedStyle(p).display, p == pages.selectedItem ? 'block' : 'none');
+ });
+ });
+ });
+
+ suite('set selected attribute', function() {
+ setup(function () {
+ pages = fixture('basic');
+ pages.selected = 'page2';
+ });
+
+ test('selected value', function() {
+ assert.equal(pages.selected, 'page2');
+ });
+
+ test('selected item', function() {
+ assert.equal(pages.selectedItem, pages.items[2]);
+ });
+
+ test('selected item is display:block and all others are display:none', function() {
+ pages.items.forEach(function(p) {
+ assert.equal(getComputedStyle(p).display, p == pages.selectedItem ? 'block' : 'none');
+ });
+ });
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-pages/test/basic.html b/polymer_1.0.4/bower_components/iron-pages/test/basic.html
new file mode 100644
index 0000000..5c83322
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-pages/test/basic.html
@@ -0,0 +1,101 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <title>iron-pages-basic</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../iron-pages.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="basic">
+ <template>
+ <iron-pages>
+ <div id="page0">Page 0</div>
+ <div id="page1">Page 1</div>
+ <div id="page2">Page 2</div>
+ <div id="page3">Page 3</div>
+ </iron-pages>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+ var pages;
+
+ suite('defaults', function() {
+ setup(function () {
+ pages = fixture('basic');
+ });
+
+ test('to nothing selected', function() {
+ assert.equal(pages.selected, undefined);
+ });
+
+ test('null activateEvent', function() {
+ // `activateEvent` is not a useful feature for iron-pages and it can interfere
+ // with ux; ensure iron-pages has cleared any default `activateEvent`
+ assert.equal(pages.activateEvent, null);
+ });
+
+ test('to iron-selected as selectedClass', function() {
+ assert.equal(pages.selectedClass, 'iron-selected');
+ });
+
+ test('as many items as children', function() {
+ assert.equal(pages.items.length, 4);
+ });
+
+ test('all pages are display:none', function() {
+ pages.items.forEach(function(p) {
+ assert.equal(getComputedStyle(p).display, 'none');
+ });
+ });
+ });
+
+ suite('set the selected attribute', function() {
+ setup(function () {
+ pages = fixture('basic');
+ pages.selected = 0;
+ });
+
+ test('selected value', function() {
+ assert.equal(pages.selected, '0');
+ });
+
+ test('selected item', function() {
+ assert.equal(pages.selectedItem, pages.items[0]);
+ });
+
+ test('selected item is display:block and all others are display:none', function() {
+ pages.items.forEach(function(p) {
+ assert.equal(getComputedStyle(p).display, p == pages.selectedItem ? 'block' : 'none');
+ });
+ });
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-pages/test/index.html b/polymer_1.0.4/bower_components/iron-pages/test/index.html
new file mode 100644
index 0000000..2a3282b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-pages/test/index.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <meta charset="utf-8">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'basic.html',
+ 'attr-for-selected.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-range-behavior/.bower.json b/polymer_1.0.4/bower_components/iron-range-behavior/.bower.json
new file mode 100644
index 0000000..0a4896f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-range-behavior/.bower.json
@@ -0,0 +1,40 @@
+{
+ "name": "iron-range-behavior",
+ "version": "1.0.1",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Provides a behavior for something with a minimum and maximum value",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "behavior"
+ ],
+ "main": [
+ "iron-range-behavior.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-range-behavior.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-input": "PolymerElements/iron-input#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-range-behavior",
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "80aa8588f3b8527b96f3206655b29e23970fb7a3"
+ },
+ "_source": "git://github.com/PolymerElements/iron-range-behavior.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-range-behavior"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-range-behavior/.gitignore b/polymer_1.0.4/bower_components/iron-range-behavior/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-range-behavior/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-range-behavior/README.md b/polymer_1.0.4/bower_components/iron-range-behavior/README.md
new file mode 100644
index 0000000..8d523bc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-range-behavior/README.md
@@ -0,0 +1,4 @@
+iron-range-behavior
+==========
+
+`Polymer.IronRangeBehavior` provides the behavior for something with a minimum to maximum range.
diff --git a/polymer_1.0.4/bower_components/iron-range-behavior/bower.json b/polymer_1.0.4/bower_components/iron-range-behavior/bower.json
new file mode 100644
index 0000000..2f3cea4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-range-behavior/bower.json
@@ -0,0 +1,30 @@
+{
+ "name": "iron-range-behavior",
+ "version": "1.0.1",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Provides a behavior for something with a minimum and maximum value",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "behavior"
+ ],
+ "main": [
+ "iron-range-behavior.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-range-behavior.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-input": "PolymerElements/iron-input#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-range-behavior/demo/index.html b/polymer_1.0.4/bower_components/iron-range-behavior/demo/index.html
new file mode 100644
index 0000000..87d06e5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-range-behavior/demo/index.html
@@ -0,0 +1,76 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<!doctype html>
+<html>
+ <head>
+ <title>iron-range-behavior demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../iron-range-behavior.html">
+ <link rel="import" href="../../iron-input/iron-input.html">
+
+ <style>
+
+ body {
+ font-family: sans-serif;
+ }
+
+ </style>
+ </head>
+
+ <body>
+ <dom-module id="x-progressbar">
+ <style>
+ :host {
+ display: block;
+ height: 40px;
+ background-color: #555;
+ border-radius: 4px;
+ padding: 8px;
+ box-shadow: inset 0px 2px 5px rgba(0, 0, 0, 0.5);
+ }
+
+ .progress {
+ background-color: #999;
+ height: 100%;
+ border-radius: 4px;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
+ }
+
+ .progress-value {
+ padding: 0 8px;
+ font-size: 18px;
+ color: #fff;
+ }
+ </style>
+ <template>
+ <div class="progress" horizontal center layout style$="{{_computeStyle(ratio)}}">
+ <div class="progress-value"><span>{{ratio}}</span>%</div>
+ </div>
+ </template>
+ </dom-module>
+
+ <script>
+ Polymer({
+ is: 'x-progressbar',
+
+ behaviors: [Polymer.IronRangeBehavior],
+
+ _computeStyle: function(ratio) {
+ return 'width: ' + ratio + '%;';
+ }
+ });
+ </script>
+
+ <x-progressbar min="0" max="200" value="120"></x-progressbar>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-range-behavior/index.html b/polymer_1.0.4/bower_components/iron-range-behavior/index.html
new file mode 100644
index 0000000..25ed936
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-range-behavior/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-range-behavior/iron-range-behavior.html b/polymer_1.0.4/bower_components/iron-range-behavior/iron-range-behavior.html
new file mode 100644
index 0000000..d89843d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-range-behavior/iron-range-behavior.html
@@ -0,0 +1,101 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+
+ /**
+ * `iron-range-behavior` provides the behavior for something with a minimum to maximum range.
+ *
+ * @demo demo/index.html
+ * @polymerBehavior
+ */
+ Polymer.IronRangeBehavior = {
+
+ properties: {
+
+ /**
+ * The number that represents the current value.
+ */
+ value: {
+ type: Number,
+ value: 0,
+ notify: true,
+ reflectToAttribute: true
+ },
+
+ /**
+ * The number that indicates the minimum value of the range.
+ */
+ min: {
+ type: Number,
+ value: 0,
+ notify: true
+ },
+
+ /**
+ * The number that indicates the maximum value of the range.
+ */
+ max: {
+ type: Number,
+ value: 100,
+ notify: true
+ },
+
+ /**
+ * Specifies the value granularity of the range's value.
+ */
+ step: {
+ type: Number,
+ value: 1,
+ notify: true
+ },
+
+ /**
+ * Returns the ratio of the value.
+ */
+ ratio: {
+ type: Number,
+ value: 0,
+ readOnly: true,
+ notify: true
+ },
+ },
+
+ observers: [
+ '_update(value, min, max, step)'
+ ],
+
+ _calcRatio: function(value) {
+ return (this._clampValue(value) - this.min) / (this.max - this.min);
+ },
+
+ _clampValue: function(value) {
+ return Math.min(this.max, Math.max(this.min, this._calcStep(value)));
+ },
+
+ _calcStep: function(value) {
+ return this.step ? (Math.round(value / this.step) / (1 / this.step)) : value;
+ },
+
+ _validateValue: function() {
+ var v = this._clampValue(this.value);
+ this.value = this.oldValue = isNaN(v) ? this.oldValue : v;
+ return this.value !== v;
+ },
+
+ _update: function() {
+ this._validateValue();
+ this._setRatio(this._calcRatio(this.value) * 100);
+ }
+
+};
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-range-behavior/test/basic.html b/polymer_1.0.4/bower_components/iron-range-behavior/test/basic.html
new file mode 100644
index 0000000..cee33a3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-range-behavior/test/basic.html
@@ -0,0 +1,119 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>iron-range-behavior</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../iron-range-behavior.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+</head>
+<body>
+
+ <script>
+ Polymer({
+ is: 'x-progressbar',
+
+ behaviors: [Polymer.IronRangeBehavior]
+ });
+ </script>
+
+ <test-fixture id="trivialRange">
+ <template>
+ <x-progressbar></x-progressbar>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('<x-progressbar>', function() {
+ var range;
+
+ setup(function() {
+ range = fixture('trivialRange');
+ });
+
+ test('check default', function() {
+ assert.equal(range.min, 0);
+ assert.equal(range.max, 100);
+ assert.equal(range.value, 0);
+ });
+
+ test('set value', function(done) {
+ range.value = 50;
+ asyncPlatformFlush(function() {
+ assert.equal(range.value, 50);
+ // test clamp value
+ range.value = 60.1;
+ asyncPlatformFlush(function() {
+ assert.equal(range.value, 60);
+ done();
+ });
+ });
+ });
+
+ test('set max', function(done) {
+ range.max = 10;
+ range.value = 11;
+ asyncPlatformFlush(function() {
+ assert.equal(range.value, range.max);
+ done();
+ });
+ });
+
+ test('test ratio', function(done) {
+ range.max = 10;
+ range.value = 5;
+ asyncPlatformFlush(function() {
+ assert.equal(range.ratio, 50);
+ done();
+ });
+ });
+
+ test('set min', function(done) {
+ range.min = 10
+ range.max = 50;
+ range.value = 30;
+ asyncPlatformFlush(function() {
+ assert.equal(range.ratio, 50);
+ range.value = 0;
+ asyncPlatformFlush(function() {
+ assert.equal(range.value, range.min);
+ done();
+ });
+ });
+ });
+
+ test('set step', function(done) {
+ range.min = 0;
+ range.max = 10;
+ range.value = 5.1;
+ asyncPlatformFlush(function() {
+ assert.equal(range.value, 5);
+ range.step = 0.1;
+ range.value = 5.1;
+ asyncPlatformFlush(function() {
+ assert.equal(range.value, 5.1);
+ done();
+ });
+ });
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-range-behavior/test/index.html b/polymer_1.0.4/bower_components/iron-range-behavior/test/index.html
new file mode 100644
index 0000000..f07aca9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-range-behavior/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-resizable-behavior/.bower.json b/polymer_1.0.4/bower_components/iron-resizable-behavior/.bower.json
new file mode 100644
index 0000000..9ae5e84
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-resizable-behavior/.bower.json
@@ -0,0 +1,40 @@
+{
+ "name": "iron-resizable-behavior",
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Coordinates the flow of resizeable elements",
+ "private": true,
+ "main": "iron-resizable-behavior.html",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "iron",
+ "behavior"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-resizable-behavior.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-resizable-behavior",
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "85de8ba28be2bf17c81d6436ef1119022b003674"
+ },
+ "_source": "git://github.com/PolymerElements/iron-resizable-behavior.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-resizable-behavior"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-resizable-behavior/.gitignore b/polymer_1.0.4/bower_components/iron-resizable-behavior/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-resizable-behavior/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-resizable-behavior/README.md b/polymer_1.0.4/bower_components/iron-resizable-behavior/README.md
new file mode 100644
index 0000000..72be6de
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-resizable-behavior/README.md
@@ -0,0 +1,16 @@
+iron-resizable-behavior
+=======================
+
+`IronResizableBehavior` is a behavior that can be used in Polymer elements to
+coordinate the flow of resize events between "resizers" (elements that control the
+size or hidden state of their children) and "resizables" (elements that need to be
+notified when they are resized or un-hidden by their parents in order to take
+action on their new measurements).
+
+Elements that perform measurement should add the `IronResizableBehavior` behavior to
+their element definition and listen for the `iron-resize` event on themselves.
+This event will be fired when they become showing after having been hidden,
+when they are resized explicitly by another resizable, or when the window has been
+resized.
+
+Note, the `iron-resize` event is non-bubbling.
diff --git a/polymer_1.0.4/bower_components/iron-resizable-behavior/bower.json b/polymer_1.0.4/bower_components/iron-resizable-behavior/bower.json
new file mode 100644
index 0000000..d0591a3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-resizable-behavior/bower.json
@@ -0,0 +1,30 @@
+{
+ "name": "iron-resizable-behavior",
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Coordinates the flow of resizeable elements",
+ "private": true,
+ "main": "iron-resizable-behavior.html",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "iron",
+ "behavior"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-resizable-behavior.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-resizable-behavior/demo/index.html b/polymer_1.0.4/bower_components/iron-resizable-behavior/demo/index.html
new file mode 100644
index 0000000..2896c50
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-resizable-behavior/demo/index.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-resizable-behavior demo</title>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="src/x-app.html">
+
+</head>
+<body>
+
+ <x-app></x-app>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-resizable-behavior/demo/src/x-app.html b/polymer_1.0.4/bower_components/iron-resizable-behavior/demo/src/x-app.html
new file mode 100644
index 0000000..c334ad3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-resizable-behavior/demo/src/x-app.html
@@ -0,0 +1,114 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../iron-resizable-behavior.html">
+
+<dom-module id="x-puck">
+
+ <style>
+
+ :host {
+ display: inline-block;
+ border: 3px solid lightblue;
+ }
+
+ </style>
+
+ <template>
+
+ <b>I'm a resize-aware, thirdifying puck at (<span>{{x}}</span> x <span>{{y}}</span>).</b>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'x-puck',
+
+ behaviors: [
+ Polymer.IronResizableBehavior
+ ],
+
+ properties: {
+ x: {
+ type: Number,
+ value: 0
+ },
+
+ y: {
+ type: Number,
+ value: 0
+ }
+ },
+
+ listeners: {
+ 'iron-resize': '_onIronResize'
+ },
+
+ attached: function() {
+ this.async(this.notifyResize, 1);
+ },
+
+ get parent() {
+ if (this.parentNode.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
+ return this.parentNode.host;
+ }
+
+ return this.parentNode;
+ },
+
+ _onIronResize: function() {
+ var x = this.x = Math.floor(this.parent.offsetWidth / 3);
+ var y = this.y = Math.floor(this.parent.offsetHeight / 3);
+
+ this.translate3d(x + 'px', y + 'px', 0);
+ }
+ });
+
+</script>
+
+<dom-module id="x-app">
+
+ <style>
+
+ :host {
+ display: block;
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ }
+
+ </style>
+
+ <template>
+
+ <x-puck></x-puck>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'x-app',
+
+ behaviors: [
+ Polymer.IronResizableBehavior
+ ]
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-resizable-behavior/index.html b/polymer_1.0.4/bower_components/iron-resizable-behavior/index.html
new file mode 100644
index 0000000..b9b8809
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-resizable-behavior/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-resizable-behavior</title>
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-resizable-behavior/iron-resizable-behavior.html b/polymer_1.0.4/bower_components/iron-resizable-behavior/iron-resizable-behavior.html
new file mode 100644
index 0000000..19b8c02
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-resizable-behavior/iron-resizable-behavior.html
@@ -0,0 +1,193 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+ /**
+ * `IronResizableBehavior` is a behavior that can be used in Polymer elements to
+ * coordinate the flow of resize events between "resizers" (elements that control the
+ * size or hidden state of their children) and "resizables" (elements that need to be
+ * notified when they are resized or un-hidden by their parents in order to take
+ * action on their new measurements).
+ * Elements that perform measurement should add the `IronResizableBehavior` behavior to
+ * their element definition and listen for the `iron-resize` event on themselves.
+ * This event will be fired when they become showing after having been hidden,
+ * when they are resized explicitly by another resizable, or when the window has been
+ * resized.
+ * Note, the `iron-resize` event is non-bubbling.
+ *
+ * @polymerBehavior Polymer.IronResizableBehavior
+ * @demo demo/index.html
+ **/
+ Polymer.IronResizableBehavior = {
+ properties: {
+ /**
+ * The closest ancestor element that implements `IronResizableBehavior`.
+ */
+ _parentResizable: {
+ type: Object,
+ observer: '_parentResizableChanged'
+ },
+
+ /**
+ * True if this element is currently notifying its descedant elements of
+ * resize.
+ */
+ _notifyingDescendant: {
+ type: Boolean,
+ value: false
+ }
+ },
+
+ listeners: {
+ 'iron-request-resize-notifications': '_onIronRequestResizeNotifications'
+ },
+
+ created: function() {
+ // We don't really need property effects on these, and also we want them
+ // to be created before the `_parentResizable` observer fires:
+ this._interestedResizables = [];
+ this._boundNotifyResize = this.notifyResize.bind(this);
+ },
+
+ attached: function() {
+ this.fire('iron-request-resize-notifications', null, {
+ node: this,
+ bubbles: true,
+ cancelable: true
+ });
+
+ if (!this._parentResizable) {
+ window.addEventListener('resize', this._boundNotifyResize);
+ this.notifyResize();
+ }
+ },
+
+ detached: function() {
+ if (this._parentResizable) {
+ this._parentResizable.stopResizeNotificationsFor(this);
+ } else {
+ window.removeEventListener('resize', this._boundNotifyResize);
+ }
+
+ this._parentResizable = null;
+ },
+
+ /**
+ * Can be called to manually notify a resizable and its descendant
+ * resizables of a resize change.
+ */
+ notifyResize: function() {
+ if (!this.isAttached) {
+ return;
+ }
+
+ this._interestedResizables.forEach(function(resizable) {
+ if (this.resizerShouldNotify(resizable)) {
+ this._notifyDescendant(resizable);
+ }
+ }, this);
+
+ this._fireResize();
+ },
+
+ /**
+ * Used to assign the closest resizable ancestor to this resizable
+ * if the ancestor detects a request for notifications.
+ */
+ assignParentResizable: function(parentResizable) {
+ this._parentResizable = parentResizable;
+ },
+
+ /**
+ * Used to remove a resizable descendant from the list of descendants
+ * that should be notified of a resize change.
+ */
+ stopResizeNotificationsFor: function(target) {
+ var index = this._interestedResizables.indexOf(target);
+
+ if (index > -1) {
+ this._interestedResizables.splice(index, 1);
+ this.unlisten(target, 'iron-resize', '_onDescendantIronResize');
+ }
+ },
+
+ /**
+ * This method can be overridden to filter nested elements that should or
+ * should not be notified by the current element. Return true if an element
+ * should be notified, or false if it should not be notified.
+ *
+ * @param {HTMLElement} element A candidate descendant element that
+ * implements `IronResizableBehavior`.
+ * @return {boolean} True if the `element` should be notified of resize.
+ */
+ resizerShouldNotify: function(element) { return true; },
+
+ _onDescendantIronResize: function(event) {
+ if (this._notifyingDescendant) {
+ event.stopPropagation();
+ return;
+ }
+
+ // NOTE(cdata): In ShadowDOM, event retargetting makes echoing of the
+ // otherwise non-bubbling event "just work." We do it manually here for
+ // the case where Polymer is not using shadow roots for whatever reason:
+ if (!Polymer.Settings.useShadow) {
+ this._fireResize();
+ }
+ },
+
+ _fireResize: function() {
+ this.fire('iron-resize', null, {
+ node: this,
+ bubbles: false
+ });
+ },
+
+ _onIronRequestResizeNotifications: function(event) {
+ var target = event.path ? event.path[0] : event.target;
+
+ if (target === this) {
+ return;
+ }
+
+ if (this._interestedResizables.indexOf(target) === -1) {
+ this._interestedResizables.push(target);
+ this.listen(target, 'iron-resize', '_onDescendantIronResize');
+ }
+
+ target.assignParentResizable(this);
+ this._notifyDescendant(target);
+
+ event.stopPropagation();
+ },
+
+ _parentResizableChanged: function(parentResizable) {
+ if (parentResizable) {
+ window.removeEventListener('resize', this._boundNotifyResize);
+ }
+ },
+
+ _notifyDescendant: function(descendant) {
+ // NOTE(cdata): In IE10, attached is fired on children first, so it's
+ // important not to notify them if the parent is not attached yet (or
+ // else they will get redundantly notified when the parent attaches).
+ if (!this.isAttached) {
+ return;
+ }
+
+ this._notifyingDescendant = true;
+ descendant.notifyResize();
+ this._notifyingDescendant = false;
+ }
+ };
+</script>
+
diff --git a/polymer_1.0.4/bower_components/iron-resizable-behavior/test/basic.html b/polymer_1.0.4/bower_components/iron-resizable-behavior/test/basic.html
new file mode 100644
index 0000000..0ae890d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-resizable-behavior/test/basic.html
@@ -0,0 +1,263 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-resizable-behavior tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-resizable-behavior.html">
+ <link rel="import" href="test-elements.html">
+
+</head>
+<body>
+
+<!--
+
+Notes on Polyfill compatibility in tests:
+- Test elements loaded via imports, to ensure load order correctness
+ w.r.t. Polymer.mixin being availbale
+- Resize notifications and asserts are done asynchronously, since
+ there are timing differences w.r.t. when detached callbacks occur
+
+-->
+
+ <test-fixture id="TestElement">
+ <template>
+ <test-element></test-element>
+ </template>
+ </test-fixture>
+
+
+ <script>
+
+ suite('iron-resizable-behavior', function() {
+ function ListenForResize(el, expectsResize) {
+ var listener = function(event) {
+ var target = event.path ? event.path[0] : event.target;
+ pendingNotifications--;
+ };
+
+ if (expectsResize !== false) {
+ pendingNotifications++;
+ }
+
+ el.addEventListener('iron-resize', listener);
+
+ return {
+ el: el,
+ remove: function() {
+ el.removeEventListener('iron-resize', listener);
+ }
+ };
+ }
+
+ function RemoveListeners(listeners) {
+ listeners.forEach(function(listener) {
+ listener.remove();
+ });
+ }
+
+ var pendingNotifications;
+ var testEl;
+
+ setup(function() {
+ pendingNotifications = 0;
+ testEl = fixture('TestElement');
+ });
+
+ suite('x-resizer-parent', function() {
+
+ test('notify resizables from window', function(done) {
+ var listeners = [
+ ListenForResize(testEl.$.parent),
+ ListenForResize(testEl.$.child1a),
+ ListenForResize(testEl.$.child1b),
+ ListenForResize(testEl.$.shadow1c.$.resizable),
+ ListenForResize(testEl.$.shadow1d.$.resizable)
+ ];
+
+ setTimeout(function() {
+ try {
+ window.dispatchEvent(new CustomEvent('resize', { bubbles: false }));
+
+ expect(pendingNotifications).to.be.eql(0);
+
+ RemoveListeners(listeners);
+
+ done();
+ } catch (e) {
+ done(e);
+ }
+ }, 0);
+ });
+
+ test('notify resizables from parent', function(done) {
+ var listeners = [
+ ListenForResize(testEl.$.parent),
+ ListenForResize(testEl.$.child1a),
+ ListenForResize(testEl.$.child1b),
+ ListenForResize(testEl.$.shadow1c.$.resizable),
+ ListenForResize(testEl.$.shadow1d.$.resizable)
+ ];
+
+ setTimeout(function() {
+ try {
+ testEl.$.parent.notifyResize();
+ expect(pendingNotifications).to.be.eql(0);
+ RemoveListeners(listeners);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ }, 0);
+ });
+
+ test('detach resizables then notify parent', function(done) {
+ var listeners = [
+ ListenForResize(testEl.$.parent),
+ ListenForResize(testEl.$.child1a, false),
+ ListenForResize(testEl.$.child1b),
+ ListenForResize(testEl.$.shadow1c.$.resizable, false),
+ ListenForResize(testEl.$.shadow1d.$.resizable)
+ ];
+
+ var el = Polymer.dom(testEl.root).querySelector('#child1a');
+
+ el.parentNode.removeChild(el);
+ el = Polymer.dom(testEl.root).querySelector('#shadow1c');
+ el.parentNode.removeChild(el);
+
+ setTimeout(function() {
+ try {
+ testEl.$.parent.notifyResize();
+ expect(pendingNotifications).to.be.eql(0);
+ RemoveListeners(listeners);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ }, 0);
+ });
+
+ test('detach parent then notify window', function(done) {
+ var listeners = [
+ ListenForResize(testEl.$.parent, false),
+ ListenForResize(testEl.$.child1a, false),
+ ListenForResize(testEl.$.child1b, false),
+ ListenForResize(testEl.$.shadow1c.$.resizable, false),
+ ListenForResize(testEl.$.shadow1d.$.resizable, false)
+ ];
+
+ var el = Polymer.dom(testEl.root).querySelector('#parent');
+
+ el.parentNode.removeChild(el);
+
+ setTimeout(function() {
+ try {
+ window.dispatchEvent(new CustomEvent('resize', { bubbles: false }));
+ expect(pendingNotifications).to.be.eql(0);
+ RemoveListeners(listeners);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ }, 0);
+ });
+
+ });
+
+ suite('x-resizer-parent-filtered', function() {
+
+ test('notify resizables from window', function(done) {
+ var listeners = [
+ ListenForResize(testEl.$.parentFiltered),
+ ListenForResize(testEl.$.child2a),
+ ListenForResize(testEl.$.child2b, false),
+ ListenForResize(testEl.$.shadow2c.$.resizable, false),
+ ListenForResize(testEl.$.shadow2d.$.resizable, false)
+ ];
+
+ testEl.$.parentFiltered.active = testEl.$.child2a;
+
+ setTimeout(function() {
+ try {
+ window.dispatchEvent(new CustomEvent('resize', { bubbles: false }));
+ expect(pendingNotifications).to.be.eql(0);
+ RemoveListeners(listeners);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ }, 0);
+ });
+
+ test('notify resizables from parent', function(done) {
+ var listeners = [
+ ListenForResize(testEl.$.parentFiltered),
+ ListenForResize(testEl.$.child2a),
+ ListenForResize(testEl.$.child2b, false),
+ ListenForResize(testEl.$.shadow2c.$.resizable, false),
+ ListenForResize(testEl.$.shadow2d.$.resizable, false)
+ ];
+
+ testEl.$.parentFiltered.active = testEl.$.child2a;
+
+ setTimeout(function() {
+ try {
+ testEl.$.parentFiltered.notifyResize();
+ expect(pendingNotifications).to.be.eql(0);
+ RemoveListeners(listeners);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ }, 0);
+ });
+
+ test('detach resizables then notify parent', function(done) {
+ var listeners = [
+ ListenForResize(testEl.$.parentFiltered),
+ ListenForResize(testEl.$.child2a, false),
+ ListenForResize(testEl.$.child2b, false),
+ ListenForResize(testEl.$.shadow2c.$.resizable, false),
+ ListenForResize(testEl.$.shadow2d.$.resizable)
+ ];
+
+ var el = Polymer.dom(testEl.root).querySelector('#child2a');
+ el.parentNode.removeChild(el);
+ el = Polymer.dom(testEl.root).querySelector('#shadow2c');
+ el.parentNode.removeChild(el);
+
+ testEl.$.parentFiltered.active = testEl.$.shadow2d.$.resizable;
+
+ setTimeout(function() {
+ try {
+ testEl.$.parentFiltered.notifyResize();
+ expect(pendingNotifications).to.be.eql(0);
+ RemoveListeners(listeners);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ }, 0);
+ });
+ });
+ });
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-resizable-behavior/test/index.html b/polymer_1.0.4/bower_components/iron-resizable-behavior/test/index.html
new file mode 100644
index 0000000..e1d3fca
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-resizable-behavior/test/index.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+
+</head>
+<body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'basic.html',
+ 'iron-resizable-behavior.html'
+ ]);
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-resizable-behavior/test/iron-resizable-behavior.html b/polymer_1.0.4/bower_components/iron-resizable-behavior/test/iron-resizable-behavior.html
new file mode 100644
index 0000000..695b977
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-resizable-behavior/test/iron-resizable-behavior.html
@@ -0,0 +1,87 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-resizable-behavior tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-resizable-behavior.html">
+ <link rel="import" href="test-elements.html">
+
+</head>
+<body>
+
+ <test-fixture id="ResizableAndShadowBoundaries">
+ <template>
+ <x-light-resizable></x-light-resizable>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('iron-resizable-behavior', function() {
+ var resizable;
+
+ suite('events across shadow boundaries', function() {
+ setup(function() {
+ resizable = fixture('ResizableAndShadowBoundaries');
+ });
+
+ suite('ancestor\'s iron-resize', function() {
+ test('only fires once for a notifying shadow descendent', function() {
+ resizable.$.childResizable1.notifyResize();
+
+ expect(resizable.ironResizeCount).to.be.equal(2);
+ });
+
+ test('only fires once when notifying descendent observables', function() {
+ resizable.notifyResize();
+
+ expect(resizable.ironResizeCount).to.be.equal(2);
+ });
+ });
+
+ suite('descendant\'s iron-resize', function() {
+ test('only fires once for a notifying shadow root', function() {
+ resizable.notifyResize();
+
+ expect(resizable.$.childResizable1.ironResizeCount).to.be.equal(2);
+ expect(resizable.$.childResizable2.ironResizeCount).to.be.equal(2);
+ });
+
+ test('only fires once for a notifying descendent observable', function() {
+ resizable.$.childResizable1.notifyResize();
+
+ expect(resizable.$.childResizable1.ironResizeCount).to.be.equal(2);
+ });
+ });
+
+ suite('window\'s resize', function() {
+ test('causes all iron-resize events to fire once', function() {
+ window.dispatchEvent(new CustomEvent('resize'));
+ expect(resizable.ironResizeCount).to.be.equal(2);
+ expect(resizable.$.childResizable1.ironResizeCount).to.be.equal(2);
+ expect(resizable.$.childResizable2.ironResizeCount).to.be.equal(2);
+ });
+ });
+ });
+
+ });
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-resizable-behavior/test/test-elements.html b/polymer_1.0.4/bower_components/iron-resizable-behavior/test/test-elements.html
new file mode 100644
index 0000000..d70561e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-resizable-behavior/test/test-elements.html
@@ -0,0 +1,193 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../iron-resizable-behavior.html">
+
+<script>
+
+ Polymer({
+
+ is: 'x-resizer-parent',
+
+ behaviors: [
+ Polymer.IronResizableBehavior
+ ],
+
+ listeners: {
+ 'core-resize': 'resizeHandler'
+ },
+
+ resizeHandler: function() {
+ }
+
+ });
+
+</script>
+
+<script>
+
+ Polymer({
+
+ is: 'x-resizer-parent-filtered',
+
+ active: null,
+
+ behaviors: [
+ Polymer.IronResizableBehavior
+ ],
+
+ listeners: {
+ 'core-resize': 'resizeHandler'
+ },
+
+ resizeHandler: function() {
+ },
+
+ resizerShouldNotify: function(el) {
+ return (el == this.active);
+ }
+
+ });
+
+</script>
+
+<script>
+
+ Polymer({
+
+ is: 'x-resizable',
+
+ behaviors: [
+ Polymer.IronResizableBehavior
+ ],
+
+ listeners: {
+ 'core-resize': 'resizeHandler'
+ },
+
+ resizeHandler: function() {
+ }
+
+ });
+
+</script>
+
+<dom-module id="x-resizable-in-shadow">
+
+ <template>
+
+ <div>
+ <x-resizable id="resizable"></x-resizable>
+ </div>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'x-resizable-in-shadow'
+
+ });
+
+</script>
+
+<dom-module id='test-element'>
+
+ <template>
+
+ <!-- Normal resizable parent with child resizables -->
+ <x-resizer-parent id="parent">
+ <x-resizable id="child1a"></x-resizable>
+ <div>
+ <x-resizable id="child1b"></x-resizable>
+ </div>
+ <x-resizable-in-shadow id="shadow1c"></x-resizable-in-shadow>
+ <div>
+ <x-resizable-in-shadow id="shadow1d"></x-resizable-in-shadow>
+ </div>
+ </x-resizer-parent>
+
+ <!-- Resizable parent using resizerShouldNotify, with child resizables -->
+ <x-resizer-parent-filtered id="parentFiltered">
+ <x-resizable id="child2a"></x-resizable>
+ <div>
+ <x-resizable id="child2b"></x-resizable>
+ </div>
+ <x-resizable-in-shadow id="shadow2c"></x-resizable-in-shadow>
+ <div>
+ <x-resizable-in-shadow id="shadow2d"></x-resizable-in-shadow>
+ </div>
+ </x-resizer-parent-filtered>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'test-element'
+
+ });
+
+</script>
+<script>
+ Polymer.ObserveIronResizeBehavior = {
+ properties: {
+ ironResizeCount: {
+ type: Number,
+ value: 0
+ }
+ },
+
+ listeners: {
+ 'iron-resize': '_incrementIronResizeCount'
+ },
+
+ _incrementIronResizeCount: function() {
+ this.ironResizeCount++;
+ }
+ };
+</script>
+<dom-module id="x-shadow-resizable">
+ <template>
+ <div></div>
+ </template>
+</dom-module>
+<script>
+ Polymer({
+ is: 'x-shadow-resizable',
+
+ behaviors: [
+ Polymer.IronResizableBehavior,
+ Polymer.ObserveIronResizeBehavior
+ ]
+ });
+</script>
+
+<dom-module id="x-light-resizable">
+ <template>
+ <x-shadow-resizable id="childResizable1"></x-shadow-resizable>
+ <x-shadow-resizable id="childResizable2"></x-shadow-resizable>
+ </template>
+</dom-module>
+<script>
+ Polymer({
+ is: 'x-light-resizable',
+
+ behaviors: [
+ Polymer.IronResizableBehavior,
+ Polymer.ObserveIronResizeBehavior
+ ]
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-selector/.bower.json b/polymer_1.0.4/bower_components/iron-selector/.bower.json
new file mode 100644
index 0000000..3105082
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/.bower.json
@@ -0,0 +1,41 @@
+{
+ "name": "iron-selector",
+ "version": "1.0.2",
+ "description": "Manages a set of elements that can be selected",
+ "private": true,
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "main": [
+ "iron-selector.html"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "selector"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-selector.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/iron-selector",
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "ea22d91d11ba6f72c01faa952d5e600f9d1773cf"
+ },
+ "_source": "git://github.com/PolymerElements/iron-selector.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-selector"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-selector/.gitignore b/polymer_1.0.4/bower_components/iron-selector/.gitignore
new file mode 100644
index 0000000..b13058c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/.gitignore
@@ -0,0 +1,2 @@
+bower_components
+.DS_Store
diff --git a/polymer_1.0.4/bower_components/iron-selector/README.md b/polymer_1.0.4/bower_components/iron-selector/README.md
new file mode 100755
index 0000000..8bb3d64
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/README.md
@@ -0,0 +1,50 @@
+iron-selector
+=============
+
+`iron-selector` is an element which can be used to manage a list of elements
+that can be selected. Tapping on the item will make the item selected. The `selected` indicates
+which item is being selected. The default is to use the index of the item.
+
+Example:
+
+```html
+<iron-selector selected="0">
+ <div>Item 1</div>
+ <div>Item 2</div>
+ <div>Item 3</div>
+</iron-selector>
+```
+
+If you want to use the attribute value of an element for `selected` instead of the index,
+set `attrForSelected` to the name of the attribute. For example, if you want to select item by
+`name`, set `attrForSelected` to `name`.
+
+Example:
+
+```html
+<iron-selector attr-for-selected="name" selected="foo">
+ <div name="foo">Foo</div>
+ <div name="bar">Bar</div>
+ <div name="zot">Zot</div>
+</iron-selector>
+```
+
+`iron-selector` is not styled. Use the `iron-selected` CSS class to style the selected element.
+
+Example:
+
+```html
+<style>
+ .iron-selected {
+ background: #eee;
+ }
+</style>
+
+...
+
+<iron-selector selected="0">
+ <div>Item 1</div>
+ <div>Item 2</div>
+ <div>Item 3</div>
+</iron-selector>
+```
diff --git a/polymer_1.0.4/bower_components/iron-selector/bower.json b/polymer_1.0.4/bower_components/iron-selector/bower.json
new file mode 100755
index 0000000..b9751df
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/bower.json
@@ -0,0 +1,31 @@
+{
+ "name": "iron-selector",
+ "version": "1.0.2",
+ "description": "Manages a set of elements that can be selected",
+ "private": true,
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "main": [
+ "iron-selector.html"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "selector"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-selector.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-selector/demo/index.html b/polymer_1.0.4/bower_components/iron-selector/demo/index.html
new file mode 100644
index 0000000..cdb7f99
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/demo/index.html
@@ -0,0 +1,66 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <title>iron-selector</title>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-selector.html">
+
+ <style>
+
+ iron-selector > * {
+ padding: 8px;
+ }
+
+ .iron-selected {
+ background-color: #ddd;
+ }
+
+ </style>
+
+ </head>
+ <body>
+
+ <h3>Basic</h3>
+
+ <iron-selector selected="0">
+ <div>Item 0</div>
+ <div>Item 1</div>
+ <div>Item 2</div>
+ <div>Item 3</div>
+ <div>Item 4</div>
+ </iron-selector>
+
+ <h3>Multi-select</h3>
+
+ <iron-selector multi selected-values='[0,2]'>
+ <div>Item 0</div>
+ <div>Item 1</div>
+ <div>Item 2</div>
+ <div>Item 3</div>
+ <div>Item 4</div>
+ </iron-selector>
+
+ <h3>Example</h3>
+
+ <iron-selector selected="foo" attr-for-selected="name">
+ <div name="foo">Foo</div>
+ <div name="bar">Bar</div>
+ <div name="zot">Zot</div>
+ </iron-selector>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-selector/index.html b/polymer_1.0.4/bower_components/iron-selector/index.html
new file mode 100755
index 0000000..741693c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/index.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-selector</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-selector/iron-multi-selectable.html b/polymer_1.0.4/bower_components/iron-selector/iron-multi-selectable.html
new file mode 100644
index 0000000..ba9455d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/iron-multi-selectable.html
@@ -0,0 +1,120 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="iron-selectable.html">
+
+<script>
+ /** @polymerBehavior Polymer.IronMultiSelectableBehavior */
+ Polymer.IronMultiSelectableBehaviorImpl = {
+ properties: {
+
+ /**
+ * If true, multiple selections are allowed.
+ */
+ multi: {
+ type: Boolean,
+ value: false,
+ observer: 'multiChanged'
+ },
+
+ /**
+ * Gets or sets the selected elements. This is used instead of `selected` when `multi`
+ * is true.
+ */
+ selectedValues: {
+ type: Array,
+ notify: true
+ },
+
+ /**
+ * Returns an array of currently selected items.
+ */
+ selectedItems: {
+ type: Array,
+ readOnly: true,
+ notify: true
+ },
+
+ },
+
+ observers: [
+ '_updateSelected(attrForSelected, selectedValues)'
+ ],
+
+ /**
+ * Selects the given value. If the `multi` property is true, then the selected state of the
+ * `value` will be toggled; otherwise the `value` will be selected.
+ *
+ * @method select
+ * @param {string} value the value to select.
+ */
+ select: function(value) {
+ if (this.multi) {
+ if (this.selectedValues) {
+ this._toggleSelected(value);
+ } else {
+ this.selectedValues = [value];
+ }
+ } else {
+ this.selected = value;
+ }
+ },
+
+ multiChanged: function(multi) {
+ this._selection.multi = multi;
+ },
+
+ _updateSelected: function() {
+ if (this.multi) {
+ this._selectMulti(this.selectedValues);
+ } else {
+ this._selectSelected(this.selected);
+ }
+ },
+
+ _selectMulti: function(values) {
+ this._selection.clear();
+ if (values) {
+ for (var i = 0; i < values.length; i++) {
+ this._selection.setItemSelected(this._valueToItem(values[i]), true);
+ }
+ }
+ },
+
+ _selectionChange: function() {
+ var s = this._selection.get();
+ if (this.multi) {
+ this._setSelectedItems(s);
+ } else {
+ this._setSelectedItems([s]);
+ this._setSelectedItem(s);
+ }
+ },
+
+ _toggleSelected: function(value) {
+ var i = this.selectedValues.indexOf(value);
+ var unselected = i < 0;
+ if (unselected) {
+ this.selectedValues.push(value);
+ } else {
+ this.selectedValues.splice(i, 1);
+ }
+ this._selection.setItemSelected(this._valueToItem(value), unselected);
+ }
+ };
+
+ /** @polymerBehavior */
+ Polymer.IronMultiSelectableBehavior = [
+ Polymer.IronSelectableBehavior,
+ Polymer.IronMultiSelectableBehaviorImpl
+ ];
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-selector/iron-selectable.html b/polymer_1.0.4/bower_components/iron-selector/iron-selectable.html
new file mode 100644
index 0000000..f0506d5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/iron-selectable.html
@@ -0,0 +1,307 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="iron-selection.html">
+
+<script>
+
+ /** @polymerBehavior */
+ Polymer.IronSelectableBehavior = {
+
+ properties: {
+
+ /**
+ * If you want to use the attribute value of an element for `selected` instead of the index,
+ * set this to the name of the attribute.
+ *
+ * @attribute attrForSelected
+ * @type {string}
+ */
+ attrForSelected: {
+ type: String,
+ value: null
+ },
+
+ /**
+ * Gets or sets the selected element. The default is to use the index of the item.
+ *
+ * @attribute selected
+ * @type {string}
+ */
+ selected: {
+ type: String,
+ notify: true
+ },
+
+ /**
+ * Returns the currently selected item.
+ *
+ * @attribute selectedItem
+ * @type {Object}
+ */
+ selectedItem: {
+ type: Object,
+ readOnly: true,
+ notify: true
+ },
+
+ /**
+ * The event that fires from items when they are selected. Selectable
+ * will listen for this event from items and update the selection state.
+ * Set to empty string to listen to no events.
+ *
+ * @attribute activateEvent
+ * @type {string}
+ * @default 'tap'
+ */
+ activateEvent: {
+ type: String,
+ value: 'tap',
+ observer: '_activateEventChanged'
+ },
+
+ /**
+ * This is a CSS selector sting. If this is set, only items that matches the CSS selector
+ * are selectable.
+ *
+ * @attribute selectable
+ * @type {string}
+ */
+ selectable: String,
+
+ /**
+ * The class to set on elements when selected.
+ *
+ * @attribute selectedClass
+ * @type {string}
+ */
+ selectedClass: {
+ type: String,
+ value: 'iron-selected'
+ },
+
+ /**
+ * The attribute to set on elements when selected.
+ *
+ * @attribute selectedAttribute
+ * @type {string}
+ */
+ selectedAttribute: {
+ type: String,
+ value: null
+ }
+
+ },
+
+ observers: [
+ '_updateSelected(attrForSelected, selected)'
+ ],
+
+ excludedLocalNames: {
+ 'template': 1
+ },
+
+ created: function() {
+ this._bindFilterItem = this._filterItem.bind(this);
+ this._selection = new Polymer.IronSelection(this._applySelection.bind(this));
+ },
+
+ attached: function() {
+ this._observer = this._observeItems(this);
+ this._contentObserver = this._observeContent(this);
+ },
+
+ detached: function() {
+ if (this._observer) {
+ this._observer.disconnect();
+ }
+ if (this._contentObserver) {
+ this._contentObserver.disconnect();
+ }
+ this._removeListener(this.activateEvent);
+ },
+
+ /**
+ * Returns an array of selectable items.
+ *
+ * @property items
+ * @type Array
+ */
+ get items() {
+ var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '*');
+ return Array.prototype.filter.call(nodes, this._bindFilterItem);
+ },
+
+ /**
+ * Returns the index of the given item.
+ *
+ * @method indexOf
+ * @param {Object} item
+ * @returns Returns the index of the item
+ */
+ indexOf: function(item) {
+ return this.items.indexOf(item);
+ },
+
+ /**
+ * Selects the given value.
+ *
+ * @method select
+ * @param {string} value the value to select.
+ */
+ select: function(value) {
+ this.selected = value;
+ },
+
+ /**
+ * Selects the previous item.
+ *
+ * @method selectPrevious
+ */
+ selectPrevious: function() {
+ var length = this.items.length;
+ var index = (Number(this._valueToIndex(this.selected)) - 1 + length) % length;
+ this.selected = this._indexToValue(index);
+ },
+
+ /**
+ * Selects the next item.
+ *
+ * @method selectNext
+ */
+ selectNext: function() {
+ var index = (Number(this._valueToIndex(this.selected)) + 1) % this.items.length;
+ this.selected = this._indexToValue(index);
+ },
+
+ _addListener: function(eventName) {
+ this.listen(this, eventName, '_activateHandler');
+ },
+
+ _removeListener: function(eventName) {
+ // There is no unlisten yet...
+ // https://github.com/Polymer/polymer/issues/1639
+ //this.removeEventListener(eventName, this._bindActivateHandler);
+ },
+
+ _activateEventChanged: function(eventName, old) {
+ this._removeListener(old);
+ this._addListener(eventName);
+ },
+
+ _updateSelected: function() {
+ this._selectSelected(this.selected);
+ },
+
+ _selectSelected: function(selected) {
+ this._selection.select(this._valueToItem(this.selected));
+ },
+
+ _filterItem: function(node) {
+ return !this.excludedLocalNames[node.localName];
+ },
+
+ _valueToItem: function(value) {
+ return (value == null) ? null : this.items[this._valueToIndex(value)];
+ },
+
+ _valueToIndex: function(value) {
+ if (this.attrForSelected) {
+ for (var i = 0, item; item = this.items[i]; i++) {
+ if (this._valueForItem(item) == value) {
+ return i;
+ }
+ }
+ } else {
+ return Number(value);
+ }
+ },
+
+ _indexToValue: function(index) {
+ if (this.attrForSelected) {
+ var item = this.items[index];
+ if (item) {
+ return this._valueForItem(item);
+ }
+ } else {
+ return index;
+ }
+ },
+
+ _valueForItem: function(item) {
+ return item[this.attrForSelected] || item.getAttribute(this.attrForSelected);
+ },
+
+ _applySelection: function(item, isSelected) {
+ if (this.selectedClass) {
+ this.toggleClass(this.selectedClass, isSelected, item);
+ }
+ if (this.selectedAttribute) {
+ this.toggleAttribute(this.selectedAttribute, isSelected, item);
+ }
+ this._selectionChange();
+ this.fire('iron-' + (isSelected ? 'select' : 'deselect'), {item: item});
+ },
+
+ _selectionChange: function() {
+ this._setSelectedItem(this._selection.get());
+ },
+
+ // observe content changes under the given node.
+ _observeContent: function(node) {
+ var content = node.querySelector('content');
+ if (content && content.parentElement === node) {
+ return this._observeItems(node.domHost);
+ }
+ },
+
+ // observe items change under the given node.
+ _observeItems: function(node) {
+ var observer = new MutationObserver(function() {
+ if (this.selected != null) {
+ this._updateSelected();
+ }
+ }.bind(this));
+ observer.observe(node, {
+ childList: true,
+ subtree: true
+ });
+ return observer;
+ },
+
+ _activateHandler: function(e) {
+ // TODO: remove this when https://github.com/Polymer/polymer/issues/1639 is fixed so we
+ // can just remove the old event listener.
+ if (e.type !== this.activateEvent) {
+ return;
+ }
+ var t = e.target;
+ var items = this.items;
+ while (t && t != this) {
+ var i = items.indexOf(t);
+ if (i >= 0) {
+ var value = this._indexToValue(i);
+ this._itemActivate(value, t);
+ return;
+ }
+ t = t.parentNode;
+ }
+ },
+
+ _itemActivate: function(value, item) {
+ if (!this.fire('iron-activate',
+ {selected: value, item: item}, {cancelable: true}).defaultPrevented) {
+ this.select(value);
+ }
+ }
+
+ };
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-selector/iron-selection.html b/polymer_1.0.4/bower_components/iron-selector/iron-selection.html
new file mode 100644
index 0000000..0ff04cf
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/iron-selection.html
@@ -0,0 +1,115 @@
+
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+
+ /**
+ * @param {!Function} selectCallback
+ * @constructor
+ */
+ Polymer.IronSelection = function(selectCallback) {
+ this.selection = [];
+ this.selectCallback = selectCallback;
+ };
+
+ Polymer.IronSelection.prototype = {
+
+ /**
+ * Retrieves the selected item(s).
+ *
+ * @method get
+ * @returns Returns the selected item(s). If the multi property is true,
+ * `get` will return an array, otherwise it will return
+ * the selected item or undefined if there is no selection.
+ */
+ get: function() {
+ return this.multi ? this.selection : this.selection[0];
+ },
+
+ /**
+ * Clears all the selection except the ones indicated.
+ *
+ * @method clear
+ * @param {Array} excludes items to be excluded.
+ */
+ clear: function(excludes) {
+ this.selection.slice().forEach(function(item) {
+ if (!excludes || excludes.indexOf(item) < 0) {
+ this.setItemSelected(item, false);
+ }
+ }, this);
+ },
+
+ /**
+ * Indicates if a given item is selected.
+ *
+ * @method isSelected
+ * @param {*} item The item whose selection state should be checked.
+ * @returns Returns true if `item` is selected.
+ */
+ isSelected: function(item) {
+ return this.selection.indexOf(item) >= 0;
+ },
+
+ /**
+ * Sets the selection state for a given item to either selected or deselected.
+ *
+ * @method setItemSelected
+ * @param {*} item The item to select.
+ * @param {boolean} isSelected True for selected, false for deselected.
+ */
+ setItemSelected: function(item, isSelected) {
+ if (item != null) {
+ if (isSelected) {
+ this.selection.push(item);
+ } else {
+ var i = this.selection.indexOf(item);
+ if (i >= 0) {
+ this.selection.splice(i, 1);
+ }
+ }
+ if (this.selectCallback) {
+ this.selectCallback(item, isSelected);
+ }
+ }
+ },
+
+ /**
+ * Sets the selection state for a given item. If the `multi` property
+ * is true, then the selected state of `item` will be toggled; otherwise
+ * the `item` will be selected.
+ *
+ * @method select
+ * @param {*} item The item to select.
+ */
+ select: function(item) {
+ if (this.multi) {
+ this.toggle(item);
+ } else if (this.get() !== item) {
+ this.setItemSelected(this.get(), false);
+ this.setItemSelected(item, true);
+ }
+ },
+
+ /**
+ * Toggles the selection state for `item`.
+ *
+ * @method toggle
+ * @param {*} item The item to toggle.
+ */
+ toggle: function(item) {
+ this.setItemSelected(item, !this.isSelected(item));
+ }
+
+ };
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-selector/iron-selector.html b/polymer_1.0.4/bower_components/iron-selector/iron-selector.html
new file mode 100644
index 0000000..92abe04
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/iron-selector.html
@@ -0,0 +1,71 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="iron-multi-selectable.html">
+
+<script>
+ /**
+ `iron-selector` is an element which can be used to manage a list of elements
+ that can be selected. Tapping on the item will make the item selected. The `selected` indicates
+ which item is being selected. The default is to use the index of the item.
+
+ Example:
+
+ <iron-selector selected="0">
+ <div>Item 1</div>
+ <div>Item 2</div>
+ <div>Item 3</div>
+ </iron-selector>
+
+ If you want to use the attribute value of an element for `selected` instead of the index,
+ set `attrForSelected` to the name of the attribute. For example, if you want to select item by
+ `name`, set `attrForSelected` to `name`.
+
+ Example:
+
+ <iron-selector attr-for-selected="name" selected="foo">
+ <div name="foo">Foo</div>
+ <div name="bar">Bar</div>
+ <div name="zot">Zot</div>
+ </iron-selector>
+
+ `iron-selector` is not styled. Use the `iron-selected` CSS class to style the selected element.
+
+ Example:
+
+ <style>
+ .iron-selected {
+ background: #eee;
+ }
+ </style>
+
+ ...
+
+ <iron-selector selected="0">
+ <div>Item 1</div>
+ <div>Item 2</div>
+ <div>Item 3</div>
+ </iron-selector>
+
+ @demo demo/index.html
+ */
+
+ Polymer({
+
+ is: 'iron-selector',
+
+ behaviors: [
+ Polymer.IronMultiSelectableBehavior
+ ]
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-selector/test/activate-event.html b/polymer_1.0.4/bower_components/iron-selector/test/activate-event.html
new file mode 100644
index 0000000..8390548
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/test/activate-event.html
@@ -0,0 +1,138 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-selector-activate-event</title>
+ <meta charset="UTF-8">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-selector.html">
+
+ <style>
+ .iron-selected {
+ background: #ccc;
+ }
+ </style>
+
+</head>
+<body>
+
+ <test-fixture id="test">
+ <template>
+ <iron-selector id="selector" selected="0">
+ <div>Item 0</div>
+ <div>Item 1</div>
+ <div>Item 2</div>
+ <div>Item 3</div>
+ <div>Item 4</div>
+ </iron-selector>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('activate event', function() {
+
+ var s;
+
+ setup(function () {
+ s = fixture('test');
+ });
+
+ test('activates on tap', function() {
+ assert.equal(s.selected, '0');
+
+ // select Item 1
+ s.children[1].dispatchEvent(new CustomEvent('tap', {bubbles: true}));
+ assert.equal(s.selected, '1');
+ });
+
+ test('activates on tap and fires iron-activate', function(done) {
+ assert.equal(s.selected, '0');
+
+ // attach iron-activate listener
+ s.addEventListener("iron-activate", function(event) {
+ assert.equal(event.detail.selected, '1');
+ assert.equal(event.detail.item, s.children[1]);
+ done();
+ });
+
+ // select Item 1
+ s.children[1].dispatchEvent(new CustomEvent('tap', {bubbles: true}));
+ });
+
+ test('tap on already selected and fires iron-activate', function(done) {
+ assert.equal(s.selected, '0');
+
+ // attach iron-activate listener
+ s.addEventListener("iron-activate", function(event) {
+ assert.equal(event.detail.selected, '0');
+ assert.equal(event.detail.item, s.children[0]);
+ done();
+ });
+
+ // select Item 0
+ s.children[0].dispatchEvent(new CustomEvent('tap', {bubbles: true}));
+ });
+
+ test('activates on mousedown', function() {
+ // set activateEvent to mousedown
+ s.activateEvent = 'mousedown';
+ // select Item 2
+ s.children[2].dispatchEvent(new CustomEvent('mousedown', {bubbles: true}));
+ assert.equal(s.selected, '2');
+ });
+
+ test('activates on mousedown and fires iron-activate', function(done) {
+ // attach iron-activate listener
+ s.addEventListener("iron-activate", function(event) {
+ assert.equal(event.detail.selected, '2');
+ assert.equal(event.detail.item, s.children[2]);
+ done();
+ });
+
+ // set activateEvent to mousedown
+ s.activateEvent = 'mousedown';
+ // select Item 2
+ s.children[2].dispatchEvent(new CustomEvent('mousedown', {bubbles: true}));
+ });
+
+ test('no activation', function() {
+ assert.equal(s.selected, '0');
+ // set activateEvent to null
+ s.activateEvent = null;
+ // select Item 2
+ s.children[2].dispatchEvent(new CustomEvent('mousedown', {bubbles: true}));
+ assert.equal(s.selected, '0');
+ });
+
+ test('activates on tap and preventDefault', function() {
+ // attach iron-activate listener
+ s.addEventListener("iron-activate", function(event) {
+ event.preventDefault();
+ });
+ // select Item 2
+ s.children[2].dispatchEvent(new CustomEvent('tap', {bubbles: true}));
+ // shouldn't got selected since we preventDefault in iron-activate
+ assert.equal(s.selected, '0');
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-selector/test/basic.html b/polymer_1.0.4/bower_components/iron-selector/test/basic.html
new file mode 100644
index 0000000..602de18
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/test/basic.html
@@ -0,0 +1,150 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-selector-basic</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-selector.html">
+
+ <style>
+ .iron-selected {
+ background: #ccc;
+ }
+
+ .my-selected {
+ background: red;
+ }
+ </style>
+
+</head>
+<body>
+
+ <test-fixture id="defaults">
+ <template>
+ <iron-selector>
+ <div>Item 0</div>
+ <div>Item 1</div>
+ <div>Item 2</div>
+ <div>Item 3</div>
+ <div>Item 4</div>
+ </iron-selector>
+ </template>
+ </test-fixture>
+
+ <br><br>
+
+ <test-fixture id="basic">
+ <template>
+ <iron-selector selected="item2" attr-for-selected="id">
+ <div id="item0">Item 0</div>
+ <div id="item1">Item 1</div>
+ <div id="item2">Item 2</div>
+ <div id="item3">Item 3</div>
+ <div id="item4">Item 4</div>
+ </iron-selector>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('defaults', function() {
+
+ var s1;
+
+ setup(function () {
+ s1 = fixture('defaults');
+ });
+
+ test('to nothing selected', function() {
+ assert.equal(s1.selected, null);
+ });
+
+ test('to iron-selected as selectedClass', function() {
+ assert.equal(s1.selectedClass, 'iron-selected');
+ });
+
+ test('to false as multi', function() {
+ assert.isFalse(s1.multi);
+ });
+
+ test('to tap as activateEvent', function() {
+ assert.equal(s1.activateEvent, 'tap');
+ });
+
+ test('to nothing as attrForSelected', function() {
+ assert.equal(s1.attrForSelected, null);
+ });
+
+ test('as many items as children', function() {
+ assert.equal(s1.items.length, s1.querySelectorAll('div').length);
+ });
+ });
+
+ suite('basic', function() {
+
+ var s2;
+
+ setup(function () {
+ s2 = fixture('basic');
+ });
+
+ test('honors the attrForSelected attribute', function() {
+ assert.equal(s2.attrForSelected, 'id');
+ assert.equal(s2.selected, 'item2');
+ assert.equal(s2.selectedItem, document.querySelector('#item2'));
+ });
+
+ test('allows assignment to selected', function() {
+ // set selected
+ s2.selected = 'item4';
+ // check selected class
+ assert.isTrue(s2.children[4].classList.contains('iron-selected'));
+ // check item
+ assert.equal(s2.selectedItem, s2.children[4]);
+ });
+
+ test('fire iron-select when selected is set', function() {
+ // setup listener for iron-select event
+ var selectedEventCounter = 0;
+ s2.addEventListener('iron-select', function(e) {
+ selectedEventCounter++;
+ });
+ // set selected
+ s2.selected = 'item4';
+ // check iron-select event
+ assert.equal(selectedEventCounter, 1);
+ });
+
+ test('set selected to old value', function() {
+ // setup listener for iron-select event
+ var selectedEventCounter = 0;
+ s2.addEventListener('iron-select', function(e) {
+ selectedEventCounter++;
+ });
+ // selecting the same value shouldn't fire iron-select
+ s2.selected = 'item2';
+ assert.equal(selectedEventCounter, 0);
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-selector/test/content-element.html b/polymer_1.0.4/bower_components/iron-selector/test/content-element.html
new file mode 100644
index 0000000..d0cd6d7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/test/content-element.html
@@ -0,0 +1,43 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-selector.html">
+
+<dom-module id="test-content-element">
+
+ <template>
+
+ <iron-selector id="selector" selected="{{selected}}" selectable="[[selectable]]" attr-for-selected="id">
+ <content></content>
+ </iron-selector>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'test-content-element',
+
+ properties: {
+
+ selectable: String,
+
+ selected: {
+ type: String,
+ notify: true
+ }
+
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-selector/test/content.html b/polymer_1.0.4/bower_components/iron-selector/test/content.html
new file mode 100644
index 0000000..e869f98
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/test/content.html
@@ -0,0 +1,168 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-selector-content</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="content-element.html">
+
+ <style>
+ .iron-selected {
+ background: #ccc;
+ }
+ </style>
+
+</head>
+<body>
+
+ <test-content-element id="selector1" selected="item0">
+ <div id="item0">item0</div>
+ <div id="item1">item1</div>
+ <div id="item2">item2</div>
+ <div id="item3">item3</div>
+ </test-content-element>
+
+ <test-content-element id="selector2" selected="item0" selectable="item">
+ <item id="item0">item0</item>
+ <hr>
+ <item id="item1">item1</item>
+ <item id="item2">item2</item>
+ <hr>
+ <item id="item3">item3</item>
+ </test-content-element>
+
+ <test-content-element id="selector3" selected="item0">
+ <template is="dom-repeat" id="t">
+ <div id$="[[item.name]]">[[item.name]]</div>
+ </template>
+ </test-content-element>
+
+ <script>
+
+ var s1 = document.querySelector('#selector1');
+ var s2 = document.querySelector('#selector2');
+ var s3 = document.querySelector('#selector3');
+
+ var t = document.querySelector('#t');
+
+ suite('content', function() {
+
+ test('attribute selected', function() {
+ // check selected class
+ assert.isTrue(s1.querySelector('#item0').classList.contains('iron-selected'));
+ });
+
+ test('set selected', function() {
+ // set selected
+ s1.selected = 'item1';
+ // check selected class
+ assert.isTrue(s1.querySelector('#item1').classList.contains('iron-selected'));
+ });
+
+ test('get items', function() {
+ assert.equal(s1.$.selector.items.length, 4);
+ });
+
+ test('activate event', function() {
+ var item = s1.querySelector('#item2');
+ item.dispatchEvent(new CustomEvent('tap', {bubbles: true}));
+ // check selected class
+ assert.isTrue(item.classList.contains('iron-selected'));
+ });
+
+ test('add item dynamically', function() {
+ var item = document.createElement('div');
+ item.id = 'item4';
+ item.textContent = 'item4';
+ Polymer.dom(s1).appendChild(item);
+ Polymer.dom.flush();
+ // set selected
+ s1.selected = 'item4';
+ // check items length
+ assert.equal(s1.$.selector.items.length, 5);
+ // check selected class
+ assert.isTrue(s1.querySelector('#item4').classList.contains('iron-selected'));
+ });
+
+ });
+
+ suite('content with selectable', function() {
+
+ test('attribute selected', function() {
+ // check selected class
+ assert.isTrue(s2.querySelector('#item0').classList.contains('iron-selected'));
+ });
+
+ test('set selected', function() {
+ // set selected
+ s2.selected = 'item1';
+ // check selected class
+ assert.isTrue(s2.querySelector('#item1').classList.contains('iron-selected'));
+ });
+
+ test('get items', function() {
+ assert.equal(s2.$.selector.items.length, 4);
+ });
+
+ test('activate event', function() {
+ var item = s2.querySelector('#item2');
+ item.dispatchEvent(new CustomEvent('tap', {bubbles: true}));
+ // check selected class
+ assert.isTrue(item.classList.contains('iron-selected'));
+ });
+
+ test('add item dynamically', function() {
+ var item = document.createElement('item');
+ item.id = 'item4';
+ item.textContent = 'item4';
+ Polymer.dom(s2).appendChild(item);
+ Polymer.dom.flush();
+ // set selected
+ s2.selected = 'item4';
+ // check items length
+ assert.equal(s2.$.selector.items.length, 5);
+ // check selected class
+ assert.isTrue(s2.querySelector('#item4').classList.contains('iron-selected'));
+ });
+
+ });
+
+ suite('content with dom-repeat', function() {
+
+ test('supports repeated children', function(done) {
+ t.items = [{name:'item0'}, {name: 'item1'}, {name: 'item2'}, {name: 'item3'}];
+ setTimeout(function() {
+ // check selected
+ assert.equal(s3.selected, 'item0');
+ // check selected class
+ assert.isTrue(s3.querySelector('#item0').classList.contains('iron-selected'));
+ // set selected
+ s3.selected = 'item2';
+ // check selected class
+ assert.isTrue(s3.querySelector('#item2').classList.contains('iron-selected'));
+ done();
+ });
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-selector/test/index.html b/polymer_1.0.4/bower_components/iron-selector/test/index.html
new file mode 100644
index 0000000..17d7e4b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/test/index.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+
+</head>
+<body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'activate-event.html',
+ 'basic.html',
+ 'multi.html',
+ 'next-previous.html',
+ 'selected-attribute.html',
+ 'template-repeat.html',
+ 'content.html'
+ ]);
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-selector/test/multi.html b/polymer_1.0.4/bower_components/iron-selector/test/multi.html
new file mode 100644
index 0000000..fdc31c7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/test/multi.html
@@ -0,0 +1,135 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-selector-multi</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-selector.html">
+
+ <style>
+ .iron-selected {
+ background: #ccc;
+ }
+ </style>
+
+</head>
+<body>
+
+ <test-fixture id="test">
+ <template>
+ <iron-selector multi>
+ <div>Item 0</div>
+ <div>Item 1</div>
+ <div>Item 2</div>
+ <div>Item 3</div>
+ <div>Item 4</div>
+ </iron-selector>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('multi', function() {
+
+ var s;
+
+ setup(function () {
+ s = fixture('test');
+ });
+
+ test('honors the multi attribute', function() {
+ assert.isTrue(s.multi);
+ });
+
+ test('has sane defaults', function() {
+ assert.equal(s.selectedValues, undefined);
+ assert.equal(s.selectedClass, 'iron-selected');
+ assert.equal(s.items.length, 5);
+ });
+
+ test('set multi-selection via selected property', function() {
+ // set selectedValues
+ s.selectedValues = [0, 2];
+ // check selected class
+ assert.isTrue(s.children[0].classList.contains('iron-selected'));
+ assert.isTrue(s.children[2].classList.contains('iron-selected'));
+ // check selectedItems
+ assert.equal(s.selectedItems.length, 2);
+ assert.equal(s.selectedItems[0], s.children[0]);
+ assert.equal(s.selectedItems[1], s.children[2]);
+ });
+
+ test('set multi-selection via tap', function() {
+ // set selectedValues
+ s.children[0].dispatchEvent(new CustomEvent('tap', {bubbles: true}));
+ s.children[2].dispatchEvent(new CustomEvent('tap', {bubbles: true}));
+ // check selected class
+ assert.isTrue(s.children[0].classList.contains('iron-selected'));
+ assert.isTrue(s.children[2].classList.contains('iron-selected'));
+ // check selectedItems
+ assert.equal(s.selectedItems.length, 2);
+ assert.equal(s.selectedItems[0], s.children[0]);
+ assert.equal(s.selectedItems[1], s.children[2]);
+ });
+
+ test('fire iron-select/deselect events', function() {
+ // setup listener for iron-select event
+ var selectEventCounter = 0;
+ s.addEventListener('iron-select', function(e) {
+ selectEventCounter++;
+ });
+ // setup listener for core-deselect event
+ var deselectEventCounter = 0;
+ s.addEventListener('iron-deselect', function(e) {
+ deselectEventCounter++;
+ });
+ // tap to select an item
+ s.children[0].dispatchEvent(new CustomEvent('tap', {bubbles: true}));
+ // check events
+ assert.equal(selectEventCounter, 1);
+ assert.equal(deselectEventCounter, 0);
+ // tap on already selected item should deselect it
+ s.children[0].dispatchEvent(new CustomEvent('tap', {bubbles: true}));
+ // check selectedValues
+ assert.equal(s.selectedValues.length, 0);
+ // check class
+ assert.isFalse(s.children[0].classList.contains('iron-selected'));
+ // check events
+ assert.equal(selectEventCounter, 1);
+ assert.equal(deselectEventCounter, 1);
+ });
+
+ /* test('toggle multi from true to false', function() {
+ // set selected
+ s.selected = [0, 2];
+ var first = s.selected[0];
+ // set mutli to false, so to make it single-selection
+ s.multi = false;
+ // selected should not be an array
+ assert.isNotArray(s.selected);
+ // selected should be the first value from the old array
+ assert.equal(s.selected, first);
+ }); */
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-selector/test/next-previous.html b/polymer_1.0.4/bower_components/iron-selector/test/next-previous.html
new file mode 100644
index 0000000..3a830c2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/test/next-previous.html
@@ -0,0 +1,134 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-selector-next-previous</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-selector.html">
+
+ <style>
+ .iron-selected {
+ background: #ccc;
+ }
+ </style>
+
+</head>
+<body>
+
+ <test-fixture id="test1">
+ <template>
+ <iron-selector selected="0">
+ <div>Item 0</div>
+ <div>Item 1</div>
+ <div>Item 2</div>
+ </iron-selector>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="test2">
+ <template>
+ <iron-selector selected="foo" attr-for-selected="name">
+ <div name="foo">Item Foo</div>
+ <div name="bar">Item Bar</div>
+ <div name="zot">Item Zot</div>
+ </iron-selector>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ var s;
+
+ function assertAndSelect(method, expectedIndex) {
+ assert.equal(s.selected, expectedIndex);
+ s[method]();
+ }
+
+ suite('next/previous', function() {
+
+ setup(function () {
+ s = fixture('test1');
+ });
+
+ test('selectNext', function() {
+ assert.equal(s.selected, 0);
+ assertAndSelect('selectNext', 0);
+ assertAndSelect('selectNext', 1);
+ assertAndSelect('selectNext', 2);
+ assert.equal(s.selected, 0);
+ });
+
+ test('selectPrevious', function() {
+ assert.equal(s.selected, 0);
+ assertAndSelect('selectPrevious', 0);
+ assertAndSelect('selectPrevious', 2);
+ assertAndSelect('selectPrevious', 1);
+ assert.equal(s.selected, 0);
+ });
+
+ test('selectNext/Previous', function() {
+ assert.equal(s.selected, 0);
+ assertAndSelect('selectNext', 0);
+ assertAndSelect('selectNext', 1);
+ assertAndSelect('selectPrevious', 2);
+ assertAndSelect('selectNext', 1);
+ assertAndSelect('selectPrevious', 2);
+ assert.equal(s.selected, 1);
+ });
+
+ });
+
+ suite('next/previous attrForSelected', function() {
+
+ setup(function () {
+ s = fixture('test2');
+ });
+
+ test('selectNext', function() {
+ assert.equal(s.selected, 'foo');
+ assertAndSelect('selectNext', 'foo');
+ assertAndSelect('selectNext', 'bar');
+ assertAndSelect('selectNext', 'zot');
+ assert.equal(s.selected, 'foo');
+ });
+
+ test('selectPrevious', function() {
+ assert.equal(s.selected, 'foo');
+ assertAndSelect('selectPrevious', 'foo');
+ assertAndSelect('selectPrevious', 'zot');
+ assertAndSelect('selectPrevious', 'bar');
+ assert.equal(s.selected, 'foo');
+ });
+
+ test('selectNext/Previous', function() {
+ assert.equal(s.selected, 'foo');
+ assertAndSelect('selectNext', 'foo');
+ assertAndSelect('selectNext', 'bar');
+ assertAndSelect('selectPrevious', 'zot');
+ assertAndSelect('selectNext', 'bar');
+ assertAndSelect('selectPrevious', 'zot');
+ assert.equal(s.selected, 'bar');
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-selector/test/selected-attribute.html b/polymer_1.0.4/bower_components/iron-selector/test/selected-attribute.html
new file mode 100644
index 0000000..3e1ecaf
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/test/selected-attribute.html
@@ -0,0 +1,72 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-selector-selected-attribute</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../iron-selector.html">
+
+ <style>
+ .iron-selected {
+ background: #ccc;
+ }
+ </style>
+
+</head>
+<body>
+
+ <test-fixture id="test">
+ <template>
+ <iron-selector id="selector">
+ <div>Item 0</div>
+ <div>Item 1</div>
+ <div>Item 2</div>
+ <div>Item 3</div>
+ <div>Item 4</div>
+ </iron-selector>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('selected attributes', function() {
+
+ var s;
+
+ setup(function () {
+ s = fixture('test');
+ });
+
+ test('custom selectedAttribute', function() {
+ // set selectedAttribute
+ s.selectedAttribute = 'myattr';
+ // check selected attribute (should not be there)
+ assert.isFalse(s.children[4].hasAttribute('myattr'));
+ // set selected
+ s.selected = 4;
+ // now selected attribute should be there
+ assert.isTrue(s.children[4].hasAttribute('myattr'));
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-selector/test/template-repeat.html b/polymer_1.0.4/bower_components/iron-selector/test/template-repeat.html
new file mode 100644
index 0000000..eae2729
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-selector/test/template-repeat.html
@@ -0,0 +1,110 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <title>iron-selector-template-repeat</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+
+ <link rel="import" href="../iron-selector.html">
+
+ <style>
+ .iron-selected {
+ background: #ccc;
+ }
+ </style>
+
+</head>
+<body>
+
+ <template is="dom-bind">
+ <iron-selector id="selector" selected="1">
+ <template id="t" is="dom-repeat">
+ <div id$="[[item.name]]">{{item.name}}</div>
+ </template>
+ </iron-selector>
+ </template>
+
+ <script>
+
+ suite('dom-repeat', function() {
+
+ var scope, s, t;
+
+ setup(function() {
+ scope = document.querySelector('template[is="dom-bind"]');
+ s = scope.$.selector;
+ t = scope.$.t;
+ t.items = [{name:'item0'}, {name: 'item1'}, {name: 'item2'}, {name: 'item3'}];
+ });
+
+ teardown(function() {
+ t.items = [];
+ });
+
+ test('supports repeated items', function(done) {
+ setTimeout(function() {
+ // check items
+ assert.equal(s.items.length, 4);
+ // check selected
+ assert.equal(s.selected, 1);
+ // check selected item
+ var item = s.selectedItem;
+ assert.equal(s.items[1], item);
+ // check selected class
+ assert.isTrue(item.classList.contains('iron-selected'));
+ done();
+ });
+ });
+
+ test('update items', function(done) {
+ setTimeout(function() {
+ // check items
+ assert.equal(s.items.length, 4);
+ // check selected
+ assert.equal(s.selected, 1);
+ // update items
+ t.items = [{name:'foo'}, {name: 'bar'}];
+ setTimeout(function() {
+ // check items
+ assert.equal(s.items.length, 2);
+ // check selected (should still honor the selected)
+ assert.equal(s.selected, 1);
+ // check selected class
+ assert.isTrue(s.querySelector('#bar').classList.contains('iron-selected'));
+ done();
+ });
+ });
+ });
+
+ test('set selected to something else', function(done) {
+ setTimeout(function() {
+ // set selected to something else
+ s.selected = 3;
+ // check selected item
+ var item = s.selectedItem;
+ assert.equal(s.items[3], item);
+ // check selected class
+ assert.isTrue(item.classList.contains('iron-selected'));
+ done();
+ });
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-signals/.bower.json b/polymer_1.0.4/bower_components/iron-signals/.bower.json
new file mode 100644
index 0000000..c005b31
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-signals/.bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "iron-signals",
+ "version": "1.0.2",
+ "description": "Basic publish-subscribe functionality",
+ "keywords": [
+ "web-component",
+ "polymer",
+ "signals"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-signals.git"
+ },
+ "main": "iron-signals.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-signals/",
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.2",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "24cfc2295603c8113a8395952435ebb1e31c2bdf"
+ },
+ "_source": "git://github.com/PolymerElements/iron-signals.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-signals"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-signals/.gitignore b/polymer_1.0.4/bower_components/iron-signals/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-signals/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-signals/README.md b/polymer_1.0.4/bower_components/iron-signals/README.md
new file mode 100644
index 0000000..ff62a2d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-signals/README.md
@@ -0,0 +1,26 @@
+iron-signals
+============
+
+`iron-signals` provides basic publish-subscribe functionality.
+
+Note: avoid using `iron-signals` whenever you can use
+a controller (parent element) to mediate communication
+instead.
+
+To send a signal, fire a custom event of type `iron-signal`, with
+a detail object containing `name` and `data` fields.
+
+```javascript
+this.fire('iron-signal', {name: 'hello', data: null});
+```
+
+To receive a signal, listen for `iron-signal-<name>` event on a
+`iron-signals` element.
+
+```html
+<iron-signals on-iron-signal-hello="helloSignal">
+```
+
+You can fire a signal event from anywhere, and all
+`iron-signals` elements will receive the event, regardless
+of where they are in DOM.
diff --git a/polymer_1.0.4/bower_components/iron-signals/bower.json b/polymer_1.0.4/bower_components/iron-signals/bower.json
new file mode 100644
index 0000000..5273405
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-signals/bower.json
@@ -0,0 +1,28 @@
+{
+ "name": "iron-signals",
+ "version": "1.0.2",
+ "description": "Basic publish-subscribe functionality",
+ "keywords": [
+ "web-component",
+ "polymer",
+ "signals"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-signals.git"
+ },
+ "main": "iron-signals.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-signals/",
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.2",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-signals/demo/index.html b/polymer_1.0.4/bower_components/iron-signals/demo/index.html
new file mode 100644
index 0000000..f5b4454
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-signals/demo/index.html
@@ -0,0 +1,54 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>iron-signals demo</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../iron-signals.html">
+ </head>
+<body>
+
+ <div class="vertical-section vertical-section-container centered">
+
+ <h1><iron-signal></h1>
+ <template is="dom-bind" id="my-app">
+ <iron-signals on-iron-signal-foo="fooSignal"></iron-signals>
+ </template>
+
+ <template is="dom-bind" id="signal-message">
+ <template is="dom-if" if="{{detail}}">
+ <div><code>my-app</code> got a <code>{{detail}}</code> signal</div>
+ </template>
+ </template>
+
+ </div>
+
+ <script>
+
+ document.addEventListener("WebComponentsReady", function() {
+ document.querySelector('#my-app').fire('iron-signal', {name: "foo", data: "Foo!"});
+ });
+
+ document.querySelector("#my-app").fooSignal = function(e, detail, sender) {
+ document.querySelector("#signal-message").detail = detail;
+ };
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-signals/index.html b/polymer_1.0.4/bower_components/iron-signals/index.html
new file mode 100644
index 0000000..246af10
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-signals/index.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-signals/iron-signals.html b/polymer_1.0.4/bower_components/iron-signals/iron-signals.html
new file mode 100644
index 0000000..dcf2e59
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-signals/iron-signals.html
@@ -0,0 +1,81 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+(function(){
+/**
+`iron-signals` provides basic publish-subscribe functionality.
+
+Note: avoid using `iron-signals` whenever you can use
+a controller (parent element) to mediate communication
+instead.
+
+To send a signal, fire a custom event of type `iron-signal`, with
+a detail object containing `name` and `data` fields.
+
+ this.fire('iron-signal', {name: 'hello', data: null});
+
+To receive a signal, listen for `iron-signal-<name>` event on a
+`iron-signals` element.
+
+ <iron-signals on-iron-signal-hello="{{helloSignal}}">
+
+You can fire a signal event from anywhere, and all
+`iron-signals` elements will receive the event, regardless
+of where they are in DOM.
+
+@demo demo/index.html
+*/
+ Polymer({
+ is: 'iron-signals',
+
+ attached: function() {
+ signals.push(this);
+ },
+ detached: function() {
+ var i = signals.indexOf(this);
+ if (i >= 0) {
+ signals.splice(i, 1);
+ }
+ }
+ });
+
+ // private shared database
+ var signals = [];
+
+ // signal dispatcher
+ function notify(name, data) {
+ // convert generic-signal event to named-signal event
+ var signal = new CustomEvent('iron-signal-' + name, {
+ // if signals bubble, it's easy to get confusing duplicates
+ // (1) listen on a container on behalf of local child
+ // (2) some deep child ignores the event and it bubbles
+ // up to said container
+ // (3) local child event bubbles up to container
+ // also, for performance, we avoid signals flying up the
+ // tree from all over the place
+ bubbles: false,
+ detail: data
+ });
+ // dispatch named-signal to all 'signals' instances,
+ // only interested listeners will react
+ signals.forEach(function(s) {
+ s.dispatchEvent(signal);
+ });
+ }
+
+ // signal listener at document
+ document.addEventListener('iron-signal', function(e) {
+ notify(e.detail.name, e.detail.data);
+ });
+
+})();
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-test-helpers/.bower.json b/polymer_1.0.4/bower_components/iron-test-helpers/.bower.json
new file mode 100644
index 0000000..0f3971a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-test-helpers/.bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "iron-test-helpers",
+ "version": "1.0.1",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "Utility classes to help make testing easier",
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer",
+ "test"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-test-helpers"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-test-helpers",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "4c5d28f58adda0d076850321582cfe86359f95fb"
+ },
+ "_source": "git://github.com/PolymerElements/iron-test-helpers.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-test-helpers"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-test-helpers/.gitignore b/polymer_1.0.4/bower_components/iron-test-helpers/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-test-helpers/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-test-helpers/README.md b/polymer_1.0.4/bower_components/iron-test-helpers/README.md
new file mode 100644
index 0000000..dbc5318
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-test-helpers/README.md
@@ -0,0 +1,23 @@
+# iron-test-helpers
+
+Utility classes to make testing easier.
+
+## Mock Interactions
+
+This is a set of methods to simulate mouse or keyboard interaction with an element. Include `mock-interactions.js` and then use them like so:
+
+```javascript
+test('can be triggered with space', function(done) {
+ button.addEventListener('keydown', function() {
+ done();
+ });
+ MockInteractions.pressSpace(button);
+});
+
+test('can be clicked', function(done) {
+ button.addEventListener('click', function() {
+ done();
+ });
+ MockInteractions.down(button);
+});
+```
diff --git a/polymer_1.0.4/bower_components/iron-test-helpers/bower.json b/polymer_1.0.4/bower_components/iron-test-helpers/bower.json
new file mode 100644
index 0000000..4b3f5f3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-test-helpers/bower.json
@@ -0,0 +1,28 @@
+{
+ "name": "iron-test-helpers",
+ "version": "1.0.1",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "Utility classes to help make testing easier",
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer",
+ "test"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-test-helpers"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-test-helpers",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-test-helpers/iron-test-helpers.html b/polymer_1.0.4/bower_components/iron-test-helpers/iron-test-helpers.html
new file mode 100644
index 0000000..b68589d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-test-helpers/iron-test-helpers.html
@@ -0,0 +1,22 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<script src="mock-interactions.js"></script>
+<script src="test-helpers.js"></script>
+<script>
+ (function(global) {
+ 'use strict';
+
+ var TestHelpers = global.TestHelpers = global.TestHelpers || {};
+
+ TestHelpers.flushAsynchronousOperations = flushAsynchronousOperations;
+ TestHelpers.forceXIfStamp = forceXIfStamp;
+ TestHelpers.fireEvent = fireEvent;
+ })(this);
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-test-helpers/mock-interactions.js b/polymer_1.0.4/bower_components/iron-test-helpers/mock-interactions.js
new file mode 100644
index 0000000..887b9be
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-test-helpers/mock-interactions.js
@@ -0,0 +1,177 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+(function(global) {
+ 'use strict';
+
+ var HAS_NEW_MOUSE = (function() {
+ var has = false;
+ try {
+ has = Boolean(new MouseEvent('x'));
+ } catch (_) {}
+ return has;
+ })();
+
+ function middleOfNode(node) {
+ var bcr = node.getBoundingClientRect();
+ return {
+ y: bcr.top + (bcr.height / 2),
+ x: bcr.left + (bcr.width / 2)
+ };
+ }
+
+ function topLeftOfNode(node) {
+ var bcr = node.getBoundingClientRect();
+ return {
+ y: bcr.top,
+ x: bcr.left
+ };
+ }
+
+ function makeEvent(type, xy, node) {
+ var props = {
+ bubbles: true,
+ cancelable: true,
+ clientX: xy.x,
+ clientY: xy.y
+ };
+ var e;
+ var mousetype = type === 'tap' ? 'click' : 'mouse' + type;
+ if (HAS_NEW_MOUSE) {
+ e = new MouseEvent(mousetype, props);
+ } else {
+ e = document.createEvent('MouseEvent');
+ e.initMouseEvent(mousetype, props.bubbles, props.cancelable, null, null, 0, 0,
+ props.clientX, props.clientY, false, false, false, false, 0, null);
+ }
+ node.dispatchEvent(e);
+ }
+
+ function down(node, xy) {
+ xy = xy || middleOfNode(node);
+ makeEvent('down', xy, node);
+ }
+
+ function move(node, fromXY, toXY, steps) {
+ steps = steps || 5;
+ var dx = Math.round((fromXY.x - toXY.x) / steps);
+ var dy = Math.round((fromXY.y - toXY.y) / steps);
+ var xy = {
+ x: fromXY.x,
+ y: fromXY.y
+ };
+ for (var i = steps; i > 0; i--) {
+ makeEvent('move', xy, node);
+ xy.x += dx;
+ xy.y += dy;
+ }
+ makeEvent('move', {
+ x: toXY.x,
+ y: toXY.y
+ }, node);
+ }
+
+ function up(node, xy) {
+ xy = xy || middleOfNode(node);
+ makeEvent('up', xy, node);
+ }
+
+ function tap(node) {
+ var xy = middleOfNode(node);
+ down(node, xy);
+ up(node, xy);
+ makeEvent('tap', xy, node);
+ }
+
+ function focus(target) {
+ Polymer.Base.fire.call(target, 'focus');
+ }
+
+ function blur(target) {
+ Polymer.Base.fire.call(target, 'blur');
+ }
+
+ function downAndUp(target, callback) {
+ down(target);
+ Polymer.Base.async(function() {
+ up(target);
+ tap(target);
+
+ callback && callback();
+ });
+ }
+
+ function track(target, dx, dy, steps) {
+ dx = dx | 0;
+ dy = dy | 0;
+ steps = steps || 5;
+ down(target);
+ var xy = middleOfNode(target);
+ var xy2 = {
+ x: xy.x + dx,
+ y: xy.y + dy
+ };
+ move(target, xy, xy2, steps);
+ up(target, xy2);
+ }
+
+ function keyboardEventFor(type, keyCode) {
+ var event = new CustomEvent(type);
+
+ event.keyCode = keyCode;
+ event.code = keyCode;
+
+ return event;
+ }
+
+ function keyEventOn(target, type, keyCode) {
+ target.dispatchEvent(keyboardEventFor(type, keyCode));
+ }
+
+ function keyDownOn(target, keyCode) {
+ keyEventOn(target, 'keydown', keyCode);
+ }
+
+ function keyUpOn(target, keyCode) {
+ keyEventOn(target, 'keyup', keyCode);
+ }
+
+ function pressAndReleaseKeyOn(target, keyCode) {
+ keyDownOn(target, keyCode);
+ Polymer.Base.async(function() {
+ keyUpOn(target, keyCode);
+ }, 1);
+ }
+
+ function pressEnter(target) {
+ pressAndReleaseKeyOn(target, 13);
+ }
+
+ function pressSpace(target) {
+ pressAndReleaseKeyOn(target, 32);
+ }
+
+ global.MockInteractions = {
+ focus: focus,
+ blur: blur,
+ down: down,
+ up: up,
+ downAndUp: downAndUp,
+ tap: tap,
+ track: track,
+ pressAndReleaseKeyOn: pressAndReleaseKeyOn,
+ pressEnter: pressEnter,
+ pressSpace: pressSpace,
+ keyDownOn: keyDownOn,
+ keyUpOn: keyUpOn,
+ middleOfNode: middleOfNode,
+ topLeftOfNode: topLeftOfNode
+ };
+})(this);
diff --git a/polymer_1.0.4/bower_components/iron-test-helpers/test-helpers.js b/polymer_1.0.4/bower_components/iron-test-helpers/test-helpers.js
new file mode 100644
index 0000000..3465186
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-test-helpers/test-helpers.js
@@ -0,0 +1,39 @@
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+(function(global) {
+
+ global.flushAsynchronousOperations = function() {
+ // force distribution
+ Polymer.dom.flush();
+ // force lifecycle callback to fire on polyfill
+ window.CustomElements && window.CustomElements.takeRecords();
+ };
+
+ global.forceXIfStamp = function(node) {
+ var templates = Polymer.dom(node.root).querySelectorAll('template[is=dom-if]');
+ for (var tmpl, i = 0; tmpl = templates[i]; i++) {
+ tmpl.render();
+ }
+
+ global.flushAsynchronousOperations();
+ };
+
+ global.fireEvent = function(type, props, node) {
+ var event = new CustomEvent(type, {
+ bubbles: true,
+ cancelable: true
+ });
+ for (p in props) {
+ event[p] = props[p];
+ }
+ node.dispatchEvent(event);
+ };
+
+})(this);
diff --git a/polymer_1.0.4/bower_components/iron-validatable-behavior/.bower.json b/polymer_1.0.4/bower_components/iron-validatable-behavior/.bower.json
new file mode 100644
index 0000000..b1acc42
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validatable-behavior/.bower.json
@@ -0,0 +1,44 @@
+{
+ "name": "iron-validatable-behavior",
+ "version": "1.0.2",
+ "description": "Provides a behavior for an element that validates user input",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "iron",
+ "behavior"
+ ],
+ "main": [
+ "iron-validatable-behavior.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-validatable-behavior.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-validatable-behavior",
+ "ignore": [],
+ "dependencies": {
+ "iron-meta": "PolymerElements/iron-meta#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.4",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "1.0.2",
+ "commit": "a4fc340fdb268e274f312dadedd0633b025ac3a4"
+ },
+ "_source": "git://github.com/PolymerElements/iron-validatable-behavior.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-validatable-behavior"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-validatable-behavior/.gitignore b/polymer_1.0.4/bower_components/iron-validatable-behavior/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validatable-behavior/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-validatable-behavior/README.md b/polymer_1.0.4/bower_components/iron-validatable-behavior/README.md
new file mode 100644
index 0000000..48f7fb2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validatable-behavior/README.md
@@ -0,0 +1,3 @@
+# iron-validatable-behavior
+Implements an element validated with Polymer.IronValidatorBehavior
+
diff --git a/polymer_1.0.4/bower_components/iron-validatable-behavior/bower.json b/polymer_1.0.4/bower_components/iron-validatable-behavior/bower.json
new file mode 100644
index 0000000..eaab387
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validatable-behavior/bower.json
@@ -0,0 +1,35 @@
+{
+ "name": "iron-validatable-behavior",
+ "version": "1.0.2",
+ "description": "Provides a behavior for an element that validates user input",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "iron",
+ "behavior"
+ ],
+ "main": [
+ "iron-validatable-behavior.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-validatable-behavior.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-validatable-behavior",
+ "ignore": [],
+ "dependencies": {
+ "iron-meta": "PolymerElements/iron-meta#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.4",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-validatable-behavior/demo/cats-only.html b/polymer_1.0.4/bower_components/iron-validatable-behavior/demo/cats-only.html
new file mode 100644
index 0000000..83ef9ba
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validatable-behavior/demo/cats-only.html
@@ -0,0 +1,46 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../../iron-validator-behavior/iron-validator-behavior.html">
+
+<script>
+
+ Polymer({
+
+ is: 'cats-only',
+
+ behaviors: [
+ Polymer.IronValidatorBehavior
+ ],
+
+ validateObject: function(obj) {
+ var valid = true;
+ for (key in obj) {
+ if (obj[key] !== 'cats') {
+ valid = false;
+ break;
+ }
+ }
+ return valid;
+ },
+
+ validate: function(values) {
+ if (typeof values === 'object') {
+ return this.validateObject(values);
+ } else {
+ var value = Array.isArray(values) ? values.join('') : values;
+ return value.match(/^(c|ca|cat|cats)?$/) !== null;
+ }
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-validatable-behavior/demo/index.html b/polymer_1.0.4/bower_components/iron-validatable-behavior/demo/index.html
new file mode 100644
index 0000000..84b96a8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validatable-behavior/demo/index.html
@@ -0,0 +1,71 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>iron-validatable-behavior demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="cats-only.html">
+ <link rel="import" href="validatable-input.html">
+
+ <style is="custom-style">
+
+ .valid {
+ color: var(--google-green-500);
+ }
+
+ .invalid {
+ color: var(--google-red-500);
+ }
+
+ </style>
+
+</head>
+<body>
+ <div class="vertical-section vertical-section-container centered">
+ <h1><iron-validatable-behavior></h1>
+
+ <template is="dom-bind">
+
+ <cats-only></cats-only>
+
+ <section>
+
+ <p>
+ only type <code>cats</code>:
+
+ <input is="validatable-input" invalid="{{invalid}}" validator="cats-only">
+
+ <span class="valid" hidden$="[[invalid]]">valid</span>
+ <span class="invalid" hidden$="[[!invalid]]">invalid</span>
+ </p>
+
+ </section>
+
+ </template>
+
+ </div>
+
+ <script>
+
+ document.querySelector('template[is="dom-bind"]').invalid = false;
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-validatable-behavior/demo/validatable-input.html b/polymer_1.0.4/bower_components/iron-validatable-behavior/demo/validatable-input.html
new file mode 100644
index 0000000..19cf477
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validatable-behavior/demo/validatable-input.html
@@ -0,0 +1,46 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../iron-validatable-behavior.html">
+
+<script>
+
+ Polymer({
+
+ is: 'validatable-input',
+
+ extends: 'input',
+
+ properties: {
+
+ invalid: {
+ notify: true,
+ type: Boolean,
+ value: false
+ }
+
+ },
+
+ behaviors: [
+ Polymer.IronValidatableBehavior
+ ],
+
+ listeners: {
+ 'input': '_onInput'
+ },
+
+ _onInput: function(event) {
+ this.invalid = !this.validate(event.target.value);
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-validatable-behavior/index.html b/polymer_1.0.4/bower_components/iron-validatable-behavior/index.html
new file mode 100644
index 0000000..cfaa5b1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validatable-behavior/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>iron-validatable-behavior</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-validatable-behavior/iron-validatable-behavior.html b/polymer_1.0.4/bower_components/iron-validatable-behavior/iron-validatable-behavior.html
new file mode 100644
index 0000000..c59c47e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validatable-behavior/iron-validatable-behavior.html
@@ -0,0 +1,101 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-meta/iron-meta.html">
+
+<script>
+
+ /**
+ * Use `Polymer.IronValidatableBehavior` to implement an element that validates user input.
+ *
+ * ### Accessiblity
+ *
+ * Changing the `invalid` property, either manually or by calling `validate()` will update the
+ * `aria-invalid` attribute.
+ *
+ * @demo demo/index.html
+ * @polymerBehavior
+ */
+ Polymer.IronValidatableBehavior = {
+
+ properties: {
+
+ /**
+ * Namespace for this validator.
+ */
+ validatorType: {
+ type: String,
+ value: 'validator'
+ },
+
+ /**
+ * Name of the validator to use.
+ */
+ validator: {
+ type: String
+ },
+
+ /**
+ * True if the last call to `validate` is invalid.
+ */
+ invalid: {
+ notify: true,
+ reflectToAttribute: true,
+ type: Boolean,
+ value: false
+ },
+
+ _validatorMeta: {
+ type: Object
+ }
+
+ },
+
+ observers: [
+ '_invalidChanged(invalid)'
+ ],
+
+ get _validator() {
+ return this._validatorMeta && this._validatorMeta.byKey(this.validator);
+ },
+
+ ready: function() {
+ this._validatorMeta = new Polymer.IronMeta({type: this.validatorType});
+ },
+
+ _invalidChanged: function() {
+ if (this.invalid) {
+ this.setAttribute('aria-invalid', 'true');
+ } else {
+ this.removeAttribute('aria-invalid');
+ }
+ },
+
+ /**
+ * @return {boolean} True if the validator `validator` exists.
+ */
+ hasValidator: function() {
+ return this._validator != null;
+ },
+
+ /**
+ * @param {Object} values Passed to the validator's `validate()` function.
+ * @return {boolean} True if `values` is valid.
+ */
+ validate: function(values) {
+ var valid = this._validator && this._validator.validate(values);
+ this.invalid = !valid;
+ return valid;
+ }
+
+ };
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-validatable-behavior/test/index.html b/polymer_1.0.4/bower_components/iron-validatable-behavior/test/index.html
new file mode 100644
index 0000000..05194fd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validatable-behavior/test/index.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>paper-validatable-behavior tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ /* no tests */
+ WCT.loadSuites([
+ 'iron-validatable-behavior.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-validatable-behavior/test/iron-validatable-behavior.html b/polymer_1.0.4/bower_components/iron-validatable-behavior/test/iron-validatable-behavior.html
new file mode 100644
index 0000000..435c034
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validatable-behavior/test/iron-validatable-behavior.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>iron-validatable-behavior tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="test-validatable.html">
+
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <test-validatable></test-validatable>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+
+ test('setting `invalid` sets `aria-invalid=true`', function() {
+ var node = fixture('basic');
+ node.invalid = true;
+ assert.equal(node.getAttribute('aria-invalid'), 'true', 'aria-invalid is set');
+ node.invalid = false;
+ assert.isFalse(node.hasAttribute('aria-invalid'), 'aria-invalid is unset');
+ });
+
+ });
+
+ </script>
+
+</body>
diff --git a/polymer_1.0.4/bower_components/iron-validatable-behavior/test/test-validatable.html b/polymer_1.0.4/bower_components/iron-validatable-behavior/test/test-validatable.html
new file mode 100644
index 0000000..51513bf
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validatable-behavior/test/test-validatable.html
@@ -0,0 +1,28 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../iron-validatable-behavior.html">
+
+<dom-module id="test-validatable">
+ <template>
+ <content></content>
+ </template>
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'test-validatable',
+
+ behaviors: [
+ Polymer.IronValidatableBehavior
+ ]
+
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-validator-behavior/.bower.json b/polymer_1.0.4/bower_components/iron-validator-behavior/.bower.json
new file mode 100644
index 0000000..257b945
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validator-behavior/.bower.json
@@ -0,0 +1,43 @@
+{
+ "name": "iron-validator-behavior",
+ "version": "1.0.1",
+ "description": "Implements a input validator",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "iron",
+ "behavior"
+ ],
+ "main": [
+ "iron-validator-behavior.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-validator-behavior.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-validator-behavior",
+ "ignore": [],
+ "dependencies": {
+ "iron-meta": "PolymerElements/iron-meta#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "fd9c609472c0c0b64657488d1d33dfc2365dea44"
+ },
+ "_source": "git://github.com/PolymerElements/iron-validator-behavior.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/iron-validator-behavior"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/iron-validator-behavior/.gitignore b/polymer_1.0.4/bower_components/iron-validator-behavior/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validator-behavior/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/iron-validator-behavior/README.md b/polymer_1.0.4/bower_components/iron-validator-behavior/README.md
new file mode 100644
index 0000000..8aa8b61
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validator-behavior/README.md
@@ -0,0 +1,4 @@
+# iron-validator-behavior
+Use `Polymer.IronValidatorBehavior` to implement a custom input/form validator. Element instances
+implementing this behavior will be registered for use in elements that implement
+`Polymer.IronValidatableBehavior`.
diff --git a/polymer_1.0.4/bower_components/iron-validator-behavior/bower.json b/polymer_1.0.4/bower_components/iron-validator-behavior/bower.json
new file mode 100644
index 0000000..7d57d72
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validator-behavior/bower.json
@@ -0,0 +1,34 @@
+{
+ "name": "iron-validator-behavior",
+ "version": "1.0.1",
+ "description": "Implements a input validator",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "iron",
+ "behavior"
+ ],
+ "main": [
+ "iron-validator-behavior.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/iron-validator-behavior.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/iron-validator-behavior",
+ "ignore": [],
+ "dependencies": {
+ "iron-meta": "PolymerElements/iron-meta#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/iron-validator-behavior/demo/cats-only.html b/polymer_1.0.4/bower_components/iron-validator-behavior/demo/cats-only.html
new file mode 100644
index 0000000..9221f65
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validator-behavior/demo/cats-only.html
@@ -0,0 +1,46 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../iron-validator-behavior.html">
+
+<script>
+
+ Polymer({
+
+ is: 'cats-only',
+
+ behaviors: [
+ Polymer.IronValidatorBehavior
+ ],
+
+ validateObject: function(obj) {
+ var valid = true;
+ for (key in obj) {
+ if (obj[key] !== 'cats') {
+ valid = false;
+ break;
+ }
+ }
+ return valid;
+ },
+
+ validate: function(values) {
+ if (typeof values === 'object') {
+ return this.validateObject(values);
+ } else {
+ var value = Array.isArray(values) ? values.join('') : values;
+ return value.match(/^(c|ca|cat|cats)?$/) !== null;
+ }
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-validator-behavior/demo/index.html b/polymer_1.0.4/bower_components/iron-validator-behavior/demo/index.html
new file mode 100644
index 0000000..8daa13b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validator-behavior/demo/index.html
@@ -0,0 +1,144 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>iron-validator-behavior demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../iron-meta/iron-meta.html">
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="cats-only.html">
+
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+
+ <style>
+
+ .valid {
+ color: limegreen;
+ }
+
+ .invalid {
+ color: red;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <template is="dom-bind">
+
+ <cats-only></cats-only>
+
+ <section>
+
+ <p>
+ only type <code>cats</code>:
+
+ <input on-input="_onInput">
+
+ <span class="valid" hidden$="[[!valid]]">valid</span>
+ <span class="invalid" hidden$="[[valid]]">invalid</span>
+ </p>
+
+ </section>
+
+ <section>
+
+ <p>
+ only type <code>cats</code> across both input fields:
+
+ <span on-input="_onInputMulti">
+ <input>
+ <input>
+ </span>
+
+ <span class="valid" hidden$="[[!validMulti]]">valid</span>
+ <span class="invalid" hidden$="[[validMulti]]">invalid</span>
+ </p>
+
+ </section>
+
+ <section>
+
+ <p>
+ only type <code>cats</code> in the form:
+
+ <form on-submit="_onSubmit">
+ <label>
+ Type something: <input name="something">
+ </label>
+ <br>
+ <label>
+ Your favorite pet:
+ <select name="pet">
+ <option>iguanas</option>
+ <option>cats</option>
+ <option>pancakes</option>
+ </select>
+ </label>
+ <br>
+ <button type="submit">submit!</button>
+ <span class="valid" hidden$="[[!validForm]]">valid</span>
+ <span class="invalid" hidden$="[[validForm]]">invalid</span>
+ </form>
+
+ </p>
+
+ </section>
+
+ </template>
+
+ <script>
+
+ document.addEventListener('WebComponentsReady', function() {
+
+ var validator = new Polymer.IronMeta({type: 'validator'}).byKey('cats-only');
+
+ var scope = document.querySelector('template[is=dom-bind]');
+ scope.valid = scope.validMulti = scope.validForm = true;
+
+ scope._onInput = function(event) {
+ this.valid = validator.validate(event.target.value);
+ };
+
+ scope._onInputMulti = function(event) {
+ var values = [];
+ var nodes = Polymer.dom(event.currentTarget).querySelectorAll('input');
+ for (var node, i = 0; node = nodes[i]; i++) {
+ values.push(node.value);
+ }
+ this.validMulti = validator.validate(values);
+ };
+
+ scope._onSubmit = function(event) {
+ event.preventDefault();
+
+ var data = {};
+ for (var el, i = 0; el = event.target.elements[i]; i++) {
+ if (el.name) {
+ data[el.name] = el.value;
+ }
+ }
+ this.validForm = validator.validate(data);
+ };
+
+ });
+
+ </script>
+
+</body>
diff --git a/polymer_1.0.4/bower_components/iron-validator-behavior/index.html b/polymer_1.0.4/bower_components/iron-validator-behavior/index.html
new file mode 100644
index 0000000..d0f6936
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validator-behavior/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>iron-validator-behavior</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-validator-behavior/iron-validator-behavior.html b/polymer_1.0.4/bower_components/iron-validator-behavior/iron-validator-behavior.html
new file mode 100644
index 0000000..d8afc84
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validator-behavior/iron-validator-behavior.html
@@ -0,0 +1,61 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-meta/iron-meta.html">
+
+<script>
+
+ /**
+ * Use `Polymer.IronValidatorBehavior` to implement a custom input/form validator. Element
+ * instances implementing this behavior will be registered for use in elements that implement
+ * `Polymer.IronValidatableBehavior`.
+ *
+ * @demo demo/index.html
+ * @polymerBehavior
+ */
+ Polymer.IronValidatorBehavior = {
+
+ properties: {
+
+ /**
+ * Namespace for this validator.
+ */
+ validatorType: {
+ type: String,
+ value: 'validator'
+ },
+
+ /**
+ * Name for this validator, used by `Polymer.IronValidatableBehavior` to lookup this element.
+ */
+ validatorName: {
+ type: String,
+ value: function() {
+ return this.is;
+ }
+ }
+
+ },
+
+ ready: function() {
+ new Polymer.IronMeta({type: this.validatorType, key: this.validatorName, value: this});
+ },
+
+ /**
+ * Implement custom validation logic in this function.
+ * @param {Object} values The value to validate. May be any type depending on the validation logic.
+ * @return {Boolean} true if `values` is valid.
+ */
+ validate: function(values) {
+ }
+ };
+
+</script>
diff --git a/polymer_1.0.4/bower_components/iron-validator-behavior/test/index.html b/polymer_1.0.4/bower_components/iron-validator-behavior/test/index.html
new file mode 100644
index 0000000..809888e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validator-behavior/test/index.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>paper-validator-behavior tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'iron-validator-behavior.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-validator-behavior/test/iron-validator-behavior.html b/polymer_1.0.4/bower_components/iron-validator-behavior/test/iron-validator-behavior.html
new file mode 100644
index 0000000..3b4ba71
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validator-behavior/test/iron-validator-behavior.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>iron-validator-behavior basic tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link href="../../test-fixture/test-fixture.html" rel="import">
+ <link href="../../iron-meta/iron-meta.html" rel="import">
+ <link href="simple-validator.html" rel="import">
+
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <simple-validator></simple-validator>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+
+ test('registered in <iron-meta>', function() {
+ fixture('basic');
+ assert.ok(new Polymer.IronMeta({type: 'validator'}).byKey('simple-validator'), 'simple-validator found in <iron-meta>');
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/iron-validator-behavior/test/simple-validator.html b/polymer_1.0.4/bower_components/iron-validator-behavior/test/simple-validator.html
new file mode 100644
index 0000000..b794ed7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/iron-validator-behavior/test/simple-validator.html
@@ -0,0 +1,26 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../iron-validator-behavior.html">
+
+<script>
+
+ Polymer({
+
+ is: 'simple-validator',
+
+ behaviors: [
+ Polymer.IronValidatorBehavior
+ ]
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/marked-element/.bower.json b/polymer_1.0.4/bower_components/marked-element/.bower.json
new file mode 100644
index 0000000..34f2def
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked-element/.bower.json
@@ -0,0 +1,44 @@
+{
+ "name": "marked-element",
+ "version": "1.0.2",
+ "description": "Element wrapper for the marked library",
+ "private": true,
+ "authors": [
+ "The Polymer Project Authors (https://polymer.github.io/AUTHORS.txt)"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "marked",
+ "markdown",
+ "container",
+ "wrapper"
+ ],
+ "dependencies": {
+ "marked": "~0.3.3",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "license": "https://polymer.github.io/LICENSE.txt",
+ "main": "marked-element.html",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/marked-element.git"
+ },
+ "devDependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.4",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/marked-element",
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "1e5d6d457574cfab7d5ab44414bfef4dc37f8037"
+ },
+ "_source": "git://github.com/PolymerElements/marked-element.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/marked-element"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/marked-element/.gitignore b/polymer_1.0.4/bower_components/marked-element/.gitignore
new file mode 100644
index 0000000..fbe05fc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked-element/.gitignore
@@ -0,0 +1 @@
+bower_components/
diff --git a/polymer_1.0.4/bower_components/marked-element/README.md b/polymer_1.0.4/bower_components/marked-element/README.md
new file mode 100644
index 0000000..9b48cad
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked-element/README.md
@@ -0,0 +1,31 @@
+marked-element
+==============
+
+Element wrapper for the [marked](https://github.com/chjj/marked) library.
+
+`<marked-element>` accepts Markdown source either via its `markdown` attribute:
+
+```html
+<marked-element markdown="`Markdown` is _awesome_!"></marked-element>
+```
+
+Or, you can provide it via a `<script type="text/markdown">` element child:
+
+```html
+<marked-element>
+ <script type="text/markdown">
+ Check out my markdown!
+
+ We can even embed elements without fear of the HTML parser mucking up their
+ textual representation:
+
+ <awesome-sauce>
+ <div>Oops, I'm about to forget to close this div.
+ </awesome-sauce>
+
+ </script>
+</marked-element>
+```
+
+Note that the `<script type="text/markdown">` approach is _static_. Changes to
+the script content will _not_ update the rendered markdown!
diff --git a/polymer_1.0.4/bower_components/marked-element/bower.json b/polymer_1.0.4/bower_components/marked-element/bower.json
new file mode 100644
index 0000000..26d36e0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked-element/bower.json
@@ -0,0 +1,34 @@
+{
+ "name": "marked-element",
+ "version": "1.0.2",
+ "description": "Element wrapper for the marked library",
+ "private": true,
+ "authors": [
+ "The Polymer Project Authors (https://polymer.github.io/AUTHORS.txt)"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "marked",
+ "markdown",
+ "container",
+ "wrapper"
+ ],
+ "dependencies": {
+ "marked": "~0.3.3",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "license": "https://polymer.github.io/LICENSE.txt",
+ "main": "marked-element.html",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/marked-element.git"
+ },
+ "devDependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.4",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/marked-element/demo/index.html b/polymer_1.0.4/bower_components/marked-element/demo/index.html
new file mode 100644
index 0000000..779422c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked-element/demo/index.html
@@ -0,0 +1,82 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>marked-element demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../marked-element.html">
+
+ <style is="custom-style">
+
+ .centered {
+ max-width: 550px;
+ padding: 0;
+ overflow: auto;
+ }
+
+ h1 {
+ margin-left: 30px;
+ }
+
+ h3 {
+ color: var(--google-grey-700);
+ margin-left: 30px;
+ }
+
+ marked-element {
+ display: block;
+ background-color: var(--google-grey-100);
+ padding: 10px 30px;
+ margin-bottom: 10px;
+ }
+
+ </style>
+</head>
+
+<body unresolved>
+
+ <div class="vertical-section vertical-section-container centered">
+ <h1><marked-element></h1>
+
+ <section>
+ <h3>Inline Text</h3>
+ <marked-element>
+ <script type="text/markdown">
+ ## Markdown Renderer
+
+ Example:
+
+ ```html
+ <paper-toolbar>
+ <paper-icon-button icon="menu"></paper-icon-button>
+ <div class="title">Title</div>
+ <paper-icon-button icon="more"></paper-icon-button>
+ </paper-toolbar>
+ ```
+
+ _Nifty_ features.
+ </script>
+ </marked-element>
+ </section>
+
+ <section>
+ <h3>Text via Attribute</h3>
+ <marked-element markdown="***Bold and italic***"></marked-element>
+ </section>
+
+ </div>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/marked-element/hero.svg b/polymer_1.0.4/bower_components/marked-element/hero.svg
new file mode 100755
index 0000000..4f28347
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked-element/hero.svg
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <circle cx="109" cy="33" r="4"/>
+ <polygon points="100,92.7 94,84.7 88,92.7 81.2,83.6 82.8,82.4 88,89.3 94,81.3 100,89.3 106.1,81.3 112.9,90.4 111.3,91.6
+ 106.1,84.7 "/>
+ <circle cx="140" cy="91" r="4"/>
+ <g>
+ <path d="M80.6,57.8l-8.2-2.1l1.3-4.1l8,3.4L81,45.7h4.2l-0.7,9.4l7.9-3.3l1.3,4.2l-8.4,2l5.6,7.1l-3.4,2.6l-4.6-8l-4.5,7.8
+ L74.9,65L80.6,57.8z"/>
+ <path d="M138.4,63.2h-5.6l-1.8,9h-3.4l1.8-9h-5.2V60h5.8l1.5-7.4H126v-3.2h6.2l1.8-9.1h3.4l-1.8,9.1h5.6l1.8-9.1h3.4l-1.8,9.1h4.4
+ v3.2h-5l-1.5,7.4h4.8v3.2h-5.4l-1.8,9h-3.4L138.4,63.2z M133.5,60h5.6l1.5-7.4H135L133.5,60z"/>
+ </g>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/marked-element/index.html b/polymer_1.0.4/bower_components/marked-element/index.html
new file mode 100644
index 0000000..487bb5c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked-element/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/marked-element/marked-element.html b/polymer_1.0.4/bower_components/marked-element/marked-element.html
new file mode 100644
index 0000000..3184eba
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked-element/marked-element.html
@@ -0,0 +1,145 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="marked-import.html">
+
+<!--
+Element wrapper for the [marked](http://marked.org/) library.
+
+`<marked-element>` accepts Markdown source either via its `markdown` attribute:
+
+ <marked-element markdown="`Markdown` is _awesome_!"></marked-element>
+
+Or, you can provide it via a `<script type="text/markdown">` element child:
+
+ <marked-element>
+ <script type="text/markdown">
+ Check out my markdown!
+
+ We can even embed elements without fear of the HTML parser mucking up their
+ textual representation:
+
+ ```html
+ <awesome-sauce>
+ <div>Oops, I'm about to forget to close this div.
+ </awesome-sauce>
+ ```
+ </script>
+ </marked-element>
+
+Note that the `<script type="text/markdown">` approach is _static_. Changes to
+the script content will _not_ update the rendered markdown!
+@element marked-element
+@group Molecules
+@hero hero.svg
+@demo demo/index.html
+-->
+<dom-module id="marked-element">
+
+ <template>
+ <div id="content"></div>
+ </template>
+
+</dom-module>
+
+<script>
+
+ 'use strict';
+
+ Polymer({
+
+ is: 'marked-element',
+
+ properties: {
+
+ /** The markdown source that should be rendered by this element. */
+ markdown: {
+ observer: 'render',
+ type: String,
+ value: null
+ }
+
+ },
+
+ ready: function() {
+ if (!this.markdown) {
+ // Use the Markdown from the first `<script>` descendant whose MIME type starts with
+ // "text/markdown". Script elements beyond the first are ignored.
+ var markdownElement = Polymer.dom(this).querySelector('[type^="text/markdown"]');
+ if (markdownElement != null) {
+ this.markdown = this._unindent(markdownElement.textContent);
+ }
+ }
+ },
+
+ /**
+ * Renders `markdown` to HTML when the element is attached.
+ *
+ * This serves a dual purpose:
+ *
+ * * Prevents unnecessary work (no need to render when not visible).
+ *
+ * * `attached` fires top-down, so we can give ancestors a chance to
+ * register listeners for the `syntax-highlight` event _before_ we render
+ * any markdown.
+ *
+ */
+ attached: function() {
+ this._attached = true;
+ this.render();
+ },
+
+ detached: function() {
+ this._attached = false;
+ },
+
+ /**
+ * Renders `markdown` into this element's DOM.
+ *
+ * This is automatically called whenever the `markdown` property is changed.
+ *
+ * The only case where you should be calling this is if you are providing
+ * markdown via `<script type="text/markdown">` after this element has been
+ * constructed (or updating that markdown).
+ */
+ render: function() {
+ if (!this._attached) return;
+ if (!this.markdown) {
+ this.$.content.innerHTML = '';
+ return;
+ }
+
+ this.$.content.innerHTML = marked(this.markdown, {
+ highlight: this._highlight.bind(this),
+ });
+ },
+
+ _highlight: function(code, lang) {
+ var event = this.fire('syntax-highlight', {code: code, lang: lang});
+ return event.detail.code || code;
+ },
+
+ _unindent: function(text) {
+ if (!text) return text;
+ var lines = text.replace(/\t/g, ' ').split('\n');
+ var indent = lines.reduce(function(prev, line) {
+ if (/^\s*$/.test(line)) return prev; // Completely ignore blank lines.
+
+ var lineIndent = line.match(/^(\s*)/)[0].length;
+ if (prev === null) return lineIndent;
+ return lineIndent < prev ? lineIndent : prev;
+ }, null);
+
+ return lines.map(function(l) { return l.substr(indent); }).join('\n');
+ },
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/marked-element/marked-import.html b/polymer_1.0.4/bower_components/marked-element/marked-import.html
new file mode 100644
index 0000000..31b1666
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked-element/marked-import.html
@@ -0,0 +1,10 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<script src='../marked/lib/marked.js'></script>
diff --git a/polymer_1.0.4/bower_components/marked-element/test/index.html b/polymer_1.0.4/bower_components/marked-element/test/index.html
new file mode 100644
index 0000000..e1a138b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked-element/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'marked-element.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/marked-element/test/marked-element.html b/polymer_1.0.4/bower_components/marked-element/test/marked-element.html
new file mode 100644
index 0000000..2535dd1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked-element/test/marked-element.html
@@ -0,0 +1,112 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>marked-element basic tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../marked-element.html">
+</head>
+<body>
+
+ <test-fixture id="CamelCaseHTML">
+ <template>
+ <marked-element>
+ <script type="text/markdown">
+```html
+<div camelCase></div>
+```
+ </script>
+ </marked-element>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="BadHTML">
+ <template>
+ <marked-element>
+ <script type="text/markdown">
+```html
+<p><div></p></div>
+```
+ </script>
+ </marked-element>
+ </template>
+ </test-fixture>
+
+ <script>
+ 'use strict';
+
+ // Replace reserved HTML characters with their character entity equivalents to match the
+ // transform done by Markdown.
+ //
+ // The Marked library itself is not used because it wraps code blocks in `<code><pre>`, which is
+ // superfluous for testing purposes.
+ function escapeHTML(string) {
+ var span = document.createElement('span');
+ span.textContent = string;
+ return span.innerHTML;
+ }
+
+ suite('<marked-element>', function() {
+
+ suite('respsects camelCased HTML', function() {
+ var markedElement;
+ var proofElement;
+
+ setup(function() {
+ markedElement = fixture('CamelCaseHTML');
+ proofElement = document.createElement('div');
+ });
+
+ test('in code blocks', function() {
+ proofElement.innerHTML = '<div camelCase></div>';
+
+ // If Markdown content were put into a `<template>` or directly into the DOM, it would be
+ // rendered as DOM and be converted from camelCase to lowercase per HTML parsing rules. By
+ // using `<script>` descendants, content is interpreted as plain text.
+ expect(proofElement.innerHTML).to.eql('<div camelcase=""></div>')
+ expect(markedElement.$.content.innerHTML).to.include(escapeHTML('<div camelCase>'));
+ });
+ });
+
+ suite('respsects bad HTML', function() {
+ var markedElement;
+ var proofElement;
+
+ setup(function() {
+ markedElement = fixture('BadHTML');
+ proofElement = document.createElement('div');
+ });
+
+ test('in code blocks', function() {
+ proofElement.innerHTML = '<p><div></p></div>';
+
+ // If Markdown content were put into a `<template>` or directly into the DOM, it would be
+ // rendered as DOM and close unbalanced tags. Because they are in code blocks they should
+ // remain as typed.
+ expect(proofElement.innerHTML).to.eql('<p></p><div><p></p></div>');
+ expect(markedElement.$.content.innerHTML).to.include(escapeHTML('<p><div></p></div>'));
+ });
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/marked/.bower.json b/polymer_1.0.4/bower_components/marked/.bower.json
new file mode 100644
index 0000000..ea0e847
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked/.bower.json
@@ -0,0 +1,33 @@
+{
+ "name": "marked",
+ "version": "0.3.3",
+ "homepage": "https://github.com/chjj/marked",
+ "authors": [
+ "Christopher Jeffrey <chjjeffrey@gmail.com>"
+ ],
+ "description": "A markdown parser built for speed",
+ "keywords": [
+ "markdown",
+ "markup",
+ "html"
+ ],
+ "main": "lib/marked.js",
+ "license": "MIT",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "app/bower_components",
+ "test",
+ "tests"
+ ],
+ "_release": "0.3.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v0.3.3",
+ "commit": "2b5802f258c5e23e48366f2377fbb4c807f47658"
+ },
+ "_source": "git://github.com/chjj/marked.git",
+ "_target": "~0.3.3",
+ "_originalSource": "marked"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/marked/LICENSE b/polymer_1.0.4/bower_components/marked/LICENSE
new file mode 100644
index 0000000..a7b812e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/)
+
+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.
diff --git a/polymer_1.0.4/bower_components/marked/Makefile b/polymer_1.0.4/bower_components/marked/Makefile
new file mode 100644
index 0000000..d9349f0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked/Makefile
@@ -0,0 +1,12 @@
+all:
+ @cp lib/marked.js marked.js
+ @uglifyjs --comments '/\*[^\0]+?Copyright[^\0]+?\*/' -o marked.min.js lib/marked.js
+
+clean:
+ @rm marked.js
+ @rm marked.min.js
+
+bench:
+ @node test --bench
+
+.PHONY: clean all
diff --git a/polymer_1.0.4/bower_components/marked/README.md b/polymer_1.0.4/bower_components/marked/README.md
new file mode 100644
index 0000000..b9817cd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked/README.md
@@ -0,0 +1,406 @@
+# marked
+
+> A full-featured markdown parser and compiler, written in JavaScript. Built
+> for speed.
+
+[][badge]
+
+## Install
+
+``` bash
+npm install marked --save
+```
+
+## Usage
+
+Minimal usage:
+
+```js
+var marked = require('marked');
+console.log(marked('I am using __markdown__.'));
+// Outputs: <p>I am using <strong>markdown</strong>.</p>
+```
+
+Example setting options with default values:
+
+```js
+var marked = require('marked');
+marked.setOptions({
+ renderer: new marked.Renderer(),
+ gfm: true,
+ tables: true,
+ breaks: false,
+ pedantic: false,
+ sanitize: true,
+ smartLists: true,
+ smartypants: false
+});
+
+console.log(marked('I am using __markdown__.'));
+```
+
+### Browser
+
+```html
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8"/>
+ <title>Marked in the browser</title>
+ <script src="lib/marked.js"></script>
+</head>
+<body>
+ <div id="content"></div>
+ <script>
+ document.getElementById('content').innerHTML =
+ marked('# Marked in browser\n\nRendered by **marked**.');
+ </script>
+</body>
+</html>
+```
+
+## marked(markdownString [,options] [,callback])
+
+### markdownString
+
+Type: `string`
+
+String of markdown source to be compiled.
+
+### options
+
+Type: `object`
+
+Hash of options. Can also be set using the `marked.setOptions` method as seen
+above.
+
+### callback
+
+Type: `function`
+
+Function called when the `markdownString` has been fully parsed when using
+async highlighting. If the `options` argument is omitted, this can be used as
+the second argument.
+
+## Options
+
+### highlight
+
+Type: `function`
+
+A function to highlight code blocks. The first example below uses async highlighting with
+[node-pygmentize-bundled][pygmentize], and the second is a synchronous example using
+[highlight.js][highlight]:
+
+```js
+var marked = require('marked');
+
+var markdownString = '```js\n console.log("hello"); \n```';
+
+// Async highlighting with pygmentize-bundled
+marked.setOptions({
+ highlight: function (code, lang, callback) {
+ require('pygmentize-bundled')({ lang: lang, format: 'html' }, code, function (err, result) {
+ callback(err, result.toString());
+ });
+ }
+});
+
+// Using async version of marked
+marked(markdownString, function (err, content) {
+ if (err) throw err;
+ console.log(content);
+});
+
+// Synchronous highlighting with highlight.js
+marked.setOptions({
+ highlight: function (code) {
+ return require('highlight.js').highlightAuto(code).value;
+ }
+});
+
+console.log(marked(markdownString));
+```
+
+#### highlight arguments
+
+`code`
+
+Type: `string`
+
+The section of code to pass to the highlighter.
+
+`lang`
+
+Type: `string`
+
+The programming language specified in the code block.
+
+`callback`
+
+Type: `function`
+
+The callback function to call when using an async highlighter.
+
+### renderer
+
+Type: `object`
+Default: `new Renderer()`
+
+An object containing functions to render tokens to HTML.
+
+#### Overriding renderer methods
+
+The renderer option allows you to render tokens in a custom manor. Here is an
+example of overriding the default heading token rendering by adding an embedded anchor tag like on GitHub:
+
+```javascript
+var marked = require('marked');
+var renderer = new marked.Renderer();
+
+renderer.heading = function (text, level) {
+ var escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');
+
+ return '<h' + level + '><a name="' +
+ escapedText +
+ '" class="anchor" href="#' +
+ escapedText +
+ '"><span class="header-link"></span></a>' +
+ text + '</h' + level + '>';
+},
+
+console.log(marked('# heading+', { renderer: renderer }));
+```
+This code will output the following HTML:
+```html
+<h1>
+ <a name="heading-" class="anchor" href="#heading-">
+ <span class="header-link"></span>
+ </a>
+ heading+
+</h1>
+```
+
+#### Block level renderer methods
+
+- code(*string* code, *string* language)
+- blockquote(*string* quote)
+- html(*string* html)
+- heading(*string* text, *number* level)
+- hr()
+- list(*string* body, *boolean* ordered)
+- listitem(*string* text)
+- paragraph(*string* text)
+- table(*string* header, *string* body)
+- tablerow(*string* content)
+- tablecell(*string* content, *object* flags)
+
+`flags` has the following properties:
+
+```js
+{
+ header: true || false,
+ align: 'center' || 'left' || 'right'
+}
+```
+
+#### Inline level renderer methods
+
+- strong(*string* text)
+- em(*string* text)
+- codespan(*string* code)
+- br()
+- del(*string* text)
+- link(*string* href, *string* title, *string* text)
+- image(*string* href, *string* title, *string* text)
+
+### gfm
+
+Type: `boolean`
+Default: `true`
+
+Enable [GitHub flavored markdown][gfm].
+
+### tables
+
+Type: `boolean`
+Default: `true`
+
+Enable GFM [tables][tables].
+This option requires the `gfm` option to be true.
+
+### breaks
+
+Type: `boolean`
+Default: `false`
+
+Enable GFM [line breaks][breaks].
+This option requires the `gfm` option to be true.
+
+### pedantic
+
+Type: `boolean`
+Default: `false`
+
+Conform to obscure parts of `markdown.pl` as much as possible. Don't fix any of
+the original markdown bugs or poor behavior.
+
+### sanitize
+
+Type: `boolean`
+Default: `false`
+
+Sanitize the output. Ignore any HTML that has been input.
+
+### smartLists
+
+Type: `boolean`
+Default: `true`
+
+Use smarter list behavior than the original markdown. May eventually be
+default with the old behavior moved into `pedantic`.
+
+### smartypants
+
+Type: `boolean`
+Default: `false`
+
+Use "smart" typograhic punctuation for things like quotes and dashes.
+
+## Access to lexer and parser
+
+You also have direct access to the lexer and parser if you so desire.
+
+``` js
+var tokens = marked.lexer(text, options);
+console.log(marked.parser(tokens));
+```
+
+``` js
+var lexer = new marked.Lexer(options);
+var tokens = lexer.lex(text);
+console.log(tokens);
+console.log(lexer.rules);
+```
+
+## CLI
+
+``` bash
+$ marked -o hello.html
+hello world
+^D
+$ cat hello.html
+<p>hello world</p>
+```
+
+## Philosophy behind marked
+
+The point of marked was to create a markdown compiler where it was possible to
+frequently parse huge chunks of markdown without having to worry about
+caching the compiled output somehow...or blocking for an unnecesarily long time.
+
+marked is very concise and still implements all markdown features. It is also
+now fully compatible with the client-side.
+
+marked more or less passes the official markdown test suite in its
+entirety. This is important because a surprising number of markdown compilers
+cannot pass more than a few tests. It was very difficult to get marked as
+compliant as it is. It could have cut corners in several areas for the sake
+of performance, but did not in order to be exactly what you expect in terms
+of a markdown rendering. In fact, this is why marked could be considered at a
+disadvantage in the benchmarks above.
+
+Along with implementing every markdown feature, marked also implements [GFM
+features][gfmf].
+
+## Benchmarks
+
+node v0.8.x
+
+``` bash
+$ node test --bench
+marked completed in 3411ms.
+marked (gfm) completed in 3727ms.
+marked (pedantic) completed in 3201ms.
+robotskirt completed in 808ms.
+showdown (reuse converter) completed in 11954ms.
+showdown (new converter) completed in 17774ms.
+markdown-js completed in 17191ms.
+```
+
+__Marked is now faster than Discount, which is written in C.__
+
+For those feeling skeptical: These benchmarks run the entire markdown test suite 1000 times. The test suite tests every feature. It doesn't cater to specific aspects.
+
+### Pro level
+
+You also have direct access to the lexer and parser if you so desire.
+
+``` js
+var tokens = marked.lexer(text, options);
+console.log(marked.parser(tokens));
+```
+
+``` js
+var lexer = new marked.Lexer(options);
+var tokens = lexer.lex(text);
+console.log(tokens);
+console.log(lexer.rules);
+```
+
+``` bash
+$ node
+> require('marked').lexer('> i am using marked.')
+[ { type: 'blockquote_start' },
+ { type: 'paragraph',
+ text: 'i am using marked.' },
+ { type: 'blockquote_end' },
+ links: {} ]
+```
+
+## Running Tests & Contributing
+
+If you want to submit a pull request, make sure your changes pass the test
+suite. If you're adding a new feature, be sure to add your own test.
+
+The marked test suite is set up slightly strangely: `test/new` is for all tests
+that are not part of the original markdown.pl test suite (this is where your
+test should go if you make one). `test/original` is only for the original
+markdown.pl tests. `test/tests` houses both types of tests after they have been
+combined and moved/generated by running `node test --fix` or `marked --test
+--fix`.
+
+In other words, if you have a test to add, add it to `test/new/` and then
+regenerate the tests with `node test --fix`. Commit the result. If your test
+uses a certain feature, for example, maybe it assumes GFM is *not* enabled, you
+can add `.nogfm` to the filename. So, `my-test.text` becomes
+`my-test.nogfm.text`. You can do this with any marked option. Say you want
+line breaks and smartypants enabled, your filename should be:
+`my-test.breaks.smartypants.text`.
+
+To run the tests:
+
+``` bash
+cd marked/
+node test
+```
+
+### Contribution and License Agreement
+
+If you contribute code to this project, you are implicitly allowing your code
+to be distributed under the MIT license. You are also implicitly verifying that
+all code is your original work. `</legalese>`
+
+## License
+
+Copyright (c) 2011-2014, Christopher Jeffrey. (MIT License)
+
+See LICENSE for more info.
+
+[gfm]: https://help.github.com/articles/github-flavored-markdown
+[gfmf]: http://github.github.com/github-flavored-markdown/
+[pygmentize]: https://github.com/rvagg/node-pygmentize-bundled
+[highlight]: https://github.com/isagalaev/highlight.js
+[badge]: http://badge.fury.io/js/marked
+[tables]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#wiki-tables
+[breaks]: https://help.github.com/articles/github-flavored-markdown#newlines
diff --git a/polymer_1.0.4/bower_components/marked/bin/marked b/polymer_1.0.4/bower_components/marked/bin/marked
new file mode 100755
index 0000000..64254fc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked/bin/marked
@@ -0,0 +1,187 @@
+#!/usr/bin/env node
+
+/**
+ * Marked CLI
+ * Copyright (c) 2011-2013, Christopher Jeffrey (MIT License)
+ */
+
+var fs = require('fs')
+ , util = require('util')
+ , marked = require('../');
+
+/**
+ * Man Page
+ */
+
+function help() {
+ var spawn = require('child_process').spawn;
+
+ var options = {
+ cwd: process.cwd(),
+ env: process.env,
+ setsid: false,
+ customFds: [0, 1, 2]
+ };
+
+ spawn('man',
+ [__dirname + '/../man/marked.1'],
+ options);
+}
+
+/**
+ * Main
+ */
+
+function main(argv, callback) {
+ var files = []
+ , options = {}
+ , input
+ , output
+ , arg
+ , tokens
+ , opt;
+
+ function getarg() {
+ var arg = argv.shift();
+
+ if (arg.indexOf('--') === 0) {
+ // e.g. --opt
+ arg = arg.split('=');
+ if (arg.length > 1) {
+ // e.g. --opt=val
+ argv.unshift(arg.slice(1).join('='));
+ }
+ arg = arg[0];
+ } else if (arg[0] === '-') {
+ if (arg.length > 2) {
+ // e.g. -abc
+ argv = arg.substring(1).split('').map(function(ch) {
+ return '-' + ch;
+ }).concat(argv);
+ arg = argv.shift();
+ } else {
+ // e.g. -a
+ }
+ } else {
+ // e.g. foo
+ }
+
+ return arg;
+ }
+
+ while (argv.length) {
+ arg = getarg();
+ switch (arg) {
+ case '--test':
+ return require('../test').main(process.argv.slice());
+ case '-o':
+ case '--output':
+ output = argv.shift();
+ break;
+ case '-i':
+ case '--input':
+ input = argv.shift();
+ break;
+ case '-t':
+ case '--tokens':
+ tokens = true;
+ break;
+ case '-h':
+ case '--help':
+ return help();
+ default:
+ if (arg.indexOf('--') === 0) {
+ opt = camelize(arg.replace(/^--(no-)?/, ''));
+ if (!marked.defaults.hasOwnProperty(opt)) {
+ continue;
+ }
+ if (arg.indexOf('--no-') === 0) {
+ options[opt] = typeof marked.defaults[opt] !== 'boolean'
+ ? null
+ : false;
+ } else {
+ options[opt] = typeof marked.defaults[opt] !== 'boolean'
+ ? argv.shift()
+ : true;
+ }
+ } else {
+ files.push(arg);
+ }
+ break;
+ }
+ }
+
+ function getData(callback) {
+ if (!input) {
+ if (files.length <= 2) {
+ return getStdin(callback);
+ }
+ input = files.pop();
+ }
+ return fs.readFile(input, 'utf8', callback);
+ }
+
+ return getData(function(err, data) {
+ if (err) return callback(err);
+
+ data = tokens
+ ? JSON.stringify(marked.lexer(data, options), null, 2)
+ : marked(data, options);
+
+ if (!output) {
+ process.stdout.write(data + '\n');
+ return callback();
+ }
+
+ return fs.writeFile(output, data, callback);
+ });
+}
+
+/**
+ * Helpers
+ */
+
+function getStdin(callback) {
+ var stdin = process.stdin
+ , buff = '';
+
+ stdin.setEncoding('utf8');
+
+ stdin.on('data', function(data) {
+ buff += data;
+ });
+
+ stdin.on('error', function(err) {
+ return callback(err);
+ });
+
+ stdin.on('end', function() {
+ return callback(null, buff);
+ });
+
+ try {
+ stdin.resume();
+ } catch (e) {
+ callback(e);
+ }
+}
+
+function camelize(text) {
+ return text.replace(/(\w)-(\w)/g, function(_, a, b) {
+ return a + b.toUpperCase();
+ });
+}
+
+/**
+ * Expose / Entry Point
+ */
+
+if (!module.parent) {
+ process.title = 'marked';
+ main(process.argv.slice(), function(err, code) {
+ if (err) throw err;
+ return process.exit(code || 0);
+ });
+} else {
+ module.exports = main;
+}
diff --git a/polymer_1.0.4/bower_components/marked/bower.json b/polymer_1.0.4/bower_components/marked/bower.json
new file mode 100644
index 0000000..3eab311
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked/bower.json
@@ -0,0 +1,24 @@
+{
+ "name": "marked",
+ "version": "0.3.2",
+ "homepage": "https://github.com/chjj/marked",
+ "authors": [
+ "Christopher Jeffrey <chjjeffrey@gmail.com>"
+ ],
+ "description": "A markdown parser built for speed",
+ "keywords": [
+ "markdown",
+ "markup",
+ "html"
+ ],
+ "main": "lib/marked.js",
+ "license": "MIT",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "app/bower_components",
+ "test",
+ "tests"
+ ]
+}
diff --git a/polymer_1.0.4/bower_components/marked/component.json b/polymer_1.0.4/bower_components/marked/component.json
new file mode 100644
index 0000000..931cbed
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked/component.json
@@ -0,0 +1,10 @@
+{
+ "name": "marked",
+ "version": "0.3.2",
+ "repo": "chjj/marked",
+ "description": "A markdown parser built for speed",
+ "keywords": ["markdown", "markup", "html"],
+ "scripts": ["lib/marked.js"],
+ "main": "lib/marked.js",
+ "license": "MIT"
+}
diff --git a/polymer_1.0.4/bower_components/marked/doc/broken.md b/polymer_1.0.4/bower_components/marked/doc/broken.md
new file mode 100644
index 0000000..7bfa49e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked/doc/broken.md
@@ -0,0 +1,426 @@
+# Markdown is broken
+
+I have a lot of scraps of markdown engine oddities that I've collected over the
+years. What you see below is slightly messy, but it's what I've managed to
+cobble together to illustrate the differences between markdown engines, and
+why, if there ever is a markdown specification, it has to be absolutely
+thorough. There are a lot more of these little differences I have documented
+elsewhere. I know I will find them lingering on my disk one day, but until
+then, I'll continue to add whatever strange nonsensical things I find.
+
+Some of these examples may only mention a particular engine compared to marked.
+However, the examples with markdown.pl could easily be swapped out for
+discount, upskirt, or markdown.js, and you would very easily see even more
+inconsistencies.
+
+A lot of this was written when I was very unsatisfied with the inconsistencies
+between markdown engines. Please excuse the frustration noticeable in my
+writing.
+
+## Examples of markdown's "stupid" list parsing
+
+```
+$ markdown.pl
+
+ * item1
+
+ * item2
+
+ text
+^D
+<ul>
+<li><p>item1</p>
+
+<ul>
+<li>item2</li>
+</ul>
+
+<p><p>text</p></li>
+</ul></p>
+```
+
+
+```
+$ marked
+ * item1
+
+ * item2
+
+ text
+^D
+<ul>
+<li><p>item1</p>
+<ul>
+<li>item2</li>
+</ul>
+<p>text</p>
+</li>
+</ul>
+```
+
+Which looks correct to you?
+
+- - -
+
+```
+$ markdown.pl
+* hello
+ > world
+^D
+<p><ul>
+<li>hello</p>
+
+<blockquote>
+ <p>world</li>
+</ul></p>
+</blockquote>
+```
+
+```
+$ marked
+* hello
+ > world
+^D
+<ul>
+<li>hello<blockquote>
+<p>world</p>
+</blockquote>
+</li>
+</ul>
+```
+
+Again, which looks correct to you?
+
+- - -
+
+EXAMPLE:
+
+```
+$ markdown.pl
+* hello
+ * world
+ * hi
+ code
+^D
+<ul>
+<li>hello
+<ul>
+<li>world</li>
+<li>hi
+ code</li>
+</ul></li>
+</ul>
+```
+
+The code isn't a code block even though it's after the bullet margin. I know,
+lets give it two more spaces, effectively making it 8 spaces past the bullet.
+
+```
+$ markdown.pl
+* hello
+ * world
+ * hi
+ code
+^D
+<ul>
+<li>hello
+<ul>
+<li>world</li>
+<li>hi
+ code</li>
+</ul></li>
+</ul>
+```
+
+And, it's still not a code block. Did you also notice that the 3rd item isn't
+even its own list? Markdown screws that up too because of its indentation
+unaware parsing.
+
+- - -
+
+Let's look at some more examples of markdown's list parsing:
+
+```
+$ markdown.pl
+
+ * item1
+
+ * item2
+
+ text
+^D
+<ul>
+<li><p>item1</p>
+
+<ul>
+<li>item2</li>
+</ul>
+
+<p><p>text</p></li>
+</ul></p>
+```
+
+Misnested tags.
+
+
+```
+$ marked
+ * item1
+
+ * item2
+
+ text
+^D
+<ul>
+<li><p>item1</p>
+<ul>
+<li>item2</li>
+</ul>
+<p>text</p>
+</li>
+</ul>
+```
+
+Which looks correct to you?
+
+- - -
+
+```
+$ markdown.pl
+* hello
+ > world
+^D
+<p><ul>
+<li>hello</p>
+
+<blockquote>
+ <p>world</li>
+</ul></p>
+</blockquote>
+```
+
+More misnested tags.
+
+
+```
+$ marked
+* hello
+ > world
+^D
+<ul>
+<li>hello<blockquote>
+<p>world</p>
+</blockquote>
+</li>
+</ul>
+```
+
+Again, which looks correct to you?
+
+- - -
+
+# Why quality matters - Part 2
+
+``` bash
+$ markdown.pl
+* hello
+ > world
+^D
+<p><ul>
+<li>hello</p>
+
+<blockquote>
+ <p>world</li>
+</ul></p>
+</blockquote>
+```
+
+``` bash
+$ sundown # upskirt
+* hello
+ > world
+^D
+<ul>
+<li>hello
+> world</li>
+</ul>
+```
+
+``` bash
+$ marked
+* hello
+ > world
+^D
+<ul><li>hello <blockquote><p>world</p></blockquote></li></ul>
+```
+
+Which looks correct to you?
+
+- - -
+
+See: https://github.com/evilstreak/markdown-js/issues/23
+
+``` bash
+$ markdown.pl # upskirt/markdown.js/discount
+* hello
+ var a = 1;
+* world
+^D
+<ul>
+<li>hello
+var a = 1;</li>
+<li>world</li>
+</ul>
+```
+
+``` bash
+$ marked
+* hello
+ var a = 1;
+* world
+^D
+<ul><li>hello
+<pre>code>var a = 1;</code></pre></li>
+<li>world</li></ul>
+```
+
+Which looks more reasonable? Why shouldn't code blocks be able to appear in
+list items in a sane way?
+
+- - -
+
+``` bash
+$ markdown.js
+<div>hello</div>
+
+<span>hello</span>
+^D
+<p><div>hello</div></p>
+
+<p><span>hello</span></p>
+```
+
+``` bash
+$ marked
+<div>hello</div>
+
+<span>hello</span>
+^D
+<div>hello</div>
+
+
+<p><span>hello</span>
+</p>
+```
+
+- - -
+
+See: https://github.com/evilstreak/markdown-js/issues/27
+
+``` bash
+$ markdown.js
+[](/link)
+^D
+<p><a href="/image)](/link">](/link)
+^D
+<p><a href="/link"><img src="/image" alt="an image"></a>
+</p>
+```
+
+- - -
+
+See: https://github.com/evilstreak/markdown-js/issues/24
+
+``` bash
+$ markdown.js
+> a
+
+> b
+
+> c
+^D
+<blockquote><p>a</p><p>bundefined> c</p></blockquote>
+```
+
+``` bash
+$ marked
+> a
+
+> b
+
+> c
+^D
+<blockquote><p>a
+
+</p></blockquote>
+<blockquote><p>b
+
+</p></blockquote>
+<blockquote><p>c
+</p></blockquote>
+```
+
+- - -
+
+``` bash
+$ markdown.pl
+* hello
+ * world
+ how
+
+ are
+ you
+
+ * today
+* hi
+^D
+<ul>
+<li><p>hello</p>
+
+<ul>
+<li>world
+how</li>
+</ul>
+
+<p>are
+you</p>
+
+<ul>
+<li>today</li>
+</ul></li>
+<li>hi</li>
+</ul>
+```
+
+``` bash
+$ marked
+* hello
+ * world
+ how
+
+ are
+ you
+
+ * today
+* hi
+^D
+<ul>
+<li><p>hello</p>
+<ul>
+<li><p>world
+how</p>
+<p>are
+you</p>
+</li>
+<li><p>today</p>
+</li>
+</ul>
+</li>
+<li>hi</li>
+</ul>
+```
diff --git a/polymer_1.0.4/bower_components/marked/doc/todo.md b/polymer_1.0.4/bower_components/marked/doc/todo.md
new file mode 100644
index 0000000..2e60b16
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked/doc/todo.md
@@ -0,0 +1,2 @@
+# Todo
+
diff --git a/polymer_1.0.4/bower_components/marked/index.js b/polymer_1.0.4/bower_components/marked/index.js
new file mode 100644
index 0000000..a12f905
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked/index.js
@@ -0,0 +1 @@
+module.exports = require('./lib/marked');
diff --git a/polymer_1.0.4/bower_components/marked/lib/marked.js b/polymer_1.0.4/bower_components/marked/lib/marked.js
new file mode 100644
index 0000000..0b7180f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked/lib/marked.js
@@ -0,0 +1,1272 @@
+/**
+ * marked - a markdown parser
+ * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/chjj/marked
+ */
+
+;(function() {
+
+/**
+ * Block-Level Grammar
+ */
+
+var block = {
+ newline: /^\n+/,
+ code: /^( {4}[^\n]+\n*)+/,
+ fences: noop,
+ hr: /^( *[-*_]){3,} *(?:\n+|$)/,
+ heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
+ nptable: noop,
+ lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
+ blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
+ list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
+ html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
+ def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
+ table: noop,
+ paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
+ text: /^[^\n]+/
+};
+
+block.bullet = /(?:[*+-]|\d+\.)/;
+block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
+block.item = replace(block.item, 'gm')
+ (/bull/g, block.bullet)
+ ();
+
+block.list = replace(block.list)
+ (/bull/g, block.bullet)
+ ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
+ ('def', '\\n+(?=' + block.def.source + ')')
+ ();
+
+block.blockquote = replace(block.blockquote)
+ ('def', block.def)
+ ();
+
+block._tag = '(?!(?:'
+ + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
+ + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
+ + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
+
+block.html = replace(block.html)
+ ('comment', /<!--[\s\S]*?-->/)
+ ('closed', /<(tag)[\s\S]+?<\/\1>/)
+ ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
+ (/tag/g, block._tag)
+ ();
+
+block.paragraph = replace(block.paragraph)
+ ('hr', block.hr)
+ ('heading', block.heading)
+ ('lheading', block.lheading)
+ ('blockquote', block.blockquote)
+ ('tag', '<' + block._tag)
+ ('def', block.def)
+ ();
+
+/**
+ * Normal Block Grammar
+ */
+
+block.normal = merge({}, block);
+
+/**
+ * GFM Block Grammar
+ */
+
+block.gfm = merge({}, block.normal, {
+ fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,
+ paragraph: /^/
+});
+
+block.gfm.paragraph = replace(block.paragraph)
+ ('(?!', '(?!'
+ + block.gfm.fences.source.replace('\\1', '\\2') + '|'
+ + block.list.source.replace('\\1', '\\3') + '|')
+ ();
+
+/**
+ * GFM + Tables Block Grammar
+ */
+
+block.tables = merge({}, block.gfm, {
+ nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
+ table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
+});
+
+/**
+ * Block Lexer
+ */
+
+function Lexer(options) {
+ this.tokens = [];
+ this.tokens.links = {};
+ this.options = options || marked.defaults;
+ this.rules = block.normal;
+
+ if (this.options.gfm) {
+ if (this.options.tables) {
+ this.rules = block.tables;
+ } else {
+ this.rules = block.gfm;
+ }
+ }
+}
+
+/**
+ * Expose Block Rules
+ */
+
+Lexer.rules = block;
+
+/**
+ * Static Lex Method
+ */
+
+Lexer.lex = function(src, options) {
+ var lexer = new Lexer(options);
+ return lexer.lex(src);
+};
+
+/**
+ * Preprocessing
+ */
+
+Lexer.prototype.lex = function(src) {
+ src = src
+ .replace(/\r\n|\r/g, '\n')
+ .replace(/\t/g, ' ')
+ .replace(/\u00a0/g, ' ')
+ .replace(/\u2424/g, '\n');
+
+ return this.token(src, true);
+};
+
+/**
+ * Lexing
+ */
+
+Lexer.prototype.token = function(src, top, bq) {
+ var src = src.replace(/^ +$/gm, '')
+ , next
+ , loose
+ , cap
+ , bull
+ , b
+ , item
+ , space
+ , i
+ , l;
+
+ while (src) {
+ // newline
+ if (cap = this.rules.newline.exec(src)) {
+ src = src.substring(cap[0].length);
+ if (cap[0].length > 1) {
+ this.tokens.push({
+ type: 'space'
+ });
+ }
+ }
+
+ // code
+ if (cap = this.rules.code.exec(src)) {
+ src = src.substring(cap[0].length);
+ cap = cap[0].replace(/^ {4}/gm, '');
+ this.tokens.push({
+ type: 'code',
+ text: !this.options.pedantic
+ ? cap.replace(/\n+$/, '')
+ : cap
+ });
+ continue;
+ }
+
+ // fences (gfm)
+ if (cap = this.rules.fences.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'code',
+ lang: cap[2],
+ text: cap[3]
+ });
+ continue;
+ }
+
+ // heading
+ if (cap = this.rules.heading.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'heading',
+ depth: cap[1].length,
+ text: cap[2]
+ });
+ continue;
+ }
+
+ // table no leading pipe (gfm)
+ if (top && (cap = this.rules.nptable.exec(src))) {
+ src = src.substring(cap[0].length);
+
+ item = {
+ type: 'table',
+ header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
+ align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
+ cells: cap[3].replace(/\n$/, '').split('\n')
+ };
+
+ for (i = 0; i < item.align.length; i++) {
+ if (/^ *-+: *$/.test(item.align[i])) {
+ item.align[i] = 'right';
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
+ item.align[i] = 'center';
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
+ item.align[i] = 'left';
+ } else {
+ item.align[i] = null;
+ }
+ }
+
+ for (i = 0; i < item.cells.length; i++) {
+ item.cells[i] = item.cells[i].split(/ *\| */);
+ }
+
+ this.tokens.push(item);
+
+ continue;
+ }
+
+ // lheading
+ if (cap = this.rules.lheading.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'heading',
+ depth: cap[2] === '=' ? 1 : 2,
+ text: cap[1]
+ });
+ continue;
+ }
+
+ // hr
+ if (cap = this.rules.hr.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'hr'
+ });
+ continue;
+ }
+
+ // blockquote
+ if (cap = this.rules.blockquote.exec(src)) {
+ src = src.substring(cap[0].length);
+
+ this.tokens.push({
+ type: 'blockquote_start'
+ });
+
+ cap = cap[0].replace(/^ *> ?/gm, '');
+
+ // Pass `top` to keep the current
+ // "toplevel" state. This is exactly
+ // how markdown.pl works.
+ this.token(cap, top, true);
+
+ this.tokens.push({
+ type: 'blockquote_end'
+ });
+
+ continue;
+ }
+
+ // list
+ if (cap = this.rules.list.exec(src)) {
+ src = src.substring(cap[0].length);
+ bull = cap[2];
+
+ this.tokens.push({
+ type: 'list_start',
+ ordered: bull.length > 1
+ });
+
+ // Get each top-level item.
+ cap = cap[0].match(this.rules.item);
+
+ next = false;
+ l = cap.length;
+ i = 0;
+
+ for (; i < l; i++) {
+ item = cap[i];
+
+ // Remove the list item's bullet
+ // so it is seen as the next token.
+ space = item.length;
+ item = item.replace(/^ *([*+-]|\d+\.) +/, '');
+
+ // Outdent whatever the
+ // list item contains. Hacky.
+ if (~item.indexOf('\n ')) {
+ space -= item.length;
+ item = !this.options.pedantic
+ ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
+ : item.replace(/^ {1,4}/gm, '');
+ }
+
+ // Determine whether the next list item belongs here.
+ // Backpedal if it does not belong in this list.
+ if (this.options.smartLists && i !== l - 1) {
+ b = block.bullet.exec(cap[i + 1])[0];
+ if (bull !== b && !(bull.length > 1 && b.length > 1)) {
+ src = cap.slice(i + 1).join('\n') + src;
+ i = l - 1;
+ }
+ }
+
+ // Determine whether item is loose or not.
+ // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
+ // for discount behavior.
+ loose = next || /\n\n(?!\s*$)/.test(item);
+ if (i !== l - 1) {
+ next = item.charAt(item.length - 1) === '\n';
+ if (!loose) loose = next;
+ }
+
+ this.tokens.push({
+ type: loose
+ ? 'loose_item_start'
+ : 'list_item_start'
+ });
+
+ // Recurse.
+ this.token(item, false, bq);
+
+ this.tokens.push({
+ type: 'list_item_end'
+ });
+ }
+
+ this.tokens.push({
+ type: 'list_end'
+ });
+
+ continue;
+ }
+
+ // html
+ if (cap = this.rules.html.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: this.options.sanitize
+ ? 'paragraph'
+ : 'html',
+ pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
+ text: cap[0]
+ });
+ continue;
+ }
+
+ // def
+ if ((!bq && top) && (cap = this.rules.def.exec(src))) {
+ src = src.substring(cap[0].length);
+ this.tokens.links[cap[1].toLowerCase()] = {
+ href: cap[2],
+ title: cap[3]
+ };
+ continue;
+ }
+
+ // table (gfm)
+ if (top && (cap = this.rules.table.exec(src))) {
+ src = src.substring(cap[0].length);
+
+ item = {
+ type: 'table',
+ header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
+ align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
+ cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
+ };
+
+ for (i = 0; i < item.align.length; i++) {
+ if (/^ *-+: *$/.test(item.align[i])) {
+ item.align[i] = 'right';
+ } else if (/^ *:-+: *$/.test(item.align[i])) {
+ item.align[i] = 'center';
+ } else if (/^ *:-+ *$/.test(item.align[i])) {
+ item.align[i] = 'left';
+ } else {
+ item.align[i] = null;
+ }
+ }
+
+ for (i = 0; i < item.cells.length; i++) {
+ item.cells[i] = item.cells[i]
+ .replace(/^ *\| *| *\| *$/g, '')
+ .split(/ *\| */);
+ }
+
+ this.tokens.push(item);
+
+ continue;
+ }
+
+ // top-level paragraph
+ if (top && (cap = this.rules.paragraph.exec(src))) {
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'paragraph',
+ text: cap[1].charAt(cap[1].length - 1) === '\n'
+ ? cap[1].slice(0, -1)
+ : cap[1]
+ });
+ continue;
+ }
+
+ // text
+ if (cap = this.rules.text.exec(src)) {
+ // Top-level should never reach here.
+ src = src.substring(cap[0].length);
+ this.tokens.push({
+ type: 'text',
+ text: cap[0]
+ });
+ continue;
+ }
+
+ if (src) {
+ throw new
+ Error('Infinite loop on byte: ' + src.charCodeAt(0));
+ }
+ }
+
+ return this.tokens;
+};
+
+/**
+ * Inline-Level Grammar
+ */
+
+var inline = {
+ escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
+ autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
+ url: noop,
+ tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
+ link: /^!?\[(inside)\]\(href\)/,
+ reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
+ nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
+ strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
+ em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
+ code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
+ br: /^ {2,}\n(?!\s*$)/,
+ del: noop,
+ text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
+};
+
+inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
+inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
+
+inline.link = replace(inline.link)
+ ('inside', inline._inside)
+ ('href', inline._href)
+ ();
+
+inline.reflink = replace(inline.reflink)
+ ('inside', inline._inside)
+ ();
+
+/**
+ * Normal Inline Grammar
+ */
+
+inline.normal = merge({}, inline);
+
+/**
+ * Pedantic Inline Grammar
+ */
+
+inline.pedantic = merge({}, inline.normal, {
+ strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
+ em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
+});
+
+/**
+ * GFM Inline Grammar
+ */
+
+inline.gfm = merge({}, inline.normal, {
+ escape: replace(inline.escape)('])', '~|])')(),
+ url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
+ del: /^~~(?=\S)([\s\S]*?\S)~~/,
+ text: replace(inline.text)
+ (']|', '~]|')
+ ('|', '|https?://|')
+ ()
+});
+
+/**
+ * GFM + Line Breaks Inline Grammar
+ */
+
+inline.breaks = merge({}, inline.gfm, {
+ br: replace(inline.br)('{2,}', '*')(),
+ text: replace(inline.gfm.text)('{2,}', '*')()
+});
+
+/**
+ * Inline Lexer & Compiler
+ */
+
+function InlineLexer(links, options) {
+ this.options = options || marked.defaults;
+ this.links = links;
+ this.rules = inline.normal;
+ this.renderer = this.options.renderer || new Renderer;
+ this.renderer.options = this.options;
+
+ if (!this.links) {
+ throw new
+ Error('Tokens array requires a `links` property.');
+ }
+
+ if (this.options.gfm) {
+ if (this.options.breaks) {
+ this.rules = inline.breaks;
+ } else {
+ this.rules = inline.gfm;
+ }
+ } else if (this.options.pedantic) {
+ this.rules = inline.pedantic;
+ }
+}
+
+/**
+ * Expose Inline Rules
+ */
+
+InlineLexer.rules = inline;
+
+/**
+ * Static Lexing/Compiling Method
+ */
+
+InlineLexer.output = function(src, links, options) {
+ var inline = new InlineLexer(links, options);
+ return inline.output(src);
+};
+
+/**
+ * Lexing/Compiling
+ */
+
+InlineLexer.prototype.output = function(src) {
+ var out = ''
+ , link
+ , text
+ , href
+ , cap;
+
+ while (src) {
+ // escape
+ if (cap = this.rules.escape.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += cap[1];
+ continue;
+ }
+
+ // autolink
+ if (cap = this.rules.autolink.exec(src)) {
+ src = src.substring(cap[0].length);
+ if (cap[2] === '@') {
+ text = cap[1].charAt(6) === ':'
+ ? this.mangle(cap[1].substring(7))
+ : this.mangle(cap[1]);
+ href = this.mangle('mailto:') + text;
+ } else {
+ text = escape(cap[1]);
+ href = text;
+ }
+ out += this.renderer.link(href, null, text);
+ continue;
+ }
+
+ // url (gfm)
+ if (!this.inLink && (cap = this.rules.url.exec(src))) {
+ src = src.substring(cap[0].length);
+ text = escape(cap[1]);
+ href = text;
+ out += this.renderer.link(href, null, text);
+ continue;
+ }
+
+ // tag
+ if (cap = this.rules.tag.exec(src)) {
+ if (!this.inLink && /^<a /i.test(cap[0])) {
+ this.inLink = true;
+ } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
+ this.inLink = false;
+ }
+ src = src.substring(cap[0].length);
+ out += this.options.sanitize
+ ? escape(cap[0])
+ : cap[0];
+ continue;
+ }
+
+ // link
+ if (cap = this.rules.link.exec(src)) {
+ src = src.substring(cap[0].length);
+ this.inLink = true;
+ out += this.outputLink(cap, {
+ href: cap[2],
+ title: cap[3]
+ });
+ this.inLink = false;
+ continue;
+ }
+
+ // reflink, nolink
+ if ((cap = this.rules.reflink.exec(src))
+ || (cap = this.rules.nolink.exec(src))) {
+ src = src.substring(cap[0].length);
+ link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
+ link = this.links[link.toLowerCase()];
+ if (!link || !link.href) {
+ out += cap[0].charAt(0);
+ src = cap[0].substring(1) + src;
+ continue;
+ }
+ this.inLink = true;
+ out += this.outputLink(cap, link);
+ this.inLink = false;
+ continue;
+ }
+
+ // strong
+ if (cap = this.rules.strong.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.strong(this.output(cap[2] || cap[1]));
+ continue;
+ }
+
+ // em
+ if (cap = this.rules.em.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.em(this.output(cap[2] || cap[1]));
+ continue;
+ }
+
+ // code
+ if (cap = this.rules.code.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.codespan(escape(cap[2], true));
+ continue;
+ }
+
+ // br
+ if (cap = this.rules.br.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.br();
+ continue;
+ }
+
+ // del (gfm)
+ if (cap = this.rules.del.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += this.renderer.del(this.output(cap[1]));
+ continue;
+ }
+
+ // text
+ if (cap = this.rules.text.exec(src)) {
+ src = src.substring(cap[0].length);
+ out += escape(this.smartypants(cap[0]));
+ continue;
+ }
+
+ if (src) {
+ throw new
+ Error('Infinite loop on byte: ' + src.charCodeAt(0));
+ }
+ }
+
+ return out;
+};
+
+/**
+ * Compile Link
+ */
+
+InlineLexer.prototype.outputLink = function(cap, link) {
+ var href = escape(link.href)
+ , title = link.title ? escape(link.title) : null;
+
+ return cap[0].charAt(0) !== '!'
+ ? this.renderer.link(href, title, this.output(cap[1]))
+ : this.renderer.image(href, title, escape(cap[1]));
+};
+
+/**
+ * Smartypants Transformations
+ */
+
+InlineLexer.prototype.smartypants = function(text) {
+ if (!this.options.smartypants) return text;
+ return text
+ // em-dashes
+ .replace(/--/g, '\u2014')
+ // opening singles
+ .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
+ // closing singles & apostrophes
+ .replace(/'/g, '\u2019')
+ // opening doubles
+ .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
+ // closing doubles
+ .replace(/"/g, '\u201d')
+ // ellipses
+ .replace(/\.{3}/g, '\u2026');
+};
+
+/**
+ * Mangle Links
+ */
+
+InlineLexer.prototype.mangle = function(text) {
+ var out = ''
+ , l = text.length
+ , i = 0
+ , ch;
+
+ for (; i < l; i++) {
+ ch = text.charCodeAt(i);
+ if (Math.random() > 0.5) {
+ ch = 'x' + ch.toString(16);
+ }
+ out += '&#' + ch + ';';
+ }
+
+ return out;
+};
+
+/**
+ * Renderer
+ */
+
+function Renderer(options) {
+ this.options = options || {};
+}
+
+Renderer.prototype.code = function(code, lang, escaped) {
+ if (this.options.highlight) {
+ var out = this.options.highlight(code, lang);
+ if (out != null && out !== code) {
+ escaped = true;
+ code = out;
+ }
+ }
+
+ if (!lang) {
+ return '<pre><code>'
+ + (escaped ? code : escape(code, true))
+ + '\n</code></pre>';
+ }
+
+ return '<pre><code class="'
+ + this.options.langPrefix
+ + escape(lang, true)
+ + '">'
+ + (escaped ? code : escape(code, true))
+ + '\n</code></pre>\n';
+};
+
+Renderer.prototype.blockquote = function(quote) {
+ return '<blockquote>\n' + quote + '</blockquote>\n';
+};
+
+Renderer.prototype.html = function(html) {
+ return html;
+};
+
+Renderer.prototype.heading = function(text, level, raw) {
+ return '<h'
+ + level
+ + ' id="'
+ + this.options.headerPrefix
+ + raw.toLowerCase().replace(/[^\w]+/g, '-')
+ + '">'
+ + text
+ + '</h'
+ + level
+ + '>\n';
+};
+
+Renderer.prototype.hr = function() {
+ return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
+};
+
+Renderer.prototype.list = function(body, ordered) {
+ var type = ordered ? 'ol' : 'ul';
+ return '<' + type + '>\n' + body + '</' + type + '>\n';
+};
+
+Renderer.prototype.listitem = function(text) {
+ return '<li>' + text + '</li>\n';
+};
+
+Renderer.prototype.paragraph = function(text) {
+ return '<p>' + text + '</p>\n';
+};
+
+Renderer.prototype.table = function(header, body) {
+ return '<table>\n'
+ + '<thead>\n'
+ + header
+ + '</thead>\n'
+ + '<tbody>\n'
+ + body
+ + '</tbody>\n'
+ + '</table>\n';
+};
+
+Renderer.prototype.tablerow = function(content) {
+ return '<tr>\n' + content + '</tr>\n';
+};
+
+Renderer.prototype.tablecell = function(content, flags) {
+ var type = flags.header ? 'th' : 'td';
+ var tag = flags.align
+ ? '<' + type + ' style="text-align:' + flags.align + '">'
+ : '<' + type + '>';
+ return tag + content + '</' + type + '>\n';
+};
+
+// span level renderer
+Renderer.prototype.strong = function(text) {
+ return '<strong>' + text + '</strong>';
+};
+
+Renderer.prototype.em = function(text) {
+ return '<em>' + text + '</em>';
+};
+
+Renderer.prototype.codespan = function(text) {
+ return '<code>' + text + '</code>';
+};
+
+Renderer.prototype.br = function() {
+ return this.options.xhtml ? '<br/>' : '<br>';
+};
+
+Renderer.prototype.del = function(text) {
+ return '<del>' + text + '</del>';
+};
+
+Renderer.prototype.link = function(href, title, text) {
+ if (this.options.sanitize) {
+ try {
+ var prot = decodeURIComponent(unescape(href))
+ .replace(/[^\w:]/g, '')
+ .toLowerCase();
+ } catch (e) {
+ return '';
+ }
+ if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) {
+ return '';
+ }
+ }
+ var out = '<a href="' + href + '"';
+ if (title) {
+ out += ' title="' + title + '"';
+ }
+ out += '>' + text + '</a>';
+ return out;
+};
+
+Renderer.prototype.image = function(href, title, text) {
+ var out = '<img src="' + href + '" alt="' + text + '"';
+ if (title) {
+ out += ' title="' + title + '"';
+ }
+ out += this.options.xhtml ? '/>' : '>';
+ return out;
+};
+
+/**
+ * Parsing & Compiling
+ */
+
+function Parser(options) {
+ this.tokens = [];
+ this.token = null;
+ this.options = options || marked.defaults;
+ this.options.renderer = this.options.renderer || new Renderer;
+ this.renderer = this.options.renderer;
+ this.renderer.options = this.options;
+}
+
+/**
+ * Static Parse Method
+ */
+
+Parser.parse = function(src, options, renderer) {
+ var parser = new Parser(options, renderer);
+ return parser.parse(src);
+};
+
+/**
+ * Parse Loop
+ */
+
+Parser.prototype.parse = function(src) {
+ this.inline = new InlineLexer(src.links, this.options, this.renderer);
+ this.tokens = src.reverse();
+
+ var out = '';
+ while (this.next()) {
+ out += this.tok();
+ }
+
+ return out;
+};
+
+/**
+ * Next Token
+ */
+
+Parser.prototype.next = function() {
+ return this.token = this.tokens.pop();
+};
+
+/**
+ * Preview Next Token
+ */
+
+Parser.prototype.peek = function() {
+ return this.tokens[this.tokens.length - 1] || 0;
+};
+
+/**
+ * Parse Text Tokens
+ */
+
+Parser.prototype.parseText = function() {
+ var body = this.token.text;
+
+ while (this.peek().type === 'text') {
+ body += '\n' + this.next().text;
+ }
+
+ return this.inline.output(body);
+};
+
+/**
+ * Parse Current Token
+ */
+
+Parser.prototype.tok = function() {
+ switch (this.token.type) {
+ case 'space': {
+ return '';
+ }
+ case 'hr': {
+ return this.renderer.hr();
+ }
+ case 'heading': {
+ return this.renderer.heading(
+ this.inline.output(this.token.text),
+ this.token.depth,
+ this.token.text);
+ }
+ case 'code': {
+ return this.renderer.code(this.token.text,
+ this.token.lang,
+ this.token.escaped);
+ }
+ case 'table': {
+ var header = ''
+ , body = ''
+ , i
+ , row
+ , cell
+ , flags
+ , j;
+
+ // header
+ cell = '';
+ for (i = 0; i < this.token.header.length; i++) {
+ flags = { header: true, align: this.token.align[i] };
+ cell += this.renderer.tablecell(
+ this.inline.output(this.token.header[i]),
+ { header: true, align: this.token.align[i] }
+ );
+ }
+ header += this.renderer.tablerow(cell);
+
+ for (i = 0; i < this.token.cells.length; i++) {
+ row = this.token.cells[i];
+
+ cell = '';
+ for (j = 0; j < row.length; j++) {
+ cell += this.renderer.tablecell(
+ this.inline.output(row[j]),
+ { header: false, align: this.token.align[j] }
+ );
+ }
+
+ body += this.renderer.tablerow(cell);
+ }
+ return this.renderer.table(header, body);
+ }
+ case 'blockquote_start': {
+ var body = '';
+
+ while (this.next().type !== 'blockquote_end') {
+ body += this.tok();
+ }
+
+ return this.renderer.blockquote(body);
+ }
+ case 'list_start': {
+ var body = ''
+ , ordered = this.token.ordered;
+
+ while (this.next().type !== 'list_end') {
+ body += this.tok();
+ }
+
+ return this.renderer.list(body, ordered);
+ }
+ case 'list_item_start': {
+ var body = '';
+
+ while (this.next().type !== 'list_item_end') {
+ body += this.token.type === 'text'
+ ? this.parseText()
+ : this.tok();
+ }
+
+ return this.renderer.listitem(body);
+ }
+ case 'loose_item_start': {
+ var body = '';
+
+ while (this.next().type !== 'list_item_end') {
+ body += this.tok();
+ }
+
+ return this.renderer.listitem(body);
+ }
+ case 'html': {
+ var html = !this.token.pre && !this.options.pedantic
+ ? this.inline.output(this.token.text)
+ : this.token.text;
+ return this.renderer.html(html);
+ }
+ case 'paragraph': {
+ return this.renderer.paragraph(this.inline.output(this.token.text));
+ }
+ case 'text': {
+ return this.renderer.paragraph(this.parseText());
+ }
+ }
+};
+
+/**
+ * Helpers
+ */
+
+function escape(html, encode) {
+ return html
+ .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&')
+ .replace(/</g, '<')
+ .replace(/>/g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''');
+}
+
+function unescape(html) {
+ return html.replace(/&([#\w]+);/g, function(_, n) {
+ n = n.toLowerCase();
+ if (n === 'colon') return ':';
+ if (n.charAt(0) === '#') {
+ return n.charAt(1) === 'x'
+ ? String.fromCharCode(parseInt(n.substring(2), 16))
+ : String.fromCharCode(+n.substring(1));
+ }
+ return '';
+ });
+}
+
+function replace(regex, opt) {
+ regex = regex.source;
+ opt = opt || '';
+ return function self(name, val) {
+ if (!name) return new RegExp(regex, opt);
+ val = val.source || val;
+ val = val.replace(/(^|[^\[])\^/g, '$1');
+ regex = regex.replace(name, val);
+ return self;
+ };
+}
+
+function noop() {}
+noop.exec = noop;
+
+function merge(obj) {
+ var i = 1
+ , target
+ , key;
+
+ for (; i < arguments.length; i++) {
+ target = arguments[i];
+ for (key in target) {
+ if (Object.prototype.hasOwnProperty.call(target, key)) {
+ obj[key] = target[key];
+ }
+ }
+ }
+
+ return obj;
+}
+
+
+/**
+ * Marked
+ */
+
+function marked(src, opt, callback) {
+ if (callback || typeof opt === 'function') {
+ if (!callback) {
+ callback = opt;
+ opt = null;
+ }
+
+ opt = merge({}, marked.defaults, opt || {});
+
+ var highlight = opt.highlight
+ , tokens
+ , pending
+ , i = 0;
+
+ try {
+ tokens = Lexer.lex(src, opt)
+ } catch (e) {
+ return callback(e);
+ }
+
+ pending = tokens.length;
+
+ var done = function(err) {
+ if (err) {
+ opt.highlight = highlight;
+ return callback(err);
+ }
+
+ var out;
+
+ try {
+ out = Parser.parse(tokens, opt);
+ } catch (e) {
+ err = e;
+ }
+
+ opt.highlight = highlight;
+
+ return err
+ ? callback(err)
+ : callback(null, out);
+ };
+
+ if (!highlight || highlight.length < 3) {
+ return done();
+ }
+
+ delete opt.highlight;
+
+ if (!pending) return done();
+
+ for (; i < tokens.length; i++) {
+ (function(token) {
+ if (token.type !== 'code') {
+ return --pending || done();
+ }
+ return highlight(token.text, token.lang, function(err, code) {
+ if (err) return done(err);
+ if (code == null || code === token.text) {
+ return --pending || done();
+ }
+ token.text = code;
+ token.escaped = true;
+ --pending || done();
+ });
+ })(tokens[i]);
+ }
+
+ return;
+ }
+ try {
+ if (opt) opt = merge({}, marked.defaults, opt);
+ return Parser.parse(Lexer.lex(src, opt), opt);
+ } catch (e) {
+ e.message += '\nPlease report this to https://github.com/chjj/marked.';
+ if ((opt || marked.defaults).silent) {
+ return '<p>An error occured:</p><pre>'
+ + escape(e.message + '', true)
+ + '</pre>';
+ }
+ throw e;
+ }
+}
+
+/**
+ * Options
+ */
+
+marked.options =
+marked.setOptions = function(opt) {
+ merge(marked.defaults, opt);
+ return marked;
+};
+
+marked.defaults = {
+ gfm: true,
+ tables: true,
+ breaks: false,
+ pedantic: false,
+ sanitize: false,
+ smartLists: false,
+ silent: false,
+ highlight: null,
+ langPrefix: 'lang-',
+ smartypants: false,
+ headerPrefix: '',
+ renderer: new Renderer,
+ xhtml: false
+};
+
+/**
+ * Expose
+ */
+
+marked.Parser = Parser;
+marked.parser = Parser.parse;
+
+marked.Renderer = Renderer;
+
+marked.Lexer = Lexer;
+marked.lexer = Lexer.lex;
+
+marked.InlineLexer = InlineLexer;
+marked.inlineLexer = InlineLexer.output;
+
+marked.parse = marked;
+
+if (typeof module !== 'undefined' && typeof exports === 'object') {
+ module.exports = marked;
+} else if (typeof define === 'function' && define.amd) {
+ define(function() { return marked; });
+} else {
+ this.marked = marked;
+}
+
+}).call(function() {
+ return this || (typeof window !== 'undefined' ? window : global);
+}());
diff --git a/polymer_1.0.4/bower_components/marked/man/marked.1 b/polymer_1.0.4/bower_components/marked/man/marked.1
new file mode 100644
index 0000000..f89f1a7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked/man/marked.1
@@ -0,0 +1,88 @@
+.ds q \N'34'
+.TH marked 1 "2014-01-31" "v0.3.1" "marked.js"
+
+.SH NAME
+marked \- a javascript markdown parser
+
+.SH SYNOPSIS
+.B marked
+[\-o \fI<output>\fP] [\-i \fI<input>\fP] [\-\-help]
+[\-\-tokens] [\-\-pedantic] [\-\-gfm]
+[\-\-breaks] [\-\-tables] [\-\-sanitize]
+[\-\-smart\-lists] [\-\-lang\-prefix \fI<prefix>\fP]
+[\-\-no\-etc...] [\-\-silent] [\fIfilename\fP]
+
+.SH DESCRIPTION
+.B marked
+is a full-featured javascript markdown parser, built for speed. It also includes
+multiple GFM features.
+
+.SH EXAMPLES
+.TP
+cat in.md | marked > out.html
+.TP
+echo "hello *world*" | marked
+.TP
+marked \-o out.html in.md \-\-gfm
+.TP
+marked \-\-output="hello world.html" \-i in.md \-\-no-breaks
+
+.SH OPTIONS
+.TP
+.BI \-o,\ \-\-output\ [\fIoutput\fP]
+Specify file output. If none is specified, write to stdout.
+.TP
+.BI \-i,\ \-\-input\ [\fIinput\fP]
+Specify file input, otherwise use last argument as input file. If no input file
+is specified, read from stdin.
+.TP
+.BI \-t,\ \-\-tokens
+Output a token stream instead of html.
+.TP
+.BI \-\-pedantic
+Conform to obscure parts of markdown.pl as much as possible. Don't fix original
+markdown bugs.
+.TP
+.BI \-\-gfm
+Enable github flavored markdown.
+.TP
+.BI \-\-breaks
+Enable GFM line breaks. Only works with the gfm option.
+.TP
+.BI \-\-tables
+Enable GFM tables. Only works with the gfm option.
+.TP
+.BI \-\-sanitize
+Sanitize output. Ignore any HTML input.
+.TP
+.BI \-\-smart\-lists
+Use smarter list behavior than the original markdown.
+.TP
+.BI \-\-lang\-prefix\ [\fIprefix\fP]
+Set the prefix for code block classes.
+.TP
+.BI \-\-no\-sanitize,\ \-no-etc...
+The inverse of any of the marked options above.
+.TP
+.BI \-\-silent
+Silence error output.
+.TP
+.BI \-h,\ \-\-help
+Display help information.
+
+.SH CONFIGURATION
+For configuring and running programmatically.
+
+.B Example
+
+ require('marked')('*foo*', { gfm: true });
+
+.SH BUGS
+Please report any bugs to https://github.com/chjj/marked.
+
+.SH LICENSE
+Copyright (c) 2011-2014, Christopher Jeffrey (MIT License).
+
+.SH "SEE ALSO"
+.BR markdown(1),
+.BR node.js(1)
diff --git a/polymer_1.0.4/bower_components/marked/marked.min.js b/polymer_1.0.4/bower_components/marked/marked.min.js
new file mode 100644
index 0000000..a5164c4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked/marked.min.js
@@ -0,0 +1,6 @@
+/**
+ * marked - a markdown parser
+ * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
+ * https://github.com/chjj/marked
+ */
+(function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+block.def.source+")")();block.blockquote=replace(block.blockquote)("def",block.def)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b";block.html=replace(block.html)("comment",/<!--[\s\S]*?-->/)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,paragraph:/^/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1","\\2")+"|"+block.list.source.replace("\\1","\\3")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm){if(this.options.tables){this.rules=block.tables}else{this.rules=block.gfm}}}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top,bq){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1){this.tokens.push({type:"space"})}}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i<item.align.length;i++){if(/^ *-+: *$/.test(item.align[i])){item.align[i]="right"}else if(/^ *:-+: *$/.test(item.align[i])){item.align[i]="center"}else if(/^ *:-+ *$/.test(item.align[i])){item.align[i]="left"}else{item.align[i]=null}}for(i=0;i<item.cells.length;i++){item.cells[i]=item.cells[i].split(/ *\| */)}this.tokens.push(item);continue}if(cap=this.rules.lheading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[2]==="="?1:2,text:cap[1]});continue}if(cap=this.rules.hr.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"hr"});continue}if(cap=this.rules.blockquote.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"blockquote_start"});cap=cap[0].replace(/^ *> ?/gm,"");this.token(cap,top,true);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i<l;i++){item=cap[i];space=item.length;item=item.replace(/^ *([*+-]|\d+\.) +/,"");if(~item.indexOf("\n ")){space-=item.length;item=!this.options.pedantic?item.replace(new RegExp("^ {1,"+space+"}","gm"),""):item.replace(/^ {1,4}/gm,"")}if(this.options.smartLists&&i!==l-1){b=block.bullet.exec(cap[i+1])[0];if(bull!==b&&!(bull.length>1&&b.length>1)){src=cap.slice(i+1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item.charAt(item.length-1)==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false,bq);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:cap[1]==="pre"||cap[1]==="script"||cap[1]==="style",text:cap[0]});continue}if(!bq&&top&&(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i<item.align.length;i++){if(/^ *-+: *$/.test(item.align[i])){item.align[i]="right"}else if(/^ *:-+: *$/.test(item.align[i])){item.align[i]="center"}else if(/^ *:-+ *$/.test(item.align[i])){item.align[i]="left"}else{item.align[i]=null}}for(i=0;i<item.cells.length;i++){item.cells[i]=item.cells[i].replace(/^ *\| *| *\| *$/g,"").split(/ *\| */)}this.tokens.push(item);continue}if(top&&(cap=this.rules.paragraph.exec(src))){src=src.substring(cap[0].length);this.tokens.push({type:"paragraph",text:cap[1].charAt(cap[1].length-1)==="\n"?cap[1].slice(0,-1):cap[1]});continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"text",text:cap[0]});continue}if(src){throw new Error("Infinite loop on byte: "+src.charCodeAt(0))}}return this.tokens};var inline={escape:/^\\([\\`*{}\[\]()#+\-.!_>])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/};inline._inside=/(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;inline._href=/\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;this.renderer=this.options.renderer||new Renderer;this.renderer.options=this.options;if(!this.links){throw new Error("Tokens array requires a `links` property.")}if(this.options.gfm){if(this.options.breaks){this.rules=inline.breaks}else{this.rules=inline.gfm}}else if(this.options.pedantic){this.rules=inline.pedantic}}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1].charAt(6)===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+=this.renderer.link(href,null,text);continue}if(!this.inLink&&(cap=this.rules.url.exec(src))){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+=this.renderer.link(href,null,text);continue}if(cap=this.rules.tag.exec(src)){if(!this.inLink&&/^<a /i.test(cap[0])){this.inLink=true}else if(this.inLink&&/^<\/a>/i.test(cap[0])){this.inLink=false}src=src.substring(cap[0].length);out+=this.options.sanitize?escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);this.inLink=true;out+=this.outputLink(cap,{href:cap[2],title:cap[3]});this.inLink=false;continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0].charAt(0);src=cap[0].substring(1)+src;continue}this.inLink=true;out+=this.outputLink(cap,link);this.inLink=false;continue}if(cap=this.rules.strong.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.strong(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.em(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.codespan(escape(cap[2],true));continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.br();continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.del(this.output(cap[1]));continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=escape(this.smartypants(cap[0]));continue}if(src){throw new Error("Infinite loop on byte: "+src.charCodeAt(0))}}return out};InlineLexer.prototype.outputLink=function(cap,link){var href=escape(link.href),title=link.title?escape(link.title):null;return cap[0].charAt(0)!=="!"?this.renderer.link(href,title,this.output(cap[1])):this.renderer.image(href,title,escape(cap[1]))};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/--/g,"—").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…")};InlineLexer.prototype.mangle=function(text){var out="",l=text.length,i=0,ch;for(;i<l;i++){ch=text.charCodeAt(i);if(Math.random()>.5){ch="x"+ch.toString(16)}out+="&#"+ch+";"}return out};function Renderer(options){this.options=options||{}}Renderer.prototype.code=function(code,lang,escaped){if(this.options.highlight){var out=this.options.highlight(code,lang);if(out!=null&&out!==code){escaped=true;code=out}}if(!lang){return"<pre><code>"+(escaped?code:escape(code,true))+"\n</code></pre>"}return'<pre><code class="'+this.options.langPrefix+escape(lang,true)+'">'+(escaped?code:escape(code,true))+"\n</code></pre>\n"};Renderer.prototype.blockquote=function(quote){return"<blockquote>\n"+quote+"</blockquote>\n"};Renderer.prototype.html=function(html){return html};Renderer.prototype.heading=function(text,level,raw){return"<h"+level+' id="'+this.options.headerPrefix+raw.toLowerCase().replace(/[^\w]+/g,"-")+'">'+text+"</h"+level+">\n"};Renderer.prototype.hr=function(){return this.options.xhtml?"<hr/>\n":"<hr>\n"};Renderer.prototype.list=function(body,ordered){var type=ordered?"ol":"ul";return"<"+type+">\n"+body+"</"+type+">\n"};Renderer.prototype.listitem=function(text){return"<li>"+text+"</li>\n"};Renderer.prototype.paragraph=function(text){return"<p>"+text+"</p>\n"};Renderer.prototype.table=function(header,body){return"<table>\n"+"<thead>\n"+header+"</thead>\n"+"<tbody>\n"+body+"</tbody>\n"+"</table>\n"};Renderer.prototype.tablerow=function(content){return"<tr>\n"+content+"</tr>\n"};Renderer.prototype.tablecell=function(content,flags){var type=flags.header?"th":"td";var tag=flags.align?"<"+type+' style="text-align:'+flags.align+'">':"<"+type+">";return tag+content+"</"+type+">\n"};Renderer.prototype.strong=function(text){return"<strong>"+text+"</strong>"};Renderer.prototype.em=function(text){return"<em>"+text+"</em>"};Renderer.prototype.codespan=function(text){return"<code>"+text+"</code>"};Renderer.prototype.br=function(){return this.options.xhtml?"<br/>":"<br>"};Renderer.prototype.del=function(text){return"<del>"+text+"</del>"};Renderer.prototype.link=function(href,title,text){if(this.options.sanitize){try{var prot=decodeURIComponent(unescape(href)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return""}if(prot.indexOf("javascript:")===0){return""}}var out='<a href="'+href+'"';if(title){out+=' title="'+title+'"'}out+=">"+text+"</a>";return out};Renderer.prototype.image=function(href,title,text){var out='<img src="'+href+'" alt="'+text+'"';if(title){out+=' title="'+title+'"'}out+=this.options.xhtml?"/>":">";return out};function Parser(options){this.tokens=[];this.token=null;this.options=options||marked.defaults;this.options.renderer=this.options.renderer||new Renderer;this.renderer=this.options.renderer;this.renderer.options=this.options}Parser.parse=function(src,options,renderer){var parser=new Parser(options,renderer);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options,this.renderer);this.tokens=src.reverse();var out="";while(this.next()){out+=this.tok()}return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;while(this.peek().type==="text"){body+="\n"+this.next().text}return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case"space":{return""}case"hr":{return this.renderer.hr()}case"heading":{return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text)}case"code":{return this.renderer.code(this.token.text,this.token.lang,this.token.escaped)}case"table":{var header="",body="",i,row,cell,flags,j;cell="";for(i=0;i<this.token.header.length;i++){flags={header:true,align:this.token.align[i]};cell+=this.renderer.tablecell(this.inline.output(this.token.header[i]),{header:true,align:this.token.align[i]})}header+=this.renderer.tablerow(cell);for(i=0;i<this.token.cells.length;i++){row=this.token.cells[i];cell="";for(j=0;j<row.length;j++){cell+=this.renderer.tablecell(this.inline.output(row[j]),{header:false,align:this.token.align[j]})}body+=this.renderer.tablerow(cell)}return this.renderer.table(header,body)}case"blockquote_start":{var body="";while(this.next().type!=="blockquote_end"){body+=this.tok()}return this.renderer.blockquote(body)}case"list_start":{var body="",ordered=this.token.ordered;while(this.next().type!=="list_end"){body+=this.tok()}return this.renderer.list(body,ordered)}case"list_item_start":{var body="";while(this.next().type!=="list_item_end"){body+=this.token.type==="text"?this.parseText():this.tok()}return this.renderer.listitem(body)}case"loose_item_start":{var body="";while(this.next().type!=="list_item_end"){body+=this.tok()}return this.renderer.listitem(body)}case"html":{var html=!this.token.pre&&!this.options.pedantic?this.inline.output(this.token.text):this.token.text;return this.renderer.html(html)}case"paragraph":{return this.renderer.paragraph(this.inline.output(this.token.text))}case"text":{return this.renderer.paragraph(this.parseText())}}};function escape(html,encode){return html.replace(!encode?/&(?!#?\w+;)/g:/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function unescape(html){return html.replace(/&([#\w]+);/g,function(_,n){n=n.toLowerCase();if(n==="colon")return":";if(n.charAt(0)==="#"){return n.charAt(1)==="x"?String.fromCharCode(parseInt(n.substring(2),16)):String.fromCharCode(+n.substring(1))}return""})}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=1,target,key;for(;i<arguments.length;i++){target=arguments[i];for(key in target){if(Object.prototype.hasOwnProperty.call(target,key)){obj[key]=target[key]}}}return obj}function marked(src,opt,callback){if(callback||typeof opt==="function"){if(!callback){callback=opt;opt=null}opt=merge({},marked.defaults,opt||{});var highlight=opt.highlight,tokens,pending,i=0;try{tokens=Lexer.lex(src,opt)}catch(e){return callback(e)}pending=tokens.length;var done=function(err){if(err){opt.highlight=highlight;return callback(err)}var out;try{out=Parser.parse(tokens,opt)}catch(e){err=e}opt.highlight=highlight;return err?callback(err):callback(null,out)};if(!highlight||highlight.length<3){return done()}delete opt.highlight;if(!pending)return done();for(;i<tokens.length;i++){(function(token){if(token.type!=="code"){return--pending||done()}return highlight(token.text,token.lang,function(err,code){if(err)return done(err);if(code==null||code===token.text){return--pending||done()}token.text=code;token.escaped=true;--pending||done()})})(tokens[i])}return}try{if(opt)opt=merge({},marked.defaults,opt);return Parser.parse(Lexer.lex(src,opt),opt)}catch(e){e.message+="\nPlease report this to https://github.com/chjj/marked.";if((opt||marked.defaults).silent){return"<p>An error occured:</p><pre>"+escape(e.message+"",true)+"</pre>"}throw e}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,smartLists:false,silent:false,highlight:null,langPrefix:"lang-",smartypants:false,headerPrefix:"",renderer:new Renderer,xhtml:false};marked.Parser=Parser;marked.parser=Parser.parse;marked.Renderer=Renderer;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;marked.parse=marked;if(typeof module!=="undefined"&&typeof exports==="object"){module.exports=marked}else if(typeof define==="function"&&define.amd){define(function(){return marked})}else{this.marked=marked}}).call(function(){return this||(typeof window!=="undefined"?window:global)}());
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/marked/package.json b/polymer_1.0.4/bower_components/marked/package.json
new file mode 100644
index 0000000..eb1e28d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/marked/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "marked",
+ "description": "A markdown parser built for speed",
+ "author": "Christopher Jeffrey",
+ "version": "0.3.3",
+ "main": "./lib/marked.js",
+ "bin": "./bin/marked",
+ "man": "./man/marked.1",
+ "preferGlobal": true,
+ "repository": "git://github.com/chjj/marked.git",
+ "homepage": "https://github.com/chjj/marked",
+ "bugs": { "url": "http://github.com/chjj/marked/issues" },
+ "license": "MIT",
+ "keywords": ["markdown", "markup", "html"],
+ "tags": ["markdown", "markup", "html"],
+ "devDependencies": {
+ "markdown": "*",
+ "showdown": "*",
+ "robotskirt": "*"
+ },
+ "scripts": { "test": "node test", "bench": "node test --bench" }
+}
diff --git a/polymer_1.0.4/bower_components/neon-animation/.bower.json b/polymer_1.0.4/bower_components/neon-animation/.bower.json
new file mode 100644
index 0000000..7526a92
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/.bower.json
@@ -0,0 +1,60 @@
+{
+ "name": "neon-animation",
+ "version": "1.0.3",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer",
+ "web-animations"
+ ],
+ "main": [
+ "neon-animated-pages.html",
+ "neon-animatable-behavior.html",
+ "neon-animation-behavior.html",
+ "neon-animation-runner-behavior.html",
+ "neon-shared-element-animatable-behavior.html",
+ "neon-shared-element-animation-behavior.html",
+ "neon-animatable.html",
+ "neon-animations.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/neon-animation"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/neon-animation",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-meta": "PolymerElements/iron-meta#^1.0.0",
+ "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.0",
+ "iron-selector": "PolymerElements/iron-selector#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "web-animations-js": "web-animations/web-animations-js#^2.0.0"
+ },
+ "devDependencies": {
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "paper-toolbar": "PolymerElements/paper-toolbar#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "paper-item": "PolymerElements/paper-item#^1.0.0",
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+ "paper-icon-button": "PolymerElements/paper-icon-button#^1.0.0"
+ },
+ "_release": "1.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.3",
+ "commit": "5573a60b33a62ea873381569418943844bc21b68"
+ },
+ "_source": "git://github.com/PolymerElements/neon-animation.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/neon-animation"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/neon-animation/.gitignore b/polymer_1.0.4/bower_components/neon-animation/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/neon-animation/README.md b/polymer_1.0.4/bower_components/neon-animation/README.md
new file mode 100644
index 0000000..c1b258c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/README.md
@@ -0,0 +1,304 @@
+# neon-animation
+
+`neon-animation` is a suite of elements and behaviors to implement pluggable animated transitions for Polymer Elements using [Web Animations](https://w3c.github.io/web-animations/).
+
+*Warning: The API may change.*
+
+* [A basic animatable element](#basic)
+* [Animation configuration](#configuration)
+ * [Animation types](#configuration-types)
+ * [Configuration properties](#configuration-properties)
+ * [Using multiple animations](#configuration-multiple)
+ * [Running animations encapsulated in children nodes](#configuration-encapsulation)
+* [Page transitions](#page-transitions)
+ * [Shared element animations](#shared-element)
+ * [Declarative page transitions](#declarative-page)
+* [Included animations](#animations)
+* [Demos](#demos)
+
+<a name="basic"></a>
+## A basic animatable element
+
+Elements that can be animated should implement the `Polymer.NeonAnimatableBehavior` behavior, or `Polymer.NeonAnimationRunnerBehavior` if they're also responsible for running an animation.
+
+```js
+Polymer({
+ is: 'my-animatable',
+ behaviors: [
+ Polymer.NeonAnimationRunnerBehavior
+ ],
+ properties: {
+ animationConfig: {
+ value: function() {
+ return {
+ // provided by neon-animation/animations/scale-down-animation.html
+ name: 'scale-down-animation',
+ node: this
+ }
+ }
+ }
+ },
+ listeners: {
+ // this event is fired when the animation finishes
+ 'neon-animation-finish': '_onNeonAnimationFinish'
+ },
+ animate: function() {
+ // run scale-down-animation
+ this.playAnimation();
+ },
+ _onNeonAnimationFinish: function() {
+ console.log('animation done!');
+ }
+});
+```
+
+[Live demo](http://morethanreal.github.io/neon-animation-demo/bower_components/neon-animation/demo/doc/basic.html)
+
+<a name="configuration"></a>
+## Animation configuration
+
+<a name="configuration-types"></a>
+### Animation types
+
+An element might run different animations, for example it might do something different when it enters the view and when it exits from view. You can set the `animationConfig` property to a map from an animation type to configuration.
+
+```js
+Polymer({
+ is: 'my-dialog',
+ behaviors: [
+ Polymer.NeonAnimationRunnerBehavior
+ ],
+ properties: {
+ opened: {
+ type: Boolean
+ },
+ animationConfig: {
+ value: function() {
+ return {
+ 'entry': {
+ // provided by neon-animation/animations/scale-up-animation.html
+ name: 'scale-up-animation',
+ node: this
+ },
+ 'exit': {
+ // provided by neon-animation-animations/fade-out-animation.html
+ name: 'fade-out-animation',
+ node: this
+ }
+ }
+ }
+ }
+ },
+ listeners: {
+ 'neon-animation-finish': '_onNeonAnimationFinish'
+ },
+ show: function() {
+ this.opened = true;
+ this.style.display = 'inline-block';
+ // run scale-up-animation
+ this.playAnimation('entry');
+ },
+ hide: function() {
+ this.opened = false;
+ // run fade-out-animation
+ this.playAnimation('fade-out-animation');
+ },
+ _onNeonAnimationFinish: function() {
+ if (!this.opened) {
+ this.style.display = 'none';
+ }
+ }
+});
+```
+
+[Live demo](http://morethanreal.github.io/neon-animation-demo/bower_components/neon-animation/demo/doc/types.html)
+
+You can also use the convenience properties `entryAnimation` and `exitAnimation` to set `entry` and `exit` animations:
+
+```js
+properties: {
+ entryAnimation: {
+ value: 'scale-up-animation'
+ },
+ exitAnimation: {
+ value: 'fade-out-animation'
+ }
+}
+```
+
+<a name="configuration-properties"></a>
+### Configuration properties
+
+You can pass additional parameters to configure an animation in the animation configuration object.
+All animations should accept the following properties:
+
+ * `name`: The name of an animation, ie. an element implementing `Polymer.NeonAnimationBehavior`.
+ * `node`: The target node to apply the animation to. Defaults to `this`.
+ * `timing`: Timing properties to use in this animation. They match the [Web Animations Animation Effect Timing interface](https://w3c.github.io/web-animations/#the-animationeffecttiming-interface). The
+ properties include the following:
+ * `duration`: The duration of the animation in milliseconds.
+ * `delay`: The delay before the start of the animation in milliseconds.
+ * `easing`: A timing function for the animation. Matches the CSS timing function values.
+
+Animations may define additional configuration properties and they are listed in their documentation.
+
+<a name="configuration-multiple"></a>
+### Using multiple animations
+
+Set the animation configuration to an array to combine animations, like this:
+
+```js
+animationConfig: {
+ value: function() {
+ return {
+ // fade-in-animation is run with a 50ms delay from slide-down-animation
+ 'entry': [{
+ name: 'slide-down-animation',
+ node: this
+ }, {
+ name: 'fade-in-animation',
+ node: this,
+ timing: {delay: 50}
+ }]
+ }
+ }
+}
+```
+
+<a name="configuration-encapsulation"></a>
+### Running animations encapsulated in children nodes
+
+You can include animations in the configuration that are encapsulated in a child element that implement `Polymer.NeonAnimatableBehavior` with the `animatable` property.
+
+```js
+animationConfig: {
+ value: function() {
+ return {
+ // run fade-in-animation on this, and the entry animation on this.$.myAnimatable
+ 'entry': [
+ {name: 'fade-in-animation', node: this},
+ {animatable: this.$.myAnimatable, type: 'entry'}
+ ]
+ }
+ }
+}
+```
+
+<a name="page-transitions"></a>
+## Page transitions
+
+*The artist formerly known as `<core-animated-pages>`*
+
+The `neon-animated-pages` element manages a set of pages to switch between, and runs animations between the page transitions. It implements the `Polymer.IronSelectableBehavior` behavior. Each child node should implement `Polymer.NeonAnimatableBehavior` and define the `entry` and `exit` animations. During a page transition, the `entry` animation is run on the new page and the `exit` animation is run on the old page.
+
+<a name="shared-element"></a>
+### Shared element animations
+
+Shared element animations work on multiple nodes. For example, a "hero" animation is used during a page transition to make two elements from separate pages appear to animate as a single element. Shared element animation configurations have an `id` property that identify they belong in the same animation. Elements containing shared elements also have a `sharedElements` property defines a map from `id` to element, the element involved with the animation.
+
+In the incoming page:
+
+```js
+properties: {
+ animationConfig: {
+ value: function() {
+ return {
+ // the incoming page defines the 'entry' animation
+ 'entry': {
+ name: 'hero-animation',
+ id: 'hero',
+ toPage: this
+ }
+ }
+ }
+ },
+ sharedElements: {
+ value: function() {
+ return {
+ 'hero': this.$.hero
+ }
+ }
+ }
+}
+```
+
+In the outgoing page:
+
+```js
+properties: {
+ animationConfig: {
+ value: function() {
+ return {
+ // the outgoing page defines the 'exit' animation
+ 'exit': {
+ name: 'hero-animation',
+ id: 'hero',
+ fromPage: this
+ }
+ }
+ }
+ },
+ sharedElements: {
+ value: function() {
+ return {
+ 'hero': this.$.otherHero
+ }
+ }
+ }
+}
+```
+
+<a name="declarative-page"></a>
+### Declarative page transitions
+
+For convenience, if you define the `entry-animation` and `exit-animation` attributes on `<neon-animated-pages>`, those animations will apply for all page transitions.
+
+For example:
+
+```js
+<neon-animated-pages id="pages" class="flex" selected="[[selected]]" entry-animation="slide-from-right-animation" exit-animation="slide-left-animation">
+ <neon-animatable>1</neon-animatable>
+ <neon-animatable>2</neon-animatable>
+ <neon-animatable>3</neon-animatable>
+ <neon-animatable>4</neon-animatable>
+ <neon-animatable>5</neon-animatable>
+</neon-animated-pages>
+```
+
+The new page will slide in from the right, and the old page slide away to the left.
+
+<a name="animations"></a>
+## Included animations
+
+Single element animations:
+
+ * `fade-in-animation` Animates opacity from `0` to `1`.
+ * `fade-out-animation` Animates opacity from `1` to `0`.
+ * `scale-down-animation` Animates transform from `scale(1)` to `scale(0)`.
+ * `scale-up-animation` Animates transform from `scale(0)` to `scale(1)`.
+ * `slide-down-animation` Animates transform from `translateY(-100%)` to `none`.
+ * `slide-up-animation` Animates transform from `none` to `translateY(-100%)`.
+ * `slide-left-animation` Animates transform from `none` to `translateX(-100%)`;
+ * `slide-right-animation` Animates transform from `none` to `translateX(100%)`;
+ * `slide-from-left-animation` Animates transform from `translateX(-100%)` to `none`;
+ * `slide-from-right-animation` Animates transform from `translateX(100%)` to `none`;
+ * `transform-animation` Animates a custom transform.
+
+Note that there is a restriction that only one transform animation can be applied on the same element at a time. Use the custom `transform-animation` to combine transform properties.
+
+Shared element animations
+
+ * `hero-animation` Animates an element such that it looks like it scales and transforms from another element.
+ * `ripple-animation` Animates an element to full screen such that it looks like it ripples from another element.
+
+Group animations
+ * `cascaded-animation` Applys an animation to an array of elements with a delay between each.
+
+<a name="demos"></a>
+## Demos
+
+ * [Grid to full screen](http://morethanreal.github.io/neon-animation-demo/bower_components/neon-animation/demo/grid/index.html)
+ * [Animation on load](http://morethanreal.github.io/neon-animation-demo/bower_components/neon-animation/demo/load/index.html)
+ * [List item to detail](http://morethanreal.github.io/neon-animation-demo/bower_components/neon-animation/demo/list/index.html) (For narrow width)
+ * [Dots to squares](http://morethanreal.github.io/neon-animation-demo/bower_components/neon-animation/demo/tiles/index.html)
+ * [Declarative](http://morethanreal.github.io/neon-animation-demo/bower_components/neon-animation/demo/declarative/index.html)
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/cascaded-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/cascaded-animation.html
new file mode 100644
index 0000000..892e2dd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/cascaded-animation.html
@@ -0,0 +1,94 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<cascaded-animation>` applies an animation on an array of elements with a delay between each.
+the delay defaults to 50ms.
+
+Configuration:
+```
+{
+ name: 'cascaded-animation',
+ animation: <animation-name>,
+ nodes: <array-of-nodes>,
+ nodedelay: <node-delay-in-ms>,
+ timing: <animation-timing>
+}
+```
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'cascaded-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ properties: {
+
+ /** @type {!Polymer.IronMeta} */
+ _animationMeta: {
+ type: Object,
+ value: function() {
+ return new Polymer.IronMeta({type: 'animation'});
+ }
+ }
+
+ },
+
+ /**
+ * @param {{
+ * animation: string,
+ * nodes: !Array<!Element>,
+ * nodeDelay: (number|undefined),
+ * timing: (Object|undefined)
+ * }} config
+ */
+ configure: function(config) {
+ var animationConstructor = /** @type {Function} */ (
+ this._animationMeta.byKey(config.animation));
+ if (!animationConstructor) {
+ console.warn(this.is + ':', 'constructor for', config.animation, 'not found!');
+ return;
+ }
+
+ var nodes = config.nodes;
+ var effects = [];
+ var nodeDelay = config.nodeDelay || 50;
+
+ config.timing = config.timing || {};
+ config.timing.delay = config.timing.delay || 0;
+
+ var oldDelay = config.timing.delay;
+ for (var node, index = 0; node = nodes[index]; index++) {
+ config.timing.delay += nodeDelay;
+ config.node = node;
+
+ var animation = new animationConstructor();
+ var effect = animation.configure(config);
+
+ effects.push(effect);
+ }
+ config.timing.delay = oldDelay;
+
+ this._effect = new GroupEffect(effects);
+ return this._effect;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/fade-in-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/fade-in-animation.html
new file mode 100644
index 0000000..cdb74e3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/fade-in-animation.html
@@ -0,0 +1,49 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<fade-in-animation>` animates the opacity of an element from 0 to 1.
+
+Configuration:
+```
+{
+ name: 'fade-in-animation',
+ node: <node>
+ timing: <animation-timing>
+}
+```
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'fade-in-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+ this._effect = new KeyframeEffect(node, [
+ {'opacity': '0'},
+ {'opacity': '1'}
+ ], this.timingFromConfig(config));
+ return this._effect;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/fade-out-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/fade-out-animation.html
new file mode 100644
index 0000000..82cc399
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/fade-out-animation.html
@@ -0,0 +1,49 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<fade-out-animation>` animates the opacity of an element from 1 to 0.
+
+Configuration:
+```
+{
+ name: 'fade-out-animation',
+ node: <node>
+ timing: <animation-timing>
+}
+```
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'fade-out-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+ this._effect = new KeyframeEffect(node, [
+ {'opacity': '1'},
+ {'opacity': '0'}
+ ], this.timingFromConfig(config));
+ return this._effect;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/hero-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/hero-animation.html
new file mode 100644
index 0000000..a9075e1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/hero-animation.html
@@ -0,0 +1,83 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-shared-element-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<hero-animation>` is a shared element animation that scales and transform an element such that it
+appears to be shared between two pages. Use this in `<neon-animated-pages>`. The source page
+should use this animation in an 'exit' animation and set the `fromPage` configuration property to
+itself, and the destination page should use this animation in an `entry` animation and set the
+`toPage` configuration property to itself. They should also define the hero elements in the
+`sharedElements` property (not a configuration property, see
+`Polymer.NeonSharedElementAnimatableBehavior`).
+
+Configuration:
+```
+{
+ name: 'hero-animation',
+ id: <shared-element-id>,
+ timing: <animation-timing>,
+ toPage: <node>, /* define for the destination page */
+ fromPage: <node>, /* define for the source page */
+}
+```
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'hero-animation',
+
+ behaviors: [
+ Polymer.NeonSharedElementAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var shared = this.findSharedElements(config);
+ if (!shared) {
+ return;
+ }
+
+ var fromRect = shared.from.getBoundingClientRect();
+ var toRect = shared.to.getBoundingClientRect();
+
+ var deltaLeft = fromRect.left - toRect.left;
+ var deltaTop = fromRect.top - toRect.top;
+ var deltaWidth = fromRect.width / toRect.width;
+ var deltaHeight = fromRect.height / toRect.height;
+
+ this.setPrefixedProperty(shared.to, 'transformOrigin', '0 0');
+ shared.to.style.zIndex = 10000;
+ shared.from.style.visibility = 'hidden';
+
+ this._effect = new KeyframeEffect(shared.to, [
+ {'transform': 'translate(' + deltaLeft + 'px,' + deltaTop + 'px) scale(' + deltaWidth + ',' + deltaHeight + ')'},
+ {'transform': 'none'}
+ ], this.timingFromConfig(config));
+
+ return this._effect;
+ },
+
+ complete: function(config) {
+ var shared = this.findSharedElements(config);
+ if (!shared) {
+ return null;
+ }
+ shared.to.style.zIndex = '';
+ shared.from.style.visibility = '';
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/opaque-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/opaque-animation.html
new file mode 100644
index 0000000..f5b60a4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/opaque-animation.html
@@ -0,0 +1,46 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<opaque-animation>` makes an element `opacity:1` for the duration of the animation. Used to prevent
+webkit/safari from drawing a frame before an animation for elements that animate from display:none.
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'opaque-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+ node.style.opacity = '0';
+ this._effect = new KeyframeEffect(node, [
+ {'opacity': '1'},
+ {'opacity': '1'}
+ ], this.timingFromConfig(config));
+ return this._effect;
+ },
+
+ complete: function(config) {
+ config.node.style.opacity = '';
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/ripple-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/ripple-animation.html
new file mode 100644
index 0000000..fc33f5f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/ripple-animation.html
@@ -0,0 +1,92 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-shared-element-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<ripple-animation>` scales and transform an element such that it appears to ripple from either
+a shared element, or from a screen position, to full screen.
+
+If using as a shared element animation in `<neon-animated-pages>`, use this animation in an `exit`
+animation in the source page and in an `entry` animation in the destination page. Also, define the
+hero elements in the `sharedElements` property (not a configuration property, see
+`Polymer.NeonSharedElementAnimatableBehavior`).
+
+If using a screen position, define the `gesture` property.
+
+Configuration:
+```
+{
+ name: 'ripple-animation`.
+ id: <shared-element-id>, /* set this or gesture */
+ gesture: {x: <page-x>, y: <page-y>}, /* set this or id */
+ timing: <animation-timing>,
+ toPage: <node>, /* define for the destination page */
+ fromPage: <node>, /* define for the source page */
+}
+```
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'ripple-animation',
+
+ behaviors: [
+ Polymer.NeonSharedElementAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var shared = this.findSharedElements(config);
+ if (!shared) {
+ return null;
+ }
+
+ var translateX, translateY;
+ var toRect = shared.to.getBoundingClientRect();
+ if (config.gesture) {
+ translateX = config.gesture.x - (toRect.left + (toRect.width / 2));
+ translateY = config.gesture.y - (toRect.left + (toRect.height / 2));
+ } else {
+ var fromRect = shared.from.getBoundingClientRect();
+ translateX = (fromRect.left + (fromRect.width / 2)) - (toRect.left + (toRect.width / 2));
+ translateY = (fromRect.top + (fromRect.height / 2)) - (toRect.left + (toRect.height / 2));
+ }
+ var translate = 'translate(' + translateX + 'px,' + translateY + 'px)';
+
+ var size = Math.max(toRect.width + Math.abs(translateX) * 2, toRect.height + Math.abs(translateY) * 2);
+ var diameter = Math.sqrt(2 * size * size);
+ var scaleX = diameter / toRect.width;
+ var scaleY = diameter / toRect.height;
+ var scale = 'scale(' + scaleX + ',' + scaleY + ')';
+
+ this.setPrefixedProperty(shared.to, 'transformOrigin', '50% 50%');
+ shared.to.style.borderRadius = '50%';
+
+ this._effect = new KeyframeEffect(shared.to, [
+ {'transform': translate + ' scale(0)'},
+ {'transform': translate + ' ' + scale}
+ ], this.timingFromConfig(config));
+ return this._effect;
+ },
+
+ complete: function() {
+ if (this.sharedElements) {
+ this.setPrefixedProperty(this.sharedElements.to, 'transformOrigin', '');
+ this.sharedElements.to.style.borderRadius = '';
+ }
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/scale-down-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/scale-down-animation.html
new file mode 100644
index 0000000..6dc187b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/scale-down-animation.html
@@ -0,0 +1,65 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<scale-down-animation>` animates the scale transform of an element from 1 to 0. By default it
+scales in both the x and y axes.
+
+Configuration:
+```
+{
+ name: 'scale-down-animation',
+ node: <node>,
+ axis: 'x' | 'y' | '',
+ transformOrigin: <transform-origin>,
+ timing: <animation-timing>
+}
+```
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'scale-down-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+
+ if (config.transformOrigin) {
+ this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
+ }
+
+ var scaleProperty = 'scale(0, 0)';
+ if (config.axis === 'x') {
+ scaleProperty = 'scale(0, 1)';
+ } else if (config.axis === 'y') {
+ scaleProperty = 'scale(1, 0)';
+ }
+
+ this._effect = new KeyframeEffect(node, [
+ {'transform': 'scale(1,1)'},
+ {'transform': scaleProperty}
+ ], this.timingFromConfig(config));
+
+ return this._effect;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/scale-up-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/scale-up-animation.html
new file mode 100644
index 0000000..dd8517f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/scale-up-animation.html
@@ -0,0 +1,65 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<scale-up-animation>` animates the scale transform of an element from 0 to 1. By default it
+scales in both the x and y axes.
+
+Configuration:
+```
+{
+ name: 'scale-up-animation',
+ node: <node>,
+ axis: 'x' | 'y' | '',
+ transformOrigin: <transform-origin>,
+ timing: <animation-timing>
+}
+```
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'scale-up-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+
+ if (config.transformOrigin) {
+ this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
+ }
+
+ var scaleProperty = 'scale(1, 1)';
+ if (config.axis === 'x') {
+ scaleProperty = 'scale(0, 1)';
+ } else if (config.axis === 'y') {
+ scaleProperty = 'scale(1, 0)';
+ }
+
+ this._effect = new KeyframeEffect(node, [
+ {'transform': scaleProperty},
+ {'transform': 'scale(1, 1)'}
+ ], this.timingFromConfig(config));
+
+ return this._effect;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/slide-down-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/slide-down-animation.html
new file mode 100644
index 0000000..83c1f9b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/slide-down-animation.html
@@ -0,0 +1,59 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<slide-down-animation>` animates the transform of an element from `translateY(-100%)` to `none`.
+The `transformOrigin` defaults to `50% 0`.
+
+Configuration:
+```
+{
+ name: 'slide-down-animation',
+ node: <node>,
+ transformOrigin: <transform-origin>,
+ timing: <animation-timing>
+}
+```
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'slide-down-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+
+ if (config.transformOrigin) {
+ this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
+ } else {
+ this.setPrefixedProperty(node, 'transformOrigin', '50% 0');
+ }
+
+ this._effect = new KeyframeEffect(node, [
+ {'transform': 'translateY(-100%)'},
+ {'transform': 'none'}
+ ], this.timingFromConfig(config));
+
+ return this._effect;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/slide-from-left-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/slide-from-left-animation.html
new file mode 100644
index 0000000..d248175
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/slide-from-left-animation.html
@@ -0,0 +1,60 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<slide-from-left-animation>` animates the transform of an element from
+`translateX(-100%)` to `none`.
+The `transformOrigin` defaults to `0 50%`.
+
+Configuration:
+```
+{
+ name: 'slide-from-left-animation',
+ node: <node>,
+ transformOrigin: <transform-origin>,
+ timing: <animation-timing>
+}
+```
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'slide-from-left-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+
+ if (config.transformOrigin) {
+ this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
+ } else {
+ this.setPrefixedProperty(node, 'transformOrigin', '0 50%');
+ }
+
+ this._effect = new KeyframeEffect(node, [
+ {'transform': 'translateX(-100%)'},
+ {'transform': 'none'}
+ ], this.timingFromConfig(config));
+
+ return this._effect;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/slide-from-right-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/slide-from-right-animation.html
new file mode 100644
index 0000000..4ebbf11
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/slide-from-right-animation.html
@@ -0,0 +1,60 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<slide-from-right-animation>` animates the transform of an element from
+`translateX(100%)` to `none`.
+The `transformOrigin` defaults to `0 50%`.
+
+Configuration:
+```
+{
+ name: 'slide-from-right-animation',
+ node: <node>,
+ transformOrigin: <transform-origin>,
+ timing: <animation-timing>
+}
+```
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'slide-from-right-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+
+ if (config.transformOrigin) {
+ this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
+ } else {
+ this.setPrefixedProperty(node, 'transformOrigin', '0 50%');
+ }
+
+ this._effect = new KeyframeEffect(node, [
+ {'transform': 'translateX(100%)'},
+ {'transform': 'none'}
+ ], this.timingFromConfig(config));
+
+ return this._effect;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/slide-left-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/slide-left-animation.html
new file mode 100644
index 0000000..7fbc446
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/slide-left-animation.html
@@ -0,0 +1,59 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<slide-left-animation>` animates the transform of an element from `none` to `translateX(-100%)`.
+The `transformOrigin` defaults to `0 50%`.
+
+Configuration:
+```
+{
+ name: 'slide-left-animation',
+ node: <node>,
+ transformOrigin: <transform-origin>,
+ timing: <animation-timing>
+}
+```
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'slide-left-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+
+ if (config.transformOrigin) {
+ this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
+ } else {
+ this.setPrefixedProperty(node, 'transformOrigin', '0 50%');
+ }
+
+ this._effect = new KeyframeEffect(node, [
+ {'transform': 'none'},
+ {'transform': 'translateX(-100%)'}
+ ], this.timingFromConfig(config));
+
+ return this._effect;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/slide-right-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/slide-right-animation.html
new file mode 100644
index 0000000..e6441c4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/slide-right-animation.html
@@ -0,0 +1,59 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<slide-right-animation>` animates the transform of an element from `none` to `translateX(100%)`.
+The `transformOrigin` defaults to `0 50%`.
+
+Configuration:
+```
+{
+ name: 'slide-right-animation',
+ node: <node>,
+ transformOrigin: <transform-origin>,
+ timing: <animation-timing>
+}
+```
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'slide-right-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+
+ if (config.transformOrigin) {
+ this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
+ } else {
+ this.setPrefixedProperty(node, 'transformOrigin', '0 50%');
+ }
+
+ this._effect = new KeyframeEffect(node, [
+ {'transform': 'none'},
+ {'transform': 'translateX(100%)'}
+ ], this.timingFromConfig(config));
+
+ return this._effect;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/slide-up-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/slide-up-animation.html
new file mode 100644
index 0000000..fdf1186
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/slide-up-animation.html
@@ -0,0 +1,59 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<slide-up-animation>` animates the transform of an element from `translateY(0)` to
+`translateY(-100%)`. The `transformOrigin` defaults to `50% 0`.
+
+Configuration:
+```
+{
+ name: 'slide-up-animation',
+ node: <node>,
+ transformOrigin: <transform-origin>,
+ timing: <animation-timing>
+}
+```
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'slide-up-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ configure: function(config) {
+ var node = config.node;
+
+ if (config.transformOrigin) {
+ this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
+ } else {
+ this.setPrefixedProperty(node, 'transformOrigin', '50% 0');
+ }
+
+ this._effect = new KeyframeEffect(node, [
+ {'transform': 'translate(0)'},
+ {'transform': 'translateY(-100%)'}
+ ], this.timingFromConfig(config));
+
+ return this._effect;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/animations/transform-animation.html b/polymer_1.0.4/bower_components/neon-animation/animations/transform-animation.html
new file mode 100644
index 0000000..e6236a4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/animations/transform-animation.html
@@ -0,0 +1,70 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../neon-animation-behavior.html">
+<link rel="import" href="../web-animations.html">
+
+<!--
+`<slide-down-animation>` animates a custom transform on an element. Use this to animate multiple
+transform properties, or to apply a custom transform value.
+
+Configuration:
+```
+{
+ name: 'slide-down-animation',
+ node: <node>,
+ transformOrigin: <transform-origin>,
+ transformFrom: <transform-from-string>,
+ transformTo: <transform-to-string>,
+ timing: <animation-timing>
+}
+```
+-->
+
+<script>
+
+ Polymer({
+
+ is: 'transform-animation',
+
+ behaviors: [
+ Polymer.NeonAnimationBehavior
+ ],
+
+ /**
+ * @param {{
+ * node: !Element,
+ * transformOrigin: (string|undefined),
+ * transformFrom: (string|undefined),
+ * transformTo: (string|undefined),
+ * timing: (Object|undefined)
+ * }} config
+ */
+ configure: function(config) {
+ var node = config.node;
+ var transformFrom = config.transformFrom || 'none';
+ var transformTo = config.transformTo || 'none';
+
+ if (config.transformOrigin) {
+ this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
+ }
+
+ this._effect = new KeyframeEffect(node, [
+ {'transform': transformFrom},
+ {'transform': transformTo}
+ ], this.timingFromConfig(config));
+
+ return this._effect;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/bower.json b/polymer_1.0.4/bower_components/neon-animation/bower.json
new file mode 100644
index 0000000..aa5c340
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/bower.json
@@ -0,0 +1,51 @@
+{
+ "name": "neon-animation",
+ "version": "1.0.3",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer",
+ "web-animations"
+ ],
+ "main": [
+ "neon-animated-pages.html",
+ "neon-animatable-behavior.html",
+ "neon-animation-behavior.html",
+ "neon-animation-runner-behavior.html",
+ "neon-shared-element-animatable-behavior.html",
+ "neon-shared-element-animation-behavior.html",
+ "neon-animatable.html",
+ "neon-animations.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/neon-animation"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/neon-animation",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-meta": "PolymerElements/iron-meta#^1.0.0",
+ "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.0",
+ "iron-selector": "PolymerElements/iron-selector#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "web-animations-js": "web-animations/web-animations-js#^2.0.0"
+ },
+ "devDependencies": {
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "paper-toolbar": "PolymerElements/paper-toolbar#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "paper-item": "PolymerElements/paper-item#^1.0.0",
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+ "paper-icon-button": "PolymerElements/paper-icon-button#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/declarative/index.html b/polymer_1.0.4/bower_components/neon-animation/demo/declarative/index.html
new file mode 100644
index 0000000..9385bcc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/declarative/index.html
@@ -0,0 +1,108 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>neon-animated-pages demo: declarative</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../neon-animated-pages.html">
+ <link rel="import" href="../../neon-animatable.html">
+ <link rel="import" href="../../neon-animations.html">
+
+ <style>
+
+ body {
+ overflow: hidden;
+ }
+
+ .toolbar {
+ padding: 8px;
+ }
+
+ </style>
+
+ <style is="custom-style">
+
+ neon-animatable {
+ color: white;
+ @apply(--layout-horizontal);
+ @apply(--layout-center-center);
+ @apply(--paper-font-display4);
+ }
+
+ neon-animatable:nth-child(1) {
+ background: var(--paper-red-500);
+ }
+
+ neon-animatable:nth-child(2) {
+ background: var(--paper-blue-500);
+ }
+
+ neon-animatable:nth-child(3) {
+ background: var(--paper-orange-500);
+ }
+
+ neon-animatable:nth-child(4) {
+ background: var(--paper-green-500);
+ }
+
+ neon-animatable:nth-child(5) {
+ background: var(--paper-purple-500);
+ }
+
+ </style>
+
+ </head>
+ <body class="fullbleed layout vertical">
+
+ <template is="dom-bind">
+
+ <div class="toolbar">
+ <button on-click="_onPrevClick"><<</button>
+ <button on-click="_onNextClick">>></button>
+ </div>
+
+ <neon-animated-pages id="pages" class="flex" selected="[[selected]]" entry-animation="[[entryAnimation]]" exit-animation="[[exitAnimation]]">
+ <neon-animatable>1</neon-animatable>
+ <neon-animatable>2</neon-animatable>
+ <neon-animatable>3</neon-animatable>
+ <neon-animatable>4</neon-animatable>
+ <neon-animatable>5</neon-animatable>
+ </neon-animated-pages>
+
+ </template>
+
+ <script>
+
+ var scope = document.querySelector('template[is="dom-bind"]');
+ scope.selected = 0;
+
+ scope._onPrevClick = function() {
+ this.entryAnimation = 'slide-from-left-animation';
+ this.exitAnimation = 'slide-right-animation';
+ this.selected = this.selected === 0 ? 4 : (this.selected - 1);
+ }
+
+ scope._onNextClick = function() {
+ this.entryAnimation = 'slide-from-right-animation';
+ this.exitAnimation = 'slide-left-animation';
+ this.selected = this.selected === 4 ? 0 : (this.selected + 1);
+ }
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/doc/basic.html b/polymer_1.0.4/bower_components/neon-animation/demo/doc/basic.html
new file mode 100644
index 0000000..9e79151
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/doc/basic.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>neon-animation demo: basic</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="my-animatable.html">
+
+ </head>
+ <body>
+
+ <template is="dom-bind">
+
+ <button on-click="_onButtonClick">click me</button>
+ <br>
+ <my-animatable></my-animatable>
+
+ </template>
+
+ <script>
+
+ var scope = document.querySelector('template[is="dom-bind"]');
+
+ scope._onButtonClick = function(event) {
+ var node = document.querySelector('my-animatable');
+ if (node) {
+ node.animate();
+ }
+ };
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/doc/my-animatable.html b/polymer_1.0.4/bower_components/neon-animation/demo/doc/my-animatable.html
new file mode 100644
index 0000000..ec74536
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/doc/my-animatable.html
@@ -0,0 +1,73 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../neon-animation-runner-behavior.html">
+<link rel="import" href="../../animations/scale-down-animation.html">
+
+<dom-module id="my-animatable">
+
+ <style>
+
+ :host {
+ display: inline-block;
+ border-radius: 50%;
+ width: 300px;
+ height: 300px;
+ background: orange;
+ }
+
+ </style>
+
+ <template>
+
+ <content></content>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'my-animatable',
+
+ behaviors: [
+ Polymer.NeonAnimationRunnerBehavior
+ ],
+
+ properties: {
+
+ animationConfig: {
+ type: Object,
+ value: function() {
+ return {
+ name: 'scale-down-animation',
+ node: this
+ }
+ }
+ }
+
+ },
+
+ listeners: {
+ 'neon-animation-finish': '_onNeonAnimationFinish'
+ },
+
+ animate: function() {
+ this.playAnimation();
+ },
+
+ _onNeonAnimationFinish: function() {
+ console.log('animation finish!');
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/doc/my-dialog.html b/polymer_1.0.4/bower_components/neon-animation/demo/doc/my-dialog.html
new file mode 100644
index 0000000..64bb300
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/doc/my-dialog.html
@@ -0,0 +1,97 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../../paper-styles/paper-styles.html">
+<link rel="import" href="../../neon-animation-runner-behavior.html">
+<link rel="import" href="../../animations/scale-up-animation.html">
+<link rel="import" href="../../animations/fade-out-animation.html">
+
+
+<dom-module id="my-dialog">
+
+ <style>
+
+ :host {
+ display: none;
+ padding: 16px;
+ background: white;
+ color: black;
+ margin: 0 auto;
+
+ @apply(--shadow-elevation-2dp);
+ }
+
+ </style>
+
+ <template>
+
+ <content></content>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'my-dialog',
+
+ behaviors: [
+ Polymer.NeonAnimationRunnerBehavior
+ ],
+
+ properties: {
+
+ opened: {
+ type: Boolean
+ },
+
+ animationConfig: {
+ type: Object,
+ value: function() {
+ return {
+ 'entry': [{
+ name: 'scale-up-animation',
+ node: this
+ }],
+ 'exit': [{
+ name: 'fade-out-animation',
+ node: this
+ }]
+ }
+ }
+ }
+
+ },
+
+ listeners: {
+ 'neon-animation-finish': '_onAnimationFinish'
+ },
+
+ _onAnimationFinish: function() {
+ if (!this.opened) {
+ this.style.display = '';
+ }
+ },
+
+ show: function() {
+ this.opened = true;
+ this.style.display = 'inline-block';
+ this.playAnimation('entry');
+ },
+
+ hide: function() {
+ this.opened = false;
+ this.playAnimation('exit');
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/doc/types.html b/polymer_1.0.4/bower_components/neon-animation/demo/doc/types.html
new file mode 100644
index 0000000..3995b6c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/doc/types.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>neon-animation demo: basic</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="my-dialog.html">
+
+ </head>
+ <body>
+
+ <template is="dom-bind">
+
+ <button on-click="_onButtonClick">Toggle</button>
+
+ <div style="text-align: center">
+ <my-dialog>Hello World!</my-dialog>
+ </div>
+
+ </template>
+
+ <script>
+
+ var scope = document.querySelector('template[is="dom-bind"]');
+
+ scope._onButtonClick = function(event) {
+ var node = document.querySelector('my-dialog');
+ if (node) {
+ if (node.opened) {
+ node.hide();
+ } else {
+ node.show();
+ }
+ }
+ };
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/dropdown/animated-dropdown.html b/polymer_1.0.4/bower_components/neon-animation/demo/dropdown/animated-dropdown.html
new file mode 100644
index 0000000..87678f5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/dropdown/animated-dropdown.html
@@ -0,0 +1,97 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../../paper-styles/paper-styles.html">
+<link rel="import" href="../../neon-animation-runner-behavior.html">
+
+
+<dom-module id="animated-dropdown">
+
+ <style>
+
+ :host {
+ display: none;
+ padding: 16px;
+ background: white;
+ color: black;
+
+ @apply(--shadow-elevation-2dp);
+ }
+
+ </style>
+
+ <template>
+
+ <content></content>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'animated-dropdown',
+
+ behaviors: [
+ Polymer.NeonAnimationRunnerBehavior
+ ],
+
+ properties: {
+
+ animationConfig: {
+ type: Object,
+ value: function() {
+ return {
+ 'entry': [{
+ name: 'scale-up-animation',
+ node: this,
+ transformOrigin: '0 0'
+ }],
+ 'exit': [{
+ name: 'fade-out-animation',
+ node: this
+ }]
+ }
+ }
+ },
+
+ _showing: {
+ type: Boolean,
+ value: false
+ }
+
+ },
+
+ listeners: {
+ 'neon-animation-finish': '_onAnimationFinish'
+ },
+
+ _onAnimationFinish: function() {
+ if (this._showing) {
+ } else {
+ this.style.display = '';
+ }
+ },
+
+ show: function() {
+ this.style.display = 'inline-block';
+ this._showing = true;
+ this.playAnimation('entry');
+ },
+
+ hide: function() {
+ this._showing = false;
+ this.playAnimation('exit');
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/dropdown/index.html b/polymer_1.0.4/bower_components/neon-animation/demo/dropdown/index.html
new file mode 100644
index 0000000..34cf821
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/dropdown/index.html
@@ -0,0 +1,54 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>neon-animated-pages demo: dropdown</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../neon-animated-pages.html">
+ <link rel="import" href="../../neon-animations.html">
+ <link rel="import" href="animated-dropdown.html">
+
+ </head>
+ <body>
+
+ <template is="dom-bind">
+
+ <button dropdown-id="dropdown" on-click="_onButtonClick">dropdown</button>
+ <br>
+ <animated-dropdown id="dropdown" on-click="_onDropdownClick">Hello world!</animated-dropdown>
+
+ </template>
+
+ <script>
+
+ var scope = document.querySelector('template[is="dom-bind"]');
+
+ scope._onButtonClick = function(event) {
+ var dropdown = document.querySelector('#' + event.target.getAttribute('dropdown-id'));
+ if (dropdown) {
+ dropdown.show();
+ }
+ };
+
+ scope._onDropdownClick = function(event) {
+ event.target.hide();
+ };
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/grid/animated-grid.html b/polymer_1.0.4/bower_components/neon-animation/demo/grid/animated-grid.html
new file mode 100644
index 0000000..af97675
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/grid/animated-grid.html
@@ -0,0 +1,166 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../../paper-styles/paper-styles.html">
+<link rel="import" href="../../neon-shared-element-animatable-behavior.html">
+
+<dom-module id="animated-grid">
+
+ <link rel="import" type="css" href="../shared.css">
+
+ <style>
+
+ :host {
+ display: block;
+ background: #000;
+ }
+
+ .tile {
+ display: inline-block;
+ float: left;
+ vertical-align: top;
+ width: calc(100% / 6);
+ height: calc(100% / 3);
+
+ @apply(--paper-font-title);
+ @apply(--layout-vertical);
+ @apply(--layout-center-center);
+ }
+
+ .tile:nth-of-type(1) {
+ width: calc(100% / 3);
+ height: calc(100% / 3 * 2);
+ }
+
+ .tile:nth-of-type(4) {
+ width: calc(100% / 3);
+ }
+
+ .tile:nth-of-type(5) {
+ width: calc(100% / 3);
+ height: calc(100% / 3 * 2);
+ }
+
+ .tile:nth-of-type(8) {
+ width: calc(100% / 3);
+ height: calc(100% / 3);
+ }
+
+ .tile:nth-of-type(9) {
+ position: absolute;
+ top: calc(100% / 3 * 2);
+ left: 0;
+ width: calc(100% / 6);
+ height: calc(100% / 3);
+ }
+
+ .tile:nth-of-type(10) {
+ position: absolute;
+ top: calc(100% / 3 * 2);
+ left: calc(100% / 6);;
+ width: calc(100% / 6);
+ height: calc(100% / 3);
+ }
+
+ </style>
+
+ <template>
+
+ <template is="dom-repeat" items="[[config]]">
+ <div class$="[[_computeTileClass(item.color)]]">
+ <span>[[item.value]]</span>
+ </div>
+ </template>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'animated-grid',
+
+ behaviors: [
+ Polymer.NeonSharedElementAnimatableBehavior
+ ],
+
+ properties: {
+
+ config: {
+ type: Array,
+ value: function() {
+ return [
+ {value: 1, color: 'blue'},
+ {value: 2, color: 'red'},
+ {value: 3, color: 'blue'},
+ {value: 4, color: 'green'},
+ {value: 5, color: 'yellow'},
+ {value: 6, color: 'blue'},
+ {value: 7, color: 'red'},
+ {value: 8, color: 'green'},
+ {value: 9, color: 'yellow'},
+ {value: 10, color: 'red'}
+ ]
+ }
+ },
+
+ animationConfig: {
+ type: Object,
+ value: function() {
+ return {
+ 'exit': [{
+ name: 'ripple-animation',
+ id: 'ripple',
+ fromPage: this
+ }, {
+ name: 'hero-animation',
+ id: 'hero',
+ fromPage: this
+ }]
+ }
+ }
+ }
+
+ },
+
+ listeners: {
+ click: '_onClick'
+ },
+
+ _computeTileClass: function(color) {
+ return 'tile ' + color + '-300';
+ },
+
+ _onClick: function(event) {
+ var target = event.target;
+ while (target !== this && !target._templateInstance) {
+ target = target.parentNode;
+ }
+
+ // configure the page animation
+ this.sharedElements = {
+ 'hero': target,
+ 'ripple': target
+ };
+ this.animationConfig['exit'][0].gesture = {
+ x: event.x || event.pageX,
+ y: event.y || event.pageY
+ };
+
+ this.fire('tile-click', {
+ tile: target,
+ data: target._templateInstance.item
+ });
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/grid/fullsize-page-with-card.html b/polymer_1.0.4/bower_components/neon-animation/demo/grid/fullsize-page-with-card.html
new file mode 100644
index 0000000..a365394
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/grid/fullsize-page-with-card.html
@@ -0,0 +1,124 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../neon-shared-element-animatable-behavior.html">
+
+
+<dom-module id="fullsize-page-with-card">
+
+ <link rel="import" type="css" href="../shared.css">
+
+ <style>
+
+ :host {
+ display: block;
+ }
+
+ .fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ height: 100vh;
+ width: 100vw;
+ }
+
+ .card {
+ position: relative;
+ margin: 200px 100px 0;
+ height: 700px;
+ }
+
+ </style>
+
+ <template>
+
+ <div id="fixed" class$="[[_computeFixedBackgroundClass(color)]]"></div>
+
+ <div id="card" class$="[[_computeCardClass(color)]]"></div>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'fullsize-page-with-card',
+
+ behaviors: [
+ Polymer.NeonSharedElementAnimatableBehavior
+ ],
+
+ properties: {
+
+ color: {
+ type: String
+ },
+
+ sharedElements: {
+ type: Object,
+ value: function() {
+ return {
+ 'hero': this.$.card,
+ 'ripple': this.$.fixed
+ }
+ }
+ },
+
+ animationConfig: {
+ type: Object,
+ value: function() {
+ return {
+ 'entry': [{
+ name: 'ripple-animation',
+ id: 'ripple',
+ toPage: this,
+ }, {
+ name: 'hero-animation',
+ id: 'hero',
+ toPage: this,
+ timing: {
+ delay: 150
+ }
+ }],
+ 'exit': [{
+ name: 'fade-out-animation',
+ node: this.$.fixed
+ }, {
+ name: 'transform-animation',
+ transformFrom: 'none',
+ transformTo: 'translate(0px,-200vh) scale(0.9,1)',
+ node: this.$.card
+ }]
+ }
+ }
+ }
+
+ },
+
+ _computeCardClass: function(color) {
+ var cls = 'card';
+ if (color) {
+ cls += ' ' + color + '-300';
+ }
+ return cls;
+ },
+
+ _computeFixedBackgroundClass: function(color) {
+ var cls = 'fixed';
+ if (color) {
+ cls += ' ' + color + '-100';
+ }
+ return cls;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/grid/index.html b/polymer_1.0.4/bower_components/neon-animation/demo/grid/index.html
new file mode 100644
index 0000000..8b34434
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/grid/index.html
@@ -0,0 +1,70 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>neon-animated-pages demo: grid</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../neon-animated-pages.html">
+ <link rel="import" href="../../neon-animations.html">
+ <link rel="import" href="animated-grid.html">
+ <link rel="import" href="fullsize-page-with-card.html">
+
+ <style>
+
+ body {
+ overflow: hidden;
+ }
+
+ neon-animated-pages {
+ height: 100%;
+ }
+
+ </style>
+
+ </head>
+ <body class="fullbleed">
+
+ <template is="dom-bind">
+
+ <neon-animated-pages id="pages" selected="0">
+
+ <animated-grid on-tile-click="_onTileClick"></animated-grid>
+
+ <fullsize-page-with-card id="fullsize-card" hero-id="hero" on-click="_onFullsizeClick">
+ </fullsize-page-with-card>
+
+ </neon-animated-pages>
+
+ </template>
+
+ <script>
+
+ var scope = document.querySelector('template[is="dom-bind"]');
+
+ scope._onTileClick = function(event) {
+ this.$['fullsize-card'].color = event.detail.data.color;
+ this.$.pages.selected = 1;
+ };
+
+ scope._onFullsizeClick = function(event) {
+ this.$.pages.selected = 0;
+ };
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/index.html b/polymer_1.0.4/bower_components/neon-animation/demo/index.html
new file mode 100644
index 0000000..3198424
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/index.html
@@ -0,0 +1,6 @@
+<a href="declarative/index.html">declarative</a><br>
+<a href="dropdown/index.html">dropdown</a><br>
+<a href="grid/index.html">grid</a><br>
+<a href="list/index.html">list</a><br>
+<a href="load/index.html">load</a><br>
+<a href="tiles/index.html">tiles</a><br>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/list/full-view.html b/polymer_1.0.4/bower_components/neon-animation/demo/list/full-view.html
new file mode 100644
index 0000000..817acfa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/list/full-view.html
@@ -0,0 +1,122 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../../paper-styles/paper-styles.html">
+<link rel="import" href="../../neon-animatable-behavior.html">
+
+<dom-module id="full-view">
+
+ <style>
+
+ :host {
+ @apply(--layout-vertical);
+ }
+
+ .main {
+ background: white;
+ @apply(--layout-flex);
+ @apply(--layout-scroll);
+ @apply(--shadow-elevation-8dp);
+ }
+
+ .image-container {
+ position: relative;
+ width: 100%;
+ padding-bottom: 100%;
+ }
+
+ .image {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ background: repeating-linear-gradient(
+ 45deg,
+ #f5f5f5,
+ #f5f5f5 8px,
+ #e0e0e0 8px,
+ #e0e0e0 16px
+ );
+ }
+
+ </style>
+
+ <template>
+
+ <paper-toolbar class="medium-tall">
+ <paper-icon-button id="button" icon="clear" on-click="_onClearButtonClick"></paper-icon-button>
+ </paper-toolbar>
+
+ <div id="main" class="main">
+ <div class="image-container">
+ <div class="image">
+ </div>
+ </div>
+ </div>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'full-view',
+
+ behaviors: [
+ Polymer.NeonAnimatableBehavior
+ ],
+
+ properties: {
+
+ sharedElements: {
+ type: Object,
+ value: function() {
+ return {
+ 'hero': this.$.main
+ };
+ }
+ },
+
+ animationConfig: {
+ type: Object,
+ value: function() {
+ return {
+ 'entry': [{
+ name: 'fade-in-animation',
+ node: this.$.button
+ }, {
+ name: 'hero-animation',
+ id: 'hero',
+ toPage: this
+ }],
+
+ 'exit': [{
+ name: 'fade-out-animation',
+ node: this.$.button
+ }, {
+ name: 'scale-down-animation',
+ node: this.$.main,
+ transformOrigin: '50% 50%',
+ axis: 'y'
+ }]
+
+ }
+ }
+ }
+
+ },
+
+ _onClearButtonClick: function() {
+ this.fire('close');
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/list/index.html b/polymer_1.0.4/bower_components/neon-animation/demo/list/index.html
new file mode 100644
index 0000000..4ee8337
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/list/index.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>neon-animated-pages demo: list</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../../paper-styles/paper-styles.html">
+ <link rel="import" href="list-demo.html">
+
+ </head>
+ <body class="fullbleed relative">
+
+ <list-demo class="fit"></list-demo>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/list/list-demo.html b/polymer_1.0.4/bower_components/neon-animation/demo/list/list-demo.html
new file mode 100644
index 0000000..6658ebf
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/list/list-demo.html
@@ -0,0 +1,112 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../../paper-styles/paper-styles.html">
+<link rel="import" href="../../../paper-toolbar/paper-toolbar.html">
+<link rel="import" href="../../neon-animated-pages.html">
+<link rel="import" href="../../neon-animations.html">
+<link rel="import" href="list-view.html">
+<link rel="import" href="full-view.html">
+
+<dom-module id="list-demo">
+
+ <style>
+
+ :host {
+ display: block;
+ }
+
+ neon-animated-pages {
+ height: 100%;
+ }
+
+ </style>
+
+ <template>
+
+ <neon-animated-pages id="pages" selected="0">
+
+ <list-view data="[[fileData]]" on-item-click="_onItemClick"></list-view>
+
+ <full-view on-close="_onClose"></full-view>
+
+ </neon-animated-pages>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'list-demo',
+
+ properties: {
+
+ fileData: {
+ type: Array,
+ value: function() {
+ return [
+ {fileName: 'IMG_4130.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4131.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4132.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4133.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4134.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4135.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4136.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4137.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4138.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4139.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4140.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4141.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4142.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4143.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4144.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4145.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4146.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4147.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4148.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4149.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4150.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4151.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4152.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4153.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4154.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4155.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4156.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4157.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4158.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4159.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4160.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4161.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4162.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4163.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4164.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4165.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4166.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4167.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4168.jpg', modifiedDate: 'May 12 2015'},
+ {fileName: 'IMG_4169.jpg', modifiedDate: 'May 12 2015'}
+ ]
+ }
+ }
+ },
+
+ _onItemClick: function() {
+ this.$.pages.selected = 1;
+ },
+
+ _onClose: function() {
+ this.$.pages.selected = 0;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/list/list-view.html b/polymer_1.0.4/bower_components/neon-animation/demo/list/list-view.html
new file mode 100644
index 0000000..b23b00d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/list/list-view.html
@@ -0,0 +1,127 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../../iron-icons/iron-icons.html">
+<link rel="import" href="../../../iron-icon/iron-icon.html">
+<link rel="import" href="../../../paper-icon-button/paper-icon-button.html">
+<link rel="import" href="../../../paper-item/paper-item.html">
+<link rel="import" href="../../../paper-item/paper-item-body.html">
+<link rel="import" href="../../../paper-styles/paper-styles.html">
+<link rel="import" href="../../neon-animatable-behavior.html">
+
+<dom-module id="list-view">
+
+ <style>
+
+ :host {
+ @apply(--layout-vertical);
+ }
+
+ .main {
+ @apply(--layout-flex);
+ @apply(--layout-scroll);
+ }
+
+ iron-icon {
+ color: var(--google-grey-500);
+ }
+
+ </style>
+
+ <template>
+
+ <paper-toolbar class="medium-tall">
+ <paper-icon-button id="button" icon="arrow-back"></paper-icon-button>
+ </paper-toolbar>
+
+ <div class="main">
+
+ <template is="dom-repeat" items="[[data]]">
+
+ <paper-item>
+ <paper-item-body two-line>
+ <div>[[item.fileName]]</div>
+ <div secondary>[[item.modifiedDate]]</div>
+ </paper-item-body>
+ <iron-icon icon="info"></iron-icon>
+ </paper-item>
+
+ </template>
+
+ </div>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'list-view',
+
+ behaviors: [
+ Polymer.NeonAnimatableBehavior
+ ],
+
+ listeners: {
+ 'click': '_onClick'
+ },
+
+ properties: {
+
+ data: {
+ type: Array,
+ value: function() {
+ return [];
+ }
+ },
+
+ animationConfig: {
+ type: Object,
+ value: function() {
+ return {
+ 'entry': [{
+ name: 'fade-in-animation',
+ node: this.$.button
+ }],
+
+ 'exit': [{
+ name: 'fade-out-animation',
+ node: this.$.button
+ }, {
+ name: 'hero-animation',
+ id: 'hero',
+ fromPage: this
+ }]
+ };
+ }
+ }
+
+ },
+
+ _onClick: function(event) {
+ var target = event.target;
+ while (target !== this && !target._templateInstance) {
+ target = target.parentNode;
+ }
+
+ // configure the page animation
+ this.sharedElements = {
+ 'hero': target,
+ };
+
+ this.fire('item-click', {
+ item: target,
+ });
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/load/animated-grid.html b/polymer_1.0.4/bower_components/neon-animation/demo/load/animated-grid.html
new file mode 100644
index 0000000..f43851b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/load/animated-grid.html
@@ -0,0 +1,147 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../../paper-styles/paper-styles.html">
+<link rel="import" href="../../neon-shared-element-animatable-behavior.html">
+
+<dom-module id="animated-grid">
+
+ <link rel="import" type="css" href="../shared.css">
+
+ <style>
+
+ :host {
+ display: block;
+ background: #000;
+ }
+
+ .tile {
+ display: inline-block;
+ float: left;
+ vertical-align: top;
+ width: calc(100% / 6);
+ height: calc(100% / 3);
+
+ @apply(--paper-font-title);
+ @apply(--layout-vertical);
+ @apply(--layout-center-center);
+ }
+
+ .tile:nth-of-type(1) {
+ width: calc(100% / 3);
+ height: calc(100% / 3 * 2);
+ }
+
+ .tile:nth-of-type(4) {
+ width: calc(100% / 3);
+ }
+
+ .tile:nth-of-type(5) {
+ width: calc(100% / 3);
+ height: calc(100% / 3 * 2);
+ }
+
+ .tile:nth-of-type(8) {
+ width: calc(100% / 3);
+ height: calc(100% / 3);
+ }
+
+ .tile:nth-of-type(9) {
+ position: absolute;
+ top: calc(100% / 3 * 2);
+ left: 0;
+ width: calc(100% / 6);
+ height: calc(100% / 3);
+ }
+
+ .tile:nth-of-type(10) {
+ position: absolute;
+ top: calc(100% / 3 * 2);
+ left: calc(100% / 6);;
+ width: calc(100% / 6);
+ height: calc(100% / 3);
+ }
+
+ </style>
+
+ <template>
+
+ <template is="dom-repeat" items="[[config]]">
+ <div class$="[[_computeTileClass(item.color)]]">
+ <span>[[item.value]]</span>
+ </div>
+ </template>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'animated-grid',
+
+ behaviors: [
+ Polymer.NeonSharedElementAnimatableBehavior
+ ],
+
+ properties: {
+
+ config: {
+ type: Array,
+ value: function() {
+ return [
+ {value: 1, color: 'blue'},
+ {value: 2, color: 'red'},
+ {value: 3, color: 'blue'},
+ {value: 4, color: 'green'},
+ {value: 5, color: 'yellow'},
+ {value: 6, color: 'blue'},
+ {value: 7, color: 'red'},
+ {value: 8, color: 'green'},
+ {value: 9, color: 'yellow'},
+ {value: 10, color: 'red'}
+ ]
+ }
+ },
+
+ animationConfig: {
+ type: Object,
+ value: function() {
+ return {
+ 'entry': [{
+ name: 'cascaded-animation',
+ animation: 'transform-animation',
+ transformFrom: 'translateY(100%)',
+ transformTo: 'none',
+ timing: {
+ delay: 50
+ }
+ }]
+ }
+ }
+ }
+
+ },
+
+ attached: function() {
+ this.async(function() {
+ var nodeList = Polymer.dom(this.root).querySelectorAll('.tile');
+ this.animationConfig['entry'][0].nodes = Array.prototype.slice.call(nodeList);
+ });
+ },
+
+ _computeTileClass: function(color) {
+ return 'tile ' + color + '-300';
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/load/full-page.html b/polymer_1.0.4/bower_components/neon-animation/demo/load/full-page.html
new file mode 100644
index 0000000..1488de1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/load/full-page.html
@@ -0,0 +1,86 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../../paper-styles/paper-styles.html">
+<link rel="import" href="../../neon-animatable-behavior.html">
+<link rel="import" href="../../neon-animation-runner-behavior.html">
+<link rel="import" href="animated-grid.html">
+
+<dom-module id="full-page">
+
+ <style>
+
+ :host {
+ background: black;
+ visibility: hidden;
+ @apply(--layout-vertical);
+ }
+
+ .toolbar {
+ background: #9c27b0;
+ height: 72px;
+ z-index: 1;
+ @apply(--shadow-elevation-2dp);
+ }
+
+ animated-grid {
+ height: calc(100% - 72px);
+ @apply(--layout-flex);
+ }
+
+ </style>
+
+ <template>
+
+ <div id="toolbar" class="toolbar"></div>
+
+ <animated-grid id="grid"></animated-grid>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+Polymer({
+
+ is: 'full-page',
+
+ behaviors: [
+ Polymer.NeonAnimatableBehavior,
+ Polymer.NeonAnimationRunnerBehavior
+ ],
+
+ properties: {
+
+ animationConfig: {
+ type: Object,
+ value: function() {
+ return {
+ 'entry': [{
+ name: 'slide-down-animation',
+ node: this.$.toolbar
+ }, {
+ animatable: this.$.grid,
+ type: 'entry'
+ }]
+ };
+ }
+ }
+
+ },
+
+ show: function() {
+ this.style.visibility = 'visible';
+ this.playAnimation('entry');
+ }
+
+});
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/load/index.html b/polymer_1.0.4/bower_components/neon-animation/demo/load/index.html
new file mode 100644
index 0000000..3c22281
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/load/index.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>neon-animated-pages demo: load</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../neon-animated-pages.html">
+ <link rel="import" href="../../neon-animations.html">
+ <link rel="import" href="full-page.html">
+
+ <style>
+ body {
+ overflow: hidden;
+ }
+ </style>
+
+ </head>
+ <body class="fullbleed relative">
+
+ <full-page class="fit"></full-page>
+
+ <script>
+
+ document.addEventListener('WebComponentsReady', function() {
+ document.querySelector('full-page').show();
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/reprojection/animated-grid.html b/polymer_1.0.4/bower_components/neon-animation/demo/reprojection/animated-grid.html
new file mode 100644
index 0000000..e65ba51
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/reprojection/animated-grid.html
@@ -0,0 +1,166 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../../paper-styles/paper-styles.html">
+<link rel="import" href="../../neon-shared-element-animatable-behavior.html">
+
+<dom-module id="animated-grid">
+
+ <link rel="import" type="css" href="../shared.css">
+
+ <style>
+
+ :host {
+ display: block;
+ background: #000;
+ }
+
+ .tile {
+ display: inline-block;
+ float: left;
+ vertical-align: top;
+ width: calc(100% / 6);
+ height: calc(100% / 3);
+
+ @apply(--paper-font-title);
+ @apply(--layout-vertical);
+ @apply(--layout-center-center);
+ }
+
+ .tile:nth-of-type(1) {
+ width: calc(100% / 3);
+ height: calc(100% / 3 * 2);
+ }
+
+ .tile:nth-of-type(4) {
+ width: calc(100% / 3);
+ }
+
+ .tile:nth-of-type(5) {
+ width: calc(100% / 3);
+ height: calc(100% / 3 * 2);
+ }
+
+ .tile:nth-of-type(8) {
+ width: calc(100% / 3);
+ height: calc(100% / 3);
+ }
+
+ .tile:nth-of-type(9) {
+ position: absolute;
+ top: calc(100% / 3 * 2);
+ left: 0;
+ width: calc(100% / 6);
+ height: calc(100% / 3);
+ }
+
+ .tile:nth-of-type(10) {
+ position: absolute;
+ top: calc(100% / 3 * 2);
+ left: calc(100% / 6);;
+ width: calc(100% / 6);
+ height: calc(100% / 3);
+ }
+
+ </style>
+
+ <template>
+
+ <template is="dom-repeat" items="[[config]]">
+ <div class$="[[_computeTileClass(item.color)]]">
+ <span>[[item.value]]</span>
+ </div>
+ </template>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'animated-grid',
+
+ behaviors: [
+ Polymer.NeonSharedElementAnimatableBehavior
+ ],
+
+ properties: {
+
+ config: {
+ type: Array,
+ value: function() {
+ return [
+ {value: 1, color: 'blue'},
+ {value: 2, color: 'red'},
+ {value: 3, color: 'blue'},
+ {value: 4, color: 'green'},
+ {value: 5, color: 'yellow'},
+ {value: 6, color: 'blue'},
+ {value: 7, color: 'red'},
+ {value: 8, color: 'green'},
+ {value: 9, color: 'yellow'},
+ {value: 10, color: 'red'}
+ ]
+ }
+ },
+
+ animationConfig: {
+ type: Object,
+ value: function() {
+ return {
+ 'exit': [{
+ name: 'ripple-animation',
+ id: 'ripple',
+ fromPage: this
+ }, {
+ name: 'hero-animation',
+ id: 'hero',
+ fromPage: this
+ }]
+ }
+ }
+ }
+
+ },
+
+ listeners: {
+ click: '_onClick'
+ },
+
+ _computeTileClass: function(color) {
+ return 'tile ' + color + '-300';
+ },
+
+ _onClick: function(event) {
+ var target = event.target;
+ while (target !== this && !target._templateInstance) {
+ target = target.parentNode;
+ }
+
+ // configure the page animation
+ this.sharedElements = {
+ 'hero': target,
+ 'ripple': target
+ };
+ this.animationConfig['exit'][0].gesture = {
+ x: event.x,
+ y: event.y
+ };
+
+ this.fire('tile-click', {
+ tile: target,
+ data: target._templateInstance.item
+ });
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/reprojection/fullsize-page-with-card.html b/polymer_1.0.4/bower_components/neon-animation/demo/reprojection/fullsize-page-with-card.html
new file mode 100644
index 0000000..a365394
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/reprojection/fullsize-page-with-card.html
@@ -0,0 +1,124 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../neon-shared-element-animatable-behavior.html">
+
+
+<dom-module id="fullsize-page-with-card">
+
+ <link rel="import" type="css" href="../shared.css">
+
+ <style>
+
+ :host {
+ display: block;
+ }
+
+ .fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ height: 100vh;
+ width: 100vw;
+ }
+
+ .card {
+ position: relative;
+ margin: 200px 100px 0;
+ height: 700px;
+ }
+
+ </style>
+
+ <template>
+
+ <div id="fixed" class$="[[_computeFixedBackgroundClass(color)]]"></div>
+
+ <div id="card" class$="[[_computeCardClass(color)]]"></div>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'fullsize-page-with-card',
+
+ behaviors: [
+ Polymer.NeonSharedElementAnimatableBehavior
+ ],
+
+ properties: {
+
+ color: {
+ type: String
+ },
+
+ sharedElements: {
+ type: Object,
+ value: function() {
+ return {
+ 'hero': this.$.card,
+ 'ripple': this.$.fixed
+ }
+ }
+ },
+
+ animationConfig: {
+ type: Object,
+ value: function() {
+ return {
+ 'entry': [{
+ name: 'ripple-animation',
+ id: 'ripple',
+ toPage: this,
+ }, {
+ name: 'hero-animation',
+ id: 'hero',
+ toPage: this,
+ timing: {
+ delay: 150
+ }
+ }],
+ 'exit': [{
+ name: 'fade-out-animation',
+ node: this.$.fixed
+ }, {
+ name: 'transform-animation',
+ transformFrom: 'none',
+ transformTo: 'translate(0px,-200vh) scale(0.9,1)',
+ node: this.$.card
+ }]
+ }
+ }
+ }
+
+ },
+
+ _computeCardClass: function(color) {
+ var cls = 'card';
+ if (color) {
+ cls += ' ' + color + '-300';
+ }
+ return cls;
+ },
+
+ _computeFixedBackgroundClass: function(color) {
+ var cls = 'fixed';
+ if (color) {
+ cls += ' ' + color + '-100';
+ }
+ return cls;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/reprojection/index.html b/polymer_1.0.4/bower_components/neon-animation/demo/reprojection/index.html
new file mode 100644
index 0000000..acd196e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/reprojection/index.html
@@ -0,0 +1,66 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>neon-animated-pages demo: grid</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../neon-animations.html">
+ <link rel="import" href="reprojected-pages.html">
+ <link rel="import" href="animated-grid.html">
+ <link rel="import" href="fullsize-page-with-card.html">
+
+ <style>
+
+ neon-animated-pages {
+ height: 100%;
+ }
+
+ </style>
+
+ </head>
+ <body class="fullbleed">
+
+ <template is="dom-bind">
+
+ <reprojected-pages id="pages" selected="0">
+
+ <animated-grid on-tile-click="_onTileClick"></animated-grid>
+
+ <fullsize-page-with-card id="fullsize-card" hero-id="hero" on-click="_onFullsizeClick">
+ </fullsize-page-with-card>
+
+ </reprojected-pages>
+
+ </template>
+
+ <script>
+
+ var scope = document.querySelector('template[is="dom-bind"]');
+
+ scope._onTileClick = function(event) {
+ this.$['fullsize-card'].color = event.detail.data.color;
+ this.$.pages.selected = 1;
+ };
+
+ scope._onFullsizeClick = function(event) {
+ this.$.pages.selected = 0;
+ };
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/reprojection/reprojected-pages.html b/polymer_1.0.4/bower_components/neon-animation/demo/reprojection/reprojected-pages.html
new file mode 100644
index 0000000..647289d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/reprojection/reprojected-pages.html
@@ -0,0 +1,42 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../neon-animated-pages.html">
+
+<dom-module id="reprojected-pages">
+
+ <template>
+
+ <neon-animated-pages selected="{{selected}}">
+ <content></content>
+ </neon-animated-pages>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'reprojected-pages',
+
+ properties: {
+
+ selected: {
+ type: String,
+ notify: true
+ }
+
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/shared.css b/polymer_1.0.4/bower_components/neon-animation/demo/shared.css
new file mode 100644
index 0000000..fc1011f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/shared.css
@@ -0,0 +1,40 @@
+/*
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+*/
+
+.red-100 {
+ background: var(--google-red-100);
+}
+
+.yellow-100 {
+ background: var(--google-yellow-100);
+}
+
+.blue-100 {
+ background: var(--google-blue-100);
+}
+
+.green-100 {
+ background: var(--google-green-100);
+}
+
+.red-300 {
+ background: var(--google-red-300);
+}
+
+.yellow-300 {
+ background: var(--google-yellow-300);
+}
+
+.blue-300 {
+ background: var(--google-blue-300);
+}
+
+.green-300 {
+ background: var(--google-green-300);
+}
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/tiles/circles-page.html b/polymer_1.0.4/bower_components/neon-animation/demo/tiles/circles-page.html
new file mode 100644
index 0000000..566d69b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/tiles/circles-page.html
@@ -0,0 +1,110 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../../paper-styles/paper-styles.html">
+<link rel="import" href="../../neon-shared-element-animatable-behavior.html">
+
+<dom-module id="circles-page">
+
+ <style>
+
+ :host {
+ @apply(--layout-horizontal);
+ @apply(--layout-center-center);
+ }
+
+ .circle {
+ display: inline-block;
+ box-sizing: border-box;
+ width: 100px;
+ height: 100px;
+ margin: 16px;
+ border-radius: 50%;
+ background: var(--color-one);
+ }
+
+ </style>
+
+ <template>
+
+ <div>
+ <div class="circle"></div>
+ <div class="circle"></div>
+ <div class="circle"></div>
+ <div class="circle"></div>
+ </div>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'circles-page',
+
+ behaviors: [
+ Polymer.NeonSharedElementAnimatableBehavior
+ ],
+
+ properties: {
+
+ animationConfig: {
+ value: function() {
+ var circles = Polymer.dom(this.root).querySelectorAll('.circle');
+ var circlesArray = Array.prototype.slice.call(circles);
+ return {
+ 'entry': [{
+ name: 'cascaded-animation',
+ animation: 'scale-up-animation',
+ nodes: circlesArray
+ }],
+
+ 'exit': [{
+ name: 'hero-animation',
+ id: 'hero',
+ fromPage: this
+ }, {
+ name: 'cascaded-animation',
+ animation: 'scale-down-animation'
+ }]
+ };
+ }
+ }
+ },
+
+ listeners: {
+ 'click': '_onClick'
+ },
+
+ _onClick: function(event) {
+ var target = event.target;
+ if (target.classList.contains('circle')) {
+ // configure the page animation
+ this.sharedElements = {
+ 'hero': target
+ };
+
+ var nodesToScale = [];
+ var circles = Polymer.dom(this.root).querySelectorAll('.circle');
+ for (var node, index = 0; node = circles[index]; index++) {
+ if (node !== event.target) {
+ nodesToScale.push(node);
+ }
+ }
+ this.animationConfig['exit'][1].nodes = nodesToScale;
+
+ this.fire('circle-click');
+ }
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/tiles/index.html b/polymer_1.0.4/bower_components/neon-animation/demo/tiles/index.html
new file mode 100644
index 0000000..0afec46
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/tiles/index.html
@@ -0,0 +1,77 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>neon-animated-pages demo: tiles</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../neon-animated-pages.html">
+ <link rel="import" href="../../neon-animations.html">
+ <link rel="import" href="circles-page.html">
+ <link rel="import" href="squares-page.html">
+
+ <style>
+
+ body {
+ overflow: hidden;
+ }
+
+ neon-animated-pages {
+ height: 100%;
+ }
+
+ </style>
+
+ <style is="custom-style">
+
+ :root {
+ --color-one: #4dd0e1;
+ --color-two: #ff9800;
+ }
+
+ </style>
+
+ </head>
+ <body class="fullbleed">
+
+ <template is="dom-bind">
+
+ <neon-animated-pages id="pages" selected="0">
+
+ <circles-page on-circle-click="_onCircleClick"></circles-page>
+
+ <squares-page on-click="_onSquaresClick"></squares-page>
+
+ </neon-animated-pages>
+
+ </template>
+
+ <script>
+
+ var scope = document.querySelector('template[is="dom-bind"]');
+
+ scope._onCircleClick = function(event) {
+ this.$.pages.selected = 1;
+ };
+
+ scope._onSquaresClick = function(event) {
+ this.$.pages.selected = 0;
+ };
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/neon-animation/demo/tiles/squares-page.html b/polymer_1.0.4/bower_components/neon-animation/demo/tiles/squares-page.html
new file mode 100644
index 0000000..f417e6b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/demo/tiles/squares-page.html
@@ -0,0 +1,104 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../../polymer/polymer.html">
+<link rel="import" href="../../../paper-styles/paper-styles.html">
+<link rel="import" href="../../neon-shared-element-animatable-behavior.html">
+
+<dom-module id="squares-page">
+
+ <style>
+
+ .header {
+ height: 40%;
+ background: var(--color-one);
+ }
+
+ .body {
+ text-align: center;
+ padding: 8px;
+ }
+
+ .square {
+ display: inline-block;
+ width: 150px;
+ height: 150px;
+ margin: 8px;
+ background: var(--color-two);
+ }
+
+ </style>
+
+ <template>
+
+ <div id="header" class="header"></div>
+
+ <div class="body">
+ <div class="square"></div>
+ <div class="square"></div>
+ <div class="square"></div>
+ <div class="square"></div>
+ </div>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'squares-page',
+
+ behaviors: [
+ Polymer.NeonSharedElementAnimatableBehavior
+ ],
+
+ properties: {
+
+ sharedElements: {
+ value: function() {
+ return {
+ 'hero': this.$.header
+ }
+ }
+ },
+
+ animationConfig: {
+ value: function() {
+ var squares = Polymer.dom(this.root).querySelectorAll('.square');
+ var squaresArray = Array.prototype.slice.call(squares);
+ return {
+ 'entry': [{
+ name: 'hero-animation',
+ id: 'hero',
+ toPage: this
+ }, {
+ name: 'cascaded-animation',
+ animation: 'transform-animation',
+ transformFrom: 'translateY(100%)',
+ nodes: squaresArray
+ }],
+
+ 'exit': [{
+ name: 'slide-up-animation',
+ node: this.$.header
+ }, {
+ name: 'cascaded-animation',
+ animation: 'transform-animation',
+ transformTo: 'translateY(60vh)',
+ nodes: squaresArray
+ }]
+ };
+ }
+ }
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/guides/neon-animation.md b/polymer_1.0.4/bower_components/neon-animation/guides/neon-animation.md
new file mode 100644
index 0000000..7af1659
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/guides/neon-animation.md
@@ -0,0 +1,313 @@
+---
+title: neon-animation
+summary: "A short guide to neon-animation and neon-animated-pages"
+tags: ['animation','core-animated-pages']
+elements: ['neon-animation','neon-animated-pages']
+updated: 2015-05-26
+---
+
+# neon-animation
+
+`neon-animation` is a suite of elements and behaviors to implement pluggable animated transitions for Polymer Elements using [Web Animations](https://w3c.github.io/web-animations/).
+
+*Warning: The API may change.*
+
+* [A basic animatable element](#basic)
+* [Animation configuration](#configuration)
+ * [Animation types](#configuration-types)
+ * [Configuration properties](#configuration-properties)
+ * [Using multiple animations](#configuration-multiple)
+ * [Running animations encapsulated in children nodes](#configuration-encapsulation)
+* [Page transitions](#page-transitions)
+ * [Shared element animations](#shared-element)
+ * [Declarative page transitions](#declarative-page)
+* [Included animations](#animations)
+* [Demos](#demos)
+
+<a name="basic"></a>
+## A basic animatable element
+
+Elements that can be animated should implement the `Polymer.NeonAnimatableBehavior` behavior, or `Polymer.NeonAnimationRunnerBehavior` if they're also responsible for running an animation.
+
+```js
+Polymer({
+ is: 'my-animatable',
+ behaviors: [
+ Polymer.NeonAnimationRunnerBehavior
+ ],
+ properties: {
+ animationConfig: {
+ value: function() {
+ return {
+ // provided by neon-animation/animations/scale-down-animation.html
+ name: 'scale-down-animation',
+ node: this
+ }
+ }
+ }
+ },
+ listeners: {
+ // this event is fired when the animation finishes
+ 'neon-animation-finish': '_onNeonAnimationFinish'
+ },
+ animate: function() {
+ // run scale-down-animation
+ this.playAnimation();
+ },
+ _onNeonAnimationFinish: function() {
+ console.log('animation done!');
+ }
+});
+```
+
+[Live demo](http://morethanreal.github.io/neon-animation-demo/bower_components/neon-animation/demo/doc/basic.html)
+
+<a name="configuration"></a>
+## Animation configuration
+
+<a name="configuration-types"></a>
+### Animation types
+
+An element might run different animations, for example it might do something different when it enters the view and when it exits from view. You can set the `animationConfig` property to a map from an animation type to configuration.
+
+```js
+Polymer({
+ is: 'my-dialog',
+ behaviors: [
+ Polymer.NeonAnimationRunnerBehavior
+ ],
+ properties: {
+ opened: {
+ type: Boolean
+ },
+ animationConfig: {
+ value: function() {
+ return {
+ 'entry': {
+ // provided by neon-animation/animations/scale-up-animation.html
+ name: 'scale-up-animation',
+ node: this
+ },
+ 'exit': {
+ // provided by neon-animation-animations/fade-out-animation.html
+ name: 'fade-out-animation',
+ node: this
+ }
+ }
+ }
+ }
+ },
+ listeners: {
+ 'neon-animation-finish': '_onNeonAnimationFinish'
+ },
+ show: function() {
+ this.opened = true;
+ this.style.display = 'inline-block';
+ // run scale-up-animation
+ this.playAnimation('entry');
+ },
+ hide: function() {
+ this.opened = false;
+ // run fade-out-animation
+ this.playAnimation('fade-out-animation');
+ },
+ _onNeonAnimationFinish: function() {
+ if (!this.opened) {
+ this.style.display = 'none';
+ }
+ }
+});
+```
+
+[Live demo](http://morethanreal.github.io/neon-animation-demo/bower_components/neon-animation/demo/doc/types.html)
+
+You can also use the convenience properties `entryAnimation` and `exitAnimation` to set `entry` and `exit` animations:
+
+```js
+properties: {
+ entryAnimation: {
+ value: 'scale-up-animation'
+ },
+ exitAnimation: {
+ value: 'fade-out-animation'
+ }
+}
+```
+
+<a name="configuration-properties"></a>
+### Configuration properties
+
+You can pass additional parameters to configure an animation in the animation configuration object.
+All animations should accept the following properties:
+
+ * `name`: The name of an animation, ie. an element implementing `Polymer.NeonAnimationBehavior`.
+ * `node`: The target node to apply the animation to. Defaults to `this`.
+ * `timing`: Timing properties to use in this animation. They match the [Web Animations Animation Effect Timing interface](https://w3c.github.io/web-animations/#the-animationeffecttiming-interface). The
+ properties include the following:
+ * `duration`: The duration of the animation in milliseconds.
+ * `delay`: The delay before the start of the animation in milliseconds.
+ * `easing`: A timing function for the animation. Matches the CSS timing function values.
+
+Animations may define additional configuration properties and they are listed in their documentation.
+
+<a name="configuration-multiple"></a>
+### Using multiple animations
+
+Set the animation configuration to an array to combine animations, like this:
+
+```js
+animationConfig: {
+ value: function() {
+ return {
+ // fade-in-animation is run with a 50ms delay from slide-down-animation
+ 'entry': [{
+ name: 'slide-down-animation',
+ node: this
+ }, {
+ name: 'fade-in-animation',
+ node: this,
+ timing: {delay: 50}
+ }]
+ }
+ }
+}
+```
+
+<a name="configuration-encapsulation"></a>
+### Running animations encapsulated in children nodes
+
+You can include animations in the configuration that are encapsulated in a child element that implement `Polymer.NeonAnimatableBehavior` with the `animatable` property.
+
+```js
+animationConfig: {
+ value: function() {
+ return {
+ // run fade-in-animation on this, and the entry animation on this.$.myAnimatable
+ 'entry': [
+ {name: 'fade-in-animation', node: this},
+ {animatable: this.$.myAnimatable, type: 'entry'}
+ ]
+ }
+ }
+}
+```
+
+<a name="page-transitions"></a>
+## Page transitions
+
+*The artist formerly known as `<core-animated-pages>`*
+
+The `neon-animated-pages` element manages a set of pages to switch between, and runs animations between the page transitions. It implements the `Polymer.IronSelectableBehavior` behavior. Each child node should implement `Polymer.NeonAnimatableBehavior` and define the `entry` and `exit` animations. During a page transition, the `entry` animation is run on the new page and the `exit` animation is run on the old page.
+
+<a name="shared-element"></a>
+### Shared element animations
+
+Shared element animations work on multiple nodes. For example, a "hero" animation is used during a page transition to make two elements from separate pages appear to animate as a single element. Shared element animation configurations have an `id` property that identify they belong in the same animation. Elements containing shared elements also have a `sharedElements` property defines a map from `id` to element, the element involved with the animation.
+
+In the incoming page:
+
+```js
+properties: {
+ animationConfig: {
+ value: function() {
+ return {
+ // the incoming page defines the 'entry' animation
+ 'entry': {
+ name: 'hero-animation',
+ id: 'hero',
+ toPage: this
+ }
+ }
+ }
+ },
+ sharedElements: {
+ value: function() {
+ return {
+ 'hero': this.$.hero
+ }
+ }
+ }
+}
+```
+
+In the outgoing page:
+
+```js
+properties: {
+ animationConfig: {
+ value: function() {
+ return {
+ // the outgoing page defines the 'exit' animation
+ 'exit': {
+ name: 'hero-animation',
+ id: 'hero',
+ fromPage: this
+ }
+ }
+ }
+ },
+ sharedElements: {
+ value: function() {
+ return {
+ 'hero': this.$.otherHero
+ }
+ }
+ }
+}
+```
+
+<a name="declarative-page"></a>
+### Declarative page transitions
+
+For convenience, if you define the `entry-animation` and `exit-animation` attributes on `<neon-animated-pages>`, those animations will apply for all page transitions.
+
+For example:
+
+```js
+<neon-animated-pages id="pages" class="flex" selected="[[selected]]" entry-animation="slide-from-right-animation" exit-animation="slide-left-animation">
+ <neon-animatable>1</neon-animatable>
+ <neon-animatable>2</neon-animatable>
+ <neon-animatable>3</neon-animatable>
+ <neon-animatable>4</neon-animatable>
+ <neon-animatable>5</neon-animatable>
+</neon-animated-pages>
+```
+
+The new page will slide in from the right, and the old page slide away to the left.
+
+<a name="animations"></a>
+## Included animations
+
+Single element animations:
+
+ * `fade-in-animation` Animates opacity from `0` to `1`.
+ * `fade-out-animation` Animates opacity from `1` to `0`.
+ * `scale-down-animation` Animates transform from `scale(1)` to `scale(0)`.
+ * `scale-up-animation` Animates transform from `scale(0)` to `scale(1)`.
+ * `slide-down-animation` Animates transform from `translateY(-100%)` to `none`.
+ * `slide-up-animation` Animates transform from `none` to `translateY(-100%)`.
+ * `slide-left-animation` Animates transform from `none` to `translateX(-100%)`;
+ * `slide-right-animation` Animates transform from `none` to `translateX(100%)`;
+ * `slide-from-left-animation` Animates transform from `translateX(-100%)` to `none`;
+ * `slide-from-right-animation` Animates transform from `translateX(100%)` to `none`;
+
+ * `transform-animation` Animates a custom transform.
+
+Note that there is a restriction that only one transform animation can be applied on the same element at a time. Use the custom `transform-animation` to combine transform properties.
+
+Shared element animations
+
+ * `hero-animation` Animates an element such that it looks like it scales and transforms from another element.
+ * `ripple-animation` Animates an element to full screen such that it looks like it ripples from another element.
+
+Group animations
+ * `cascaded-animation` Applys an animation to an array of elements with a delay between each.
+
+<a name="demos"></a>
+## Demos
+
+ * [Grid to full screen](http://morethanreal.github.io/neon-animation-demo/bower_components/neon-animation/demo/grid/index.html)
+ * [Animation on load](http://morethanreal.github.io/neon-animation-demo/bower_components/neon-animation/demo/load/index.html)
+ * [List item to detail](http://morethanreal.github.io/neon-animation-demo/bower_components/neon-animation/demo/list/index.html) (For narrow width)
+ * [Dots to squares](http://morethanreal.github.io/neon-animation-demo/bower_components/neon-animation/demo/tiles/index.html)
+ * [Declarative](http://morethanreal.github.io/neon-animation-demo/bower_components/neon-animation/demo/declarative/index.html)
diff --git a/polymer_1.0.4/bower_components/neon-animation/index.html b/polymer_1.0.4/bower_components/neon-animation/index.html
new file mode 100644
index 0000000..6f5feed
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>neon-animation</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/neon-animation/neon-animatable-behavior.html b/polymer_1.0.4/bower_components/neon-animation/neon-animatable-behavior.html
new file mode 100644
index 0000000..fac56f8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/neon-animatable-behavior.html
@@ -0,0 +1,156 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="animations/opaque-animation.html">
+
+<script>
+
+ /**
+ * `Polymer.NeonAnimatableBehavior` is implemented by elements containing animations for use with
+ * elements implementing `Polymer.NeonAnimationRunnerBehavior`.
+ * @polymerBehavior
+ */
+ Polymer.NeonAnimatableBehavior = {
+
+ properties: {
+
+ /**
+ * Animation configuration. See README for more info.
+ */
+ animationConfig: {
+ type: Object
+ },
+
+ /**
+ * Convenience property for setting an 'entry' animation. Do not set `animationConfig.entry`
+ * manually if using this. The animated node is set to `this` if using this property.
+ */
+ entryAnimation: {
+ observer: '_entryAnimationChanged',
+ type: String
+ },
+
+ /**
+ * Convenience property for setting an 'exit' animation. Do not set `animationConfig.exit`
+ * manually if using this. The animated node is set to `this` if using this property.
+ */
+ exitAnimation: {
+ observer: '_exitAnimationChanged',
+ type: String
+ }
+
+ },
+
+ _entryAnimationChanged: function() {
+ this.animationConfig = this.animationConfig || {};
+ if (this.entryAnimation !== 'fade-in-animation') {
+ // insert polyfill hack
+ this.animationConfig['entry'] = [{
+ name: 'opaque-animation',
+ node: this
+ }, {
+ name: this.entryAnimation,
+ node: this
+ }];
+ } else {
+ this.animationConfig['entry'] = [{
+ name: this.entryAnimation,
+ node: this
+ }];
+ }
+ },
+
+ _exitAnimationChanged: function() {
+ this.animationConfig = this.animationConfig || {};
+ this.animationConfig['exit'] = [{
+ name: this.exitAnimation,
+ node: this
+ }];
+ },
+
+ _copyProperties: function(config1, config2) {
+ // shallowly copy properties from config2 to config1
+ for (var property in config2) {
+ config1[property] = config2[property];
+ }
+ },
+
+ _cloneConfig: function(config) {
+ var clone = {
+ isClone: true
+ };
+ this._copyProperties(clone, config);
+ return clone;
+ },
+
+ _getAnimationConfigRecursive: function(type, map, allConfigs) {
+ if (!this.animationConfig) {
+ return;
+ }
+
+ // type is optional
+ var thisConfig;
+ if (type) {
+ thisConfig = this.animationConfig[type];
+ } else {
+ thisConfig = this.animationConfig;
+ }
+
+ if (!Array.isArray(thisConfig)) {
+ thisConfig = [thisConfig];
+ }
+
+ // iterate animations and recurse to process configurations from child nodes
+ if (thisConfig) {
+ for (var config, index = 0; config = thisConfig[index]; index++) {
+ if (config.animatable) {
+ config.animatable._getAnimationConfigRecursive(config.type || type, map, allConfigs);
+ } else {
+ if (config.id) {
+ var cachedConfig = map[config.id];
+ if (cachedConfig) {
+ // merge configurations with the same id, making a clone lazily
+ if (!cachedConfig.isClone) {
+ map[config.id] = this._cloneConfig(cachedConfig)
+ cachedConfig = map[config.id];
+ }
+ this._copyProperties(cachedConfig, config);
+ } else {
+ // put any configs with an id into a map
+ map[config.id] = config;
+ }
+ } else {
+ allConfigs.push(config);
+ }
+ }
+ }
+ }
+ },
+
+ /**
+ * An element implementing `Polymer.NeonAnimationRunnerBehavior` calls this method to configure
+ * an animation with an optional type. Elements implementing `Polymer.NeonAnimatableBehavior`
+ * should define the property `animationConfig`, which is either a configuration object
+ * or a map of animation type to array of configuration objects.
+ */
+ getAnimationConfig: function(type) {
+ var map = [];
+ var allConfigs = [];
+ this._getAnimationConfigRecursive(type, map, allConfigs);
+ // append the configurations saved in the map to the array
+ for (var key in map) {
+ allConfigs.push(map[key]);
+ }
+ return allConfigs;
+ }
+
+ };
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/neon-animatable.html b/polymer_1.0.4/bower_components/neon-animation/neon-animatable.html
new file mode 100644
index 0000000..6db9d83
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/neon-animatable.html
@@ -0,0 +1,54 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="neon-animatable-behavior.html">
+
+<!--
+`<neon-animatable>` is a simple container element implementing `Polymer.NeonAnimatableBehavior`. This is a convenience element for use with `<neon-animated-pages>`.
+
+```
+<neon-animated-pages selected="0"
+ entry-animation="slide-from-right-animation"
+ exit-animation="slide-left-animation">
+ <neon-animatable>1</neon-animatable>
+ <neon-animatable>2</neon-animatable>
+</neon-animated-pages>
+```
+-->
+
+<dom-module id="neon-animatable">
+
+ <style>
+
+ :host {
+ display: block;
+ }
+
+ </style>
+
+ <template>
+ <content></content>
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'neon-animatable',
+
+ behaviors: [
+ Polymer.NeonAnimatableBehavior
+ ]
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/neon-animated-pages.html b/polymer_1.0.4/bower_components/neon-animation/neon-animated-pages.html
new file mode 100644
index 0000000..de73f76
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/neon-animated-pages.html
@@ -0,0 +1,212 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html">
+<link rel="import" href="../iron-selector/iron-selectable.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+<link rel="import" href="neon-animation-runner-behavior.html">
+<link rel="import" href="animations/opaque-animation.html">
+
+<!--
+`neon-animated-pages` manages a set of pages and runs an animation when switching between them. Its
+children pages should implement `Polymer.NeonAnimatableBehavior` and define `entry` and `exit`
+animations to be run when switching to or switching out of the page.
+
+@group Neon Elements
+@element neon-animated-pages
+@demo demo/index.html
+-->
+
+<dom-module id="neon-animated-pages">
+
+ <style>
+
+ :host {
+ display: block;
+ position: relative;
+ }
+
+ :host > ::content > * {
+ @apply(--layout-fit);
+ height: 100%;
+ }
+
+ :host > ::content > :not(.iron-selected):not(.neon-animating) {
+ display: none !important;
+ }
+
+ :host > ::content > .neon-animating {
+ pointer-events: none;
+ }
+
+ </style>
+
+ <template>
+ <content id="content"></content>
+ </template>
+
+</dom-module>
+
+<script>
+(function() {
+
+ Polymer({
+
+ is: 'neon-animated-pages',
+
+ behaviors: [
+ Polymer.IronResizableBehavior,
+ Polymer.IronSelectableBehavior,
+ Polymer.NeonAnimationRunnerBehavior
+ ],
+
+ properties: {
+
+ activateEvent: {
+ type: String,
+ value: ''
+ },
+
+ // if true, the initial page selection will also be animated according to its animation config.
+ animateInitialSelection: {
+ type: Boolean,
+ value: false
+ }
+
+ },
+
+ observers: [
+ '_selectedChanged(selected)'
+ ],
+
+ listeners: {
+ 'neon-animation-finish': '_onNeonAnimationFinish'
+ },
+
+ _selectedChanged: function(selected) {
+
+ var selectedPage = this.selectedItem;
+ var oldPage = this._prevSelected || false;
+ this._prevSelected = selectedPage;
+
+ // on initial load and if animateInitialSelection is negated, simply display selectedPage.
+ if (!oldPage && !this.animateInitialSelection) {
+ this._completeSelectedChanged();
+ return;
+ }
+
+ // insert safari fix.
+ this.animationConfig = [{
+ name: 'opaque-animation',
+ node: selectedPage
+ }];
+
+ // configure selectedPage animations.
+ if (this.entryAnimation) {
+ this.animationConfig.push({
+ name: this.entryAnimation,
+ node: selectedPage
+ });
+ } else {
+ if (selectedPage.getAnimationConfig) {
+ this.animationConfig.push({
+ animatable: selectedPage,
+ type: 'entry'
+ });
+ }
+ }
+
+ // configure oldPage animations iff exists.
+ if (oldPage) {
+
+ // cancel the currently running animation if one is ongoing.
+ if (oldPage.classList.contains('neon-animating')) {
+ this._squelchNextFinishEvent = true;
+ this.cancelAnimation();
+ this._completeSelectedChanged();
+ }
+
+ // configure the animation.
+ if (this.exitAnimation) {
+ this.animationConfig.push({
+ name: this.exitAnimation,
+ node: oldPage
+ });
+ } else {
+ if (oldPage.getAnimationConfig) {
+ this.animationConfig.push({
+ animatable: oldPage,
+ type: 'exit'
+ });
+ }
+ }
+
+ // display the oldPage during the transition.
+ oldPage.classList.add('neon-animating');
+ }
+
+ // display the selectedPage during the transition.
+ selectedPage.classList.add('neon-animating');
+
+ // actually run the animations.
+ if (this.animationConfig.length > 1) {
+
+ // on first load, ensure we run animations only after element is attached.
+ if (!this.isAttached) {
+ this.async(function () {
+ this.playAnimation(undefined, {
+ fromPage: null,
+ toPage: selectedPage
+ });
+ });
+
+ } else {
+ this.playAnimation(undefined, {
+ fromPage: oldPage,
+ toPage: selectedPage
+ });
+ }
+
+ } else {
+ this._completeSelectedChanged(oldPage, selectedPage);
+ }
+ },
+
+ /**
+ * @param {Object=} oldPage
+ * @param {Object=} selectedPage
+ */
+ _completeSelectedChanged: function(oldPage, selectedPage) {
+ if (selectedPage) {
+ selectedPage.classList.remove('neon-animating');
+ }
+ if (oldPage) {
+ oldPage.classList.remove('neon-animating');
+ }
+ if (!selectedPage || !oldPage) {
+ var nodes = Polymer.dom(this.$.content).getDistributedNodes();
+ for (var node, index = 0; node = nodes[index]; index++) {
+ node.classList && node.classList.remove('neon-animating');
+ }
+ }
+ this.async(this.notifyResize);
+ },
+
+ _onNeonAnimationFinish: function(event) {
+ if (this._squelchNextFinishEvent) {
+ this._squelchNextFinishEvent = false;
+ return;
+ }
+ this._completeSelectedChanged(event.detail.fromPage, event.detail.toPage);
+ }
+
+ })
+
+})();
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/neon-animation-behavior.html b/polymer_1.0.4/bower_components/neon-animation/neon-animation-behavior.html
new file mode 100644
index 0000000..107d753
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/neon-animation-behavior.html
@@ -0,0 +1,85 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-meta/iron-meta.html">
+
+<script>
+
+ /**
+ * Use `Polymer.NeonAnimationBehavior` to implement an animation.
+ * @polymerBehavior
+ */
+ Polymer.NeonAnimationBehavior = {
+
+ properties: {
+
+ /**
+ * Defines the animation timing.
+ */
+ animationTiming: {
+ type: Object,
+ value: function() {
+ return {
+ duration: 500,
+ easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
+ fill: 'both'
+ }
+ }
+ }
+
+ },
+
+ registered: function() {
+ new Polymer.IronMeta({type: 'animation', key: this.is, value: this.constructor});
+ },
+
+ /**
+ * Do any animation configuration here.
+ */
+ // configure: function(config) {
+ // },
+
+ /**
+ * Returns the animation timing by mixing in properties from `config` to the defaults defined
+ * by the animation.
+ */
+ timingFromConfig: function(config) {
+ if (config.timing) {
+ for (var property in config.timing) {
+ this.animationTiming[property] = config.timing[property];
+ }
+ }
+ return this.animationTiming;
+ },
+
+ /**
+ * Sets `transform` and `transformOrigin` properties along with the prefixed versions.
+ */
+ setPrefixedProperty: function(node, property, value) {
+ var map = {
+ 'transform': ['webkitTransform'],
+ 'transformOrigin': ['mozTransformOrigin', 'webkitTransformOrigin']
+ };
+ var prefixes = map[property];
+ for (var prefix, index = 0; prefix = prefixes[index]; index++) {
+ node.style[prefix] = value;
+ }
+ node.style[property] = value;
+ },
+
+ /**
+ * Called when the animation finishes.
+ */
+ complete: function() {}
+
+ };
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/neon-animation-runner-behavior.html b/polymer_1.0.4/bower_components/neon-animation/neon-animation-runner-behavior.html
new file mode 100644
index 0000000..9f89a9e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/neon-animation-runner-behavior.html
@@ -0,0 +1,113 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-meta/iron-meta.html">
+<link rel="import" href="neon-animatable-behavior.html">
+
+<script>
+
+ /**
+ * `Polymer.NeonAnimationRunnerBehavior` adds a method to run animations.
+ * @polymerBehavior
+ */
+ Polymer.NeonAnimationRunnerBehavior = [Polymer.NeonAnimatableBehavior, {
+
+ properties: {
+
+ _animationMeta: {
+ type: Object,
+ value: function() {
+ return new Polymer.IronMeta({type: 'animation'});
+ }
+ },
+
+ /** @type {?Object} */
+ _player: {
+ type: Object
+ }
+
+ },
+
+ _configureAnimationEffects: function(allConfigs) {
+ var allAnimations = [];
+ if (allConfigs.length > 0) {
+ for (var config, index = 0; config = allConfigs[index]; index++) {
+ var animationConstructor = this._animationMeta.byKey(config.name);
+ if (animationConstructor) {
+ var animation = animationConstructor && new animationConstructor();
+ var effect = animation.configure(config);
+ if (effect) {
+ allAnimations.push({
+ animation: animation,
+ config: config,
+ effect: effect
+ });
+ }
+ } else {
+ console.warn(this.is + ':', config.name, 'not found!');
+ }
+ }
+ }
+ return allAnimations;
+ },
+
+ _runAnimationEffects: function(allEffects) {
+ return document.timeline.play(new GroupEffect(allEffects));
+ },
+
+ _completeAnimations: function(allAnimations) {
+ for (var animation, index = 0; animation = allAnimations[index]; index++) {
+ animation.animation.complete(animation.config);
+ }
+ },
+
+ /**
+ * Plays an animation with an optional `type`.
+ * @param {string=} type
+ * @param {!Object=} cookie
+ */
+ playAnimation: function(type, cookie) {
+ var allConfigs = this.getAnimationConfig(type);
+ if (!allConfigs) {
+ return;
+ }
+ var allAnimations = this._configureAnimationEffects(allConfigs);
+ var allEffects = allAnimations.map(function(animation) {
+ return animation.effect;
+ });
+
+ if (allEffects.length > 0) {
+ this._player = this._runAnimationEffects(allEffects);
+ this._player.onfinish = function() {
+ this._completeAnimations(allAnimations);
+
+ if (this._player) {
+ this._player.cancel();
+ this._player = null;
+ }
+
+ this.fire('neon-animation-finish', cookie, {bubbles: false});
+ }.bind(this);
+
+ } else {
+ this.fire('neon-animation-finish', cookie, {bubbles: false});
+ }
+ },
+
+ /**
+ * Cancels the currently running animation.
+ */
+ cancelAnimation: function() {
+ if (this._player) {
+ this._player.cancel();
+ }
+ }
+
+ }];
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/neon-animation.html b/polymer_1.0.4/bower_components/neon-animation/neon-animation.html
new file mode 100644
index 0000000..150068a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/neon-animation.html
@@ -0,0 +1,17 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="neon-animatable-behavior.html">
+<link rel="import" href="neon-animated-pages.html">
+<link rel="import" href="neon-animatable.html">
+<link rel="import" href="neon-animation-behavior.html">
+<link rel="import" href="neon-animation-runner-behavior.html">
+<link rel="import" href="neon-animations.html">
+<link rel="import" href="neon-shared-element-animatable-behavior.html">
+<link rel="import" href="neon-shared-element-animation-behavior.html">
diff --git a/polymer_1.0.4/bower_components/neon-animation/neon-animations.html b/polymer_1.0.4/bower_components/neon-animation/neon-animations.html
new file mode 100644
index 0000000..f3bdf49
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/neon-animations.html
@@ -0,0 +1,25 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="animations/cascaded-animation.html">
+<link rel="import" href="animations/fade-in-animation.html">
+<link rel="import" href="animations/fade-out-animation.html">
+<link rel="import" href="animations/hero-animation.html">
+<link rel="import" href="animations/opaque-animation.html">
+<link rel="import" href="animations/ripple-animation.html">
+<link rel="import" href="animations/scale-down-animation.html">
+<link rel="import" href="animations/scale-up-animation.html">
+<link rel="import" href="animations/slide-from-left-animation.html">
+<link rel="import" href="animations/slide-from-right-animation.html">
+<link rel="import" href="animations/slide-left-animation.html">
+<link rel="import" href="animations/slide-right-animation.html">
+<link rel="import" href="animations/slide-up-animation.html">
+<link rel="import" href="animations/slide-down-animation.html">
+<link rel="import" href="animations/transform-animation.html">
+
diff --git a/polymer_1.0.4/bower_components/neon-animation/neon-shared-element-animatable-behavior.html b/polymer_1.0.4/bower_components/neon-animation/neon-shared-element-animatable-behavior.html
new file mode 100644
index 0000000..9d5f6e7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/neon-shared-element-animatable-behavior.html
@@ -0,0 +1,37 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="neon-animatable-behavior.html">
+
+<script>
+
+ /**
+ * Use `Polymer.NeonSharedElementAnimatableBehavior` to implement elements containing shared element
+ * animations.
+ * @polymerBehavior
+ */
+ Polymer.NeonSharedElementAnimatableBehavior = [Polymer.NeonAnimatableBehavior, {
+
+ properties: {
+
+ /**
+ * A map of shared element id to node.
+ */
+ sharedElements: {
+ type: Object,
+ value: {}
+ }
+
+ }
+
+ }];
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/neon-shared-element-animation-behavior.html b/polymer_1.0.4/bower_components/neon-animation/neon-shared-element-animation-behavior.html
new file mode 100644
index 0000000..88a9ccb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/neon-shared-element-animation-behavior.html
@@ -0,0 +1,66 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="neon-animation-behavior.html">
+
+<script>
+
+ /**
+ * Use `Polymer.NeonSharedElementAnimationBehavior` to implement shared element animations.
+ * @polymerBehavior
+ */
+ Polymer.NeonSharedElementAnimationBehavior = [Polymer.NeonAnimationBehavior, {
+
+ properties: {
+
+ /**
+ * Cached copy of shared elements.
+ */
+ sharedElements: {
+ type: Object
+ }
+
+ },
+
+ /**
+ * Finds shared elements based on `config`.
+ */
+ findSharedElements: function(config) {
+ var fromPage = config.fromPage;
+ var toPage = config.toPage;
+ if (!fromPage || !toPage) {
+ console.warn(this.is + ':', !fromPage ? 'fromPage' : 'toPage', 'is undefined!');
+ return null;
+ };
+
+ if (!fromPage.sharedElements || !toPage.sharedElements) {
+ console.warn(this.is + ':', 'sharedElements are undefined for', !fromPage.sharedElements ? fromPage : toPage);
+ return null;
+ };
+
+ var from = fromPage.sharedElements[config.id]
+ var to = toPage.sharedElements[config.id];
+
+ if (!from || !to) {
+ console.warn(this.is + ':', 'sharedElement with id', config.id, 'not found in', !from ? fromPage : toPage);
+ return null;
+ }
+
+ this.sharedElements = {
+ from: from,
+ to: to
+ };
+ return this.sharedElements;
+ }
+
+ }];
+
+</script>
diff --git a/polymer_1.0.4/bower_components/neon-animation/web-animations.html b/polymer_1.0.4/bower_components/neon-animation/web-animations.html
new file mode 100644
index 0000000..c871854
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-animation/web-animations.html
@@ -0,0 +1,11 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<script src="../web-animations-js/web-animations-next-lite.min.js"></script>
diff --git a/polymer_1.0.4/bower_components/neon-elements/.bower.json b/polymer_1.0.4/bower_components/neon-elements/.bower.json
new file mode 100644
index 0000000..173841c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-elements/.bower.json
@@ -0,0 +1,36 @@
+{
+ "name": "neon-elements",
+ "version": "1.0.0",
+ "homepage": "https://github.com/PolymerElements/neon-elements",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "\"Neon elements implement special effects.\"",
+ "main": "\"neon-elements.html\"",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "paper"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "neon-animation": "PolymerElements/neon-animation#^1.0.0"
+ },
+ "_release": "1.0.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.0",
+ "commit": "1e0e6c868c6c648b63ad84fdbde9025bc93505c2"
+ },
+ "_source": "git://github.com/PolymerElements/neon-elements.git",
+ "_target": "~1.0.0",
+ "_originalSource": "PolymerElements/neon-elements",
+ "_direct": true
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/neon-elements/README.md b/polymer_1.0.4/bower_components/neon-elements/README.md
new file mode 100644
index 0000000..165e597
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-elements/README.md
@@ -0,0 +1,19 @@
+# neon-elements
+
+The neon elements are for flashy transitions and animations.
+
+## Roadmap
+
+### Elements in progress
+
+* `neon-animations` - This is released an usable but we're still adding to it. It contains a ton of neat animation features, including much of the behavior previously in `core-animated-pages`.
+
+### Elements planned
+_Elements we're planning on building soon but haven't started yet_
+
+[Lot's we're planning on here, but nothing explicit to list. If there are specific animations you'd like to see, feel free to file issues!]
+
+### Elements not planned, notably
+_Elements we're not planning on building as part of this product line, but that one might be wondering about_
+
+[None]
diff --git a/polymer_1.0.4/bower_components/neon-elements/bower.json b/polymer_1.0.4/bower_components/neon-elements/bower.json
new file mode 100644
index 0000000..f2d59ed
--- /dev/null
+++ b/polymer_1.0.4/bower_components/neon-elements/bower.json
@@ -0,0 +1,26 @@
+{
+ "name": "neon-elements",
+ "version": "1.0.0",
+ "homepage": "https://github.com/PolymerElements/neon-elements",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "\"Neon elements implement special effects.\"",
+ "main": "\"neon-elements.html\"",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "paper"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "neon-animation": "PolymerElements/neon-animation#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/.bower.json b/polymer_1.0.4/bower_components/paper-behaviors/.bower.json
new file mode 100644
index 0000000..7c969e4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/.bower.json
@@ -0,0 +1,48 @@
+{
+ "name": "paper-behaviors",
+ "version": "1.0.2",
+ "description": "Common behaviors across the paper elements",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "main": [
+ "paper-button-behavior.html",
+ "paper-radio-button-behavior.html"
+ ],
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer",
+ "paper",
+ "behavior"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-behaviors"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-behaviors",
+ "dependencies": {
+ "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
+ "paper-material": "PolymerElements/paper-material#^1.0.0",
+ "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "4dd226a2cc5b780a73d0058cd9998b6e0af1cb2c"
+ },
+ "_source": "git://github.com/polymerelements/paper-behaviors.git",
+ "_target": "^1.0.0",
+ "_originalSource": "polymerelements/paper-behaviors"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/.gitignore b/polymer_1.0.4/bower_components/paper-behaviors/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/README.md b/polymer_1.0.4/bower_components/paper-behaviors/README.md
new file mode 100644
index 0000000..e793a62
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/README.md
@@ -0,0 +1,4 @@
+paper-behaviors
+===============
+
+These are common behaviors used across `paper-*` elements.
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/bower.json b/polymer_1.0.4/bower_components/paper-behaviors/bower.json
new file mode 100644
index 0000000..d4cae45
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "paper-behaviors",
+ "version": "1.0.2",
+ "description": "Common behaviors across the paper elements",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "main": [
+ "paper-button-behavior.html",
+ "paper-radio-button-behavior.html"
+ ],
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer",
+ "paper",
+ "behavior"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-behaviors"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-behaviors",
+ "dependencies": {
+ "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
+ "paper-material": "PolymerElements/paper-material#^1.0.0",
+ "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/demo/index.html b/polymer_1.0.4/bower_components/paper-behaviors/demo/index.html
new file mode 100644
index 0000000..d6b775b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/demo/index.html
@@ -0,0 +1,57 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>paper-behaviors demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link href="paper-button.html" rel="import">
+ <link href="paper-radio-button.html" rel="import">
+
+ <style>
+
+ body {
+ font-family: sans-serif;
+ padding: 24px;
+ margin: 0;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <h3>Normal</h3>
+
+ <paper-button tabindex="0">Hello World</paper-button>
+
+ <h3>Toggles</h3>
+
+ <paper-button toggles tabindex="0">Hello World</paper-button>
+
+ <h3>Disabled</h3>
+
+ <paper-button disabled tabindex="0">Hello World</paper-button>
+
+ <h3>Radio button with focus state</h3>
+
+ <paper-radio-button tabindex="0" title="Radio button with focus state"></paper-radio-button>
+
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/demo/paper-button.html b/polymer_1.0.4/bower_components/paper-behaviors/demo/paper-button.html
new file mode 100644
index 0000000..c38bd00
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/demo/paper-button.html
@@ -0,0 +1,71 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../../paper-material/paper-material.html">
+<link rel="import" href="../paper-button-behavior.html">
+
+<dom-module id="paper-button">
+
+ <style>
+
+ :host {
+ display: inline-block;
+ background-color: #4285F4;
+ color: #fff;
+ border-radius: 3px;
+ text-transform: uppercase;
+ outline: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -webkit-user-select: none;
+ user-select: none;
+ cursor: pointer;
+ }
+
+ paper-material {
+ border-radius: inherit;
+ padding: 16px;
+ }
+
+ :host([disabled]) {
+ background-color: #888;
+ pointer-events: none;
+ }
+
+ :host([active]),
+ :host([pressed]) {
+ background-color: #3367D6;
+ box-shadow: inset 0 3px 5px rgba(0,0,0,.2);
+ }
+
+ </style>
+
+ <template>
+
+ <paper-material class="content" elevation="[[_elevation]]" animated>
+ <content></content>
+ </paper-material>
+
+ </template>
+
+ <script>
+
+ Polymer({
+ is: 'paper-button',
+
+ behaviors: [
+ Polymer.PaperButtonBehavior
+ ]
+ });
+
+ </script>
+
+</dom-module>
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/demo/paper-radio-button.html b/polymer_1.0.4/bower_components/paper-behaviors/demo/paper-radio-button.html
new file mode 100644
index 0000000..93af175
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/demo/paper-radio-button.html
@@ -0,0 +1,116 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../../paper-ripple/paper-ripple.html">
+<link rel="import" href="../paper-inky-focus-behavior.html">
+
+<dom-module id="paper-radio-button">
+
+ <style>
+ :host {
+ display: inline-block;
+ white-space: nowrap;
+ }
+
+ :host(:focus) {
+ outline: none
+ }
+
+ #radioContainer {
+ display: inline-block;
+ position: relative;
+ width: 16px;
+ height: 16px;
+ cursor: pointer;
+ vertical-align: middle;
+ }
+
+ #offRadio {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 12px;
+ height: 12px;
+ border-radius: 50%;
+ border: solid 2px;
+ border-color: black;
+ transition: border-color 0.28s;
+ }
+
+ #onRadio {
+ position: absolute;
+ top: 4px;
+ left: 4px;
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background-color: red;
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ transition: -webkit-transform ease 0.28s;
+ transition: transform ease 0.28s;
+ }
+
+ :host([disabled]) {
+ opacity: 0.3;
+ pointer-events: none;
+ }
+
+ :host([pressed]) #offRadio,
+ :host([active]) #offRadio {
+ border-color: red;
+ }
+
+ :host([pressed]) #onRadio,
+ :host([active]) #onRadio {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+
+ #ink {
+ position: absolute;
+ top: -16px;
+ left: -16px;
+ width: 48px;
+ height: 48px;
+ }
+
+ </style>
+
+ <template>
+ <div id="radioContainer">
+ <div id="offRadio"></div>
+ <div id="onRadio"></div>
+ <paper-ripple id="ink" class="circle" center></paper-ripple>
+ </div>
+ </template>
+
+ <script>
+
+ Polymer({
+
+ behaviors: [
+ Polymer.PaperInkyFocusBehavior
+ ],
+
+ hostAttributes: {
+ role: 'radio'
+ },
+
+ ready: function() {
+ this.toggles = true;
+ }
+
+ });
+
+ </script>
+
+</dom-module>
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/index.html b/polymer_1.0.4/bower_components/paper-behaviors/index.html
new file mode 100644
index 0000000..3e003cb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page src="paper-button-behavior.html"></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/paper-button-behavior.html b/polymer_1.0.4/bower_components/paper-behaviors/paper-button-behavior.html
new file mode 100644
index 0000000..bbe508f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/paper-button-behavior.html
@@ -0,0 +1,56 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-behaviors/iron-button-state.html">
+
+<script>
+
+ /** @polymerBehavior */
+ Polymer.PaperButtonBehaviorImpl = {
+
+ properties: {
+
+ _elevation: {
+ type: Number
+ }
+
+ },
+
+ observers: [
+ '_calculateElevation(focused, disabled, active, pressed, receivedFocusFromKeyboard)'
+ ],
+
+ hostAttributes: {
+ role: 'button',
+ tabindex: '0'
+ },
+
+ _calculateElevation: function() {
+ var e = 1;
+ if (this.disabled) {
+ e = 0;
+ } else if (this.active || this.pressed) {
+ e = 4;
+ } else if (this.receivedFocusFromKeyboard) {
+ e = 3;
+ }
+ this._elevation = e;
+ }
+ };
+
+ /** @polymerBehavior */
+ Polymer.PaperButtonBehavior = [
+ Polymer.IronButtonState,
+ Polymer.IronControlState,
+ Polymer.PaperButtonBehaviorImpl
+ ];
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/paper-inky-focus-behavior.html b/polymer_1.0.4/bower_components/paper-behaviors/paper-inky-focus-behavior.html
new file mode 100644
index 0000000..4f6e9f8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/paper-inky-focus-behavior.html
@@ -0,0 +1,44 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-behaviors/iron-button-state.html">
+
+<script>
+
+ /**
+ * `Polymer.PaperInkyFocusBehavior` implements a ripple when the element has keyboard focus.
+ *
+ * @polymerBehavior Polymer.PaperInkyFocusBehavior
+ */
+ Polymer.PaperInkyFocusBehaviorImpl = {
+
+ observers: [
+ '_focusedChanged(receivedFocusFromKeyboard)'
+ ],
+
+ _focusedChanged: function(receivedFocusFromKeyboard) {
+ if (!this.$.ink) {
+ return;
+ }
+
+ this.$.ink.holdDown = receivedFocusFromKeyboard;
+ }
+
+ };
+
+ /** @polymerBehavior Polymer.PaperInkyFocusBehavior */
+ Polymer.PaperInkyFocusBehavior = [
+ Polymer.IronButtonState,
+ Polymer.IronControlState,
+ Polymer.PaperInkyFocusBehaviorImpl
+ ];
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/test/index.html b/polymer_1.0.4/bower_components/paper-behaviors/test/index.html
new file mode 100644
index 0000000..c58bfee
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/test/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'paper-button-behavior.html',
+ 'paper-radio-button-behavior.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/test/paper-button-behavior.html b/polymer_1.0.4/bower_components/paper-behaviors/test/paper-button-behavior.html
new file mode 100644
index 0000000..9663938
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/test/paper-button-behavior.html
@@ -0,0 +1,82 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+ <title>paper-button-behavior</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+ <script src="../../iron-test-helpers/mock-interactions.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="test-button.html">
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <test-button></test-button>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('basic', function() {
+ var button;
+
+ setup(function() {
+ button = fixture('basic');
+ });
+
+ test('normal (no states)', function() {
+ assert.equal(button._elevation, 1);
+ });
+
+ test('set disabled property', function() {
+ button.disabled = true;
+ assert.equal(button._elevation, 0);
+ });
+
+ test('pressed and released', function() {
+ MockInteractions.down(button);
+ assert.equal(button._elevation, 4);
+ MockInteractions.up(button);
+ assert.equal(button._elevation, 1);
+ });
+
+ suite('a button with toggles', function() {
+ setup(function() {
+ button.toggles = true;
+ });
+
+ test('activated by tap', function(done) {
+ MockInteractions.downAndUp(button, function() {
+ try {
+ assert.equal(button._elevation, 4);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ });
+ });
+ });
+
+ test('receives focused', function() {
+ MockInteractions.focus(button);
+ assert.equal(button._elevation, 3);
+ });
+ });
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/test/paper-radio-button-behavior.html b/polymer_1.0.4/bower_components/paper-behaviors/test/paper-radio-button-behavior.html
new file mode 100644
index 0000000..890d0bb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/test/paper-radio-button-behavior.html
@@ -0,0 +1,62 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+ <title>paper-radio-button-behavior</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+ <script src="../../iron-test-helpers/mock-interactions.js"></script>
+
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="test-radio-button.html">
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <test-radio-button></test-radio-button>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('basic', function() {
+ var button;
+ var ink;
+
+ setup(function() {
+ button = fixture('basic');
+ ink = button.querySelector('paper-ripple');
+ MockInteractions.blur(button);
+ });
+
+ test('normal (no states)', function() {
+ assert.isFalse(button.focused);
+ assert.isFalse(ink._animating);
+ assert.equal(ink.ripples.length, 0);
+ });
+
+ test('receives focus', function() {
+ MockInteractions.focus(button);
+
+ assert.isTrue(button.focused);
+ assert.isTrue(ink._animating);
+ assert.equal(ink.ripples.length, 1);
+ });
+
+ });
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/test/test-button.html b/polymer_1.0.4/bower_components/paper-behaviors/test/test-button.html
new file mode 100644
index 0000000..3bbf356
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/test/test-button.html
@@ -0,0 +1,34 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../paper-button-behavior.html">
+
+<dom-module id="test-button">
+
+ <template>
+ <content></content>
+ </template>
+
+ <script>
+
+ Polymer({
+
+ is: 'test-button',
+
+ behaviors: [
+ Polymer.PaperButtonBehavior
+ ]
+
+ });
+
+ </script>
+
+</dom-module>
diff --git a/polymer_1.0.4/bower_components/paper-behaviors/test/test-radio-button.html b/polymer_1.0.4/bower_components/paper-behaviors/test/test-radio-button.html
new file mode 100644
index 0000000..afeabbb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-behaviors/test/test-radio-button.html
@@ -0,0 +1,41 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../paper-inky-focus-behavior.html">
+<link rel="import" href="../../paper-ripple/paper-ripple.html">
+
+<dom-module id="test-radio-button">
+ <style>
+ :host #ink {
+ position: absolute;
+ top: -16px;
+ left: -16px;
+ width: 48px;
+ height: 48px;
+ }
+
+ </style>
+ <template>
+ <div id="container">
+ <paper-ripple id="ink" class="circle" center></paper-ripple>
+ </div>
+ </template>
+</dom-module>
+
+<script>
+ Polymer({
+ is: 'test-radio-button',
+
+ behaviors: [
+ Polymer.PaperInkyFocusBehavior
+ ]
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-button/.bower.json b/polymer_1.0.4/bower_components/paper-button/.bower.json
new file mode 100644
index 0000000..21100e3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-button/.bower.json
@@ -0,0 +1,48 @@
+{
+ "name": "paper-button",
+ "version": "1.0.1",
+ "description": "Material design button",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer",
+ "paper",
+ "button"
+ ],
+ "main": "paper-button.html",
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-button"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-button",
+ "dependencies": {
+ "paper-ripple": "polymerelements/paper-ripple#^1.0.0",
+ "paper-material": "polymerelements/paper-material#^1.0.0",
+ "paper-behaviors": "polymerelements/paper-behaviors#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "iron-icons": "polymerelements/iron-icons#^1.0.0",
+ "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "e11a0603feaaedd8cf6c7e0d533bdc67de24c8de"
+ },
+ "_source": "git://github.com/PolymerElements/paper-button.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-button"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-button/.gitignore b/polymer_1.0.4/bower_components/paper-button/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-button/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-button/README.md b/polymer_1.0.4/bower_components/paper-button/README.md
new file mode 100644
index 0000000..035b004
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-button/README.md
@@ -0,0 +1,45 @@
+paper-button
+============
+
+Material Design: <a href="http://www.google.com/design/spec/components/buttons.html">Buttons</a>
+
+`paper-button` is a button. When the user touches the button, a ripple effect emanates
+from the point of contact. It may be flat or raised. A raised button is styled with a
+shadow.
+
+Example:
+```html
+ <paper-button>flat button</paper-button>
+ <paper-button raised>raised button</paper-button>
+ <paper-button noink>No ripple effect</paper-button>
+```
+You may use custom DOM in the button body to create a variety of buttons. For example, to
+create a button with an icon and some text:
+
+```html
+ <paper-button>
+ <iron-icon icon="favorite"></iron-icon>
+ custom button content
+ </paper-button>
+```
+## Styling
+
+Style the button with CSS as you would a normal DOM element.
+
+```css
+ /* make #my-button green with yellow text */
+ #my-button {
+ background: green;
+ color: yellow;
+ }
+```
+By default, the ripple is the same color as the foreground at 25% opacity. You may
+customize the color using this selector:
+
+```css
+ /* make #my-button use a blue ripple instead of foreground color */
+ #my-button::shadow paper-ripple {
+ color: blue;
+ }
+```
+The opacity of the ripple is not customizable via CSS.
diff --git a/polymer_1.0.4/bower_components/paper-button/bower.json b/polymer_1.0.4/bower_components/paper-button/bower.json
new file mode 100644
index 0000000..940aa6d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-button/bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "paper-button",
+ "version": "1.0.1",
+ "description": "Material design button",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer",
+ "paper",
+ "button"
+ ],
+ "main": "paper-button.html",
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-button"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-button",
+ "dependencies": {
+ "paper-ripple": "polymerelements/paper-ripple#^1.0.0",
+ "paper-material": "polymerelements/paper-material#^1.0.0",
+ "paper-behaviors": "polymerelements/paper-behaviors#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "iron-icons": "polymerelements/iron-icons#^1.0.0",
+ "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-button/demo/index.html b/polymer_1.0.4/bower_components/paper-button/demo/index.html
new file mode 100644
index 0000000..e8af296
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-button/demo/index.html
@@ -0,0 +1,158 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>paper-button demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../paper-button.html">
+
+ <style is="custom-style">
+ .horizontal-section {
+ min-width: 130px;
+ }
+
+ paper-button {
+ display: block;
+ margin-bottom: 24px;
+ }
+
+ paper-button.colorful {
+ color: #4285f4;
+ }
+
+ paper-button[raised].colorful {
+ background: #4285f4;
+ color: #fff;
+ }
+
+ paper-button[toggles] {
+ transition: background-color 0.3s;
+ }
+
+ paper-button[toggles][active] {
+ background-color: rgba(0, 0, 0, 0.25);
+ }
+
+ paper-button[toggles][active].colorful {
+ background-color: rgba(66, 133, 244, 0.25);
+ }
+
+ paper-button[toggles][active][raised].colorful {
+ background-color: rgba(66, 133, 244, 0.75);
+ }
+
+ paper-button.blue {
+ color: var(--paper-light-blue-500);
+ --paper-button-flat-focus-color: var(--paper-light-blue-50);
+ }
+ paper-button.blue:hover {
+ background: var(--paper-light-blue-50);
+ }
+ paper-button.red {
+ color: var(--paper-red-500);
+ --paper-button-flat-focus-color: var(--paper-red-50);
+ }
+ paper-button.red:hover {
+ background: var(--paper-red-50);
+ }
+ paper-button.green {
+ color: var(--paper-green-500);
+ --paper-button-flat-focus-color: var(--paper-green-50);
+ }
+ paper-button.green:hover {
+ background: var(--paper-green-50);
+ }
+ paper-button.orange {
+ color: var(--paper-orange-500);
+ --paper-button-flat-focus-color: var(--paper-orange-50);
+ }
+ paper-button.orange:hover {
+ background: var(--paper-orange-50);
+ }
+
+ paper-button.hover:hover {
+ background: #eee;
+ }
+
+ paper-button.ripple::shadow paper-ripple {
+ color: var(--paper-pink-a200);
+ }
+
+ paper-button.ripple paper-ripple {
+ color: var(--paper-pink-a200);
+ }
+
+ </style>
+
+</head>
+<body>
+ <div class="horizontal center-justified layout">
+ <div>
+ <h4>Flat</h4>
+ <div class="horizontal-section">
+ <paper-button tabindex="0">button</paper-button>
+ <paper-button tabindex="0" class="colorful">colorful</paper-button>
+ <paper-button tabindex="0" disabled>disabled</paper-button>
+ <paper-button tabindex="0" noink>noink</paper-button>
+ <paper-button tabindex="0" class="colorful custom"><iron-icon icon="check"></iron-icon>ok</paper-button>
+ <paper-button tabindex="0" class="custom"><iron-icon icon="clear"></iron-icon>cancel</paper-button>
+
+ </div>
+ </div>
+
+ <div>
+ <h4>Raised</h4>
+ <div class="horizontal-section">
+ <paper-button tabindex="0" raised>button</paper-button>
+ <paper-button tabindex="0" raised class="colorful">colorful</paper-button>
+ <paper-button tabindex="0" raised disabled>disabled</paper-button>
+ <paper-button tabindex="0" raised noink>noink</paper-button>
+ <paper-button tabindex="0" raised class="colorful custom"><iron-icon icon="check"></iron-icon>ok</paper-button>
+ <paper-button tabindex="0" raised class="custom"><iron-icon icon="clear"></iron-icon>cancel</paper-button>
+ </div>
+ </div>
+
+ <div>
+ <h4>Toggleable</h4>
+ <div class="horizontal-section">
+ <paper-button tabindex="0" toggles>button</paper-button>
+ <paper-button tabindex="0" toggles raised noink>noink</paper-button>
+ <paper-button tabindex="0" toggles active class="colorful">colorful</paper-button>
+ <paper-button tabindex="0" toggles raised active class="colorful">colorful</paper-button>
+ <paper-button tabindex="0" toggles class="colorful custom"><iron-icon icon="check"></iron-icon>ok</paper-button>
+ <paper-button tabindex="0" toggles class="custom"><iron-icon icon="clear"></iron-icon>cancel</paper-button>
+ </div>
+ </div>
+
+ <div>
+ <h4>Color</h4>
+ <div class="horizontal-section">
+ <paper-button tabindex="0" class="blue ripple">button</paper-button>
+ <paper-button tabindex="0" class="red ripple">noink</paper-button>
+ <paper-button tabindex="0" class="orange ripple">colorful</paper-button>
+ <paper-button tabindex="0" class="green ripple">colorful</paper-button>
+ <paper-button tabindex="0" class="red ripple"><iron-icon icon="check"></iron-icon>ok</paper-button>
+ <paper-button tabindex="0" class="blue ripple"><iron-icon icon="clear"></iron-icon>cancel</paper-button>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-button/index.html b/polymer_1.0.4/bower_components/paper-button/index.html
new file mode 100644
index 0000000..e871f17
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-button/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-button/paper-button.html b/polymer_1.0.4/bower_components/paper-button/paper-button.html
new file mode 100644
index 0000000..897ccc6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-button/paper-button.html
@@ -0,0 +1,177 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-material/paper-material.html">
+<link rel="import" href="../paper-ripple/paper-ripple.html">
+<link rel="import" href="../paper-behaviors/paper-button-behavior.html">
+
+<!--
+
+Material Design: <a href="http://www.google.com/design/spec/components/buttons.html">Buttons</a>
+
+`paper-button` is a button. When the user touches the button, a ripple effect emanates
+from the point of contact. It may be flat or raised. A raised button is styled with a
+shadow.
+
+Example:
+
+ <paper-button>flat button</paper-button>
+ <paper-button raised>raised button</paper-button>
+ <paper-button noink>No ripple effect</paper-button>
+
+You may use custom DOM in the button body to create a variety of buttons. For example, to
+create a button with an icon and some text:
+
+ <paper-button>
+ <core-icon icon="favorite"></core-icon>
+ custom button content
+ </paper-button>
+
+### Styling
+
+Style the button with CSS as you would a normal DOM element.
+
+ /* make #my-button green with yellow text */
+ #my-button {
+ background: green;
+ color: yellow;
+ }
+
+By default, the ripple is the same color as the foreground at 25% opacity. You may
+customize the color using this selector:
+
+ /* make #my-button use a blue ripple instead of foreground color */
+ #my-button::shadow paper-ripple {
+ color: blue;
+ }
+
+The opacity of the ripple is not customizable via CSS.
+
+The following custom properties and mixins are also available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-button-flat-focus-color` | Background color of a focused flat button | `--paper-grey-200`
+`--paper-button` | Mixin applied to the button | `{}`
+`--paper-button-disabled` | Mixin applied to the disabled button | `{}`
+
+@demo demo/index.html
+-->
+
+<dom-module id="paper-button">
+
+ <style>
+
+ :host {
+ display: inline-block;
+ position: relative;
+ box-sizing: border-box;
+ min-width: 5.14em;
+ margin: 0 0.29em;
+ background: transparent;
+ text-align: center;
+ font: inherit;
+ text-transform: uppercase;
+ outline: none;
+ border-radius: 3px;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -webkit-user-select: none;
+ user-select: none;
+ cursor: pointer;
+ z-index: 0;
+
+ @apply(--paper-button);
+ }
+
+ .keyboard-focus {
+ font-weight: bold;
+ }
+
+ :host([disabled]) {
+ background: #eaeaea;
+ color: #a8a8a8;
+ cursor: auto;
+ pointer-events: none;
+
+ @apply(--paper-button-disabled);
+ }
+
+ :host([noink]) paper-ripple {
+ display: none;
+ }
+
+ paper-material {
+ border-radius: inherit;
+ }
+
+ .content > ::content * {
+ text-transform: inherit;
+ }
+
+ .content {
+ padding: 0.7em 0.57em
+ }
+ </style>
+
+ <template>
+
+ <paper-ripple></paper-ripple>
+
+ <paper-material class$="[[_computeContentClass(receivedFocusFromKeyboard)]]" elevation="[[_elevation]]" animated>
+ <content></content>
+ </paper-material>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'paper-button',
+
+ behaviors: [
+ Polymer.PaperButtonBehavior
+ ],
+
+ properties: {
+
+ /**
+ * If true, the button should be styled with a shadow.
+ */
+ raised: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: false,
+ observer: '_calculateElevation'
+ }
+ },
+
+ _calculateElevation: function() {
+ if (!this.raised) {
+ this._elevation = 0;
+ } else {
+ Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this);
+ }
+ },
+
+ _computeContentClass: function(receivedFocusFromKeyboard) {
+ var className = 'content ';
+ if (receivedFocusFromKeyboard) {
+ className += ' keyboard-focus';
+ }
+ return className;
+ }
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-button/test/index.html b/polymer_1.0.4/bower_components/paper-button/test/index.html
new file mode 100644
index 0000000..07ed03c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-button/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>paper-button tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'paper-button.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-button/test/paper-button.html b/polymer_1.0.4/bower_components/paper-button/test/paper-button.html
new file mode 100644
index 0000000..797688c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-button/test/paper-button.html
@@ -0,0 +1,83 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>paper-button basic tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+ <script src="../../iron-test-helpers/mock-interactions.js"></script>
+
+ <link rel="import" href="../paper-button.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+
+</head>
+<body>
+
+ <test-fixture id="TrivialButton">
+ <template>
+ <paper-button>Button</paper-button>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('<paper-button>', function() {
+ var button;
+
+ setup(function() {
+ button = fixture('TrivialButton');
+ });
+
+ test('can be raised imperatively', function(done) {
+ button.raised = true;
+
+ expect(button.hasAttribute('raised')).to.be.eql(true);
+
+ Polymer.Base.async(function() {
+ try {
+ expect(button._elevation).to.be.eql(1);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ }, 1);
+ });
+
+ test('has aria role "button"', function() {
+ expect(button.getAttribute('role')).to.be.eql('button');
+ });
+
+ test('can be disabled imperatively', function() {
+ button.disabled = true;
+ expect(button.getAttribute('aria-disabled')).to.be.eql('true');
+ expect(button.hasAttribute('disabled')).to.be.eql(true);
+ });
+
+ test('can be triggered with space', function(done) {
+ button.addEventListener('click', function() {
+ done();
+ });
+ MockInteractions.pressSpace(button);
+ });
+
+ test('can be triggered with enter', function(done) {
+ button.addEventListener('click', function() {
+ done();
+ });
+ MockInteractions.pressEnter(button);
+ });
+ });
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-checkbox/.bower.json b/polymer_1.0.4/bower_components/paper-checkbox/.bower.json
new file mode 100644
index 0000000..f4cb1ba
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-checkbox/.bower.json
@@ -0,0 +1,46 @@
+{
+ "name": "paper-checkbox",
+ "version": "1.0.3",
+ "description": "A material design checkbox",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "paper",
+ "checkbox",
+ "control"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-checkbox"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-checkbox",
+ "ignore": [],
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "dependencies": {
+ "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "_release": "1.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.3",
+ "commit": "b32696b963cdcb00223f2a2433ef439363c9a150"
+ },
+ "_source": "git://github.com/PolymerElements/paper-checkbox.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-checkbox"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-checkbox/.gitignore b/polymer_1.0.4/bower_components/paper-checkbox/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-checkbox/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-checkbox/README.md b/polymer_1.0.4/bower_components/paper-checkbox/README.md
new file mode 100644
index 0000000..2269079
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-checkbox/README.md
@@ -0,0 +1,31 @@
+# paper-checkbox
+
+`paper-checkbox` is a button that can be either checked or unchecked. User
+can tap the checkbox to check or uncheck it. Usually you use checkboxes
+to allow user to select multiple options from a set. If you have a single
+ON/OFF option, avoid using a single checkbox and use `paper-toggle-button`
+instead.
+
+Example:
+
+```html
+<paper-checkbox>label</paper-checkbox>
+
+<paper-checkbox checked>label</paper-checkbox>
+```
+
+Styling a checkbox:
+
+```html
+<style is="custom-style">
+ paper-checkbox {
+ /* Unhecked state colors. */
+ --paper-checkbox-unchecked-color: #5a5a5a;
+ --paper-checkbox-unchecked-ink-color: #5a5a5a;
+
+ /* Checked state colors. */
+ --paper-checkbox-checked-color: #009688;
+ --paper-checkbox-checked-ink-color: #009688;
+ }
+</style>
+```
diff --git a/polymer_1.0.4/bower_components/paper-checkbox/bower.json b/polymer_1.0.4/bower_components/paper-checkbox/bower.json
new file mode 100644
index 0000000..c68d6d8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-checkbox/bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "paper-checkbox",
+ "version": "1.0.3",
+ "description": "A material design checkbox",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "paper",
+ "checkbox",
+ "control"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-checkbox"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-checkbox",
+ "ignore": [],
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "dependencies": {
+ "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-checkbox/demo/index.html b/polymer_1.0.4/bower_components/paper-checkbox/demo/index.html
new file mode 100644
index 0000000..dd66e47
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-checkbox/demo/index.html
@@ -0,0 +1,94 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>paper-checkbox demo</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../paper-checkbox.html">
+
+ <style is="custom-style">
+
+ paper-checkbox {
+ display: block;
+ margin-bottom: 40px;
+ }
+
+ paper-checkbox.blue {
+ --paper-checkbox-checked-color: var(--paper-light-blue-500);
+ --paper-checkbox-checked-ink-color: var(--paper-light-blue-500);
+ --paper-checkbox-unchecked-color: var(--paper-light-blue-900);
+ --paper-checkbox-unchecked-ink-color: var(--paper-light-blue-900);
+ }
+
+ paper-checkbox.red {
+ --paper-checkbox-checked-color: var(--paper-red-500);
+ --paper-checkbox-checked-ink-color: var(--paper-red-500);
+ --paper-checkbox-unchecked-color: var(--paper-red-900);
+ --paper-checkbox-unchecked-ink-color: var(--paper-red-900);
+ }
+
+ paper-checkbox.green {
+ --paper-checkbox-checked-color: var(--paper-green-500);
+ --paper-checkbox-checked-ink-color: var(--paper-green-500);
+ --paper-checkbox-unchecked-color: var(--paper-green-900);
+ --paper-checkbox-unchecked-ink-color: var(--paper-green-900);
+ }
+
+ paper-checkbox.orange {
+ --paper-checkbox-checked-color: var(--paper-orange-500);
+ --paper-checkbox-checked-ink-color: var(--paper-orange-500);
+ --paper-checkbox-unchecked-color: var(--paper-orange-900);
+ --paper-checkbox-unchecked-ink-color: var(--paper-orange-900);
+ }
+ </style>
+ </head>
+ <body>
+ <div class="horizontal center-justified layout">
+ <div>
+ <h4>Enabled</h4>
+ <div class="horizontal-section">
+ <paper-checkbox>Oxygen</paper-checkbox>
+ <paper-checkbox>Carbon</paper-checkbox>
+ <paper-checkbox checked>Hydrogen</paper-checkbox>
+ <paper-checkbox checked>Nitrogen</paper-checkbox>
+ <paper-checkbox checked>Calcium</paper-checkbox>
+ </div>
+ </div>
+ <div>
+ <h4>Disabled</h4>
+ <div class="horizontal-section">
+ <paper-checkbox disabled>Oxygen</paper-checkbox>
+ <paper-checkbox disabled>Carbon</paper-checkbox>
+ <paper-checkbox checked disabled>Hydrogen</paper-checkbox>
+ <paper-checkbox checked disabled>Nitrogen</paper-checkbox>
+ <paper-checkbox checked disabled>Calcium</paper-checkbox>
+ </div>
+ </div>
+ <div>
+ <h4>Color</h4>
+ <div class="horizontal-section">
+ <paper-checkbox class="blue" checked>Oxygen</paper-checkbox>
+ <paper-checkbox class="red" checked>Carbon</paper-checkbox>
+ <paper-checkbox class="orange" checked>Hydrogen</paper-checkbox>
+ <paper-checkbox class="green" checked>Nitrogen</paper-checkbox>
+ <paper-checkbox class="blue" checked>Calcium</paper-checkbox>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-checkbox/index.html b/polymer_1.0.4/bower_components/paper-checkbox/index.html
new file mode 100644
index 0000000..b368797
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-checkbox/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>paper-checkbox</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+ </head>
+ <body>
+
+ <iron-component-page></iron-component-page>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-checkbox/metadata.html b/polymer_1.0.4/bower_components/paper-checkbox/metadata.html
new file mode 100644
index 0000000..4d068e8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-checkbox/metadata.html
@@ -0,0 +1,17 @@
+<!--
+ @license
+ Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ Code distributed by Google as part of the polymer project is also
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<x-meta id="paper-checkbox" label="Checkbox" group="Paper">
+ <template>
+ <paper-checkbox label="click me"></paper-checkbox>
+ </template>
+ <template id="imports">
+ <link rel="import" href="paper-checkbox.html">
+ </template>
+</x-meta>
diff --git a/polymer_1.0.4/bower_components/paper-checkbox/paper-checkbox.css b/polymer_1.0.4/bower_components/paper-checkbox/paper-checkbox.css
new file mode 100644
index 0000000..195d822
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-checkbox/paper-checkbox.css
@@ -0,0 +1,149 @@
+/*
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+*/
+
+:host {
+ display: inline-block;
+ white-space: nowrap;
+}
+
+:host(:focus) {
+ outline: none;
+}
+
+.hidden {
+ display: none;
+}
+
+#checkboxContainer {
+ display: inline-block;
+ position: relative;
+ width: 18px;
+ height: 18px;
+ cursor: pointer;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ vertical-align: middle;
+}
+
+:host #ink {
+ position: absolute;
+ top: -15px;
+ left: -15px;
+ width: 48px;
+ height: 48px;
+ color: var(--paper-checkbox-unchecked-ink-color, --primary-text-color);
+ opacity: 0.6;
+}
+
+:host #ink[checked] {
+ color: var(--paper-checkbox-checked-ink-color, --default-primary-color);
+}
+
+:host #checkbox {
+ position: relative;
+ box-sizing: border-box;
+ height: 100%;
+ border: solid 2px;
+ border-color: var(--paper-checkbox-unchecked-color, --primary-text-color);
+ border-radius: 2px;
+ pointer-events: none;
+ -webkit-transition: background-color 140ms, border-color 140ms;
+ transition: background-color 140ms, border-color 140ms;
+}
+
+/* checkbox checked animations */
+#checkbox.checked #checkmark {
+ -webkit-animation: checkmark-expand 140ms ease-out forwards;
+ animation: checkmark-expand 140ms ease-out forwards;
+}
+
+@-webkit-keyframes checkmark-expand {
+ 0% {
+ top: 9px;
+ left: 6px;
+ width: 0px;
+ height: 0px;
+ }
+ 100% {
+ top: -1px;
+ left: 4px;
+ width: 5px;
+ height: 10px;
+ }
+}
+
+@keyframes checkmark-expand {
+ 0% {
+ top: 9px;
+ left: 6px;
+ width: 0px;
+ height: 0px;
+ }
+ 100% {
+ top: -1px;
+ left: 4px;
+ width: 5px;
+ height: 10px;
+ }
+}
+
+:host #checkbox.checked {
+ background-color: var(--paper-checkbox-checked-color, --default-primary-color);
+ border-color: var(--paper-checkbox-checked-color, --default-primary-color);
+}
+
+:host #checkmark {
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ position: absolute;
+ top: -1px;
+ left: 4px;
+ width: 5px;
+ height: 10px;
+ border-style: solid;
+ border-top: none;
+ border-left: none;
+ border-right-width: 2px;
+ border-bottom-width: 2px;
+ border-color: white;
+}
+
+/* label */
+#checkboxLabel {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+ padding-left: 8px;
+ white-space: normal;
+ pointer-events: none;
+ color: var(--paper-checkbox-label-color, --primary-text-color);
+}
+
+#checkboxLabel[hidden] {
+ display: none;
+}
+
+/* disabled state */
+:host([disabled]) {
+ pointer-events: none;
+}
+
+:host([disabled]) #checkbox {
+ opacity: 0.5;
+ border-color: var(--paper-checkbox-unchecked-color, --primary-text-color);
+}
+
+:host([disabled][checked]) #checkbox {
+ background-color: var(--paper-checkbox-unchecked-color, --primary-text-color);
+ opacity: 0.5;
+}
+
+:host([disabled]) #checkboxLabel {
+ opacity: 0.65;
+}
diff --git a/polymer_1.0.4/bower_components/paper-checkbox/paper-checkbox.html b/polymer_1.0.4/bower_components/paper-checkbox/paper-checkbox.html
new file mode 100644
index 0000000..ee40cf9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-checkbox/paper-checkbox.html
@@ -0,0 +1,151 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-ripple/paper-ripple.html">
+<link rel="import" href="../paper-styles/default-theme.html">
+<link rel="import" href="../paper-behaviors/paper-inky-focus-behavior.html">
+
+<!--
+
+`paper-checkbox` is a button that can be either checked or unchecked. User
+can tap the checkbox to check or uncheck it. Usually you use checkboxes
+to allow user to select multiple options from a set. If you have a single
+ON/OFF option, avoid using a single checkbox and use `paper-toggle-button`
+instead.
+
+Example:
+
+ <paper-checkbox>label</paper-checkbox>
+
+ <paper-checkbox checked> label</paper-checkbox>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-checkbox-unchecked-color` | Checkbox color when the input is not checked | `--primary-text-color`
+`--paper-checkbox-unchecked-ink-color` | Selected/focus ripple color when the input is not checked | `--primary-text-color`
+`--paper-checkbox-checked-color` | Checkbox color when the input is checked | `--default-primary-color`
+`--paper-checkbox-checked-ink-color` | Selected/focus ripple color when the input is checked | `--default-primary-color`
+`--paper-checkbox-label-color` | Label color | `--primary-text-color`
+
+@demo demo/index.html
+-->
+
+<dom-module id="paper-checkbox">
+ <link rel="import" type="css" href="paper-checkbox.css">
+
+ <template>
+
+ <div id="checkboxContainer">
+ <paper-ripple id="ink" class="circle" center checked$="[[checked]]"></paper-ripple>
+ <div id="checkbox" class$="[[_computeCheckboxClass(checked)]]">
+ <div id="checkmark" class$="[[_computeCheckmarkClass(checked)]]"></div>
+ </div>
+ </div>
+
+ <div id="checkboxLabel" aria-hidden="true"><content></content></div>
+
+ </template>
+
+ <script>
+ Polymer({
+ is: 'paper-checkbox',
+
+ behaviors: [
+ Polymer.PaperInkyFocusBehavior
+ ],
+
+ hostAttributes: {
+ role: 'checkbox',
+ 'aria-checked': false,
+ tabindex: 0
+ },
+
+ properties: {
+ /**
+ * Fired when the checked state changes due to user interaction.
+ *
+ * @event change
+ */
+
+ /**
+ * Fired when the checked state changes.
+ *
+ * @event iron-change
+ */
+
+ /**
+ * Gets or sets the state, `true` is checked and `false` is unchecked.
+ */
+ checked: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true,
+ notify: true,
+ observer: '_checkedChanged'
+ },
+
+ /**
+ * If true, the button toggles the active state with each tap or press
+ * of the spacebar.
+ */
+ toggles: {
+ type: Boolean,
+ value: true,
+ reflectToAttribute: true
+ }
+ },
+
+ ready: function() {
+ if (Polymer.dom(this).textContent == '') {
+ this.$.checkboxLabel.hidden = true;
+ } else {
+ this.setAttribute('aria-label', Polymer.dom(this).textContent);
+ }
+ this._isReady = true;
+ },
+
+ // button-behavior hook
+ _buttonStateChanged: function() {
+ if (this.disabled) {
+ return;
+ }
+ if (this._isReady) {
+ this.checked = this.active;
+ }
+ },
+
+ _checkedChanged: function(checked) {
+ this.setAttribute('aria-checked', this.checked ? 'true' : 'false');
+ this.active = this.checked;
+ this.fire('iron-change');
+ },
+
+ _computeCheckboxClass: function(checked) {
+ if (checked) {
+ return 'checked';
+ }
+ return '';
+ },
+
+ _computeCheckmarkClass: function(checked) {
+ if (!checked) {
+ return 'hidden';
+ }
+ return '';
+ }
+ })
+ </script>
+
+</dom-module>
diff --git a/polymer_1.0.4/bower_components/paper-checkbox/test/basic.html b/polymer_1.0.4/bower_components/paper-checkbox/test/basic.html
new file mode 100644
index 0000000..d9cd514
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-checkbox/test/basic.html
@@ -0,0 +1,101 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>paper-radio-button basic tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+ <script src="../../iron-test-helpers/mock-interactions.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../paper-checkbox.html">
+
+</head>
+<body>
+
+ <test-fixture id="NoLabel">
+ <template>
+ <paper-checkbox id="check1"></paper-checkbox>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="WithLabel">
+ <template>
+ <paper-checkbox id="check2">Batman</paper-checkbox>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('defaults', function() {
+ var c1;
+
+ setup(function() {
+ c1 = fixture('NoLabel');
+ });
+
+ test('check checkbox via click', function() {
+ c1.addEventListener('click', function() {
+ assert.isTrue(c1.getAttribute('aria-checked'));
+ assert.isTrue(c1.checked);
+ done();
+ });
+ MockInteractions.down(c1);
+ });
+
+ test('toggle checkbox via click', function() {
+ c1.checked = true;
+ c1.addEventListener('click', function() {
+ assert.isFalse(c1.getAttribute('aria-checked'));
+ assert.isFalse(c1.checked);
+ done();
+ });
+ MockInteractions.down(c1);
+ });
+
+ test('disabled checkbox cannot be clicked', function() {
+ c1.disabled = true;
+ c1.addEventListener('click', function() {
+ assert.isTrue(c1.getAttribute('aria-checked'));
+ assert.isTrue(c1.checked);
+ done();
+ });
+ MockInteractions.down(c1);
+ });
+ });
+
+ suite('a11y', function() {
+ var c1;
+ var c2;
+
+ setup(function() {
+ c1 = fixture('NoLabel');
+ c2 = fixture('WithLabel');
+ });
+
+ test('has aria role "checkbox"', function() {
+ assert.isTrue(c1.getAttribute('role') == 'checkbox');
+ assert.isTrue(c2.getAttribute('role') == 'checkbox');
+ });
+
+ test('checkbox with no label has no aria label', function() {
+ assert.isTrue(!c1.getAttribute('aria-label'));
+ });
+
+ test('checkbox with a label sets an aria label', function() {
+ assert.isTrue(c2.getAttribute('aria-label') == "Batman");
+ });
+ });
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-checkbox/test/index.html b/polymer_1.0.4/bower_components/paper-checkbox/test/index.html
new file mode 100644
index 0000000..ac9a12c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-checkbox/test/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>paper-checkbox tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-dialog-behavior/.bower.json b/polymer_1.0.4/bower_components/paper-dialog-behavior/.bower.json
new file mode 100644
index 0000000..0a7138b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-behavior/.bower.json
@@ -0,0 +1,46 @@
+{
+ "name": "paper-dialog-behavior",
+ "version": "1.0.4",
+ "description": "Implements a behavior used for material design dialogs",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "dialog",
+ "overlay",
+ "behavior"
+ ],
+ "main": [
+ "paper-dialog-behavior.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-dialog-behavior"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-dialog-behavior",
+ "ignore": [],
+ "dependencies": {
+ "iron-overlay-behavior": "PolymerElements/iron-overlay-behavior#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.4",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "paper-button": "PolymerElements/paper-button#^1.0.0",
+ "paper-dialog-scrollable": "PolymerElements/paper-dialog-scrollable#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.4",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.4",
+ "commit": "09662387b0bc55651dd7b9ef8d38b3b8f55ecf3c"
+ },
+ "_source": "git://github.com/PolymerElements/paper-dialog-behavior.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-dialog-behavior"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-dialog-behavior/.gitignore b/polymer_1.0.4/bower_components/paper-dialog-behavior/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-behavior/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-dialog-behavior/README.md b/polymer_1.0.4/bower_components/paper-dialog-behavior/README.md
new file mode 100644
index 0000000..2c63d3c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-behavior/README.md
@@ -0,0 +1,24 @@
+# paper-dialog-behavior
+
+`paper-dialog-behavior` implements behavior related to a Material Design dialog. Use this behavior
+and include `paper-dialog-common.css` in your element to implement a dialog.
+
+`paper-dialog-common.css` provide styles for a header, content area, and an action area for buttons.
+Use the `<h2>` tag for the header and the `buttons` class for the action area. You can use the
+`paper-dialog-scrollable` element (in its own repository) if you need a scrolling content area.
+
+Use the `dialog-dismiss` and `dialog-confirm` attributes on interactive controls to close the
+dialog.
+
+For example, if `<paper-dialog-impl>` implements this behavior:
+
+```html
+<paper-dialog-impl>
+ <h2>Header</h2>
+ <div>Dialog body</div>
+ <div class="buttons">
+ <paper-button dialog-dismiss>Cancel</paper-button>
+ <paper-button dialog-confirm>Accept</paper-button>
+ </div>
+</paper-dialog-impl>
+```
diff --git a/polymer_1.0.4/bower_components/paper-dialog-behavior/bower.json b/polymer_1.0.4/bower_components/paper-dialog-behavior/bower.json
new file mode 100644
index 0000000..9ff98a0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-behavior/bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "paper-dialog-behavior",
+ "version": "1.0.4",
+ "description": "Implements a behavior used for material design dialogs",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "dialog",
+ "overlay",
+ "behavior"
+ ],
+ "main": [
+ "paper-dialog-behavior.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-dialog-behavior"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-dialog-behavior",
+ "ignore": [],
+ "dependencies": {
+ "iron-overlay-behavior": "PolymerElements/iron-overlay-behavior#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.4",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "paper-button": "PolymerElements/paper-button#^1.0.0",
+ "paper-dialog-scrollable": "PolymerElements/paper-dialog-scrollable#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-dialog-behavior/demo/index.html b/polymer_1.0.4/bower_components/paper-dialog-behavior/demo/index.html
new file mode 100644
index 0000000..3f354e7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-behavior/demo/index.html
@@ -0,0 +1,96 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>paper-dialog-behavior demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="simple-dialog.html">
+
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../../paper-button/paper-button.html">
+ <link rel="import" href="../../paper-dialog-scrollable/paper-dialog-scrollable.html">
+
+ <style is="custom-style">
+ .centered {
+ text-align: center;
+ }
+ </style>
+</head>
+<body unresolved onclick="clickHandler(event)">
+
+ <div class="vertical-section centered">
+
+ <button data-dialog="dialog">dialog</button>
+
+ <simple-dialog id="dialog">
+ <h2>Dialog Title</h2>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ </simple-dialog>
+
+ <button data-dialog="alert">modal alert</button>
+
+ <simple-dialog id="alert" modal role="alertdialog">
+ <h2>Alert</h2>
+ <p>Discard draft?</p>
+ <div class="buttons">
+ <paper-button dialog-dismiss>Cancel</paper-button>
+ <paper-button dialog-confirm autofocus>Discard</paper-button>
+ </div>
+ </simple-dialog>
+
+ <button data-dialog="scrolling">scrolling</button>
+
+ <simple-dialog id="scrolling">
+ <h2>Scrolling</h2>
+ <paper-dialog-scrollable>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ </paper-dialog-scrollable>
+ <div class="buttons">
+ <paper-button dialog-dismiss>Cancel</paper-button>
+ <paper-button dialog-confirm>OK</paper-button>
+ </div>
+ </simple-dialog>
+
+ </div>
+
+ <script>
+
+ function clickHandler(e) {
+ if (!e.target.hasAttribute('data-dialog')) {
+ return;
+ }
+
+ var id = e.target.getAttribute('data-dialog');
+ var dialog = document.getElementById(id);
+ if (dialog) {
+ dialog.toggle();
+ e.target.toggleAttribute && e.target.toggleAttribute('data-dialog-opened', dialog.opened);
+ }
+ }
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-dialog-behavior/demo/simple-dialog.html b/polymer_1.0.4/bower_components/paper-dialog-behavior/demo/simple-dialog.html
new file mode 100644
index 0000000..1bda9cd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-behavior/demo/simple-dialog.html
@@ -0,0 +1,42 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../../paper-styles/paper-styles.html">
+
+<link rel="import" href="../paper-dialog-behavior.html">
+
+<dom-module id="simple-dialog">
+
+ <link rel="import" type="css" href="../paper-dialog-common.css">
+
+ <template>
+ <content></content>
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'simple-dialog',
+
+ behaviors: [
+ Polymer.PaperDialogBehavior
+ ]
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-dialog-behavior/hero.svg b/polymer_1.0.4/bower_components/paper-dialog-behavior/hero.svg
new file mode 100755
index 0000000..d473816
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-behavior/hero.svg
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <g>
+ <polygon points="76.7,98 79.2,98 74,91.1 74,94.4 "/>
+ <polygon points="74,81.4 74,84.7 84.1,98 86.6,98 "/>
+ <polygon points="74,71.7 74,75 91.5,98 94,98 "/>
+ <polygon points="74,62 74,65.3 98.9,98 101.4,98 "/>
+ <polygon points="94.3,79 92,79 92,76 74,52.3 74,55.6 106.2,98 108.7,98 "/>
+ <polygon points="92,69.6 92,66.3 74,42.6 74,45.9 "/>
+ <polygon points="101.7,79 99.2,79 113.6,98 116.1,98 "/>
+ <polygon points="92,59.9 92,56.6 74,32.9 74,36.2 "/>
+ <polygon points="109.1,79 106.5,79 121,98 123.5,98 "/>
+ <polygon points="92,50.2 92,47 92.1,47 77.7,28 75.2,28 "/>
+ <polygon points="116.4,79 113.9,79 128.4,98 130.9,98 "/>
+ <polygon points="97,47 99.5,47 85,28 82.5,28 "/>
+ <polygon points="123.8,79 121.3,79 135.7,98 138.2,98 "/>
+ <polygon points="104.4,47 106.9,47 92.4,28 89.9,28 "/>
+ <polygon points="131.2,79 128.7,79 143.1,98 145.6,98 "/>
+ <polygon points="132,70.4 132,73.7 150,97.4 150,94.1 "/>
+ <polygon points="111.7,47 114.2,47 99.8,28 97.3,28 "/>
+ <polygon points="132,60.7 132,64 150,87.7 150,84.3 "/>
+ <polygon points="119.1,47 121.6,47 107.2,28 104.7,28 "/>
+ <polygon points="132,51 132,54.3 150,77.9 150,74.6 "/>
+ <polygon points="114.6,28 112,28 126.5,47 129,47 "/>
+ <polygon points="121.9,28 119.4,28 150,68.2 150,64.9 "/>
+ <polygon points="129.3,28 126.8,28 150,58.5 150,55.2 "/>
+ <polygon points="136.7,28 134.2,28 150,48.8 150,45.5 "/>
+ <polygon points="144.1,28 141.5,28 150,39.1 150,35.8 "/>
+ <polygon points="150,29.4 150,28 148.9,28 "/>
+ </g>
+ <path d="M133,80H91V46h42V80z M93,78h38V48H93V78z"/>
+ <path d="M151,99H73V27h78V99z M75,97h74V29H75V97z"/>
+ <circle cx="74" cy="28" r="4"/>
+ <circle cx="150" cy="28" r="4"/>
+ <circle cx="150" cy="98" r="4"/>
+ <circle cx="74" cy="98" r="4"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-dialog-behavior/index.html b/polymer_1.0.4/bower_components/paper-dialog-behavior/index.html
new file mode 100644
index 0000000..af98b85
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-behavior/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>paper-dialog-behavior</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-dialog-behavior/paper-dialog-behavior.html b/polymer_1.0.4/bower_components/paper-dialog-behavior/paper-dialog-behavior.html
new file mode 100644
index 0000000..0afcb8b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-behavior/paper-dialog-behavior.html
@@ -0,0 +1,239 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-overlay-behavior/iron-overlay-behavior.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+
+<script>
+
+/**
+Use `Polymer.PaperDialogBehavior` and `paper-dialog-common.css` to implement a Material Design
+dialog.
+
+For example, if `<paper-dialog-impl>` implements this behavior:
+
+ <paper-dialog-impl>
+ <h2>Header</h2>
+ <div>Dialog body</div>
+ <div class="buttons">
+ <paper-button dialog-dismiss>Cancel</paper-button>
+ <paper-button dialog-confirm>Accept</paper-button>
+ </div>
+ </paper-dialog-impl>
+
+`paper-dialog-common.css` provide styles for a header, content area, and an action area for buttons.
+Use the `<h2>` tag for the header and the `buttons` class for the action area. You can use the
+`paper-dialog-scrollable` element (in its own repository) if you need a scrolling content area.
+
+Use the `dialog-dismiss` and `dialog-confirm` attributes on interactive controls to close the
+dialog. If the user dismisses the dialog with `dialog-confirm`, the `closingReason` will update
+to include `confirmed: true`.
+
+### Styling
+
+The following custom properties and mixins are available for styling.
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-dialog-background-color` | Dialog background color | `--primary-background-color`
+`--paper-dialog-color` | Dialog foreground color | `--primary-text-color`
+`--paper-dialog` | Mixin applied to the dialog | `{}`
+`--paper-dialog-title` | Mixin applied to the title (`<h2>`) element | `{}`
+`--paper-dialog-button-color` | Button area foreground color | `--default-primary-color`
+
+### Accessibility
+
+This element has `role="dialog"` by default. Depending on the context, it may be more appropriate
+to override this attribute with `role="alertdialog"`.
+
+If `modal` is set, the element will set `aria-modal` and prevent the focus from exiting the element.
+It will also ensure that focus remains in the dialog.
+
+The `aria-labelledby` attribute will be set to the header element, if one exists.
+
+@hero hero.svg
+@demo demo/index.html
+@polymerBehavior Polymer.PaperDialogBehavior
+*/
+
+ Polymer.PaperDialogBehaviorImpl = {
+
+ hostAttributes: {
+ 'role': 'dialog',
+ 'tabindex': '-1'
+ },
+
+ properties: {
+
+ /**
+ * If `modal` is true, this implies `no-cancel-on-outside-click` and `with-backdrop`.
+ */
+ modal: {
+ observer: '_modalChanged',
+ type: Boolean,
+ value: false
+ },
+
+ /** @type {?Node} */
+ _lastFocusedElement: {
+ type: Object
+ },
+
+ _boundOnFocus: {
+ type: Function,
+ value: function() {
+ return this._onFocus.bind(this);
+ }
+ },
+
+ _boundOnBackdropClick: {
+ type: Function,
+ value: function() {
+ return this._onBackdropClick.bind(this);
+ }
+ }
+
+ },
+
+ listeners: {
+ 'click': '_onDialogClick',
+ 'iron-overlay-opened': '_onIronOverlayOpened',
+ 'iron-overlay-closed': '_onIronOverlayClosed'
+ },
+
+ attached: function() {
+ this._observer = this._observe(this);
+ this._updateAriaLabelledBy();
+ },
+
+ detached: function() {
+ if (this._observer) {
+ this._observer.disconnect();
+ }
+ },
+
+ _observe: function(node) {
+ var observer = new MutationObserver(function() {
+ this._updateAriaLabelledBy();
+ }.bind(this));
+ observer.observe(node, {
+ childList: true,
+ subtree: true
+ });
+ return observer;
+ },
+
+ _modalChanged: function() {
+ if (this.modal) {
+ this.setAttribute('aria-modal', 'true');
+ } else {
+ this.setAttribute('aria-modal', 'false');
+ }
+ // modal implies noCancelOnOutsideClick and withBackdrop if true, don't overwrite
+ // those properties otherwise.
+ if (this.modal) {
+ this.noCancelOnOutsideClick = true;
+ this.withBackdrop = true;
+ }
+ },
+
+ _updateAriaLabelledBy: function() {
+ var header = Polymer.dom(this).querySelector('h2');
+ if (!header) {
+ this.removeAttribute('aria-labelledby');
+ return;
+ }
+ var headerId = header.getAttribute('id');
+ if (headerId && this.getAttribute('aria-labelledby') === headerId) {
+ return;
+ }
+ // set aria-describedBy to the header element
+ var labelledById;
+ if (headerId) {
+ labelledById = headerId;
+ } else {
+ labelledById = 'paper-dialog-header-' + new Date().getUTCMilliseconds();
+ header.setAttribute('id', labelledById);
+ }
+ this.setAttribute('aria-labelledby', labelledById);
+ },
+
+ _updateClosingReasonConfirmed: function(confirmed) {
+ this.closingReason = this.closingReason || {};
+ this.closingReason.confirmed = confirmed;
+ },
+
+ _onDialogClick: function(event) {
+ var target = event.target;
+ while (target && target !== this) {
+ if (target.hasAttribute) {
+ if (target.hasAttribute('dialog-dismiss')) {
+ this._updateClosingReasonConfirmed(false);
+ this.close();
+ break;
+ } else if (target.hasAttribute('dialog-confirm')) {
+ this._updateClosingReasonConfirmed(true);
+ this.close();
+ break;
+ }
+ }
+ target = target.parentNode;
+ }
+ },
+
+ _onIronOverlayOpened: function() {
+ if (this.modal) {
+ document.body.addEventListener('focus', this._boundOnFocus, true);
+ this.backdropElement.addEventListener('click', this._boundOnBackdropClick);
+ }
+ },
+
+ _onIronOverlayClosed: function() {
+ document.body.removeEventListener('focus', this._boundOnFocus, true);
+ this.backdropElement.removeEventListener('click', this._boundOnBackdropClick);
+ },
+
+ _onFocus: function(event) {
+ if (this.modal) {
+ var target = event.target;
+ while (target && target !== this && target !== document.body) {
+ target = target.parentNode;
+ }
+ if (target) {
+ if (target === document.body) {
+ if (this._lastFocusedElement) {
+ this._lastFocusedElement.focus();
+ } else {
+ this._focusNode.focus();
+ }
+ } else {
+ this._lastFocusedElement = event.target;
+ }
+ }
+ }
+ },
+
+ _onBackdropClick: function() {
+ if (this.modal) {
+ if (this._lastFocusedElement) {
+ this._lastFocusedElement.focus();
+ } else {
+ this._focusNode.focus();
+ }
+ }
+ }
+
+ };
+
+ /** @polymerBehavior */
+ Polymer.PaperDialogBehavior = [Polymer.IronOverlayBehavior, Polymer.PaperDialogBehaviorImpl];
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-dialog-behavior/paper-dialog-common.css b/polymer_1.0.4/bower_components/paper-dialog-behavior/paper-dialog-common.css
new file mode 100644
index 0000000..542f6f3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-behavior/paper-dialog-common.css
@@ -0,0 +1,58 @@
+/*
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+*/
+
+:host {
+ display: block;
+ margin: 24px 40px;
+
+ background: var(--paper-dialog-background-color, --primary-background-color);
+ color: var(--paper-dialog-color, --primary-text-color);
+
+ @apply(--layout-scroll);
+ @apply(--paper-font-body1);
+ @apply(--shadow-elevation-16dp);
+ @apply(--paper-dialog);
+}
+
+:host > ::content > * {
+ margin-top: 20px;
+ padding: 0 24px;
+}
+
+:host > ::content > .no-padding {
+ padding: 0;
+}
+
+:host > ::content > *:first-child {
+ margin-top: 24px;
+}
+
+:host > ::content > *:last-child {
+ margin-bottom: 24px;
+}
+
+:host > ::content h2 {
+ position: relative;
+ margin: 0;
+ @apply(--paper-font-title);
+
+ @apply(--paper-dialog-title);
+}
+
+:host > ::content .buttons {
+ position: relative;
+ padding: 8px 8px 8px 24px;
+ margin: 0;
+
+ color: var(--paper-dialog-button-color, --default-primary-color);
+
+ @apply(--layout-horizontal);
+ @apply(--layout-end-justified);
+}
diff --git a/polymer_1.0.4/bower_components/paper-dialog-behavior/test/index.html b/polymer_1.0.4/bower_components/paper-dialog-behavior/test/index.html
new file mode 100644
index 0000000..7a7b2d0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-behavior/test/index.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>paper-dialog tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'paper-dialog-behavior.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-dialog-behavior/test/paper-dialog-behavior.html b/polymer_1.0.4/bower_components/paper-dialog-behavior/test/paper-dialog-behavior.html
new file mode 100644
index 0000000..f34bd83
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-behavior/test/paper-dialog-behavior.html
@@ -0,0 +1,231 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>paper-dialog-behavior tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="test-dialog.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="basic">
+ <template>
+ <test-dialog>
+ <p>Dialog</p>
+ <div class="buttons">
+ <button extra>extra</button>
+ <button dialog-dismiss>dismiss</button>
+ <button dialog-confirm>confirm</button>
+ </div>
+ </test-dialog>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="modal">
+ <template>
+ <test-dialog modal>
+ <p>Dialog</p>
+ <div class="buttons">
+ <button dialog-dismiss>dismiss</button>
+ <button dialog-confirm autofocus>confirm</button>
+ </div>
+ </test-dialog>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="backdrop">
+ <template>
+ <test-dialog with-backdrop>
+ <p>Dialog</p>
+ <div class="buttons">
+ <button dialog-dismiss>dismiss</button>
+ <button dialog-confirm autofocus>confirm</button>
+ </div>
+ </test-dialog>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="header">
+ <template>
+ <test-dialog>
+ <h2>Dialog</h2>
+ <div class="buttons">
+ <button dialog-dismiss>dismiss</button>
+ <button dialog-confirm autofocus>confirm</button>
+ </div>
+ </test-dialog>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="header-with-id">
+ <template>
+ <test-dialog>
+ <h2 id="header">Dialog</h2>
+ <div class="buttons">
+ <button dialog-dismiss>dismiss</button>
+ <button dialog-confirm autofocus>confirm</button>
+ </div>
+ </test-dialog>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ function runAfterOpen(dialog, cb) {
+ dialog.addEventListener('iron-overlay-opened', function() {
+ cb();
+ });
+ dialog.open();
+ }
+
+ suite('basic', function() {
+
+ test('clicking dialog does not cancel the dialog', function(done) {
+ var dialog = fixture('basic');
+ runAfterOpen(dialog, function() {
+ dialog.addEventListener('iron-overlay-closed', function() {
+ assert('dialog should not close');
+ });
+ dialog.click();
+ setTimeout(function() {
+ done();
+ }, 100);
+ });
+ });
+
+ test('clicking dialog-dismiss button closes the dialog without confirmation', function(done) {
+ var dialog = fixture('basic');
+ runAfterOpen(dialog, function() {
+ dialog.addEventListener('iron-overlay-closed', function(event) {
+ assert.isFalse(event.detail.canceled, 'dialog is not canceled');
+ assert.isFalse(event.detail.confirmed, 'dialog is not confirmed');
+ done();
+ });
+ Polymer.dom(dialog).querySelector('[dialog-dismiss]').click();
+ });
+ });
+
+ test('clicking dialog-confirm button closes the dialog with confirmation', function(done) {
+ var dialog = fixture('basic');
+ runAfterOpen(dialog, function() {
+ dialog.addEventListener('iron-overlay-closed', function(event) {
+ assert.isFalse(event.detail.canceled, 'dialog is not canceled');
+ assert.isTrue(event.detail.confirmed, 'dialog is confirmed');
+ done();
+ });
+ Polymer.dom(dialog).querySelector('[dialog-confirm]').click();
+ });
+ });
+
+ test('with-backdrop works', function() {
+ var dialog = fixture('backdrop');
+ runAfterOpen(dialog, function() {
+ assert.isTrue(dialog.backdropElement.opened, 'backdrop is open');
+ });
+ });
+
+ test('modal dialog has backdrop', function() {
+ var dialog = fixture('modal');
+ assert.isTrue(dialog.withBackdrop, 'withBackdrop is true');
+ });
+
+ test('modal dialog has no-cancel-on-outside-click', function() {
+ var dialog = fixture('modal');
+ assert.isTrue(dialog.noCancelOnOutsideClick, 'noCancelOnOutsideClick is true');
+ });
+
+ test('clicking outside a modal dialog does not move focus from dialog', function(done) {
+ var dialog = fixture('modal');
+ runAfterOpen(dialog, function() {
+ dialog.backdropElement.click();
+ setTimeout(function() {
+ assert.equal(document.activeElement, Polymer.dom(dialog).querySelector('[autofocus]'), 'document.activeElement is the autofocused button');
+ done();
+ }, 10);
+ });
+ });
+
+ test('removing a child element on click does not cause an exception', function(done) {
+ var dialog = fixture('basic');
+ runAfterOpen(dialog, function() {
+ var button = Polymer.dom(dialog).querySelector('[extra]');
+ button.addEventListener('click', function(event) {
+ Polymer.dom(event.target.parentNode).removeChild(event.target);
+ // should not throw exception here
+ done();
+ });
+ button.click();
+ });
+ });
+
+ });
+
+ suite('a11y', function() {
+
+ test('dialog has role="dialog"', function() {
+ var dialog = fixture('basic');
+ assert.equal(dialog.getAttribute('role'), 'dialog', 'has role="dialog"');
+ });
+
+ test('dialog has aria-modal=false', function() {
+ var dialog = fixture('basic');
+ assert.equal(dialog.getAttribute('aria-modal'), 'false', 'has aria-modal="false"');
+ });
+
+ test('modal dialog has aria-modal=true', function() {
+ var dialog = fixture('modal');
+ assert.equal(dialog.getAttribute('aria-modal'), 'true', 'has aria-modal="true"');
+ });
+
+ test('dialog with header has aria-labelledby', function() {
+ var dialog = fixture('header');
+ var header = Polymer.dom(dialog).querySelector('h2');
+ assert.ok(header.getAttribute('id'), 'header has auto-generated id');
+ assert.equal(dialog.getAttribute('aria-labelledby'), header.getAttribute('id'), 'aria-labelledby is set to header id');
+ });
+
+ test('dialog with lazily created header has aria-labelledby', function(done) {
+ var dialog = fixture('basic');
+ var header = document.createElement('h2');
+ Polymer.dom(dialog).appendChild(header);
+ Polymer.dom.flush();
+ setTimeout(function() {
+ assert.ok(header.getAttribute('id'), 'header has auto-generated id');
+ assert.equal(dialog.getAttribute('aria-labelledby'), header.getAttribute('id'), 'aria-labelledby is set to header id');
+ done();
+ }, 10);
+ });
+
+ test('dialog with header with id preserves id and has aria-labelledby', function() {
+ var dialog = fixture('header-with-id');
+ var header = Polymer.dom(dialog).querySelector('h2');
+ assert.equal(header.getAttribute('id'), 'header', 'header has preset id');
+ assert.equal(dialog.getAttribute('aria-labelledby'), 'header', 'aria-labelledby is set to header id');
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-dialog-behavior/test/test-dialog.html b/polymer_1.0.4/bower_components/paper-dialog-behavior/test/test-dialog.html
new file mode 100644
index 0000000..6a3952a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-behavior/test/test-dialog.html
@@ -0,0 +1,42 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../../paper-styles/paper-styles.html">
+
+<link rel="import" href="../paper-dialog-behavior.html">
+
+<dom-module id="test-dialog">
+
+ <link rel="import" type="css" href="../paper-dialog-common.css">
+
+ <template>
+ <content></content>
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'test-dialog',
+
+ behaviors: [
+ Polymer.PaperDialogBehavior
+ ]
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-dialog-scrollable/.bower.json b/polymer_1.0.4/bower_components/paper-dialog-scrollable/.bower.json
new file mode 100644
index 0000000..a7eda78
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-scrollable/.bower.json
@@ -0,0 +1,45 @@
+{
+ "name": "paper-dialog-scrollable",
+ "version": "1.0.1",
+ "description": "A scrollable area used inside the material design dialog",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "dialog",
+ "overlay"
+ ],
+ "main": [
+ "paper-dialog-scrollable.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-dialog-scrollable"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-dialog-scrollable",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "94e65968791d9166d2d3bf186e449d042b10168f"
+ },
+ "_source": "git://github.com/PolymerElements/paper-dialog-scrollable.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-dialog-scrollable"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-dialog-scrollable/.gitignore b/polymer_1.0.4/bower_components/paper-dialog-scrollable/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-scrollable/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-dialog-scrollable/README.md b/polymer_1.0.4/bower_components/paper-dialog-scrollable/README.md
new file mode 100644
index 0000000..201d0af
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-scrollable/README.md
@@ -0,0 +1,8 @@
+# paper-dialog-scrollable
+
+`paper-dialog-scrollable` implements a scrolling area used in a Material Design dialog. Use this
+together with elements implementing `paper-dialog-behavior`.
+
+It shows a top divider after scrolling if it is not the first child in its parent container. It
+shows a bottom divider if it is scrollable and it is not the last child in its parent container.
+The bottom divider is hidden if it is scrolled to the bottom.
diff --git a/polymer_1.0.4/bower_components/paper-dialog-scrollable/bower.json b/polymer_1.0.4/bower_components/paper-dialog-scrollable/bower.json
new file mode 100644
index 0000000..17ae8f7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-scrollable/bower.json
@@ -0,0 +1,36 @@
+{
+ "name": "paper-dialog-scrollable",
+ "version": "1.0.1",
+ "description": "A scrollable area used inside the material design dialog",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "dialog",
+ "overlay"
+ ],
+ "main": [
+ "paper-dialog-scrollable.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-dialog-scrollable"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-dialog-scrollable",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-dialog-scrollable/demo/index.html b/polymer_1.0.4/bower_components/paper-dialog-scrollable/demo/index.html
new file mode 100644
index 0000000..120aa87
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-scrollable/demo/index.html
@@ -0,0 +1,290 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>paper-dialog-scrollable demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-dialog-scrollable.html">
+
+ <link rel="import" href="../../paper-styles/classes/typography.html">
+ <link rel="import" href="../../iron-flex-layout/classes/iron-flex-layout.html">
+
+ <style>
+
+ section {
+ height: 100%;
+ }
+
+ .header, .footer {
+ padding: 8px 24px;
+ }
+
+ .footer {
+ text-align: right;
+ }
+
+ </style>
+
+</head>
+<body class="fullbleed">
+
+ <section class="layout vertical">
+
+ <div class="header paper-font-title">
+ Alice in Wonderland
+ </div>
+
+ <paper-dialog-scrollable class="flex paper-font-body1">
+
+ <p>Alice was beginning to get very tired of sitting by her sister
+ on the bank, and of having nothing to do: once or twice she had
+ peeped into the book her sister was reading, but it had no
+ pictures or conversations in it, 'and what is the use of a book,'
+ thought Alice 'without pictures or conversation?'</p>
+
+ <p>So she was considering in her own mind (as well as she could,
+ for the hot day made her feel very sleepy and stupid), whether
+ the pleasure of making a daisy-chain would be worth the trouble
+ of getting up and picking the daisies, when suddenly a White
+ Rabbit with pink eyes ran close by her.</p>
+
+ <p>There was nothing so <i>very</i> remarkable in that; nor did
+ Alice think it so <i>very</i> much out of the way to hear the
+ Rabbit say to itself, 'Oh dear! Oh dear! I shall be late!' (when
+ she thought it over afterwards, it occurred to her that she ought
+ to have wondered at this, but at the time it all seemed quite
+ natural); but when the Rabbit actually <i>took a watch out of its
+ waistcoat-pocket,</i> and looked at it, and then hurried on,
+ Alice started to her feet, for it flashed across her mind that
+ she had never before seen a rabbit with either a
+ waistcoat-pocket, or a watch to take out of it, and burning with
+ curiosity, she ran across the field after it, and fortunately was
+ just in time to see it pop down a large rabbit-hole under the
+ hedge.</p>
+
+ <p>In another moment down went Alice after it, never once
+ considering how in the world she was to get out again.</p>
+
+ <p>The rabbit-hole went straight on like a tunnel for some way,
+ and then dipped suddenly down, so suddenly that Alice had not a
+ moment to think about stopping herself before she found herself
+ falling down a very deep well.</p>
+
+ <p>Either the well was very deep, or she fell very slowly, for
+ she had plenty of time as she went down to look about her and to
+ wonder what was going to happen next. First, she tried to look
+ down and make out what she was coming to, but it was too dark to
+ see anything; then she looked at the sides of the well, and
+ noticed that they were filled with cupboards and book-shelves;
+ here and there she saw maps and pictures hung upon pegs. She took
+ down a jar from one of the shelves as she passed; it was labelled
+ 'ORANGE MARMALADE', but to her great disappointment it was empty:
+ she did not like to drop the jar for fear of killing somebody, so
+ managed to put it into one of the cupboards as she fell past
+ it.</p>
+
+ <p>'Well!' thought Alice to herself, 'after such a fall as this,
+ I shall think nothing of tumbling down stairs! How brave they'll
+ all think me at home! Why, I wouldn't say anything about it, even
+ if I fell off the top of the house!' (Which was very likely
+ true.)</p>
+
+ <p>Down, down, down. Would the fall <i>never</i> come to an end!
+ 'I wonder how many miles I've fallen by this time?' she said
+ aloud. 'I must be getting somewhere near the centre of the earth.
+ Let me see: that would be four thousand miles down, I think--'
+ (for, you see, Alice had learnt several things of this sort in
+ her lessons in the schoolroom, and though this was not a <i>very</i>
+ good opportunity for showing off her knowledge, as there was no
+ one to listen to her, still it was good practice to say it over)
+ '--yes, that's about the right distance--but then I wonder what
+ Latitude or Longitude I've got to?' (Alice had no idea what
+ Latitude was, or Longitude either, but thought they were nice
+ grand words to say.)</p>
+
+ <p>Presently she began again. 'I wonder if I shall fall right
+ <i>through</i> the earth! How funny it'll seem to come out among
+ the people that walk with their heads downward! The Antipathies,
+ I think--' (she was rather glad there <i>was</i> no one listening, this
+ time, as it didn't sound at all the right word) '--but I shall
+ have to ask them what the name of the country is, you know.
+ Please, Ma'am, is this New Zealand or Australia?' (and she tried
+ to curtsey as she spoke--fancy <i>curtseying</i> as you're
+ falling through the air! Do you think you could manage it?) 'And
+ what an ignorant little girl she'll think me for asking! No,
+ it'll never do to ask: perhaps I shall see it written up
+ somewhere.'</p>
+
+ <p>Down, down, down. There was nothing else to do, so Alice soon
+ began talking again. 'Dinah'll miss me very much to-night, I
+ should think!' (Dinah was the cat.) 'I hope they'll remember her
+ saucer of milk at tea-time. Dinah my dear! I wish you were down
+ here with me! There are no mice in the air, I'm afraid, but you
+ might catch a bat, and that's very like a mouse, you know. But do
+ cats eat bats, I wonder?' And here Alice began to get rather
+ sleepy, and went on saying to herself, in a dreamy sort of way,
+ 'Do cats eat bats? Do cats eat bats?' and sometimes, 'Do bats eat
+ cats?' for, you see, as she couldn't answer either question, it
+ didn't much matter which way she put it. She felt that she was
+ dozing off, and had just begun to dream that she was walking hand
+ in hand with Dinah, and saying to her very earnestly, 'Now,
+ Dinah, tell me the truth: did you ever eat a bat?' when suddenly,
+ thump! thump! down she came upon a heap of sticks and dry leaves,
+ and the fall was over.</p>
+
+ <p>Alice was not a bit hurt, and she jumped up on to her feet in
+ a moment: she looked up, but it was all dark overhead; before her
+ was another long passage, and the White Rabbit was still in
+ sight, hurrying down it. There was not a moment to be lost: away
+ went Alice like the wind, and was just in time to hear it say, as
+ it turned a corner, 'Oh my ears and whiskers, how late it's
+ getting!' She was close behind it when she turned the corner, but
+ the Rabbit was no longer to be seen: she found herself in a long,
+ low hall, which was lit up by a row of lamps hanging from the
+ roof.</p>
+
+ <p>There were doors all round the hall, but they were all locked;
+ and when Alice had been all the way down one side and up the
+ other, trying every door, she walked sadly down the middle,
+ wondering how she was ever to get out again.</p>
+
+ <p>Suddenly she came upon a little three-legged table, all made
+ of solid glass; there was nothing on it except a tiny golden key,
+ and Alice's first thought was that it might belong to one of the
+ doors of the hall; but, alas! either the locks were too large, or
+ the key was too small, but at any rate it would not open any of
+ them. However, on the second time round, she came upon a low
+ curtain she had not noticed before, and behind it was a little
+ door about fifteen inches high: she tried the little golden key
+ in the lock, and to her great delight it fitted!</p>
+
+ <p>Alice opened the door and found that it led into a small
+ passage, not much larger than a rat-hole: she knelt down and
+ looked along the passage into the loveliest garden you ever saw.
+ How she longed to get out of that dark hall, and wander about
+ among those beds of bright flowers and those cool fountains, but
+ she could not even get her head though the doorway; 'and even if
+ my head <i>would</i> go through,' thought poor Alice, 'it would
+ be of very little use without my shoulders. Oh, how I wish I
+ could shut up like a telescope! I think I could, if I only know
+ how to begin.' For, you see, so many out-of-the-way things had
+ happened lately, that Alice had begun to think that very few
+ things indeed were really impossible.</p>
+
+ <p>There seemed to be no use in waiting by the little door, so
+ she went back to the table, half hoping she might find another
+ key on it, or at any rate a book of rules for shutting people up
+ like telescopes: this time she found a little bottle on it,
+ ('which certainly was not here before,' said Alice,) and round
+ the neck of the bottle was a paper label, with the words 'DRINK
+ ME' beautifully printed on it in large letters.</p>
+
+ <p>It was all very well to say 'Drink me,' but the wise little
+ Alice was not going to do <i>that</i> in a hurry. 'No, I'll look
+ first,' she said, 'and see whether it's marked "<i>poison</i>" or
+ not'; for she had read several nice little histories about
+ children who had got burnt, and eaten up by wild beasts and other
+ unpleasant things, all because they <i>would</i> not remember the
+ simple rules their friends had taught them: such as, that a
+ red-hot poker will burn you if you hold it too long; and that if
+ you cut your finger <i>very</i> deeply with a knife, it usually
+ bleeds; and she had never forgotten that, if you drink much from
+ a bottle marked '<i>poison</i>,' it is almost certain to disagree
+ with you, sooner or later.</p>
+
+ <p>However, this bottle was <i>not</i> marked 'poison,' so Alice
+ ventured to taste it, and finding it very nice, (it had, in fact,
+ a sort of mixed flavour of cherry-tart, custard, pine-apple,
+ roast turkey, toffee, and hot buttered toast,) she very soon
+ finished it off.</p>
+
+ <p class="asterisks">
+ <br>
+ * * * * *
+ <br>
+ * * * *
+ <br>
+ * * * * *
+ <br>
+ </p>
+
+ <p>'What a curious feeling!' said Alice; 'I must be shutting up
+ like a telescope.'</p>
+
+ <p>And so it was indeed: she was now only ten inches high, and
+ her face brightened up at the thought that she was now the right
+ size for going through the little door into that lovely garden.
+ First, however, she waited for a few minutes to see if she was
+ going to shrink any further: she felt a little nervous about
+ this; 'for it might end, you know,' said Alice to herself, 'in my
+ going out altogether, like a candle. I wonder what I should be
+ like then?' And she tried to fancy what the flame of a candle is
+ like after the candle is blown out, for she could not remember
+ ever having seen such a thing.</p>
+
+ <p>After a while, finding that nothing more happened, she decided
+ on going into the garden at once; but, alas for poor Alice! when
+ she got to the door, she found she had forgotten the little
+ golden key, and when she went back to the table for it, she found
+ she could not possibly reach it: she could see it quite plainly
+ through the glass, and she tried her best to climb up one of the
+ legs of the table, but it was too slippery; and when she had
+ tired herself out with trying, the poor little thing sat down and
+ cried.</p>
+
+ <p>'Come, there's no use in crying like that!' said Alice to
+ herself, rather sharply; 'I advise you to leave off this minute!'
+ She generally gave herself very good advice, (though she very
+ seldom followed it), and sometimes she scolded herself so
+ severely as to bring tears into her eyes; and once she remembered
+ trying to box her own ears for having cheated herself in a game
+ of croquet she was playing against herself, for this curious
+ child was very fond of pretending to be two people. 'But it's no
+ use now,' thought poor Alice, 'to pretend to be two people! Why,
+ there's hardly enough of me left to make <i>one</i> respectable
+ person!'</p>
+
+ <p>Soon her eye fell on a little glass box that was lying under
+ the table: she opened it, and found in it a very small cake, on
+ which the words 'EAT ME' were beautifully marked in currants.
+ 'Well, I'll eat it,' said Alice, 'and if it makes me grow larger,
+ I can reach the key; and if it makes me grow smaller, I can creep
+ under the door; so either way I'll get into the garden, and I
+ don't care which happens!'</p>
+
+ <p>She ate a little bit, and said anxiously to herself, 'Which
+ way? Which way?', holding her hand on the top of her head to feel
+ which way it was growing, and she was quite surprised to find
+ that she remained the same size: to be sure, this generally
+ happens when one eats cake, but Alice had got so much into the
+ way of expecting nothing but out-of-the-way things to happen,
+ that it seemed quite dull and stupid for life to go on in the
+ common way.</p>
+
+ <p>So she set to work, and very soon finished off the cake.</p>
+
+ </paper-dialog-scrollable>
+
+ <div class="footer paper-font-subhead">
+ Lewis Carroll
+ </div>
+
+ </section>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-dialog-scrollable/hero.svg b/polymer_1.0.4/bower_components/paper-dialog-scrollable/hero.svg
new file mode 100755
index 0000000..40bc69a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-scrollable/hero.svg
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <g>
+ <polygon points="0,124 0,126 2,126 "/>
+ <polygon points="0,111.6 0,114.4 11.6,126 14.4,126 "/>
+ <polygon points="0,99.1 0,101.9 24.1,126 26.9,126 "/>
+ <polygon points="0,86.6 0,89.5 36.5,126 39.4,126 "/>
+ <polygon points="0,74.2 0,77 49,126 51.8,126 "/>
+ <polygon points="0,61.7 0,64.5 61.5,126 64.3,126 "/>
+ <polygon points="0,49.2 0,52.1 73.9,126 76.8,126 "/>
+ <polygon points="0,36.8 0,39.6 86.4,126 89.2,126 "/>
+ <polygon points="76.7,101 74,101 74,98.3 0,24.3 0,27.1 98.9,126 101.7,126 "/>
+ <polygon points="74,88.7 74,85.8 0,11.8 0,14.7 "/>
+ <polygon points="89.2,101 86.3,101 111.3,126 114.2,126 "/>
+ <polygon points="101.6,101 98.8,101 123.8,126 126.6,126 "/>
+ <polygon points="74,76.2 74,73.4 0.6,0 0,0 0,2.2 "/>
+ <polygon points="114.1,101 111.3,101 136.3,126 139.1,126 "/>
+ <polygon points="74,63.7 74,60.9 13.1,0 10.3,0 "/>
+ <polygon points="74,51.3 74,48.4 25.6,0 22.7,0 "/>
+ <polygon points="126.6,101 123.7,101 148.7,126 151.6,126 "/>
+ <polygon points="74,38.8 74,36 38,0 35.2,0 "/>
+ <polygon points="139,101 136.2,101 161.2,126 164,126 "/>
+ <polygon points="74,26.3 74,25 75.5,25 50.5,0 47.7,0 "/>
+ <polygon points="150,99.5 150,101 148.7,101 173.7,126 176.5,126 "/>
+ <polygon points="150,87 150,89.9 186.1,126 189,126 "/>
+ <polygon points="85.1,25 88,25 63,0 60.1,0 "/>
+ <polygon points="150,74.6 150,77.4 198.6,126 201.4,126 "/>
+ <polygon points="97.6,25 100.4,25 75.4,0 72.6,0 "/>
+ <polygon points="150,62.1 150,64.9 211.1,126 213.9,126 "/>
+ <polygon points="110.1,25 112.9,25 87.9,0 85.1,0 "/>
+ <polygon points="150,49.7 150,52.5 223.5,126 225,126 225,124.7 "/>
+ <polygon points="122.5,25 125.3,25 100.3,0 97.5,0 "/>
+ <polygon points="112.8,0 110,0 135,25 137.8,25 "/>
+ <polygon points="150,37.2 150,40 225,115 225,112.2 "/>
+ <polygon points="125.3,0 122.5,0 147.5,25 150,25 150,27.5 225,102.5 225,99.7 "/>
+ <polygon points="137.7,0 134.9,0 225,90.1 225,87.3 "/>
+ <polygon points="150.2,0 147.4,0 225,77.6 225,74.8 "/>
+ <polygon points="162.7,0 159.8,0 225,65.2 225,62.3 "/>
+ <polygon points="175.1,0 172.3,0 225,52.7 225,49.9 "/>
+ <polygon points="187.6,0 184.8,0 225,40.2 225,37.4 "/>
+ <polygon points="200.1,0 197.2,0 225,27.8 225,24.9 "/>
+ <polygon points="212.5,0 209.7,0 225,15.3 225,12.5 "/>
+ <polygon points="225,0 222.2,0 225,2.8 225,0 "/>
+ </g>
+ <path d="M151,102H73V24h78V102z M75,100h74V26H75V100z"/>
+ <rect x="82" y="53" width="26" height="2"/>
+ <rect x="116" y="53" width="26" height="2"/>
+ <rect x="82" y="62" width="26" height="2"/>
+ <rect x="82" y="72" width="26" height="2"/>
+ <rect x="116" y="72" width="26" height="2"/>
+ <rect x="82" y="42" width="26" height="2"/>
+ <circle cx="120" cy="63" r="4"/>
+ <circle cx="134" cy="63" r="4"/>
+ <rect x="116" y="85" width="22" height="5.5"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-dialog-scrollable/index.html b/polymer_1.0.4/bower_components/paper-dialog-scrollable/index.html
new file mode 100644
index 0000000..2d2ec7e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-scrollable/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>paper-dialog-scrollable</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html b/polymer_1.0.4/bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html
new file mode 100644
index 0000000..5f46d9c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html
@@ -0,0 +1,151 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+
+<!--
+`paper-dialog-scrollable` implements a scrolling area used in a Material Design dialog. It shows
+a divider at the top and/or bottom indicating more content, depending on scroll position. Use this
+together with elements implementing `Polymer.PaperDialogBehavior`.
+
+ <paper-dialog-impl>
+ <h2>Header</h2>
+ <paper-dialog-scrollable>
+ Lorem ipsum...
+ </paper-dialog-scrollable>
+ <div class="buttons">
+ <paper-button>OK</paper-button>
+ </div>
+ </paper-dialog-impl>
+
+It shows a top divider after scrolling if it is not the first child in its parent container,
+indicating there is more content above. It shows a bottom divider if it is scrollable and it is not
+the last child in its parent container, indicating there is more content below. The bottom divider
+is hidden if it is scrolled to the bottom.
+
+@group Paper Elements
+@element paper-dialog-scrollable
+@demo demo/index.html
+@hero hero.svg
+-->
+
+<dom-module id="paper-dialog-scrollable">
+
+ <style>
+
+ :host {
+ display: block;
+ position: relative;
+ }
+
+ :host(.is-scrolled:not(:first-child))::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 1px;
+ background: var(--divider-color);
+ }
+
+ :host(.can-scroll:not(.scrolled-to-bottom):not(:last-child))::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 1px;
+ background: var(--divider-color);
+ }
+
+ .scrollable {
+ padding: 0 24px;
+
+ @apply(--layout-scroll);
+
+ @apply(--paper-dialog-scrollable);
+ }
+ </style>
+
+ <template>
+ <div id="scrollable" class="scrollable">
+ <content></content>
+ </div>
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'paper-dialog-scrollable',
+
+ properties: {
+
+ /**
+ * The dialog element that implements `Polymer.PaperDialogBehavior` containing this element.
+ * @type {?Node}
+ */
+ dialogElement: {
+ type: Object,
+ value: function() {
+ return this.parentNode;
+ }
+ }
+
+ },
+
+ listeners: {
+ 'scrollable.scroll': '_onScroll',
+ 'iron-resize': '_onIronResize'
+ },
+
+ /**
+ * Returns the scrolling element.
+ */
+ get scrollTarget() {
+ return this.$.scrollable;
+ },
+
+ attached: function() {
+ this.classList.add('no-padding');
+ // Set itself to the overlay sizing target
+ this.dialogElement.sizingTarget = this.scrollTarget;
+ // If the host is sized, fit the scrollable area to the container. Otherwise let it be
+ // its natural size.
+ requestAnimationFrame(function() {
+ if (this.offsetHeight > 0) {
+ this.$.scrollable.classList.add('fit');
+ }
+ this._scroll();
+ }.bind(this));
+ },
+
+ _scroll: function() {
+ this.toggleClass('is-scrolled', this.scrollTarget.scrollTop > 0);
+ this.toggleClass('can-scroll', this.scrollTarget.offsetHeight < this.scrollTarget.scrollHeight);
+ this.toggleClass('scrolled-to-bottom',
+ this.scrollTarget.scrollTop + this.scrollTarget.offsetHeight >= this.scrollTarget.scrollHeight);
+ },
+
+ _onScroll: function() {
+ this._scroll();
+ }
+
+ })
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-dialog-scrollable/test/index.html b/polymer_1.0.4/bower_components/paper-dialog-scrollable/test/index.html
new file mode 100644
index 0000000..cb5a5a9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-scrollable/test/index.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>paper-dialog tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'paper-dialog-scrollable.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-dialog-scrollable/test/paper-dialog-scrollable.html b/polymer_1.0.4/bower_components/paper-dialog-scrollable/test/paper-dialog-scrollable.html
new file mode 100644
index 0000000..e6606d6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog-scrollable/test/paper-dialog-scrollable.html
@@ -0,0 +1,171 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>paper-dialog-scrollable tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../paper-dialog-scrollable.html">
+
+ <link rel="import" href="../../iron-flex-layout/classes/iron-flex-layout.html">
+
+ <style>
+ .fixed-height {
+ height: 400px;
+ }
+ </style>
+
+ </head>
+ <body>
+
+ <test-fixture id="basic">
+ <template>
+ <section class="fixed-height layout vertical">
+ <div class="header">Header</div>
+ <paper-dialog-scrollable class="flex">
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ </paper-dialog-scrollable>
+ <div class="footer">Footer</div>
+ </section>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="only-child">
+ <template>
+ <section class="fixed-height layout vertical">
+ <paper-dialog-scrollable class="flex">
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ </paper-dialog-scrollable>
+ </section>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="short">
+ <template>
+ <section class="fixed-height layout vertical">
+ <div class="header">Header</div>
+ <paper-dialog-scrollable class="flex">
+ <p>Hello world!</p>
+ </paper-dialog-scrollable>
+ <div class="footer">Footer</div>
+ </section>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ function runAfterScroll(node, scrollTop, callback) {
+ var timeout = function() {
+ node.scrollTop = scrollTop;
+ if (node.scrollTop === scrollTop) {
+ // there seems to be no good way to wait for pseudoelement styling to apply and
+ // chrome takes a while before getComputedStyle returns the correct values
+ setTimeout(function() {
+ callback();
+ }, 250);
+ } else {
+ setTimeout(timeout, 10);
+ }
+ };
+ node.scrollTop = scrollTop;
+ setTimeout(timeout);
+ }
+
+ suite('basic', function() {
+
+ test('shows top divider if scrolled', function(done) {
+ var container = fixture('basic');
+ var scrollable = Polymer.dom(container).querySelector('paper-dialog-scrollable');
+ setTimeout(function() {
+ runAfterScroll(scrollable.scrollTarget, 10, function() {
+ assert.ok(getComputedStyle(scrollable, '::before').content, '::before has content');
+ done();
+ });
+ }, 10);
+ });
+
+ test('shows bottom divider if scrollable', function(done) {
+ var container = fixture('basic');
+ setTimeout(function() {
+ var scrollable = Polymer.dom(container).querySelector('paper-dialog-scrollable');
+ requestAnimationFrame(function() {
+ assert.ok(getComputedStyle(scrollable, '::after').content, '::after has content');
+ done();
+ });
+ }, 10);
+ });
+
+ test('hides bottom divider if scrolled to bottom', function(done) {
+ var container = fixture('basic');
+ var scrollable = Polymer.dom(container).querySelector('paper-dialog-scrollable');
+ setTimeout(function() {
+ runAfterScroll(scrollable.scrollTarget, scrollable.scrollTarget.scrollHeight - scrollable.scrollTarget.offsetHeight, function() {
+ var content = getComputedStyle(scrollable, '::after').content;
+ assert.ok(!content || content === 'none', '::after does not have content');
+ done();
+ });
+ }, 10);
+ });
+
+ test('does not show dividers if scrolled and only child', function(done) {
+ var container = fixture('only-child');
+ var scrollable = Polymer.dom(container).querySelector('paper-dialog-scrollable');
+ setTimeout(function() {
+ runAfterScroll(scrollable.scrollTarget, 10, function() {
+ var contentBefore = getComputedStyle(scrollable, '::before').content;
+ assert.ok(!contentBefore || contentBefore === 'none', '::before does not have content');
+ var contentAfter = getComputedStyle(scrollable, '::after').content;
+ assert.ok(!contentAfter || contentAfter === 'none', '::after does not have content');
+ done();
+ });
+ }, 10);
+ });
+
+ test('does not show bottom divider if not scrollable', function(done) {
+ var container = fixture('short');
+ setTimeout(function() {
+ var scrollable = Polymer.dom(container).querySelector('paper-dialog-scrollable');
+ var contentAfter = getComputedStyle(scrollable, '::after').content;
+ assert.ok(!contentAfter || contentAfter === 'none', '::after does not have content');
+ done();
+ }, 10);
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-dialog/.bower.json b/polymer_1.0.4/bower_components/paper-dialog/.bower.json
new file mode 100644
index 0000000..540adab
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog/.bower.json
@@ -0,0 +1,44 @@
+{
+ "name": "paper-dialog",
+ "description": "A Material Design dialog",
+ "version": "1.0.0",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "dialog",
+ "overlay"
+ ],
+ "main": "paper-dialog.html",
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-dialog"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-dialog",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "paper-dialog-behavior": "PolymerElements/paper-dialog-behavior#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "neon-animation": "PolymerElements/neon-animation#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "paper-button": "PolymerElements/paper-button#^1.0.0",
+ "paper-dialog-scrollable": "PolymerElements/paper-dialog-scrollable#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.0",
+ "commit": "6d66cf1e022e56ec28353a2f718e93535c7cac20"
+ },
+ "_source": "git://github.com/PolymerElements/paper-dialog.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-dialog"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-dialog/.gitignore b/polymer_1.0.4/bower_components/paper-dialog/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-dialog/README.md b/polymer_1.0.4/bower_components/paper-dialog/README.md
new file mode 100644
index 0000000..a4d5c7f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog/README.md
@@ -0,0 +1,3 @@
+# paper-dialog
+
+A Material Design dialog
diff --git a/polymer_1.0.4/bower_components/paper-dialog/bower.json b/polymer_1.0.4/bower_components/paper-dialog/bower.json
new file mode 100644
index 0000000..2bce00e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog/bower.json
@@ -0,0 +1,35 @@
+{
+ "name": "paper-dialog",
+ "description": "A Material Design dialog",
+ "version": "1.0.0",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "dialog",
+ "overlay"
+ ],
+ "main": "paper-dialog.html",
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-dialog"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-dialog",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "paper-dialog-behavior": "PolymerElements/paper-dialog-behavior#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "neon-animation": "PolymerElements/neon-animation#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "paper-button": "PolymerElements/paper-button#^1.0.0",
+ "paper-dialog-scrollable": "PolymerElements/paper-dialog-scrollable#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-dialog/demo/index.html b/polymer_1.0.4/bower_components/paper-dialog/demo/index.html
new file mode 100644
index 0000000..619c6dc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog/demo/index.html
@@ -0,0 +1,158 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>paper-dialog demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-dialog.html">
+ <link rel="import" href="../../paper-button/paper-button.html">
+ <link rel="import" href="../../paper-dialog-scrollable/paper-dialog-scrollable.html">
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../../neon-animation/neon-animations.html">
+
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+
+ <style is="custom-style">
+ section > paper-button {
+ background-color: var(--google-grey-300);
+ padding: 5px;
+ }
+
+ section > paper-button:hover {
+ background-color: var(--paper-light-blue-200);
+ padding: 5px;
+ }
+
+ paper-dialog.colored {
+ border: 2px solid;
+ border-color: var(--paper-green-500);
+ background-color: var(--paper-light-green-50);
+ color: var(--paper-green-500);
+ }
+
+ paper-dialog.size-position {
+ position: fixed;
+ top: 16px;
+ right: 16px;
+ }
+
+ paper-dialog.size-position {
+ width: 300px;
+ height: 300px;
+ }
+ </style>
+
+</head>
+<body>
+
+ <section onclick="clickHandler(event)">
+ <h4>Dialog layouts</h4>
+
+ <paper-button data-dialog="dialog">plain dialog</paper-button>
+ <paper-button data-dialog="scrolling">scrolling dialog</paper-button>
+ <paper-button data-dialog="actions">dialog with actions</paper-button>
+ <paper-button data-dialog="modal">modal dialog</paper-button>
+
+ <paper-dialog id="dialog">
+ <h2>Dialog Title</h2>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ </paper-dialog>
+
+ <paper-dialog id="scrolling">
+ <h2>Scrolling</h2>
+ <paper-dialog-scrollable>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ </paper-dialog-scrollable>
+ <div class="buttons">
+ <paper-button dialog-dismiss>Cancel</paper-button>
+ <paper-button dialog-confirm autofocus>OK</paper-button>
+ </div>
+ </paper-dialog>
+
+ <paper-dialog id="actions">
+ <h2>Dialog Title</h2>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ <div class="buttons">
+ <paper-button >More Info...</paper-button>
+ <paper-button dialog-dismiss>Decline</paper-button>
+ <paper-button dialog-confirm autofocus>Accept</paper-button>
+ </div>
+ </paper-dialog>
+
+ <paper-dialog id="modal" modal>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
+ <div class="buttons">
+ <paper-button dialog-confirm autofocus>Tap me to close</paper-button>
+ </div>
+ </paper-dialog>
+
+ </section>
+
+ <section onclick="clickHandler(event)">
+ <h4>Custom styling</h4>
+ <paper-button data-dialog="colors">colors</paper-button>
+ <paper-button data-dialog="position">size & position</paper-button>
+
+ <paper-dialog id="colors" heading="Custom Colors" class="colored">
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ </paper-dialog>
+
+ <paper-dialog id="position" heading="Custom Size & Position" class="size-position">
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ </paper-dialog>
+ </section>
+
+ <section onclick="clickHandler(event)">
+ <h4>Transitions</h4>
+ <paper-button data-dialog="animated">transitions</paper-button>
+ <paper-dialog id="animated" with-backdrop entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop>
+ <h2>Dialog Title</h2>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
+ </paper-dialog>
+ </section>
+
+ <script>
+ function clickHandler(e) {
+ var button = e.target;
+ while (!button.hasAttribute('data-dialog') && button !== document.body) {
+ button = button.parentElement;
+ }
+
+ if (!button.hasAttribute('data-dialog')) {
+ return;
+ }
+
+ var id = button.getAttribute('data-dialog');
+ var dialog = document.getElementById(id);
+ if (dialog) {
+ dialog.open();
+ }
+ }
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-dialog/hero.svg b/polymer_1.0.4/bower_components/paper-dialog/hero.svg
new file mode 100755
index 0000000..713329b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog/hero.svg
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <g>
+ <polygon points="0,124 0,126 2,126 "/>
+ <polygon points="0,111.6 0,114.4 11.6,126 14.4,126 "/>
+ <polygon points="0,99.1 0,101.9 24.1,126 26.9,126 "/>
+ <polygon points="0,86.6 0,89.5 36.5,126 39.4,126 "/>
+ <polygon points="0,74.2 0,77 49,126 51.8,126 "/>
+ <polygon points="0,61.7 0,64.5 61.5,126 64.3,126 "/>
+ <polygon points="0,49.2 0,52.1 73.9,126 76.8,126 "/>
+ <polygon points="0,36.8 0,39.6 86.4,126 89.2,126 "/>
+ <polygon points="0,24.3 0,27.1 98.9,126 101.7,126 "/>
+ <polygon points="75.2,87 74,87 74,85.8 0,11.8 0,14.7 111.3,126 114.2,126 "/>
+ <polygon points="87.6,87 84.8,87 123.8,126 126.6,126 "/>
+ <polygon points="74,76.2 74,73.4 0.6,0 0,0 0,2.2 "/>
+ <polygon points="74,63.7 74,60.9 13.1,0 10.3,0 "/>
+ <polygon points="100.1,87 97.3,87 136.3,126 139.1,126 "/>
+ <polygon points="112.6,87 109.7,87 148.7,126 151.6,126 "/>
+ <polygon points="74,51.3 74,48.4 25.6,0 22.7,0 "/>
+ <polygon points="125,87 122.2,87 161.2,126 164,126 "/>
+ <polygon points="74.2,39 77,39 38,0 35.2,0 "/>
+ <polygon points="86.7,39 89.5,39 50.5,0 47.7,0 "/>
+ <polygon points="137.5,87 134.7,87 173.7,126 176.5,126 "/>
+ <polygon points="150,87 147.1,87 186.1,126 189,126 "/>
+ <polygon points="99.1,39 102,39 63,0 60.1,0 "/>
+ <polygon points="150,74.6 150,77.4 198.6,126 201.4,126 "/>
+ <polygon points="111.6,39 114.4,39 75.4,0 72.6,0 "/>
+ <polygon points="150,62.1 150,64.9 211.1,126 213.9,126 "/>
+ <polygon points="124.1,39 126.9,39 87.9,0 85.1,0 "/>
+ <polygon points="100.3,0 97.5,0 136.5,39 139.3,39 "/>
+ <polygon points="150,49.7 150,52.5 223.5,126 225,126 225,124.7 "/>
+ <polygon points="112.8,0 110,0 149,39 150,39 150,40 225,115 225,112.2 "/>
+ <polygon points="125.3,0 122.5,0 225,102.5 225,99.7 "/>
+ <polygon points="137.7,0 134.9,0 225,90.1 225,87.3 "/>
+ <polygon points="150.2,0 147.4,0 225,77.6 225,74.8 "/>
+ <polygon points="162.7,0 159.8,0 225,65.2 225,62.3 "/>
+ <polygon points="175.1,0 172.3,0 225,52.7 225,49.9 "/>
+ <polygon points="187.6,0 184.8,0 225,40.2 225,37.4 "/>
+ <polygon points="200.1,0 197.2,0 225,27.8 225,24.9 "/>
+ <polygon points="212.5,0 209.7,0 225,15.3 225,12.5 "/>
+ <polygon points="225,0 222.2,0 225,2.8 225,0 "/>
+ </g>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+ <path d="M151,88H73V38h78V88z M75,86h74V40H75V86z"/>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-dialog/index.html b/polymer_1.0.4/bower_components/paper-dialog/index.html
new file mode 100644
index 0000000..6304b8d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>paper-dialog</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-dialog/paper-dialog.html b/polymer_1.0.4/bower_components/paper-dialog/paper-dialog.html
new file mode 100644
index 0000000..002e242
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog/paper-dialog.html
@@ -0,0 +1,122 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../neon-animation/neon-animation-runner-behavior.html">
+<link rel="import" href="../paper-dialog-behavior/paper-dialog-behavior.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+
+<!--
+`<paper-dialog>` is a dialog with Material Design styling and optional animations when it is
+opened or closed. It provides styles for a header, content area, and an action area for buttons.
+You can use the `<paper-dialog-scrollable` element (in its own repository) if you need a scrolling
+content area. See `Polymer.PaperDialogBehavior` for specifics.
+
+For example, the following code implements a dialog with a header, scrolling content area and
+buttons.
+
+ <paper-dialog>
+ <h2>Header</h2>
+ <paper-dialog-scrollable>
+ Lorem ipsum...
+ </paper-dialog-scrollable>
+ <div class="buttons">
+ <paper-button dialog-dismiss>Cancel</paper-button>
+ <paper-button dialog-confirm>Accept</paper-button>
+ </div>
+ </paper-dialog>
+
+### Styling
+
+See the docs for `Polymer.PaperDialogBehavior` for the custom properties available for styling
+this element.
+
+### Animations
+
+Set the `entry-animation` and/or `exit-animation` attributes to add an animation when the dialog
+is opened or closed. See the documentation in
+[PolymerElements/neon-animation](https://github.com/PolymerElements/neon-animation) for more info.
+
+For example:
+
+ <link rel="import" href="components/neon-animation/animations/scale-up-animation.html">
+ <link rel="import" href="components/neon-animation/animations/fade-out-animation.html">
+
+ <paper-dialog entry-animation="scale-up-animation"
+ exit-animation="fade-out-animation">
+ <h2>Header</h2>
+ <div>Dialog body</div>
+ </paper-dialog>
+
+### Accessibility
+
+See the docs for `Polymer.PaperDialogBehavior` for accessibility features implemented by this
+element.
+
+@group Paper Elements
+@element paper-dialog
+@hero hero.svg
+@demo demo/index.html
+-->
+
+<dom-module id="paper-dialog">
+
+ <link rel="import" type="css" href="../paper-dialog-behavior/paper-dialog-common.css">
+
+ <template>
+ <content></content>
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'paper-dialog',
+
+ behaviors: [
+ Polymer.PaperDialogBehavior,
+ Polymer.NeonAnimationRunnerBehavior
+ ],
+
+ listeners: {
+ 'neon-animation-finish': '_onNeonAnimationFinish'
+ },
+
+ _renderOpened: function() {
+ if (this.withBackdrop) {
+ this.backdropElement.open();
+ }
+ this.playAnimation('entry');
+ },
+
+ _renderClosed: function() {
+ if (this.withBackdrop) {
+ this.backdropElement.close();
+ }
+ this.playAnimation('exit');
+ },
+
+ _onNeonAnimationFinish: function() {
+ if (this.opened) {
+ this._finishRenderOpened();
+ } else {
+ this._finishRenderClosed();
+ }
+ }
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-dialog/test/index.html b/polymer_1.0.4/bower_components/paper-dialog/test/index.html
new file mode 100644
index 0000000..ae925b0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog/test/index.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>paper-dialog tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'paper-dialog.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-dialog/test/paper-dialog.html b/polymer_1.0.4/bower_components/paper-dialog/test/paper-dialog.html
new file mode 100644
index 0000000..2eb0057
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-dialog/test/paper-dialog.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>paper-dialog tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../paper-dialog.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="basic">
+ <template>
+ <paper-dialog>
+ <p>Dialog</p>
+ </paper-dialog>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('a11y', function() {
+
+ test('dialog has role="dialog"', function() {
+ var dialog = fixture('basic');
+ assert.equal(dialog.getAttribute('role'), 'dialog', 'has role="dialog"');
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-drawer-panel/.bower.json b/polymer_1.0.4/bower_components/paper-drawer-panel/.bower.json
new file mode 100644
index 0000000..e49fa46
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-drawer-panel/.bower.json
@@ -0,0 +1,42 @@
+{
+ "name": "paper-drawer-panel",
+ "version": "1.0.2",
+ "description": "A responsive drawer panel",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "drawer",
+ "responsive",
+ "layout"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-drawer-panel.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-drawer-panel",
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-selector": "PolymerElements/iron-selector#^1.0.0",
+ "iron-media-query": "PolymerElements/iron-media-query#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "paper-button": "PolymerElements/paper-button#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "691739c877914f7231eaca16b724bdca295dfe8d"
+ },
+ "_source": "git://github.com/PolymerElements/paper-drawer-panel.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-drawer-panel"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-drawer-panel/.gitignore b/polymer_1.0.4/bower_components/paper-drawer-panel/.gitignore
new file mode 100644
index 0000000..fbe05fc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-drawer-panel/.gitignore
@@ -0,0 +1 @@
+bower_components/
diff --git a/polymer_1.0.4/bower_components/paper-drawer-panel/README.md b/polymer_1.0.4/bower_components/paper-drawer-panel/README.md
new file mode 100644
index 0000000..2828663
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-drawer-panel/README.md
@@ -0,0 +1,71 @@
+# paper-drawer-panel
+
+`paper-drawer-panel` contains a drawer panel and a main panel. The drawer
+and the main panel are side-by-side with drawer on the left. When the browser
+window size is smaller than the `responsiveWidth`, `paper-drawer-panel`
+changes to narrow layout. In narrow layout, the drawer will be stacked on top
+of the main panel. The drawer will slide in/out to hide/reveal the main
+panel.
+
+Use the attribute `drawer` to indicate that the element is the drawer panel and
+`main` to indicate that the element is the main panel.
+
+Example:
+
+```html
+<paper-drawer-panel>
+ <div drawer> Drawer panel... </div>
+ <div main> Main panel... </div>
+</paper-drawer-panel>
+```
+
+The drawer and the main panels are not scrollable. You can set CSS overflow
+property on the elements to make them scrollable or use `paper-header-panel`.
+
+Example:
+
+```html
+<paper-drawer-panel>
+ <paper-header-panel drawer>
+ <paper-toolbar></paper-toolbar>
+ <div> Drawer content... </div>
+ </paper-header-panel>
+ <paper-header-panel main>
+ <paper-toolbar></paper-toolbar>
+ <div> Main content... </div>
+ </paper-header-panel>
+</paper-drawer-panel>
+```
+
+An element that should toggle the drawer will automatically do so if it's
+given the `paper-drawer-toggle` attribute. Also this element will automatically
+be hidden in wide layout.
+
+Example:
+
+```html
+<paper-drawer-panel>
+ <paper-header-panel drawer>
+ <paper-toolbar>
+ <div>Application</div>
+ </paper-toolbar>
+ <div> Drawer content... </div>
+ </paper-header-panel>
+ <paper-header-panel main>
+ <paper-toolbar>
+ <paper-icon-button icon="menu" paper-drawer-toggle></paper-icon-button>
+ <div>Title</div>
+ </paper-toolbar>
+ <div> Main content... </div>
+ </paper-header-panel>
+</paper-drawer-panel>
+```
+
+To position the drawer to the right, add `right-drawer` attribute.
+
+```html
+<paper-drawer-panel right-drawer>
+ <div drawer> Drawer panel... </div>
+ <div main> Main panel... </div>
+</paper-drawer-panel>
+```
diff --git a/polymer_1.0.4/bower_components/paper-drawer-panel/bower.json b/polymer_1.0.4/bower_components/paper-drawer-panel/bower.json
new file mode 100644
index 0000000..f87cca9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-drawer-panel/bower.json
@@ -0,0 +1,33 @@
+{
+ "name": "paper-drawer-panel",
+ "version": "1.0.2",
+ "description": "A responsive drawer panel",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "drawer",
+ "responsive",
+ "layout"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-drawer-panel.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-drawer-panel",
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-selector": "PolymerElements/iron-selector#^1.0.0",
+ "iron-media-query": "PolymerElements/iron-media-query#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "paper-button": "PolymerElements/paper-button#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-drawer-panel/demo/index.html b/polymer_1.0.4/bower_components/paper-drawer-panel/demo/index.html
new file mode 100644
index 0000000..f69df9f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-drawer-panel/demo/index.html
@@ -0,0 +1,85 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>paper-drawer-panel demo</title>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+
+ <link rel="import" href="../../paper-button/paper-button.html">
+ <link rel="import" href="../paper-drawer-panel.html">
+
+ <style is="custom-style">
+
+ #paperDrawerPanel [main] {
+ background-color: var(--google-grey-100);
+ }
+
+ #paperDrawerPanel [drawer] {
+ border-right: 1px solid var(--google-grey-300);
+ }
+
+ #paperDrawerPanel[right-drawer] [drawer] {
+ border-left: 1px solid var(--google-grey-300);
+ }
+
+ paper-button {
+ color: white;
+ margin: 10px;
+ background-color: var(--google-blue-700);
+ white-space: nowrap;
+ }
+
+ </style>
+ </head>
+
+ <body unresolved>
+
+ <paper-drawer-panel id="paperDrawerPanel">
+ <div drawer></div>
+ <div main>
+ <div>
+ <paper-button onclick="flipDrawer()" raised>flip drawer</paper-button>
+ </div>
+ <div>
+ <paper-button paper-drawer-toggle raised>toggle drawer</paper-button>
+ </div>
+ </div>
+ </paper-drawer-panel>
+
+ <script>
+ (function(global) {
+
+ 'use strict';
+
+ var DRAWER_ATTR = 'right-drawer';
+
+ var pdp = document.getElementById('paperDrawerPanel');
+
+ global.flipDrawer = function() {
+ if (pdp.hasAttribute(DRAWER_ATTR)) {
+ pdp.removeAttribute(DRAWER_ATTR);
+ } else {
+ pdp.setAttribute(DRAWER_ATTR, '');
+ }
+ }
+
+ }(this));
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-drawer-panel/hero.svg b/polymer_1.0.4/bower_components/paper-drawer-panel/hero.svg
new file mode 100755
index 0000000..5dfef36
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-drawer-panel/hero.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <path d="M175,102H61V24h114V102z M63,100h110V26H63V100z"/>
+ <path d="M91,102H61V24h30V102z M63,100h26V26H63V100z"/>
+ <circle cx="123" cy="63" r="4"/>
+ <rect x="90" y="62" width="33" height="2"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-drawer-panel/index.html b/polymer_1.0.4/bower_components/paper-drawer-panel/index.html
new file mode 100644
index 0000000..1390ecc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-drawer-panel/index.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>paper-drawer-panel</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-drawer-panel/paper-drawer-panel.css b/polymer_1.0.4/bower_components/paper-drawer-panel/paper-drawer-panel.css
new file mode 100644
index 0000000..ab7c568
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-drawer-panel/paper-drawer-panel.css
@@ -0,0 +1,142 @@
+/**
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+
+*/
+:host {
+ display: block;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+}
+
+iron-selector > #drawer {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ background-color: white;
+ will-change: transform;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+
+ @apply(--paper-drawer-panel-drawer-container);
+}
+
+.transition > #drawer {
+ transition: -webkit-transform ease-in-out 0.3s, width ease-in-out 0.3s;
+ transition: transform ease-in-out 0.3s, width ease-in-out 0.3s;
+}
+
+.left-drawer > #drawer {
+ @apply(--paper-drawer-panel-left-drawer-container);
+}
+
+.right-drawer > #drawer {
+ left: auto;
+ right: 0;
+
+ @apply(--paper-drawer-panel-right-drawer-container);
+}
+
+iron-selector > #main {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+
+ @apply(--paper-drawer-panel-main-container);
+}
+
+.transition > #main {
+ transition: left ease-in-out 0.3s, padding ease-in-out 0.3s;
+}
+
+.right-drawer > #main {
+ left: 0;
+}
+
+.right-drawer.transition > #main {
+ transition: right ease-in-out 0.3s, padding ease-in-out 0.3s;
+}
+
+#main > ::content > [main] {
+ height: 100%;
+}
+
+#drawer > ::content > [drawer] {
+ height: 100%;
+}
+
+#scrim {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ visibility: hidden;
+ opacity: 0;
+ transition: opacity ease-in-out 0.38s, visibility ease-in-out 0.38s;
+ background-color: rgba(0, 0, 0, 0.3);
+}
+
+.narrow-layout > #drawer.iron-selected {
+ box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.15);
+}
+
+.right-drawer.narrow-layout > #drawer.iron-selected {
+ box-shadow: -2px 2px 4px rgba(0, 0, 0, 0.15);
+}
+
+.narrow-layout > #drawer > ::content > [drawer] {
+ border: 0;
+}
+
+.left-drawer.narrow-layout > #drawer:not(.iron-selected) {
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+}
+
+.right-drawer.narrow-layout > #drawer:not(.iron-selected) {
+ left: auto;
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+}
+
+.narrow-layout > #main {
+ left: 0 !important;
+ padding: 0;
+}
+
+.right-drawer.narrow-layout > #main {
+ left: 0;
+ right: 0;
+ padding: 0;
+}
+
+.narrow-layout > #main:not(.iron-selected) > #scrim,
+.dragging > #main > #scrim {
+ visibility: visible;
+ opacity: var(--paper-drawer-panel-scrim-opacity, 1);
+}
+
+.narrow-layout > #main > * {
+ margin: 0;
+ min-height: 100%;
+ left: 0;
+ right: 0;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+}
+
+iron-selector:not(.narrow-layout) #main ::content [paper-drawer-toggle] {
+ display: none;
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-drawer-panel/paper-drawer-panel.html b/polymer_1.0.4/bower_components/paper-drawer-panel/paper-drawer-panel.html
new file mode 100644
index 0000000..148cfeb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-drawer-panel/paper-drawer-panel.html
@@ -0,0 +1,591 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-media-query/iron-media-query.html">
+<link rel="import" href="../iron-selector/iron-selector.html">
+
+<!--
+`paper-drawer-panel` contains a drawer panel and a main panel. The drawer
+and the main panel are side-by-side with drawer on the left. When the browser
+window size is smaller than the `responsiveWidth`, `paper-drawer-panel`
+changes to narrow layout. In narrow layout, the drawer will be stacked on top
+of the main panel. The drawer will slide in/out to hide/reveal the main
+panel.
+
+Use the attribute `drawer` to indicate that the element is the drawer panel and
+`main` to indicate that the element is the main panel.
+
+Example:
+
+ <paper-drawer-panel>
+ <div drawer> Drawer panel... </div>
+ <div main> Main panel... </div>
+ </paper-drawer-panel>
+
+The drawer and the main panels are not scrollable. You can set CSS overflow
+property on the elements to make them scrollable or use `paper-header-panel`.
+
+Example:
+
+ <paper-drawer-panel>
+ <paper-header-panel drawer>
+ <paper-toolbar></paper-toolbar>
+ <div> Drawer content... </div>
+ </paper-header-panel>
+ <paper-header-panel main>
+ <paper-toolbar></paper-toolbar>
+ <div> Main content... </div>
+ </paper-header-panel>
+ </paper-drawer-panel>
+
+An element that should toggle the drawer will automatically do so if it's
+given the `paper-drawer-toggle` attribute. Also this element will automatically
+be hidden in wide layout.
+
+Example:
+
+ <paper-drawer-panel>
+ <paper-header-panel drawer>
+ <paper-toolbar>
+ <div>Application</div>
+ </paper-toolbar>
+ <div> Drawer content... </div>
+ </paper-header-panel>
+ <paper-header-panel main>
+ <paper-toolbar>
+ <paper-icon-button icon="menu" paper-drawer-toggle></paper-icon-button>
+ <div>Title</div>
+ </paper-toolbar>
+ <div> Main content... </div>
+ </paper-header-panel>
+ </paper-drawer-panel>
+
+To position the drawer to the right, add `right-drawer` attribute.
+
+ <paper-drawer-panel right-drawer>
+ <div drawer> Drawer panel... </div>
+ <div main> Main panel... </div>
+ </paper-drawer-panel>
+
+Styling paper-drawer-panel:
+
+To change the main container:
+ paper-drawer-panel {
+ --paper-drawer-panel-main-container: {
+ background-color: gray;
+ };
+ }
+
+To change the drawer container when it's in the left side:
+ paper-drawer-panel {
+ --paper-drawer-panel-left-drawer-container: {
+ background-color: white;
+ };
+ }
+
+To change the drawer container when it's in the right side:
+
+ paper-drawer-panel {
+ --paper-drawer-panel-right-drawer-container: {
+ background-color: white;
+ };
+ }
+
+@group Paper elements
+@element paper-drawer-panel
+@demo demo/index.html
+@hero hero.svg
+-->
+
+<dom-module id="paper-drawer-panel">
+ <link rel="import" type="css" href="paper-drawer-panel.css">
+
+ <template>
+ <iron-media-query
+ id="mq"
+ on-query-matches-changed="_onQueryMatchesChanged"
+ query="[[_computeMediaQuery(forceNarrow, responsiveWidth)]]">
+ </iron-media-query>
+
+ <iron-selector
+ attr-for-selected="id"
+ class$="[[_computeIronSelectorClass(narrow, transition, dragging, rightDrawer)]]"
+ activate-event=""
+ selected="[[selected]]">
+
+ <div id="main" style$="[[_computeMainStyle(narrow, rightDrawer, drawerWidth)]]">
+ <content select="[main]"></content>
+ <div id="scrim" on-tap="closeDrawer"></div>
+ </div>
+
+ <div id="drawer" style$="[[_computeDrawerStyle(drawerWidth)]]">
+ <content select="[drawer]"></content>
+ </div>
+
+ </iron-selector>
+ </template>
+
+</dom-module>
+
+<script>
+
+ (function() {
+
+ 'use strict';
+
+ // this would be the only `paper-drawer-panel` in
+ // the whole app that can be in `dragging` state
+ var sharedPanel = null;
+
+ function classNames(obj) {
+ var classes = [];
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key) && obj[key]) {
+ classes.push(key);
+ }
+ }
+
+ return classes.join(' ');
+ }
+
+ Polymer({
+
+ is: 'paper-drawer-panel',
+
+ /**
+ * Fired when the narrow layout changes.
+ *
+ * @event paper-responsive-change {{narrow: boolean}} detail -
+ * narrow: true if the panel is in narrow layout.
+ */
+
+ /**
+ * Fired when the selected panel changes.
+ *
+ * Listening for this event is an alternative to observing changes in the `selected` attribute.
+ * This event is fired both when a panel is selected and deselected.
+ * The `isSelected` detail property contains the selection state.
+ *
+ * @event paper-select {{isSelected: boolean, item: Object}} detail -
+ * isSelected: True for selection and false for deselection.
+ * item: The panel that the event refers to.
+ */
+
+ properties: {
+
+ /**
+ * The panel to be selected when `paper-drawer-panel` changes to narrow
+ * layout.
+ */
+ defaultSelected: {
+ type: String,
+ value: 'main'
+ },
+
+ /**
+ * If true, swipe from the edge is disable.
+ */
+ disableEdgeSwipe: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, swipe to open/close the drawer is disabled.
+ */
+ disableSwipe: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Whether the user is dragging the drawer interactively.
+ */
+ dragging: {
+ type: Boolean,
+ value: false,
+ readOnly: true,
+ notify: true
+ },
+
+ /**
+ * Width of the drawer panel.
+ */
+ drawerWidth: {
+ type: String,
+ value: '256px'
+ },
+
+ /**
+ * How many pixels on the side of the screen are sensitive to edge
+ * swipes and peek.
+ */
+ edgeSwipeSensitivity: {
+ type: Number,
+ value: 30
+ },
+
+ /**
+ * If true, ignore `responsiveWidth` setting and force the narrow layout.
+ */
+ forceNarrow: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Whether the browser has support for the transform CSS property.
+ */
+ hasTransform: {
+ type: Boolean,
+ value: function() {
+ return 'transform' in this.style;
+ }
+ },
+
+ /**
+ * Whether the browser has support for the will-change CSS property.
+ */
+ hasWillChange: {
+ type: Boolean,
+ value: function() {
+ return 'willChange' in this.style;
+ }
+ },
+
+ /**
+ * Returns true if the panel is in narrow layout. This is useful if you
+ * need to show/hide elements based on the layout.
+ */
+ narrow: {
+ reflectToAttribute: true,
+ type: Boolean,
+ value: false,
+ readOnly: true,
+ notify: true
+ },
+
+ /**
+ * Whether the drawer is peeking out from the edge.
+ */
+ peeking: {
+ type: Boolean,
+ value: false,
+ readOnly: true,
+ notify: true
+ },
+
+ /**
+ * Max-width when the panel changes to narrow layout.
+ */
+ responsiveWidth: {
+ type: String,
+ value: '640px'
+ },
+
+ /**
+ * If true, position the drawer to the right.
+ */
+ rightDrawer: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The panel that is being selected. `drawer` for the drawer panel and
+ * `main` for the main panel.
+ */
+ selected: {
+ reflectToAttribute: true,
+ notify: true,
+ type: String,
+ value: null
+ },
+
+ /**
+ * The attribute on elements that should toggle the drawer on tap, also elements will
+ * automatically be hidden in wide layout.
+ */
+ drawerToggleAttribute: {
+ type: String,
+ value: 'paper-drawer-toggle'
+ },
+
+ /**
+ * Whether the transition is enabled.
+ */
+ transition: {
+ type: Boolean,
+ value: false
+ },
+
+ },
+
+ listeners: {
+ tap: '_onTap',
+ track: '_onTrack',
+ down: '_downHandler',
+ up: '_upHandler'
+ },
+
+ observers: [
+ '_forceNarrowChanged(forceNarrow, defaultSelected)'
+ ],
+
+ /**
+ * Toggles the panel open and closed.
+ *
+ * @method togglePanel
+ */
+ togglePanel: function() {
+ if (this._isMainSelected()) {
+ this.openDrawer();
+ } else {
+ this.closeDrawer();
+ }
+ },
+
+ /**
+ * Opens the drawer.
+ *
+ * @method openDrawer
+ */
+ openDrawer: function() {
+ this.selected = 'drawer';
+ },
+
+ /**
+ * Closes the drawer.
+ *
+ * @method closeDrawer
+ */
+ closeDrawer: function() {
+ this.selected = 'main';
+ },
+
+ ready: function() {
+ // Avoid transition at the beginning e.g. page loads and enable
+ // transitions only after the element is rendered and ready.
+ this.transition = true;
+ },
+
+ _computeIronSelectorClass: function(narrow, transition, dragging, rightDrawer) {
+ return classNames({
+ dragging: dragging,
+ 'narrow-layout': narrow,
+ 'right-drawer': rightDrawer,
+ 'left-drawer': !rightDrawer,
+ transition: transition
+ });
+ },
+
+ _computeDrawerStyle: function(drawerWidth) {
+ return 'width:' + drawerWidth + ';';
+ },
+
+ _computeMainStyle: function(narrow, rightDrawer, drawerWidth) {
+ var style = '';
+
+ style += 'left:' + ((narrow || rightDrawer) ? '0' : drawerWidth) + ';';
+
+ if (rightDrawer) {
+ style += 'right:' + (narrow ? '' : drawerWidth) + ';';
+ } else {
+ style += 'right:;';
+ }
+
+ return style;
+ },
+
+ _computeMediaQuery: function(forceNarrow, responsiveWidth) {
+ return forceNarrow ? '' : '(max-width: ' + responsiveWidth + ')';
+ },
+
+ _computeSwipeOverlayHidden: function(narrow, disableEdgeSwipe) {
+ return !narrow || disableEdgeSwipe;
+ },
+
+ _onTrack: function(e) {
+ if (sharedPanel && this !== sharedPanel) {
+ return;
+ }
+ switch (e.detail.state) {
+ case 'start':
+ this._trackStart(e);
+ break;
+ case 'track':
+ this._trackX(e);
+ break;
+ case 'end':
+ this._trackEnd(e);
+ break;
+ }
+
+ },
+
+ _responsiveChange: function(narrow) {
+ this._setNarrow(narrow);
+
+ if (this.narrow) {
+ this.selected = this.defaultSelected;
+ }
+
+ this.setScrollDirection(this._swipeAllowed() ? 'y' : 'all');
+ this.fire('paper-responsive-change', {narrow: this.narrow});
+ },
+
+ _onQueryMatchesChanged: function(e) {
+ this._responsiveChange(e.detail.value);
+ },
+
+ _forceNarrowChanged: function() {
+ // set the narrow mode only if we reached the `responsiveWidth`
+ this._responsiveChange(this.forceNarrow || this.$.mq.queryMatches);
+ },
+
+ _swipeAllowed: function() {
+ return this.narrow && !this.disableSwipe;
+ },
+
+ _isMainSelected: function() {
+ return this.selected === 'main';
+ },
+
+ _startEdgePeek: function() {
+ this.width = this.$.drawer.offsetWidth;
+ this._moveDrawer(this._translateXForDeltaX(this.rightDrawer ?
+ -this.edgeSwipeSensitivity : this.edgeSwipeSensitivity));
+ this._setPeeking(true);
+ },
+
+ _stopEdgePeek: function() {
+ if (this.peeking) {
+ this._setPeeking(false);
+ this._moveDrawer(null);
+ }
+ },
+
+ _downHandler: function(e) {
+ if (!this.dragging && this._isMainSelected() && this._isEdgeTouch(e) && !sharedPanel) {
+ this._startEdgePeek();
+ // grab this panel
+ sharedPanel = this;
+ }
+ },
+
+ _upHandler: function() {
+ this._stopEdgePeek();
+ // release the panel
+ sharedPanel = null;
+ },
+
+ _onTap: function(e) {
+ var targetElement = Polymer.dom(e).localTarget;
+ var isTargetToggleElement = targetElement &&
+ this.drawerToggleAttribute &&
+ targetElement.hasAttribute(this.drawerToggleAttribute);
+
+ if (isTargetToggleElement) {
+ this.togglePanel();
+ }
+ },
+
+ _isEdgeTouch: function(e) {
+ var x = e.detail.x;
+
+ return !this.disableEdgeSwipe && this._swipeAllowed() &&
+ (this.rightDrawer ?
+ x >= this.offsetWidth - this.edgeSwipeSensitivity :
+ x <= this.edgeSwipeSensitivity);
+ },
+
+ _trackStart: function(event) {
+ if (this._swipeAllowed()) {
+ sharedPanel = this;
+ this._setDragging(true);
+
+ if (this._isMainSelected()) {
+ this._setDragging(this.peeking || this._isEdgeTouch(event));
+ }
+
+ if (this.dragging) {
+ this.width = this.$.drawer.offsetWidth;
+ this.transition = false;
+ }
+ }
+ },
+
+ _translateXForDeltaX: function(deltaX) {
+ var isMain = this._isMainSelected();
+
+ if (this.rightDrawer) {
+ return Math.max(0, isMain ? this.width + deltaX : deltaX);
+ } else {
+ return Math.min(0, isMain ? deltaX - this.width : deltaX);
+ }
+ },
+
+ _trackX: function(e) {
+ if (this.dragging) {
+ var dx = e.detail.dx;
+
+ if (this.peeking) {
+ if (Math.abs(dx) <= this.edgeSwipeSensitivity) {
+ // Ignore trackx until we move past the edge peek.
+ return;
+ }
+ this._setPeeking(false);
+ }
+
+ this._moveDrawer(this._translateXForDeltaX(dx));
+ }
+ },
+
+ _trackEnd: function(e) {
+ if (this.dragging) {
+ var xDirection = e.detail.dx > 0;
+
+ this._setDragging(false);
+ this.transition = true;
+ sharedPanel = null;
+ this._moveDrawer(null);
+
+ if (this.rightDrawer) {
+ this[xDirection ? 'closeDrawer' : 'openDrawer']();
+ } else {
+ this[xDirection ? 'openDrawer' : 'closeDrawer']();
+ }
+ }
+ },
+
+ _transformForTranslateX: function(translateX) {
+ if (translateX === null) {
+ return '';
+ }
+
+ return this.hasWillChange ? 'translateX(' + translateX + 'px)' :
+ 'translate3d(' + translateX + 'px, 0, 0)';
+ },
+
+ _moveDrawer: function(translateX) {
+ var s = this.$.drawer.style;
+
+ if (this.hasTransform) {
+ s.transform = this._transformForTranslateX(translateX);
+ } else {
+ s.webkitTransform = this._transformForTranslateX(translateX);
+ }
+ }
+
+ });
+
+ }());
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-elements/.bower.json b/polymer_1.0.4/bower_components/paper-elements/.bower.json
new file mode 100644
index 0000000..527e9fe
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-elements/.bower.json
@@ -0,0 +1,61 @@
+{
+ "name": "paper-elements",
+ "version": "1.0.1",
+ "homepage": "https://github.com/PolymerElements/paper-elements",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "Paper elements are a set of visual elements that implement Google's Material Design.",
+ "main": "paper-elements.html",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "paper"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
+ "paper-button": "PolymerElements/paper-button#^1.0.0",
+ "paper-checkbox": "PolymerElements/paper-checkbox#^1.0.0",
+ "paper-dialog": "PolymerElements/paper-dialog#^1.0.0",
+ "paper-dialog-behavior": "PolymerElements/paper-dialog-behavior#^1.0.0",
+ "paper-dialog-scrollable": "PolymerElements/paper-dialog-scrollable#^1.0.0",
+ "paper-drawer-panel": "PolymerElements/paper-drawer-panel#^1.0.0",
+ "paper-fab": "PolymerElements/paper-fab#^1.0.0",
+ "paper-header-panel": "PolymerElements/paper-header-panel#^1.0.0",
+ "paper-icon-button": "PolymerElements/paper-icon-button#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-item": "PolymerElements/paper-item#^1.0.0",
+ "paper-material": "PolymerElements/paper-material#^1.0.0",
+ "paper-menu": "PolymerElements/paper-menu#^1.0.0",
+ "paper-progress": "PolymerElements/paper-progress#^1.0.0",
+ "paper-radio-button": "PolymerElements/paper-radio-button#^1.0.0",
+ "paper-radio-group": "PolymerElements/paper-radio-group#^1.0.0",
+ "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+ "paper-slider": "PolymerElements/paper-slider#^1.0.0",
+ "paper-spinner": "PolymerElements/paper-spinner#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "paper-tabs": "PolymerElements/paper-tabs#^1.0.0",
+ "paper-toast": "PolymerElements/paper-toast#^1.0.0",
+ "paper-toggle-button": "PolymerElements/paper-toggle-button#^1.0.0",
+ "paper-toolbar": "PolymerElements/paper-toolbar#^1.0.0",
+ "paper-scroll-header-panel": "PolymerElements/paper-scroll-header-panel#^1.0.0"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "c4b7d791a9a7cfec9d671a34112c97a0dad5de69"
+ },
+ "_source": "git://github.com/PolymerElements/paper-elements.git",
+ "_target": "~1.0.1",
+ "_originalSource": "PolymerElements/paper-elements",
+ "_direct": true
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-elements/README.md b/polymer_1.0.4/bower_components/paper-elements/README.md
new file mode 100644
index 0000000..300275c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-elements/README.md
@@ -0,0 +1,21 @@
+#paper-elements
+
+The paper elements are a set of UI components designed to implement Google's [material design](http://www.google.com/design/spec/material-design/introduction.html) guidelines.
+
+## Roadmap
+
+### Elements in progress
+
+* `paper-dropdown-menu` - a dropdown menu
+
+### Elements planned
+_Elements we're planning on building soon but haven't started yet_
+
+* `paper-tooltip` - a hover tooltip
+
+[Currently focused on getting all elements up to speed]
+
+### Elements not planned, notably
+_Elements we're not planning on building as part of this product line, but that one might be wondering about_
+
+[None]
diff --git a/polymer_1.0.4/bower_components/paper-elements/bower.json b/polymer_1.0.4/bower_components/paper-elements/bower.json
new file mode 100644
index 0000000..34083c3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-elements/bower.json
@@ -0,0 +1,51 @@
+{
+ "name": "paper-elements",
+ "version": "1.0.1",
+ "homepage": "https://github.com/PolymerElements/paper-elements",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "Paper elements are a set of visual elements that implement Google's Material Design.",
+ "main": "paper-elements.html",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "paper"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
+ "paper-button": "PolymerElements/paper-button#^1.0.0",
+ "paper-checkbox": "PolymerElements/paper-checkbox#^1.0.0",
+ "paper-dialog": "PolymerElements/paper-dialog#^1.0.0",
+ "paper-dialog-behavior": "PolymerElements/paper-dialog-behavior#^1.0.0",
+ "paper-dialog-scrollable": "PolymerElements/paper-dialog-scrollable#^1.0.0",
+ "paper-drawer-panel": "PolymerElements/paper-drawer-panel#^1.0.0",
+ "paper-fab": "PolymerElements/paper-fab#^1.0.0",
+ "paper-header-panel": "PolymerElements/paper-header-panel#^1.0.0",
+ "paper-icon-button": "PolymerElements/paper-icon-button#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-item": "PolymerElements/paper-item#^1.0.0",
+ "paper-material": "PolymerElements/paper-material#^1.0.0",
+ "paper-menu": "PolymerElements/paper-menu#^1.0.0",
+ "paper-progress": "PolymerElements/paper-progress#^1.0.0",
+ "paper-radio-button": "PolymerElements/paper-radio-button#^1.0.0",
+ "paper-radio-group": "PolymerElements/paper-radio-group#^1.0.0",
+ "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+ "paper-slider": "PolymerElements/paper-slider#^1.0.0",
+ "paper-spinner": "PolymerElements/paper-spinner#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "paper-tabs": "PolymerElements/paper-tabs#^1.0.0",
+ "paper-toast": "PolymerElements/paper-toast#^1.0.0",
+ "paper-toggle-button": "PolymerElements/paper-toggle-button#^1.0.0",
+ "paper-toolbar": "PolymerElements/paper-toolbar#^1.0.0",
+ "paper-scroll-header-panel": "PolymerElements/paper-scroll-header-panel#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-fab/.bower.json b/polymer_1.0.4/bower_components/paper-fab/.bower.json
new file mode 100644
index 0000000..15e922a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-fab/.bower.json
@@ -0,0 +1,48 @@
+{
+ "name": "paper-fab",
+ "version": "1.0.2",
+ "description": "A material design floating action button",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "button"
+ ],
+ "main": "paper-fab.html",
+ "ignore": [],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-fab"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-fab",
+ "dependencies": {
+ "paper-ripple": "polymerelements/paper-ripple#^1.0.0",
+ "paper-material": "polymerelements/paper-material#^1.0.0",
+ "paper-behaviors": "polymerelements/paper-behaviors#^1.0.0",
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "iron-icons": "polymerelements/iron-icons#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "59d2f77f456271f1ae4059b92d83ba7655fb1580"
+ },
+ "_source": "git://github.com/PolymerElements/paper-fab.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-fab"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-fab/.gitignore b/polymer_1.0.4/bower_components/paper-fab/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-fab/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-fab/README.md b/polymer_1.0.4/bower_components/paper-fab/README.md
new file mode 100644
index 0000000..5da43e2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-fab/README.md
@@ -0,0 +1,44 @@
+paper-fab
+=========
+
+Material Design: <a href="http://www.google.com/design/spec/components/buttons.html">Button</a>
+
+`paper-fab` is a floating action button. It contains an image placed in the center and
+comes in two sizes: regular size and a smaller size by applying the attribute `mini`. When
+the user touches the button, a ripple effect emanates from the center of the button.
+
+You may import `iron-icons` to use with this element, or provide a URL to a custom icon.
+See `iron-iconset` for more information about how to use a custom icon set.
+
+Example:
+
+```html
+<link href="path/to/iron-icons/iron-icons.html" rel="import">
+
+<paper-fab icon="add"></paper-fab>
+<paper-fab mini icon="favorite"></paper-fab>
+<paper-fab src="star.png"></paper-fab>
+```
+
+Styling
+-------
+
+Style the button with CSS as you would a normal DOM element. If you are using the icons
+provided by `iron-icons`, the icon will inherit the foreground color of the button.
+
+```html
+<!-- make a blue "cloud" button -->
+<paper-fab icon="cloud" style="color: blue;"></paper-fab>
+```
+
+By default, the ripple is the same color as the foreground at 25% opacity. You may
+customize the color using this selector:
+
+```css
+/* make #my-button use a blue ripple instead of foreground color */
+#my-button::shadow #ripple {
+ color: blue;
+}
+```
+
+The opacity of the ripple is not customizable via CSS.
diff --git a/polymer_1.0.4/bower_components/paper-fab/bower.json b/polymer_1.0.4/bower_components/paper-fab/bower.json
new file mode 100644
index 0000000..f3738a2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-fab/bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "paper-fab",
+ "version": "1.0.2",
+ "description": "A material design floating action button",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "button"
+ ],
+ "main": "paper-fab.html",
+ "ignore": [],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-fab"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-fab",
+ "dependencies": {
+ "paper-ripple": "polymerelements/paper-ripple#^1.0.0",
+ "paper-material": "polymerelements/paper-material#^1.0.0",
+ "paper-behaviors": "polymerelements/paper-behaviors#^1.0.0",
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "iron-icons": "polymerelements/iron-icons#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-fab/demo/index.html b/polymer_1.0.4/bower_components/paper-fab/demo/index.html
new file mode 100644
index 0000000..3bd9935
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-fab/demo/index.html
@@ -0,0 +1,97 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>paper-fab demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../paper-fab.html">
+
+ <style is="custom-style">
+ .horizontal-section {
+ min-width: 200px;
+ }
+
+ paper-fab {
+ display: block;
+ margin-bottom:24px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+
+ paper-fab.blue {
+ --paper-fab-background: var(--paper-light-blue-500);
+ --paper-fab-keyboard-focus-background: var(--paper-light-blue-900);
+ }
+
+ paper-fab.red {
+ --paper-fab-background: var(--paper-red-500);
+ --paper-fab-keyboard-focus-background: var(--paper-red-900);
+ }
+
+ paper-fab.green {
+ --paper-fab-background: var(--paper-green-500);
+ --paper-fab-keyboard-focus-background: var(--paper-green-900);
+ }
+
+ paper-fab.orange {
+ --paper-fab-background: var(--paper-orange-500);
+ --paper-fab-keyboard-focus-background: var(--paper-orange-900);
+ }
+
+ </style>
+
+</head>
+<body>
+ <div class="horizontal center-justified layout">
+ <div>
+ <h4>Enabled</h4>
+ <div class="horizontal-section">
+ <paper-fab icon="arrow-forward" title="arrow-forward" tabindex="0"></paper-fab>
+ <paper-fab icon="create" title="create" tabindex="0"></paper-fab>
+ <paper-fab icon="favorite" title="heart" tabindex="0"></paper-fab>
+ <paper-fab mini icon="done" title="done" tabindex="0"></paper-fab>
+ <paper-fab mini icon="reply" title="reply" tabindex="0"></paper-fab>
+ </div>
+ </div>
+
+ <div>
+ <h4>Disabled</h4>
+ <div class="horizontal-section">
+ <paper-fab disabled icon="arrow-forward" title="arrow-forward" tabindex="0"></paper-fab>
+ <paper-fab disabled icon="create" title="create" tabindex="0"></paper-fab>
+ <paper-fab disabled icon="favorite" title="heart" tabindex="0"></paper-fab>
+ <paper-fab disabled mini icon="done" title="done" tabindex="0"></paper-fab>
+ <paper-fab disabled mini icon="reply" title="reply" tabindex="0"></paper-fab>
+ </div>
+ </div>
+
+ <div>
+ <h4>Colors</h4>
+ <div class="horizontal-section">
+ <paper-fab icon="arrow-forward" title="arrow-forward" tabindex="0" class="blue"></paper-fab>
+ <paper-fab icon="create" title="create" tabindex="0" class="red"></paper-fab>
+ <paper-fab icon="favorite" title="heart" tabindex="0" class="orange"></paper-fab>
+ <paper-fab mini icon="done" title="done" tabindex="0" class="green"></paper-fab>
+ <paper-fab mini icon="reply" title="reply" tabindex="0" class="blue"></paper-fab>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-fab/index.html b/polymer_1.0.4/bower_components/paper-fab/index.html
new file mode 100644
index 0000000..c98a658
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-fab/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <title>paper-fab</title>
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-fab/paper-fab.html b/polymer_1.0.4/bower_components/paper-fab/paper-fab.html
new file mode 100644
index 0000000..f607ca4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-fab/paper-fab.html
@@ -0,0 +1,175 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="../paper-styles/default-theme.html">
+<link rel="import" href="../paper-styles/color.html">
+<link rel="import" href="../paper-material/paper-material.html">
+<link rel="import" href="../paper-ripple/paper-ripple.html">
+<link rel="import" href="../paper-behaviors/paper-button-behavior.html">
+
+<!--
+Material Design: <a href="http://www.google.com/design/spec/components/buttons.html">Button</a>
+
+`paper-fab` is a floating action button. It contains an image placed in the center and
+comes in two sizes: regular size and a smaller size by applying the attribute `mini`. When
+the user touches the button, a ripple effect emanates from the center of the button.
+
+You may import `iron-icons` to use with this element, or provide a URL to a custom icon.
+See `iron-iconset` for more information about how to use a custom icon set.
+
+Example:
+
+ <link href="path/to/iron-icons/iron-icons.html" rel="import">
+
+ <paper-fab icon="add"></paper-fab>
+ <paper-fab mini icon="favorite"></paper-fab>
+ <paper-fab src="star.png"></paper-fab>
+
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-fab-background` | The background color of the button | `--accent-color`
+`--paper-fab-keyboard-focus-background` | The background color of the button when focused | `--paper-pink-900`
+`--paper-fab-disabled-background` | The background color of the button when it's disabled | `--paper-grey-300`
+`--paper-fab-disabled-text` | The text color of the button when it's disabled | `--paper-grey-500`
+`--paper-fab` | Mixin applied to the button | `{}`
+`--paper-fab-mini` | Mixin applied to a mini button | `{}`
+`--paper-fab-disabled` | Mixin applied to a disabled button | `{}`
+
+@group Paper Elements
+@demo demo/index.html
+
+-->
+
+<dom-module id="paper-fab">
+ <style>
+
+ :host {
+ display: inline-block;
+ position: relative;
+ outline: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -webkit-user-select: none;
+ user-select: none;
+ cursor: pointer;
+
+ box-sizing: border-box;
+ min-width: 0;
+ width: 56px;
+ height: 56px;
+ background: var(--paper-fab-background, --accent-color);
+ color: var(--text-primary-color);
+ border-radius: 50%;
+ padding: 16px;
+
+ z-index: 0;
+
+ @apply(--paper-fab);
+ }
+
+ :host([mini]) {
+ width: 40px;
+ height: 40px;
+ padding: 8px;
+
+ @apply(--paper-fab-mini);
+ }
+
+ :host([disabled]) {
+ color: var(--paper-fab-disabled-text, --paper-grey-500);
+ background: var(--paper-fab-disabled-background, --paper-grey-300);
+ @apply(--paper-fab-disabled);
+ }
+
+ paper-material {
+ border-radius: inherit;
+ @apply(--layout-fit);
+ @apply(--layout-vertical);
+ @apply(--layout-center-center);
+ }
+
+ .keyboard-focus {
+ background: var(--paper-fab-keyboard-focus-background, --paper-pink-900);
+ }
+ </style>
+ <template>
+ <paper-ripple></paper-ripple>
+ <paper-material class$="[[_computeContentClass(receivedFocusFromKeyboard)]]" elevation="[[_elevation]]" animated>
+ <iron-icon id="icon" src="[[src]]" icon="[[icon]]"></iron-icon>
+ </paper-material>
+ </template>
+</dom-module>
+<script>
+ Polymer({
+ is: 'paper-fab',
+
+ behaviors: [
+ Polymer.PaperButtonBehavior
+ ],
+
+ properties: {
+ /**
+ * The URL of an image for the icon. If the src property is specified,
+ * the icon property should not be.
+ *
+ * @attribute src
+ * @type string
+ * @default ''
+ */
+ src: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * Specifies the icon name or index in the set of icons available in
+ * the icon's icon set. If the icon property is specified,
+ * the src property should not be.
+ *
+ * @attribute icon
+ * @type string
+ * @default ''
+ */
+ icon: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * Set this to true to style this is a "mini" FAB.
+ *
+ * @attribute mini
+ * @type boolean
+ * @default false
+ */
+ mini: {
+ type: Boolean,
+ value: false
+ }
+ },
+
+ _computeContentClass: function(receivedFocusFromKeyboard) {
+ var className = 'content';
+ if (receivedFocusFromKeyboard) {
+ className += ' keyboard-focus';
+ }
+ return className;
+ }
+
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-fab/test/a11y.html b/polymer_1.0.4/bower_components/paper-fab/test/a11y.html
new file mode 100644
index 0000000..2a2cbe3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-fab/test/a11y.html
@@ -0,0 +1,71 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>paper-fab a11y tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../core-icons/core-icons.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../paper-fab.html">
+
+</head>
+<body>
+
+ <test-fixture id="A11yFabs">
+ <template>
+ <paper-fab id="fab1" icon="add"></paper-fab>
+ <paper-fab id="fab2" icon="add" disabled></paper-fab>
+ <paper-fab id="fab3" icon="add" aria-label="custom"></paper-fab>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ var f1;
+ var f2;
+ var f3;
+
+ setup(function() {
+ var fabs = fixture('A11yFabs');
+
+ f1 = fabs[0];
+ f2 = fabs[1];
+ f3 = fabs[2];
+ });
+
+ test('aria role is a button', function() {
+ assert.strictEqual(f1.getAttribute('role'), 'button');
+ });
+
+ test('aria-disabled is set', function() {
+ assert.ok(f2.hasAttribute('aria-disabled'));
+ f2.removeAttribute('disabled');
+ assert.strictEqual(f2.getAttribute('aria-disabled'), 'false');
+ });
+
+ test('aria-label is set');
+
+ test('user-defined aria-label is preserved', function() {
+ assert.strictEqual(f3.getAttribute('aria-label'), 'custom');
+ f3.icon = 'arrow-forward';
+ assert.strictEqual(f3.getAttribute('aria-label'), 'custom');
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-fab/test/basic.html b/polymer_1.0.4/bower_components/paper-fab/test/basic.html
new file mode 100644
index 0000000..6c8a48a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-fab/test/basic.html
@@ -0,0 +1,76 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>paper-fab basic tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../paper-fab.html">
+
+</head>
+<body>
+
+ <test-fixture id="TrivialFab">
+ <template>
+ <div style="line-height:30px;">
+ <paper-fab id="fab1" icon="add"></paper-fab>
+ </div>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="SrcFab">
+ <template>
+ <paper-fab src="add.png"></paper-fab>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ var f1;
+ var f2;
+
+ function centerOf(element) {
+ var rect = element.getBoundingClientRect();
+ return {left: rect.left + rect.width / 2, top: rect.top + rect.height / 2};
+ }
+
+ function approxEqual(p1, p2) {
+ return Math.round(p1.left) == Math.round(p2.left) && Math.round(p1.top) == Math.round(p2.top);
+ }
+
+ setup(function() {
+ f1 = fixture('TrivialFab').querySelector('#fab1');
+ f2 = fixture('SrcFab');
+ });
+
+ test('applies an icon specified by the `icon` attribute', function() {
+ assert.strictEqual(!!f1.$.icon.usesSrcAttribute, false);
+ assert.ok(Polymer.dom(f1.$.icon.root).querySelector('svg'));
+ });
+
+ test('applies an icon specified by the `src` attribute', function() {
+ assert.strictEqual(f2.$.icon._usesIconset(), false);
+ assert.ok(f2.$.icon._img);
+ });
+
+ test('renders correctly independent of line height', function() {
+ assert.ok(approxEqual(centerOf(f1.$.icon), centerOf(f1)));
+ });
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-fab/test/index.html b/polymer_1.0.4/bower_components/paper-fab/test/index.html
new file mode 100644
index 0000000..9f90214
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-fab/test/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>paper-fab tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html',
+ 'a11y.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-header-panel/.bower.json b/polymer_1.0.4/bower_components/paper-header-panel/.bower.json
new file mode 100644
index 0000000..6129668
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-header-panel/.bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "paper-header-panel",
+ "version": "1.0.2",
+ "description": "A header and content wrapper for layout with headers",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "layout"
+ ],
+ "private": true,
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-header-panel",
+ "ignore": [],
+ "dependencies": {
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "19cde2fc5dfd51439e3433b3d5e6b618d444cb0a"
+ },
+ "_source": "git://github.com/PolymerElements/paper-header-panel.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-header-panel"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-header-panel/.gitignore b/polymer_1.0.4/bower_components/paper-header-panel/.gitignore
new file mode 100644
index 0000000..fbe05fc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-header-panel/.gitignore
@@ -0,0 +1 @@
+bower_components/
diff --git a/polymer_1.0.4/bower_components/paper-header-panel/README.md b/polymer_1.0.4/bower_components/paper-header-panel/README.md
new file mode 100644
index 0000000..aab76e6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-header-panel/README.md
@@ -0,0 +1,105 @@
+# paper-header-panel
+
+`paper-header-panel` contains a header section and a content panel section.
+
+__Important:__ The `paper-header-panel` will not display if its parent does not have a height.
+
+Using [layout classes](http://www.polymer-project.org/docs/polymer/layout-attrs.html), you can make
+the `paper-header-panel` fill the screen
+
+```html
+<body class="fullbleed layout vertical">
+ <paper-header-panel class="flex">
+ <paper-toolbar>
+ <div>Hello World!</div>
+ </paper-toolbar>
+ </paper-header-panel>
+</body>
+```
+
+Special support is provided for scrolling modes when one uses a `paper-toolbar` or equivalent for the header section. For example:
+
+```html
+<paper-header-panel>
+ <paper-toolbar>Header</paper-toolbar>
+ <div>Content goes here...</div>
+</paper-header-panel>
+```
+
+If you want to use other than `paper-toolbar` for the header, add `paper-header` class to that
+element:
+
+```html
+<paper-header-panel>
+ <div class="paper-header">Header</div>
+ <div>Content goes here...</div>
+</paper-header-panel>
+```
+
+To have the content fit to the main area, use the `fit` class:
+
+```html
+<paper-header-panel>
+ <div class="paper-header">standard</div>
+ <div class="content fit">content fits 100% below the header</div>
+</paper-header-panel>
+```
+
+### Mode
+
+Controls header and scrolling behavior. Options are `standard`, `seamed`, `waterfall`, `waterfall-tall`, `scroll` and
+`cover`. Default is `standard`.
+
+Mode | Description
+----------------|-------------
+`standard` | The header is a step above the panel. The header will consume the panel at the point of entry, preventing it from passing through to the opposite side.
+`seamed` | The header is presented as seamed with the panel.
+`waterfall` | Similar to standard mode, but header is initially presented as seamed with panel, but then separates to form the step.
+`waterfall-tall` | The header is initially taller (`tall` class is added to the header). As the user scrolls, the header separates (forming an edge) while condensing (`tall` class is removed from the header).
+`scroll` | The header keeps its seam with the panel, and is pushed off screen.
+`cover` | The panel covers the whole `paper-header-panel` including the header. This allows user to style the panel in such a way that the panel is partially covering the header.
+
+Example:
+
+```html
+<paper-header-panel mode="waterfall">
+ <div class="paper-header">standard</div>
+ <div class="content fit">content fits 100% below the header</div>
+</paper-header-panel>
+```
+
+### Styling header panel:
+
+To change the shadow that shows up underneath the header:
+
+```css
+paper-header-panel {
+ --paper-header-panel-shadow: {
+ height: 6px;
+ bottom: -6px;
+ box-shadow: inset 0px 5px 6px -3px rgba(0, 0, 0, 0.4);
+ };
+}
+```
+
+To change the panel container:
+
+```css
+paper-slider {
+ --paper-header-panel-standard-container: {
+ border: 1px solid gray;
+ };
+
+ --paper-header-panel-cover-container: {
+ border: 1px solid gray;
+ };
+
+ --paper-header-panel-waterfall-container: {
+ border: 1px solid gray;
+ };
+
+ --paper-header-panel-waterfall-tall-container: {
+ border: 1px solid gray;
+ };
+}
+```
diff --git a/polymer_1.0.4/bower_components/paper-header-panel/bower.json b/polymer_1.0.4/bower_components/paper-header-panel/bower.json
new file mode 100644
index 0000000..62efe83
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-header-panel/bower.json
@@ -0,0 +1,28 @@
+{
+ "name": "paper-header-panel",
+ "version": "1.0.2",
+ "description": "A header and content wrapper for layout with headers",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "layout"
+ ],
+ "private": true,
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-header-panel",
+ "ignore": [],
+ "dependencies": {
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-header-panel/demo/index.html b/polymer_1.0.4/bower_components/paper-header-panel/demo/index.html
new file mode 100644
index 0000000..9820ddc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-header-panel/demo/index.html
@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+
+ <head>
+ <title>paper-header-panel demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../paper-header-panel.html">
+
+ <style is="custom-style">
+ body {
+ padding: 40px;
+ }
+
+ paper-header-panel {
+ float: left;
+ width: 240px;
+ height: 240px;
+ margin: 12px;
+ @apply(--shadow-elevation-2dp);
+ }
+
+ .paper-header {
+ height: 60px;
+ font-size: 16px;
+ line-height: 60px;
+ padding: 0 10px;
+ color: white;
+ transition: height 0.2s;
+ }
+
+ .paper-header.tall {
+ height: 120px;
+ }
+
+ .paper-header.medium-tall {
+ height: 100px;
+ line-height: 50px;
+ }
+
+ .content {
+ height: 2000px;
+ }
+
+ .cover {
+ margin: 60px;
+ }
+
+ .blue .paper-header {
+ background-color: var(--paper-light-blue-500);
+ }
+ .red .paper-header {
+ background-color: var(--paper-red-500);
+ }
+ .orange .paper-header {
+ background-color: var(--paper-amber-500);
+ }
+ .green .paper-header {
+ background-color: var(--paper-green-500);
+ }
+ .cyan .paper-header {
+ background-color: var(--paper-cyan-500);
+ }
+ .lime .paper-header {
+ background-color: var(--paper-lime-500);
+ }
+ .pink .paper-header {
+ background-color: var(--paper-pink-a200);
+ }
+
+ /* TODO: replace these with background: linear-gradient(white, var(...))
+ when custom properties allow it */
+
+ .blue .content {
+ background: linear-gradient(white, #b3e5fc);
+ }
+ .red .content {
+ background: linear-gradient(white, #ffcdd2);
+ }
+ .orange .content {
+ background: linear-gradient(white, #ffecb3);
+ }
+ .green .content {
+ background: linear-gradient(white, #c8e6c9);
+ }
+ .cyan .content {
+ background: linear-gradient(white, #b2ebf2);
+ }
+ .lime .content {
+ background: linear-gradient(white, #f0f4c3);
+ }
+ .pink .content {
+ background: linear-gradient(white, #f8bbd0);
+ }
+ </style>
+ </head>
+
+ <body>
+ <div class="layout wrap inline center-center">
+ <paper-header-panel class="blue">
+ <div class="paper-header">standard</div>
+ <div class="content"></div>
+ </paper-header-panel>
+
+ <paper-header-panel mode="seamed" class="red">
+ <div class="paper-header">seamed</div>
+ <div class="content"></div>
+ </paper-header-panel>
+
+ <paper-header-panel mode="scroll" class="orange">
+ <div class="paper-header">scroll</div>
+ <div class="content"></div>
+ </paper-header-panel>
+
+ <paper-header-panel mode="waterfall" class="green">
+ <div class="paper-header">waterfall</div>
+ <div class="content"></div>
+ </paper-header-panel>
+
+ <paper-header-panel mode="waterfall-tall" class="pink">
+ <div class="paper-header">waterfall-tall</div>
+ <div class="content"></div>
+ </paper-header-panel>
+
+ <paper-header-panel mode="waterfall-tall" tall-class="medium-tall" class="cyan">
+ <div class="paper-header">waterfall-tall<br>tall-class: medium-tall</div>
+ <div class="content"></div>
+ </paper-header-panel>
+
+ <paper-header-panel mode="cover" class="lime">
+ <div class="paper-header tall">cover</div>
+ <div class="content cover"></div>
+ </paper-header-panel>
+ </div>
+ </body>
+
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-header-panel/hero.svg b/polymer_1.0.4/bower_components/paper-header-panel/hero.svg
new file mode 100755
index 0000000..60c7488
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-header-panel/hero.svg
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <path d="M163,102H73V24h90V102z M75,100h86V26H75V100z"/>
+ <g>
+ <polygon points="74,59.6 74,62.5 74.5,63 77.4,63 "/>
+ <polygon points="74,51.9 74,54.7 82.3,63 85.1,63 "/>
+ <polygon points="74,44.1 74,46.9 90.1,63 92.9,63 "/>
+ <polygon points="74,36.3 74,39.2 97.8,63 100.7,63 "/>
+ <polygon points="74,28.6 74,31.4 105.6,63 108.4,63 "/>
+ <polygon points="78.2,25 75.4,25 113.4,63 116.2,63 "/>
+ <polygon points="86,25 83.1,25 121.1,63 124,63 "/>
+ <polygon points="93.7,25 90.9,25 128.9,63 131.7,63 "/>
+ <polygon points="101.5,25 98.7,25 136.7,63 139.5,63 "/>
+ <polygon points="109.2,25 106.4,25 144.4,63 147.2,63 "/>
+ <polygon points="117,25 114.2,25 152.2,63 155,63 "/>
+ <polygon points="124.8,25 122,25 160,63 162,63 162,62.2 "/>
+ <polygon points="132.5,25 129.7,25 162,57.3 162,54.5 "/>
+ <polygon points="140.3,25 137.5,25 162,49.5 162,46.7 "/>
+ <polygon points="148.1,25 145.2,25 162,41.8 162,38.9 "/>
+ <polygon points="155.8,25 153,25 162,34 162,31.2 "/>
+ <polygon points="162,26.2 162,25 160.8,25 "/>
+ </g>
+ <rect x="74" y="62" width="88" height="2"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-header-panel/index.html b/polymer_1.0.4/bower_components/paper-header-panel/index.html
new file mode 100644
index 0000000..8d0771c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-header-panel/index.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>paper-header-panel</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+ <style>
+ body {
+ margin: 16px;
+ }
+ </style>
+
+ </head>
+ <body>
+
+ <iron-component-page></iron-component-page>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-header-panel/paper-header-panel.html b/polymer_1.0.4/bower_components/paper-header-panel/paper-header-panel.html
new file mode 100644
index 0000000..d337995
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-header-panel/paper-header-panel.html
@@ -0,0 +1,494 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
+
+<!--
+`paper-header-panel` contains a header section and a content panel section.
+
+__Important:__ The `paper-header-panel` will not display if its parent does not have a height.
+
+Using layout classes, you can make the `paper-header-panel` fill the screen
+
+ <body class="fullbleed layout vertical">
+ <paper-header-panel class="flex">
+ <paper-toolbar>
+ <div>Hello World!</div>
+ </paper-toolbar>
+ </paper-header-panel>
+ </body>
+
+Special support is provided for scrolling modes when one uses a paper-toolbar or equivalent for the
+header section.
+
+Example:
+
+ <paper-header-panel>
+ <paper-toolbar>Header</paper-toolbar>
+ <div>Content goes here...</div>
+ </paper-header-panel>
+
+If you want to use other than `paper-toolbar` for the header, add `paper-header` class to that
+element.
+
+Example:
+
+ <paper-header-panel>
+ <div class="paper-header">Header</div>
+ <div>Content goes here...</div>
+ </paper-header-panel>
+
+To have the content fit to the main area, use the `fit` class.
+
+ <paper-header-panel>
+ <div class="paper-header">standard</div>
+ <div class="fit">content fits 100% below the header</div>
+ </paper-header-panel>
+
+Modes
+
+Controls header and scrolling behavior. Options are `standard`, `seamed`, `waterfall`, `waterfall-tall`, `scroll` and
+`cover`. Default is `standard`.
+
+Mode | Description
+----------------|-------------
+`standard` | The header is a step above the panel. The header will consume the panel at the point of entry, preventing it from passing through to the opposite side.
+`seamed` | The header is presented as seamed with the panel.
+`waterfall` | Similar to standard mode, but header is initially presented as seamed with panel, but then separates to form the step.
+`waterfall-tall` | The header is initially taller (`tall` class is added to the header). As the user scrolls, the header separates (forming an edge) while condensing (`tall` class is removed from the header).
+`scroll` | The header keeps its seam with the panel, and is pushed off screen.
+`cover` | The panel covers the whole `paper-header-panel` including the header. This allows user to style the panel in such a way that the panel is partially covering the header.
+
+Example:
+
+ <paper-header-panel mode="waterfall">
+ <div class="paper-header">standard</div>
+ <div class="content fit">content fits 100% below the header</div>
+ </paper-header-panel>
+
+
+Styling header panel:
+
+To change the shadow that shows up underneath the header:
+
+ paper-header-panel {
+ --paper-header-panel-shadow: {
+ height: 6px;
+ bottom: -6px;
+ box-shadow: inset 0px 5px 6px -3px rgba(0, 0, 0, 0.4);
+ };
+ }
+
+To change the panel container in different modes:
+
+ paper-slider {
+ --paper-header-panel-standard-container: {
+ border: 1px solid gray;
+ };
+
+ --paper-header-panel-cover-container: {
+ border: 1px solid gray;
+ };
+
+ --paper-header-panel-waterfall-container: {
+ border: 1px solid gray;
+ };
+
+ --paper-header-panel-waterfall-tall-container: {
+ border: 1px solid gray;
+ };
+ }
+
+@group Paper Elements
+@element paper-header-panel
+@demo demo/index.html
+@hero hero.svg
+-->
+
+<dom-module id="paper-header-panel">
+
+ <style>
+ :host {
+ @apply(--layout);
+ @apply(--layout-vertical);
+
+ display: block;
+ position: relative;
+ height: 100%;
+
+ /* Create a stack context, we will need it for the shadow*/
+ z-index: 0;
+ }
+
+ :root {
+ /**
+ * Default paper header panel shadow
+ */
+ --paper-header-panel-shadow: {
+ height: 6px;
+ bottom: -6px;
+ box-shadow: inset 0px 5px 6px -3px rgba(0, 0, 0, 0.4);
+ };
+ }
+
+ #mainContainer {
+ @apply(--layout-flex);
+
+ position: relative;
+ overflow-y: auto;
+ overflow-x: hidden;
+ -webkit-overflow-scrolling: touch;
+ flex-basis: 0.0001px;
+ }
+
+ /*
+ * mode: scroll
+ */
+ :host([mode=scroll]) #mainContainer {
+ @apply(--paper-header-panel-scroll-container);
+ overflow: visible;
+ }
+
+ :host([mode=scroll]) {
+ overflow-y: auto;
+ overflow-x: hidden;
+ -webkit-overflow-scrolling: touch;
+ }
+
+ /*
+ * mode: cover
+ */
+ :host([mode=cover]) #mainContainer {
+ @apply(--paper-header-panel-cover-container);
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ }
+
+ /*
+ * mode: standard
+ */
+ :host([mode=standard]) #mainContainer {
+ @apply(--paper-header-panel-standard-container);
+ }
+
+ /*
+ * mode: waterfall
+ */
+ :host([mode=waterfall]) #mainContainer {
+ @apply(--paper-header-panel-waterfall-container);
+ }
+
+ /*
+ * mode: waterfall-tall
+ */
+ :host([mode=waterfall-tall]) #mainContainer {
+ @apply(--paper-header-panel-waterfall-tall-container);
+ }
+
+ :host ::content paper-toolbar,
+ :host ::content .paper-header {
+ position: relative;
+ overflow: visible !important;
+ }
+
+ :host ::content paper-toolbar:after,
+ :host ::content .paper-header:after {
+ @apply(--paper-header-panel-shadow);
+
+ -webkit-transition: opacity 0.5s, -webkit-transform 0.5s;
+ transition: opacity 0.5s, transform 0.5s;
+
+ opacity: 0;
+ content: "";
+
+ width: 100%;
+ position: absolute;
+ left: 0px;
+ right: 0px;
+ z-index: 1;
+
+ -webkit-transform: scale3d(1, 0, 1);
+ -webkit-transform-origin: 0% 0%;
+
+ transform: scale3d(1, 0, 1);
+ transform-origin: 0% 0%;
+ }
+
+ :host ::content paper-toolbar.has-shadow:after,
+ :host ::content .paper-header.has-shadow:after {
+ opacity: 1;
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+ </style>
+
+ <template>
+ <content id="headerContent" select="paper-toolbar, .paper-header"></content>
+ <div id="mainContainer" class$="[[_computeMainContainerClass(mode)]]">
+ <content id="mainContent" select="*"></content>
+ </div>
+ </template>
+
+</dom-module>
+
+<script>
+
+ (function() {
+
+ 'use strict';
+
+ var SHADOW_WHEN_SCROLLING = 1;
+ var SHADOW_ALWAYS = 2;
+
+
+ var MODE_CONFIGS = {
+
+ outerScroll: {
+ scroll: true
+ },
+
+ shadowMode: {
+ standard: SHADOW_ALWAYS,
+ waterfall: SHADOW_WHEN_SCROLLING,
+ 'waterfall-tall': SHADOW_WHEN_SCROLLING
+ },
+
+ tallMode: {
+ 'waterfall-tall': true
+ }
+ };
+
+ Polymer({
+
+ is: 'paper-header-panel',
+
+ /**
+ * Fired when the content has been scrolled. `event.detail.target` returns
+ * the scrollable element which you can use to access scroll info such as
+ * `scrollTop`.
+ *
+ * <paper-header-panel on-content-scroll="{{scrollHandler}}">
+ * ...
+ * </paper-header-panel>
+ *
+ *
+ * scrollHandler: function(event) {
+ * var scroller = event.detail.target;
+ * console.log(scroller.scrollTop);
+ * }
+ *
+ * @event content-scroll
+ */
+
+ properties: {
+
+ /**
+ * Controls header and scrolling behavior. Options are
+ * `standard`, `seamed`, `waterfall`, `waterfall-tall`, `scroll` and
+ * `cover`. Default is `standard`.
+ *
+ * `standard`: The header is a step above the panel. The header will consume the
+ * panel at the point of entry, preventing it from passing through to the
+ * opposite side.
+ *
+ * `seamed`: The header is presented as seamed with the panel.
+ *
+ * `waterfall`: Similar to standard mode, but header is initially presented as
+ * seamed with panel, but then separates to form the step.
+ *
+ * `waterfall-tall`: The header is initially taller (`tall` class is added to
+ * the header). As the user scrolls, the header separates (forming an edge)
+ * while condensing (`tall` class is removed from the header).
+ *
+ * `scroll`: The header keeps its seam with the panel, and is pushed off screen.
+ *
+ * `cover`: The panel covers the whole `paper-header-panel` including the
+ * header. This allows user to style the panel in such a way that the panel is
+ * partially covering the header.
+ *
+ * <paper-header-panel mode="cover">
+ * <paper-toolbar class="tall">
+ * <core-icon-button icon="menu"></core-icon-button>
+ * </paper-toolbar>
+ * <div class="content"></div>
+ * </paper-header-panel>
+ */
+ mode: {
+ type: String,
+ value: 'standard',
+ observer: '_modeChanged',
+ reflectToAttribute: true
+ },
+
+ /**
+ * If true, the drop-shadow is always shown no matter what mode is set to.
+ */
+ shadow: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The class used in waterfall-tall mode. Change this if the header
+ * accepts a different class for toggling height, e.g. "medium-tall"
+ */
+ tallClass: {
+ type: String,
+ value: 'tall'
+ },
+
+ /**
+ * If true, the scroller is at the top
+ */
+ atTop: {
+ type: Boolean,
+ value: true,
+ readOnly: true
+ }
+ },
+
+ observers: [
+ '_computeDropShadowHidden(atTop, mode, shadow)'
+ ],
+
+ ready: function() {
+ this.scrollHandler = this._scroll.bind(this);
+ this._addListener();
+
+ // Run `scroll` logic once to initialze class names, etc.
+ this._keepScrollingState();
+ },
+
+ detached: function() {
+ this._removeListener();
+ },
+
+ /**
+ * Returns the header element
+ *
+ * @property header
+ * @type Object
+ */
+ get header() {
+ return Polymer.dom(this.$.headerContent).getDistributedNodes()[0];
+ },
+
+ /**
+ * Returns the scrollable element.
+ *
+ * @property scroller
+ * @type Object
+ */
+ get scroller() {
+ return this._getScrollerForMode(this.mode);
+ },
+
+ /**
+ * Returns true if the scroller has a visible shadow.
+ *
+ * @property visibleShadow
+ * @type Boolean
+ */
+ get visibleShadow() {
+ return this.header.classList.contains('has-shadow');
+ },
+
+ _computeDropShadowHidden: function(atTop, mode, shadow) {
+
+ var shadowMode = MODE_CONFIGS.shadowMode[mode];
+
+ if (this.shadow) {
+ this.toggleClass('has-shadow', true, this.header);
+
+ } else if (shadowMode === SHADOW_ALWAYS) {
+ this.toggleClass('has-shadow', true, this.header);
+
+ } else if (shadowMode === SHADOW_WHEN_SCROLLING && !atTop) {
+ this.toggleClass('has-shadow', true, this.header);
+
+ } else {
+ this.toggleClass('has-shadow', false, this.header);
+
+ }
+ },
+
+ _computeMainContainerClass: function(mode) {
+ // TODO: It will be useful to have a utility for classes
+ // e.g. Polymer.Utils.classes({ foo: true });
+
+ var classes = {};
+
+ classes['flex'] = mode !== 'cover';
+
+ return Object.keys(classes).filter(
+ function(className) {
+ return classes[className];
+ }).join(' ');
+ },
+
+ _addListener: function() {
+ this.scroller.addEventListener('scroll', this.scrollHandler, false);
+ },
+
+ _removeListener: function() {
+ this.scroller.removeEventListener('scroll', this.scrollHandler);
+ },
+
+ _modeChanged: function(newMode, oldMode) {
+ var configs = MODE_CONFIGS;
+ var header = this.header;
+ var animateDuration = 200;
+
+ if (header) {
+ // in tallMode it may add tallClass to the header; so do the cleanup
+ // when mode is changed from tallMode to not tallMode
+ if (configs.tallMode[oldMode] && !configs.tallMode[newMode]) {
+ header.classList.remove(this.tallClass);
+ this.async(function() {
+ header.classList.remove('animate');
+ }, animateDuration);
+ } else {
+ header.classList.toggle('animate', configs.tallMode[newMode]);
+ }
+ }
+ this._keepScrollingState();
+ },
+
+ _keepScrollingState: function () {
+ var main = this.scroller;
+ var header = this.header;
+
+ this._setAtTop(main.scrollTop === 0);
+
+ if (header && MODE_CONFIGS.tallMode[this.mode]) {
+ this.toggleClass(this.tallClass, this.atTop ||
+ header.classList.contains(this.tallClass) &&
+ main.scrollHeight < this.offsetHeight, header);
+ }
+ },
+
+ _scroll: function(e) {
+ this._keepScrollingState();
+ this.fire('content-scroll', {target: this.scroller}, {bubbles: false});
+ },
+
+ _getScrollerForMode: function(mode) {
+ return MODE_CONFIGS.outerScroll[mode] ?
+ this : this.$.mainContainer;
+ }
+
+ });
+
+ })();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-header-panel/test/basic.html b/polymer_1.0.4/bower_components/paper-header-panel/test/basic.html
new file mode 100644
index 0000000..46e6d5a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-header-panel/test/basic.html
@@ -0,0 +1,156 @@
+<!--
+ @license
+ Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ Code distributed by Google as part of the polymer project is also
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!DOCTYPE html>
+<html>
+<head>
+
+ <title>paper-header-panel tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../paper-header-panel.html">
+
+ <style>
+
+ paper-header-panel {
+ height: 100%;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <test-fixture id="standard">
+ <template>
+ <paper-header-panel mode="standard">
+ <div class="paper-header">header</div>
+ <div>body</div>
+ </paper-header-panel>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="seamed">
+ <template>
+ <paper-header-panel mode="seamed">
+ <div class="paper-header">header</div>
+ <div>body</div>
+ </paper-header-panel>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="seamed-shadow">
+ <template>
+ <paper-header-panel mode="seamed" shadow>
+ <div class="paper-header">header</div>
+ <div>body</div>
+ </paper-header-panel>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="waterfall">
+ <template>
+ <paper-header-panel mode="waterfall">
+ <div class="paper-header">header</div>
+ <div>body</div>
+ </paper-header-panel>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="waterfall-tall">
+ <template>
+ <paper-header-panel mode="waterfall-tall">
+ <div class="paper-header">header</div>
+ <div>body</div>
+ </paper-header-panel>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="scroll">
+ <template>
+ <paper-header-panel mode="scroll">
+ <div class="paper-header">header</div>
+ <div>body</div>
+ </paper-header-panel>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="cover">
+ <template>
+ <paper-header-panel mode="cover">
+ <div class="paper-header">header</div>
+ <div>body</div>
+ </paper-header-panel>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('shadow', function() {
+ var standard, seamed, waterfall, waterfallTall, scroll, cover;
+
+ setup(function(done) {
+ standard = fixture('standard');
+ seamed = fixture('seamed');
+ seamedShadow = fixture('seamed-shadow');
+ waterfall = fixture('waterfall');
+ waterfallTall = fixture('waterfall-tall');
+ scroll = fixture('scroll');
+ cover = fixture('cover');
+ // async to let change handlers fire
+ setTimeout(done, 0);
+ });
+
+ function hasShadow(panel) {
+ return panel.visibleShadow;
+ };
+
+ test('has shadow in standard mode', function() {
+ assert.isTrue(hasShadow(standard), 'shadow has display');
+ });
+
+ test('no shadow in seamed mode', function() {
+ assert.isFalse(hasShadow(seamed), 'shadow is display:none');
+ });
+
+ test('no shadow in waterfall mode', function() {
+ assert.isFalse(hasShadow(waterfall), 'shadow is display:none');
+ });
+
+ test('no shadow in waterfall-tall mode', function() {
+ assert.isFalse(hasShadow(waterfallTall), 'shadow is display:none');
+ });
+
+ test('no shadow in scroll mode', function() {
+ assert.isFalse(hasShadow(scroll), 'shadow is display:none');
+ });
+
+ test('no shadow in cover mode', function() {
+ assert.isFalse(hasShadow(cover), 'shadow is display:none');
+ });
+
+ test('shadow property forces shadow to show', function() {
+ assert.isTrue(hasShadow(seamedShadow), 'shadow has display');
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-header-panel/test/index.html b/polymer_1.0.4/bower_components/paper-header-panel/test/index.html
new file mode 100644
index 0000000..ce8727d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-header-panel/test/index.html
@@ -0,0 +1,34 @@
+<!--
+ @license
+ Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ Code distributed by Google as part of the polymer project is also
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!DOCTYPE html>
+<html>
+ <head>
+
+ <title>paper-header-panel tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-icon-button/.bower.json b/polymer_1.0.4/bower_components/paper-icon-button/.bower.json
new file mode 100644
index 0000000..71c8d45
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-icon-button/.bower.json
@@ -0,0 +1,43 @@
+{
+ "name": "paper-icon-button",
+ "private": true,
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "A material design icon button",
+ "main": "paper-icon-button.html",
+ "author": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "button",
+ "icon",
+ "control"
+ ],
+ "dependencies": {
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "iron-icons": "polymerelements/iron-icons#^1.0.0",
+ "paper-behaviors": "polymerelements/paper-behaviors#^1.0.0",
+ "paper-ripple": "polymerelements/paper-ripple#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/paper-icon-button",
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "b22ade2080f2527760eae41e4700c52d4689a866"
+ },
+ "_source": "git://github.com/PolymerElements/paper-icon-button.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-icon-button"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-icon-button/.gitignore b/polymer_1.0.4/bower_components/paper-icon-button/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-icon-button/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-icon-button/README.md b/polymer_1.0.4/bower_components/paper-icon-button/README.md
new file mode 100644
index 0000000..96dbf8e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-icon-button/README.md
@@ -0,0 +1,49 @@
+paper-icon-button
+=================
+
+Material Design: <a href="http://www.google.com/design/spec/components/buttons.html">Buttons</a>
+
+`paper-icon-button` is a button with an image placed at the center. When the user touches
+the button, a ripple effect emanates from the center of the button.
+
+`paper-icon-button` includes a default icon set. Use `icon` to specify which icon
+from the icon set to use.
+
+```html
+<paper-icon-button icon="menu"></paper-icon-button>
+```
+
+See [`iron-iconset`](#iron-iconset) for more information about
+how to use a custom icon set.
+
+Example:
+
+```html
+<link href="path/to/iron-icons/iron-icons.html" rel="import">
+
+<paper-icon-button icon="favorite"></paper-icon-button>
+<paper-icon-button src="star.png"></paper-icon-button>
+```
+
+Styling
+-------
+
+Style the button with CSS as you would a normal DOM element. If you are using the icons
+provided by `iron-icons`, they will inherit the foreground color of the button.
+
+```html
+<!-- make a red "favorite" button -->
+<paper-icon-button icon="favorite" style="color: red;"></paper-icon-button>
+```
+
+By default, the ripple is the same color as the foreground at 25% opacity. You may
+customize the color using this selector:
+
+```css
+/* make #my-button use a blue ripple instead of foreground color */
+#my-button::shadow #ripple {
+ color: blue;
+}
+```
+
+The opacity of the ripple is not customizable via CSS.
diff --git a/polymer_1.0.4/bower_components/paper-icon-button/bower.json b/polymer_1.0.4/bower_components/paper-icon-button/bower.json
new file mode 100644
index 0000000..6886757
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-icon-button/bower.json
@@ -0,0 +1,33 @@
+{
+ "name": "paper-icon-button",
+ "private": true,
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "A material design icon button",
+ "main": "paper-icon-button.html",
+ "author": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "button",
+ "icon",
+ "control"
+ ],
+ "dependencies": {
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "iron-icons": "polymerelements/iron-icons#^1.0.0",
+ "paper-behaviors": "polymerelements/paper-behaviors#^1.0.0",
+ "paper-ripple": "polymerelements/paper-ripple#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-icon-button/demo/index.html b/polymer_1.0.4/bower_components/paper-icon-button/demo/index.html
new file mode 100644
index 0000000..cbe6795
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-icon-button/demo/index.html
@@ -0,0 +1,154 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+ <head>
+ <title>paper-icon-button</title>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../paper-icon-button.html">
+
+ <style is="custom-style">
+ .horizontal-section {
+ min-width: 100px;
+ }
+
+ paper-icon-button {
+ margin-left: 30px;
+ display: block;
+ width: 24px;
+ text-align: center;
+ }
+
+ paper-icon-button.blue {
+ color: var(--paper-light-blue-500);
+ }
+
+ paper-icon-button.red {
+ color: var(--paper-red-500);
+ }
+
+ paper-icon-button.orange {
+ color: var(--paper-orange-500);
+ }
+
+ paper-icon-button.green {
+ color: var(--paper-green-500);
+ }
+
+ paper-icon-button.blue:hover {
+ background: var(--paper-light-blue-50);
+ border-radius: 50%;
+ }
+
+ paper-icon-button.red:hover {
+ background: var(--paper-red-50);
+ border-radius: 50%;
+ }
+
+ paper-icon-button.orange:hover {
+ background: var(--paper-orange-50);
+ border-radius: 50%;
+ }
+
+ paper-icon-button.green:hover {
+ background: var(--paper-green-50);
+ border-radius: 50%;
+ }
+
+ paper-icon-button.huge {
+ margin-left: 0px;
+ width: 100px;
+ --paper-icon-button-ink-color: var(--paper-indigo-500);
+ }
+
+ paper-icon-button.huge::shadow #icon {
+ width: 100px;
+ height: 100px;
+ }
+
+ paper-icon-button.huge #icon {
+ width: 100px;
+ height: 100px;
+ }
+ </style>
+
+ </head>
+
+ <body onclick="clickAction(event);">
+
+ <div class="horizontal center-justified layout">
+ <div>
+ <h4>Enabled</h4>
+ <div class="horizontal-section">
+ <paper-icon-button icon="menu" alt="menu" title="menu"></paper-icon-button>
+ <paper-icon-button icon="favorite" alt="heart" title="heart"></paper-icon-button>
+ <paper-icon-button icon="arrow-back" alt="arrow-back" title="arrow-back"></paper-icon-button>
+ <paper-icon-button icon="arrow-forward" alt="arrow-forward" title="arrow-forward"></paper-icon-button>
+ <paper-icon-button icon="clear" alt="clear" title="clear"></paper-icon-button>
+ <paper-icon-button icon="polymer" alt="polymer" title="polymer"></paper-icon-button>
+ <paper-icon-button src="https://assets-cdn.github.com/images/modules/logos_page/Octocat.png" alt="octocat" title="octocat"></paper-icon-button>
+ </div>
+ </div>
+
+ <div>
+ <h4>Disabled</h4>
+ <div class="horizontal-section">
+ <paper-icon-button icon="menu" alt="menu" disabled></paper-icon-button>
+ <paper-icon-button icon="favorite" alt="heart" disabled></paper-icon-button>
+ <paper-icon-button icon="arrow-back" alt="arrow-back" disabled></paper-icon-button>
+ <paper-icon-button icon="arrow-forward" alt="arrow-forward" disabled></paper-icon-button>
+ <paper-icon-button icon="clear" alt="clear" disabled></paper-icon-button>
+ <paper-icon-button icon="polymer" alt="polymer" disabled></paper-icon-button>
+ <paper-icon-button src="https://assets-cdn.github.com/images/modules/logos_page/Octocat.png" alt="octocat" disabled></paper-icon-button>
+ </div>
+ </div>
+
+ <div>
+ <h4>Color</h4>
+ <div class="horizontal-section">
+ <paper-icon-button icon="menu" alt="menu" class="blue"></paper-icon-button>
+ <paper-icon-button icon="favorite" alt="heart" class="red"></paper-icon-button>
+ <paper-icon-button icon="arrow-back" alt="arrow-back" class="orange"></paper-icon-button>
+ <paper-icon-button icon="arrow-forward" alt="arrow-forward" class="green"></paper-icon-button>
+ <paper-icon-button icon="clear" alt="clear" class="blue"></paper-icon-button>
+ <paper-icon-button icon="polymer" alt="polymer" class="red"></paper-icon-button>
+ <paper-icon-button class="blue" src="https://assets-cdn.github.com/images/modules/logos_page/Octocat.png" alt="octocat"></paper-icon-button>
+ </div>
+ </div>
+
+ <div>
+ <h4>Size</h4>
+ <div class="horizontal-section">
+ <paper-icon-button icon="favorite" alt="heart" class="huge"></paper-icon-button>
+ <br><br><br>
+ <paper-icon-button icon="polymer" alt="polymer" class="huge"></paper-icon-button>
+ </div>
+ </div>
+ </div>
+
+ <script>
+ function clickAction(e) {
+ var t = e.target;
+ if (t.localName === 'paper-icon-button') {
+ if (t.hasAttribute('disabled')) {
+ console.error('should not be able to click disabled button', t);
+ } else {
+ console.log('click', t);
+ }
+ }
+ }
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-icon-button/index.html b/polymer_1.0.4/bower_components/paper-icon-button/index.html
new file mode 100644
index 0000000..94c3720
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-icon-button/index.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <script src="../webcomponentsjs/webcomponents.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-icon-button/paper-icon-button.html b/polymer_1.0.4/bower_components/paper-icon-button/paper-icon-button.html
new file mode 100644
index 0000000..f4164ce
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-icon-button/paper-icon-button.html
@@ -0,0 +1,156 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
+<link rel="import" href="../paper-styles/default-theme.html">
+<link rel="import" href="../paper-behaviors/paper-button-behavior.html">
+<link rel="import" href="../paper-behaviors/paper-inky-focus-behavior.html">
+<link rel="import" href="../paper-ripple/paper-ripple.html">
+
+<!--
+Material Design: <a href="http://www.google.com/design/spec/components/buttons.html">Buttons</a>
+
+`paper-icon-button` is a button with an image placed at the center. When the user touches
+the button, a ripple effect emanates from the center of the button.
+
+`paper-icon-button` includes a default icon set. Use `icon` to specify which icon
+from the icon set to use.
+
+ <paper-icon-button icon="menu"></paper-icon-button>
+
+See [`iron-iconset`](#iron-iconset) for more information about
+how to use a custom icon set.
+
+Example:
+
+ <link href="path/to/iron-icons/iron-icons.html" rel="import">
+
+ <paper-icon-button icon="favorite"></paper-icon-button>
+ <paper-icon-button src="star.png"></paper-icon-button>
+
+###Styling
+
+Style the button with CSS as you would a normal DOM element. If you are using the icons
+provided by `iron-icons`, they will inherit the foreground color of the button.
+
+ /* make a red "favorite" button */
+ <paper-icon-button icon="favorite" style="color: red;"></paper-icon-button>
+
+By default, the ripple is the same color as the foreground at 25% opacity. You may
+customize the color using this selector:
+
+ /* make #my-button use a blue ripple instead of foreground color */
+ #my-button::shadow #ripple {
+ color: blue;
+ }
+
+The opacity of the ripple is not customizable via CSS.
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-icon-button-disabled-text` | The color of the disabled button | `--primary-text-color`
+`--paper-icon-button-ink-color` | Selected/focus ripple color | `--default-primary-color`
+`--paper-icon-button` | Mixin for a button | `{}`
+`--paper-icon-button-disabled` | Mixin for a disabled button | `{}`
+
+@group Paper Elements
+@element paper-icon-button
+@demo demo/index.html
+-->
+
+<dom-module id="paper-icon-button">
+ <style>
+
+ :host {
+ display: inline-block;
+ position: relative;
+ padding: 8px;
+ outline: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ cursor: pointer;
+ z-index: 0;
+
+ @apply(--paper-icon-button);
+ }
+
+ :host #ink {
+ color: var(--paper-icon-button-ink-color, --primary-text-color);
+ opacity: 0.6;
+ }
+
+ :host([disabled]) {
+ color: var(--paper-icon-button-disabled-text, --disabled-text-color);
+ pointer-events: none;
+ cursor: auto;
+ @apply(--paper-icon-button-disabled);
+ }
+ </style>
+ <template>
+ <paper-ripple id="ink" class="circle" center></paper-ripple>
+ <iron-icon id="icon" src="[[src]]" icon="[[icon]]" alt$="[[alt]]"></iron-icon>
+ </template>
+</dom-module>
+<script>
+ Polymer({
+ is: 'paper-icon-button',
+
+ hostAttributes: {
+ role: 'button',
+ tabindex: '0'
+ },
+
+ behaviors: [
+ Polymer.PaperInkyFocusBehavior
+ ],
+
+ properties: {
+ /**
+ * The URL of an image for the icon. If the src property is specified,
+ * the icon property should not be.
+ */
+ src: {
+ type: String
+ },
+
+ /**
+ * Specifies the icon name or index in the set of icons available in
+ * the icon's icon set. If the icon property is specified,
+ * the src property should not be.
+ */
+ icon: {
+ type: String
+ },
+
+ /**
+ * Specifies the alternate text for the button, for accessibility.
+ */
+ alt: {
+ type: String,
+ observer: "_altChanged"
+ }
+ },
+
+ _altChanged: function(newValue, oldValue) {
+ var label = this.getAttribute('aria-label');
+
+ // Don't stomp over a user-set aria-label.
+ if (!label || oldValue == label) {
+ this.setAttribute('aria-label', newValue);
+ }
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-icon-button/test/a11y.html b/polymer_1.0.4/bower_components/paper-icon-button/test/a11y.html
new file mode 100644
index 0000000..f6bf6fd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-icon-button/test/a11y.html
@@ -0,0 +1,94 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>paper-icon-button a11y tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../paper-icon-button.html">
+
+</head>
+<body>
+
+ <test-fixture id="A11yIconButtons">
+ <template>
+ <paper-icon-button id="iconButton1" icon="add"></paper-icon-button>
+ <paper-icon-button id="iconButton2" icon="add" disabled></paper-icon-button>
+ <paper-icon-button id="iconButton3" icon="add" aria-label="custom"></paper-icon-button>
+ <paper-icon-button id="iconButton4" icon="add" alt="alt text"></paper-icon-button>
+ <paper-icon-button id="iconButton5" icon="add" aria-label="custom" alt="alt text" ></paper-icon-button>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ var b1;
+ var b2;
+ var b3;
+ var b4;
+ var b5;
+
+ setup(function() {
+ var iconButtons = fixture('A11yIconButtons');
+
+ b1 = iconButtons[0];
+ b2 = iconButtons[1];
+ b3 = iconButtons[2];
+ b4 = iconButtons[3];
+ b5 = iconButtons[4];
+ });
+
+ test('aria role is a button', function() {
+ assert.strictEqual(b1.getAttribute('role'), 'button');
+ });
+
+ test('aria-disabled is set', function() {
+ assert.strictEqual(b2.getAttribute('aria-disabled'), 'true');
+ b2.removeAttribute('disabled');
+ assert.strictEqual(b2.getAttribute('aria-disabled'), 'false');
+ });
+
+ test('user-defined aria-label is preserved', function() {
+ assert.strictEqual(b3.getAttribute('aria-label'), 'custom');
+ b3.icon = 'arrow-forward';
+ assert.strictEqual(b3.getAttribute('aria-label'), 'custom');
+ });
+
+ test('alt attribute is used for the aria-label', function() {
+ assert.strictEqual(b4.getAttribute('aria-label'), 'alt text');
+ b4.icon = 'arrow-forward';
+ assert.strictEqual(b4.getAttribute('aria-label'), 'alt text');
+ });
+
+ test('aria-label wins over alt attribute', function() {
+ assert.strictEqual(b5.getAttribute('aria-label'), 'custom');
+ b5.icon = 'arrow-forward';
+ b5.alt = 'other alt'
+ assert.strictEqual(b5.getAttribute('aria-label'), 'custom');
+ });
+
+ test('alt attribute can be updated', function() {
+ assert.strictEqual(b4.getAttribute('aria-label'), 'alt text');
+ b4.alt = 'alt again';
+ assert.strictEqual(b4.getAttribute('aria-label'), 'alt again');
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-icon-button/test/basic.html b/polymer_1.0.4/bower_components/paper-icon-button/test/basic.html
new file mode 100644
index 0000000..e98689c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-icon-button/test/basic.html
@@ -0,0 +1,77 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>paper-icon-button basic tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../paper-icon-button.html">
+
+</head>
+<body>
+
+ <test-fixture id="TrivialIconButton">
+ <template>
+ <div style="line-height:30px;">
+ <paper-icon-button id="fab1" icon="add"></paper-icon-button>
+ </div>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="SrcIconButton">
+ <template>
+ <paper-icon-button src="add.png"></paper-icon-button>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ var b1;
+ var b2;
+
+ function centerOf(element) {
+ var rect = element.getBoundingClientRect();
+ return {left: rect.left + rect.width / 2, top: rect.top + rect.height / 2};
+ }
+
+ function approxEqual(p1, p2) {
+ return Math.abs(p1.left - p2.left) <= 2 && Math.abs(p1.top-p2.top) <= 2;
+ }
+
+ setup(function() {
+ b1 = fixture('TrivialIconButton').querySelector('#fab1');
+ b2 = fixture('SrcIconButton');
+ });
+
+ test('applies an icon specified by the `icon` attribute', function() {
+ assert.strictEqual(!!b1.$.icon.src, false);
+ assert.ok(Polymer.dom(b1.$.icon.root).querySelector('svg'));
+ });
+
+ test('applies an icon specified by the `src` attribute', function() {
+
+ assert.strictEqual(!!b2.$.icon.src, true);
+ assert.ok(b2.$.icon.src);
+ });
+
+ test('renders correctly independent of line height', function() {
+ assert.ok(approxEqual(centerOf(b1.$.icon), centerOf(b1)));
+ });
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-icon-button/test/index.html b/polymer_1.0.4/bower_components/paper-icon-button/test/index.html
new file mode 100644
index 0000000..321c261
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-icon-button/test/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>paper-icon-button tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html',
+ 'a11y.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-input/.bower.json b/polymer_1.0.4/bower_components/paper-input/.bower.json
new file mode 100644
index 0000000..ad35939
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/.bower.json
@@ -0,0 +1,54 @@
+{
+ "name": "paper-input",
+ "version": "1.0.5",
+ "description": "Material design text fields",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "input"
+ ],
+ "main": [
+ "paper-input.html",
+ "paper-textarea.html",
+ "paper-input-behavior.html",
+ "paper-input-container.html",
+ "paper-input-error.html",
+ "paper-input-char-counter.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-input",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-autogrow-textarea": "PolymerElements/iron-autogrow-textarea#^1.0.0",
+ "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "iron-input": "PolymerElements/iron-input#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.5",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.5",
+ "commit": "72821a081710d9d5443e7b2311ff561def260807"
+ },
+ "_source": "git://github.com/PolymerElements/paper-input.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-input"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-input/.gitignore b/polymer_1.0.4/bower_components/paper-input/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-input/README.md b/polymer_1.0.4/bower_components/paper-input/README.md
new file mode 100644
index 0000000..c49ccc0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/README.md
@@ -0,0 +1,5 @@
+# paper-input
+
+`<paper-input>` is a Material Design text field.
+
+Contains a number of different features for validation, character counting, and more.
diff --git a/polymer_1.0.4/bower_components/paper-input/all-imports.html b/polymer_1.0.4/bower_components/paper-input/all-imports.html
new file mode 100644
index 0000000..0f45771
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/all-imports.html
@@ -0,0 +1,12 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="paper-input.html">
+<link rel="import" href="paper-textarea.html">
diff --git a/polymer_1.0.4/bower_components/paper-input/bower.json b/polymer_1.0.4/bower_components/paper-input/bower.json
new file mode 100644
index 0000000..a306a10
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/bower.json
@@ -0,0 +1,45 @@
+{
+ "name": "paper-input",
+ "version": "1.0.5",
+ "description": "Material design text fields",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "input"
+ ],
+ "main": [
+ "paper-input.html",
+ "paper-textarea.html",
+ "paper-input-behavior.html",
+ "paper-input-container.html",
+ "paper-input-error.html",
+ "paper-input-char-counter.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-input.git"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-input",
+ "ignore": [],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-autogrow-textarea": "PolymerElements/iron-autogrow-textarea#^1.0.0",
+ "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
+ "iron-input": "PolymerElements/iron-input#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "iron-validator-behavior": "PolymerElements/iron-validator-behavior#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-input/demo/index.html b/polymer_1.0.4/bower_components/paper-input/demo/index.html
new file mode 100644
index 0000000..57150bd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/demo/index.html
@@ -0,0 +1,96 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>paper-input demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-input.html">
+ <link rel="import" href="../paper-input-container.html">
+ <link rel="import" href="../paper-input-error.html">
+ <link rel="import" href="../paper-input-char-counter.html">
+ <link rel="import" href="../paper-textarea.html">
+ <link rel="import" href="../../iron-input/iron-input.html">
+ <link rel="import" href="ssn-input.html">
+
+ <link rel="stylesheet" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+
+ <style>
+ body {
+ padding: 40px;
+ }
+ </style>
+
+</head>
+<body unresolved>
+
+ <div class="vertical center-justified layout">
+ <h4>Text input</h4>
+ <div class="vertical-section">
+ <paper-input label="label"></paper-input>
+
+ <paper-input label="password" type="password"></paper-input>
+
+ <paper-input no-label-float label="label (no-label-float)"></paper-input>
+
+ <paper-input label="disabled" disabled></paper-input>
+ </div>
+
+ <h4>Text area</h4>
+ <div class="vertical-section">
+ <paper-textarea label="textarea label"></paper-textarea>
+ </div>
+
+ <h4>Validation</h4>
+ <div class="vertical-section">
+ <paper-input label="only type letters (auto-validate)" auto-validate pattern="[a-zA-Z]*" error-message="letters only!"></paper-input>
+
+ <paper-input id="inputForValidation" required label="only type letters (no auto validate)" pattern="[a-zA-Z]*" error-message="letters only, required input!"></paper-input>
+ <br>
+ <button onclick="validate()">Validate!</button>
+ </div>
+
+ <h4>Character counter</h4>
+ <div class="vertical-section">
+ <paper-input label="label" char-counter></paper-input>
+
+ <paper-input label="at most 10 letters" char-counter auto-validate pattern="[a-zA-Z]*" maxlength="10" error-message="letters only!"></paper-input>
+
+ <paper-textarea label="textarea" char-counter></paper-textarea>
+
+ <paper-textarea label="textarea with maxlength" char-counter maxlength="10"></paper-textarea>
+ </div>
+
+ <h4>Complex inputs</h4>
+ <div class="vertical-section">
+ <template is="dom-bind">
+ <paper-input-container always-float-label auto-validate attr-for-value="value">
+ <label>Social Security Number</label>
+ <ssn-input class="paper-input-input"></ssn-input>
+ <paper-input-error>SSN invalid!</paper-input-error>
+ </paper-input-container>
+ </template>
+ </div>
+ </div>
+ <script>
+ function validate() {
+ document.getElementById('inputForValidation').validate();
+ }
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-input/demo/ssn-input.html b/polymer_1.0.4/bower_components/paper-input/demo/ssn-input.html
new file mode 100644
index 0000000..6037909
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/demo/ssn-input.html
@@ -0,0 +1,94 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../../iron-input/iron-input.html">
+<link rel="import" href="ssn-validator.html">
+
+<dom-module id="ssn-input">
+
+ <style>
+
+ :host {
+ display: inline-block;
+ }
+
+ input[is="iron-input"] {
+ font: inherit;
+ outline: none;
+ box-shadow: none;
+ border: none;
+ width: auto;
+ text-align: center;
+ }
+
+ </style>
+
+ <template>
+
+ <ssn-validator></ssn-validator>
+
+ <input is="iron-input" maxlength="3" bind-value="{{_ssn1}}" size="3" aria-label="First 3 digits of social security number">
+ -
+ <input is="iron-input" maxlength="2" bind-value="{{_ssn2}}" size="2" aria-label="Middle 2 digits of social security number">
+ -
+ <input is="iron-input" maxlength="4" bind-value="{{_ssn3}}" size="4" aria-label="Last 4 digits of social security number">
+
+ </template>
+
+</dom-module>
+
+<script>
+(function() {
+
+ Polymer({
+
+ is: 'ssn-input',
+
+ behaviors: [
+ Polymer.IronValidatableBehavior
+ ],
+
+ properties: {
+
+ value: {
+ notify: true,
+ type: String
+ },
+
+ _ssn1: {
+ type: String
+ },
+
+ _ssn2: {
+ type: String
+ },
+
+ _ssn3: {
+ type: String
+ },
+
+ validator: {
+ type: String,
+ value: 'ssn-validator'
+ }
+
+ },
+
+ observers: [
+ '_computeValue(_ssn1,_ssn2,_ssn3)'
+ ],
+
+ _computeValue: function(ssn1, ssn2, ssn3) {
+ this.value = ssn1.trim() + '-' + ssn2.trim() + '-' + ssn3.trim();
+ }
+
+ })
+})();
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-input/demo/ssn-validator.html b/polymer_1.0.4/bower_components/paper-input/demo/ssn-validator.html
new file mode 100644
index 0000000..4ab92f7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/demo/ssn-validator.html
@@ -0,0 +1,31 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../../iron-validator-behavior/iron-validator-behavior.html">
+
+<script>
+
+ Polymer({
+
+ is: 'ssn-validator',
+
+ behaviors: [
+ Polymer.IronValidatorBehavior
+ ],
+
+ validate: function(value) {
+ // this regex validates incomplete ssn's (by design)
+ return !value || value.match(/^[0-9]{0,3}-[0-9]{0,2}-[0-9]{0,4}$/);
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-input/hero.svg b/polymer_1.0.4/bower_components/paper-input/hero.svg
new file mode 100755
index 0000000..146ffea
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/hero.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <rect x="49" y="53" width="2" height="18"/>
+ <path d="M188,78H37V44h151V78z M39,76h147V46H39V76z"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-input/index.html b/polymer_1.0.4/bower_components/paper-input/index.html
new file mode 100644
index 0000000..e6c9fad
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/index.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <title>paper-input</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page src="all-imports.html"></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-input/paper-input-addon-behavior.html b/polymer_1.0.4/bower_components/paper-input/paper-input-addon-behavior.html
new file mode 100644
index 0000000..0b021a5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/paper-input-addon-behavior.html
@@ -0,0 +1,47 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+
+ /**
+ * Use `Polymer.PaperInputAddonBehavior` to implement an add-on for `<paper-input-container>`. A
+ * add-on appears below the input, and may display information based on the input value and
+ * validity such as a character counter or an error message.
+ * @polymerBehavior
+ */
+ Polymer.PaperInputAddonBehavior = {
+
+ hostAttributes: {
+ 'add-on': ''
+ },
+
+ attached: function() {
+ this.fire('addon-attached');
+ },
+
+ /**
+ * The function called by `<paper-input-container>` when the input value or validity changes.
+ * @param {{
+ * inputElement: (Node|undefined),
+ * value: (string|undefined),
+ * invalid: (boolean|undefined)
+ * }} state All properties are optional -
+ * inputElement: The input element.
+ * value: The input value.
+ * invalid: True if the input value is invalid.
+ */
+ update: function(state) {
+ }
+
+ };
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-input/paper-input-behavior.html b/polymer_1.0.4/bower_components/paper-input/paper-input-behavior.html
new file mode 100644
index 0000000..0afbc83
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/paper-input-behavior.html
@@ -0,0 +1,328 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-behaviors/iron-control-state.html">
+
+<script>
+
+ /**
+ * Use `Polymer.PaperInputBehavior` to implement inputs with `<paper-input-container>`. This
+ * behavior is implemented by `<paper-input>`. It exposes a number of properties from
+ * `<paper-input-container>` and `<input is="iron-input">` and they should be bound in your
+ * template.
+ *
+ * The input element can be accessed by the `inputElement` property if you need to access
+ * properties or methods that are not exposed.
+ * @polymerBehavior Polymer.PaperInputBehavior
+ */
+ Polymer.PaperInputBehaviorImpl = {
+
+ properties: {
+
+ /**
+ * The label for this input. Bind this to `<paper-input-container>`'s `label` property.
+ */
+ label: {
+ type: String
+ },
+
+ /**
+ * The value for this input. Bind this to the `<input is="iron-input">`'s `bindValue`
+ * property, or the value property of your input that is `notify:true`.
+ */
+ value: {
+ notify: true,
+ type: String
+ },
+
+ /**
+ * Set to true to disable this input. Bind this to both the `<paper-input-container>`'s
+ * and the input's `disabled` property.
+ */
+ disabled: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Returns true if the value is invalid. Bind this to both the `<paper-input-container>`'s
+ * and the input's `invalid` property.
+ */
+ invalid: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to prevent the user from entering invalid input. Bind this to the
+ * `<input is="iron-input">`'s `preventInvalidInput` property.
+ */
+ preventInvalidInput: {
+ type: Boolean
+ },
+
+ /**
+ * Set this to specify the pattern allowed by `preventInvalidInput`. Bind this to the
+ * `<input is="iron-input">`'s `allowedPattern` property.
+ */
+ allowedPattern: {
+ type: String
+ },
+
+ /**
+ * The type of the input. The supported types are `text`, `number` and `password`. Bind this
+ * to the `<input is="iron-input">`'s `type` property.
+ */
+ type: {
+ type: String
+ },
+
+ /**
+ * The datalist of the input (if any). This should match the id of an existing <datalist>. Bind this
+ * to the `<input is="iron-input">`'s `list` property.
+ */
+ list: {
+ type: String
+ },
+
+ /**
+ * A pattern to validate the `input` with. Bind this to the `<input is="iron-input">`'s
+ * `pattern` property.
+ */
+ pattern: {
+ type: String
+ },
+
+ /**
+ * Set to true to mark the input as required. Bind this to the `<input is="iron-input">`'s
+ * `required` property.
+ */
+ required: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The maximum length of the input value. Bind this to the `<input is="iron-input">`'s
+ * `maxlength` property.
+ */
+ maxlength: {
+ type: Number
+ },
+
+ /**
+ * The error message to display when the input is invalid. Bind this to the
+ * `<paper-input-error>`'s content, if using.
+ */
+ errorMessage: {
+ type: String
+ },
+
+ /**
+ * Set to true to show a character counter.
+ */
+ charCounter: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to disable the floating label. Bind this to the `<paper-input-container>`'s
+ * `noLabelFloat` property.
+ */
+ noLabelFloat: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to always float the label. Bind this to the `<paper-input-container>`'s
+ * `alwaysFloatLabel` property.
+ */
+ alwaysFloatLabel: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to auto-validate the input value. Bind this to the `<paper-input-container>`'s
+ * `autoValidate` property.
+ */
+ autoValidate: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Name of the validator to use. Bind this to the `<input is="iron-input">`'s `validator`
+ * property.
+ */
+ validator: {
+ type: String
+ },
+
+ // HTMLInputElement attributes for binding if needed
+
+ /**
+ * Bind this to the `<input is="iron-input">`'s `autocomplete` property.
+ */
+ autocomplete: {
+ type: String,
+ value: 'off'
+ },
+
+ /**
+ * Bind this to the `<input is="iron-input">`'s `autofocus` property.
+ */
+ autofocus: {
+ type: Boolean
+ },
+
+ /**
+ * Bind this to the `<input is="iron-input">`'s `inputmode` property.
+ */
+ inputmode: {
+ type: String
+ },
+
+ /**
+ * Bind this to the `<input is="iron-input">`'s `minlength` property.
+ */
+ minlength: {
+ type: Number
+ },
+
+ /**
+ * Bind this to the `<input is="iron-input">`'s `name` property.
+ */
+ name: {
+ type: String
+ },
+
+ /**
+ * A placeholder string in addition to the label. If this is set, the label will always float.
+ */
+ placeholder: {
+ type: String,
+ // need to set a default so _computeAlwaysFloatLabel is run
+ value: ''
+ },
+
+ /**
+ * Bind this to the `<input is="iron-input">`'s `readonly` property.
+ */
+ readonly: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Bind this to the `<input is="iron-input">`'s `size` property.
+ */
+ size: {
+ type: Number
+ },
+
+ _ariaDescribedBy: {
+ type: String,
+ value: ''
+ }
+
+ },
+
+ listeners: {
+ 'addon-attached': '_onAddonAttached'
+ },
+
+ /**
+ * Returns a reference to the input element.
+ */
+ get inputElement() {
+ return this.$.input;
+ },
+
+ attached: function() {
+ this._updateAriaLabelledBy();
+ },
+
+ _appendStringWithSpace: function(str, more) {
+ if (str) {
+ str = str + ' ' + more;
+ } else {
+ str = more;
+ }
+ return str;
+ },
+
+ _onAddonAttached: function(event) {
+ var target = event.path ? event.path[0] : event.target;
+ if (target.id) {
+ this._ariaDescribedBy = this._appendStringWithSpace(this._ariaDescribedBy, target.id);
+ } else {
+ var id = 'paper-input-add-on-' + Math.floor((Math.random() * 100000));
+ target.id = id;
+ this._ariaDescribedBy = this._appendStringWithSpace(this._ariaDescribedBy, id);
+ }
+ },
+
+ /**
+ * Validates the input element and sets an error style if needed.
+ */
+ validate: function() {
+ return this.inputElement.validate();
+ },
+
+ /**
+ * Restores the cursor to its original position after updating the value.
+ * @param {string} newValue The value that should be saved.
+ */
+ updateValueAndPreserveCaret: function(newValue) {
+ // Not all elements might have selection, and even if they have the
+ // right properties, accessing them might throw an exception (like for
+ // <input type=number>)
+ try {
+ var start = this.inputElement.selectionStart;
+ this.value = newValue;
+
+ // The cursor automatically jumps to the end after re-setting the value,
+ // so restore it to its original position.
+ this.inputElement.selectionStart = start;
+ this.inputElement.selectionEnd = start;
+ } catch (e) {
+ // Just set the value and give up on the caret.
+ this.value = newValue;
+ }
+ },
+
+ _computeAlwaysFloatLabel: function(alwaysFloatLabel, placeholder) {
+ return placeholder || alwaysFloatLabel;
+ },
+
+ _updateAriaLabelledBy: function() {
+ var label = Polymer.dom(this.root).querySelector('label');
+ if (!label) {
+ this._ariaLabelledBy = '';
+ return;
+ }
+ var labelledBy;
+ if (label.id) {
+ labelledBy = label.id;
+ } else {
+ labelledBy = 'paper-input-label-' + new Date().getUTCMilliseconds();
+ label.id = labelledBy;
+ }
+ this._ariaLabelledBy = labelledBy;
+ }
+
+ };
+
+ Polymer.PaperInputBehavior = [Polymer.IronControlState, Polymer.PaperInputBehaviorImpl];
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-input/paper-input-char-counter.html b/polymer_1.0.4/bower_components/paper-input/paper-input-char-counter.html
new file mode 100644
index 0000000..566f8c6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/paper-input-char-counter.html
@@ -0,0 +1,95 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+<link rel="import" href="paper-input-addon-behavior.html">
+
+<!--
+`<paper-input-char-counter>` is a character counter for use with `<paper-input-container>`. It
+shows the number of characters entered in the input and the max length if it is specified.
+
+ <paper-input-container>
+ <input is="iron-input" maxlength="20">
+ <paper-input-char-counter></paper-input-char-counter>
+ </paper-input-container>
+
+### Styling
+
+The following mixin is available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-input-char-counter` | Mixin applied to the element | `{}`
+-->
+<dom-module id="paper-input-char-counter">
+
+ <style>
+
+ :host {
+ display: inline-block;
+ float: right;
+
+ @apply(--paper-font-caption);
+ @apply(--paper-input-char-counter);
+ }
+
+ </style>
+
+ <template>
+
+ <span>[[_charCounterStr]]</span>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'paper-input-char-counter',
+
+ behaviors: [
+ Polymer.PaperInputAddonBehavior
+ ],
+
+ properties: {
+
+ _charCounterStr: {
+ type: String,
+ value: '0'
+ }
+
+ },
+
+ update: function(state) {
+ if (!state.inputElement) {
+ return;
+ }
+
+ state.value = state.value || '';
+
+ // Account for the textarea's new lines.
+ var str = state.value.replace(/(\r\n|\n|\r)/g, '--').length;
+
+ if (state.inputElement.hasAttribute('maxlength')) {
+ str += '/' + state.inputElement.getAttribute('maxlength');
+ }
+ this._charCounterStr = str;
+ }
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-input/paper-input-container.html b/polymer_1.0.4/bower_components/paper-input/paper-input-container.html
new file mode 100644
index 0000000..e9088c2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/paper-input-container.html
@@ -0,0 +1,506 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+
+<!--
+`<paper-input-container>` is a container for a `<label>`, an `<input is="iron-input">` or
+`<iron-autogrow-textarea>` and optional add-on elements such as an error message or character
+counter, used to implement Material Design text fields.
+
+For example:
+
+ <paper-input-container>
+ <label>Your name</label>
+ <input is="iron-input">
+ </paper-input-container>
+
+### Listening for input changes
+
+By default, it listens for changes on the `bind-value` attribute on its children nodes and perform
+tasks such as auto-validating and label styling when the `bind-value` changes. You can configure
+the attribute it listens to with the `attr-for-value` attribute.
+
+### Using a custom input element
+
+You can use a custom input element in a `<paper-input-container>`, for example to implement a
+compound input field like a social security number input. The custom input element should have the
+`paper-input-input` class, have a `notify:true` value property and optionally implements
+`Polymer.IronValidatableBehavior` if it is validatble.
+
+ <paper-input-container attr-for-value="ssn-value">
+ <label>Social security number</label>
+ <ssn-input class="paper-input-input"></ssn-input>
+ </paper-input-container>
+
+### Validation
+
+If the `auto-validate` attribute is set, the input container will validate the input and update
+the container styling when the input value changes.
+
+### Add-ons
+
+Add-ons are child elements of a `<paper-input-container>` with the `add-on` attribute and
+implements the `Polymer.PaperInputAddonBehavior` behavior. They are notified when the input value
+or validity changes, and may implement functionality such as error messages or character counters.
+They appear at the bottom of the input.
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-input-container-color` | Label and underline color when the input is not focused | `--secondary-text-color`
+`--paper-input-container-focus-color` | Label and underline color when the input is focused | `--default-primary-color`
+`--paper-input-container-invalid-color` | Label and underline color when the input is focused | `--google-red-500`
+`--paper-input-container-input-color` | Input foreground color | `--primary-text-color`
+`--paper-input-container` | Mixin applied to the container | `{}`
+`--paper-input-container-label` | Mixin applied to the label | `{}`
+`--paper-input-container-input` | Mixin applied to the input | `{}`
+
+This element is `display:block` by default, but you can set the `inline` attribute to make it
+`display:inline-block`.
+-->
+<dom-module id="paper-input-container">
+
+ <style>
+
+ :host {
+ display: block;
+ padding: 8px 0;
+
+ @apply(--paper-input-container);
+ }
+
+ :host[inline] {
+ display: inline-block;
+ }
+
+ :host([disabled]) {
+ pointer-events: none;
+ opacity: 0.33;
+ }
+
+ .floated-label-placeholder {
+ @apply(--paper-font-caption);
+ }
+
+ .underline {
+ position: relative;
+ }
+
+ .focused-line {
+ height: 2px;
+
+ -webkit-transform-origin: center center;
+ transform-origin: center center;
+ -webkit-transform: scale3d(0,1,1);
+ transform: scale3d(0,1,1);
+
+ background: var(--paper-input-container-focus-color, --default-primary-color);
+ }
+
+ .underline.is-highlighted .focused-line {
+ -webkit-transform: none;
+ transform: none;
+ -webkit-transition: -webkit-transform 0.25s;
+ transition: transform 0.25s;
+
+ @apply(--paper-transition-easing);
+ }
+
+ .underline.is-invalid .focused-line {
+ background: var(--paper-input-container-invalid-color, --google-red-500);
+
+ -webkit-transform: none;
+ transform: none;
+ -webkit-transition: -webkit-transform 0.25s;
+ transition: transform 0.25s;
+
+ @apply(--paper-transition-easing);
+ }
+
+ .unfocused-line {
+ height: 1px;
+ background: var(--paper-input-container-color, --secondary-text-color);
+ }
+
+ :host([disabled]) .unfocused-line {
+ border-bottom: 1px dashed;
+ border-color: var(--paper-input-container-color, --secondary-text-color);
+ background: transparent;
+ }
+
+ .input-content {
+ position: relative;
+ }
+
+ .input-content ::content label,
+ .input-content ::content .paper-input-label {
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ font: inherit;
+ color: var(--paper-input-container-color, --secondary-text-color);
+
+ @apply(--paper-font-subhead);
+ @apply(--paper-input-container-label);
+ }
+
+ .input-content.label-is-floating ::content label,
+ .input-content.label-is-floating ::content .paper-input-label {
+ -webkit-transform: translate3d(0, -75%, 0) scale(0.75);
+ transform: translate3d(0, -75%, 0) scale(0.75);
+ -webkit-transform-origin: left top;
+ transform-origin: left top;
+ -webkit-transition: -webkit-transform 0.25s;
+ transition: transform 0.25s;
+
+ @apply(--paper-transition-easing);
+ }
+
+ .input-content.label-is-highlighted ::content label,
+ .input-content.label-is-highlighted ::content .paper-input-label {
+ color: var(--paper-input-container-focus-color, --default-primary-color);
+ }
+
+ .input-content.is-invalid ::content label,
+ .input-content.is-invalid ::content .paper-input-label {
+ color: var(--paper-input-container-invalid-color, --google-red-500);
+ }
+
+ .input-content.label-is-hidden ::content label,
+ .input-content.label-is-hidden ::content .paper-input-label {
+ visibility: hidden;
+ }
+
+ .input-content ::content input,
+ .input-content ::content textarea,
+ .input-content ::content iron-autogrow-textarea,
+ .input-content ::content .paper-input-input {
+ position: relative; /* to make a stacking context */
+ outline: none;
+ box-shadow: none;
+ padding: 0;
+ width: 100%;
+ background: transparent;
+ border: none;
+ color: var(--paper-input-container-input-color, --primary-text-color);
+
+ @apply(--paper-font-subhead);
+ @apply(--paper-input-container-input);
+ }
+
+ /* Firefox sets a min-width on the input, which can cause layout issues */
+ .input-content ::content input {
+ min-width: 0;
+ }
+
+ .input-content ::content textarea {
+ resize: none;
+ }
+
+ .add-on-content.is-invalid ::content * {
+ color: var(--paper-input-container-invalid-color, --google-red-500);
+ }
+
+ .add-on-content.is-highlighted ::content * {
+ color: var(--paper-input-container-focus-color, --default-primary-color);
+ }
+
+ </style>
+
+ <template>
+
+ <template is="dom-if" if="[[!noLabelFloat]]">
+ <div class="floated-label-placeholder"> </div>
+ </template>
+
+ <div class$="[[_computeInputContentClass(noLabelFloat,alwaysFloatLabel,focused,invalid,_inputHasContent)]]">
+ <content select=":not([add-on])"></content>
+ </div>
+
+ <div class$="[[_computeUnderlineClass(focused,invalid)]]">
+ <div class="unfocused-line fit"></div>
+ <div class="focused-line fit"></div>
+ </div>
+
+ <div class$="[[_computeAddOnContentClass(focused,invalid)]]">
+ <content id="addOnContent" select="[add-on]"></content>
+ </div>
+
+ </template>
+
+</dom-module>
+
+<script>
+(function() {
+
+ Polymer({
+
+ is: 'paper-input-container',
+
+ properties: {
+
+ /**
+ * Set to true to disable the floating label. The label disappears when the input value is
+ * not null.
+ */
+ noLabelFloat: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to always float the floating label.
+ */
+ alwaysFloatLabel: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The attribute to listen for value changes on.
+ */
+ attrForValue: {
+ type: String,
+ value: 'bind-value'
+ },
+
+ /**
+ * Set to true to auto-validate the input value when it changes.
+ */
+ autoValidate: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * True if the input is invalid. This property is set automatically when the input value
+ * changes if auto-validating, or when the `iron-input-valid` event is heard from a child.
+ */
+ invalid: {
+ observer: '_invalidChanged',
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * True if the input has focus.
+ */
+ focused: {
+ readOnly: true,
+ type: Boolean,
+ value: false
+ },
+
+ _addons: {
+ type: Array
+ // do not set a default value here intentionally - it will be initialized lazily when a
+ // distributed child is attached, which may occur before configuration for this element
+ // in polyfill.
+ },
+
+ _inputHasContent: {
+ type: Boolean,
+ value: false
+ },
+
+ _inputSelector: {
+ type: String,
+ value: 'input,textarea,.paper-input-input'
+ },
+
+ _boundOnFocus: {
+ type: Function,
+ value: function() {
+ return this._onFocus.bind(this);
+ }
+ },
+
+ _boundOnBlur: {
+ type: Function,
+ value: function() {
+ return this._onBlur.bind(this);
+ }
+ },
+
+ _boundOnInput: {
+ type: Function,
+ value: function() {
+ return this._onInput.bind(this);
+ }
+ },
+
+ _boundValueChanged: {
+ type: Function,
+ value: function() {
+ return this._onValueChanged.bind(this);
+ }
+ }
+
+ },
+
+ listeners: {
+ 'addon-attached': '_onAddonAttached',
+ 'iron-input-validate': '_onIronInputValidate'
+ },
+
+ get _valueChangedEvent() {
+ return this.attrForValue + '-changed';
+ },
+
+ get _propertyForValue() {
+ return Polymer.CaseMap.dashToCamelCase(this.attrForValue);
+ },
+
+ get _inputElement() {
+ return Polymer.dom(this).querySelector(this._inputSelector);
+ },
+
+ ready: function() {
+ if (!this._addons) {
+ this._addons = [];
+ }
+ this.addEventListener('focus', this._boundOnFocus, true);
+ this.addEventListener('blur', this._boundOnBlur, true);
+ if (this.attrForValue) {
+ this._inputElement.addEventListener(this._valueChangedEvent, this._boundValueChanged);
+ } else {
+ this.addEventListener('input', this._onInput);
+ }
+ },
+
+ attached: function() {
+ this._handleValue(this._inputElement);
+ },
+
+ _onAddonAttached: function(event) {
+ if (!this._addons) {
+ this._addons = [];
+ }
+ var target = event.target;
+ if (this._addons.indexOf(target) === -1) {
+ this._addons.push(target);
+ if (this.isAttached) {
+ this._handleValue(this._inputElement);
+ }
+ }
+ },
+
+ _onFocus: function() {
+ this._setFocused(true);
+ },
+
+ _onBlur: function() {
+ this._setFocused(false);
+ },
+
+ _onInput: function(event) {
+ this._handleValue(event.target);
+ },
+
+ _onValueChanged: function(event) {
+ this._handleValue(event.target);
+ },
+
+ _handleValue: function(inputElement) {
+ var value = inputElement[this._propertyForValue] || inputElement.value;
+
+ if (this.autoValidate) {
+ var valid;
+ if (inputElement.validate) {
+ valid = inputElement.validate(value);
+ } else {
+ valid = inputElement.checkValidity();
+ }
+ this.invalid = !valid;
+ }
+
+ // type="number" hack needed because this.value is empty until it's valid
+ if (value || (inputElement.type === 'number' && !inputElement.checkValidity())) {
+ this._inputHasContent = true;
+ } else {
+ this._inputHasContent = false;
+ }
+
+ this.updateAddons({
+ inputElement: inputElement,
+ value: value,
+ invalid: this.invalid
+ });
+ },
+
+ _onIronInputValidate: function(event) {
+ this.invalid = this._inputElement.invalid;
+ },
+
+ _invalidChanged: function() {
+ if (this._addons) {
+ this.updateAddons({invalid: this.invalid});
+ }
+ },
+
+ /**
+ * Call this to update the state of add-ons.
+ * @param {Object} state Add-on state.
+ */
+ updateAddons: function(state) {
+ for (var addon, index = 0; addon = this._addons[index]; index++) {
+ addon.update(state);
+ }
+ },
+
+ _computeInputContentClass: function(noLabelFloat, alwaysFloatLabel, focused, invalid, _inputHasContent) {
+ var cls = 'input-content';
+ if (!noLabelFloat) {
+ if (alwaysFloatLabel || _inputHasContent) {
+ cls += ' label-is-floating';
+ if (invalid) {
+ cls += ' is-invalid';
+ } else if (focused) {
+ cls += " label-is-highlighted";
+ }
+ }
+ } else {
+ if (_inputHasContent) {
+ cls += ' label-is-hidden';
+ }
+ }
+ return cls;
+ },
+
+ _computeUnderlineClass: function(focused, invalid) {
+ var cls = 'underline';
+ if (invalid) {
+ cls += ' is-invalid';
+ } else if (focused) {
+ cls += ' is-highlighted'
+ }
+ return cls;
+ },
+
+ _computeAddOnContentClass: function(focused, invalid) {
+ var cls = 'add-on-content';
+ if (invalid) {
+ cls += ' is-invalid';
+ } else if (focused) {
+ cls += ' is-highlighted'
+ }
+ return cls;
+ }
+
+ });
+
+})();
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-input/paper-input-error.html b/polymer_1.0.4/bower_components/paper-input/paper-input-error.html
new file mode 100644
index 0000000..c034e96
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/paper-input-error.html
@@ -0,0 +1,99 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+<link rel="import" href="paper-input-addon-behavior.html">
+
+<!--
+`<paper-input-error>` is an error message for use with `<paper-input-container>`. The error is
+displayed when the `<paper-input-container>` is `invalid`.
+
+ <paper-input-container>
+ <input is="iron-input" pattern="[0-9]*">
+ <paper-input-error>Only numbers are allowed!</paper-input-error>
+ </paper-input-container>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-input-container-invalid-color` | The foreground color of the error | `--google-red-500`
+`--paper-input-error` | Mixin applied to the error | `{}`
+-->
+<dom-module id="paper-input-error">
+
+ <style>
+
+ :host {
+ /* need to use display: none for role="alert" */
+ display: none;
+ float: left;
+
+ color: var(--paper-input-container-invalid-color, --google-red-500);
+
+ @apply(--paper-font-caption);
+ @apply(--paper-input-error);
+ }
+
+ :host([invalid]) {
+ display: inline-block;
+ };
+
+ </style>
+
+ <template>
+
+ <content></content>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'paper-input-error',
+
+ behaviors: [
+ Polymer.PaperInputAddonBehavior
+ ],
+
+ hostAttributes: {
+ 'role': 'alert'
+ },
+
+ properties: {
+
+ /**
+ * True if the error is showing.
+ */
+ invalid: {
+ readOnly: true,
+ reflectToAttribute: true,
+ type: Boolean
+ }
+
+ },
+
+ update: function(state) {
+ this._setInvalid(state.invalid);
+ }
+
+ })
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-input/paper-input.html b/polymer_1.0.4/bower_components/paper-input/paper-input.html
new file mode 100644
index 0000000..5aa4a6e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/paper-input.html
@@ -0,0 +1,127 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-input/iron-input.html">
+<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
+<link rel="import" href="paper-input-behavior.html">
+<link rel="import" href="paper-input-container.html">
+<link rel="import" href="paper-input-error.html">
+<link rel="import" href="paper-input-char-counter.html">
+
+<!--
+`<paper-input>` is a single-line text field with Material Design styling.
+
+ <paper-input label="Input label"></paper-input>
+
+It may include an optional error message or character counter.
+
+ <paper-input error-message="Invalid input!" label="Input label"></paper-input>
+ <paper-input char-counter label="Input label"></paper-input>
+
+See `Polymer.PaperInputBehavior` for more API docs.
+
+### Styling
+
+See `Polymer.PaperInputContainer` for a list of custom properties used to
+style this element.
+
+@group Paper Elements
+@element paper-input
+@hero hero.svg
+@demo demo/index.html
+-->
+
+<dom-module id="paper-input">
+
+ <style>
+
+ :host {
+ display: block;
+ }
+
+ input::-webkit-input-placeholder {
+ color: var(--paper-input-container-color, --secondary-text-color);
+ }
+
+ input:-moz-placeholder {
+ color: var(--paper-input-container-color, --secondary-text-color);
+ }
+
+ input::-moz-placeholder {
+ color: var(--paper-input-container-color, --secondary-text-color);
+ }
+
+ input:-ms-input-placeholder {
+ color: var(--paper-input-container-color, --secondary-text-color);
+ }
+
+ </style>
+
+ <template>
+
+ <paper-input-container no-label-float="[[noLabelFloat]]" always-float-label="[[_computeAlwaysFloatLabel(alwaysFloatLabel,placeholder)]]" auto-validate$="[[autoValidate]]" disabled$="[[disabled]]" invalid="[[invalid]]">
+
+ <label hidden$="[[!label]]">[[label]]</label>
+
+ <input is="iron-input" id="input"
+ aria-labelledby$="[[_ariaLabelledBy]]"
+ aria-describedby$="[[_ariaDescribedBy]]"
+ disabled$="[[disabled]]"
+ bind-value="{{value}}"
+ invalid="{{invalid}}"
+ prevent-invalid-input="[[preventInvalidInput]]"
+ allowed-pattern="[[allowedPattern]]"
+ validator="[[validator]]"
+ type$="[[type]]"
+ pattern$="[[pattern]]"
+ maxlength$="[[maxlength]]"
+ required$="[[required]]"
+ autocomplete$="[[autocomplete]]"
+ autofocus$="[[autofocus]]"
+ inputmode$="[[inputmode]]"
+ minlength$="[[minlength]]"
+ name$="[[name]]"
+ placeholder$="[[placeholder]]"
+ readonly$="[[readonly]]"
+ list$="[[list]]"
+ size$="[[size]]">
+
+ <template is="dom-if" if="[[errorMessage]]">
+ <paper-input-error>[[errorMessage]]</paper-input-error>
+ </template>
+
+ <template is="dom-if" if="[[charCounter]]">
+ <paper-input-char-counter></paper-input-char-counter>
+ </template>
+
+ </paper-input-container>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'paper-input',
+
+ behaviors: [
+ Polymer.PaperInputBehavior,
+ Polymer.IronControlState
+ ]
+
+ })
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-input/paper-textarea.html b/polymer_1.0.4/bower_components/paper-input/paper-textarea.html
new file mode 100644
index 0000000..d47a5b5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/paper-textarea.html
@@ -0,0 +1,106 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
+<link rel="import" href="paper-input-behavior.html">
+<link rel="import" href="paper-input-container.html">
+<link rel="import" href="paper-input-error.html">
+<link rel="import" href="paper-input-char-counter.html">
+
+<!--
+`<paper-textarea>` is a multi-line text field with Material Design styling.
+
+ <paper-textarea label="Textarea label"></paper-textarea>
+
+See `Polymer.PaperInputBehavior` for more API docs.
+
+### Validation
+
+Currently only `required` and `maxlength` validation is supported.
+
+### Styling
+
+See `Polymer.PaperInputContainer` for a list of custom properties used to
+style this element.
+-->
+
+<dom-module id="paper-textarea">
+ <template>
+
+ <paper-input-container no-label-float$="[[noLabelFloat]]" always-float-label="[[_computeAlwaysFloatLabel(alwaysFloatLabel,placeholder)]]" auto-validate$="[[autoValidate]]" disabled$="[[disabled]]" invalid="[[invalid]]">
+
+ <label hidden$="[[!label]]">[[label]]</label>
+
+ <iron-autogrow-textarea id="input" class="paper-input-input"
+ bind-value="{{value}}"
+ autocomplete$="[[autocomplete]]"
+ autofocus$="[[autofocus]]"
+ inputmode$="[[inputmode]]"
+ name$="[[name]]"
+ placeholder$="[[placeholder]]"
+ readonly$="[[readonly]]"
+ required$="[[required]]"
+ maxlength$="[[maxlength]]"></iron-autogrow-textarea>
+
+ <template is="dom-if" if="[[errorMessage]]">
+ <paper-input-error>[[errorMessage]]</paper-input-error>
+ </template>
+
+ <template is="dom-if" if="[[charCounter]]">
+ <paper-input-char-counter></paper-input-char-counter>
+ </template>
+
+ </paper-input-container>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'paper-textarea',
+
+ behaviors: [
+ Polymer.PaperInputBehavior,
+ Polymer.IronFormElementBehavior
+ ],
+
+ properties: {
+
+ _ariaLabelledBy: {
+ observer: '_ariaLabelledByChanged',
+ type: String
+ },
+
+ _ariaDescribedBy: {
+ observer: '_ariaDescribedByChanged',
+ type: String
+ }
+
+ },
+
+ _ariaLabelledByChanged: function(ariaLabelledBy) {
+ this.$.input.textarea.setAttribute('aria-labelledby', ariaLabelledBy);
+ },
+
+ _ariaDescribedByChanged: function(ariaDescribedBy) {
+ this.$.input.textarea.setAttribute('aria-describedby', ariaDescribedBy);
+ }
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-input/test/index.html b/polymer_1.0.4/bower_components/paper-input/test/index.html
new file mode 100644
index 0000000..cfed0b1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/test/index.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>paper-input tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'paper-input.html',
+ 'paper-textarea.html',
+ 'paper-input-container.html',
+ 'paper-input-error.html',
+ 'paper-input-char-counter.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-input/test/letters-only.html b/polymer_1.0.4/bower_components/paper-input/test/letters-only.html
new file mode 100644
index 0000000..bfc301c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/test/letters-only.html
@@ -0,0 +1,30 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../../polymer/polymer.html">
+<link rel="import" href="../../iron-validator-behavior/iron-validator-behavior.html">
+
+<script>
+
+ Polymer({
+
+ is: 'letters-only',
+
+ behaviors: [
+ Polymer.IronValidatorBehavior
+ ],
+
+ validate: function(value) {
+ return !value || value.match(/^[a-zA-Z]*$/) !== null;
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-input/test/paper-input-char-counter.html b/polymer_1.0.4/bower_components/paper-input/test/paper-input-char-counter.html
new file mode 100644
index 0000000..6986aa7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/test/paper-input-char-counter.html
@@ -0,0 +1,112 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>paper-input-counter tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <script src="../../iron-test-helpers/test-helpers.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../../iron-input/iron-input.html">
+ <link rel="import" href="../paper-input-container.html">
+ <link rel="import" href="../paper-input-char-counter.html">
+ <link rel="import" href="../paper-textarea.html">
+
+</head>
+<body>
+
+ <test-fixture id="counter">
+ <template>
+ <paper-input-container>
+ <label id="l">label</label>
+ <input id="i" value="foobar">
+ <paper-input-char-counter id="c"></paper-input-char-counter>
+ </paper-input-container>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="counter-with-max">
+ <template>
+ <paper-input-container>
+ <label id="l">label</label>
+ <input id="i" value="foobar" maxlength="10">
+ <paper-input-char-counter id="c"></paper-input-char-counter>
+ </paper-input-container>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="textarea">
+ <template>
+ <paper-textarea char-counter value="foobar"></paper-textarea>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="textarea-with-max">
+ <template>
+ <paper-textarea char-counter value="foobar" maxlength="100"></paper-textarea>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+
+ test('character counter shows the value length', function() {
+ var container = fixture('counter');
+ var input = Polymer.dom(container).querySelector('#i');
+ var counter = Polymer.dom(container).querySelector('#c');
+ assert.equal(counter._charCounterStr, input.value.length, 'character counter shows input value length');
+ });
+
+ test('character counter shows the value length with maxlength', function() {
+ var container = fixture('counter-with-max');
+ var input = Polymer.dom(container).querySelector('#i');
+ var counter = Polymer.dom(container).querySelector('#c');
+ assert.equal(counter._charCounterStr, input.value.length + '/' + input.maxLength, 'character counter shows input value length and maxLength');
+ });
+
+ test('character counter shows the value length with maxlength', function() {
+ var input = fixture('textarea-with-max');
+ forceXIfStamp(input);
+
+ var counter = Polymer.dom(input.root).querySelector('paper-input-char-counter');
+ assert.ok(counter, 'paper-input-char-counter exists');
+
+ assert.equal(counter._charCounterStr, input.value.length + '/' + input.inputElement.textarea.getAttribute('maxlength'), 'character counter shows input value length and maxLength');
+ });
+
+ test('character counter counts new lines in textareas correctly', function() {
+ var input = fixture('textarea');
+ input.value = 'foo\nbar';
+ forceXIfStamp(input);
+
+ var counter = Polymer.dom(input.root).querySelector('paper-input-char-counter')
+ assert.ok(counter, 'paper-input-char-counter exists');
+
+ // A new line counts as two characters.
+ assert.equal(counter._charCounterStr, input.value.length + 1, 'character counter shows the value length');
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-input/test/paper-input-container.html b/polymer_1.0.4/bower_components/paper-input/test/paper-input-container.html
new file mode 100644
index 0000000..0b7acf8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/test/paper-input-container.html
@@ -0,0 +1,237 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>paper-input-container tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../../iron-input/iron-input.html">
+ <link rel="import" href="../paper-input-container.html">
+ <link rel="import" href="letters-only.html">
+
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <paper-input-container>
+ <label id="l">label</label>
+ <input id="i">
+ </paper-input-container>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="has-value">
+ <template>
+ <paper-input-container>
+ <label id="l">label</label>
+ <input id="i" value="value">
+ </paper-input-container>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="no-float-has-value">
+ <template>
+ <paper-input-container no-label-float>
+ <label id="l">label</label>
+ <input id="i" value="value">
+ </paper-input-container>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="always-float">
+ <template>
+ <paper-input-container always-float-label>
+ <label id="l">label</label>
+ <input id="i" value="value">
+ </paper-input-container>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="auto-validate-numbers">
+ <template>
+ <paper-input-container auto-validate>
+ <label id="l">label</label>
+ <input is="iron-input" id="i" pattern="[0-9]*">
+ </paper-input-container>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="manual-validate-numbers">
+ <template>
+ <paper-input-container>
+ <label id="l">label</label>
+ <input is="iron-input" id="i" pattern="[0-9]*">
+ </paper-input-container>
+ </template>
+ </test-fixture>
+
+ <letters-only></letters-only>
+
+ <test-fixture id="auto-validate-validator">
+ <template>
+ <paper-input-container auto-validate>
+ <label id="l">label</label>
+ <input is="iron-input" id="i" pattern="[0-9]*" validator="letters-only">
+ </paper-input-container>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="auto-validate-validator-has-invalid-value">
+ <template>
+ <paper-input-container auto-validate>
+ <label id="l">label</label>
+ <input is="iron-input" id="i" validator="letters-only" value="123123">
+ </paper-input-container>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ function getTransform(node) {
+ var style = getComputedStyle(node);
+ return style.transform || style.webkitTransform;
+ }
+
+ suite('label position', function() {
+
+ test('label is visible by default', function() {
+ var container = fixture('basic');
+ assert.equal(getComputedStyle(container.querySelector('#l')).visibility, 'visible', 'label has visibility:visible');
+ });
+
+ test('label is floated if value is initialized to not null', function() {
+ var container = fixture('has-value');
+ assert.notEqual(getTransform(container.querySelector('#l')), 'none', 'label has transform');
+ });
+
+ test('label is invisible if no-label-float and value is initialized to not null', function() {
+ var container = fixture('no-float-has-value');
+ assert.equal(getComputedStyle(container.querySelector('#l')).visibility, 'hidden', 'label has visibility:hidden');
+ });
+
+ test('label is floated if always-float-label is true', function() {
+ var container = fixture('always-float');
+ assert.notEqual(getTransform(container.querySelector('#l')), 'none', 'label has transform');
+ })
+
+ });
+
+ suite('focused styling', function() {
+
+ test('label is colored when input is focused and has value', function(done) {
+ var container = fixture('has-value');
+ var label = Polymer.dom(container).querySelector('#l');
+ var input = Polymer.dom(container).querySelector('#i');
+ var inputContent = Polymer.dom(container.root).querySelector('.input-content');
+ input.focus();
+ // 'focus' event isn't firing on windows ff for some reason when you call focus()
+ container._onFocus();
+ requestAnimationFrame(function() {
+ assert.equal(document.activeElement, input, 'input is focused');
+ assert.isTrue(container.focused, 'focused is true');
+ assert.isTrue(inputContent.classList.contains('label-is-highlighted'), 'label is highlighted when input has focus');
+ done();
+ });
+ });
+
+ test('label is not colored when input is focused and has null value', function(done) {
+ var container = fixture('basic');
+ var label = Polymer.dom(container).querySelector('#l');
+ var input = Polymer.dom(container).querySelector('#i');
+ var inputContent = Polymer.dom(container.root).querySelector('.input-content');
+ input.focus();
+ container._onFocus();
+ requestAnimationFrame(function() {
+ assert.isFalse(inputContent.classList.contains('label-is-highlighted'), 'label is not highlighted when input has focus and has null value');
+ done();
+ });
+ });
+
+ test('underline is colored when input is focused', function(done) {
+ var container = fixture('basic');
+ var input = Polymer.dom(container).querySelector('#i');
+ var line = Polymer.dom(container.root).querySelector('.underline');
+ assert.isFalse(line.classList.contains('is-highlighted'), 'line is not highlighted when input is not focused');
+ input.focus();
+ container._onFocus();
+ requestAnimationFrame(function() {
+ assert.equal(document.activeElement, input, 'input is focused');
+ assert.isTrue(line.classList.contains('is-highlighted'), 'line is highlighted when input is focused');
+ done();
+ });
+ });
+
+ });
+
+ suite('validation', function() {
+
+ test('styled when the input is set to an invalid value with auto-validate', function() {
+ var container = fixture('auto-validate-numbers');
+ var input = Polymer.dom(container).querySelector('#i');
+ var inputContent = Polymer.dom(container.root).querySelector('.input-content');
+ var line = Polymer.dom(container.root).querySelector('.underline');
+
+ input.bindValue = 'foobar';
+
+ assert.isTrue(container.invalid, 'invalid is true');
+ assert.isTrue(inputContent.classList.contains('is-invalid'), 'label has invalid styling when input is invalid');
+ assert.isTrue(line.classList.contains('is-invalid'), 'underline has invalid styling when input is invalid');
+ });
+
+ test('styled when the input is set to an invalid value with auto-validate, with validator', function() {
+ var container = fixture('auto-validate-validator');
+ var input = Polymer.dom(container).querySelector('#i');
+ var inputContent = Polymer.dom(container.root).querySelector('.input-content');
+ var line = Polymer.dom(container.root).querySelector('.underline');
+
+ input.bindValue = '123123';
+
+ assert.isTrue(container.invalid, 'invalid is true');
+ assert.isTrue(inputContent.classList.contains('is-invalid'), 'label has invalid styling when input is invalid');
+ assert.isTrue(line.classList.contains('is-invalid'), 'underline has invalid styling when input is invalid');
+ });
+
+ test('styled when the input is set initially to an invalid value with auto-validate, with validator', function() {
+ var container = fixture('auto-validate-validator-has-invalid-value');
+ assert.isTrue(container.invalid, 'invalid is true');
+ assert.isTrue(Polymer.dom(container.root).querySelector('.underline').classList.contains('is-invalid'), 'underline has is-invalid class');
+ });
+
+ test('styled when the input is set to an invalid value with manual validation', function() {
+ var container = fixture('manual-validate-numbers');
+ var input = Polymer.dom(container).querySelector('#i');
+ var inputContent = Polymer.dom(container.root).querySelector('.input-content');
+ var line = Polymer.dom(container.root).querySelector('.underline');
+
+ input.bindValue = 'foobar';
+ input.validate();
+
+ assert.isTrue(container.invalid, 'invalid is true');
+ assert.isTrue(inputContent.classList.contains('is-invalid'), 'label has invalid styling when input is invalid');
+ assert.isTrue(line.classList.contains('is-invalid'), 'underline has invalid styling when input is invalid');
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-input/test/paper-input-error.html b/polymer_1.0.4/bower_components/paper-input/test/paper-input-error.html
new file mode 100644
index 0000000..2753b85
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/test/paper-input-error.html
@@ -0,0 +1,70 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>paper-input-error tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../../iron-input/iron-input.html">
+ <link rel="import" href="../paper-input-container.html">
+ <link rel="import" href="../paper-input-error.html">
+
+</head>
+<body>
+
+ <paper-input-container id="container">
+ <input is="iron-input">
+ <paper-input-error>error</paper-input-error>
+ </paper-input-container>
+
+ <test-fixture id="auto-validate-numbers">
+ <template>
+ <paper-input-container auto-validate attr-for-value="bind-value">
+ <label id="l">label</label>
+ <input is="iron-input" id="i" pattern="[0-9]*">
+ <paper-input-error id="e">error</paper-input-error>
+ </paper-input-container>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+
+ test('error message only appears when input is invalid', function() {
+ var container = fixture('auto-validate-numbers');
+ var input = Polymer.dom(container).querySelector('#i');
+ var error = Polymer.dom(container).querySelector('#e');
+ assert.equal(getComputedStyle(error).display, 'none', 'error is display:none');
+ input.bindValue = 'foobar';
+ assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
+ });
+
+ test('error message add on is registered', function() {
+ var container = document.getElementById('container');
+ assert.isTrue(container._addons && container._addons.length === 1, 'add on is registered');
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-input/test/paper-input.html b/polymer_1.0.4/bower_components/paper-input/test/paper-input.html
new file mode 100644
index 0000000..1c4dc25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/test/paper-input.html
@@ -0,0 +1,244 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>paper-input tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <script src="../../iron-test-helpers/test-helpers.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../paper-input.html">
+ <link rel="import" href="letters-only.html">
+
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <paper-input></paper-input>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="label">
+ <template>
+ <paper-input label="foo"></paper-input>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="error">
+ <template>
+ <paper-input auto-validate pattern="[0-9]*" value="foobar" error-message="error"></paper-input>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="required">
+ <template>
+ <paper-input auto-validate required error-message="error"></paper-input>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="required-no-auto-validate">
+ <template>
+ <paper-input required error-message="error"></paper-input>
+ </template>
+ </test-fixture>
+
+
+ <test-fixture id="required-char-counter">
+ <template>
+ <paper-input auto-validate char-counter required error-message="error"></paper-input>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="char-counter">
+ <template>
+ <paper-input char-counter value="foobar"></paper-input>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="always-float-label">
+ <template>
+ <paper-input always-float-label label="foo"></paper-input>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="placeholder">
+ <template>
+ <paper-input label="foo" placeholder="bar"></paper-input>
+ </template>
+ </test-fixture>
+
+ <letters-only></letters-only>
+
+ <test-fixture id="validator">
+ <template>
+ <paper-input value="123123" validator="letters-only" auto-validate></paper-input>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+
+ test('setting value sets the input value', function() {
+ var input = fixture('basic');
+ input.value = 'foobar';
+ assert.equal(input.inputElement.value, input.value, 'inputElement.value equals input.value');
+ });
+
+ test('placeholder does not overlap label', function() {
+ var input = fixture('placeholder');
+ assert.equal(input.inputElement.placeholder, input.placeholder, 'inputElement.placeholder equals input.placeholder');
+ assert.equal(input.noLabelFloat, false);
+ var floatingLabel = Polymer.dom(Polymer.dom(input.root).querySelector('paper-input-container').root).querySelector('.label-is-floating');
+ assert.ok(floatingLabel);
+ });
+
+ test('always-float-label attribute works without placeholder', function() {
+ var input = fixture('always-float-label');
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ var inputContent = Polymer.dom(container.root).querySelector('.input-content');
+ assert.isTrue(inputContent.classList.contains('label-is-floating'), 'label is floating');
+ });
+
+ test('error message is displayed', function() {
+ var input = fixture('error');
+ forceXIfStamp(input);
+ var error = Polymer.dom(input.root).querySelector('paper-input-error');
+ assert.ok(error, 'paper-input-error exists');
+ assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
+ });
+
+ test('empty required input shows error', function() {
+ var input = fixture('required');
+ forceXIfStamp(input);
+ var error = Polymer.dom(input.root).querySelector('paper-input-error');
+ assert.ok(error, 'paper-input-error exists');
+ assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
+ });
+
+ test('character counter is displayed', function() {
+ var input = fixture('char-counter');
+ forceXIfStamp(input);
+ var counter = Polymer.dom(input.root).querySelector('paper-input-char-counter')
+ assert.ok(counter, 'paper-input-char-counter exists');
+ assert.equal(counter._charCounterStr, input.value.length, 'character counter shows the value length');
+ });
+
+ test('validator is used', function() {
+ var input = fixture('validator');
+ assert.ok(input.inputElement.invalid, 'input is invalid');
+ });
+
+ test('caret position is preserved', function() {
+ var input = fixture('basic');
+ var ironInput = Polymer.dom(input.root).querySelector('input[is="iron-input"]');
+ input.value = 'nananana';
+ ironInput.selectionStart = 2;
+ ironInput.selectionEnd = 2;
+
+ input.updateValueAndPreserveCaret('nanananabatman');
+
+ assert.equal(ironInput.selectionStart, 2, 'selectionStart is preserved');
+ assert.equal(ironInput.selectionEnd, 2, 'selectionEnd is preserved');
+ });
+
+ });
+
+ suite('focus/blur events', function() {
+ var input;
+
+ setup(function() {
+ input = fixture('basic');
+ });
+
+ test('focus/blur events fired on host element', function(done) {
+ var nFocusEvents = 0;
+ var nBlurEvents = 0;
+ input.addEventListener('focus', function() {
+ nFocusEvents += 1;
+ // setTimeout to wait for potentially more, erroneous events
+ setTimeout(function() {
+ assert.equal(nFocusEvents, 1, 'one focus event fired');
+ input.inputElement.blur();
+ });
+ });
+ input.addEventListener('blur', function() {
+ nBlurEvents += 1;
+ // setTimeout to wait for potentially more, erroneous events
+ setTimeout(function() {
+ assert.equal(nBlurEvents, 1, 'one blur event fired');
+ done();
+ });
+ });
+ input.inputElement.focus();
+ });
+
+ });
+
+ suite('validation', function() {
+
+ test('invalid attribute updated after calling validate()', function() {
+ var input = fixture('required-no-auto-validate');
+ forceXIfStamp(input);
+ input.validate();
+ var error = Polymer.dom(input.root).querySelector('paper-input-error');
+ assert.ok(error, 'paper-input-error exists');
+ assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
+ assert.isTrue(input.invalid, 'invalid is true');
+ });
+
+ });
+
+ suite('a11y', function() {
+
+ test('has aria-labelledby', function() {
+ var input = fixture('label');
+ assert.isTrue(input.inputElement.hasAttribute('aria-labelledby'))
+ assert.equal(input.inputElement.getAttribute('aria-labelledby'), Polymer.dom(input.root).querySelector('label').id, 'aria-labelledby points to the label');
+ });
+
+ test('has aria-describedby for error message', function() {
+ var input = fixture('required');
+ forceXIfStamp(input);
+ assert.isTrue(input.inputElement.hasAttribute('aria-describedby'));
+ assert.equal(input.inputElement.getAttribute('aria-describedby'), Polymer.dom(input.root).querySelector('paper-input-error').id, 'aria-describedby points to the error message');
+ });
+
+ test('has aria-describedby for character counter', function() {
+ var input = fixture('char-counter');
+ forceXIfStamp(input);
+ assert.isTrue(input.inputElement.hasAttribute('aria-describedby'));
+ assert.equal(input.inputElement.getAttribute('aria-describedby'), Polymer.dom(input.root).querySelector('paper-input-char-counter').id, 'aria-describedby points to the character counter');
+ });
+
+ test('has aria-describedby for character counter and error', function() {
+ var input = fixture('required-char-counter');
+ forceXIfStamp(input);
+ assert.isTrue(input.inputElement.hasAttribute('aria-describedby'));
+ assert.equal(input.inputElement.getAttribute('aria-describedby'), Polymer.dom(input.root).querySelector('paper-input-error').id + ' ' + Polymer.dom(input.root).querySelector('paper-input-char-counter').id, 'aria-describedby points to the error message and character counter');
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-input/test/paper-textarea.html b/polymer_1.0.4/bower_components/paper-input/test/paper-textarea.html
new file mode 100644
index 0000000..7371a77
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-input/test/paper-textarea.html
@@ -0,0 +1,200 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <title>paper-textarea tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <script src="../../iron-test-helpers/test-helpers.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../paper-textarea.html">
+
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <paper-textarea></paper-textarea>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="label">
+ <template>
+ <paper-textarea label="foo"></paper-textarea>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="char-counter">
+ <template>
+ <paper-textarea char-counter></paper-textarea>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="required">
+ <template>
+ <paper-textarea auto-validate required error-message="error"></paper-textarea>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="required-char-counter">
+ <template>
+ <paper-textarea auto-validate char-counter required error-message="error"></paper-textarea>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="always-float-label">
+ <template>
+ <paper-textarea always-float-label label="label"></paper-textarea>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('basic', function() {
+
+ test('setting value sets the input value', function() {
+ var input = fixture('basic');
+ input.value = 'foobar';
+ assert.equal(input.inputElement.bindValue, input.value, 'inputElement value equals input.value');
+ });
+
+ test('empty required input shows error', function() {
+ var input = fixture('required');
+ forceXIfStamp(input);
+ var error = Polymer.dom(input.root).querySelector('paper-input-error');
+ assert.ok(error, 'paper-input-error exists');
+ assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
+ });
+
+ test('caret position is preserved', function() {
+ var input = fixture('basic');
+ var ironTextarea = Polymer.dom(input.root).querySelector('iron-autogrow-textarea');
+ input.value = 'nananana';
+ ironTextarea.selectionStart = 2;
+ ironTextarea.selectionEnd = 2;
+
+ input.updateValueAndPreserveCaret('nanananabatman');
+
+ assert.equal(ironTextarea.selectionStart, 2, 'selectionStart is preserved');
+ assert.equal(ironTextarea.selectionEnd, 2, 'selectionEnd is preserved');
+ });
+
+ test('input attributes are bound to textarea', function() {
+ var input = fixture('basic');
+ var attrs = {
+ 'autocomplete': 'true',
+ 'autofocus': true,
+ 'inputmode': 'number',
+ 'name': 'foo',
+ 'placeholder': 'bar',
+ 'readonly': true,
+ 'required': true,
+ 'maxlength': 3
+ };
+ for (var attr in attrs) {
+ input[attr] = attrs[attr];
+ }
+ for (var attr in attrs) {
+ var inputAttr = input.inputElement.getAttribute(attr);
+ if (typeof attrs[attr] === 'boolean') {
+ assert.equal(inputAttr !== null, attrs[attr], 'attribute "' + attr + '" is equal to property (' + attrs[attr] + ', ' + inputAttr !== null + ')');
+ } else {
+ assert.equal(inputAttr, attrs[attr], 'attribute "' + attr + '" is equal to property (' + attrs[attr] + ', ' + inputAttr + ')');
+ }
+ }
+ });
+
+ test('always-float-label attribute works', function() {
+ var input = fixture('always-float-label');
+ var container = Polymer.dom(input.root).querySelector('paper-input-container');
+ var inputContent = Polymer.dom(container.root).querySelector('.input-content');
+ assert.isTrue(inputContent.classList.contains('label-is-floating'), 'label is floating');
+ });
+
+ });
+
+ suite('focus/blur events', function() {
+ var input;
+
+ setup(function() {
+ input = fixture('basic');
+ });
+
+ test('focus/blur events fired on host element', function(done) {
+ var nFocusEvents = 0;
+ var nBlurEvents = 0;
+ input.addEventListener('focus', function() {
+ nFocusEvents += 1;
+ // setTimeout to wait for potentially more, erroneous events
+ setTimeout(function() {
+ assert.equal(nFocusEvents, 1, 'one focus event fired');
+ input.inputElement.textarea.blur();
+ });
+ });
+ input.addEventListener('blur', function() {
+ nBlurEvents += 1;
+ // setTimeout to wait for potentially more, erroneous events
+ setTimeout(function() {
+ assert.equal(nBlurEvents, 1, 'one blur event fired');
+ done();
+ });
+ });
+ input.inputElement.textarea.focus();
+ });
+
+ });
+
+ suite('a11y', function() {
+
+ test('has aria-labelledby', function() {
+ var input = fixture('label');
+ assert.isTrue(input.inputElement.textarea.hasAttribute('aria-labelledby'))
+ assert.equal(input.inputElement.textarea.getAttribute('aria-labelledby'), Polymer.dom(input.root).querySelector('label').id, 'aria-labelledby points to the label');
+ });
+
+ test('has aria-describedby for error message', function() {
+ var input = fixture('required');
+ forceXIfStamp(input);
+ assert.isTrue(input.inputElement.textarea.hasAttribute('aria-describedby'));
+ assert.equal(input.inputElement.textarea.getAttribute('aria-describedby'), Polymer.dom(input.root).querySelector('paper-input-error').id, 'aria-describedby points to the error message');
+ });
+
+ test('has aria-describedby for character counter', function() {
+ var input = fixture('char-counter');
+ forceXIfStamp(input);
+ assert.isTrue(input.inputElement.textarea.hasAttribute('aria-describedby'));
+ assert.equal(input.inputElement.textarea.getAttribute('aria-describedby'), Polymer.dom(input.root).querySelector('paper-input-char-counter').id, 'aria-describedby points to the character counter');
+ });
+
+ test('has aria-describedby for character counter and error', function() {
+ var input = fixture('required-char-counter');
+ forceXIfStamp(input);
+ assert.isTrue(input.inputElement.textarea.hasAttribute('aria-describedby'));
+ assert.equal(input.inputElement.textarea.getAttribute('aria-describedby'), Polymer.dom(input.root).querySelector('paper-input-error').id + ' ' + Polymer.dom(input.root).querySelector('paper-input-char-counter').id, 'aria-describedby points to the error message and character counter');
+ });
+
+
+ });
+
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-item/.bower.json b/polymer_1.0.4/bower_components/paper-item/.bower.json
new file mode 100644
index 0000000..00391bb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-item/.bower.json
@@ -0,0 +1,49 @@
+{
+ "name": "paper-item",
+ "version": "1.0.1",
+ "description": "A material-design styled list item",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "item"
+ ],
+ "main": [
+ "paper-item.html",
+ "paper-icon-item.html",
+ "paper-item-body.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-item"
+ },
+ "license": "MIT",
+ "homepage": "https://github.com/PolymerElements/paper-item",
+ "ignore": [],
+ "dependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+ "paper-checkbox": "PolymerElements/paper-checkbox#^1.0.0",
+ "paper-toggle-button": "PolymerElements/paper-toggle-button#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "645ebae475ab4fc28698da253ccc3aa2c48341d7"
+ },
+ "_source": "git://github.com/PolymerElements/paper-item.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-item"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-item/.gitignore b/polymer_1.0.4/bower_components/paper-item/.gitignore
new file mode 100644
index 0000000..fbe05fc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-item/.gitignore
@@ -0,0 +1 @@
+bower_components/
diff --git a/polymer_1.0.4/bower_components/paper-item/README.md b/polymer_1.0.4/bower_components/paper-item/README.md
new file mode 100644
index 0000000..02f8202
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-item/README.md
@@ -0,0 +1,4 @@
+paper-item
+=========
+
+A non-interactive list item.
diff --git a/polymer_1.0.4/bower_components/paper-item/all-imports.html b/polymer_1.0.4/bower_components/paper-item/all-imports.html
new file mode 100644
index 0000000..4b1583f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-item/all-imports.html
@@ -0,0 +1,13 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="paper-item.html">
+<link rel="import" href="paper-item-body.html">
+<link rel="import" href="paper-icon-item.html">
diff --git a/polymer_1.0.4/bower_components/paper-item/bower.json b/polymer_1.0.4/bower_components/paper-item/bower.json
new file mode 100644
index 0000000..f077268
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-item/bower.json
@@ -0,0 +1,40 @@
+{
+ "name": "paper-item",
+ "version": "1.0.1",
+ "description": "A material-design styled list item",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "item"
+ ],
+ "main": [
+ "paper-item.html",
+ "paper-icon-item.html",
+ "paper-item-body.html"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-item"
+ },
+ "license": "MIT",
+ "homepage": "https://github.com/PolymerElements/paper-item",
+ "ignore": [],
+ "dependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-icon": "PolymerElements/iron-icon#^1.0.0",
+ "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+ "paper-checkbox": "PolymerElements/paper-checkbox#^1.0.0",
+ "paper-toggle-button": "PolymerElements/paper-toggle-button#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-item/demo/index.html b/polymer_1.0.4/bower_components/paper-item/demo/index.html
new file mode 100644
index 0000000..cdedb31
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-item/demo/index.html
@@ -0,0 +1,285 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>paper-item demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../iron-icon/iron-icon.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../../iron-icons/communication-icons.html">
+ <link rel="import" href="../../paper-checkbox/paper-checkbox.html">
+ <link rel="import" href="../../paper-toggle-button/paper-toggle-button.html">
+ <link rel="import" href="../paper-icon-item.html">
+ <link rel="import" href="../paper-item.html">
+ <link rel="import" href="../paper-item-body.html">
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+
+ <style is="custom-style">
+ .list {
+ padding-top: 12px;
+ background-color: white;
+ display: inline-block;
+ width: 240px;
+ height: 228px;
+ margin: 12px;
+ @apply(--shadow-elevation-2dp);
+ }
+
+ .short {
+ padding-top: 12px;
+ height: 216px;
+ }
+
+ h4 {
+ margin-left: 24px;
+ }
+
+ .avatar {
+ display: inline-block;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ overflow: hidden;
+ background: #ccc;
+ }
+
+ .blue {
+ background-color: var(--paper-light-blue-300);
+ }
+ .red {
+ background-color: var(--paper-red-300);
+ }
+ .orange {
+ background-color: var(--paper-amber-300);
+ }
+ .green {
+ background-color: var(--paper-green-300);
+ }
+ </style>
+</head>
+<body>
+ <div class="layout wrap inline center-center">
+ <div>
+ <h4>Single line items</h4>
+ <div class="list short">
+ <paper-item>Inbox</paper-item>
+ <paper-item>Starred</paper-item>
+ <paper-item>Sent mail</paper-item>
+ <paper-item>Drafts</paper-item>
+ </div>
+ </div>
+
+ <div>
+ <h4>Icon with text</h4>
+ <div class="list short">
+ <paper-icon-item>
+ <iron-icon icon="inbox" item-icon></iron-icon> Inbox
+ </paper-icon-item>
+ <paper-icon-item>
+ <iron-icon icon="send" item-icon></iron-icon> Outbox
+ </paper-icon-item>
+ <paper-icon-item>
+ <iron-icon icon="delete" item-icon></iron-icon> Trash
+ </paper-icon-item>
+ <paper-icon-item>
+ <iron-icon icon="report" item-icon></iron-icon> Spam
+ </paper-icon-item>
+ </div>
+ </div>
+
+ <div>
+ <h4>Avatar with text</h4>
+ <div class="list short">
+ <paper-icon-item>
+ <div class="avatar blue" item-icon></div> Alphonso Engelking
+ </paper-icon-item>
+ <paper-icon-item>
+ <div class="avatar red" item-icon></div> Andrews Boyd
+ </paper-icon-item>
+ <paper-icon-item>
+ <div class="avatar orange" item-icon></div> Angela Decker
+ </paper-icon-item>
+ <paper-icon-item>
+ <div class="avatar green" item-icon></div> Lorem Ipsum
+ </paper-icon-item>
+ </div>
+ </div>
+
+ <div>
+ <h4>Avatar with text and icon</h4>
+ <div class="list short">
+ <paper-icon-item>
+ <div class="avatar red" item-icon></div>
+ <div class="flex">Alphonso</div>
+ <iron-icon icon="communication:messenger"></iron-icon>
+ </paper-icon-item>
+ <paper-icon-item>
+ <div class="avatar orange" item-icon></div>
+ <div class="flex">Andrews</div>
+ <iron-icon icon="communication:messenger"></iron-icon>
+ </paper-icon-item>
+ <paper-icon-item>
+ <div class="avatar green" item-icon></div>
+ <div class="flex">Angela</div>
+ <iron-icon icon="communication:messenger"></iron-icon>
+ </paper-icon-item>
+ <paper-icon-item>
+ <div class="avatar blue" item-icon></div>
+ <div class="flex">Lorem</div>
+ <iron-icon icon="communication:messenger"></iron-icon>
+ </paper-icon-item>
+ </div>
+ </div>
+
+ <div>
+ <h4>Avatar with text and control</h4>
+ <div class="list short">
+ <paper-icon-item>
+ <div class="avatar orange" item-icon></div>
+ <div class="flex">Alphonso</div>
+ <paper-checkbox></paper-checkbox>
+ </paper-icon-item>
+ <paper-icon-item>
+ <div class="avatar green" item-icon></div>
+ <div class="flex">Andrews</div>
+ <paper-checkbox checked></paper-checkbox>
+ </paper-icon-item>
+ <paper-icon-item>
+ <div class="avatar blue" item-icon></div>
+ <div class="flex">Angela</div>
+ <paper-checkbox></paper-checkbox>
+ </paper-icon-item>
+ <paper-icon-item>
+ <div class="avatar red" item-icon></div>
+ <div class="flex">Lorem</div>
+ <paper-checkbox></paper-checkbox>
+ </paper-icon-item>
+ </div>
+ </div>
+
+ <div>
+ <h4>Control with text and icon</h4>
+ <div class="list short">
+ <paper-icon-item>
+ <paper-checkbox item-icon></paper-checkbox>
+ <div class="flex">Alphonso</div>
+ <iron-icon icon="communication:messenger"></iron-icon>
+ </paper-icon-item>
+ <paper-icon-item>
+ <paper-checkbox checked item-icon></paper-checkbox>
+ <div class="flex">Andrews</div>
+ <iron-icon icon="communication:messenger"></iron-icon>
+ </paper-icon-item>
+ <paper-icon-item>
+ <paper-checkbox item-icon></paper-checkbox>
+ <div class="flex">Angela</div>
+ <iron-icon icon="communication:messenger"></iron-icon>
+ </paper-icon-item>
+ <paper-icon-item>
+ <paper-checkbox item-icon></paper-checkbox>
+ <div class="flex">Lorem</div>
+ <iron-icon icon="communication:messenger"></iron-icon>
+ </paper-icon-item>
+ </div>
+ </div>
+
+ <div>
+ <h4>Two-line items</h4>
+ <div class="list">
+ <paper-item>
+ <paper-item-body two-line class="layout vertical">
+ <div>Profile Photo</div>
+ <div secondary>Change your Google+ profile photo</div>
+ </paper-item-body>
+ </paper-item>
+ <paper-item>
+ <paper-item-body two-line>
+ <div>Show your status</div>
+ <div secondary>Your status is visible to everyone you use with</div>
+ </paper-item-body>
+ </paper-item>
+ <paper-item>
+ <paper-item-body two-line class="layout vertical">
+ <div>Settings</div>
+ <div secondary>Change your account settings</div>
+ </paper-item-body>
+ </paper-item>
+ </div>
+ </div>
+
+ <div>
+ <h4>Icon with two-line text</h4>
+ <div class="list">
+ <paper-icon-item>
+ <div class="avatar green" item-icon></div>
+ <paper-item-body two-line>
+ <div>Alphonso Engelking</div>
+ <div secondary>Change photo</div>
+ </paper-item-body>
+ </paper-icon-item>
+ <paper-icon-item>
+ <iron-icon icon="communication:phone" item-icon></iron-icon>
+ <paper-item-body two-line>
+ <div>(650) 555-1234</div>
+ <div secondary>Mobile</div>
+ </paper-item-body>
+ </paper-icon-item>
+ <paper-icon-item>
+ <iron-icon icon="communication:email" item-icon></iron-icon>
+ <paper-item-body two-line>
+ <div>alphonso@example.com</div>
+ <div secondary>Personal</div>
+ </paper-item-body>
+ </paper-icon-item>
+ <paper-icon-item>
+ </div>
+ </div>
+
+ <div>
+ <h4>Avatar with text and icon</h4>
+ <div class="list">
+ <paper-icon-item>
+ <div class="avatar blue" item-icon></div>
+ <paper-item-body two-line>
+ <div>Photos</div>
+ <div secondary>Jan 9, 2014</div>
+ </paper-item-body>
+ <iron-icon icon="star"></iron-icon>
+ </paper-icon-item>
+ <paper-icon-item>
+ <div class="avatar red" item-icon></div>
+ <paper-item-body two-line>
+ <div>Recipes</div>
+ <div secondary>Jan 17, 2014</div>
+ </paper-item-body>
+ <iron-icon icon="star"></iron-icon>
+ </paper-icon-item>
+ <paper-icon-item>
+ <div class="avatar orange" item-icon></div>
+ <paper-item-body two-line>
+ <div>Work</div>
+ <div secondary>Jan 28, 2014</div>
+ </paper-item-body>
+ <iron-icon icon="star"></iron-icon>
+ </paper-icon-item>
+ </div>
+ </div>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-item/index.html b/polymer_1.0.4/bower_components/paper-item/index.html
new file mode 100644
index 0000000..b409ed1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-item/index.html
@@ -0,0 +1,30 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!doctype html>
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>paper-item</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page src="all-imports.html"></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-item/paper-icon-item.html b/polymer_1.0.4/bower_components/paper-item/paper-icon-item.html
new file mode 100644
index 0000000..231159c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-item/paper-icon-item.html
@@ -0,0 +1,86 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+
+<!--
+`<paper-icon-item>` is a convenience element to make an item with icon. It is a non interactive list
+item with a fixed-width icon area, according to Material Design. This is useful if the icons are of
+varying widths, but you want the item bodies to line up. Use this like a `<paper-item>`. The child
+node with the attribute `item-icon` is placed in the icon area.
+
+ <paper-icon-item>
+ <iron-icon icon="favorite" item-icon></iron-icon>
+ Favorite
+ </paper-icon-item>
+ <paper-icon-item>
+ <div class="avatar" item-icon></div>
+ Avatar
+ </paper-icon-item>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-item-icon-width` | Width of the icon area | `56px`
+`--paper-icon-item` | Mixin applied to the item | `{}`
+
+-->
+
+<dom-module id="paper-icon-item">
+
+ <link rel="import" type="css" href="paper-item-shared.css">
+
+ <style>
+
+ :host {
+ @apply(--layout-horizontal);
+ @apply(--layout-center);
+ @apply(--paper-font-subhead);
+
+ @apply(--paper-item);
+ @apply(--paper-icon-item);
+ }
+
+ .content-icon {
+ width: var(--paper-item-icon-width, 56px);
+ }
+
+ </style>
+
+ <template>
+ <div id="contentIcon" class="content-icon layout horizontal center">
+ <content select="[item-icon]"></content>
+ </div>
+ <content></content>
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'paper-icon-item',
+
+ hostAttributes: {
+ 'role': 'listitem'
+ }
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-item/paper-item-body.html b/polymer_1.0.4/bower_components/paper-item/paper-item-body.html
new file mode 100644
index 0000000..6345830
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-item/paper-item-body.html
@@ -0,0 +1,93 @@
+<!--
+ @license
+ Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ Code distributed by Google as part of the polymer project is also
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+
+<!--
+Use `<paper-item-body>` in a `<paper-item>` or `<paper-icon-item>` to make two- or
+three- line items. It is a flex item that is a vertical flexbox.
+
+ <paper-item>
+ <paper-item-body two-line>
+ <div>Show your status</div>
+ <div secondary>Your status is visible to everyone</div>
+ </paper-item-body>
+ </paper-item>
+
+The child elements with the `secondary` attribute is given secondary text styling.
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-item-body-two-line-min-height` | Minimum height of a two-line item | `72px`
+`--paper-item-body-three-line-min-height` | Minimum height of a three-line item | `88px`
+`--paper-item-body-secondary-color` | Foreground color for the `secondary` area | `--secondary-text-color`
+`--paper-item-body-secondary` | Mixin applied to the `secondary` area | `{}`
+
+-->
+
+<dom-module id="paper-item-body">
+
+ <style>
+
+ :host {
+ overflow: hidden; /* needed for text-overflow: ellipsis to work on ff */
+ @apply(--layout-vertical);
+ @apply(--layout-center-justified);
+ @apply(--layout-flex);
+ }
+
+ :host([two-line]) {
+ min-height: var(--paper-item-body-two-line-min-height, 72px);
+ }
+
+ :host([three-line]) {
+ min-height: var(--paper-item-body-three-line-min-height, 88px);
+ }
+
+ :host > ::content > * {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ :host > ::content [secondary] {
+ color: var(--paper-item-body-secondary-color, --secondary-text-color);
+ @apply(--paper-font-body1);
+
+ @apply(--paper-item-body-secondary);
+ }
+
+
+ </style>
+
+ <template>
+ <content></content>
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'paper-item-body'
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-item/paper-item-shared.css b/polymer_1.0.4/bower_components/paper-item/paper-item-shared.css
new file mode 100644
index 0000000..8528d1a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-item/paper-item-shared.css
@@ -0,0 +1,19 @@
+/*
+ @license
+ Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ Code distributed by Google as part of the polymer project is also
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+*/
+
+:host {
+ display: block;
+ min-height: var(--paper-item-min-height, 48px);
+ padding: 0px 16px;
+}
+
+:host > ::content > *:not(:first-child):not(:last-child) {
+ margin-right: 16px;
+}
diff --git a/polymer_1.0.4/bower_components/paper-item/paper-item.html b/polymer_1.0.4/bower_components/paper-item/paper-item.html
new file mode 100644
index 0000000..50b89fe
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-item/paper-item.html
@@ -0,0 +1,95 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+
+<!--
+`<paper-item>` is a non-interactive list item. By default, it is a horizontal flexbox.
+
+ <paper-item>Item</paper-item>
+
+Use this element with `<paper-item-body>` to make Material Design styled two-line and three-line
+items.
+
+ <paper-item>
+ <paper-item-body two-line>
+ <div>Show your status</div>
+ <div secondary>Your status is visible to everyone</div>
+ </paper-item-body>
+ <iron-icon icon="warning"></iron-icon>
+ </paper-item>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-item-min-height` | Minimum height of the item | `48px`
+`--paper-item` | Mixin applied to the item | `{}`
+
+### Accessibility
+
+This element has `role="listitem"` by default. Depending on usage, it may be more appropriate to set
+`role="menuitem"`, `role="menuitemcheckbox"` or `role="menuitemradio"`.
+
+ <paper-item role="menuitemcheckbox">
+ <paper-item-body>
+ Show your status
+ </paper-item-body>
+ <paper-checkbox></paper-checkbox>
+ </paper-item>
+
+@group Paper Elements
+@element paper-item
+@demo demo/index.html
+-->
+
+<dom-module id="paper-item">
+
+ <link rel="import" type="css" href="paper-item-shared.css">
+
+ <style>
+
+ :host {
+ @apply(--layout-horizontal);
+ @apply(--layout-center);
+ @apply(--paper-font-subhead);
+
+ @apply(--paper-item);
+ }
+
+ </style>
+
+ <template>
+ <content></content>
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'paper-item',
+
+ hostAttributes: {
+ role: 'listitem'
+ }
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-item/test/index.html b/polymer_1.0.4/bower_components/paper-item/test/index.html
new file mode 100644
index 0000000..6f5314c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-item/test/index.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>paper-item tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'paper-item.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-item/test/paper-item.html b/polymer_1.0.4/bower_components/paper-item/test/paper-item.html
new file mode 100644
index 0000000..3c77ce3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-item/test/paper-item.html
@@ -0,0 +1,66 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!doctype html>
+<html>
+ <head>
+
+ <title>paper-item tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../paper-item.html">
+ <link rel="import" href="../paper-icon-item.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="item">
+ <template>
+ <paper-item>item</paper-item>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="iconItem">
+ <template>
+ <paper-icon-item>item</paper-icon-item>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('item a11y tests', function() {
+ var item, iconItem;
+
+ setup(function() {
+ item = fixture('item');
+ iconItem = fixture('iconItem');
+ });
+
+ test('item has role="listitem"', function() {
+ assert.equal(item.getAttribute('role'), 'listitem', 'has role="item"');
+ });
+
+ test('icon item has role="listitem"', function() {
+ assert.equal(iconItem.getAttribute('role'), 'listitem', 'has role="item"');
+ });
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-material/.bower.json b/polymer_1.0.4/bower_components/paper-material/.bower.json
new file mode 100644
index 0000000..1933706
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-material/.bower.json
@@ -0,0 +1,45 @@
+{
+ "name": "paper-material",
+ "version": "1.0.0",
+ "description": "A material design container that looks like a lifted sheet of paper",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer",
+ "paper",
+ "container"
+ ],
+ "main": [
+ "paper-material.html"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-material"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-material",
+ "ignore": [],
+ "dependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.0",
+ "commit": "bd769d2b8c4f9ab000aee22582d76b5935793dc1"
+ },
+ "_source": "git://github.com/polymerelements/paper-material.git",
+ "_target": "^1.0.0",
+ "_originalSource": "polymerelements/paper-material"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-material/.gitignore b/polymer_1.0.4/bower_components/paper-material/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-material/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-material/README.md b/polymer_1.0.4/bower_components/paper-material/README.md
new file mode 100644
index 0000000..1105102
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-material/README.md
@@ -0,0 +1,13 @@
+# paper-material
+A Material Design container that looks like a lifted piece of paper.
+
+`paper-material` is a container that renders two shadows on top of each other to
+create the effect of a lifted piece of paper.
+
+Example:
+
+```html
+<paper-material elevation="1">
+ ... content ...
+</paper-material>
+```
diff --git a/polymer_1.0.4/bower_components/paper-material/bower.json b/polymer_1.0.4/bower_components/paper-material/bower.json
new file mode 100644
index 0000000..e6f78bc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-material/bower.json
@@ -0,0 +1,36 @@
+{
+ "name": "paper-material",
+ "version": "1.0.0",
+ "description": "A material design container that looks like a lifted sheet of paper",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "web-component",
+ "polymer",
+ "paper",
+ "container"
+ ],
+ "main": [
+ "paper-material.html"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-material"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-material",
+ "ignore": [],
+ "dependencies": {
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-material/demo/index.html b/polymer_1.0.4/bower_components/paper-material/demo/index.html
new file mode 100644
index 0000000..864f696
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-material/demo/index.html
@@ -0,0 +1,113 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>paper-material demo</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../iron-flex-layout/classes/iron-flex-layout.html">
+ <link rel="import" href="../../paper-styles/typography.html">
+ <link rel="import" href="../paper-material.html">
+
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+
+</head>
+<body>
+ <template is="dom-bind" id="demo">
+ <style>
+ paper-material {
+ display: inline-block;
+ background: white;
+ box-sizing: border-box;
+ margin: 16px;
+ padding: 16px;
+ border-radius: 2px;
+ }
+
+ .fab {
+ display: inline-block;
+ background: white;
+ box-sizing: border-box;
+ width: 56px;
+ height: 56px;
+ margin: 16px;
+ padding: 16px;
+ border-radius: 50%;
+ text-align: center;
+ cursor: pointer;
+ }
+ </style>
+ <section>
+ <div>Paper Elevations</div>
+
+ <paper-material elevation="0">
+ elevation = 0
+ </paper-material>
+
+ <paper-material elevation="1">
+ elevation = 1
+ </paper-material>
+
+ <paper-material elevation="2">
+ elevation = 2
+ </paper-material>
+
+ <paper-material elevation="3">
+ elevation = 3
+ </paper-material>
+
+ <paper-material elevation="4">
+ elevation = 4
+ </paper-material>
+
+ <paper-material elevation="5">
+ elevation = 5
+ </paper-material>
+ </section>
+
+ <section on-click="tapAction">
+ <div>Animated</div>
+
+ <paper-material elevation="0" animated>
+ tap
+ </paper-material>
+
+ <paper-material class="fab layout center-center" elevation="0" animated>
+ tap
+ </paper-material>
+ </section>
+ </template>
+
+ <script>
+
+ demo.tapAction = function(e) {
+ var target = e.target;
+ if (!target.down) {
+ target.elevation += 1;
+ if (target.elevation === 5) {
+ target.down = true;
+ }
+ } else {
+ target.elevation -= 1;
+ if (target.elevation === 0) {
+ target.down = false;
+ }
+ }
+ };
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-material/index.html b/polymer_1.0.4/bower_components/paper-material/index.html
new file mode 100644
index 0000000..7209e6d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-material/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>paper-material</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-material/paper-material.html b/polymer_1.0.4/bower_components/paper-material/paper-material.html
new file mode 100644
index 0000000..60f87ba
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-material/paper-material.html
@@ -0,0 +1,98 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-styles/shadow.html">
+
+<!--
+
+`paper-material` is a container that renders two shadows on top of each other to
+create the effect of a lifted piece of paper.
+
+Example:
+
+ <paper-material elevation="1">
+ ... content ...
+ </paper-material>
+
+@group Paper Elements
+@class paper-material
+@demo demo/index.html
+-->
+
+<dom-module id="paper-material">
+ <style>
+ :host {
+ display: block;
+ position: relative;
+ @apply(--shadow-transition);
+ }
+
+ :host([elevation="1"]) {
+ @apply(--shadow-elevation-2dp);
+ }
+
+ :host([elevation="2"]) {
+ @apply(--shadow-elevation-4dp);
+ }
+
+ :host([elevation="3"]) {
+ @apply(--shadow-elevation-6dp);
+ }
+
+ :host([elevation="4"]) {
+ @apply(--shadow-elevation-8dp);
+ }
+
+ :host([elevation="5"]) {
+ @apply(--shadow-elevation-16dp);
+ }
+ </style>
+ <template>
+ <content></content>
+ </template>
+</dom-module>
+<script>
+ Polymer({
+ is: 'paper-material',
+
+ properties: {
+
+ /**
+ * The z-depth of this element, from 0-5. Setting to 0 will remove the
+ * shadow, and each increasing number greater than 0 will be "deeper"
+ * than the last.
+ *
+ * @attribute elevation
+ * @type number
+ * @default 1
+ */
+ elevation: {
+ type: Number,
+ reflectToAttribute: true,
+ value: 1
+ },
+
+ /**
+ * Set this to true to animate the shadow when setting a new
+ * `elevation` value.
+ *
+ * @attribute animated
+ * @type boolean
+ * @default false
+ */
+ animated: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: false
+ }
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-material/test/index.html b/polymer_1.0.4/bower_components/paper-material/test/index.html
new file mode 100644
index 0000000..492a567
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-material/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>paper-material tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'paper-material.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-material/test/paper-material.html b/polymer_1.0.4/bower_components/paper-material/test/paper-material.html
new file mode 100644
index 0000000..0a593fb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-material/test/paper-material.html
@@ -0,0 +1,92 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>paper-material basic tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link href="../../test-fixture/test-fixture.html" rel="import">
+ <link href="../../layout/layout.html" rel="import">
+ <link href="../paper-material.html" rel="import">
+
+</head>
+<body>
+ <test-fixture id="TrivialCard">
+ <template>
+ <paper-material elevation="1"></paper-material>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="ProgressiveElevations">
+ <template>
+ <paper-material elevation="1"></paper-material>
+ <paper-material elevation="2"></paper-material>
+ <paper-material elevation="3"></paper-material>
+ <paper-material elevation="4"></paper-material>
+ <paper-material elevation="5"></paper-material>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('<paper-material>', function() {
+ suite('with a non-zero elevation attribute', function() {
+ var style;
+ var card;
+
+ setup(function() {
+ card = fixture('TrivialCard');
+ style = window.getComputedStyle(card);
+ });
+
+ test('has a shadow', function() {
+ expect(style.boxShadow).to.be.ok;
+ expect(style.boxShadow).to.not.be.eql('none');
+ });
+
+ test('loses shadow with elevation value 0', function() {
+ card.elevation = 0;
+ expect(style.boxShadow).to.be.eql('none');
+ });
+ });
+
+ suite('progressively increasing values of elevation', function() {
+ var cards;
+
+ setup(function() {
+ cards = fixture('ProgressiveElevations');
+ });
+
+ test('yield progressively "deeper" cards', function() {
+ var lastStyle;
+ var style;
+
+ expect(cards.length).to.be.eql(5);
+
+ cards.forEach(function (card) {
+ style = window.getComputedStyle(card);
+
+ expect(style.boxShadow).to.be.ok;
+ expect(style.boxShadow).to.not.be.eql('none');
+ expect(style.boxShadow).to.not.be.eql(lastStyle && lastStyle.boxShadow);
+
+ lastStyle = style;
+ });
+ });
+ });
+ });
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-menu/.bower.json b/polymer_1.0.4/bower_components/paper-menu/.bower.json
new file mode 100644
index 0000000..0e4dff9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-menu/.bower.json
@@ -0,0 +1,41 @@
+{
+ "name": "paper-menu",
+ "version": "1.0.0",
+ "description": "Implements an accessible material design menu",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "menu"
+ ],
+ "main": "paper-menu.html",
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-menu"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-menu",
+ "ignore": [],
+ "dependencies": {
+ "iron-menu-behavior": "PolymerElements/iron-menu-behavior#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "paper-item": "PolymerElements/paper-item#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.0",
+ "commit": "0642450ec9df0fc0b1d909842f436c3dea79ed1e"
+ },
+ "_source": "git://github.com/PolymerElements/paper-menu.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-menu"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-menu/.gitignore b/polymer_1.0.4/bower_components/paper-menu/.gitignore
new file mode 100644
index 0000000..fbe05fc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-menu/.gitignore
@@ -0,0 +1 @@
+bower_components/
diff --git a/polymer_1.0.4/bower_components/paper-menu/README.md b/polymer_1.0.4/bower_components/paper-menu/README.md
new file mode 100644
index 0000000..9991680
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-menu/README.md
@@ -0,0 +1,3 @@
+# paper-menu
+
+`<paper-menu>` implements an accessible menu control with Material Design styling.
diff --git a/polymer_1.0.4/bower_components/paper-menu/bower.json b/polymer_1.0.4/bower_components/paper-menu/bower.json
new file mode 100644
index 0000000..dd2a5cd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-menu/bower.json
@@ -0,0 +1,32 @@
+{
+ "name": "paper-menu",
+ "version": "1.0.0",
+ "description": "Implements an accessible material design menu",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "menu"
+ ],
+ "main": "paper-menu.html",
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-menu"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-menu",
+ "ignore": [],
+ "dependencies": {
+ "iron-menu-behavior": "PolymerElements/iron-menu-behavior#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "paper-item": "PolymerElements/paper-item#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-menu/demo/index.html b/polymer_1.0.4/bower_components/paper-menu/demo/index.html
new file mode 100644
index 0000000..9734cac
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-menu/demo/index.html
@@ -0,0 +1,81 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>paper-menu demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../paper-item/paper-item.html">
+ <link rel="import" href="../paper-menu.html">
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+
+ <style>
+ .horizontal-section {
+ padding: 0 !important;
+ }
+
+ .avatar {
+ display: inline-block;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ overflow: hidden;
+ background: #ccc;
+ }
+ </style>
+</head>
+<body>
+ <div class="horizontal center-justified layout">
+ <div>
+ <h4>Standard</h4>
+ <div class="horizontal-section">
+ <paper-menu class="list">
+ <paper-item>Inbox</paper-item>
+ <paper-item>Starred</paper-item>
+ <paper-item>Sent mail</paper-item>
+ <paper-item>Drafts</paper-item>
+ </paper-menu>
+ </div>
+ </div>
+
+ <div>
+ <h4>Pre-selected</h4>
+ <div class="horizontal-section">
+ <paper-menu class="list" selected="0">
+ <paper-item>Inbox</paper-item>
+ <paper-item disabled>Starred</paper-item>
+ <paper-item>Sent mail</paper-item>
+ <paper-item>Drafts</paper-item>
+ </paper-menu>
+ </div>
+ </div>
+
+ <div>
+ <h4>Multi-select</h4>
+ <div class="horizontal-section">
+ <paper-menu class="list" multi>
+ <paper-item>Bold</paper-item>
+ <paper-item>Italic</paper-item>
+ <paper-item>Underline</paper-item>
+ <paper-item>Strikethrough</paper-item>
+ </paper-menu>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-menu/hero.svg b/polymer_1.0.4/bower_components/paper-menu/hero.svg
new file mode 100755
index 0000000..91af1f6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-menu/hero.svg
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <g>
+ <circle cx="86.5" cy="39" r="4"/>
+ <path d="M138,44c-2,0-3.6-2.4-4.6-4.6c-1.1-2.1-1.7-3.4-3-3.4s-2,1.3-3,3.4c-1.1,2.1-2.2,4.6-4.9,4.6c-2.6,0-3.8-2.4-4.9-4.6
+ c-1.1-2.1-1.8-3.4-3.1-3.4c-1.3,0-2,1.3-3.1,3.4c-1.1,2.1-2.3,4.6-4.9,4.6c-2.6,0-4.1-2.4-5.1-4.6C100.3,37.3,100,36,98,36v-2
+ c3,0,4.1,2.4,5.1,4.6c1.1,2.1,1.9,3.4,3.2,3.4c1.3,0,2.1-1.3,3.2-3.4c1.1-2.1,2.3-4.6,4.9-4.6c2.6,0,3.8,2.4,4.9,4.6
+ c1.1,2.1,1.8,3.4,3.1,3.4c1.3,0,2-1.3,3.1-3.4c1.1-2.1,2.3-4.6,4.9-4.6s3.6,2.4,4.6,4.6c1.1,2.1,1.9,3.4,2.9,3.4V44z"/>
+ <circle cx="86.5" cy="63" r="4"/>
+ <path d="M138,68c-2,0-3.6-2.4-4.6-4.6c-1.1-2.1-1.7-3.4-3-3.4s-2,1.3-3,3.4c-1.1,2.1-2.2,4.6-4.9,4.6c-2.6,0-3.8-2.4-4.9-4.6
+ c-1.1-2.1-1.8-3.4-3.1-3.4c-1.3,0-2,1.3-3.1,3.4c-1.1,2.1-2.3,4.6-4.9,4.6c-2.6,0-4.1-2.4-5.1-4.6C100.3,61.3,100,60,98,60v-2
+ c3,0,4.1,2.4,5.1,4.6c1.1,2.1,1.9,3.4,3.2,3.4c1.3,0,2.1-1.3,3.2-3.4c1.1-2.1,2.3-4.6,4.9-4.6c2.6,0,3.8,2.4,4.9,4.6
+ c1.1,2.1,1.8,3.4,3.1,3.4c1.3,0,2-1.3,3.1-3.4c1.1-2.1,2.3-4.6,4.9-4.6s3.6,2.4,4.6,4.6c1.1,2.1,1.9,3.4,2.9,3.4V68z"/>
+ <circle cx="86.5" cy="88" r="4"/>
+ <path d="M138,93c-2,0-3.6-2.4-4.6-4.6c-1.1-2.1-1.7-3.4-3-3.4s-2,1.3-3,3.4c-1.1,2.1-2.2,4.6-4.9,4.6c-2.6,0-3.8-2.4-4.9-4.6
+ c-1.1-2.1-1.8-3.4-3.1-3.4c-1.3,0-2,1.3-3.1,3.4c-1.1,2.1-2.3,4.6-4.9,4.6c-2.6,0-4.1-2.4-5.1-4.6C100.3,86.3,100,85,98,85v-2
+ c3,0,4.1,2.4,5.1,4.6c1.1,2.1,1.9,3.4,3.2,3.4c1.3,0,2.1-1.3,3.2-3.4c1.1-2.1,2.3-4.6,4.9-4.6c2.6,0,3.8,2.4,4.9,4.6
+ c1.1,2.1,1.8,3.4,3.1,3.4c1.3,0,2-1.3,3.1-3.4c1.1-2.1,2.3-4.6,4.9-4.6s3.6,2.4,4.6,4.6c1.1,2.1,1.9,3.4,2.9,3.4V93z"/>
+ <path d="M151,102H73V24h78V102z M75,100h74V26H75V100z"/>
+ </g>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-menu/index.html b/polymer_1.0.4/bower_components/paper-menu/index.html
new file mode 100644
index 0000000..fc88411
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-menu/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>paper-menu</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-menu/paper-menu.html b/polymer_1.0.4/bower_components/paper-menu/paper-menu.html
new file mode 100644
index 0000000..45ecd72
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-menu/paper-menu.html
@@ -0,0 +1,133 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-menu-behavior/iron-menu-behavior.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+
+<!--
+`<paper-menu>` implements an accessible menu control with Material Design styling. The focused item
+is highlighted, and the selected item has bolded text.
+
+ <paper-menu>
+ <paper-item>Item 1</paper-item>
+ <paper-item>Item 2</paper-item>
+ </paper-menu>
+
+Make a multi-select menu with the `multi` attribute. Items in a multi-select menu can be deselected,
+and multiple item can be selected.
+
+ <paper-menu multi>
+ <paper-item>Item 1</paper-item>
+ <paper-item>Item 2</paper-item>
+ </paper-menu>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-menu-background-color` | Menu background color | `--primary-background-color`
+`-paper-menu-color` | Menu foreground color | `--primary-text-color`
+`--paper-menu-disabled-color` | Foreground color for a disabled item | `--disabled-text-color`
+`--paper-menu` | Mixin applied to the menu | `{}`
+`--paper-menu-selected-item` | Mixin applied to the selected item | `{}`
+`--paper-menu-focused-item` | Mixin applied to the focused item | `{}`
+`--paper-menu-focused-item-after` | Mixin applied to the ::after pseudo-element for the focused item | `{}`
+
+### Accessibility
+
+`<paper-menu>` has `role="menu"` by default. A multi-select menu will also have
+`aria-multiselectable` set. It implements key bindings to navigate through the menu with the up and
+down arrow keys, esc to exit the menu, and enter to activate a menu item. Typing the first letter
+of a menu item will also focus it.
+
+@group Paper Elements
+@element paper-menu
+@hero hero.svg
+@demo demo/index.html
+-->
+
+<dom-module id="paper-menu">
+
+ <style>
+
+ :host {
+ display: block;
+ padding: 8px 0;
+
+ background: var(--paper-menu-background-color, --primary-background-color);
+ color: var(--paper-menu-color, --primary-text-color);
+
+ @apply(--paper-menu);
+ }
+
+ /* need a wrapper element to make this higher specificity than the :host rule in paper-item */
+ .content > ::content > .iron-selected {
+ font-weight: bold;
+
+ @apply(--paper-menu-selected-item);
+ }
+
+ .content > ::content > [disabled] {
+ color: var(--paper-menu-disabled-color, --disabled-text-color);
+ }
+
+ .content > ::content > *:focus {
+ position: relative;
+ outline: 0;
+
+ @apply(--paper-menu-colored-focused-item);
+ }
+
+ .content > ::content > *:focus:after {
+ @apply(--layout-fit);
+ background: currentColor;
+ /* FIXME move to paper-styles for next widget */
+ opacity: 0.12;
+ content: '';
+
+ @apply(--paper-menu-colored-focused-item-after);
+ }
+
+ .content > ::content > *[colored]:focus:after {
+ opacity: 0.26;
+ }
+
+ </style>
+
+ <template>
+
+ <div class="content">
+ <content></content>
+ </div>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+(function() {
+
+ Polymer({
+
+ is: 'paper-menu',
+
+ behaviors: [
+ Polymer.IronMenuBehavior
+ ]
+
+ });
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-menu/test/index.html b/polymer_1.0.4/bower_components/paper-menu/test/index.html
new file mode 100644
index 0000000..e6b26d5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-menu/test/index.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>paper-menu tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'paper-menu.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-menu/test/paper-menu.html b/polymer_1.0.4/bower_components/paper-menu/test/paper-menu.html
new file mode 100644
index 0000000..5856775
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-menu/test/paper-menu.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>paper-menu tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../paper-menu.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="basic">
+ <template>
+ <paper-menu>
+ <div>item 1</div>
+ <div>item 2</div>
+ <div>item 3</div>
+ </paper-menu>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('<paper-menu>', function() {
+ var menu;
+
+ setup(function() {
+ menu = fixture('basic');
+ });
+
+ test('selected item is styled', function() {
+
+ var boldDiv = document.createElement('div');
+ boldDiv.style.fontWeight = 'bold';
+ document.body.appendChild(boldDiv);
+
+ menu.selected = 1;
+
+ assert.equal(getComputedStyle(menu.selectedItem).fontWeight,
+ getComputedStyle(boldDiv).fontWeight, 'selected item is bold');
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-progress/.bower.json b/polymer_1.0.4/bower_components/paper-progress/.bower.json
new file mode 100644
index 0000000..100fe00
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-progress/.bower.json
@@ -0,0 +1,41 @@
+{
+ "name": "paper-progress",
+ "version": "1.0.0",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "A material design progress bar",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "progress"
+ ],
+ "main": [
+ "paper-progress.html"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-progress.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-range-behavior": "PolymerElements/iron-range-behavior#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "paper-button": "PolymerElements/paper-button#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/paper-progress",
+ "_release": "1.0.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.0",
+ "commit": "1bef80a0d4110654b85746e70c006796ce8cdc2c"
+ },
+ "_source": "git://github.com/PolymerElements/paper-progress.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-progress"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-progress/.gitignore b/polymer_1.0.4/bower_components/paper-progress/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-progress/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-progress/README.md b/polymer_1.0.4/bower_components/paper-progress/README.md
new file mode 100644
index 0000000..7aaf060
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-progress/README.md
@@ -0,0 +1,47 @@
+paper-progress
+===================
+
+The progress bars are for situations where the percentage completed can be
+determined. They give users a quick sense of how much longer an operation
+will take.
+
+Example:
+
+```html
+<paper-progress value="10"></paper-progress>
+```
+
+There is also a secondary progress which is useful for displaying intermediate
+progress, such as the buffer level during a streaming playback progress bar.
+
+Example:
+
+```html
+<paper-progress value="10" secondaryProgress="30"></paper-progress>
+```
+
+Styling progress bar:
+
+To change the active progress bar color:
+
+```css
+paper-progress {
+ --paper-progress-active-color: #e91e63;
+}
+```
+
+To change the secondary progress bar color:
+
+```css
+paper-progress {
+ --paper-progress-secondary-color: #f8bbd0;
+}
+```
+
+To change the progress bar background color:
+
+```css
+paper-progress {
+ --paper-progress-container-color: #64ffda;
+}
+```
diff --git a/polymer_1.0.4/bower_components/paper-progress/bower.json b/polymer_1.0.4/bower_components/paper-progress/bower.json
new file mode 100644
index 0000000..8c17acb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-progress/bower.json
@@ -0,0 +1,31 @@
+{
+ "name": "paper-progress",
+ "version": "1.0.0",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "A material design progress bar",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "progress"
+ ],
+ "main": [
+ "paper-progress.html"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-progress.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-range-behavior": "PolymerElements/iron-range-behavior#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "paper-button": "PolymerElements/paper-button#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-progress/demo/index.html b/polymer_1.0.4/bower_components/paper-progress/demo/index.html
new file mode 100644
index 0000000..97f8c1b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-progress/demo/index.html
@@ -0,0 +1,122 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<!doctype html>
+<html>
+<head>
+ <title>paper-progress demo</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../paper-progress.html">
+ <link rel="import" href="../../paper-button/paper-button.html">
+
+ <style is="custom-style">
+ body {
+ padding: 40px;
+ }
+
+ paper-progress {
+ display: block;
+ width: 100%;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ }
+
+ paper-progress.blue {
+ --paper-progress-active-color: var(--paper-light-blue-500);
+ --paper-progress-secondary-color: var(--paper-light-blue-100);
+ }
+
+ paper-progress.red {
+ --paper-progress-active-color: var(--paper-red-500);
+ --paper-progress-secondary-color: var(--paper-red-100);
+ }
+
+ paper-progress.orange {
+ --paper-progress-active-color: var(--paper-orange-500);
+ --paper-progress-secondary-color: var(--paper-orange-100);
+ }
+
+ paper-progress.green {
+ --paper-progress-active-color: var(--paper-light-green-500);
+ --paper-progress-secondary-color: var(--paper-light-green-100);
+ }
+ </style>
+
+</head>
+<body>
+ <div class="vertical layout">
+ <h4>Progress bar</h4>
+ <div class="vertical-section">
+ <paper-progress></paper-progress>
+ <paper-button raised onclick="startProgress();">Start</paper-button>
+ </div>
+
+ <h4>Indeterminate</h4>
+ <div class="vertical-section">
+ <paper-progress indeterminate></paper-progress><br>
+ <paper-progress class="blue" indeterminate alue="800" min="100" max="1000"></paper-progress><br>
+ </div>
+
+ <h4>Color</h4>
+ <div class="vertical-section">
+ <paper-progress value="40" class="blue"></paper-progress><br>
+ <paper-progress value="800" min="100" max="1000" class="red"></paper-progress><br>
+ <paper-progress value="40" class="orange"></paper-progress><br>
+ <paper-progress value="200" max="200" class="green"></paper-progress><br>
+ <paper-progress value="40" secondary-progress="80" class="blue"></paper-progress><br>
+ </div>
+ </div>
+
+ <script>
+
+ var progress = document.querySelector('paper-progress');
+ var button = document.querySelector('paper-button');
+
+ var repeat, maxRepeat = 5, animating = false;
+
+ function nextProgress() {
+ animating = true;
+ if (progress.value < progress.max) {
+ progress.value += (progress.step || 1);
+ } else {
+ if (++repeat >= maxRepeat) {
+ animating = false;
+ button.disabled = false;
+ return;
+ }
+ progress.value = progress.min;
+ }
+
+ requestAnimationFrame(nextProgress);
+ }
+
+ function startProgress() {
+ repeat = 0;
+ progress.value = progress.min;
+ button.disabled = true;
+ if (!animating) {
+ nextProgress();
+ }
+ }
+
+ window.addEventListener('WebComponentsReady', function() {
+ startProgress();
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-progress/hero.svg b/polymer_1.0.4/bower_components/paper-progress/hero.svg
new file mode 100755
index 0000000..dc422a4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-progress/hero.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <rect x="57" y="59" width="20" height="2"/>
+ <rect x="38" y="59" width="11" height="2"/>
+ <rect x="84" y="59" width="40" height="2"/>
+ <rect x="133" y="59" width="54" height="2"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-progress/index.html b/polymer_1.0.4/bower_components/paper-progress/index.html
new file mode 100644
index 0000000..225e3dd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-progress/index.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <title>paper-progress</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-progress/paper-progress.html b/polymer_1.0.4/bower_components/paper-progress/paper-progress.html
new file mode 100644
index 0000000..949e1bc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-progress/paper-progress.html
@@ -0,0 +1,199 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+
+<link rel="import" href="../paper-styles/paper-styles.html">
+<link rel="import" href="../iron-range-behavior/iron-range-behavior.html">
+<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+
+<!--
+The progress bars are for situations where the percentage completed can be
+determined. They give users a quick sense of how much longer an operation
+will take.
+
+Example:
+
+ <paper-progress value="10"></paper-progress>
+
+There is also a secondary progress which is useful for displaying intermediate
+progress, such as the buffer level during a streaming playback progress bar.
+
+Example:
+
+ <paper-progress value="10" secondary-progress="30"></paper-progress>
+
+Styling progress bar:
+
+To change the active progress bar color:
+
+ paper-progress {
+ --paper-progress-active-color: #e91e63;
+ }
+
+To change the secondary progress bar color:
+
+ paper-progress {
+ --paper-progress-secondary-color: #f8bbd0;
+ }
+
+To change the progress bar background color:
+
+ paper-progress {
+ --paper-progress-container-color: #64ffda;
+ }
+
+@group Paper Elements
+@element paper-progress
+@hero hero.svg
+@demo demo/index.html
+-->
+
+<dom-module id="paper-progress">
+ <style>
+ :host {
+ display: inline-block;
+ width: 200px;
+ height: 4px;
+ }
+
+ #progressContainer {
+ position: relative;
+ height: 100%;
+ background-color: var(--paper-progress-container-color, --google-grey-300);
+ overflow: hidden;
+ }
+
+ #activeProgress,
+ #secondaryProgress {
+ -webkit-transform-origin: left center;
+ transform-origin: left center;
+ -webkit-transform: scaleX(0);
+ transform: scaleX(0);
+ }
+
+ #activeProgress {
+ background-color: var(--paper-progress-active-color, --google-green-500);
+ }
+
+ #secondaryProgress {
+ background-color: var(--paper-progress-secondary-color, --google-green-100);
+ }
+
+ #activeProgress.indeterminate {
+ -webkit-transform-origin: center center;
+ transform-origin: center center;
+ -webkit-animation: indeterminate-bar 1s linear infinite;
+ animation: indeterminate-bar 1s linear infinite;
+ }
+
+ @-webkit-keyframes indeterminate-bar {
+ 0% {
+ -webkit-transform: translate(-50%) scaleX(0);
+ }
+ 50% {
+ -webkit-transform: translate(0%) scaleX(0.3);
+ }
+ 100% {
+ -webkit-transform: translate(50%) scaleX(0);
+ }
+ }
+
+ @keyframes indeterminate-bar {
+ 0% {
+ transform: translate(-50%) scaleX(0);
+ }
+ 50% {
+ transform: translate(0%) scaleX(0.3);
+ }
+ 100% {
+ transform: translate(50%) scaleX(0);
+ }
+ }
+ </style>
+ <template>
+ <div id="progressContainer" role="progressbar" aria-valuenow$="{{value}}" aria-valuemin$="{{min}}" aria-valuemax$="{{max}}">
+ <div id="secondaryProgress" class="fit"></div>
+ <div id="activeProgress" class="fit"></div>
+ </div>
+ </template>
+</dom-module>
+
+<script>
+ Polymer({
+
+ is: 'paper-progress',
+
+ behaviors: [
+ Polymer.IronRangeBehavior
+ ],
+
+ properties: {
+
+ /**
+ * The number that represents the current secondary progress.
+ */
+ secondaryProgress: {
+ type: Number,
+ value: 0,
+ notify: true
+ },
+
+ /**
+ * The secondary ratio
+ */
+ secondaryRatio: {
+ type: Number,
+ value: 0,
+ readOnly: true,
+ observer: '_secondaryRatioChanged'
+ },
+
+ /**
+ * Use an indeterminate progress indicator.
+ */
+ indeterminate: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ observer: '_toggleIndeterminate'
+ }
+ },
+
+ observers: [
+ '_ratioChanged(ratio)',
+ '_secondaryProgressChanged(secondaryProgress, min, max)'
+ ],
+
+ _toggleIndeterminate: function() {
+ // If we use attribute/class binding, the animation sometimes doesn't translate properly
+ // on Safari 7.1. So instead, we toggle the class here in the update method.
+ this.toggleClass('indeterminate', this.indeterminate, this.$.activeProgress);
+ },
+
+ _transformProgress: function(progress, ratio) {
+ var transform = 'scaleX(' + (ratio / 100) + ')';
+ progress.style.transform = progress.style.webkitTransform = transform;
+ },
+
+ _ratioChanged: function(ratio) {
+ this._transformProgress(this.$.activeProgress, ratio);
+ },
+
+ _secondaryRatioChanged: function(secondaryRatio) {
+ this._transformProgress(this.$.secondaryProgress, secondaryRatio);
+ },
+
+ _secondaryProgressChanged: function() {
+ this.secondaryProgress = this._clampValue(this.secondaryProgress);
+ this._setSecondaryRatio(this._calcRatio(this.secondaryProgress) * 100);
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-progress/test/basic.html b/polymer_1.0.4/bower_components/paper-progress/test/basic.html
new file mode 100644
index 0000000..dddb6ef
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-progress/test/basic.html
@@ -0,0 +1,121 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>paper-progress test</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../paper-progress.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+</head>
+<body>
+
+
+ <test-fixture id="trivialProgress">
+ <template>
+ <paper-progress></paper-progress>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('<paper-progress>', function() {
+ var range;
+
+ setup(function() {
+ range = fixture('trivialProgress');
+ });
+
+ test('check default', function() {
+ assert.equal(range.min, 0);
+ assert.equal(range.max, 100);
+ assert.equal(range.value, 0);
+ });
+
+ test('set value', function(done) {
+ range.value = 50;
+ asyncPlatformFlush(function() {
+ assert.equal(range.value, 50);
+ // test clamp value
+ range.value = 60.1;
+ asyncPlatformFlush(function() {
+ assert.equal(range.value, 60);
+ done();
+ });
+ });
+ });
+
+ test('set max', function(done) {
+ range.max = 10;
+ range.value = 11;
+ asyncPlatformFlush(function() {
+ assert.equal(range.value, range.max);
+ done();
+ });
+ });
+
+ test('test ratio', function(done) {
+ range.max = 10;
+ range.value = 5;
+ asyncPlatformFlush(function() {
+ assert.equal(range.ratio, 50);
+ done();
+ });
+ });
+
+ test('test secondary ratio', function(done) {
+ range.max = 10;
+ range.secondaryProgress = 5;
+ asyncPlatformFlush(function() {
+ assert.equal(range.secondaryRatio, 50);
+ done();
+ });
+ });
+
+ test('set min', function(done) {
+ range.min = 10
+ range.max = 50;
+ range.value = 30;
+ asyncPlatformFlush(function() {
+ assert.equal(range.ratio, 50);
+ range.value = 0;
+ asyncPlatformFlush(function() {
+ assert.equal(range.value, range.min);
+ done();
+ });
+ });
+ });
+
+ test('set step', function(done) {
+ range.min = 0;
+ range.max = 10;
+ range.value = 5.1;
+ asyncPlatformFlush(function() {
+ assert.equal(range.value, 5);
+ range.step = 0.1;
+ range.value = 5.1;
+ asyncPlatformFlush(function() {
+ assert.equal(range.value, 5.1);
+ done();
+ });
+ });
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-progress/test/index.html b/polymer_1.0.4/bower_components/paper-progress/test/index.html
new file mode 100644
index 0000000..f07aca9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-progress/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-radio-button/.bower.json b/polymer_1.0.4/bower_components/paper-radio-button/.bower.json
new file mode 100644
index 0000000..921a3c1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-button/.bower.json
@@ -0,0 +1,44 @@
+{
+ "name": "paper-radio-button",
+ "version": "1.0.3",
+ "description": "A material design radio button",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "radio",
+ "control"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-radio-button"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-radio-button",
+ "ignore": [],
+ "dependencies": {
+ "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+ "paper-styles": "PolymerLabs/paper-styles#^1.0.0",
+ "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.3",
+ "commit": "adf0de18d7f0b20b6ee7e891b4f265427fe2e5ff"
+ },
+ "_source": "git://github.com/PolymerElements/paper-radio-button.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-radio-button"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-radio-button/.gitignore b/polymer_1.0.4/bower_components/paper-radio-button/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-button/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-radio-button/README.md b/polymer_1.0.4/bower_components/paper-radio-button/README.md
new file mode 100644
index 0000000..f1bdf54
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-button/README.md
@@ -0,0 +1,29 @@
+# paper-radio-button
+
+`paper-radio-button` is a button that can be either checked or unchecked.
+User can tap the radio button to check it. But it cannot be unchecked by
+tapping once checked.
+
+Use `paper-radio-group` to group a set of radio buttons. When radio buttons
+are inside a radio group, only one radio button in the group can be checked.
+
+Example:
+
+```html
+<paper-radio-button></paper-radio-button>
+```
+Styling a radio button:
+
+```html
+<style is="custom-style">
+ :root {
+ /* Unchecked state colors. */
+ --paper-radio-button-unchecked-color: #5a5a5a;
+ --paper-radio-button-unchecked-ink-color: #5a5a5a;
+
+ /* Checked state colors. */
+ --paper-radio-button-checked-color: #009688;
+ --paper-radio-button-checked-ink-color: #0f9d58;
+ }
+</style>
+```
diff --git a/polymer_1.0.4/bower_components/paper-radio-button/bower.json b/polymer_1.0.4/bower_components/paper-radio-button/bower.json
new file mode 100644
index 0000000..4612f3d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-button/bower.json
@@ -0,0 +1,35 @@
+{
+ "name": "paper-radio-button",
+ "version": "1.0.3",
+ "description": "A material design radio button",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "radio",
+ "control"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-radio-button"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-radio-button",
+ "ignore": [],
+ "dependencies": {
+ "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+ "paper-styles": "PolymerLabs/paper-styles#^1.0.0",
+ "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-radio-button/demo/index.html b/polymer_1.0.4/bower_components/paper-radio-button/demo/index.html
new file mode 100644
index 0000000..e298b0a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-button/demo/index.html
@@ -0,0 +1,94 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>paper-radio-button demo</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../paper-radio-button.html">
+
+ <style is="custom-style">
+ paper-radio-button {
+ display: block;
+ margin-bottom: 40px;
+ }
+
+ paper-radio-button.blue {
+ --paper-radio-button-checked-color: var(--paper-light-blue-500);
+ --paper-radio-button-checked-ink-color: var(--paper-light-blue-500);
+ --paper-radio-button-unchecked-color: var(--paper-light-blue-900);
+ --paper-radio-button-unchecked-ink-color: var(--paper-light-blue-900);
+ }
+
+ paper-radio-button.red {
+ --paper-radio-button-checked-color: var(--paper-red-500);
+ --paper-radio-button-checked-ink-color: var(--paper-red-500);
+ --paper-radio-button-unchecked-color: var(--paper-red-900);
+ --paper-radio-button-unchecked-ink-color: var(--paper-red-900);
+ }
+
+ paper-radio-button.green {
+ --paper-radio-button-checked-color: var(--paper-green-500);
+ --paper-radio-button-checked-ink-color: var(--paper-green-500);
+ --paper-radio-button-unchecked-color: var(--paper-green-900);
+ --paper-radio-button-unchecked-ink-color: var(--paper-green-900);
+ }
+
+ paper-radio-button.orange {
+ --paper-radio-button-checked-color: var(--paper-orange-500);
+ --paper-radio-button-checked-ink-color: var(--paper-orange-500);
+ --paper-radio-button-unchecked-color: var(--paper-orange-900);
+ --paper-radio-button-unchecked-ink-color: var(--paper-orange-900);
+ }
+ </style>
+</head>
+<body>
+ <div class="horizontal center-justified layout">
+ <div>
+ <h4>Enabled</h4>
+ <div class="horizontal-section">
+ <paper-radio-button>Oxygen</paper-radio-button>
+ <paper-radio-button>Carbon</paper-radio-button>
+ <paper-radio-button checked>Hydrogen</paper-radio-button>
+ <paper-radio-button checked>Nitrogen</paper-radio-button>
+ <paper-radio-button checked>Calcium</paper-radio-button>
+ </div>
+ </div>
+
+ <div>
+ <h4>Disabled</h4>
+ <div class="horizontal-section">
+ <paper-radio-button disabled>Oxygen</paper-radio-button>
+ <paper-radio-button disabled>Carbon</paper-radio-button>
+ <paper-radio-button checked disabled>Hydrogen</paper-radio-button>
+ <paper-radio-button checked disabled>Nitrogen</paper-radio-button>
+ <paper-radio-button checked disabled>Calcium</paper-radio-button>
+ </div>
+ </div>
+
+ <div>
+ <h4>Color</h4>
+ <div class="horizontal-section">
+ <paper-radio-button class="blue" checked>Oxygen</paper-radio-button>
+ <paper-radio-button class="red" checked>Carbon</paper-radio-button>
+ <paper-radio-button class="orange" checked>Hydrogen</paper-radio-button>
+ <paper-radio-button class="green" checked>Nitrogen</paper-radio-button>
+ <paper-radio-button class="blue" checked>Calcium</paper-radio-button>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-radio-button/hero.svg b/polymer_1.0.4/bower_components/paper-radio-button/hero.svg
new file mode 100755
index 0000000..7fbac94
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-button/hero.svg
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <g>
+ <circle cx="112.5" cy="63" r="8"/>
+ <path d="M112.5,80c-9.4,0-17-7.6-17-17s7.6-17,17-17s17,7.6,17,17S121.9,80,112.5,80z M112.5,48c-8.3,0-15,6.7-15,15s6.7,15,15,15
+ s15-6.7,15-15S120.8,48,112.5,48z"/>
+ </g>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-radio-button/index.html b/polymer_1.0.4/bower_components/paper-radio-button/index.html
new file mode 100644
index 0000000..a564b41
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-button/index.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>paper-radio-button</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-radio-button/paper-radio-button.css b/polymer_1.0.4/bower_components/paper-radio-button/paper-radio-button.css
new file mode 100644
index 0000000..682d8c5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-button/paper-radio-button.css
@@ -0,0 +1,109 @@
+/*
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+*/
+
+:host {
+ display: inline-block;
+ white-space: nowrap;
+}
+
+:host(:focus) {
+ outline: none;
+}
+
+#radioContainer {
+ display: inline-block;
+ position: relative;
+ width: 16px;
+ height: 16px;
+ cursor: pointer;
+ vertical-align: middle;
+}
+
+:host #ink {
+ position: absolute;
+ top: -16px;
+ left: -16px;
+ width: 48px;
+ height: 48px;
+ color: var(--paper-radio-button-unchecked-ink-color, --primary-text-color);
+ opacity: 0.6;
+}
+
+:host #ink[checked] {
+ color: var(--paper-radio-button-checked-ink-color, --default-primary-color);
+}
+
+:host #offRadio {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 12px;
+ height: 12px;
+ border-radius: 50%;
+ border: solid 2px;
+ border-color: var(--paper-radio-button-unchecked-color, --primary-text-color);
+ transition: border-color 0.28s;
+}
+
+:host #onRadio {
+ position: absolute;
+ top: 4px;
+ left: 4px;
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background-color: var(--paper-radio-button-checked-color, --default-primary-color);
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ transition: -webkit-transform ease 0.28s;
+ transition: transform ease 0.28s;
+}
+
+:host([checked]) #offRadio {
+ border-color: var(--paper-radio-button-checked-color, --default-primary-color);
+}
+
+:host([checked]) #onRadio {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+}
+
+#radioLabel {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+ margin-left: 10px;
+ white-space: normal;
+ pointer-events: none;
+ color: var(--paper-radio-button-label-color, --primary-text-color);
+}
+
+#radioLabel[hidden] {
+ display: none;
+}
+
+/* disabled state */
+:host([disabled]) {
+ pointer-events: none;
+}
+
+:host([disabled]) #offRadio {
+ border-color: var(--paper-radio-button-unchecked-color, --primary-text-color);
+ opacity: 0.5;
+}
+
+:host([disabled][checked]) #onRadio {
+ background-color: var(--paper-radio-button-unchecked-color, --primary-text-color);
+ opacity: 0.5;
+}
+
+:host([disabled]) #radioLabel {
+ /* slightly darker than the button, so that it's readable */
+ opacity: 0.65;
+}
diff --git a/polymer_1.0.4/bower_components/paper-radio-button/paper-radio-button.html b/polymer_1.0.4/bower_components/paper-radio-button/paper-radio-button.html
new file mode 100644
index 0000000..63fba75
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-button/paper-radio-button.html
@@ -0,0 +1,136 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-ripple/paper-ripple.html">
+<link rel="import" href="../paper-styles/default-theme.html">
+<link rel="import" href="../paper-behaviors/paper-inky-focus-behavior.html">
+
+<!--
+`paper-radio-button` is a button that can be either checked or unchecked.
+User can tap the radio button to check it. But it cannot be unchecked by
+tapping once checked.
+
+Use `paper-radio-group` to group a set of radio buttons. When radio buttons
+are inside a radio group, only one radio button in the group can be checked.
+
+Example:
+
+ <paper-radio-button></paper-radio-button>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-radio-button-unchecked-color` | Radio button color when the input is not checked | `--primary-text-color`
+`--paper-radio-button-unchecked-ink-color` | Selected/focus ripple color when the input is not checked | `--primary-text-color`
+`--paper-radio-button-checked-color` | Radio button color when the input is checked | `--default-primary-color`
+`--paper-radio-button-checked-ink-color` | Selected/focus ripple color when the input is checked | `--default-primary-color`
+`--paper-radio-button-label-color` | Label color | `--primary-text-color`
+
+@group Paper Elements
+@element paper-radio-button
+@hero hero.svg
+@demo demo/index.html
+-->
+
+<dom-module id="paper-radio-button">
+
+ <link rel="import" type="css" href="paper-radio-button.css">
+
+ <template>
+
+ <div id="radioContainer">
+ <div id="offRadio"></div>
+ <div id="onRadio"></div>
+ <paper-ripple id="ink" class="circle" center checked$="[[checked]]"></paper-ripple>
+ </div>
+
+ <div id="radioLabel" aria-hidden="true"><content></content></div>
+
+ </template>
+
+ <script>
+ Polymer({
+ is: 'paper-radio-button',
+
+ behaviors: [
+ Polymer.PaperInkyFocusBehavior
+ ],
+
+ hostAttributes: {
+ role: 'radio',
+ 'aria-checked': false,
+ tabindex: 0
+ },
+
+ properties: {
+ /**
+ * Fired when the checked state changes due to user interaction.
+ *
+ * @event change
+ */
+
+ /**
+ * Fired when the checked state changes.
+ *
+ * @event iron-change
+ */
+
+ /**
+ * Gets or sets the state, `true` is checked and `false` is unchecked.
+ */
+ checked: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true,
+ notify: true,
+ observer: '_checkedChanged'
+ },
+
+ /**
+ * If true, the button toggles the active state with each tap or press
+ * of the spacebar.
+ */
+ toggles: {
+ type: Boolean,
+ value: true,
+ reflectToAttribute: true
+ }
+ },
+
+ ready: function() {
+ if (Polymer.dom(this).textContent == '') {
+ this.$.radioLabel.hidden = true;
+ } else {
+ this.setAttribute('aria-label', Polymer.dom(this).textContent);
+ }
+ this._isReady = true;
+ },
+
+ _buttonStateChanged: function() {
+ if (this.disabled) {
+ return;
+ }
+ if (this._isReady) {
+ this.checked = this.active;
+ }
+ },
+
+ _checkedChanged: function() {
+ this.setAttribute('aria-checked', this.checked ? 'true' : 'false');
+ this.active = this.checked;
+ this.fire('iron-change');
+ }
+ })
+ </script>
+
+</dom-module>
diff --git a/polymer_1.0.4/bower_components/paper-radio-button/test/basic.html b/polymer_1.0.4/bower_components/paper-radio-button/test/basic.html
new file mode 100644
index 0000000..6851d3d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-button/test/basic.html
@@ -0,0 +1,101 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>paper-radio-button basic tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+ <script src="../../iron-test-helpers/mock-interactions.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../paper-radio-button.html">
+
+</head>
+<body>
+
+ <test-fixture id="NoLabel">
+ <template>
+ <paper-radio-button id="radio1"></paper-radio-button>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="WithLabel">
+ <template>
+ <paper-radio-button id="radio2">Batman</paper-radio-button>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('defaults', function() {
+ var r1;
+
+ setup(function() {
+ r1 = fixture('NoLabel');
+ });
+
+ test('check button via click', function() {
+ r1.addEventListener('click', function() {
+ assert.isTrue(r1.getAttribute('aria-checked'));
+ assert.isTrue(r1.checked);
+ done();
+ });
+ MockInteractions.down(r1);
+ });
+
+ test('toggle button via click', function() {
+ r1.checked = true;
+ r1.addEventListener('click', function() {
+ assert.isFalse(r1.getAttribute('aria-checked'));
+ assert.isFalse(r1.checked);
+ done();
+ });
+ MockInteractions.down(r1);
+ });
+
+ test('disabled button cannot be clicked', function() {
+ r1.disabled = true;
+ r1.addEventListener('click', function() {
+ assert.isTrue(r1.getAttribute('aria-checked'));
+ assert.isTrue(r1.checked);
+ done();
+ });
+ MockInteractions.down(r1);
+ });
+ });
+
+ suite('a11y', function() {
+ var r1;
+ var r2;
+
+ setup(function() {
+ r1 = fixture('NoLabel');
+ r2 = fixture('WithLabel');
+ });
+
+ test('has aria role "radio"', function() {
+ assert.isTrue(r1.getAttribute('role') == 'radio');
+ assert.isTrue(r2.getAttribute('role') == 'radio');
+ });
+
+ test('button with no label has no aria label', function() {
+ assert.isTrue(!r1.getAttribute('aria-label'));
+ });
+
+ test('button with a label sets an aria label', function() {
+ assert.isTrue(r2.getAttribute('aria-label') == "Batman");
+ });
+ });
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-radio-button/test/index.html b/polymer_1.0.4/bower_components/paper-radio-button/test/index.html
new file mode 100644
index 0000000..bc6ad6e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-button/test/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>paper-radio-button tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-radio-group/.bower.json b/polymer_1.0.4/bower_components/paper-radio-group/.bower.json
new file mode 100644
index 0000000..0e82626
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-group/.bower.json
@@ -0,0 +1,45 @@
+{
+ "name": "paper-radio-group",
+ "version": "1.0.3",
+ "description": "A group of material design radio buttons",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "radio",
+ "control"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-radio-group"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-radio-group",
+ "ignore": [],
+ "dependencies": {
+ "iron-selector": "PolymerElements/iron-selector#^1.0.0",
+ "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "paper-radio-button": "PolymerElements/paper-radio-button#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.3",
+ "commit": "84eb004ff1daba9125c96cf19c682fc394ca8321"
+ },
+ "_source": "git://github.com/PolymerElements/paper-radio-group.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-radio-group"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-radio-group/.gitignore b/polymer_1.0.4/bower_components/paper-radio-group/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-group/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-radio-group/README.md b/polymer_1.0.4/bower_components/paper-radio-group/README.md
new file mode 100644
index 0000000..e643ee7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-group/README.md
@@ -0,0 +1,20 @@
+paper-radio-group
+=================
+
+`paper-radio-group` allows user to select only one radio button from a set.
+Checking one radio button that belongs to a radio group unchecks any
+previously checked radio button within the same group. Use
+`selected` to get or set the selected radio button.
+
+Example:
+
+```html
+<paper-radio-group selected="small">
+ <paper-radio-button name="small">Small</paper-radio-button>
+ <paper-radio-button name="medium">Medium</paper-radio-button>
+ <paper-radio-button name="large">Large</paper-radio-button>
+</paper-radio-group>
+```
+
+See <a href="paper-radio-button.html">paper-radio-button</a> for more
+information about `paper-radio-button`.
diff --git a/polymer_1.0.4/bower_components/paper-radio-group/bower.json b/polymer_1.0.4/bower_components/paper-radio-group/bower.json
new file mode 100644
index 0000000..8338727
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-group/bower.json
@@ -0,0 +1,36 @@
+{
+ "name": "paper-radio-group",
+ "version": "1.0.3",
+ "description": "A group of material design radio buttons",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "radio",
+ "control"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-radio-group"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-radio-group",
+ "ignore": [],
+ "dependencies": {
+ "iron-selector": "PolymerElements/iron-selector#^1.0.0",
+ "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "paper-radio-button": "PolymerElements/paper-radio-button#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-radio-group/demo/index.html b/polymer_1.0.4/bower_components/paper-radio-group/demo/index.html
new file mode 100644
index 0000000..ecd23b7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-group/demo/index.html
@@ -0,0 +1,108 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>paper-radio-group demo</title>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../paper-radio-button/paper-radio-button.html">
+ <link rel="import" href="../paper-radio-group.html">
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+
+ <style is="custom-style">
+ .horizontal-section {
+ min-width: 200px;
+ }
+
+ paper-radio-button.blue {
+ --paper-radio-button-checked-color: var(--paper-light-blue-500);
+ --paper-radio-button-checked-ink-color: var(--paper-light-blue-500);
+ --paper-radio-button-unchecked-color: var(--paper-light-blue-900);
+ --paper-radio-button-unchecked-ink-color: var(--paper-light-blue-900);
+ }
+
+ paper-radio-button.red {
+ --paper-radio-button-checked-color: var(--paper-red-500);
+ --paper-radio-button-checked-ink-color: var(--paper-red-500);
+ --paper-radio-button-unchecked-color: var(--paper-red-900);
+ --paper-radio-button-unchecked-ink-color: var(--paper-red-900);
+ }
+
+ paper-radio-button.green {
+ --paper-radio-button-checked-color: var(--paper-green-500);
+ --paper-radio-button-checked-ink-color: var(--paper-green-500);
+ --paper-radio-button-unchecked-color: var(--paper-green-900);
+ --paper-radio-button-unchecked-ink-color: var(--paper-green-900);
+ }
+
+ paper-radio-button.orange {
+ --paper-radio-button-checked-color: var(--paper-orange-500);
+ --paper-radio-button-checked-ink-color: var(--paper-orange-500);
+ --paper-radio-button-unchecked-color: var(--paper-orange-900);
+ --paper-radio-button-unchecked-ink-color: var(--paper-orange-900);
+ }
+
+ paper-radio-button {
+ display: block;
+ }
+
+ </style>
+ </head>
+
+ <body>
+ <div class="horizontal center-justified layout">
+ <div>
+ <h4>Enabled</h4>
+ <div class="horizontal-section">
+ <paper-radio-group selected="c">
+ <paper-radio-button name="o">Oxygen</paper-radio-button>
+ <paper-radio-button name="c">Carbon</paper-radio-button>
+ <paper-radio-button name="h">Hydrogen</paper-radio-button>
+ <paper-radio-button name="n">Nitrogen</paper-radio-button>
+ <paper-radio-button name="ca">Calcium</paper-radio-button>
+ </paper-radio-group>
+ </div>
+ </div>
+
+ <div>
+ <h4>Disabled</h4>
+ <div class="horizontal-section">
+ <paper-radio-group selected="c">
+ <paper-radio-button name="o">Oxygen</paper-radio-button>
+ <paper-radio-button name="c">Carbon</paper-radio-button>
+ <paper-radio-button name="h" disabled>Hydrogen</paper-radio-button>
+ <paper-radio-button name="n" disabled>Nitrogen</paper-radio-button>
+ <paper-radio-button name="ca">Calcium</paper-radio-button>
+ </paper-radio-group>
+ </div>
+ </div>
+
+ <div>
+ <h4>Color</h4>
+ <div class="horizontal-section">
+ <paper-radio-group selected="c">
+ <paper-radio-button name="o" class="blue">Oxygen</paper-radio-button>
+ <paper-radio-button name="c" class="red">Carbon</paper-radio-button>
+ <paper-radio-button name="h" class="orange">Hydrogen</paper-radio-button>
+ <paper-radio-button name="n" class="green">Nitrogen</paper-radio-button>
+ <paper-radio-button name="ca" class="blue">Calcium</paper-radio-button>
+ </paper-radio-group>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-radio-group/hero.svg b/polymer_1.0.4/bower_components/paper-radio-group/hero.svg
new file mode 100755
index 0000000..fc78ba7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-group/hero.svg
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <g>
+ <circle cx="112.5" cy="41" r="8"/>
+ <path d="M112.5,58c-9.4,0-17-7.6-17-17s7.6-17,17-17s17,7.6,17,17S121.9,58,112.5,58z M112.5,26c-8.3,0-15,6.7-15,15s6.7,15,15,15
+ s15-6.7,15-15S120.8,26,112.5,26z"/>
+ <circle cx="112.5" cy="85" r="8"/>
+ <path d="M112.5,102c-9.4,0-17-7.6-17-17s7.6-17,17-17s17,7.6,17,17S121.9,102,112.5,102z M112.5,70c-8.3,0-15,6.7-15,15
+ s6.7,15,15,15s15-6.7,15-15S120.8,70,112.5,70z"/>
+ </g>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-radio-group/index.html b/polymer_1.0.4/bower_components/paper-radio-group/index.html
new file mode 100644
index 0000000..966c717
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-group/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>paper-radio-group</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+ </head>
+ <body>
+
+ <iron-component-page></iron-component-page>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-radio-group/paper-radio-group.html b/polymer_1.0.4/bower_components/paper-radio-group/paper-radio-group.html
new file mode 100644
index 0000000..355db7b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-group/paper-radio-group.html
@@ -0,0 +1,144 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-selector/iron-selectable.html">
+<link rel="import" href="../paper-radio-button/paper-radio-button.html">
+<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
+
+<!--
+`paper-radio-group` allows user to select only one radio button from a set.
+Checking one radio button that belongs to a radio group unchecks any
+previously checked radio button within the same group. Use
+`selected` to get or set the selected radio button.
+
+Example:
+
+ <paper-radio-group selected="small">
+ <paper-radio-button name="small">Small</paper-radio-button>
+ <paper-radio-button name="medium">Medium</paper-radio-button>
+ <paper-radio-button name="large">Large</paper-radio-button>
+ </paper-radio-group>
+
+See <a href="paper-radio-button.html">paper-radio-button</a> for more
+information about `paper-radio-button`.
+
+@group Paper Elements
+@element paper-radio-group
+@hero hero.svg
+@demo demo/index.html
+-->
+
+<dom-module name="paper-radio-group">
+ <style>
+ :host {
+ display: inline-block;
+ }
+
+ :host ::content > * {
+ padding: 12px;
+ }
+ </style>
+
+ <template>
+ <content id="items" select="*"></content>
+ </template>
+
+</dom-module>
+
+<script>
+ Polymer({
+ is: 'paper-radio-group',
+
+ behaviors: [
+ Polymer.IronA11yKeysBehavior,
+ Polymer.IronSelectableBehavior
+ ],
+
+ hostAttributes: {
+ role: 'radiogroup',
+ tabindex: 0
+ },
+
+ properties: {
+ /**
+ * Overriden from Polymer.IronSelectableBehavior
+ */
+ attrForSelected: {
+ type: String,
+ value: 'name'
+ },
+
+ /**
+ * Overriden from Polymer.IronSelectableBehavior
+ */
+ selectedAttribute: {
+ type: String,
+ value: 'checked'
+ }
+ },
+
+ keyBindings: {
+ 'left up': 'selectPrevious',
+ 'right down': 'selectNext',
+ },
+
+ /**
+ * Selects the given value.
+ */
+ select: function(value) {
+ if (this.selected) {
+ var oldItem = this._valueToItem(this.selected);
+
+ // Do not allow unchecking the selected item.
+ if (this.selected == value) {
+ oldItem.checked = true;
+ return;
+ }
+
+ if (oldItem)
+ oldItem.checked = false;
+ }
+
+ Polymer.IronSelectableBehavior.select.apply(this, [value]);
+ this.fire('paper-radio-group-changed');
+ },
+
+ /**
+ * Selects the previous item. If the previous item is disabled, then it is
+ * skipped, and its previous item is selected
+ */
+ selectPrevious: function() {
+ var length = this.items.length;
+ var newIndex = Number(this._valueToIndex(this.selected));
+
+ do {
+ newIndex = (newIndex - 1 + length) % length;
+ } while (this.items[newIndex].disabled)
+
+ this.select(this._indexToValue(newIndex));
+ },
+
+ /**
+ * Selects the next item. If the next item is disabled, then it is
+ * skipped, and its nexy item is selected
+ */
+ selectNext: function() {
+ var length = this.items.length;
+ var newIndex = Number(this._valueToIndex(this.selected));
+
+ do {
+ newIndex = (newIndex + 1 + length) % length;
+ } while (this.items[newIndex].disabled)
+
+ this.select(this._indexToValue(newIndex));
+ },
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-radio-group/test/basic.html b/polymer_1.0.4/bower_components/paper-radio-group/test/basic.html
new file mode 100644
index 0000000..f9a1255
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-group/test/basic.html
@@ -0,0 +1,171 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <title>paper-radio-group basic tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+ <script src="../../iron-test-helpers/mock-interactions.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../paper-radio-group.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="NoSelection">
+ <template>
+ <paper-radio-group>
+ <paper-radio-button name="r1">r1</paper-radio-button>
+ <paper-radio-button name="r2">r2</paper-radio-button>
+ <paper-radio-button name="r3">r3</paper-radio-button>
+ </paper-radio-group>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="WithSelection">
+ <template>
+ <paper-radio-group selected="r1">
+ <paper-radio-button name="r1">r1</paper-radio-button>
+ <paper-radio-button name="r2">r2</paper-radio-button>
+ <paper-radio-button name="r3">r3</paper-radio-button>
+ </paper-radio-group>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="WithDisabled">
+ <template>
+ <paper-radio-group selected="r1">
+ <paper-radio-button name="r1">r1</paper-radio-button>
+ <paper-radio-button name="r2" disabled>r2</paper-radio-button>
+ <paper-radio-button name="r3">r3</paper-radio-button>
+ </paper-radio-group>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('defaults', function() {
+ var LEFT_ARROW = 37;
+ var RIGHT_ARROW = 39;
+
+ test('group can have no selection', function () {
+ var g = fixture('NoSelection');
+ expect(g.selected).to.not.be.ok;
+ var items = g.items;
+ expect(items.length).to.be.equal(3);
+ expect(items[0].checked).to.be.equal(false);
+ expect(items[1].checked).to.be.equal(false);
+ expect(items[2].checked).to.be.equal(false);
+ });
+
+ test('group can have a selection', function () {
+ var g = fixture('WithSelection');
+ expect(g.selected).to.be.ok;
+ var items = g.items;
+ expect(items.length).to.be.equal(3);
+
+ expect(items[0].checked).to.be.equal(true);
+ expect(items[1].checked).to.be.equal(false);
+ expect(items[2].checked).to.be.equal(false);
+ expect(items[0].getAttribute('name')).to.be.equal(g.selected);
+ });
+
+ test('right arrow advances the selection', function (done) {
+ var g = fixture('WithSelection');
+ var items = g.items;
+
+ expect(items[0].checked).to.be.equal(true);
+
+ g.addEventListener('paper-radio-group-changed', function () {
+ expect(items[0].checked).to.be.equal(false);
+ expect(items[1].checked).to.be.equal(true);
+ expect(items[2].checked).to.be.equal(false);
+ done();
+ });
+
+ MockInteractions.keyDownOn(g, RIGHT_ARROW);
+ });
+
+ test('left arrow reverses the selection', function (done) {
+ var g = fixture('WithSelection');
+ var items = g.items;
+
+ expect(items[0].checked).to.be.equal(true);
+
+ g.addEventListener('paper-radio-group-changed', function () {
+ expect(items[0].checked).to.be.equal(false);
+ expect(items[1].checked).to.be.equal(false);
+ expect(items[2].checked).to.be.equal(true);
+ done();
+ });
+ MockInteractions.keyDownOn(g, LEFT_ARROW);
+ });
+
+ test('selection should skip disabled items', function (done) {
+ var g = fixture('WithDisabled');
+ var items = g.items;
+
+ expect(items[0].checked).to.be.equal(true);
+
+ g.addEventListener('paper-radio-group-changed', function () {
+ expect(items[0].checked).to.be.equal(false);
+ expect(items[1].checked).to.be.equal(false);
+ expect(items[2].checked).to.be.equal(true);
+ done();
+ });
+ MockInteractions.keyDownOn(g, RIGHT_ARROW);
+ });
+
+ test('clicking should change the selection', function (done) {
+ var g = fixture('WithSelection');
+ var items = g.items;
+
+ expect(items[0].checked).to.be.equal(true);
+
+ g.addEventListener('paper-radio-group-changed', function () {
+ expect(items[0].checked).to.be.equal(false);
+ expect(items[1].checked).to.be.equal(true);
+ expect(items[2].checked).to.be.equal(false);
+ done();
+ });
+
+ MockInteractions.tap(items[1]);
+ });
+
+ test('clicking the selected item should not deselect', function (done) {
+ var g = fixture('WithSelection');
+ var items = g.items;
+
+ expect(items[0].checked).to.be.equal(true);
+ MockInteractions.tap(items[0]);
+
+ // The selection should not change, but wait for a little bit just
+ // in case it would and an event would be fired.
+ setTimeout(function() {
+ try {
+ expect(items[0].checked).to.be.equal(true);
+ expect(items[1].checked).to.be.equal(false);
+ expect(items[2].checked).to.be.equal(false);
+ done();
+ } catch (e) {
+ done(e)
+ }
+ }, 200);
+ });
+
+ });
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-radio-group/test/index.html b/polymer_1.0.4/bower_components/paper-radio-group/test/index.html
new file mode 100644
index 0000000..acb161f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-radio-group/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>paper-radio-group tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+ </head>
+ <body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-ripple/.bower.json b/polymer_1.0.4/bower_components/paper-ripple/.bower.json
new file mode 100644
index 0000000..0cbf50c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-ripple/.bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "paper-ripple",
+ "version": "1.0.1",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Adds a material design ripple to any container",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "ripple"
+ ],
+ "main": "paper-ripple.html",
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-a11y-keys-behavior": "polymerelements/iron-a11y-keys-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "iron-icons": "polymerelements/iron-icons#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/polymerelements/paper-ripple",
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "af19d904802437c305390bb03415c11661de3d0a"
+ },
+ "_source": "git://github.com/polymerelements/paper-ripple.git",
+ "_target": "^1.0.0",
+ "_originalSource": "polymerelements/paper-ripple"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-ripple/.gitignore b/polymer_1.0.4/bower_components/paper-ripple/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-ripple/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-ripple/README.md b/polymer_1.0.4/bower_components/paper-ripple/README.md
new file mode 100644
index 0000000..b9bde23
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-ripple/README.md
@@ -0,0 +1,65 @@
+paper-ripple
+============
+
+`paper-ripple` provides a visual effect that other paper elements can
+use to simulate a rippling effect emanating from the point of contact. The
+effect can be visualized as a concentric circle with motion.
+
+Example:
+
+```html
+<paper-ripple></paper-ripple>
+```
+
+`paper-ripple` listens to "mousedown" and "mouseup" events so it would display ripple
+effect when touches on it. You can also defeat the default behavior and
+manually route the down and up actions to the ripple element. Note that it is
+important if you call downAction() you will have to make sure to call
+upAction() so that `paper-ripple` would end the animation loop.
+
+Example:
+
+```html
+<paper-ripple id="ripple" style="pointer-events: none;"></paper-ripple>
+...
+<script>
+ downAction: function(e) {
+ this.$.ripple.downAction({x: e.x, y: e.y});
+ },
+ upAction: function(e) {
+ this.$.ripple.upAction();
+ }
+</script>
+```
+
+Styling ripple effect:
+
+Use CSS color property to style the ripple:
+
+```css
+paper-ripple {
+ color: #4285f4;
+}
+```
+
+Note that CSS color property is inherited so it is not required to set it on
+the `paper-ripple` element directly.
+
+
+By default, the ripple is centered on the point of contact. Apply the ``recenters`` attribute to have the ripple grow toward the center of its container.
+
+```html
+<paper-ripple recenters></paper-ripple>
+```
+
+Apply `center` to center the ripple inside its container from the start.
+
+```html
+<paper-ripple center></paper-ripple>
+```
+
+Apply `circle` class to make the rippling effect within a circle.
+
+```html
+<paper-ripple class="circle"></paper-ripple>
+```
diff --git a/polymer_1.0.4/bower_components/paper-ripple/bower.json b/polymer_1.0.4/bower_components/paper-ripple/bower.json
new file mode 100644
index 0000000..b9bb0d9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-ripple/bower.json
@@ -0,0 +1,29 @@
+{
+ "name": "paper-ripple",
+ "version": "1.0.1",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Adds a material design ripple to any container",
+ "private": true,
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "ripple"
+ ],
+ "main": "paper-ripple.html",
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-a11y-keys-behavior": "polymerelements/iron-a11y-keys-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "iron-icons": "polymerelements/iron-icons#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-ripple/demo/index.html b/polymer_1.0.4/bower_components/paper-ripple/demo/index.html
new file mode 100644
index 0000000..365eb3e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-ripple/demo/index.html
@@ -0,0 +1,413 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!doctype html>
+<html>
+<head>
+ <title>paper-ripple demo</title>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../paper-ripple.html">
+ <link rel="import" href="../../paper-styles/classes/typography.html">
+ <link rel="import" href="../../iron-icon/iron-icon.html">
+
+ <style>
+
+ body {
+ background-color: #f9f9f9;
+ font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
+ -webkit-tap-highlight-color: rgba(0,0,0,0);
+ -webkit-touch-callout: none;
+ }
+
+ section {
+ padding: 30px 25px;
+ }
+
+ section > * {
+ margin: 10px
+ }
+
+ /* Button */
+ .button {
+ display: inline-block;
+ position: relative;
+ width: 120px;
+ height: 32px;
+ line-height: 32px;
+ border-radius: 2px;
+ font-size: 0.9em;
+ background-color: #fff;
+ color: #646464;
+ }
+
+ .button > paper-ripple {
+ border-radius: 2px;
+ overflow: hidden;
+ }
+
+ .button.narrow {
+ width: 60px;
+ }
+
+ .button.grey {
+ background-color: #eee;
+ }
+
+ .button.blue {
+ background-color: #4285f4;
+ color: #fff;
+ }
+
+ .button.green {
+ background-color: #0f9d58;
+ color: #fff;
+ }
+
+ .button.raised {
+ transition: box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+ transition-delay: 0.2s;
+ box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
+ }
+
+ .button.raised:active {
+ box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2);
+ transition-delay: 0s;
+ }
+
+ /* Icon Button */
+ .icon-button {
+ position: relative;
+ display: inline-block;
+ width: 56px;
+ height: 56px;
+ }
+
+ .icon-button > iron-icon {
+ margin: 16px;
+ transition: -webkit-transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+ transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+ }
+
+ .icon-button:hover > iron-icon {
+ -webkit-transform: scale(1.2);
+ transform: scale(1.2);
+ }
+
+ .icon-button > paper-ripple {
+ overflow: hidden;
+ color: #646464;
+ }
+
+ .icon-button.red > iron-icon::shadow path {
+ fill: #db4437;
+ }
+
+ .icon-button.red > paper-ripple {
+ color: #db4437;
+ }
+
+ .icon-button.blue > iron-icon::shadow path {
+ fill: #4285f4;
+ }
+
+ .icon-button.blue > paper-ripple {
+ color: #4285f4;
+ }
+
+ /* FAB */
+ .fab {
+ position: relative;
+ display: inline-block;
+ width: 56px;
+ height: 56px;
+ border-radius: 50%;
+ color: #fff;
+ overflow: hidden;
+ transition: box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+ transition-delay: 0.2s;
+ box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
+ }
+
+ .fab.red {
+ background-color: #d23f31;
+ }
+
+ .fab.blue {
+ background-color: #4285f4;
+ }
+
+ .fab.green {
+ background-color: #0f9d58;
+ }
+
+ .fab:active {
+ box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2);
+ transition-delay: 0s;
+ }
+
+ .fab > iron-icon {
+ margin: 16px;
+ }
+
+ .fab > iron-icon::shadow path {
+ fill: #fff;
+ }
+
+ /* Menu */
+ .menu {
+ display: inline-block;
+ width: 180px;
+ background-color: #fff;
+ box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2);
+ }
+
+ .item {
+ position: relative;
+ height: 48px;
+ line-height: 48px;
+ color: #646464;
+ font-size: 0.9em;
+ }
+
+ .menu.blue > .item {
+ color: #4285f4;
+ }
+
+ /* Card, Dialog */
+ .card, .dialog {
+ position: relative;
+ display: inline-block;
+ width: 300px;
+ height: 240px;
+ vertical-align: top;
+ background-color: #fff;
+ box-shadow: 0 12px 15px 0 rgba(0, 0, 0, 0.24);
+ }
+
+ .dialog {
+ box-sizing: border-box;
+ padding: 16px;
+ }
+
+ .dialog > .content {
+ height: 170px;
+ font-size: 0.9em;
+ }
+
+ .dialog > .content > .title {
+ font-size: 1.3em;
+ }
+
+ .dialog > .button {
+ width: 90px;
+ float: right;
+ }
+
+ .card.image {
+ background: url(http://lorempixel.com/300/240/nature/);
+ color: #fff;
+ }
+
+ /* Misc */
+ .center {
+ text-align: center;
+ }
+
+ .label {
+ padding: 0 16px;
+ }
+
+ .label-blue {
+ color: #4285f4;
+ }
+
+ .label-red {
+ color: #d23f31;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <section>
+
+ <div class="button raised">
+ <div class="center" fit>SUBMIT</div>
+ <paper-ripple></paper-ripple>
+ </div>
+
+ <div class="button raised grey">
+ <div class="center" fit>CANCEL</div>
+ <paper-ripple></paper-ripple>
+ </div>
+
+ <div class="button raised blue">
+ <div class="center" fit>COMPOSE</div>
+ <paper-ripple></paper-ripple>
+ </div>
+
+ <div class="button raised green">
+ <div class="center" fit>OK</div>
+ <paper-ripple></paper-ripple>
+ </div>
+
+ </section>
+
+ <section>
+
+ <div class="button raised grey narrow">
+ <div class="center" fit>+1</div>
+ <paper-ripple></paper-ripple>
+ </div>
+
+ <div class="button raised grey narrow label-blue">
+ <div class="center" fit>+1</div>
+ <paper-ripple></paper-ripple>
+ </div>
+
+ <div class="button raised grey narrow label-red">
+ <div class="center" fit>+1</div>
+ <paper-ripple></paper-ripple>
+ </div>
+
+ </section>
+
+ <section>
+
+ <div class="icon-button">
+ <iron-icon icon="menu"></iron-icon>
+ <paper-ripple class="circle" recenters></paper-ripple>
+ </div>
+
+ <div class="icon-button">
+ <iron-icon icon="more-vert"></iron-icon>
+ <paper-ripple class="circle" recenters></paper-ripple>
+ </div>
+
+ <div class="icon-button red">
+ <iron-icon icon="delete"></iron-icon>
+ <paper-ripple class="circle" recenters></paper-ripple>
+ </div>
+
+ <div class="icon-button blue">
+ <iron-icon icon="account-box"></iron-icon>
+ <paper-ripple class="circle" recenters></paper-ripple>
+ </div>
+
+ </section>
+
+ <section>
+
+ <div class="fab red">
+ <iron-icon icon="add"></iron-icon>
+ <paper-ripple class="circle" recenters></paper-ripple>
+ </div>
+
+ <div class="fab blue">
+ <iron-icon icon="mail"></iron-icon>
+ <paper-ripple class="circle" recenters></paper-ripple>
+ </div>
+
+ <div class="fab green">
+ <iron-icon icon="create"></iron-icon>
+ <paper-ripple class="circle" recenters></paper-ripple>
+ </div>
+
+ </section>
+
+ <section>
+
+ <div class="menu">
+
+ <div class="item">
+ <div class="label" fit>Mark as unread</div>
+ <paper-ripple></paper-ripple>
+ </div>
+ <div class="item">
+ <div class="label" fit>Mark as important</div>
+ <paper-ripple></paper-ripple>
+ </div>
+ <div class="item">
+ <div class="label" fit>Add to Tasks</div>
+ <paper-ripple></paper-ripple>
+ </div>
+ <div class="item">
+ <div class="label" fit>Create event</div>
+ <paper-ripple></paper-ripple>
+ </div>
+
+ </div>
+
+ <div class="menu blue">
+
+ <div class="item">
+ <div class="label" fit>Import</div>
+ <paper-ripple></paper-ripple>
+ </div>
+ <div class="item">
+ <div class="label" fit>Export</div>
+ <paper-ripple></paper-ripple>
+ </div>
+ <div class="item">
+ <div class="label" fit>Print</div>
+ <paper-ripple></paper-ripple>
+ </div>
+ <div class="item">
+ <div class="label" fit>Restore contacts</div>
+ <paper-ripple></paper-ripple>
+ </div>
+
+ </div>
+
+ </section>
+
+ <section>
+
+ <div class="dialog">
+
+ <div class="content">
+ <div class="title">Permission</div><br>
+ <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.</div>
+ </div>
+
+ <div class="button label-blue">
+ <div class="center" fit>ACCEPT</div>
+ <paper-ripple></paper-ripple>
+ </div>
+
+ <div class="button">
+ <div class="center" fit>DECLINE</div>
+ <paper-ripple></paper-ripple>
+ </div>
+
+ </div>
+
+ <div class="card">
+ <paper-ripple recenters></paper-ripple>
+ </div>
+
+ <div class="card image">
+
+ <paper-ripple recenters></paper-ripple>
+
+ </div>
+
+ </section>
+
+</body>
+</html>
+
diff --git a/polymer_1.0.4/bower_components/paper-ripple/hero.svg b/polymer_1.0.4/bower_components/paper-ripple/hero.svg
new file mode 100755
index 0000000..f8a872f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-ripple/hero.svg
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <path d="M175,81H49V45h126V81z M51,79h122V47H51V79z"/>
+ <g>
+ <defs>
+ <rect id="SVGID_5_" x="50" y="46" width="124" height="34"/>
+ </defs>
+ <clipPath id="SVGID_2_">
+ <use xlink:href="#SVGID_5_" overflow="visible"/>
+ </clipPath>
+ <circle opacity="0.5" clip-path="url(#SVGID_2_)" cx="84.4" cy="62.7" r="41.9"/>
+ <circle opacity="0.6" clip-path="url(#SVGID_2_)" cx="84.4" cy="62.7" r="26.3"/>
+ <circle opacity="0.6" clip-path="url(#SVGID_2_)" cx="66.4" cy="62.7" r="26.3"/>
+ </g>
+ <circle cx="50" cy="80" r="4"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-ripple/index.html b/polymer_1.0.4/bower_components/paper-ripple/index.html
new file mode 100644
index 0000000..3c371fa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-ripple/index.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <title>paper-ripple</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-ripple/paper-ripple.html b/polymer_1.0.4/bower_components/paper-ripple/paper-ripple.html
new file mode 100644
index 0000000..08d3da1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-ripple/paper-ripple.html
@@ -0,0 +1,716 @@
+<!--
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
+
+<!--
+`paper-ripple` provides a visual effect that other paper elements can
+use to simulate a rippling effect emanating from the point of contact. The
+effect can be visualized as a concentric circle with motion.
+
+Example:
+
+ <paper-ripple></paper-ripple>
+
+`paper-ripple` listens to "mousedown" and "mouseup" events so it would display ripple
+effect when touches on it. You can also defeat the default behavior and
+manually route the down and up actions to the ripple element. Note that it is
+important if you call downAction() you will have to make sure to call
+upAction() so that `paper-ripple` would end the animation loop.
+
+Example:
+
+ <paper-ripple id="ripple" style="pointer-events: none;"></paper-ripple>
+ ...
+ downAction: function(e) {
+ this.$.ripple.downAction({x: e.x, y: e.y});
+ },
+ upAction: function(e) {
+ this.$.ripple.upAction();
+ }
+
+Styling ripple effect:
+
+ Use CSS color property to style the ripple:
+
+ paper-ripple {
+ color: #4285f4;
+ }
+
+ Note that CSS color property is inherited so it is not required to set it on
+ the `paper-ripple` element directly.
+
+By default, the ripple is centered on the point of contact. Apply the `recenters`
+attribute to have the ripple grow toward the center of its container.
+
+ <paper-ripple recenters></paper-ripple>
+
+You can also center the ripple inside its container from the start.
+
+ <paper-ripple center></paper-ripple>
+
+Apply `circle` class to make the rippling effect within a circle.
+
+ <paper-ripple class="circle"></paper-ripple>
+
+@group Paper Elements
+@element paper-ripple
+@hero hero.svg
+@demo demo/index.html
+-->
+
+<dom-module id="paper-ripple">
+
+ <!--
+ Fired when the animation finishes. This is useful if you want to wait until the ripple
+ animation finishes to perform some action.
+
+ @event transitionend
+ @param {Object} detail
+ @param {Object} detail.node The animated node
+ -->
+
+ <style>
+ :host {
+ display: block;
+ position: absolute;
+ border-radius: inherit;
+ overflow: hidden;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ }
+
+ :host([animating]) {
+ /* This resolves a rendering issue in Chrome (as of 40) where the
+ ripple is not properly clipped by its parent (which may have
+ rounded corners). See: http://jsbin.com/temexa/4
+
+ Note: We only apply this style conditionally. Otherwise, the browser
+ will create a new compositing layer for every ripple element on the
+ page, and that would be bad. */
+ -webkit-transform: translate(0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+
+ :host([noink]) {
+ pointer-events: none;
+ }
+
+ #background,
+ #waves,
+ .wave-container,
+ .wave {
+ pointer-events: none;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ }
+
+ #background,
+ .wave {
+ opacity: 0;
+ }
+
+ #waves,
+ .wave {
+ overflow: hidden;
+ }
+
+ .wave-container,
+ .wave {
+ border-radius: 50%;
+ }
+
+ :host(.circle) #background,
+ :host(.circle) #waves {
+ border-radius: 50%;
+ }
+
+ :host(.circle) .wave-container {
+ overflow: hidden;
+ }
+
+ </style>
+ <template>
+ <div id="background"></div>
+ <div id="waves"></div>
+ </template>
+</dom-module>
+<script>
+ (function() {
+ var Utility = {
+ cssColorWithAlpha: function(cssColor, alpha) {
+ var parts = cssColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
+
+ if (typeof alpha == 'undefined') {
+ alpha = 1;
+ }
+
+ if (!parts) {
+ return 'rgba(255, 255, 255, ' + alpha + ')';
+ }
+
+ return 'rgba(' + parts[1] + ', ' + parts[2] + ', ' + parts[3] + ', ' + alpha + ')';
+ },
+
+ distance: function(x1, y1, x2, y2) {
+ var xDelta = (x1 - x2);
+ var yDelta = (y1 - y2);
+
+ return Math.sqrt(xDelta * xDelta + yDelta * yDelta);
+ },
+
+ now: (function() {
+ if (window.performance && window.performance.now) {
+ return window.performance.now.bind(window.performance);
+ }
+
+ return Date.now;
+ })()
+ };
+
+ /**
+ * @param {HTMLElement} element
+ * @constructor
+ */
+ function ElementMetrics(element) {
+ this.element = element;
+ this.width = this.boundingRect.width;
+ this.height = this.boundingRect.height;
+
+ this.size = Math.max(this.width, this.height);
+ }
+
+ ElementMetrics.prototype = {
+ get boundingRect () {
+ return this.element.getBoundingClientRect();
+ },
+
+ furthestCornerDistanceFrom: function(x, y) {
+ var topLeft = Utility.distance(x, y, 0, 0);
+ var topRight = Utility.distance(x, y, this.width, 0);
+ var bottomLeft = Utility.distance(x, y, 0, this.height);
+ var bottomRight = Utility.distance(x, y, this.width, this.height);
+
+ return Math.max(topLeft, topRight, bottomLeft, bottomRight);
+ }
+ };
+
+ /**
+ * @param {HTMLElement} element
+ * @constructor
+ */
+ function Ripple(element) {
+ this.element = element;
+ this.color = window.getComputedStyle(element).color;
+
+ this.wave = document.createElement('div');
+ this.waveContainer = document.createElement('div');
+ this.wave.style.backgroundColor = this.color;
+ this.wave.classList.add('wave');
+ this.waveContainer.classList.add('wave-container');
+ Polymer.dom(this.waveContainer).appendChild(this.wave);
+
+ this.resetInteractionState();
+ }
+
+ Ripple.MAX_RADIUS = 300;
+
+ Ripple.prototype = {
+ get recenters() {
+ return this.element.recenters;
+ },
+
+ get center() {
+ return this.element.center;
+ },
+
+ get mouseDownElapsed() {
+ var elapsed;
+
+ if (!this.mouseDownStart) {
+ return 0;
+ }
+
+ elapsed = Utility.now() - this.mouseDownStart;
+
+ if (this.mouseUpStart) {
+ elapsed -= this.mouseUpElapsed;
+ }
+
+ return elapsed;
+ },
+
+ get mouseUpElapsed() {
+ return this.mouseUpStart ?
+ Utility.now () - this.mouseUpStart : 0;
+ },
+
+ get mouseDownElapsedSeconds() {
+ return this.mouseDownElapsed / 1000;
+ },
+
+ get mouseUpElapsedSeconds() {
+ return this.mouseUpElapsed / 1000;
+ },
+
+ get mouseInteractionSeconds() {
+ return this.mouseDownElapsedSeconds + this.mouseUpElapsedSeconds;
+ },
+
+ get initialOpacity() {
+ return this.element.initialOpacity;
+ },
+
+ get opacityDecayVelocity() {
+ return this.element.opacityDecayVelocity;
+ },
+
+ get radius() {
+ var width2 = this.containerMetrics.width * this.containerMetrics.width;
+ var height2 = this.containerMetrics.height * this.containerMetrics.height;
+ var waveRadius = Math.min(
+ Math.sqrt(width2 + height2),
+ Ripple.MAX_RADIUS
+ ) * 1.1 + 5;
+
+ var duration = 1.1 - 0.2 * (waveRadius / Ripple.MAX_RADIUS);
+ var timeNow = this.mouseInteractionSeconds / duration;
+ var size = waveRadius * (1 - Math.pow(80, -timeNow));
+
+ return Math.abs(size);
+ },
+
+ get opacity() {
+ if (!this.mouseUpStart) {
+ return this.initialOpacity;
+ }
+
+ return Math.max(
+ 0,
+ this.initialOpacity - this.mouseUpElapsedSeconds * this.opacityDecayVelocity
+ );
+ },
+
+ get outerOpacity() {
+ // Linear increase in background opacity, capped at the opacity
+ // of the wavefront (waveOpacity).
+ var outerOpacity = this.mouseUpElapsedSeconds * 0.3;
+ var waveOpacity = this.opacity;
+
+ return Math.max(
+ 0,
+ Math.min(outerOpacity, waveOpacity)
+ );
+ },
+
+ get isOpacityFullyDecayed() {
+ return this.opacity < 0.01 &&
+ this.radius >= Math.min(this.maxRadius, Ripple.MAX_RADIUS);
+ },
+
+ get isRestingAtMaxRadius() {
+ return this.opacity >= this.initialOpacity &&
+ this.radius >= Math.min(this.maxRadius, Ripple.MAX_RADIUS);
+ },
+
+ get isAnimationComplete() {
+ return this.mouseUpStart ?
+ this.isOpacityFullyDecayed : this.isRestingAtMaxRadius;
+ },
+
+ get translationFraction() {
+ return Math.min(
+ 1,
+ this.radius / this.containerMetrics.size * 2 / Math.sqrt(2)
+ );
+ },
+
+ get xNow() {
+ if (this.xEnd) {
+ return this.xStart + this.translationFraction * (this.xEnd - this.xStart);
+ }
+
+ return this.xStart;
+ },
+
+ get yNow() {
+ if (this.yEnd) {
+ return this.yStart + this.translationFraction * (this.yEnd - this.yStart);
+ }
+
+ return this.yStart;
+ },
+
+ get isMouseDown() {
+ return this.mouseDownStart && !this.mouseUpStart;
+ },
+
+ resetInteractionState: function() {
+ this.maxRadius = 0;
+ this.mouseDownStart = 0;
+ this.mouseUpStart = 0;
+
+ this.xStart = 0;
+ this.yStart = 0;
+ this.xEnd = 0;
+ this.yEnd = 0;
+ this.slideDistance = 0;
+
+ this.containerMetrics = new ElementMetrics(this.element);
+ },
+
+ draw: function() {
+ var scale;
+ var translateString;
+ var dx;
+ var dy;
+
+ this.wave.style.opacity = this.opacity;
+
+ scale = this.radius / (this.containerMetrics.size / 2);
+ dx = this.xNow - (this.containerMetrics.width / 2);
+ dy = this.yNow - (this.containerMetrics.height / 2);
+
+
+ // 2d transform for safari because of border-radius and overflow:hidden clipping bug.
+ // https://bugs.webkit.org/show_bug.cgi?id=98538
+ this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' + dy + 'px)';
+ this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy + 'px, 0)';
+ this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')';
+ this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)';
+ },
+
+ /** @param {Event=} event */
+ downAction: function(event) {
+ var xCenter = this.containerMetrics.width / 2;
+ var yCenter = this.containerMetrics.height / 2;
+
+ this.resetInteractionState();
+ this.mouseDownStart = Utility.now();
+
+ if (this.center) {
+ this.xStart = xCenter;
+ this.yStart = yCenter;
+ this.slideDistance = Utility.distance(
+ this.xStart, this.yStart, this.xEnd, this.yEnd
+ );
+ } else {
+ this.xStart = event ?
+ event.detail.x - this.containerMetrics.boundingRect.left :
+ this.containerMetrics.width / 2;
+ this.yStart = event ?
+ event.detail.y - this.containerMetrics.boundingRect.top :
+ this.containerMetrics.height / 2;
+ }
+
+ if (this.recenters) {
+ this.xEnd = xCenter;
+ this.yEnd = yCenter;
+ this.slideDistance = Utility.distance(
+ this.xStart, this.yStart, this.xEnd, this.yEnd
+ );
+ }
+
+ this.maxRadius = this.containerMetrics.furthestCornerDistanceFrom(
+ this.xStart,
+ this.yStart
+ );
+
+ this.waveContainer.style.top =
+ (this.containerMetrics.height - this.containerMetrics.size) / 2 + 'px';
+ this.waveContainer.style.left =
+ (this.containerMetrics.width - this.containerMetrics.size) / 2 + 'px';
+
+ this.waveContainer.style.width = this.containerMetrics.size + 'px';
+ this.waveContainer.style.height = this.containerMetrics.size + 'px';
+ },
+
+ /** @param {Event=} event */
+ upAction: function(event) {
+ if (!this.isMouseDown) {
+ return;
+ }
+
+ this.mouseUpStart = Utility.now();
+ },
+
+ remove: function() {
+ Polymer.dom(this.waveContainer.parentNode).removeChild(
+ this.waveContainer
+ );
+ }
+ };
+
+ Polymer({
+ is: 'paper-ripple',
+
+ behaviors: [
+ Polymer.IronA11yKeysBehavior
+ ],
+
+ properties: {
+ /**
+ * The initial opacity set on the wave.
+ *
+ * @attribute initialOpacity
+ * @type number
+ * @default 0.25
+ */
+ initialOpacity: {
+ type: Number,
+ value: 0.25
+ },
+
+ /**
+ * How fast (opacity per second) the wave fades out.
+ *
+ * @attribute opacityDecayVelocity
+ * @type number
+ * @default 0.8
+ */
+ opacityDecayVelocity: {
+ type: Number,
+ value: 0.8
+ },
+
+ /**
+ * If true, ripples will exhibit a gravitational pull towards
+ * the center of their container as they fade away.
+ *
+ * @attribute recenters
+ * @type boolean
+ * @default false
+ */
+ recenters: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, ripples will center inside its container
+ *
+ * @attribute recenters
+ * @type boolean
+ * @default false
+ */
+ center: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * A list of the visual ripples.
+ *
+ * @attribute ripples
+ * @type Array
+ * @default []
+ */
+ ripples: {
+ type: Array,
+ value: function() {
+ return [];
+ }
+ },
+
+ /**
+ * True when there are visible ripples animating within the
+ * element.
+ */
+ animating: {
+ type: Boolean,
+ readOnly: true,
+ reflectToAttribute: true,
+ value: false
+ },
+
+ /**
+ * If true, the ripple will remain in the "down" state until `holdDown`
+ * is set to false again.
+ */
+ holdDown: {
+ type: Boolean,
+ value: false,
+ observer: '_holdDownChanged'
+ },
+
+ _animating: {
+ type: Boolean
+ },
+
+ _boundAnimate: {
+ type: Function,
+ value: function() {
+ return this.animate.bind(this);
+ }
+ }
+ },
+
+ get target () {
+ var ownerRoot = Polymer.dom(this).getOwnerRoot();
+ var target;
+
+ if (this.parentNode.nodeType == 11) { // DOCUMENT_FRAGMENT_NODE
+ target = ownerRoot.host;
+ } else {
+ target = this.parentNode;
+ }
+
+ return target;
+ },
+
+ keyBindings: {
+ 'enter:keydown': '_onEnterKeydown',
+ 'space:keydown': '_onSpaceKeydown',
+ 'space:keyup': '_onSpaceKeyup'
+ },
+
+ attached: function() {
+ this.listen(this.target, 'up', 'upAction');
+ this.listen(this.target, 'down', 'downAction');
+
+ if (!this.target.hasAttribute('noink')) {
+ this.keyEventTarget = this.target;
+ }
+ },
+
+ get shouldKeepAnimating () {
+ for (var index = 0; index < this.ripples.length; ++index) {
+ if (!this.ripples[index].isAnimationComplete) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ simulatedRipple: function() {
+ this.downAction(null);
+
+ // Please see polymer/polymer#1305
+ this.async(function() {
+ this.upAction();
+ }, 1);
+ },
+
+ /** @param {Event=} event */
+ downAction: function(event) {
+ if (this.holdDown && this.ripples.length > 0) {
+ return;
+ }
+
+ var ripple = this.addRipple();
+
+ ripple.downAction(event);
+
+ if (!this._animating) {
+ this.animate();
+ }
+ },
+
+ /** @param {Event=} event */
+ upAction: function(event) {
+ if (this.holdDown) {
+ return;
+ }
+
+ this.ripples.forEach(function(ripple) {
+ ripple.upAction(event);
+ });
+
+ this.animate();
+ },
+
+ onAnimationComplete: function() {
+ this._animating = false;
+ this.$.background.style.backgroundColor = null;
+ this.fire('transitionend');
+ },
+
+ addRipple: function() {
+ var ripple = new Ripple(this);
+
+ Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);
+ this.$.background.style.backgroundColor = ripple.color;
+ this.ripples.push(ripple);
+
+ this._setAnimating(true);
+
+ return ripple;
+ },
+
+ removeRipple: function(ripple) {
+ var rippleIndex = this.ripples.indexOf(ripple);
+
+ if (rippleIndex < 0) {
+ return;
+ }
+
+ this.ripples.splice(rippleIndex, 1);
+
+ ripple.remove();
+
+ if (!this.ripples.length) {
+ this._setAnimating(false);
+ }
+ },
+
+ animate: function() {
+ var index;
+ var ripple;
+
+ this._animating = true;
+
+ for (index = 0; index < this.ripples.length; ++index) {
+ ripple = this.ripples[index];
+
+ ripple.draw();
+
+ this.$.background.style.opacity = ripple.outerOpacity;
+
+ if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) {
+ this.removeRipple(ripple);
+ }
+ }
+
+ if (!this.shouldKeepAnimating && this.ripples.length === 0) {
+ this.onAnimationComplete();
+ } else {
+ window.requestAnimationFrame(this._boundAnimate);
+ }
+ },
+
+ _onEnterKeydown: function() {
+ this.downAction();
+ this.async(this.upAction, 1);
+ },
+
+ _onSpaceKeydown: function() {
+ this.downAction();
+ },
+
+ _onSpaceKeyup: function() {
+ this.upAction();
+ },
+
+ _holdDownChanged: function(holdDown) {
+ if (holdDown) {
+ this.downAction();
+ } else {
+ this.upAction();
+ }
+ }
+ });
+ })();
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-ripple/test/index.html b/polymer_1.0.4/bower_components/paper-ripple/test/index.html
new file mode 100644
index 0000000..48197c0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-ripple/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'paper-ripple.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-ripple/test/paper-ripple.html b/polymer_1.0.4/bower_components/paper-ripple/test/paper-ripple.html
new file mode 100644
index 0000000..8123206
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-ripple/test/paper-ripple.html
@@ -0,0 +1,166 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="UTF-8">
+ <title>paper-ripple</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../paper-ripple.html">
+
+ <style>
+ #RippleContainer {
+ display: block;
+ position: relative;
+ width: 100px;
+ height: 50px;
+ }
+ </style>
+</head>
+<body>
+ <test-fixture id="TrivialRipple">
+ <template>
+ <div id="RippleContainer">
+ <paper-ripple></paper-ripple>
+ </div>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="CenteringRipple">
+ <template>
+ <div id="RippleContainer">
+ <paper-ripple center></paper-ripple>
+ </div>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="RecenteringRipple">
+ <template>
+ <div id="RippleContainer">
+ <paper-ripple recenters></paper-ripple>
+ </div>
+ </template>
+ </test-fixture>
+
+ <script>
+ function FakeMouseEvent (target, relativeX, relativeX) {
+ var rect = target.getBoundingClientRect();
+
+ return {
+ detail: {
+ x: rect.left + relativeX,
+ y: rect.top + relativeX
+ }
+ };
+ }
+
+ suite('<paper-ripple>', function () {
+ var mouseEvent;
+ var rippleContainer;
+ var ripple;
+
+ suite('when tapped', function () {
+ setup(function () {
+ rippleContainer = fixture('TrivialRipple');
+ ripple = rippleContainer.firstElementChild;
+
+ mouseEvent = new FakeMouseEvent(ripple, 10, 10);
+ });
+
+ test('creates a ripple', function () {
+ expect(ripple.ripples.length).to.be.eql(0);
+ ripple.downAction(mouseEvent);
+ expect(ripple.ripples.length).to.be.eql(1);
+ });
+
+ test('may create multiple ripples that overlap', function () {
+ expect(ripple.ripples.length).to.be.eql(0);
+
+ for (var i = 0; i < 3; ++i) {
+ ripple.downAction(mouseEvent);
+ expect(ripple.ripples.length).to.be.eql(i + 1);
+ }
+ });
+ });
+
+ suite('with the `center` attribute set to true', function () {
+ setup(function () {
+ rippleContainer = fixture('CenteringRipple');
+ ripple = rippleContainer.firstElementChild;
+
+ mouseEvent = new FakeMouseEvent(ripple, 10, 10);
+ });
+
+ test('ripples will center', function (done) {
+ var waveContainerElement;
+ // let's ask the browser what `translate3d(0px, 0px, 0)` will actually look like
+ var div = document.createElement('div');
+ div.style.webkitTransform = 'translate3d(0px, 0px, 0px)';
+ div.style.transform = 'translate3d(0px, 0px, 0)';
+
+ ripple.downAction(mouseEvent);
+
+ waveContainerElement = ripple.ripples[0].waveContainer;
+
+ ripple.upAction(mouseEvent);
+
+ window.requestAnimationFrame(function () {
+ var currentTransform = waveContainerElement.style.transform;
+ try {
+ expect(div.style.transform).to.be.ok;
+ expect(currentTransform).to.be.ok;
+ expect(currentTransform).to.be.eql(div.style.transform);
+
+ done();
+ } catch (e) {
+ done(e);
+ }
+ });
+ });
+ });
+
+ suite('with the `recenters` attribute set to true', function () {
+ setup(function () {
+ rippleContainer = fixture('RecenteringRipple');
+ ripple = rippleContainer.firstElementChild;
+ mouseEvent = new FakeMouseEvent(ripple, 10, 10);
+ });
+ test('ripples will gravitate towards the center', function (done) {
+ var waveContainerElement;
+ var waveTranslateString;
+ ripple.downAction(mouseEvent);
+ waveContainerElement = ripple.ripples[0].waveContainer;
+ waveTranslateString = waveContainerElement.style.transform;
+ ripple.upAction(mouseEvent);
+ window.requestAnimationFrame(function () {
+ try {
+ expect(waveTranslateString).to.be.ok;
+ expect(waveContainerElement.style.transform).to.be.ok;
+ expect(waveContainerElement.style.transform).to.not.be.eql(waveTranslateString);
+ done();
+ } catch (e) {
+ done(e);
+ }
+ });
+ });
+ });
+
+ });
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/.bower.json b/polymer_1.0.4/bower_components/paper-scroll-header-panel/.bower.json
new file mode 100644
index 0000000..422d641
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/.bower.json
@@ -0,0 +1,48 @@
+{
+ "name": "paper-scroll-header-panel",
+ "description": "A header bar with scrolling behavior",
+ "version": "1.0.4",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "private": true,
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "layout",
+ "responsive"
+ ],
+ "main": [
+ "paper-scroll-header-panel.html"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-scroll-header-panel.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "paper-toolbar": "PolymerElements/paper-toolbar#^1.0.0",
+ "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "iron-media-query": "PolymerElements/iron-media-query#^1.0.0",
+ "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+ "paper-icon-button": "PolymerElements/paper-icon-button#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/paper-scroll-header-panel",
+ "_release": "1.0.4",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.4",
+ "commit": "13f17709ce666adf2ab25161bc180816c53e7583"
+ },
+ "_source": "git://github.com/PolymerElements/paper-scroll-header-panel.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-scroll-header-panel"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/.gitignore b/polymer_1.0.4/bower_components/paper-scroll-header-panel/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/README.md b/polymer_1.0.4/bower_components/paper-scroll-header-panel/README.md
new file mode 100644
index 0000000..78f6376
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/README.md
@@ -0,0 +1,56 @@
+paper-scroll-header-panel
+========================
+
+`paper-scroll-header-panel` contains a header section and a content section. The header is initially on the top part of the view but it scrolls away with the rest of the scrollable content. Upon scrolling slightly up at any point, the header scrolls back into view. This saves screen space and allows users to access important controls by easily moving them back to the view.
+
+Important: The `paper-scroll-header-panel` will not display if its parent does not have a height. Using layout classes, you can easily make the `paper-scroll-header-panel` fill the screen
+
+```html
+<body class="fullbleed layout vertical">
+ <paper-scroll-header-panel class="flex">
+ <paper-toolbar>
+ Hello World!
+ </paper-toolbar>
+ </paper-scroll-header-panel>
+</body>
+```
+or, if you would prefer to do it in CSS, just give html, body, and `paper-scroll-header-panel` a height of 100%:
+```css
+html, body {
+ height: 100%;
+ margin: 0;
+}
+paper-scroll-header-panel {
+ height: 100%;
+}
+```
+`paper-scroll-header-panel` works well with `paper-toolbar` but can use any element that represents a header by adding a `paper-header` class to it.
+
+```html
+<paper-scroll-header-panel>
+ <paper-toolbar>Header</paper-toolbar>
+ <div>Content goes here...</div>
+</paper-scroll-header-panel>
+```
+
+### Styling scroll-header-panel:
+
+To change background for toolbar when it is at its full size:
+
+```css
+paper-scroll-header-panel {
+ --paper-scroll-header-panel-full-header: {
+ background-color: red;
+ };
+}
+```
+
+To change the background for toolbar when it is condensed:
+
+```css
+paper-scroll-header-panel {
+ --paper-scroll-header-panel-condensed-header: {
+ background-color: #f4b400;
+ };
+}
+```
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/bower.json b/polymer_1.0.4/bower_components/paper-scroll-header-panel/bower.json
new file mode 100644
index 0000000..007cc44
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/bower.json
@@ -0,0 +1,38 @@
+{
+ "name": "paper-scroll-header-panel",
+ "description": "A header bar with scrolling behavior",
+ "version": "1.0.4",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "private": true,
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "layout",
+ "responsive"
+ ],
+ "main": [
+ "paper-scroll-header-panel.html"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-scroll-header-panel.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "paper-toolbar": "PolymerElements/paper-toolbar#^1.0.0",
+ "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "iron-media-query": "PolymerElements/iron-media-query#^1.0.0",
+ "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+ "paper-icon-button": "PolymerElements/paper-icon-button#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo1.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo1.html
new file mode 100644
index 0000000..b14b0e7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo1.html
@@ -0,0 +1,81 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>paper-scroll-header-panel: demo1</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-scroll-header-panel.html">
+ <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../../paper-icon-button/paper-icon-button.html">
+ <link rel="import" href="sample-content.html">
+
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+
+ <style is="custom-style">
+
+ paper-scroll-header-panel {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-color: var(--paper-grey-200, #eee);;
+ }
+
+ paper-toolbar {
+ background-color: var(--google-blue-500, #4285f4);
+ }
+
+ paper-toolbar iron-icon {
+ margin: 0 8px;
+ }
+
+ paper-toolbar .title {
+ margin: 0 8px;
+ }
+
+ paper-scroll-header-panel .content {
+ padding: 8px;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <paper-scroll-header-panel>
+
+ <paper-toolbar>
+
+ <paper-icon-button icon="arrow-back"></paper-icon-button>
+ <div class="flex title">Title</div>
+ <paper-icon-button icon="search"></paper-icon-button>
+ <paper-icon-button icon="more-vert"></paper-icon-button>
+
+ </paper-toolbar>
+
+ <div class="content">
+
+ <sample-content size="100"></sample-content>
+
+ </div>
+
+ </paper-scroll-header-panel>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo2.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo2.html
new file mode 100644
index 0000000..81c9484
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo2.html
@@ -0,0 +1,78 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>paper-scroll-header-panel: demo2</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-scroll-header-panel.html">
+ <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../../paper-icon-button/paper-icon-button.html">
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+ <link rel="import" href="sample-content.html">
+
+ <style is="custom-style">
+
+ paper-scroll-header-panel {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-color: var(--paper-grey-200, #eee);
+ }
+
+ paper-toolbar {
+ background-color: var(--google-blue-500, #4285f4);
+ }
+
+ paper-toolbar .title {
+ margin-left: 60px;
+ }
+
+ .content {
+ padding: 8px;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <paper-scroll-header-panel condenses>
+
+ <paper-toolbar class="tall">
+
+ <paper-icon-button icon="arrow-back"></paper-icon-button>
+ <div class="flex"></div>
+ <paper-icon-button icon="search"></paper-icon-button>
+ <paper-icon-button icon="more-vert"></paper-icon-button>
+
+ <div class="bottom title">Title</div>
+
+ </paper-toolbar>
+
+ <div class="content">
+
+ <sample-content size="100"></sample-content>
+
+ </div>
+
+ </paper-scroll-header-panel>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo3.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo3.html
new file mode 100644
index 0000000..eb41f1b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo3.html
@@ -0,0 +1,79 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>paper-scroll-header-panel: demo3</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-scroll-header-panel.html">
+ <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../../paper-icon-button/paper-icon-button.html">
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+ <link rel="import" href="sample-content.html">
+
+ <style is="custom-style">
+
+ paper-scroll-header-panel {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-color: var(--paper-grey-200, #eee);
+
+ /* background for toolbar when it is at its full size */
+ --paper-scroll-header-panel-full-header: {
+ background-image: url(images/bg3.jpg);
+ };
+ }
+
+ paper-toolbar {
+ background-color: transparent;
+ }
+
+ paper-toolbar iron-icon {
+ margin: 0 8px;
+ }
+
+ .content {
+ padding: 8px;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <paper-scroll-header-panel condenses no-reveal no-dissolve>
+
+ <paper-toolbar class="tall">
+
+ <div class="flex"></div>
+ <paper-icon-button icon="search"></paper-icon-button>
+
+ </paper-toolbar>
+
+ <div class="content">
+
+ <sample-content size="100"></sample-content>
+
+ </div>
+
+ </paper-scroll-header-panel>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo4.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo4.html
new file mode 100644
index 0000000..9b865d7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo4.html
@@ -0,0 +1,114 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>paper-scroll-header-panel: demo4</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-scroll-header-panel.html">
+ <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../../paper-icon-button/paper-icon-button.html">
+ <link rel="import" href="sample-content.html">
+
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+
+
+ <style is="custom-style">
+
+ paper-scroll-header-panel {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-color: var(--paper-grey-200, #eee);
+
+ /* background for toolbar when it is at its full size */
+ --paper-scroll-header-panel-full-header: {
+ background-image: url(images/bg6.jpg);
+ };
+
+ /* background for toolbar when it is condensed */
+ --paper-scroll-header-panel-condensed-header: {
+ background-color: var(--paper-deep-orange-500, #ff5722);
+ };
+ }
+
+ paper-toolbar.tall {
+ background-color: transparent;
+ }
+
+ paper-toolbar.tall .title {
+ font-size: 40px;
+ margin-left: 60px;
+
+ -webkit-transform-origin: left center;
+ transform-origin: left center;
+
+ /* Issue #15 */
+ isolation: isolate;
+ }
+
+ paper-toolbar.tall iron-icon {
+ margin: 0 8px;
+ }
+
+ .content {
+ padding: 8px;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <paper-scroll-header-panel condenses>
+
+ <paper-toolbar class="tall">
+
+ <paper-icon-button icon="arrow-back"></paper-icon-button>
+ <div class="flex"></div>
+ <paper-icon-button icon="search"></paper-icon-button>
+ <paper-icon-button icon="more-vert"></paper-icon-button>
+ <div class="bottom title">Title</div>
+
+ </paper-toolbar>
+
+ <div class="content">
+
+ <sample-content size="100"></sample-content>
+
+ </div>
+
+ </paper-scroll-header-panel>
+
+ <script>
+
+ // custom transformation: scale header's title
+ var title = document.querySelector('.title');
+ addEventListener('paper-header-transform', function(e) {
+ var d = e.detail;
+ var m = d.height - d.condensedHeight;
+ var scale = Math.max(0.75, (m - d.y) / (m / 0.25) + 0.75);
+
+ Polymer.Base.transform('scale(' + scale + ') translateZ(0)', title);
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo5.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo5.html
new file mode 100644
index 0000000..5cb2048
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo5.html
@@ -0,0 +1,113 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>paper-scroll-header-panel: demo5</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-scroll-header-panel.html">
+ <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../../paper-icon-button/paper-icon-button.html">
+ <link rel="import" href="sample-content.html">
+
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+
+ <style is="custom-style">
+
+ paper-scroll-header-panel {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-color: var(--paper-grey-200, #eee);
+
+ /* background for toolbar when it is at its full size */
+ --paper-scroll-header-panel-full-header: {
+ background-image: url(images/bg6.jpg);
+ };
+
+ /* background for toolbar when it is condensed */
+ --paper-scroll-header-panel-condensed-header: {
+ background-color: var(--google-yellow-500, #f4b400);
+ };
+ }
+
+ paper-toolbar.tall {
+ background-color: transparent;
+ }
+
+ paper-toolbar.tall .title {
+ font-size: 40px;
+ margin-left: 60px;
+
+ -webkit-transform-origin: left center;
+ transform-origin: left center;
+
+ /* Issue #15 */
+ isolation: isolate;
+ }
+
+ paper-toolbar.tall iron-icon {
+ margin: 0 8px;
+ }
+
+ .content {
+ padding: 8px;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <paper-scroll-header-panel condenses>
+
+ <paper-toolbar class="tall">
+
+ <paper-icon-button icon="arrow-back"></paper-icon-button>
+ <div class="flex"></div>
+ <paper-icon-button icon="search"></paper-icon-button>
+ <paper-icon-button icon="more-vert"></paper-icon-button>
+ <div class="bottom title">Title</div>
+
+ </paper-toolbar>
+
+ <div class="content">
+
+ <sample-content size="100"></sample-content>
+
+ </div>
+
+ </paper-scroll-header-panel>
+
+ <script>
+
+ // custom transformation: scale header's title
+ var title = document.querySelector('.title');
+ addEventListener('paper-header-transform', function(e) {
+ var d = e.detail;
+ var m = d.height - d.condensedHeight;
+ var scale = Math.max(0.75, (m - d.y) / (m / 0.25) + 0.75);
+
+ Polymer.Base.transform('scale(' + scale + ') translateZ(0)', title);
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo6.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo6.html
new file mode 100644
index 0000000..c1524ab
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo6.html
@@ -0,0 +1,117 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>paper-scroll-header-panel: demo6</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-scroll-header-panel.html">
+ <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../../paper-icon-button/paper-icon-button.html">
+ <link rel="import" href="sample-content.html">
+
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+
+ <style is="custom-style">
+
+ paper-scroll-header-panel {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-color: var(--paper-grey-200, #eee);
+
+ /* background for toolbar when it is at its full size */
+ --paper-scroll-header-panel-full-header: {
+ background-image: url(images/bg6.jpg);
+ };
+
+ /* background for toolbar when it is condensed */
+ --paper-scroll-header-panel-condensed-header: {
+ background-image: url(images/bg2.jpg);
+ };
+ }
+
+ paper-toolbar.tall {
+ /* custom toolbar height */
+ height: 256px;
+ background-color: transparent;
+ }
+
+ paper-toolbar.tall .title {
+ font-size: 40px;
+ margin-left: 60px;
+
+ -webkit-transform-origin: left center;
+ transform-origin: left center;
+
+ /* Issue #15 */
+ isolation: isolate;
+ }
+
+ paper-toolbar.tall iron-icon {
+ margin: 0 8px;
+ }
+
+ .content {
+ padding: 8px;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <!-- By default condensedHeaderHeight is 1/3 of the header's height. Here
+ we want to set the condensed header's height to be 64px. -->
+ <paper-scroll-header-panel condenses header-height="256" condensed-header-height="64">
+
+ <paper-toolbar class="tall">
+
+ <paper-icon-button icon="arrow-back"></paper-icon-button>
+ <div class="flex"></div>
+ <paper-icon-button icon="search"></paper-icon-button>
+ <paper-icon-button icon="more-vert"></paper-icon-button>
+ <div class="bottom title">Title</div>
+
+ </paper-toolbar>
+
+ <div class="content">
+
+ <sample-content size="100"></sample-content>
+
+ </div>
+
+ </paper-scroll-header-panel>
+
+ <script>
+
+ // custom transformation: scale header's title
+ var title = document.querySelector('.title');
+ addEventListener('paper-header-transform', function(e) {
+ var d = e.detail;
+ var m = d.height - d.condensedHeight;
+ var scale = Math.max(0.75, (m - d.y) / (m / 0.25) + 0.75);
+
+ Polymer.Base.transform('scale(' + scale + ') translateZ(0)', title);
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo7.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo7.html
new file mode 100644
index 0000000..4b5710b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo7.html
@@ -0,0 +1,120 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>paper-scroll-header-panel: demo7</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-scroll-header-panel.html">
+ <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../../paper-icon-button/paper-icon-button.html">
+ <link rel="import" href="../../iron-media-query/iron-media-query.html">
+ <link rel="import" href="sample-content.html">
+
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+
+ <style is="custom-style">
+
+ paper-scroll-header-panel {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-color: var(--paper-grey-200, #eee);
+
+ /* background for toolbar when it is at its full size */
+ --paper-scroll-header-panel-full-header: {
+ background-image: url(images/bg2.jpg);
+ };
+
+ /* background for toolbar when it is condensed */
+ --paper-scroll-header-panel-condensed-header: {
+ background-color: var(--google-yellow-500, #f4b400);
+ };
+ }
+
+ paper-toolbar.tall {
+ background-color: transparent;
+ }
+
+ paper-toolbar.tall .title {
+ font-size: 40px;
+ margin-left: 60px;
+
+ -webkit-transform-origin: left center;
+ transform-origin: left center;
+
+ /* Issue #15 */
+ isolation: isolate;
+ }
+
+ .content {
+ padding: 8px;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <paper-scroll-header-panel condenses>
+
+ <paper-toolbar class="tall">
+
+ <paper-icon-button icon="arrow-back"></paper-icon-button>
+ <div class="flex"></div>
+ <paper-icon-button icon="search"></paper-icon-button>
+ <paper-icon-button icon="more-vert"></paper-icon-button>
+ <div class="bottom indent title">Title</div>
+
+ </paper-toolbar>
+
+ <div class="content">
+
+ <h3>Resize window to toggle between fixed header and scrolled header</h3>
+ <sample-content size="100"></sample-content>
+
+ </div>
+
+ </paper-scroll-header-panel>
+
+ <iron-media-query id="mquery" query="min-width: 600px"></iron-media-query>
+
+ <script>
+
+ // toggle fixed header based on screen size
+ var panel = document.querySelector('paper-scroll-header-panel');
+ var mquery = document.querySelector('#mquery');
+ mquery.addEventListener('query-matches-changed', function() {
+ panel.fixed = mquery.queryMatches;
+ });
+
+ // custom transformation: scale header's title
+ var title = document.querySelector('.title');
+ addEventListener('paper-header-transform', function(e) {
+ var d = e.detail;
+ var m = d.height - d.condensedHeight;
+ var scale = Math.max(0.75, (m - d.y) / (m / 0.25) + 0.75);
+
+ Polymer.Base.transform('scale(' + scale + ') translateZ(0)', title);
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo8.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo8.html
new file mode 100644
index 0000000..ffc24e6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo8.html
@@ -0,0 +1,126 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>paper-scroll-header-panel: demo8</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-scroll-header-panel.html">
+ <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
+ <link rel="import" href="../../iron-icon/iron-icon.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../../paper-icon-button/paper-icon-button.html">
+ <link rel="import" href="sample-content.html">
+
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+
+ <style is="custom-style">
+
+ paper-scroll-header-panel {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-color: var(--paper-grey-200, #eee);
+
+ /* background for toolbar when it is at its full size */
+ --paper-scroll-header-panel-full-header: {
+ background-image: url(images/bg9.jpg);
+ };
+
+ /* background for toolbar when it is condensed */
+ --paper-scroll-header-panel-condensed-header: {
+ background-color: var(--paper-purple-800, #6a1b9a);
+ };
+ }
+
+ paper-toolbar {
+ /* custom toolbar height */
+ height: 256px;
+ background-color: transparent;
+ overflow: visible;
+ }
+
+ paper-toolbar paper-icon-button {
+ margin: 0 8px;
+ }
+
+ .bottom-text {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+
+ font-size: 20px;
+ padding-bottom: 10px;
+ }
+
+ .subtitle {
+ padding-top: 4px;
+ font-size: 16px;
+ color: #ccc;
+ }
+
+ .bookmark {
+ position: absolute;
+ bottom: -24px;
+ right: 24px;
+ fill: #4285f4;
+ height: 48px;
+ width: 48px;
+ }
+
+ .content {
+ padding: 16px 10px 16px 50px;
+ }
+
+ .indent {
+ margin-left: 60px;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <!-- `keepCondensedHeader` makes the condensed header to not scroll away -->
+ <paper-scroll-header-panel condenses keep-condensed-header header-height="256" condensed-header-height="140">
+
+ <paper-toolbar>
+
+ <paper-icon-button icon="arrow-back"></paper-icon-button>
+ <div class="flex"></div>
+ <paper-icon-button icon="thumb-up"></paper-icon-button>
+ <paper-icon-button icon="mail"></paper-icon-button>
+
+ <div class="bottom indent bottom-text" self-end>
+ <div>Lorem ipsum dolor sit amet</div>
+ <div class="subtitle">Iisque perfecto dissentiet cum et</div>
+ </div>
+
+ <iron-icon class="bottom bookmark" icon="bookmark"></iron-icon>
+
+ </paper-toolbar>
+
+ <div class="content">
+
+ <sample-content size="100"></sample-content>
+
+ </div>
+
+ </paper-scroll-header-panel>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo9.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo9.html
new file mode 100644
index 0000000..3c0d691
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/demo9.html
@@ -0,0 +1,108 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>paper-scroll-header-panel: demo9</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-scroll-header-panel.html">
+ <link rel="import" href="../../iron-icon/iron-icon.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../../iron-icons/av-icons.html">
+ <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
+ <link rel="import" href="../../paper-input/paper-input.html">
+ <link rel="import" href="sample-content.html">
+
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+
+
+ <style is="custom-style">
+
+ paper-scroll-header-panel {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-color: var(--paper-grey-200, #eee);
+
+ /* background for toolbar when it is at its full size */
+ --paper-scroll-header-panel-full-header: {
+ background-image: url(images/bg9.jpg);
+ };
+
+ /* background for toolbar when it is condensed */
+ --paper-scroll-header-panel-condensed-header: {
+ background-color: transparent;
+ };
+ }
+
+ paper-toolbar {
+ background-color: transparent;
+ }
+
+ .field {
+ background-color: #fff;
+ border: 1px solid #eee;
+ box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
+ height: 40px;
+ }
+
+ .field iron-icon {
+ color: var(--google-grey-700);
+ fill: var(--google-grey-700);
+ margin: 0 8px;
+ }
+
+ .field input {
+ font-size: 20px;
+ outline: 0;
+ border: none;
+ margin-left: 20px;
+ }
+
+ .content {
+ padding: 8px;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <!-- Instead of using 1/3 of the header's height, we want to manually set the
+ condensed header's height to 64px -->
+ <paper-scroll-header-panel condenses condensed-header-height="64">
+
+ <paper-toolbar class="medium-tall">
+
+ <div class="flex center horizontal layout bottom field">
+ <iron-icon icon="menu"></iron-icon>
+ <input class="flex">
+ <iron-icon icon="av:mic"></iron-icon>
+ </div>
+ </paper-toolbar>
+
+ <div class="content">
+
+ <sample-content size="100"></sample-content>
+
+ </div>
+
+ </paper-scroll-header-panel>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg2.jpg b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg2.jpg
new file mode 100644
index 0000000..9aad0a9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg2.jpg
Binary files differ
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg3.jpg b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg3.jpg
new file mode 100644
index 0000000..5079b4e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg3.jpg
Binary files differ
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg5.jpg b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg5.jpg
new file mode 100644
index 0000000..979ef17
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg5.jpg
Binary files differ
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg6.jpg b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg6.jpg
new file mode 100644
index 0000000..1dec3f3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg6.jpg
Binary files differ
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg9.jpg b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg9.jpg
new file mode 100644
index 0000000..c9a2e65
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/images/bg9.jpg
Binary files differ
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/index.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/index.html
new file mode 100644
index 0000000..f2119b4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/index.html
@@ -0,0 +1,113 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>paper-scroll-header-panel: demo4</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-scroll-header-panel.html">
+ <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../../paper-icon-button/paper-icon-button.html">
+ <link rel="import" href="sample-content.html">
+
+ <link rel="stylesheet" href="../../paper-styles/demo.css">
+
+ <style is="custom-style">
+
+ paper-scroll-header-panel {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-color: var(--paper-grey-200, #eee);
+
+ /* background for toolbar when it is at its full size */
+ --paper-scroll-header-panel-full-header: {
+ background-image: url(images/bg6.jpg);
+ };
+
+ /* background for toolbar when it is condensed */
+ --paper-scroll-header-panel-condensed-header: {
+ background-color: var(--paper-deep-orange-500, #ff5722);
+ };
+ }
+
+ paper-toolbar.tall {
+ background-color: transparent;
+ }
+
+ paper-toolbar.tall .title {
+ font-size: 40px;
+ margin-left: 60px;
+
+ -webkit-transform-origin: left center;
+ transform-origin: left center;
+
+ /* Issue #15 */
+ isolation: isolate;
+ }
+
+ paper-toolbar.tall iron-icon {
+ margin: 0 8px;
+ }
+
+ .content {
+ padding: 8px;
+ }
+
+ </style>
+
+</head>
+<body unresolved>
+
+ <paper-scroll-header-panel condenses>
+
+ <paper-toolbar class="tall">
+
+ <paper-icon-button icon="arrow-back"></paper-icon-button>
+ <div class="flex"></div>
+ <paper-icon-button icon="search"></paper-icon-button>
+ <paper-icon-button icon="more-vert"></paper-icon-button>
+ <div class="bottom title">Title</div>
+
+ </paper-toolbar>
+
+ <div class="content">
+
+ <sample-content size="100"></sample-content>
+
+ </div>
+
+ </paper-scroll-header-panel>
+
+ <script>
+
+ // custom transformation: scale header's title
+ var title = document.querySelector('.title');
+ addEventListener('paper-header-transform', function(e) {
+ var d = e.detail;
+ var m = d.height - d.condensedHeight;
+ var scale = Math.max(0.75, (m - d.y) / (m / 0.25) + 0.75);
+
+ Polymer.Base.transform('scale(' + scale + ') translateZ(0)', title);
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/lorem-ipsum.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/lorem-ipsum.html
new file mode 100644
index 0000000..ed4fb4c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/lorem-ipsum.html
@@ -0,0 +1,42 @@
+<!--
+ @license
+ Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ Code distributed by Google as part of the polymer project is also
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<dom-module name="lorem-ipsum" attributes="paragraphs">
+<script>
+
+ (function() {
+ var strings = [
+ 'Lorem ipsum dolor sit amet, per in nusquam nominavi periculis, sit elit oportere ea, id minim maiestatis incorrupte duo. Dolorum verterem ad ius, his et nullam verterem. Eu alia debet usu, an doming tritani est. Vix ad ponderum petentium suavitate, eum eu tempor populo, graece sententiae constituam vim ex. Cu torquatos reprimique neglegentur nec, voluptua periculis has ut, at eos discere deleniti sensibus.',
+ 'Ut labores minimum atomorum pro. Laudem tibique ut has. No nam ipsum lorem aliquip, accumsan quaerendum ei usu. Maiestatis vituperatoribus qui at, ne suscipit volutpat tractatos nam. Nonumy semper mollis vis an, nam et harum detracto. An pri dolor percipitur, vel maluisset disputationi te.',
+ 'Fugit adolescens vis et, ei graeci forensibus sed. Denique argumentum comprehensam ei vis, id has facete accommodare, quo scripta utroque id. Autem nullam doming ad eam, te nam dicam iriure periculis. Quem vocent veritus eu vis, nam ut hinc idque feugait.',
+ 'Convenire definiebas scriptorem eu cum. Sit dolor dicunt consectetuer no, in vix nisl velit, duo ridens abhorreant delicatissimi ut. Pro ei libris omnium scripserit, natum volumus propriae no eam. Suscipit pericula explicari sed ei, te usu iudicabit forensibus efficiantur. Has quot dicam animal id.',
+ 'Ea duis bonorum nec, falli paulo aliquid ei eum. Cu mei vide viris gloriatur, at populo eripuit sit. Idque molestiae duo ne. Qui id tempor accusamus sadipscing. His odio feugait et. Ne vis vide labitur, eu corpora appareat interpretaris mel.',
+ 'Usu eu novum principes, vel quodsi aliquip ea. Labore mandamus persequeris id mea, has eripuit neglegentur id, illum noster nec in. Ea nam quod quando cetero, per qualisque tincidunt in. Qui ne meliore commune voluptatibus, qui justo labores no. Et dicat cotidieque eos, vis homero legere et, eam timeam nominavi in. Pri dicam option placerat an, cu qui aliquam adipiscing signiferumque. Vis euismod accusamus no, soluta vocibus ei cum.',
+ 'Has at minim mucius aliquam, est id tempor laoreet. Ius officiis convenire ex, in vim iuvaret patrioque similique, veritus detraxit sed ad. Mel no admodum abhorreant cotidieque, et duo possim postulant, consul convenire adolescens cu mel. Duo in decore soleat doming. Fabellas interpretaris eos at. No cum unum novum dicit.',
+ 'Pro saepe pertinax ei, ad pri animal labores suscipiantur. Modus commodo minimum eum te, vero utinam assueverit per eu, zril oportere suscipiantur pri te. Partem percipitur deterruisset ad sea, at eam suas luptatum dissentiunt. No error alienum pro, erant senserit ex mei, pri semper alterum no. Ut habemus menandri vulputate mea. Feugiat verterem ut sed. Dolores maiestatis id per.',
+ 'Detracto suavitate repudiandae no eum. Id adhuc minim soluta nam, novum denique ad eum. At mucius malorum meliore his, te ferri tritani cum, eu mel legendos ocurreret. His te ludus aperiam malorum, mundi nominati deseruisse pro ne, mel discere intellegat in. Vero dissentiunt quo in, vel cu meis maiestatis adversarium. In sit summo nostrum petentium, ea vix amet nullam minimum, ornatus sensibus theophrastus ex nam.',
+ 'Iisque perfecto dissentiet cum et, sit ut quot mandamus, ut vim tibique splendide instructior. Id nam odio natum malorum, tibique copiosae expetenda mel ea. Mea melius malorum ut. Ut nec tollit vocent timeam. Facer nonumy numquam id his, munere salutatus consequuntur eum et, eum cotidieque definitionem signiferumque id. Ei oblique graecis patrioque vis, et probatus dignissim inciderint vel. Sed id paulo erroribus, autem semper accusamus in mel.'
+ ];
+
+ Polymer('lorem-ipsum', {
+
+ paragraphs: 0,
+
+ paragraphsChanged: function() {
+ this.innerHTML = '';
+ for (var i = 0; i < this.paragraphs; i++) {
+ this.innerHTML += '<p>' + strings[Math.floor(Math.random() * strings.length)] + '</p>';
+ }
+ }
+
+ });
+ })();
+
+</script>
+</dom-module>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/sample-content.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/sample-content.html
new file mode 100644
index 0000000..e325fe2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/demo/sample-content.html
@@ -0,0 +1,72 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<dom-module id="sample-content">
+ <template>
+ <div id="content"></div>
+ </template>
+</dom-module>
+
+<script>
+
+ (function() {
+
+ var strings = [
+ 'Lorem ipsum dolor sit amet, per in nusquam nominavi periculis, sit elit oportere ea.',
+ 'Ut labores minimum atomorum pro. Laudem tibique ut has.',
+ 'Fugit adolescens vis et, ei graeci forensibus sed.',
+ 'Convenire definiebas scriptorem eu cum. Sit dolor dicunt consectetuer no.',
+ 'Ea duis bonorum nec, falli paulo aliquid ei eum.',
+ 'Usu eu novum principes, vel quodsi aliquip ea.',
+ 'Has at minim mucius aliquam, est id tempor laoreet.',
+ 'Pro saepe pertinax ei, ad pri animal labores suscipiantur.',
+ 'Detracto suavitate repudiandae no eum. Id adhuc minim soluta nam.',
+ 'Iisque perfecto dissentiet cum et, sit ut quot mandamus, ut vim tibique splendide instructior.',
+ 'Id nam odio natum malorum, tibique copiosae expetenda mel ea.',
+ 'Cu mei vide viris gloriatur, at populo eripuit sit.',
+ 'Modus commodo minimum eum te, vero utinam assueverit per eu.',
+ 'No nam ipsum lorem aliquip, accumsan quaerendum ei usu.'
+ ];
+
+ function randomString() {
+ return strings[Math.floor(Math.random() * strings.length)];
+ }
+
+ function randomLetter() {
+ return String.fromCharCode(65 + Math.floor(Math.random() * 26));
+ }
+
+ Polymer({
+ is: 'sample-content',
+
+ properties: {
+ size: {
+ type: Number,
+ value: 0,
+ observer: 'sizeChanged'
+ }
+ },
+
+ sizeChanged: function() {
+ var html = '';
+ for (var i = 0; i < this.size; i++) {
+ html +=
+ '<div style="border: 1px solid #bebebe; padding: 16px; margin: 16px; border-radius: 5px; background-color: #fff; color: #555;">' +
+ '<div style="display: inline-block; height: 64px; width: 64px; border-radius: 50%; background: #ddd; line-height: 64px; font-size: 30px; color: #666; text-align: center;">'+ randomLetter() + '</div>' +
+ '<div style="font-size: 22px; padding: 8px 0 16px; color: #888;">' + randomString() + '</div>' +
+ '<div style="font-size: 16px; padding-bottom: 8px;">' + randomString() + '</div>' +
+ '<div style="font-size: 12px;">' + randomString() + '</div>' +
+ '<div style="font-size: 12px;">' + randomString() + '</div>' +
+ '</div>';
+ this.$.content.innerHTML = html;
+ }
+ }
+ });
+ })();
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/hero.svg b/polymer_1.0.4/bower_components/paper-scroll-header-panel/hero.svg
new file mode 100755
index 0000000..c130c84
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/hero.svg
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <circle cx="170.6" cy="28.5" r="4"/>
+ <circle cx="170.6" cy="58.5" r="4"/>
+ <rect x="170" y="29" width="2" height="30"/>
+ <path d="M163,102H73V24h90V102z M75,100h86V26H75V100z"/>
+ <rect x="74" y="62" width="88" height="2"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+ <g>
+ <polygon points="74,59.6 74,62.5 74.5,63 77.4,63 "/>
+ <polygon points="74,51.9 74,54.7 82.3,63 85.1,63 "/>
+ <polygon points="74,44.1 74,46.9 90.1,63 92.9,63 "/>
+ <polygon points="74,36.3 74,39.2 97.8,63 100.7,63 "/>
+ <polygon points="74,28.6 74,31.4 105.6,63 108.4,63 "/>
+ <polygon points="78.2,25 75.4,25 113.4,63 116.2,63 "/>
+ <polygon points="86,25 83.1,25 121.1,63 124,63 "/>
+ <polygon points="93.7,25 90.9,25 128.9,63 131.7,63 "/>
+ <polygon points="101.5,25 98.7,25 136.7,63 139.5,63 "/>
+ <polygon points="109.2,25 106.4,25 144.4,63 147.2,63 "/>
+ <polygon points="117,25 114.2,25 152.2,63 155,63 "/>
+ <polygon points="124.8,25 122,25 160,63 162,63 162,62.2 "/>
+ <polygon points="132.5,25 129.7,25 162,57.3 162,54.5 "/>
+ <polygon points="140.3,25 137.5,25 162,49.5 162,46.7 "/>
+ <polygon points="148.1,25 145.2,25 162,41.8 162,38.9 "/>
+ <polygon points="155.8,25 153,25 162,34 162,31.2 "/>
+ <polygon points="162,26.2 162,25 160.8,25 "/>
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/index.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/index.html
new file mode 100644
index 0000000..e2e7712
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/index.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <title>paper-scroll-header-panel</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/paper-scroll-header-panel.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/paper-scroll-header-panel.html
new file mode 100644
index 0000000..ba6b5cd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/paper-scroll-header-panel.html
@@ -0,0 +1,455 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html">
+
+<!--
+`paper-scroll-header-panel` contains a header section and a content section. The
+header is initially on the top part of the view but it scrolls away with the
+rest of the scrollable content. Upon scrolling slightly up at any point, the
+header scrolls back into view. This saves screen space and allows users to
+access important controls by easily moving them back to the view.
+
+__Important:__ The `paper-scroll-header-panel` will not display if its parent does not have a height.
+
+Using [layout classes](https://www.polymer-project.org/1.0/docs/migration.html#layout-attributes) or custom properties, you can easily make the `paper-scroll-header-panel` fill the screen
+
+ <body class="fullbleed layout vertical">
+ <paper-scroll-header-panel class="flex">
+ <paper-toolbar>
+ <div>Hello World!</div>
+ </paper-toolbar>
+ </paper-scroll-header-panel>
+ </body>
+
+or, if you would prefer to do it in CSS, just give `html`, `body`, and `paper-scroll-header-panel` a height of 100%:
+
+ html, body {
+ height: 100%;
+ margin: 0;
+ }
+ paper-scroll-header-panel {
+ height: 100%;
+ }
+
+`paper-scroll-header-panel` works well with `paper-toolbar` but can use any element
+that represents a header by adding a `paper-header` class to it.
+
+ <paper-scroll-header-panel>
+ <paper-toolbar>Header</paper-toolbar>
+ <div>Content goes here...</div>
+ </paper-scroll-header-panel>
+
+Styling scroll-header-panel:
+
+To change background for toolbar when it is at its full size:
+
+ paper-scroll-header-panel {
+ --paper-scroll-header-panel-full-header: {
+ background-color: red;
+ };
+ }
+
+To change the background for toolbar when it is condensed:
+
+ paper-scroll-header-panel {
+ --paper-scroll-header-panel-condensed-header: {
+ background-color: #f4b400;
+ };
+ }
+
+@group Paper Element
+@element paper-scroll-header-panel
+@demo demo/index.html
+@hero hero.svg
+-->
+
+<dom-module id="paper-scroll-header-panel">
+
+ <style>
+ :host {
+ display: block;
+ position: relative;
+ overflow: hidden;
+ }
+
+ #mainContainer {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ -webkit-overflow-scrolling: touch;
+ overflow-x: hidden;
+ overflow-y: auto;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+
+ #headerContainer {
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ }
+
+ .bg-container {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ }
+
+ #headerBg {
+ @apply(--paper-scroll-header-panel-full-header);
+ }
+
+ #condensedHeaderBg {
+ @apply(--paper-scroll-header-panel-condensed-header);
+ }
+
+ #headerBg, #condensedHeaderBg {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-repeat: no-repeat;
+ background-size: cover;
+ background-position: center center;
+ }
+
+ #condensedHeaderBg {
+ opacity: 0;
+ }
+ </style>
+ <template>
+ <div id="mainContainer">
+ <content id="mainContent" select=":not(paper-toolbar):not(.paper-header)"></content>
+ </div>
+ <div id="headerContainer">
+ <div class="bg-container">
+ <div id="condensedHeaderBg"></div>
+ <div id="headerBg"></div>
+ </div>
+ <content id="headerContent" select="paper-toolbar, .paper-header"></content>
+ </div>
+ </template>
+</dom-module>
+
+<script>
+(function() {
+
+ 'use strict';
+
+ Polymer({
+
+ /**
+ * Fired when the content has been scrolled.
+ *
+ * @event content-scroll
+ */
+
+ /**
+ * Fired when the header is transformed.
+ *
+ * @event paper-header-transform
+ */
+
+ is: 'paper-scroll-header-panel',
+
+ behaviors: [
+ Polymer.IronResizableBehavior
+ ],
+
+ properties: {
+
+ /**
+ * If true, the header's height will condense to `condensedHeaderHeight`
+ * as the user scrolls down from the top of the content area.
+ */
+ condenses: {
+ type: Boolean,
+ value: false,
+ observer: '_condensesChanged'
+ },
+
+ /**
+ * If true, no cross-fade transition from one background to another.
+ */
+ noDissolve: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, the header doesn't slide back in when scrolling back up.
+ */
+ noReveal: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, the header is fixed to the top and never moves away.
+ */
+ fixed: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, the condensed header is always shown and does not move away.
+ */
+ keepCondensedHeader: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The height of the header when it is at its full size.
+ *
+ * By default, the height will be measured when it is ready. If the height
+ * changes later the user needs to either set this value to reflect the
+ * new height or invoke `measureHeaderHeight()`.
+ */
+ headerHeight: {
+ type: Number,
+ value: 0
+ },
+
+ /**
+ * The height of the header when it is condensed.
+ *
+ * By default, `condensedHeaderHeight` is 1/3 of `headerHeight` unless
+ * this is specified.
+ */
+ condensedHeaderHeight: {
+ type: Number,
+ value: 0
+ },
+
+ /**
+ * By default, the top part of the header stays when the header is being
+ * condensed. Set this to true if you want the top part of the header
+ * to be scrolled away.
+ */
+ scrollAwayTopbar: {
+ type: Boolean,
+ value: false
+ },
+
+ _headerMargin: {
+ type: Number
+ },
+
+ _prevScrollTop: {
+ type: Number
+ },
+
+ _y: {
+ type: Number
+ }
+
+ },
+
+ observers: [
+ '_setup(_headerMargin, headerHeight, fixed)',
+ '_headerHeightChanged(headerHeight, condensedHeaderHeight)',
+ '_condensedHeaderHeightChanged(headerHeight, condensedHeaderHeight)'
+ ],
+
+ listeners: {
+ 'iron-resize': 'measureHeaderHeight'
+ },
+
+ ready: function() {
+ this.async(this.measureHeaderHeight, 5);
+ this._scrollHandler = this._scroll.bind(this);
+ this.scroller.addEventListener('scroll', this._scrollHandler);
+ },
+
+ detached: function() {
+ this.scroller.removeEventListener('scroll', this._scrollHandler);
+ },
+
+ /**
+ * Returns the header element.
+ *
+ * @property header
+ * @type Object
+ */
+ get header() {
+ return Polymer.dom(this.$.headerContent).getDistributedNodes()[0];
+ },
+
+ /**
+ * Returns the content element.
+ *
+ * @property content
+ * @type Object
+ */
+ get content() {
+ return Polymer.dom(this.$.mainContent).getDistributedNodes()[0];
+ },
+
+ /**
+ * Returns the scrollable element.
+ *
+ * @property scroller
+ * @type Object
+ */
+ get scroller() {
+ return this.$.mainContainer;
+ },
+
+ /**
+ * Invoke this to tell `paper-scroll-header-panel` to re-measure the header's
+ * height.
+ *
+ * @method measureHeaderHeight
+ */
+ measureHeaderHeight: function() {
+ var header = this.header;
+ if (header && header.offsetHeight) {
+ this.headerHeight = header.offsetHeight;
+ }
+ },
+
+ _headerHeightChanged: function() {
+ if (!this.condensedHeaderHeight) {
+ // assume condensedHeaderHeight is 1/3 of the headerHeight
+ this.condensedHeaderHeight = this.headerHeight * 1 / 3;
+ }
+ },
+
+ _condensedHeaderHeightChanged: function() {
+ if (this.headerHeight) {
+ this._headerMargin = this.headerHeight - this.condensedHeaderHeight;
+ }
+ },
+
+ _condensesChanged: function() {
+ if (this.condenses) {
+ this._scroll();
+ } else {
+ // reset transform/opacity set on the header
+ this._condenseHeader(null);
+ }
+ },
+
+ _setup: function() {
+ var s = this.scroller.style;
+ s.paddingTop = this.fixed ? '' : this.headerHeight + 'px';
+
+ s.top = this.fixed ? this.headerHeight + 'px' : '';
+
+ if (this.fixed) {
+ this._transformHeader(null);
+ } else {
+ this._scroll();
+ }
+ },
+
+ _transformHeader: function(y) {
+ var s = this.$.headerContainer.style;
+ this._translateY(s, -y);
+
+ if (this.condenses) {
+ this._condenseHeader(y);
+ }
+
+ this.fire('paper-header-transform', {y: y, height: this.headerHeight,
+ condensedHeight: this.condensedHeaderHeight});
+ },
+
+ _condenseHeader: function(y) {
+ var reset = (y === null);
+
+ // adjust top bar in paper-header so the top bar stays at the top
+ if (!this.scrollAwayTopbar && this.header.$ && this.header.$.topBar) {
+ this._translateY(this.header.$.topBar.style,
+ reset ? null : Math.min(y, this._headerMargin));
+ }
+ // transition header bg
+ var hbg = this.$.headerBg.style;
+ if (!this.noDissolve) {
+ hbg.opacity = reset ? '' : (this._headerMargin - y) / this._headerMargin;
+ }
+ // adjust header bg so it stays at the center
+ this._translateY(hbg, reset ? null : y / 2);
+ // transition condensed header bg
+ if (!this.noDissolve) {
+ var chbg = this.$.condensedHeaderBg.style;
+ chbg = this.$.condensedHeaderBg.style;
+ chbg.opacity = reset ? '' : y / this._headerMargin;
+
+ // adjust condensed header bg so it stays at the center
+ this._translateY(chbg, reset ? null : y / 2);
+ }
+ },
+
+ _translateY: function(s, y) {
+ var t = (y === null) ? '' : 'translate3d(0, ' + y + 'px, 0)';
+ setTransform(s, t);
+ },
+
+ /** @param {Event=} event */
+ _scroll: function(event) {
+ if (!this.header) {
+ return;
+ }
+
+ var sTop = this.scroller.scrollTop;
+
+ this._y = this._y || 0;
+ this._prevScrollTop = this._prevScrollTop || 0;
+
+ var y = Math.min(this.keepCondensedHeader ?
+ this._headerMargin : this.headerHeight, Math.max(0,
+ (this.noReveal ? sTop : this._y + sTop - this._prevScrollTop)));
+
+ if (this.condenses && this._prevScrollTop >= sTop && sTop > this._headerMargin) {
+ y = Math.max(y, this._headerMargin);
+ }
+
+ if (!event || !this.fixed && y !== this._y) {
+ this._transformHeader(y);
+ }
+
+ this._prevScrollTop = Math.max(sTop, 0);
+ this._y = y;
+
+ if (event) {
+ this.fire('content-scroll', {target: this.scroller}, {cancelable: false});
+ }
+ }
+
+ });
+
+ //determine proper transform mechanizm
+ if (document.documentElement.style.transform !== undefined) {
+ var setTransform = function(style, string) {
+ style.transform = string;
+ }
+ } else {
+ var setTransform = function(style, string) {
+ style.webkitTransform = string;
+ }
+ }
+
+})();
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/test/basic.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/test/basic.html
new file mode 100644
index 0000000..9017654
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/test/basic.html
@@ -0,0 +1,112 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>paper-scroll-header-panel test</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../paper-scroll-header-panel.html">
+ <link rel="import" href="../demo/sample-content.html">
+ <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+</head>
+<body>
+
+ <test-fixture id="trivialProgress">
+ <template>
+ <paper-scroll-header-panel>
+ <paper-toolbar>
+ </paper-toolbar>
+ <div class="content">
+ <sample-content size="100"></sample-content>
+ </div>
+ </paper-scroll-header-panel>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('<paper-scroll-header-panel>', function() {
+ var scrollHeaderPanel, toolbar, content;
+
+ setup(function() {
+ scrollHeaderPanel = fixture('trivialProgress');
+
+ toolbar = Polymer.dom(scrollHeaderPanel).querySelector('paper-toolbar');
+ content = Polymer.dom(scrollHeaderPanel).querySelector('.content');
+ });
+
+ test('check default', function() {
+ assert.equal(scrollHeaderPanel.header, toolbar);
+ assert.equal(scrollHeaderPanel.content, content);
+ assert.equal(scrollHeaderPanel.condenses, false);
+ assert.equal(scrollHeaderPanel.noReveal, false);
+ assert.equal(scrollHeaderPanel.fixed, false);
+ assert.typeOf(scrollHeaderPanel.scroller, 'object');
+ assert.equal(scrollHeaderPanel.keepCondensedHeader, false);
+ assert.equal(scrollHeaderPanel.keepCondensedHeader, false);
+ assert.equal(scrollHeaderPanel.headerHeight, toolbar.offsetHeight);
+ assert.equal(scrollHeaderPanel.condensedHeaderHeight, toolbar.offsetHeight * 1 / 3);
+ });
+
+ test('condensation', function(done) {
+ var top1 = toolbar.getBoundingClientRect().top;
+
+ scrollHeaderPanel.condenses = true;
+ scrollHeaderPanel.headerHeight = 150;
+ scrollHeaderPanel.condensedHeaderHeight = 50;
+ scrollHeaderPanel.scroller.scrollTop = 300;
+
+ flush(function() {
+ assert.notEqual(top1, toolbar.getBoundingClientRect().top)
+ done();
+ });
+ });
+
+ test('paper-header-transform event', function(done) {
+ scrollHeaderPanel.condenses = false;
+ scrollHeaderPanel.headerHeight = scrollHeaderPanel.headerHeight || 150;
+
+ scrollHeaderPanel.addEventListener('paper-header-transform', function(e) {
+ assert.typeOf(e.detail.y, 'number');
+ assert.equal(e.detail.height, scrollHeaderPanel.headerHeight);
+ assert.equal(e.detail.condensedHeight, scrollHeaderPanel.condensedHeaderHeight);
+ done();
+ });
+
+ flush(function() {
+ scrollHeaderPanel.scroller.scrollTop = 300;
+ });
+ });
+
+ test('content-scroll event', function(done) {
+ scrollHeaderPanel.condenses = false;
+
+ scrollHeaderPanel.addEventListener('content-scroll', function(e) {
+ assert.equal(e.detail.target, scrollHeaderPanel.scroller);
+ done();
+ });
+
+ flush(function() {
+ scrollHeaderPanel.scroller.scrollTop = 300;
+ });
+ });
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-scroll-header-panel/test/index.html b/polymer_1.0.4/bower_components/paper-scroll-header-panel/test/index.html
new file mode 100644
index 0000000..f07aca9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-scroll-header-panel/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-slider/.bower.json b/polymer_1.0.4/bower_components/paper-slider/.bower.json
new file mode 100644
index 0000000..99e51fb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-slider/.bower.json
@@ -0,0 +1,49 @@
+{
+ "name": "paper-slider",
+ "version": "1.0.2",
+ "description": "A material design-style slider",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "slider",
+ "control"
+ ],
+ "main": [
+ "paper-slider.html"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-slider.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-progress": "PolymerElements/paper-progress#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+ "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
+ "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
+ "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/paper-slider",
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "88ca34f8b87059a2cb187a4a42f5105756a30eff"
+ },
+ "_source": "git://github.com/PolymerElements/paper-slider.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-slider"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-slider/.gitignore b/polymer_1.0.4/bower_components/paper-slider/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-slider/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-slider/README.md b/polymer_1.0.4/bower_components/paper-slider/README.md
new file mode 100644
index 0000000..fd00cd2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-slider/README.md
@@ -0,0 +1,69 @@
+paper-slider
+============
+
+`paper-slider` allows user to select a value from a range of values by
+moving the slider thumb. The interactive nature of the slider makes it a
+great choice for settings that reflect intensity levels, such as volume,
+brightness, or color saturation.
+
+Example:
+
+```html
+<paper-slider></paper-slider>
+```
+
+Use `min` and `max` to specify the slider range. Default is `0` to `100`. For example:
+```html
+<paper-slider min="10" max="200" value="110"></paper-slider>
+```
+
+### Styling slider
+
+To change the slider progress bar color:
+```css
+paper-slider {
+ --paper-slider-active-color: #0f9d58;
+}
+```
+
+To change the slider knob color:
+```css
+paper-slider {
+ --paper-slider-knob-color: #0f9d58;
+}
+```
+
+To change the slider pin color:
+```css
+paper-slider {
+ --paper-slider-pin-color: #0f9d58;
+}
+```
+
+To change the slider pin's font color:
+```css
+paper-slider {
+ --paper-slider-pin-font-color: #0f9d58;
+}
+```
+
+To change the slider secondary progress bar color:
+```css
+paper-slider {
+ --paper-slider-secondary-color: #0f9d58;
+}
+```
+
+To change the slider disabled active color:
+```css
+paper-slider {
+ --paper-slider-disabled-active-color: #ccc;
+}
+```
+
+To change the slider disabled secondary progress bar color:
+```css
+paper-slider {
+ --paper-slider-disabled-secondary-color: #ccc;
+}
+```
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-slider/bower.json b/polymer_1.0.4/bower_components/paper-slider/bower.json
new file mode 100644
index 0000000..127b9ac
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-slider/bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "paper-slider",
+ "version": "1.0.2",
+ "description": "A material design-style slider",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "authors": "The Polymer Authors",
+ "keywords": [
+ "web-components",
+ "polymer",
+ "slider",
+ "control"
+ ],
+ "main": [
+ "paper-slider.html"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-slider.git"
+ },
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "paper-input": "PolymerElements/paper-input#^1.0.0",
+ "paper-progress": "PolymerElements/paper-progress#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+ "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
+ "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
+ "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0",
+ "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-slider/demo/index.html b/polymer_1.0.4/bower_components/paper-slider/demo/index.html
new file mode 100644
index 0000000..e9f2430
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-slider/demo/index.html
@@ -0,0 +1,117 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<!doctype html>
+<html>
+<head>
+ <title>paper-slider demo</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <link rel="stylesheet" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../paper-slider.html">
+
+ <style is="custom-style">
+ body {
+ padding: 40px;
+ }
+
+ paper-slider {
+ width: 100%;
+ }
+
+ paper-slider.blue {
+ --paper-slider-knob-color: var(--paper-light-blue-500);
+ --paper-slider-active-color: var(--paper-light-blue-500);
+ }
+
+ paper-slider.red {
+ --paper-slider-knob-color: var(--paper-red-500);
+ --paper-slider-active-color: var(--paper-red-500);
+ }
+
+ paper-slider.green {
+ --paper-slider-knob-color: var(--paper-green-500);
+ --paper-slider-active-color: var(--paper-green-500);
+ }
+
+ paper-slider.orange {
+ --paper-slider-knob-color: var(--paper-orange-500);
+ --paper-slider-active-color: var(--paper-orange-500);
+ --paper-slider-pin-color: var(--paper-orange-500);
+ }
+
+ #ratingsLabel {
+ padding-left: 12px;
+ color: #a0a0a0;
+ }
+
+ </style>
+
+</head>
+<body unresolved>
+ <div class="vertical center-justified layout">
+ <h4>Default</h4>
+ <div class="vertical-section">
+ <div>Oxygen</div>
+ <paper-slider value="21"></paper-slider><br><br>
+ <div>Argon</div>
+ <paper-slider value="1"></paper-slider><br><br>
+ <div>Hydrogen</div>
+ <paper-slider value="0"></paper-slider><br><br>
+ <div>Nitrogen</div>
+ <paper-slider value="78"></paper-slider><br><br>
+ <div>Sprinkles</div>
+ <paper-slider disabled value="33"></paper-slider>
+ </div>
+
+ <h4>Editable</h4>
+ <div class="vertical-section">
+ <div class="center horizontal layout">
+ <div>R</div>
+ <paper-slider class="red" value="23" max="255" editable></paper-slider>
+ </div>
+ <div class="center horizontal layout">
+ <div>G</div>
+ <paper-slider class="green" value="183" max="255" editable></paper-slider>
+ </div>
+ <div class="center horizontal layout">
+ <div>B</div>
+ <paper-slider class="blue" value="211" max="255" editable></paper-slider>
+ </div>
+ <div class="center horizontal layout">
+ <div>α</div>
+ <paper-slider max="1.0" step="0.01" editable></paper-slider>
+ </div>
+ </div>
+
+ <h4>Labelled pins</h4>
+ <div class="vertical-section">
+ <div>Brightness</div><br>
+ <paper-slider pin value="20" class="orange"></paper-slider>
+ <div>Ratings: <span id="ratingsLabel"></span></div><br>
+ <paper-slider id="ratings" pin snaps max="10" step="1" value="5" class="orange"></paper-slider>
+ </div>
+ </div>
+
+ <script>
+
+ var ratings = document.querySelector('#ratings');
+ ratings.addEventListener('value-change', function() {
+ document.querySelector('#ratingsLabel').textContent = ratings.value;
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-slider/hero.svg b/polymer_1.0.4/bower_components/paper-slider/hero.svg
new file mode 100755
index 0000000..8a518e1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-slider/hero.svg
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <circle cx="110" cy="61" r="4"/>
+ <rect x="61" y="60" width="49" height="2"/>
+ <rect x="110" y="60" width="53" height="2"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-slider/index.html b/polymer_1.0.4/bower_components/paper-slider/index.html
new file mode 100644
index 0000000..6add074
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-slider/index.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <title>paper-slider</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
+
diff --git a/polymer_1.0.4/bower_components/paper-slider/paper-slider.css b/polymer_1.0.4/bower_components/paper-slider/paper-slider.css
new file mode 100644
index 0000000..0fd8682
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-slider/paper-slider.css
@@ -0,0 +1,256 @@
+/**
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+*/
+
+:host {
+ display: inline-block;
+ width: 200px;
+ cursor: default;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+:host(:not([disabled])) #sliderBar::shadow #activeProgress {
+ background-color: var(--paper-slider-active-color, --google-blue-700);
+}
+
+:host(:not([disabled])) #sliderBar::shadow #secondaryProgress {
+ background-color: var(--paper-slider-secondary-color, --google-blue-300);
+}
+
+:host([disabled]) #sliderBar::shadow #activeProgress {
+ background-color: var(--paper-slider-disabled-active-color, --google-grey-500);
+}
+
+:host([disabled]) #sliderBar::shadow #secondaryProgress {
+ background-color: var(--paper-slider-disabled-secondary-color, --google-grey-300);
+}
+
+:host(:focus) {
+ outline: none;
+}
+
+#sliderContainer {
+ position: relative;
+ width: calc(100% - 32px);
+ height: 32px;
+}
+
+#sliderContainer.editable {
+ float: left;
+ width: calc(100% - 72px);
+ margin: 12px 0;
+}
+
+.bar-container {
+ position: absolute;
+ top: 0;
+ left: 16px;
+ height: 100%;
+ width: 100%;
+ overflow: hidden;
+}
+
+.ring > .bar-container {
+ left: 20px;
+ width: calc(100% - 4px);
+ transition: left 0.18s ease, width 0.18s ease;
+}
+
+.ring.expand:not(.pin) > .bar-container {
+ left: 30px;
+ width: calc(100% - 14px);
+}
+
+.ring.expand.dragging > .bar-container {
+ transition: none;
+}
+
+#sliderBar {
+ position: absolute;
+ top: 15px;
+ left: 0;
+ height: 2px;
+ width: 100%;
+ padding: 8px 0;
+ margin: -8px 0;
+}
+
+.ring #sliderBar {
+ left: -4px;
+ width: calc(100% + 4px);
+}
+
+.ring.expand:not(.pin) #sliderBar {
+ left: -14px;
+ width: calc(100% + 14px);
+}
+
+.slider-markers {
+ position: absolute;
+ top: 15px;
+ left: 15px;
+ height: 2px;
+ width: calc(100% + 2px);
+ box-sizing: border-box;
+ pointer-events: none;
+}
+
+.slider-markers::after,
+.slider-marker::after {
+ content: "";
+ display: block;
+ width: 2px;
+ height: 2px;
+ border-radius: 50%;
+ background-color: black;
+}
+
+.transiting #sliderBar::shadow #activeProgress {
+ -webkit-transition: -webkit-transform 0.08s ease;
+ transition: transform 0.08s ease;
+}
+
+#sliderKnob {
+ @apply(--layout-center-justified);
+ @apply(--layout-center);
+ @apply(--layout-horizontal);
+
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 32px;
+ height: 32px;
+}
+
+.transiting > #sliderKnob {
+ transition: left 0.08s ease;
+}
+
+#sliderKnob:focus {
+ outline: none;
+}
+
+#sliderKnob.dragging {
+ transition: none;
+}
+
+.snaps > #sliderKnob.dragging {
+ transition: -webkit-transform 0.08s ease;
+ transition: transform 0.08s ease;
+}
+
+#sliderKnobInner {
+ width: 12px;
+ height: 12px;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ border-radius: 50%;
+ background-color: var(--paper-slider-knob-color, --google-blue-700);
+ transition-property: height, width, background-color, border;
+ transition-duration: 0.1s;
+ transition-timing-function: ease;
+}
+
+.expand:not(.pin) > #sliderKnob > #sliderKnobInner {
+ width: 100%;
+ height: 100%;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+}
+
+.ring > #sliderKnob > #sliderKnobInner {
+ background-color: transparent;
+ border: 2px solid #c8c8c8;
+}
+
+#sliderKnobInner::before {
+ background-color: var(--paper-slider-pin-color, --google-blue-700);
+}
+
+.pin > #sliderKnob > #sliderKnobInner::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 26px;
+ height: 26px;
+ margin-left: 3px;
+ border-radius: 50% 50% 50% 0;
+ -webkit-transform: rotate(-45deg) scale(0) translate(0);
+ transform: rotate(-45deg) scale(0) translate(0);
+}
+
+#sliderKnobInner::before,
+#sliderKnobInner::after {
+ transition: -webkit-transform .2s ease, background-color .18s ease;
+ transition: transform .2s ease, background-color .18s ease;
+}
+
+.pin.ring > #sliderKnob > #sliderKnobInner::before {
+ background-color: #c8c8c8;
+}
+
+.pin.expand > #sliderKnob > #sliderKnobInner::before {
+ -webkit-transform: rotate(-45deg) scale(1) translate(17px, -17px);
+ transform: rotate(-45deg) scale(1) translate(17px, -17px);
+}
+
+.pin > #sliderKnob > #sliderKnobInner::after {
+ content: attr(value);
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 32px;
+ height: 26px;
+ text-align: center;
+ color: var(--paper-slider-font-color, #fff);
+ font-size: 10px;
+ -webkit-transform: scale(0) translate(0);
+ transform: scale(0) translate(0);
+}
+
+.pin.expand > #sliderKnob > #sliderKnobInner::after {
+ -webkit-transform: scale(1) translate(0, -17px);
+ transform: scale(1) translate(0, -17px);
+}
+
+/* editable: paper-input */
+.slider-input {
+ width: 40px;
+ float: right;
+ overflow: hidden;
+}
+
+.slider-input::shadow input {
+ /* FIXME(ffu): should one be able set text-align directly on paper-input? */
+ text-align: center;
+}
+
+/* disabled state */
+#sliderContainer.disabled {
+ pointer-events: none;
+}
+
+.disabled > #sliderKnob > #sliderKnobInner {
+ width: 8px;
+ height: 8px;
+ background-color: var(--paper-slider-disabled-knob-color, --google-grey-500);
+}
+
+.disabled.ring > #sliderKnob > #sliderKnobInner {
+ background-color: transparent;
+}
+
+paper-ripple {
+ color: var(--paper-slider-knob-color, --google-blue-700);
+}
diff --git a/polymer_1.0.4/bower_components/paper-slider/paper-slider.html b/polymer_1.0.4/bower_components/paper-slider/paper-slider.html
new file mode 100644
index 0000000..c51236f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-slider/paper-slider.html
@@ -0,0 +1,516 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+<link rel="import" href="../paper-progress/paper-progress.html">
+<link rel="import" href="../paper-input/paper-input.html">
+<link rel="import" href="../paper-behaviors/paper-inky-focus-behavior.html">
+<link rel="import" href="../paper-ripple/paper-ripple.html">
+<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
+<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
+
+<!--
+`paper-slider` allows user to select a value from a range of values by
+moving the slider thumb. The interactive nature of the slider makes it a
+great choice for settings that reflect intensity levels, such as volume,
+brightness, or color saturation.
+
+Example:
+
+ <paper-slider></paper-slider>
+
+Use `min` and `max` to specify the slider range. Default is 0 to 100.
+
+Example:
+
+ <paper-slider min="10" max="200" value="110"></paper-slider>
+
+Styling slider:
+
+To change the slider progress bar color:
+
+ paper-slider {
+ --paper-slider-active-color: #0f9d58;
+ }
+
+To change the slider knob color:
+
+ paper-slider {
+ --paper-slider-knob-color: #0f9d58;
+ }
+
+To change the slider pin color:
+
+ paper-slider {
+ --paper-slider-pin-color: #0f9d58;
+ }
+
+To change the slider pin's font color:
+
+ paper-slider {
+ --paper-slider-pin-font-color: #0f9d58;
+ }
+
+To change the slider secondary progress bar color:
+
+ paper-slider {
+ --paper-slider-secondary-color: #0f9d58;
+ }
+
+To change the slider disabled active color:
+
+ paper-slider {
+ --paper-slider-disabled-active-color: #ccc;
+ }
+
+To change the slider disabled secondary progress bar color:
+
+ paper-slider {
+ --paper-slider-disabled-secondary-color: #ccc;
+ }
+
+@group Paper Elements
+@element paper-slider
+@demo demo/index.html
+@hero hero.svg
+-->
+
+<dom-module id="paper-slider">
+
+ <link rel="import" type="css" href="paper-slider.css">
+
+ <template>
+ <div id="sliderContainer"
+ class$="[[_getClassNames(disabled, pin, snaps, immediateValue, min, expand, dragging, transiting, editable)]]">
+
+ <div class="bar-container">
+ <paper-progress
+ id="sliderBar"
+ aria-hidden="true"
+ min="[[min]]"
+ max="[[max]]"
+ step="[[step]]"
+ value="[[immediateValue]]"
+ secondary-progress="[[secondaryProgress]]"
+ on-down="_bardown"
+ on-up="_resetKnob"
+ on-track="_onTrack">
+ </paper-progress>
+ </div>
+
+ <template is="dom-if" if="[[snaps]]">
+ <div class="slider-markers horizontal layout">
+ <template is="dom-repeat" items="[[markers]]">
+ <div class="slider-marker flex"></div>
+ </template>
+ </div>
+ </template>
+
+ <div id="sliderKnob"
+ class="center-justified center horizontal layout"
+ on-down="_knobdown"
+ on-up="_resetKnob"
+ on-track="_onTrack"
+ on-transitionend="_knobTransitionEnd">
+ <paper-ripple id="ink" class="circle" center></paper-ripple>
+ <div id="sliderKnobInner" value$="[[immediateValue]]"></div>
+ </div>
+ </div>
+
+ <template is="dom-if" if="[[editable]]">
+ <paper-input
+ id="input"
+ class="slider-input"
+ disabled$="[[disabled]]"
+ on-change="_inputChange">
+ </paper-input>
+ </template>
+ </template>
+
+</dom-module>
+
+<script>
+ /**
+ * Fired when the slider's value changes.
+ *
+ * @event value-change
+ */
+
+ /**
+ * Fired when the slider's immediateValue changes.
+ *
+ * @event immediate-value-change
+ */
+
+ /**
+ * Fired when the slider's value changes due to user interaction.
+ *
+ * Changes to the slider's value due to changes in an underlying
+ * bound variable will not trigger this event.
+ *
+ * @event change
+ */
+
+ Polymer({
+ is: 'paper-slider',
+
+ behaviors: [
+ Polymer.IronRangeBehavior,
+ Polymer.IronA11yKeysBehavior,
+ Polymer.IronFormElementBehavior,
+ Polymer.PaperInkyFocusBehavior
+ ],
+
+ properties: {
+ /**
+ * If true, the slider thumb snaps to tick marks evenly spaced based
+ * on the `step` property value.
+ */
+ snaps: {
+ type: Boolean,
+ value: false,
+ notify: true
+ },
+
+ /**
+ * If true, a pin with numeric value label is shown when the slider thumb
+ * is pressed. Use for settings for which users need to know the exact
+ * value of the setting.
+ */
+ pin: {
+ type: Boolean,
+ value: false,
+ notify: true
+ },
+
+ /**
+ * The number that represents the current secondary progress.
+ */
+ secondaryProgress: {
+ type: Number,
+ value: 0,
+ notify: true,
+ observer: '_secondaryProgressChanged'
+ },
+
+ /**
+ * If true, an input is shown and user can use it to set the slider value.
+ */
+ editable: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The immediate value of the slider. This value is updated while the user
+ * is dragging the slider.
+ */
+ immediateValue: {
+ type: Number,
+ value: 0,
+ readOnly: true
+ },
+
+ /**
+ * The maximum number of markers
+ */
+ maxMarkers: {
+ type: Number,
+ value: 0,
+ notify: true,
+ observer: '_maxMarkersChanged'
+ },
+
+ /**
+ * If true, the knob is expanded
+ */
+ expand: {
+ type: Boolean,
+ value: false,
+ readOnly: true
+ },
+
+ /**
+ * True when the user is dragging the slider.
+ */
+ dragging: {
+ type: Boolean,
+ value: false,
+ readOnly: true
+ },
+
+ transiting: {
+ type: Boolean,
+ value: false,
+ readOnly: true
+ },
+
+ markers: {
+ type: Array,
+ readOnly: true,
+ value: []
+ },
+ },
+
+ observers: [
+ '_updateKnob(value, min, max, snaps, step)',
+ '_minChanged(min)',
+ '_maxChanged(max)',
+ '_valueChanged(value)',
+ '_immediateValueChanged(immediateValue)'
+ ],
+
+ hostAttributes: {
+ role: 'slider',
+ tabindex: 0
+ },
+
+ keyBindings: {
+ 'left down pagedown home': '_decrementKey',
+ 'right up pageup end': '_incrementKey'
+ },
+
+ ready: function() {
+ // issue polymer/polymer#1305
+
+ this.async(function() {
+ this._updateKnob(this.value);
+ this._updateInputValue();
+ }, 1);
+ },
+
+ /**
+ * Increases value by `step` but not above `max`.
+ * @method increment
+ */
+ increment: function() {
+ this.value = this._clampValue(this.value + this.step);
+ },
+
+ /**
+ * Decreases value by `step` but not below `min`.
+ * @method decrement
+ */
+ decrement: function() {
+ this.value = this._clampValue(this.value - this.step);
+ },
+
+ _updateKnob: function(value) {
+ this._positionKnob(this._calcRatio(value));
+ },
+
+ _minChanged: function() {
+ this.setAttribute('aria-valuemin', this.min);
+ },
+
+ _maxChanged: function() {
+ this.setAttribute('aria-valuemax', this.max);
+ },
+
+ _valueChanged: function() {
+ this.setAttribute('aria-valuenow', this.value);
+ this.fire('value-change');
+ },
+
+ _immediateValueChanged: function() {
+ if (this.dragging) {
+ this.fire('immediate-value-change');
+ } else {
+ this.value = this.immediateValue;
+ }
+ this._updateInputValue();
+ },
+
+ _secondaryProgressChanged: function() {
+ this.secondaryProgress = this._clampValue(this.secondaryProgress);
+ },
+
+ _updateInputValue: function() {
+ if (this.editable) {
+ this.$$('#input').value = this.immediateValue.toString();
+ }
+ },
+
+ _expandKnob: function() {
+ this.$.ink.holdDown = false;
+ this._setExpand(true);
+ },
+
+ _resetKnob: function() {
+ this.cancelDebouncer('expandKnob');
+ this._setExpand(false);
+ this.$.ink.hidden = true;
+ },
+
+ _positionKnob: function(ratio) {
+ this._setImmediateValue(this._calcStep(this._calcKnobPosition(ratio)));
+ this._setRatio(this._calcRatio(this.immediateValue));
+
+ this.$.sliderKnob.style.left = (this.ratio * 100) + '%';
+ },
+
+ _inputChange: function() {
+ this.value = this.$$('#input').value;
+ this.fire('change');
+ },
+
+ _calcKnobPosition: function(ratio) {
+ return (this.max - this.min) * ratio + this.min;
+ },
+
+ _onTrack: function(event) {
+ switch (event.detail.state) {
+ case 'start':
+ this._trackStart(event);
+ break;
+ case 'track':
+ this._trackX(event);
+ break;
+ case 'end':
+ this._trackEnd();
+ break;
+ }
+ },
+
+ _trackStart: function(event) {
+ this._w = this.$.sliderBar.offsetWidth;
+ this._x = this.ratio * this._w;
+ this._startx = this._x || 0;
+ this._minx = - this._startx;
+ this._maxx = this._w - this._startx;
+ this.$.sliderKnob.classList.add('dragging');
+
+ this._setDragging(true);
+ },
+
+ _trackX: function(e) {
+ if (!this.dragging) {
+ this._trackStart(e);
+ }
+
+ var dx = Math.min(this._maxx, Math.max(this._minx, e.detail.dx));
+ this._x = this._startx + dx;
+
+ var immediateValue = this._calcStep(this._calcKnobPosition(this._x / this._w));
+ this._setImmediateValue(immediateValue);
+
+ // update knob's position
+ var translateX = ((this._calcRatio(immediateValue) * this._w) - this._startx);
+ this.translate3d(translateX + 'px', 0, 0, this.$.sliderKnob);
+ },
+
+ _trackEnd: function() {
+ var s = this.$.sliderKnob.style;
+
+ this.$.sliderKnob.classList.remove('dragging');
+ this._setDragging(false);
+ this._resetKnob();
+ this.value = this.immediateValue;
+
+ s.transform = s.webkitTransform = '';
+
+ this.fire('change');
+ },
+
+ _knobdown: function(event) {
+ this._expandKnob();
+
+ // cancel selection
+ event.detail.sourceEvent.preventDefault();
+
+ // set the focus manually because we will called prevent default
+ this.focus();
+ },
+
+ _bardown: function(event) {
+ this.$.ink.hidden = true;
+
+ event.preventDefault();
+
+ this._w = this.$.sliderBar.offsetWidth;
+ var rect = this.$.sliderBar.getBoundingClientRect();
+ var ratio = (event.detail.x - rect.left) / this._w;
+ var prevRatio = this.ratio;
+
+ this._setTransiting(true);
+
+ this._positionKnob(ratio);
+
+ this.debounce('expandKnob', this._expandKnob, 60);
+
+ // if the ratio doesn't change, sliderKnob's animation won't start
+ // and `_knobTransitionEnd` won't be called
+ // Therefore, we need to manually update the `transiting` state
+
+ if (prevRatio === this.ratio) {
+ this._setTransiting(false);
+ }
+
+ this.async(function() {
+ this.fire('change');
+ });
+
+ // cancel selection
+ event.detail.sourceEvent.preventDefault();
+ },
+
+ _knobTransitionEnd: function(event) {
+ if (event.target === this.$.sliderKnob) {
+ this._setTransiting(false);
+ }
+ },
+
+ _maxMarkersChanged: function(maxMarkers) {
+ var l = (this.max - this.min) / this.step;
+ if (!this.snaps && l > maxMarkers) {
+ this._setMarkers([]);
+ } else {
+ this._setMarkers(new Array(l));
+ }
+ },
+
+ _getClassNames: function() {
+ var classes = {};
+
+ classes.disabled = this.disabled;
+ classes.pin = this.pin;
+ classes.snaps = this.snaps;
+ classes.ring = this.immediateValue <= this.min;
+ classes.expand = this.expand;
+ classes.dragging = this.dragging;
+ classes.transiting = this.transiting;
+ classes.editable = this.editable;
+
+ return Object.keys(classes).filter(
+ function(className) {
+ return classes[className];
+ }).join(' ');
+ },
+
+ _incrementKey: function(event) {
+ if (event.detail.key === 'end') {
+ this.value = this.max;
+ } else {
+ this.increment();
+ }
+ this.fire('change');
+ },
+
+ _decrementKey: function(event) {
+ if (event.detail.key === 'home') {
+ this.value = this.min;
+ } else {
+ this.decrement();
+ }
+ this.fire('change');
+ }
+ })
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-slider/test/basic.html b/polymer_1.0.4/bower_components/paper-slider/test/basic.html
new file mode 100644
index 0000000..47b6289
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-slider/test/basic.html
@@ -0,0 +1,186 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>paper-slider test</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+ <script src="../../iron-test-helpers/mock-interactions.js"></script>
+
+ <link rel="import" href="../paper-slider.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+</head>
+<body>
+
+
+ <test-fixture id="trivialProgress">
+ <template>
+ <paper-slider></paper-slider>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('<paper-slider>', function() {
+ var slider;
+
+ setup(function() {
+ slider = fixture('trivialProgress');
+ });
+
+ test('check default', function() {
+ assert.equal(slider.min, 0);
+ assert.equal(slider.max, 100);
+ assert.equal(slider.value, 0);
+ });
+
+ test('set value', function(done) {
+ slider.value = 50;
+ flush(function() {
+ assert.equal(slider.value, 50);
+ // test clamp value
+ slider.value = 60.1;
+ flush(function() {
+ assert.equal(slider.value, 60);
+ done();
+ });
+ });
+ });
+
+ test('set max', function(done) {
+ slider.max = 10;
+ slider.value = 11;
+ flush(function() {
+ assert.equal(slider.value, slider.max);
+ done();
+ });
+ });
+
+ test('ratio', function(done) {
+ slider.max = 10;
+ slider.value = 5;
+ flush(function() {
+ assert.equal(slider.ratio, 0.5);
+ done();
+ });
+ });
+
+ test('snaps', function(done) {
+ slider.snaps = true;
+ slider.step = 10;
+ slider.max = 100;
+ slider.value = 25;
+ flush(function() {
+ assert.equal(slider.value, 30);
+
+ slider.value = 51.1;
+
+ flush(function() {
+ assert.equal(slider.value, 50);
+ slider.snaps = false;
+ slider.step = 1;
+ done();
+ });
+ });
+ });
+
+ test('secondary progress', function(done) {
+ slider.max = 10;
+ slider.secondaryProgress = 50;
+ flush(function() {
+ assert.equal(slider.secondaryProgress, slider.max);
+ done();
+ });
+ });
+
+ test('increment', function(done) {
+ slider.min = 0;
+ slider.max = 10;
+ slider.step = 2;
+ slider.value = 0;
+ slider.increment();
+
+ flush(function() {
+ assert.equal(slider.value, slider.step);
+ slider.step = 1;
+ done();
+ });
+ });
+
+ test('decrement', function(done) {
+ slider.min = 0;
+ slider.max = 10;
+ slider.step = 2;
+ slider.value = 8;
+ slider.decrement();
+
+ flush(function() {
+ assert.equal(slider.value, 6);
+ slider.step = 1;
+ done();
+ });
+ });
+
+ test('editable', function(done) {
+ slider.min = 0;
+ slider.max = 10;
+ slider.step = 1;
+ slider.editable = true;
+
+ flush(function() {
+ slider.value = 2;
+ assert.equal(slider.$$('#input').value, slider.value);
+ done();
+ });
+ });
+
+ test('decimal values', function(done) {
+ slider.min = 0;
+ slider.max = 1;
+ slider.value = slider.min;
+ slider.step = 0.1;
+
+ slider.increment();
+
+ flush(function() {
+ assert.equal(slider.value, slider.step);
+ assert.equal(slider.$.sliderBar.value, slider.step);
+ done();
+ });
+ });
+
+ test('snap to the correct value on tapping', function(done) {
+ var cursor = MockInteractions.topLeftOfNode(slider.$.sliderBar);
+ cursor.x += slider.$.sliderBar.getBoundingClientRect().width * 0.9;
+
+ slider.min = 0;
+ slider.max = 2;
+ slider.step = 1;
+ slider.value = 0;
+
+ MockInteractions.down(slider.$.sliderBar, cursor);
+
+ flush(function() {
+ assert.equal(slider.value, slider.max);
+ slider.step = 1;
+ done();
+ });
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-slider/test/index.html b/polymer_1.0.4/bower_components/paper-slider/test/index.html
new file mode 100644
index 0000000..f07aca9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-slider/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-spinner/.bower.json b/polymer_1.0.4/bower_components/paper-spinner/.bower.json
new file mode 100644
index 0000000..1787b05
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-spinner/.bower.json
@@ -0,0 +1,42 @@
+{
+ "name": "paper-spinner",
+ "version": "1.0.1",
+ "description": "A material design spinner",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "spinner",
+ "loading"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-spinner"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-spinner",
+ "ignore": [],
+ "dependencies": {
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "5e2b7412922259c9eed1805d69abb18e433efaad"
+ },
+ "_source": "git://github.com/PolymerElements/paper-spinner.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-spinner"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-spinner/.gitignore b/polymer_1.0.4/bower_components/paper-spinner/.gitignore
new file mode 100644
index 0000000..fbe05fc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-spinner/.gitignore
@@ -0,0 +1 @@
+bower_components/
diff --git a/polymer_1.0.4/bower_components/paper-spinner/README.md b/polymer_1.0.4/bower_components/paper-spinner/README.md
new file mode 100644
index 0000000..c447c8b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-spinner/README.md
@@ -0,0 +1,45 @@
+paper-spinner
+=============
+
+Element providing material design circular spinner.
+
+##### Example
+
+```html
+<paper-spinner active></paper-spinner>
+```
+
+The default spinner cycles between four layers of colors; by default they are
+blue, red, yellow and green. It can be customized so that it uses one color only
+by setting all the layer colors to the same value.
+
+##### Example
+
+```html
+<style is="custom-style">
+ paper-spinner .rainbow {
+ --paper-spinner-layer-1-color: yellow;
+ --paper-spinner-layer-2-color: red;
+ --paper-spinner-layer-3-color: blue;
+ --paper-spinner-layer-4-color: green;
+ }
+
+ paper-spinner .red {
+ --paper-spinner-layer-1-color: red;
+ --paper-spinner-layer-2-color: red;
+ --paper-spinner-layer-3-color: red;
+ --paper-spinner-layer-4-color: red;
+ }
+</style>
+```
+
+Alt attribute should be set to provide adequate context for accessibility. If not provided,
+it defaults to 'loading'.
+Empty alt can be provided to mark the element as decorative if alternative content is provided
+in another form (e.g. a text block following the spinner).
+
+##### Example
+
+```html
+<paper-spinner alt="Loading contacts list" active></paper-spinner>
+```
diff --git a/polymer_1.0.4/bower_components/paper-spinner/bower.json b/polymer_1.0.4/bower_components/paper-spinner/bower.json
new file mode 100644
index 0000000..d27e049
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-spinner/bower.json
@@ -0,0 +1,33 @@
+{
+ "name": "paper-spinner",
+ "version": "1.0.1",
+ "description": "A material design spinner",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "spinner",
+ "loading"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-spinner"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-spinner",
+ "ignore": [],
+ "dependencies": {
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-spinner/demo/index.html b/polymer_1.0.4/bower_components/paper-spinner/demo/index.html
new file mode 100644
index 0000000..15f6385
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-spinner/demo/index.html
@@ -0,0 +1,98 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html lang="en">
+
+ <head>
+ <meta charset="UTF-8">
+ <title>paper-spinner demo</title>
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../paper-spinner.html">
+
+ <style is="custom-style">
+ .horizontal-section {
+ width: 100px;
+ }
+
+ paper-spinner, button {
+ display: block;
+ margin-bottom: 24px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+
+ paper-spinner.blue {
+ --paper-spinner-layer-1-color: var(--paper-light-blue-500);
+ --paper-spinner-layer-2-color: var(--paper-light-blue-500);
+ --paper-spinner-layer-3-color: var(--paper-light-blue-500);
+ --paper-spinner-layer-4-color: var(--paper-light-blue-500);
+ }
+
+ paper-spinner.red {
+ --paper-spinner-layer-1-color: var(--paper-red-500);
+ --paper-spinner-layer-2-color: var(--paper-red-500);
+ --paper-spinner-layer-3-color: var(--paper-red-500);
+ --paper-spinner-layer-4-color: var(--paper-red-500);
+ }
+
+ paper-spinner.orange {
+ --paper-spinner-layer-1-color: var(--paper-orange-500);
+ --paper-spinner-layer-2-color: var(--paper-orange-500);
+ --paper-spinner-layer-3-color: var(--paper-orange-500);
+ --paper-spinner-layer-4-color: var(--paper-orange-500);
+ }
+
+ paper-spinner.green {
+ --paper-spinner-layer-1-color: var(--paper-green-500);
+ --paper-spinner-layer-2-color: var(--paper-green-500);
+ --paper-spinner-layer-3-color: var(--paper-green-500);
+ --paper-spinner-layer-4-color: var(--paper-green-500);
+ }
+ </style>
+ </head>
+
+ <body>
+ <div class="horizontal center-justified layout">
+ <div>
+ <h4>Default</h4>
+ <div class="horizontal-section">
+ <paper-spinner active></paper-spinner>
+ <paper-spinner active></paper-spinner>
+ <paper-spinner active></paper-spinner>
+ <paper-spinner active></paper-spinner>
+ <button onclick="toggle(event)">Toggle</button>
+ </div>
+ </div>
+
+ <div>
+ <h4>Color</h4>
+ <div class="horizontal-section">
+ <paper-spinner class="blue" active></paper-spinner>
+ <paper-spinner class="red" active></paper-spinner>
+ <paper-spinner class="orange" active></paper-spinner>
+ <paper-spinner class="green" active></paper-spinner>
+ <button onclick="toggle(event)">Toggle</button>
+ </div>
+ </div>
+ </div>
+
+ <script>
+ function toggle(event) {
+ var spinners = event.target.parentElement.querySelectorAll('paper-spinner');
+ Array.prototype.forEach.call(spinners, function(spinner) {
+ spinner.active = !spinner.active;
+ });
+ };
+ </script>
+ </body>
+
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-spinner/hero.svg b/polymer_1.0.4/bower_components/paper-spinner/hero.svg
new file mode 100755
index 0000000..034b1f1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-spinner/hero.svg
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <g>
+ <path d="M112.1,92.3c-13.4,0-25.1-9.1-28.4-22l1.9-0.5c3.1,12.1,13.9,20.5,26.4,20.5c15,0,27.3-12.2,27.3-27.3
+ s-12.2-27.3-27.3-27.3c-8.1,0-15.8,3.6-21,9.8l-1.5-1.3c5.6-6.7,13.8-10.6,22.5-10.6c16.1,0,29.3,13.1,29.3,29.3
+ S128.2,92.3,112.1,92.3z"/>
+ <path d="M112.7,87.3c-6.6,0-12.7-2.5-17.3-7.2c-4.6-4.6-7.2-10.8-7.2-17.3c0-6.6,2.5-12.7,7.2-17.3c7.9-7.9,20.2-9.5,29.8-3.8
+ l-1,1.7c-8.8-5.3-20.1-3.8-27.4,3.5c-4.2,4.2-6.6,9.9-6.6,15.9s2.3,11.7,6.6,15.9s9.9,6.6,15.9,6.6c6,0,11.7-2.3,15.9-6.6
+ c4.7-4.7,7.1-11.3,6.5-18l2-0.2c0.7,7.3-1.9,14.4-7.1,19.6C125.4,84.7,119.2,87.3,112.7,87.3z"/>
+ <path d="M112.5,43.5C101.8,43.5,93,52.3,93,63s8.7,19.5,19.5,19.5S132,73.7,132,63S123.2,43.5,112.5,43.5z M119,64h-6v6h-2v-6h-6
+ v-2h6v-6h2v6h6V64z"/>
+ </g>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-spinner/index.html b/polymer_1.0.4/bower_components/paper-spinner/index.html
new file mode 100644
index 0000000..9874334
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-spinner/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>paper-spinner</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+ </head>
+ <body>
+
+ <iron-component-page></iron-component-page>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-spinner/paper-spinner.css b/polymer_1.0.4/bower_components/paper-spinner/paper-spinner.css
new file mode 100644
index 0000000..30c4e7e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-spinner/paper-spinner.css
@@ -0,0 +1,325 @@
+/**
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+
+*/
+/**************************/
+/* STYLES FOR THE SPINNER */
+/**************************/
+
+/*
+ * Constants:
+ * STROKEWIDTH = 3px
+ * ARCSIZE = 270 degrees (amount of circle the arc takes up)
+ * ARCTIME = 1333ms (time it takes to expand and contract arc)
+ * ARCSTARTROT = 216 degrees (how much the start location of the arc
+ * should rotate each time, 216 gives us a
+ * 5 pointed star shape (it's 360/5 * 3).
+ * For a 7 pointed star, we might do
+ * 360/7 * 3 = 154.286)
+ * CONTAINERWIDTH = 28px
+ * SHRINK_TIME = 400ms
+ */
+
+ :host {
+ display: inline-block;
+ position: relative;
+ width: 28px; /* CONTAINERWIDTH */
+ height: 28px; /* CONTAINERWIDTH */
+}
+
+#spinnerContainer {
+ width: 100%;
+ height: 100%;
+}
+
+#spinnerContainer.active {
+ /* duration: 360 * ARCTIME / (ARCSTARTROT + (360-ARCSIZE)) */
+ -webkit-animation: container-rotate 1568ms linear infinite;
+ animation: container-rotate 1568ms linear infinite;
+}
+
+@-webkit-keyframes container-rotate {
+ to { -webkit-transform: rotate(360deg) }
+}
+
+@keyframes container-rotate {
+ to { transform: rotate(360deg) }
+}
+
+.spinner-layer {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ opacity: 0;
+}
+
+.layer-1 {
+ border-color: var(--paper-spinner-layer-1-color, --google-blue-500);
+}
+
+.layer-2 {
+ border-color: var(--paper-spinner-layer-2-color, --google-red-500);
+}
+
+.layer-3 {
+ border-color: var(--paper-spinner-layer-3-color, --google-yellow-500);
+}
+
+.layer-4 {
+ border-color: var(--paper-spinner-layer-4-color, --google-blue-500);
+}
+
+/**
+ * IMPORTANT NOTE ABOUT CSS ANIMATION PROPERTIES (keanulee):
+ *
+ * iOS Safari (tested on iOS 8.1) does not handle animation-delay very well - it doesn't
+ * guarantee that the animation will start _exactly_ after that value. So we avoid using
+ * animation-delay and instead set custom keyframes for each color (as layer-2undant as it
+ * seems).
+ *
+ * We write out each animation in full (instead of separating animation-name,
+ * animation-duration, etc.) because under the polyfill, Safari does not recognize those
+ * specific properties properly, treats them as -webkit-animation, and overrides the
+ * other animation rules. See https://github.com/Polymer/platform/issues/53.
+ */
+.active .spinner-layer.layer-1 {
+ /* durations: 4 * ARCTIME */
+ -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+ animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+}
+
+.active .spinner-layer.layer-2 {
+ /* durations: 4 * ARCTIME */
+ -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+ animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+}
+
+.active .spinner-layer.layer-3 {
+ /* durations: 4 * ARCTIME */
+ -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+ animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+}
+
+.active .spinner-layer.layer-4 {
+ /* durations: 4 * ARCTIME */
+ -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+ animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+}
+
+@-webkit-keyframes fill-unfill-rotate {
+ 12.5% { -webkit-transform: rotate(135deg); } /* 0.5 * ARCSIZE */
+ 25% { -webkit-transform: rotate(270deg); } /* 1 * ARCSIZE */
+ 37.5% { -webkit-transform: rotate(405deg); } /* 1.5 * ARCSIZE */
+ 50% { -webkit-transform: rotate(540deg); } /* 2 * ARCSIZE */
+ 62.5% { -webkit-transform: rotate(675deg); } /* 2.5 * ARCSIZE */
+ 75% { -webkit-transform: rotate(810deg); } /* 3 * ARCSIZE */
+ 87.5% { -webkit-transform: rotate(945deg); } /* 3.5 * ARCSIZE */
+ to { -webkit-transform: rotate(1080deg); } /* 4 * ARCSIZE */
+}
+
+@keyframes fill-unfill-rotate {
+ 12.5% { transform: rotate(135deg); } /* 0.5 * ARCSIZE */
+ 25% { transform: rotate(270deg); } /* 1 * ARCSIZE */
+ 37.5% { transform: rotate(405deg); } /* 1.5 * ARCSIZE */
+ 50% { transform: rotate(540deg); } /* 2 * ARCSIZE */
+ 62.5% { transform: rotate(675deg); } /* 2.5 * ARCSIZE */
+ 75% { transform: rotate(810deg); } /* 3 * ARCSIZE */
+ 87.5% { transform: rotate(945deg); } /* 3.5 * ARCSIZE */
+ to { transform: rotate(1080deg); } /* 4 * ARCSIZE */
+}
+
+/**
+ * HACK: Even though the intention is to have the current .spinner-layer at
+ * `opacity: 1`, we set it to `opacity: 0.99` instead since this forces Chrome
+ * to do proper subpixel rendering for the elements being animated. This is
+ * especially visible in Chrome 39 on Ubuntu 14.04. See:
+ *
+ * - https://github.com/Polymer/paper-spinner/issues/9
+ * - https://code.google.com/p/chromium/issues/detail?id=436255
+ */
+@-webkit-keyframes layer-1-fade-in-out {
+ from { opacity: 0.99; }
+ 25% { opacity: 0.99; }
+ 26% { opacity: 0; }
+ 89% { opacity: 0; }
+ 90% { opacity: 0.99; }
+ 100% { opacity: 0.99; }
+}
+
+@keyframes layer-1-fade-in-out {
+ from { opacity: 0.99; }
+ 25% { opacity: 0.99; }
+ 26% { opacity: 0; }
+ 89% { opacity: 0; }
+ 90% { opacity: 0.99; }
+ 100% { opacity: 0.99; }
+}
+
+@-webkit-keyframes layer-2-fade-in-out {
+ from { opacity: 0; }
+ 15% { opacity: 0; }
+ 25% { opacity: 0.99; }
+ 50% { opacity: 0.99; }
+ 51% { opacity: 0; }
+}
+
+@keyframes layer-2-fade-in-out {
+ from { opacity: 0; }
+ 15% { opacity: 0; }
+ 25% { opacity: 0.99; }
+ 50% { opacity: 0.99; }
+ 51% { opacity: 0; }
+}
+
+@-webkit-keyframes layer-3-fade-in-out {
+ from { opacity: 0; }
+ 40% { opacity: 0; }
+ 50% { opacity: 0.99; }
+ 75% { opacity: 0.99; }
+ 76% { opacity: 0; }
+}
+
+@keyframes layer-3-fade-in-out {
+ from { opacity: 0; }
+ 40% { opacity: 0; }
+ 50% { opacity: 0.99; }
+ 75% { opacity: 0.99; }
+ 76% { opacity: 0; }
+}
+
+@-webkit-keyframes layer-4-fade-in-out {
+ from { opacity: 0; }
+ 65% { opacity: 0; }
+ 75% { opacity: 0.99; }
+ 90% { opacity: 0.99; }
+ 100% { opacity: 0; }
+}
+
+@keyframes layer-4-fade-in-out {
+ from { opacity: 0; }
+ 65% { opacity: 0; }
+ 75% { opacity: 0.99; }
+ 90% { opacity: 0.99; }
+ 100% { opacity: 0; }
+}
+
+/**
+ * Patch the gap that appear between the two adjacent div.circle-clipper while the
+ * spinner is rotating (appears on Chrome 38, Safari 7.1, and IE 11).
+ *
+ * Update: the gap no longer appears on Chrome when .spinner-layer's opacity is 0.99,
+ * but still does on Safari and IE.
+ */
+.gap-patch {
+ position: absolute;
+ box-sizing: border-box;
+ top: 0;
+ left: 45%;
+ width: 10%;
+ height: 100%;
+ overflow: hidden;
+ border-color: inherit;
+}
+
+.gap-patch .circle {
+ width: 1000%;
+ left: -450%;
+}
+
+.circle-clipper {
+ display: inline-block;
+ position: relative;
+ width: 50%;
+ height: 100%;
+ overflow: hidden;
+ border-color: inherit;
+}
+
+.circle-clipper .circle {
+ width: 200%;
+}
+
+.circle {
+ box-sizing: border-box;
+ height: 100%;
+ border-width: 3px; /* STROKEWIDTH */
+ border-style: solid;
+ border-color: inherit;
+ border-bottom-color: transparent !important;
+ border-radius: 50%;
+ -webkit-animation: none;
+ animation: none;
+
+ @apply(--layout-fit);
+}
+
+.circle-clipper.left .circle {
+ border-right-color: transparent !important;
+ -webkit-transform: rotate(129deg);
+ transform: rotate(129deg);
+}
+
+.circle-clipper.right .circle {
+ left: -100%;
+ border-left-color: transparent !important;
+ -webkit-transform: rotate(-129deg);
+ transform: rotate(-129deg);
+}
+
+.active .circle-clipper.left .circle {
+ /* duration: ARCTIME */
+ -webkit-animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+ animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+}
+
+.active .circle-clipper.right .circle {
+ /* duration: ARCTIME */
+ -webkit-animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+ animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
+}
+
+@-webkit-keyframes left-spin {
+ from { -webkit-transform: rotate(130deg); }
+ 50% { -webkit-transform: rotate(-5deg); }
+ to { -webkit-transform: rotate(130deg); }
+}
+
+@keyframes left-spin {
+ from { transform: rotate(130deg); }
+ 50% { transform: rotate(-5deg); }
+ to { transform: rotate(130deg); }
+}
+
+@-webkit-keyframes right-spin {
+ from { -webkit-transform: rotate(-130deg); }
+ 50% { -webkit-transform: rotate(5deg); }
+ to { -webkit-transform: rotate(-130deg); }
+}
+
+@keyframes right-spin {
+ from { transform: rotate(-130deg); }
+ 50% { transform: rotate(5deg); }
+ to { transform: rotate(-130deg); }
+}
+
+#spinnerContainer.cooldown {
+ /* duration: SHRINK_TIME */
+ -webkit-animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0.0, 0.2, 1);
+ animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0.0, 0.2, 1);
+}
+
+@-webkit-keyframes fade-out {
+ from { opacity: 0.99; }
+ to { opacity: 0; }
+}
+
+@keyframes fade-out {
+ from { opacity: 0.99; }
+ to { opacity: 0; }
+}
diff --git a/polymer_1.0.4/bower_components/paper-spinner/paper-spinner.html b/polymer_1.0.4/bower_components/paper-spinner/paper-spinner.html
new file mode 100644
index 0000000..b5503cc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-spinner/paper-spinner.html
@@ -0,0 +1,222 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-styles/color.html">
+<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
+
+<!--
+Element providing material design circular spinner.
+
+ <paper-spinner active></paper-spinner>
+
+The default spinner cycles between four layers of colors; by default they are
+blue, red, yellow and green. It can be customized so that it uses one color only
+by setting all the layer colors to the same value.
+
+### Accessibility
+
+Alt attribute should be set to provide adequate context for accessibility. If not provided,
+it defaults to 'loading'.
+Empty alt can be provided to mark the element as decorative if alternative content is provided
+in another form (e.g. a text block following the spinner).
+
+ <paper-spinner alt="Loading contacts list" active></paper-spinner>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-spinner-layer-1-color` | Color of the first spinner rotation | `--google-blue-500`
+`--paper-spinner-layer-2-color` | Color of the second spinner rotation | `--google-red-500`
+`--paper-spinner-layer-3-color` | Color of the third spinner rotation | `--google-yellow-500`
+`--paper-spinner-layer-4-color` | Color of the fourth spinner rotation | `--google-green-500`
+
+@group Paper Elements
+@element paper-spinner
+@hero hero.svg
+@demo demo/index.html
+-->
+
+<dom-module id="paper-spinner">
+
+ <link rel="import" type="css" href="paper-spinner.css">
+
+ <template>
+
+ <div id="spinnerContainer" class-name="[[_spinnerContainerClassName]]">
+ <div class="spinner-layer layer-1">
+ <div class="circle-clipper left">
+ <div class="circle"></div>
+ </div><div class="gap-patch">
+ <div class="circle"></div>
+ </div><div class="circle-clipper right">
+ <div class="circle"></div>
+ </div>
+ </div>
+
+ <div class="spinner-layer layer-2">
+ <div class="circle-clipper left">
+ <div class="circle"></div>
+ </div><div class="gap-patch">
+ <div class="circle"></div>
+ </div><div class="circle-clipper right">
+ <div class="circle"></div>
+ </div>
+ </div>
+
+ <div class="spinner-layer layer-3">
+ <div class="circle-clipper left">
+ <div class="circle"></div>
+ </div><div class="gap-patch">
+ <div class="circle"></div>
+ </div><div class="circle-clipper right">
+ <div class="circle"></div>
+ </div>
+ </div>
+
+ <div class="spinner-layer layer-4">
+ <div class="circle-clipper left">
+ <div class="circle"></div>
+ </div><div class="gap-patch">
+ <div class="circle"></div>
+ </div><div class="circle-clipper right">
+ <div class="circle"></div>
+ </div>
+ </div>
+ </div>
+
+ </template>
+
+ <script>
+
+ (function() {
+
+ 'use strict';
+
+ function classNames(obj) {
+ var classNames = [];
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key) && obj[key]) {
+ classNames.push(key);
+ }
+ }
+
+ return classNames.join(' ');
+ }
+
+ Polymer({
+
+ is: 'paper-spinner',
+
+ listeners: {
+ 'animationend': 'reset',
+ 'webkitAnimationEnd': 'reset'
+ },
+
+ properties: {
+
+ /**
+ * Displays the spinner.
+ *
+ * @attribute active
+ * @type boolean
+ * @default false
+ */
+ active: {
+ observer: '_activeChanged',
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Alternative text content for accessibility support.
+ * If alt is present, it will add an aria-label whose content matches alt when active.
+ * If alt is not present, it will default to 'loading' as the alt value.
+ *
+ * @attribute alt
+ * @type string
+ * @default 'loading'
+ */
+ alt: {
+ observer: '_altChanged',
+ type: String,
+ value: 'loading'
+ },
+
+ /**
+ * True when the spinner is going from active to inactive. This is represented by a fade
+ * to 0% opacity to the user.
+ */
+ _coolingDown: {
+ type: Boolean,
+ value: false
+ },
+
+ _spinnerContainerClassName: {
+ type: String,
+ computed: '_computeSpinnerContainerClassName(active, _coolingDown)'
+ }
+
+ },
+
+ _computeSpinnerContainerClassName: function(active, _coolingDown) {
+ return classNames({
+ active: active || _coolingDown,
+ cooldown: _coolingDown
+ });
+ },
+
+ ready: function() {
+ // Allow user-provided `aria-label` take preference to any other text alternative.
+ if (this.hasAttribute('aria-label')) {
+ this.alt = this.getAttribute('aria-label');
+ } else {
+ this.setAttribute('aria-label', this.alt);
+ }
+
+ if (!this.active) {
+ this.setAttribute('aria-hidden', 'true');
+ }
+ },
+
+ _activeChanged: function() {
+ if (this.active) {
+ this.removeAttribute('aria-hidden');
+ } else {
+ this._coolingDown = true;
+ this.setAttribute('aria-hidden', 'true');
+ }
+ },
+
+ _altChanged: function() {
+ if (this.alt === '') {
+ this.setAttribute('aria-hidden', 'true');
+ } else {
+ this.removeAttribute('aria-hidden');
+ }
+
+ this.setAttribute('aria-label', this.alt);
+ },
+
+ reset: function() {
+ this.active = false;
+ this._coolingDown = false;
+ }
+
+ });
+
+ }());
+
+ </script>
+
+</dom-module>
diff --git a/polymer_1.0.4/bower_components/paper-spinner/test/index.html b/polymer_1.0.4/bower_components/paper-spinner/test/index.html
new file mode 100644
index 0000000..469b3ee
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-spinner/test/index.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <title>paper-spinner tests</title>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'paper-spinner.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-spinner/test/paper-spinner.html b/polymer_1.0.4/bower_components/paper-spinner/test/paper-spinner.html
new file mode 100644
index 0000000..f270c33
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-spinner/test/paper-spinner.html
@@ -0,0 +1,63 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+
+ <meta charset="UTF-8">
+ <title>paper-spinner basic tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link href="../../test-fixture/test-fixture.html" rel="import">
+ <link href="../paper-spinner.html" rel="import">
+
+ </head>
+ <body>
+
+ <test-fixture id="PaperSpinner">
+ <template>
+ <paper-spinner></paper-spinner>
+ </template>
+ </test-fixture>
+
+ <script>
+ 'use strict';
+
+ suite('<paper-spinner>', function() {
+
+ suite('an accessible paper spinner', function() {
+ var spinner;
+
+ setup(function() {
+ spinner = fixture('PaperSpinner');
+ });
+
+ test('adds an ARIA label when `alt` is supplied', function() {
+ var ALT_TEXT = 'Loading the next gif...';
+
+ spinner.alt = ALT_TEXT;
+ expect(spinner.getAttribute('aria-label')).to.be.eql(ALT_TEXT);
+ });
+
+ test('hides from ARIA when inactive', function() {
+ spinner.active = false;
+ expect(spinner.getAttribute('aria-hidden')).to.be.eql('true');
+ });
+ });
+
+ });
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-styles/.bower.json b/polymer_1.0.4/bower_components/paper-styles/.bower.json
new file mode 100644
index 0000000..60acc89
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/.bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "paper-styles",
+ "version": "1.0.6",
+ "description": "Common (global) styles for Material Design elements.",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-component",
+ "polymer",
+ "style"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-styles.git"
+ },
+ "main": "paper-styles.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/polymerelements/paper-styles/",
+ "ignore": [
+ "/.*"
+ ],
+ "dependencies": {
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.6",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.6",
+ "commit": "bc929064ab5f782c75fadd401841cbabac2b9a74"
+ },
+ "_source": "git://github.com/PolymerElements/paper-styles.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-styles"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-styles/README.md b/polymer_1.0.4/bower_components/paper-styles/README.md
new file mode 100644
index 0000000..82a7847
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/README.md
@@ -0,0 +1,3 @@
+# paper-styles
+
+Material design CSS styles.
diff --git a/polymer_1.0.4/bower_components/paper-styles/bower.json b/polymer_1.0.4/bower_components/paper-styles/bower.json
new file mode 100644
index 0000000..c9a5f92
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/bower.json
@@ -0,0 +1,30 @@
+{
+ "name": "paper-styles",
+ "version": "1.0.6",
+ "description": "Common (global) styles for Material Design elements.",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-component",
+ "polymer",
+ "style"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-styles.git"
+ },
+ "main": "paper-styles.html",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/polymerelements/paper-styles/",
+ "ignore": [
+ "/.*"
+ ],
+ "dependencies": {
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-styles/classes/global.html b/polymer_1.0.4/bower_components/paper-styles/classes/global.html
new file mode 100644
index 0000000..6f0d5dd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/classes/global.html
@@ -0,0 +1,96 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../paper-styles-classes.html">
+
+<!--
+A set of base styles that are applied to the document and standard elements that
+match the Material Design spec.
+-->
+<style>
+/*
+Note that there is a lot of style duplication here. The hope is that the Polymer
+0.8 styling solution will allow for inheritance of properties so that we can
+eventually avoid it.
+*/
+
+/* Mixins */
+
+/* [paper-font] */
+body {
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased; /* OS X subpixel AA bleed bug */
+}
+
+/* [paper-font=display2] */
+h1 {
+ font-size: 45px;
+ font-weight: 400;
+ letter-spacing: -.018em;
+ line-height: 48px;
+}
+
+/* [paper-font=display1] */
+h2 {
+ font-size: 34px;
+ font-weight: 400;
+ letter-spacing: -.01em;
+ line-height: 40px;
+}
+
+/* [paper-font=headline] */
+h3 {
+ font-size: 24px;
+ font-weight: 400;
+ letter-spacing: -.012em;
+ line-height: 32px;
+}
+
+/* [paper-font=subhead] */
+h4 {
+ font-size: 16px;
+ font-weight: 400;
+ line-height: 24px;
+}
+
+/* [paper-font=body2] */
+h5, h6 {
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 24px;
+}
+
+/* [paper-font=button] */
+a {
+ font-size: 14px;
+ font-weight: 500;
+ letter-spacing: 0.018em;
+ line-height: 24px;
+ text-transform: uppercase;
+}
+
+/* Overrides */
+
+body, a {
+ color: #212121;
+}
+
+h1, h2, h3, h4, h5, h6, p {
+ margin: 0 0 20px 0;
+}
+
+h1, h2, h3, h4, h5, h6, a {
+ text-rendering: optimizeLegibility;
+}
+
+a {
+ text-decoration: none;
+}
+
+</style>
diff --git a/polymer_1.0.4/bower_components/paper-styles/classes/shadow-layout.html b/polymer_1.0.4/bower_components/paper-styles/classes/shadow-layout.html
new file mode 100644
index 0000000..c42067a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/classes/shadow-layout.html
@@ -0,0 +1,302 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<style>
+
+ /*******************************
+ Flex Layout
+ *******************************/
+
+ html /deep/ .layout.horizontal,
+ html /deep/ .layout.horizontal-reverse,
+ html /deep/ .layout.vertical,
+ html /deep/ .layout.vertical-reverse {
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+ }
+
+ html /deep/ .layout.inline {
+ display: -ms-inline-flexbox;
+ display: -webkit-inline-flex;
+ display: inline-flex;
+ }
+
+ html /deep/ .layout.horizontal {
+ -ms-flex-direction: row;
+ -webkit-flex-direction: row;
+ flex-direction: row;
+ }
+
+ html /deep/ .layout.horizontal-reverse {
+ -ms-flex-direction: row-reverse;
+ -webkit-flex-direction: row-reverse;
+ flex-direction: row-reverse;
+ }
+
+ html /deep/ .layout.vertical {
+ -ms-flex-direction: column;
+ -webkit-flex-direction: column;
+ flex-direction: column;
+ }
+
+ html /deep/ .layout.vertical-reverse {
+ -ms-flex-direction: column-reverse;
+ -webkit-flex-direction: column-reverse;
+ flex-direction: column-reverse;
+ }
+
+ html /deep/ .layout.wrap {
+ -ms-flex-wrap: wrap;
+ -webkit-flex-wrap: wrap;
+ flex-wrap: wrap;
+ }
+
+ html /deep/ .layout.wrap-reverse {
+ -ms-flex-wrap: wrap-reverse;
+ -webkit-flex-wrap: wrap-reverse;
+ flex-wrap: wrap-reverse;
+ }
+
+ html /deep/ .flex-auto {
+ -ms-flex: 1 1 auto;
+ -webkit-flex: 1 1 auto;
+ flex: 1 1 auto;
+ }
+
+ html /deep/ .flex-none {
+ -ms-flex: none;
+ -webkit-flex: none;
+ flex: none;
+ }
+
+ html /deep/ .flex,
+ html /deep/ .flex-1 {
+ -ms-flex: 1;
+ -webkit-flex: 1;
+ flex: 1;
+ }
+
+ html /deep/ .flex-2 {
+ -ms-flex: 2;
+ -webkit-flex: 2;
+ flex: 2;
+ }
+
+ html /deep/ .flex-3 {
+ -ms-flex: 3;
+ -webkit-flex: 3;
+ flex: 3;
+ }
+
+ html /deep/ .flex-4 {
+ -ms-flex: 4;
+ -webkit-flex: 4;
+ flex: 4;
+ }
+
+ html /deep/ .flex-5 {
+ -ms-flex: 5;
+ -webkit-flex: 5;
+ flex: 5;
+ }
+
+ html /deep/ .flex-6 {
+ -ms-flex: 6;
+ -webkit-flex: 6;
+ flex: 6;
+ }
+
+ html /deep/ .flex-7 {
+ -ms-flex: 7;
+ -webkit-flex: 7;
+ flex: 7;
+ }
+
+ html /deep/ .flex-8 {
+ -ms-flex: 8;
+ -webkit-flex: 8;
+ flex: 8;
+ }
+
+ html /deep/ .flex-9 {
+ -ms-flex: 9;
+ -webkit-flex: 9;
+ flex: 9;
+ }
+
+ html /deep/ .flex-10 {
+ -ms-flex: 10;
+ -webkit-flex: 10;
+ flex: 10;
+ }
+
+ html /deep/ .flex-11 {
+ -ms-flex: 11;
+ -webkit-flex: 11;
+ flex: 11;
+ }
+
+ html /deep/ .flex-12 {
+ -ms-flex: 12;
+ -webkit-flex: 12;
+ flex: 12;
+ }
+
+ /* alignment in cross axis */
+
+ html /deep/ .layout.start {
+ -ms-flex-align: start;
+ -webkit-align-items: flex-start;
+ align-items: flex-start;
+ }
+
+ html /deep/ .layout.center,
+ html /deep/ .layout.center-center {
+ -ms-flex-align: center;
+ -webkit-align-items: center;
+ align-items: center;
+ }
+
+ html /deep/ .layout.end {
+ -ms-flex-align: end;
+ -webkit-align-items: flex-end;
+ align-items: flex-end;
+ }
+
+ /* alignment in main axis */
+
+ html /deep/ .layout.start-justified {
+ -ms-flex-pack: start;
+ -webkit-justify-content: flex-start;
+ justify-content: flex-start;
+ }
+
+ html /deep/ .layout.center-justified,
+ html /deep/ .layout.center-center {
+ -ms-flex-pack: center;
+ -webkit-justify-content: center;
+ justify-content: center;
+ }
+
+ html /deep/ .layout.end-justified {
+ -ms-flex-pack: end;
+ -webkit-justify-content: flex-end;
+ justify-content: flex-end;
+ }
+
+ html /deep/ .layout.around-justified {
+ -ms-flex-pack: around;
+ -webkit-justify-content: space-around;
+ justify-content: space-around;
+ }
+
+ html /deep/ .layout.justified {
+ -ms-flex-pack: justify;
+ -webkit-justify-content: space-between;
+ justify-content: space-between;
+ }
+
+ /* self alignment */
+
+ html /deep/ .self-start {
+ -ms-align-self: flex-start;
+ -webkit-align-self: flex-start;
+ align-self: flex-start;
+ }
+
+ html /deep/ .self-center {
+ -ms-align-self: center;
+ -webkit-align-self: center;
+ align-self: center;
+ }
+
+ html /deep/ .self-end {
+ -ms-align-self: flex-end;
+ -webkit-align-self: flex-end;
+ align-self: flex-end;
+ }
+
+ html /deep/ .self-stretch {
+ -ms-align-self: stretch;
+ -webkit-align-self: stretch;
+ align-self: stretch;
+ }
+
+ /*******************************
+ Other Layout
+ *******************************/
+
+ html /deep/ .block {
+ display: block;
+ }
+
+ /* IE 10 support for HTML5 hidden attr */
+ html /deep/ [hidden] {
+ display: none !important;
+ }
+
+ html /deep/ .invisible {
+ visibility: hidden !important;
+ }
+
+ html /deep/ .relative {
+ position: relative;
+ }
+
+ html /deep/ .fit {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ }
+
+ body.fullbleed {
+ margin: 0;
+ height: 100vh;
+ }
+
+ html /deep/ .scroll {
+ -webkit-overflow-scrolling: touch;
+ overflow: auto;
+ }
+
+ .fixed-bottom,
+ .fixed-left,
+ .fixed-right,
+ .fixed-top {
+ position: fixed;
+ }
+
+ html /deep/ .fixed-top {
+ top: 0;
+ left: 0;
+ right: 0;
+ }
+
+ html /deep/ .fixed-right {
+ top: 0;
+ right: 0;
+ botttom: 0;
+ }
+
+ html /deep/ .fixed-bottom {
+ right: 0;
+ bottom: 0;
+ left: 0;
+ }
+
+ html /deep/ .fixed-left {
+ top: 0;
+ botttom: 0;
+ left: 0;
+ }
+
+</style>
diff --git a/polymer_1.0.4/bower_components/paper-styles/classes/shadow.html b/polymer_1.0.4/bower_components/paper-styles/classes/shadow.html
new file mode 100644
index 0000000..4c40a14
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/classes/shadow.html
@@ -0,0 +1,52 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<style>
+.shadow-transition {
+ transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.shadow-elevation-2dp {
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 5px 0 rgba(0, 0, 0, 0.12),
+ 0 3px 1px -2px rgba(0, 0, 0, 0.2);
+}
+
+.shadow-elevation-3dp {
+ box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 8px 0 rgba(0, 0, 0, 0.12),
+ 0 3px 3px -2px rgba(0, 0, 0, 0.4);
+}
+
+.shadow-elevation-4dp {
+ box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 10px 0 rgba(0, 0, 0, 0.12),
+ 0 2px 4px -1px rgba(0, 0, 0, 0.4);
+}
+
+.shadow-elevation-6dp {
+ box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 18px 0 rgba(0, 0, 0, 0.12),
+ 0 3px 5px -1px rgba(0, 0, 0, 0.4);
+}
+
+.shadow-elevation-8dp {
+ box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14),
+ 0 3px 14px 2px rgba(0, 0, 0, 0.12),
+ 0 5px 5px -3px rgba(0, 0, 0, 0.4);
+}
+
+.shadow-elevation-16dp {
+ box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14),
+ 0 6px 30px 5px rgba(0, 0, 0, 0.12),
+ 0 8px 10px -5px rgba(0, 0, 0, 0.4);
+}
+
+</style>
diff --git a/polymer_1.0.4/bower_components/paper-styles/classes/typography.html b/polymer_1.0.4/bower_components/paper-styles/classes/typography.html
new file mode 100644
index 0000000..5514abb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/classes/typography.html
@@ -0,0 +1,171 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!-- TODO(nevir): Should we upgrade Polymer/font-roboto to the final font? -->
+<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,500,500italic,700,700italic">
+<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Inconsolata:400,700">
+
+<!--
+Typographic styles are provided matching the Material Design standard styles:
+http://www.google.com/design/spec/style/typography.html#typography-standard-styles
+
+To make use of them, apply a `paper-font-<style>` class to elements, matching
+the font style you wish it to inherit.
+
+ <header class="paper-font-display2">Hey there!</header>
+
+Note that these are English/Latin centric styles. You may need to further adjust
+line heights and weights for CJK typesetting. See the notes in the Material
+Design typography section.
+-->
+<style>
+
+.paper-font-display4,
+.paper-font-display3,
+.paper-font-display2,
+.paper-font-display1,
+.paper-font-headline,
+.paper-font-title,
+.paper-font-subhead,
+.paper-font-body2,
+.paper-font-body1,
+.paper-font-caption,
+.paper-font-menu,
+.paper-font-button {
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased; /* OS X subpixel AA bleed bug */
+}
+
+.paper-font-code2,
+.paper-font-code1 {
+ font-family: 'Inconsolata', 'Consolas', 'Source Code Pro', 'Monaco', 'Menlo', monospace;
+ -webkit-font-smoothing: antialiased; /* OS X subpixel AA bleed bug */
+}
+
+/* Opt for better kerning for headers & other short labels. */
+.paper-font-display4,
+.paper-font-display3,
+.paper-font-display2,
+.paper-font-display1,
+.paper-font-headline,
+.paper-font-title,
+.paper-font-subhead,
+.paper-font-menu,
+.paper-font-button {
+ text-rendering: optimizeLegibility;
+}
+
+/*
+"Line wrapping only applies to Body, Subhead, Headline, and the smaller Display
+styles. All other styles should exist as single lines."
+*/
+.paper-font-display4,
+.paper-font-display3,
+.paper-font-title,
+.paper-font-caption,
+.paper-font-menu,
+.paper-font-button {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.paper-font-display4 {
+ font-size: 112px;
+ font-weight: 300;
+ letter-spacing: -.044em;
+ line-height: 120px;
+}
+
+.paper-font-display3 {
+ font-size: 56px;
+ font-weight: 400;
+ letter-spacing: -.026em;
+ line-height: 60px;
+}
+
+.paper-font-display2 {
+ font-size: 45px;
+ font-weight: 400;
+ letter-spacing: -.018em;
+ line-height: 48px;
+}
+
+.paper-font-display1 {
+ font-size: 34px;
+ font-weight: 400;
+ letter-spacing: -.01em;
+ line-height: 40px;
+}
+
+.paper-font-headline {
+ font-size: 24px;
+ font-weight: 400;
+ letter-spacing: -.012em;
+ line-height: 32px;
+}
+
+.paper-font-title {
+ font-size: 20px;
+ font-weight: 500;
+ line-height: 28px;
+}
+
+.paper-font-subhead {
+ font-size: 16px;
+ font-weight: 400;
+ line-height: 24px;
+}
+
+.paper-font-body2 {
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 24px;
+}
+
+.paper-font-body1 {
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 20px;
+}
+
+.paper-font-caption {
+ font-size: 12px;
+ font-weight: 400;
+ letter-spacing: 0.011em;
+ line-height: 20px;
+}
+
+.paper-font-menu {
+ font-size: 13px;
+ font-weight: 500;
+ line-height: 24px;
+}
+
+.paper-font-button {
+ font-size: 14px;
+ font-weight: 500;
+ letter-spacing: 0.018em;
+ line-height: 24px;
+ text-transform: uppercase;
+}
+
+.paper-font-code2 {
+ font-size: 14px;
+ font-weight: 700;
+ line-height: 20px;
+}
+
+.paper-font-code1 {
+ font-size: 14px;
+ font-weight: 700;
+ line-height: 20px;
+}
+
+</style>
diff --git a/polymer_1.0.4/bower_components/paper-styles/color.html b/polymer_1.0.4/bower_components/paper-styles/color.html
new file mode 100644
index 0000000..f0be341
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/color.html
@@ -0,0 +1,333 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<style is="custom-style">
+
+ :root {
+
+ /* Material Design color palette for Google products */
+
+ --google-red-100: #f4c7c3;
+ --google-red-300: #e67c73;
+ --google-red-500: #db4437;
+ --google-red-700: #c53929;
+
+ --google-blue-100: #c6dafc;
+ --google-blue-300: #7baaf7;
+ --google-blue-500: #4285f4;
+ --google-blue-700: #3367d6;
+
+ --google-green-100: #b7e1cd;
+ --google-green-300: #57bb8a;
+ --google-green-500: #0f9d58;
+ --google-green-700: #0b8043;
+
+ --google-yellow-100: #fce8b2;
+ --google-yellow-300: #f7cb4d;
+ --google-yellow-500: #f4b400;
+ --google-yellow-700: #f09300;
+
+ --google-grey-100: #f5f5f5;
+ --google-grey-300: #e0e0e0;
+ --google-grey-500: #9e9e9e;
+ --google-grey-700: #616161;
+
+ /* Material Design color palette from online spec document */
+
+ --paper-red-50: #ffebee;
+ --paper-red-100: #ffcdd2;
+ --paper-red-200: #ef9a9a;
+ --paper-red-300: #e57373;
+ --paper-red-400: #ef5350;
+ --paper-red-500: #f44336;
+ --paper-red-600: #e53935;
+ --paper-red-700: #d32f2f;
+ --paper-red-800: #c62828;
+ --paper-red-900: #b71c1c;
+ --paper-red-a100: #ff8a80;
+ --paper-red-a200: #ff5252;
+ --paper-red-a400: #ff1744;
+ --paper-red-a700: #d50000;
+
+ --paper-pink-50: #fce4ec;
+ --paper-pink-100: #f8bbd0;
+ --paper-pink-200: #f48fb1;
+ --paper-pink-300: #f06292;
+ --paper-pink-400: #ec407a;
+ --paper-pink-500: #e91e63;
+ --paper-pink-600: #d81b60;
+ --paper-pink-700: #c2185b;
+ --paper-pink-800: #ad1457;
+ --paper-pink-900: #880e4f;
+ --paper-pink-a100: #ff80ab;
+ --paper-pink-a200: #ff4081;
+ --paper-pink-a400: #f50057;
+ --paper-pink-a700: #c51162;
+
+ --paper-purple-50: #f3e5f5;
+ --paper-purple-100: #e1bee7;
+ --paper-purple-200: #ce93d8;
+ --paper-purple-300: #ba68c8;
+ --paper-purple-400: #ab47bc;
+ --paper-purple-500: #9c27b0;
+ --paper-purple-600: #8e24aa;
+ --paper-purple-700: #7b1fa2;
+ --paper-purple-800: #6a1b9a;
+ --paper-purple-900: #4a148c;
+ --paper-purple-a100: #ea80fc;
+ --paper-purple-a200: #e040fb;
+ --paper-purple-a400: #d500f9;
+ --paper-purple-a700: #aa00ff;
+
+ --paper-deep-purple-50: #ede7f6;
+ --paper-deep-purple-100: #d1c4e9;
+ --paper-deep-purple-200: #b39ddb;
+ --paper-deep-purple-300: #9575cd;
+ --paper-deep-purple-400: #7e57c2;
+ --paper-deep-purple-500: #673ab7;
+ --paper-deep-purple-600: #5e35b1;
+ --paper-deep-purple-700: #512da8;
+ --paper-deep-purple-800: #4527a0;
+ --paper-deep-purple-900: #311b92;
+ --paper-deep-purple-a100: #b388ff;
+ --paper-deep-purple-a200: #7c4dff;
+ --paper-deep-purple-a400: #651fff;
+ --paper-deep-purple-a700: #6200ea;
+
+ --paper-indigo-50: #e8eaf6;
+ --paper-indigo-100: #c5cae9;
+ --paper-indigo-200: #9fa8da;
+ --paper-indigo-300: #7986cb;
+ --paper-indigo-400: #5c6bc0;
+ --paper-indigo-500: #3f51b5;
+ --paper-indigo-600: #3949ab;
+ --paper-indigo-700: #303f9f;
+ --paper-indigo-800: #283593;
+ --paper-indigo-900: #1a237e;
+ --paper-indigo-a100: #8c9eff;
+ --paper-indigo-a200: #536dfe;
+ --paper-indigo-a400: #3d5afe;
+ --paper-indigo-a700: #304ffe;
+
+ --paper-blue-50: #e3f2fd;
+ --paper-blue-100: #bbdefb;
+ --paper-blue-200: #90caf9;
+ --paper-blue-300: #64b5f6;
+ --paper-blue-400: #42a5f5;
+ --paper-blue-500: #2196f3;
+ --paper-blue-600: #1e88e5;
+ --paper-blue-700: #1976d2;
+ --paper-blue-800: #1565c0;
+ --paper-blue-900: #0d47a1;
+ --paper-blue-a100: #82b1ff;
+ --paper-blue-a200: #448aff;
+ --paper-blue-a400: #2979ff;
+ --paper-blue-a700: #2962ff;
+
+ --paper-light-blue-50: #e1f5fe;
+ --paper-light-blue-100: #b3e5fc;
+ --paper-light-blue-200: #81d4fa;
+ --paper-light-blue-300: #4fc3f7;
+ --paper-light-blue-400: #29b6f6;
+ --paper-light-blue-500: #03a9f4;
+ --paper-light-blue-600: #039be5;
+ --paper-light-blue-700: #0288d1;
+ --paper-light-blue-800: #0277bd;
+ --paper-light-blue-900: #01579b;
+ --paper-light-blue-a100: #80d8ff;
+ --paper-light-blue-a200: #40c4ff;
+ --paper-light-blue-a400: #00b0ff;
+ --paper-light-blue-a700: #0091ea;
+
+ --paper-cyan-50: #e0f7fa;
+ --paper-cyan-100: #b2ebf2;
+ --paper-cyan-200: #80deea;
+ --paper-cyan-300: #4dd0e1;
+ --paper-cyan-400: #26c6da;
+ --paper-cyan-500: #00bcd4;
+ --paper-cyan-600: #00acc1;
+ --paper-cyan-700: #0097a7;
+ --paper-cyan-800: #00838f;
+ --paper-cyan-900: #006064;
+ --paper-cyan-a100: #84ffff;
+ --paper-cyan-a200: #18ffff;
+ --paper-cyan-a400: #00e5ff;
+ --paper-cyan-a700: #00b8d4;
+
+ --paper-teal-50: #e0f2f1;
+ --paper-teal-100: #b2dfdb;
+ --paper-teal-200: #80cbc4;
+ --paper-teal-300: #4db6ac;
+ --paper-teal-400: #26a69a;
+ --paper-teal-500: #009688;
+ --paper-teal-600: #00897b;
+ --paper-teal-700: #00796b;
+ --paper-teal-800: #00695c;
+ --paper-teal-900: #004d40;
+ --paper-teal-a100: #a7ffeb;
+ --paper-teal-a200: #64ffda;
+ --paper-teal-a400: #1de9b6;
+ --paper-teal-a700: #00bfa5;
+
+ --paper-green-50: #e8f5e9;
+ --paper-green-100: #c8e6c9;
+ --paper-green-200: #a5d6a7;
+ --paper-green-300: #81c784;
+ --paper-green-400: #66bb6a;
+ --paper-green-500: #4caf50;
+ --paper-green-600: #43a047;
+ --paper-green-700: #388e3c;
+ --paper-green-800: #2e7d32;
+ --paper-green-900: #1b5e20;
+ --paper-green-a100: #b9f6ca;
+ --paper-green-a200: #69f0ae;
+ --paper-green-a400: #00e676;
+ --paper-green-a700: #00c853;
+
+ --paper-light-green-50: #f1f8e9;
+ --paper-light-green-100: #dcedc8;
+ --paper-light-green-200: #c5e1a5;
+ --paper-light-green-300: #aed581;
+ --paper-light-green-400: #9ccc65;
+ --paper-light-green-500: #8bc34a;
+ --paper-light-green-600: #7cb342;
+ --paper-light-green-700: #689f38;
+ --paper-light-green-800: #558b2f;
+ --paper-light-green-900: #33691e;
+ --paper-light-green-a100: #ccff90;
+ --paper-light-green-a200: #b2ff59;
+ --paper-light-green-a400: #76ff03;
+ --paper-light-green-a700: #64dd17;
+
+ --paper-lime-50: #f9fbe7;
+ --paper-lime-100: #f0f4c3;
+ --paper-lime-200: #e6ee9c;
+ --paper-lime-300: #dce775;
+ --paper-lime-400: #d4e157;
+ --paper-lime-500: #cddc39;
+ --paper-lime-600: #c0ca33;
+ --paper-lime-700: #afb42b;
+ --paper-lime-800: #9e9d24;
+ --paper-lime-900: #827717;
+ --paper-lime-a100: #f4ff81;
+ --paper-lime-a200: #eeff41;
+ --paper-lime-a400: #c6ff00;
+ --paper-lime-a700: #aeea00;
+
+ --paper-yellow-50: #fffde7;
+ --paper-yellow-100: #fff9c4;
+ --paper-yellow-200: #fff59d;
+ --paper-yellow-300: #fff176;
+ --paper-yellow-400: #ffee58;
+ --paper-yellow-500: #ffeb3b;
+ --paper-yellow-600: #fdd835;
+ --paper-yellow-700: #fbc02d;
+ --paper-yellow-800: #f9a825;
+ --paper-yellow-900: #f57f17;
+ --paper-yellow-a100: #ffff8d;
+ --paper-yellow-a200: #ffff00;
+ --paper-yellow-a400: #ffea00;
+ --paper-yellow-a700: #ffd600;
+
+ --paper-amber-50: #fff8e1;
+ --paper-amber-100: #ffecb3;
+ --paper-amber-200: #ffe082;
+ --paper-amber-300: #ffd54f;
+ --paper-amber-400: #ffca28;
+ --paper-amber-500: #ffc107;
+ --paper-amber-600: #ffb300;
+ --paper-amber-700: #ffa000;
+ --paper-amber-800: #ff8f00;
+ --paper-amber-900: #ff6f00;
+ --paper-amber-a100: #ffe57f;
+ --paper-amber-a200: #ffd740;
+ --paper-amber-a400: #ffc400;
+ --paper-amber-a700: #ffab00;
+
+ --paper-orange-50: #fff3e0;
+ --paper-orange-100: #ffe0b2;
+ --paper-orange-200: #ffcc80;
+ --paper-orange-300: #ffb74d;
+ --paper-orange-400: #ffa726;
+ --paper-orange-500: #ff9800;
+ --paper-orange-600: #fb8c00;
+ --paper-orange-700: #f57c00;
+ --paper-orange-800: #ef6c00;
+ --paper-orange-900: #e65100;
+ --paper-orange-a100: #ffd180;
+ --paper-orange-a200: #ffab40;
+ --paper-orange-a400: #ff9100;
+ --paper-orange-a700: #ff6500;
+
+ --paper-deep-orange-50: #ff5722;
+ --paper-deep-orange-100: #fbe9e7;
+ --paper-deep-orange-200: #ffccbc;
+ --paper-deep-orange-300: #ff8a65;
+ --paper-deep-orange-400: #ff7043;
+ --paper-deep-orange-500: #ff5722;
+ --paper-deep-orange-600: #f4511e;
+ --paper-deep-orange-700: #e64a19;
+ --paper-deep-orange-800: #d84315;
+ --paper-deep-orange-900: #bf360c;
+ --paper-deep-orange-a100: #ff9e80;
+ --paper-deep-orange-a200: #ff6e40;
+ --paper-deep-orange-a400: #ff3d00;
+ --paper-deep-orange-a700: #dd2c00;
+
+ --paper-brown-50: #efebe9;
+ --paper-brown-100: #d7ccc8;
+ --paper-brown-200: #bcaaa4;
+ --paper-brown-300: #a1887f;
+ --paper-brown-400: #8d6e63;
+ --paper-brown-500: #795548;
+ --paper-brown-600: #6d4c41;
+ --paper-brown-700: #5d4037;
+ --paper-brown-800: #4e342e;
+ --paper-brown-900: #3e2723;
+
+ --paper-grey-50: #fafafa;
+ --paper-grey-100: #f5f5f5;
+ --paper-grey-200: #eeeeee;
+ --paper-grey-300: #e0e0e0;
+ --paper-grey-400: #bdbdbd;
+ --paper-grey-500: #9e9e9e;
+ --paper-grey-600: #757575;
+ --paper-grey-700: #616161;
+ --paper-grey-800: #424242;
+ --paper-grey-900: #212121;
+
+ --paper-blue-grey-50: #eceff1;
+ --paper-blue-grey-100: #cfd8dc;
+ --paper-blue-grey-200: #b0bec5;
+ --paper-blue-grey-300: #90a4ae;
+ --paper-blue-grey-400: #78909c;
+ --paper-blue-grey-500: #607d8b;
+ --paper-blue-grey-600: #546e7a;
+ --paper-blue-grey-700: #455a64;
+ --paper-blue-grey-800: #37474f;
+ --paper-blue-grey-900: #263238;
+
+ /* opacity for dark text on a light background */
+ --dark-divider-opacity: 0.12;
+ --dark-disabled-opacity: 0.26; /* or hint text */
+ --dark-secondary-opacity: 0.54; /* or icon */
+ --dark-primary-opacity: 0.87;
+
+ /* opacity for light text on a dark background */
+ --light-divider-opacity: 0.12;
+ --light-disabled-opacity: 0.3; /* or hint text */
+ --light-secondary-opacity: 0.7; /* or icon */
+ --light-primary-opacity: 1.0;
+
+ }
+
+</style>
diff --git a/polymer_1.0.4/bower_components/paper-styles/default-theme.html b/polymer_1.0.4/bower_components/paper-styles/default-theme.html
new file mode 100644
index 0000000..add581c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/default-theme.html
@@ -0,0 +1,39 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<style is="custom-style">
+
+ :root {
+
+ --dark-primary-color: #303f9f;
+
+ --default-primary-color: #3f51b5;
+
+ --light-primary-color: #c5cae9;
+
+ --text-primary-color: #ffffff;
+
+ --accent-color: #ff4081;
+
+ --primary-background-color: #ffffff;
+
+ --primary-text-color: #212121;
+
+ --secondary-text-color: #757575;
+
+ --disabled-text-color: #bdbdbd;
+
+ --divider-color: #e0e0e0;
+
+ }
+
+</style>
diff --git a/polymer_1.0.4/bower_components/paper-styles/demo-pages.html b/polymer_1.0.4/bower_components/paper-styles/demo-pages.html
new file mode 100644
index 0000000..44f2288
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/demo-pages.html
@@ -0,0 +1,72 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
+
+<link rel="import" href="color.html">
+<link rel="import" href="typography.html">
+<link rel="import" href="shadow.html">
+
+<style is="custom-style">
+
+ body {
+ font-family: 'Roboto', 'Noto', sans-serif;
+ font-size: 14px;
+ margin: 0;
+ padding: 24px;
+ background-color: var(--paper-grey-50);
+ }
+
+ .horizontal-section-container {
+ @apply(--layout-horizontal);
+ @apply(--layout-center-justified);
+ @apply(--layout-wrap);
+ }
+
+ .vertical-section-container {
+ @apply(--layout-vertical);
+ @apply(--center-justified);
+ }
+
+ .horizontal-section {
+ background-color: white;
+ padding: 24px;
+ margin-right: 24px;
+ min-width: 200px;
+
+ @apply(--shadow-elevation-2dp);
+ }
+
+ .vertical-section {
+ background-color: white;
+ padding: 24px;
+ margin: 0 24px 24px 24px;
+
+ @apply(--shadow-elevation-2dp);
+ }
+
+ .centered {
+ max-width: 400px;
+ margin-left: auto;
+ margin-right: auto;
+ }
+
+ code {
+ color: var(--google-grey-700);
+ }
+
+ /* TODO: remove this hack and use horizontal-section-container instead */
+ body > div.layout.horizontal.center-justified {
+ @apply(--layout-wrap);
+ }
+
+</style>
diff --git a/polymer_1.0.4/bower_components/paper-styles/demo.css b/polymer_1.0.4/bower_components/paper-styles/demo.css
new file mode 100644
index 0000000..efd8b47
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/demo.css
@@ -0,0 +1,25 @@
+/**
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+
+*/
+body {
+ font-family: 'Roboto', 'Noto', sans-serif;
+ font-size: 14px;
+ margin: 0;
+ padding: 24px;
+}
+
+section {
+ padding: 20px 0;
+}
+
+section > div {
+ padding: 14px;
+ font-size: 16px;
+}
diff --git a/polymer_1.0.4/bower_components/paper-styles/demo/index.html b/polymer_1.0.4/bower_components/paper-styles/demo/index.html
new file mode 100644
index 0000000..42f449f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/demo/index.html
@@ -0,0 +1,358 @@
+<!doctype html>
+
+<!--
+ @license
+ Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ Code distributed by Google as part of the polymer project is also
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>paper-styles demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-styles.html">
+ <link rel="import" href="../demo-pages.html">
+
+ <style>
+
+ .redlines {
+ background: linear-gradient(0deg, transparent, transparent 3.5px, rgba(255,0,0,0.2) 3.5px, rgba(255,0,0,0.2) 4px);
+ background-size: 100% 4px;
+ }
+
+ .paragraph {
+ margin-bottom: 20px;
+ }
+
+ </style>
+
+ </head>
+ <body>
+
+ <!-- FIXME remove when https://github.com/Polymer/polymer/issues/1415 is resolved -->
+ <dom-module id="x-demo">
+
+ <style>
+
+ .paper-font-display4 {
+ @apply(--paper-font-display4);
+ }
+
+ .paper-font-display3 {
+ @apply(--paper-font-display3);
+ }
+
+ .paper-font-display2 {
+ @apply(--paper-font-display2);
+ }
+
+ .paper-font-display1 {
+ @apply(--paper-font-display1);
+ }
+
+ .paper-font-headline {
+ @apply(--paper-font-headline);
+ }
+
+ .paper-font-title {
+ @apply(--paper-font-title);
+ }
+
+ .paper-font-subhead {
+ @apply(--paper-font-subhead);
+ }
+
+ .paper-font-body2 {
+ @apply(--paper-font-body1);
+ }
+
+ .paper-font-body1 {
+ @apply(--paper-font-body1);
+ }
+
+ .paper-font-caption {
+ @apply(--paper-font-caption);
+ }
+
+ .paper-font-menu {
+ @apply(--paper-font-menu);
+ }
+
+ .paper-font-button {
+ @apply(--paper-font-button);
+ }
+
+ .mobile-app {
+ max-width: 320px;
+ }
+
+ .toolbar {
+ height: 144px;
+ padding: 16px;
+
+ background: var(--default-primary-color);
+ color: var(--text-primary-color);
+ @apply(--paper-font-display1);
+ }
+
+ .item, .disabled-item {
+ position: relative;
+ padding: 8px;
+ border: 1px solid;
+ border-color: var(--divider-color);
+ border-top: 0;
+ }
+
+ .item .primary {
+ color: var(--primary-text-color);
+
+ @apply(--paper-font-body2);
+ }
+
+ .item .secondary {
+ color: var(--secondary-text-color);
+
+ @apply(--paper-font-body1);
+ }
+
+ .disabled-item {
+ color: var(--disabled-text-color);
+
+ @apply(--paper-font-body2);
+ }
+
+ .fab {
+ position: absolute;
+ box-sizing: border-box;
+ padding: 8px;
+ width: 56px;
+ height: 56px;
+ right: 16px;
+ top: -28px;
+ border-radius: 50%;
+ text-align: center;
+
+ background: var(--accent-color);
+ color: var(--text-primary-color);
+ @apply(--paper-font-display1);
+ }
+
+ .shadow {
+ display: inline-block;
+ padding: 8px;
+ margin: 16px;
+ height: 50px;
+ width: 50px;
+ }
+
+ .shadow-2dp {
+ @apply(--shadow-elevation-2dp);
+ }
+
+ .shadow-3dp {
+ @apply(--shadow-elevation-3dp);
+ }
+
+ .shadow-4dp {
+ @apply(--shadow-elevation-4dp);
+ }
+
+ .shadow-6dp {
+ @apply(--shadow-elevation-6dp);
+ }
+
+ .shadow-8dp {
+ @apply(--shadow-elevation-8dp);
+ }
+
+ .shadow-16dp {
+ @apply(--shadow-elevation-16dp);
+ }
+
+ </style>
+
+ <template>
+
+ <h1>paper-styles</h1>
+
+ <section id="default-theme">
+ <h2>default-theme.html</h2>
+
+ <section class="mobile-app">
+ <div class="toolbar">
+ Title
+ </div>
+ <div class="item">
+ <div class="fab">+</div>
+ <div class="primary">Primary text</div>
+ <div class="secondary">Secondary text</div>
+ </div>
+ <div class="disabled-item">
+ Disabled
+ </div>
+ </section>
+ </section>
+
+ <section id="typography">
+ <h2>typography.html</h2>
+ <p>
+ Grumpy wizards make toxic brew for the evil Queen and Jack.
+ </p>
+ <section class="redlines paragraph">
+ <div class="paper-font-display4">Display 4</div>
+ <div class="paper-font-display3">Display 3</div>
+ <div class="paper-font-display2">Display 2</div>
+ <div class="paper-font-display1">Display 1</div>
+ <div class="paper-font-headline">Headline</div>
+ <div class="paper-font-title">Title</div>
+ <div class="paper-font-subhead">Subhead</div>
+ <div class="paper-font-body2">Body 2</div>
+ <div class="paper-font-body1">Body 1</div>
+ <div class="paper-font-caption">Caption</div>
+ <div class="paper-font-menu">Menu</div>
+ <div class="paper-font-button">Button</div>
+ </section>
+
+ <h3>Paragraphs</h3>
+
+ <h4>body2</h4>
+ <section class="paper-font-body2 redlines">
+ <p>
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi
+ tincidunt dui sit amet mi auctor, ac gravida magna aliquam. Fusce quis
+ purus elementum, tempus nisi vel, volutpat nulla. Vestibulum mollis
+ dictum tellus, vulputate porttitor arcu. Curabitur imperdiet risus id
+ egestas accumsan. Donec lectus felis, dignissim id iaculis sit amet,
+ faucibus in leo.
+ </p>
+ <p>
+ Mauris id urna ac ante ultrices commodo a imperdiet elit. Vivamus
+ interdum neque magna, eget dapibus est auctor et. Donec accumsan
+ libero nec augue scelerisque, ac egestas ante tincidunt. Proin
+ sollicitudin, mi eget sagittis mollis, arcu orci scelerisque turpis, a
+ sollicitudin tellus quam non sapien.
+ </p>
+ </section>
+
+ <h4>body1</h4>
+ <section class="paper-font-body1 redlines">
+ <p>
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi
+ tincidunt dui sit amet mi auctor, ac gravida magna aliquam. Fusce quis
+ purus elementum, tempus nisi vel, volutpat nulla. Vestibulum mollis
+ dictum tellus, vulputate porttitor arcu. Curabitur imperdiet risus id
+ egestas accumsan. Donec lectus felis, dignissim id iaculis sit amet,
+ faucibus in leo.
+ </p>
+ <p>
+ Mauris id urna ac ante ultrices commodo a imperdiet elit. Vivamus
+ interdum neque magna, eget dapibus est auctor et. Donec accumsan
+ libero nec augue scelerisque, ac egestas ante tincidunt. Proin
+ sollicitudin, mi eget sagittis mollis, arcu orci scelerisque turpis, a
+ sollicitudin tellus quam non sapien.
+ </p>
+ </section>
+ </section>
+
+ <section id="shadow">
+ <h2>shadow.html</h2>
+ <div class="shadow shadow-2dp">2dp</div>
+ <div class="shadow shadow-3dp">3dp</div>
+ <div class="shadow shadow-4dp">4dp</div>
+ <div class="shadow shadow-6dp">6dp</div>
+ <div class="shadow shadow-8dp">8dp</div>
+ <div class="shadow shadow-16dp">16dp</div>
+ </section>
+
+ </template>
+ </dom-module>
+
+ <script>
+ document.addEventListener('HTMLImportsLoaded', function() {
+ Polymer({
+ is: 'x-demo',
+ enableCustomStyleProperties: true
+ });
+ });
+ </script>
+
+ <x-demo></x-demo>
+
+ <section id="demo-page">
+ <h2>demo-pages.html</h2>
+
+ <h3>Horizontal sections</h3>
+ <div class="horizontal-section-container">
+ <div>
+ <h4>Column 1</h4>
+ <div class="horizontal-section">
+ <div>Oxygen</div>
+ <div>Carbon</div>
+ <div>Hydrogen</div>
+ <div>Nitrogen</div>
+ <div>Calcium</div>
+ </div>
+ </div>
+
+ <div>
+ <h4>Column 2</h4>
+ <div class="horizontal-section">
+ <div>Oxygen</div>
+ <div>Carbon</div>
+ <div>Hydrogen</div>
+ <div>Nitrogen</div>
+ <div>Calcium</div>
+ </div>
+ </div>
+
+ <div>
+ <h4>Column 3</h4>
+ <div class="horizontal-section">
+ <div>Oxygen</div>
+ <div>Carbon</div>
+ <div>Hydrogen</div>
+ <div>Nitrogen</div>
+ <div>Calcium</div>
+ </div>
+ </div>
+ </div>
+
+ <h3>Vertical sections</h3>
+ <div class="vertical-section-container">
+ <div>
+ <h4>Section 1</h4>
+ <div class="vertical-section">
+ <div>Oxygen</div>
+ <div>Carbon</div>
+ <div>Hydrogen</div>
+ <div>Nitrogen</div>
+ <div>Calcium</div>
+ </div>
+ </div>
+ </div>
+
+ <div class="vertical-section-container centered">
+ <h4>Section 2 (centered)</h4>
+ <div class="vertical-section">
+ <div>Oxygen</div>
+ <div>Carbon</div>
+ <div>Hydrogen</div>
+ <div>Nitrogen</div>
+ <div>Calcium</div>
+ </div>
+ </div>
+
+ </section>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-styles/paper-styles-classes.html b/polymer_1.0.4/bower_components/paper-styles/paper-styles-classes.html
new file mode 100644
index 0000000..ae315a5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/paper-styles-classes.html
@@ -0,0 +1,14 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+
+<link rel="import" href="classes/typography.html">
+<link rel="import" href="classes/shadow.html">
diff --git a/polymer_1.0.4/bower_components/paper-styles/paper-styles.html b/polymer_1.0.4/bower_components/paper-styles/paper-styles.html
new file mode 100644
index 0000000..1e4fce5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/paper-styles.html
@@ -0,0 +1,17 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
+<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+
+<link rel="import" href="color.html">
+<link rel="import" href="default-theme.html">
+<link rel="import" href="shadow.html">
+<link rel="import" href="typography.html">
diff --git a/polymer_1.0.4/bower_components/paper-styles/shadow.html b/polymer_1.0.4/bower_components/paper-styles/shadow.html
new file mode 100644
index 0000000..dfb7e8a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/shadow.html
@@ -0,0 +1,65 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<style is="custom-style">
+
+ :root {
+
+ --shadow-transition: {
+ transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);
+ };
+
+ --shadow-none: {
+ box-shadow: none;
+ };
+
+ /* from http://codepen.io/shyndman/pen/c5394ddf2e8b2a5c9185904b57421cdb */
+
+ --shadow-elevation-2dp: {
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 5px 0 rgba(0, 0, 0, 0.12),
+ 0 3px 1px -2px rgba(0, 0, 0, 0.2);
+ };
+
+ --shadow-elevation-3dp: {
+ box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 8px 0 rgba(0, 0, 0, 0.12),
+ 0 3px 3px -2px rgba(0, 0, 0, 0.4);
+ };
+
+ --shadow-elevation-4dp: {
+ box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 10px 0 rgba(0, 0, 0, 0.12),
+ 0 2px 4px -1px rgba(0, 0, 0, 0.4);
+ };
+
+ --shadow-elevation-6dp: {
+ box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 18px 0 rgba(0, 0, 0, 0.12),
+ 0 3px 5px -1px rgba(0, 0, 0, 0.4);
+ };
+
+ --shadow-elevation-8dp: {
+ box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14),
+ 0 3px 14px 2px rgba(0, 0, 0, 0.12),
+ 0 5px 5px -3px rgba(0, 0, 0, 0.4);
+ };
+
+ --shadow-elevation-16dp: {
+ box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14),
+ 0 6px 30px 5px rgba(0, 0, 0, 0.12),
+ 0 8px 10px -5px rgba(0, 0, 0, 0.4);
+ };
+
+ }
+
+</style>
diff --git a/polymer_1.0.4/bower_components/paper-styles/typography.html b/polymer_1.0.4/bower_components/paper-styles/typography.html
new file mode 100644
index 0000000..e6cbff7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-styles/typography.html
@@ -0,0 +1,239 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!-- TODO(nevir): Should we upgrade Polymer/font-roboto to the final font? -->
+<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,500,500italic,700,700italic">
+
+<link rel="import" href="../polymer/polymer.html">
+
+<style is="custom-style">
+
+ :root {
+
+ /* Shared Styles */
+
+ /*
+ Unfortunately, we can't use nested rules
+ See https://github.com/Polymer/polymer/issues/1399
+ */
+ --paper-font-common-base: {
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ };
+
+ --paper-font-common-code: {
+ font-family: 'Inconsolata', 'Consolas', 'Source Code Pro', 'Monaco', 'Menlo', monospace;
+ -webkit-font-smoothing: antialiased;
+ };
+
+ --paper-font-common-expensive-kerning: {
+ text-rendering: optimizeLegibility;
+ };
+
+ --paper-font-common-nowrap: {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ };
+
+ /* Material Font Styles */
+
+ --paper-font-display4: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ /* @apply(--paper-font-common-expensive-kerning); */
+ text-rendering: optimizeLegibility;
+ /* @apply(--paper-font-common-nowrap); */
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ font-size: 112px;
+ font-weight: 300;
+ letter-spacing: -.044em;
+ line-height: 120px;
+ };
+
+ --paper-font-display3: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ /* @apply(--paper-font-common-expensive-kerning); */
+ text-rendering: optimizeLegibility;
+ /* @apply(--paper-font-common-nowrap); */
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ font-size: 56px;
+ font-weight: 400;
+ letter-spacing: -.026em;
+ line-height: 60px;
+ };
+
+ --paper-font-display2: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ /* @apply(--paper-font-common-expensive-kerning); */
+ text-rendering: optimizeLegibility;
+
+ font-size: 45px;
+ font-weight: 400;
+ letter-spacing: -.018em;
+ line-height: 48px;
+ };
+
+ --paper-font-display1: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ /* @apply(--paper-font-common-expensive-kerning); */
+ text-rendering: optimizeLegibility;
+
+ font-size: 34px;
+ font-weight: 400;
+ letter-spacing: -.01em;
+ line-height: 40px;
+ };
+
+ --paper-font-headline: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ /* @apply(--paper-font-common-expensive-kerning); */
+ text-rendering: optimizeLegibility;
+
+ font-size: 24px;
+ font-weight: 400;
+ letter-spacing: -.012em;
+ line-height: 32px;
+ };
+
+ --paper-font-title: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ /* @apply(--paper-font-common-expensive-kerning); */
+ text-rendering: optimizeLegibility;
+ /* @apply(--paper-font-common-nowrap); */
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ font-size: 20px;
+ font-weight: 500;
+ line-height: 28px;
+ };
+
+ --paper-font-subhead: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ /* @apply(--paper-font-common-expensive-kerning); */
+ text-rendering: optimizeLegibility;
+
+ font-size: 16px;
+ font-weight: 400;
+ line-height: 24px;
+ };
+
+ --paper-font-body2: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 24px;
+ };
+
+ --paper-font-body1: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 20px;
+ };
+
+ --paper-font-caption: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ /* @apply(--paper-font-common-nowrap); */
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ font-size: 12px;
+ font-weight: 400;
+ letter-spacing: 0.011em;
+ line-height: 20px;
+ };
+
+ --paper-font-menu: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ /* @apply(--paper-font-common-expensive-kerning); */
+ text-rendering: optimizeLegibility;
+ /* @apply(--paper-font-common-nowrap); */
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ font-size: 13px;
+ font-weight: 500;
+ line-height: 24px;
+ };
+
+ --paper-font-button: {
+ /* @apply(--paper-font-common-base) */
+ font-family: 'Roboto', 'Noto', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ /* @apply(--paper-font-common-expensive-kerning); */
+ text-rendering: optimizeLegibility;
+ /* @apply(--paper-font-common-nowrap); */
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ font-size: 14px;
+ font-weight: 500;
+ letter-spacing: 0.018em;
+ line-height: 24px;
+ text-transform: uppercase;
+ };
+
+ --paper-font-code2: {
+ /* @apply(--paper-font-common-code); */
+ font-family: 'Inconsolata', 'Consolas', 'Source Code Pro', 'Monaco', 'Menlo', monospace;
+ -webkit-font-smoothing: antialiased;
+
+ font-size: 14px;
+ font-weight: 700;
+ line-height: 20px;
+ };
+
+ --paper-font-code1: {
+ /* @apply(--paper-font-common-code); */
+ font-family: 'Inconsolata', 'Consolas', 'Source Code Pro', 'Monaco', 'Menlo', monospace;
+ -webkit-font-smoothing: antialiased;
+
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 20px;
+ };
+
+ }
+
+</style>
diff --git a/polymer_1.0.4/bower_components/paper-tabs/.bower.json b/polymer_1.0.4/bower_components/paper-tabs/.bower.json
new file mode 100644
index 0000000..0b9b4e2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-tabs/.bower.json
@@ -0,0 +1,47 @@
+{
+ "name": "paper-tabs",
+ "version": "1.0.0",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Material design tabs",
+ "private": true,
+ "main": "paper-tabs.html",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "tabs",
+ "control"
+ ],
+ "repository": "https://github.com/PolymerElements/paper-tabs.git",
+ "dependencies": {
+ "iron-behaviors": "polymerelements/iron-behaviors#^1.0.0",
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "iron-iconset-svg": "polymerelements/iron-iconset-svg#^1.0.0",
+ "iron-menu-behavior": "polymerelements/iron-menu-behavior#^1.0.0",
+ "iron-resizable-behavior": "polymerelements/iron-resizable-behavior#^1.0.0",
+ "paper-ripple": "polymerelements/paper-ripple#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0",
+ "paper-icon-button": "polymerelements/paper-icon-button#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "paper-toolbar": "polymerelements/paper-toolbar#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "web-component-tester": "*"
+ },
+ "homepage": "https://github.com/PolymerElements/paper-tabs",
+ "_release": "1.0.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.0",
+ "commit": "af6820e55f73fc5aa8c8e4d5294085e46374c7ca"
+ },
+ "_source": "git://github.com/PolymerElements/paper-tabs.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-tabs"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-tabs/.gitignore b/polymer_1.0.4/bower_components/paper-tabs/.gitignore
new file mode 100644
index 0000000..fbe05fc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-tabs/.gitignore
@@ -0,0 +1 @@
+bower_components/
diff --git a/polymer_1.0.4/bower_components/paper-tabs/README.md b/polymer_1.0.4/bower_components/paper-tabs/README.md
new file mode 100644
index 0000000..d4744e2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-tabs/README.md
@@ -0,0 +1,56 @@
+paper-tabs
+============
+
+`paper-tabs` makes it easy to explore and switch between different views or functional aspects of
+an app, or to browse categorized data sets.
+
+Use `selected` property to get or set the selected tab.
+
+Example:
+
+```html
+<paper-tabs selected="0">
+ <paper-tab>TAB 1</paper-tab>
+ <paper-tab>TAB 2</paper-tab>
+ <paper-tab>TAB 3</paper-tab>
+</paper-tabs>
+```
+
+See <a href="#paper-tab">paper-tab</a> for more information about
+`paper-tab`.
+
+A common usage for `paper-tabs` is to use it along with `iron-pages` to switch
+between different views.
+
+```html
+<paper-tabs selected="{{selected}}">
+ <paper-tab>Tab 1</paper-tab>
+ <paper-tab>Tab 2</paper-tab>
+ <paper-tab>Tab 3</paper-tab>
+</paper-tabs>
+
+<iron-pages selected="{{selected}}">
+ <div>Page 1</div>
+ <div>Page 2</div>
+ <div>Page 3</div>
+</iron-pages>
+```
+
+To use links in tabs, add `link` attribute to `paper-tab` and put an `<a>`
+element in `paper-tab`.
+
+Example:
+
+```html
+<paper-tabs selected="0">
+ <paper-tab link>
+ <a href="#link1" class="horizontal center-center layout">TAB ONE</a>
+ </paper-tab>
+ <paper-tab link>
+ <a href="#link2" class="horizontal center-center layout">TAB TWO</a>
+ </paper-tab>
+ <paper-tab link>
+ <a href="#link3" class="horizontal center-center layout">TAB THREE</a>
+ </paper-tab>
+</paper-tabs>
+```
diff --git a/polymer_1.0.4/bower_components/paper-tabs/bower.json b/polymer_1.0.4/bower_components/paper-tabs/bower.json
new file mode 100644
index 0000000..cff76e9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-tabs/bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "paper-tabs",
+ "version": "1.0.0",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "Material design tabs",
+ "private": true,
+ "main": "paper-tabs.html",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "tabs",
+ "control"
+ ],
+ "repository": "https://github.com/PolymerElements/paper-tabs.git",
+ "dependencies": {
+ "iron-behaviors": "polymerelements/iron-behaviors#^1.0.0",
+ "iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
+ "iron-icon": "polymerelements/iron-icon#^1.0.0",
+ "iron-iconset-svg": "polymerelements/iron-iconset-svg#^1.0.0",
+ "iron-menu-behavior": "polymerelements/iron-menu-behavior#^1.0.0",
+ "iron-resizable-behavior": "polymerelements/iron-resizable-behavior#^1.0.0",
+ "paper-ripple": "polymerelements/paper-ripple#^1.0.0",
+ "paper-styles": "polymerelements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0",
+ "paper-icon-button": "polymerelements/paper-icon-button#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "paper-toolbar": "polymerelements/paper-toolbar#^1.0.0",
+ "test-fixture": "polymerelements/test-fixture#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
+ "web-component-tester": "*"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-tabs/demo/index.html b/polymer_1.0.4/bower_components/paper-tabs/demo/index.html
new file mode 100644
index 0000000..8ec8055
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-tabs/demo/index.html
@@ -0,0 +1,177 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+
+<html>
+ <head>
+
+ <title>paper-tabs</title>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../iron-flex-layout/classes/iron-flex-layout.html">
+
+ <link rel="import" href="../../paper-toolbar/paper-toolbar.html">
+
+ <link rel="import" href="../paper-tabs.html">
+ <link rel="import" href="../paper-tab.html">
+ <style is="custom-style">
+ :root {
+ --paper-toolbar-background: #00bcd4;
+ }
+
+ body {
+ font-family: sans-serif;
+ margin: 0;
+ padding: 24px;
+ color: #333;
+ }
+
+ paper-tabs, paper-toolbar {
+ background-color: #00bcd4;
+ color: #fff;
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.2);
+ }
+
+ paper-toolbar paper-tabs {
+ box-shadow: none;
+ }
+
+ paper-tabs[noink][no-bar] paper-tab.iron-selected {
+ color: #ffff8d;
+ }
+
+ paper-tabs[alignBottom] {
+ box-shadow: 0px -2px 6px rgba(0, 0, 0, 0.15);
+ }
+
+ h3 {
+ font-size: 16px;
+ font-weight: 400;
+ padding-top: 20px;
+ }
+
+ </style>
+
+ </head>
+ <body>
+
+ <h3>A. No ink effect and no sliding bar</h3>
+
+ <paper-tabs selected="0" noink no-bar>
+
+ <paper-tab>ITEM ONE</paper-tab>
+ <paper-tab>ITEM TWO</paper-tab>
+ <paper-tab>ITEM THREE</paper-tab>
+
+ </paper-tabs>
+
+ <h3>B. The bottom bar appears to indicate the selected tab, but without sliding effect.</h3>
+
+ <paper-tabs selected="0" noink no-slide>
+
+ <paper-tab>ITEM ONE</paper-tab>
+ <paper-tab>ITEM TWO</paper-tab>
+ <paper-tab>ITEM THREE</paper-tab>
+
+ </paper-tabs>
+
+ <h3>C. The bar slides to the selected tab</h3>
+
+ <paper-tabs selected="0" noink>
+
+ <paper-tab>ITEM ONE</paper-tab>
+ <paper-tab>ITEM TWO</paper-tab>
+ <paper-tab>ITEM THREE</paper-tab>
+
+ </paper-tabs>
+
+ <h3>D. Inky Tabs</h3>
+
+ <paper-tabs selected="0">
+
+ <paper-tab>ITEM ONE</paper-tab>
+ <paper-tab>ITEM TWO</paper-tab>
+ <paper-tab>ITEM THREE</paper-tab>
+
+ </paper-tabs>
+
+ <h3>E. Scrollable Tabs</h3>
+
+ <paper-tabs id="scrollableTabs" selected="0" scrollable>
+
+ <paper-tab>NUMBER ONE ITEM</paper-tab>
+ <paper-tab>ITEM TWO</paper-tab>
+ <paper-tab>THE THIRD ITEM</paper-tab>
+ <paper-tab>THE ITEM FOUR</paper-tab>
+ <paper-tab>FIFTH</paper-tab>
+ <paper-tab>THE SIXTH TAB</paper-tab>
+ <paper-tab>NUMBER SEVEN</paper-tab>
+ <paper-tab>EIGHT</paper-tab>
+ <paper-tab>NUMBER NINE</paper-tab>
+ <paper-tab>THE TENTH</paper-tab>
+ <paper-tab>THE ITEM ELEVEN</paper-tab>
+ <paper-tab>TWELFTH ITEM</paper-tab>
+
+ </paper-tabs>
+
+ <h3>F. Link Tabs</h3>
+
+ <paper-tabs selected="0">
+
+ <paper-tab link><a href="#item1" class="horizontal center-center layout">ITEM ONE</a></paper-tab>
+ <paper-tab link><a href="#item2" class="horizontal center-center layout">ITEM TWO</a></paper-tab>
+ <paper-tab link><a href="#item3" class="horizontal center-center layout">ITEM THREE</a></paper-tab>
+
+ </paper-tabs>
+
+ <h3>G. Tabs in Toolbar</h3>
+
+ <paper-toolbar class="tall">
+
+ <paper-tabs selected="0" class="bottom self-end" style="width: 300px;">
+
+ <paper-tab>ITEM ONE</paper-tab>
+ <paper-tab>ITEM TWO</paper-tab>
+
+ </paper-tabs>
+
+ <div class="bottom flex"></div>
+
+ </paper-toolbar>
+
+ <h3>H. Tabs aligned to bottom</h3>
+
+ <paper-tabs selected="0" alignBottom>
+
+ <paper-tab>ITEM ONE</paper-tab>
+ <paper-tab>ITEM TWO</paper-tab>
+ <paper-tab>ITEM THREE</paper-tab>
+
+ </paper-tabs>
+
+ <h3>I. Bound Selection</h3>
+
+ <template is="dom-bind">
+ <h2>Current Tab: <span>[[selected]]</span></h2>
+ <paper-tabs selected="{{selected}}">
+
+ <paper-tab>ITEM ONE</paper-tab>
+ <paper-tab>ITEM TWO</paper-tab>
+ <paper-tab>ITEM THREE</paper-tab>
+
+ </paper-tabs>
+ </template>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-tabs/hero.svg b/polymer_1.0.4/bower_components/paper-tabs/hero.svg
new file mode 100755
index 0000000..bfcbdac
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-tabs/hero.svg
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <path d="M188,78H37V44h151V78z M39,76h147V46H39V76z"/>
+ <polygon points="66,64.8 60.6,56.8 55.3,64.8 49.2,55.6 50.8,54.4 55.3,61.2 60.6,53.2 66,61.2 71.3,53.2 77.4,62.4 75.8,63.6
+ 71.3,56.8 "/>
+ <rect x="149" y="58" width="26" height="2"/>
+ <rect x="99" y="58" width="26" height="2"/>
+ <rect x="38" y="72" width="50" height="4"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-tabs/index.html b/polymer_1.0.4/bower_components/paper-tabs/index.html
new file mode 100644
index 0000000..98ab07d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-tabs/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <title>paper-tabs</title>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page sources='["paper-tabs.html", "paper-tab.html"]'></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-tabs/paper-tab.html b/polymer_1.0.4/bower_components/paper-tabs/paper-tab.html
new file mode 100644
index 0000000..4737ec8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-tabs/paper-tab.html
@@ -0,0 +1,158 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
+<link rel="import" href="../iron-behaviors/iron-control-state.html">
+<link rel="import" href="../paper-ripple/paper-ripple.html">
+
+<!--
+`paper-tab` is styled to look like a tab. It should be used in conjunction with
+`paper-tabs`.
+
+Example:
+
+ <paper-tabs selected="0">
+ <paper-tab>TAB 1</paper-tab>
+ <paper-tab>TAB 2</paper-tab>
+ <paper-tab>TAB 3</paper-tab>
+ </paper-tabs>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-tab-ink` | Ink color | `--paper-yellow-a100`
+`--paper-tab` | Mixin applied to the tab | `{}`
+`--paper-tab-content` | Mixin applied to the tab content | `{}`
+
+-->
+
+<dom-module id="paper-tab">
+
+ <style>
+
+ :host {
+ @apply(--layout-inline);
+ @apply(--layout-center);
+ @apply(--layout-center-justified);
+ @apply(--layout-flex);
+
+ position: relative;
+ padding: 0 12px;
+ overflow: hidden;
+ cursor: pointer;
+
+ @apply(--paper-tab);
+ }
+
+ :host(:focus) {
+ outline: none;
+ }
+
+ :host([link]) {
+ padding: 0;
+ }
+
+ .tab-content {
+ height: 100%;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ transition: opacity 0.1s cubic-bezier(0.4, 0.0, 1, 1);
+
+ @apply(--paper-tab-content);
+ }
+
+ :host(:not(.iron-selected)) > .tab-content {
+ opacity: 0.8;
+ }
+
+ :host(:focus) .tab-content {
+ opacity: 1;
+ font-weight: 700;
+ }
+
+ #ink {
+ color: var(--paper-tab-ink, --paper-yellow-a100);
+ pointer-events: none;
+ }
+
+ .tab-content > ::content > a {
+ height: 100%;
+ /* flex */
+ -ms-flex: 1 1 0.000000001px;
+ -webkit-flex: 1;
+ flex: 1;
+ -webkit-flex-basis: 0.000000001px;
+ flex-basis: 0.000000001px;
+ }
+
+ </style>
+
+ <template>
+
+ <div class="tab-content flex-auto center-center horizontal layout">
+ <content></content>
+ </div>
+
+ <template is="dom-if" if="[[!noink]]">
+ <paper-ripple id="ink" initial-opacity="0.95" opacity-decay-velocity="0.98"></paper-ripple>
+ </template>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'paper-tab',
+
+ behaviors: [
+ Polymer.IronControlState
+ ],
+
+ properties: {
+
+ /**
+ * If true, ink ripple effect is disabled.
+ *
+ * @attribute noink
+ */
+ noink: {
+ type: Boolean,
+ value: false
+ }
+
+ },
+
+ hostAttributes: {
+ role: 'tab'
+ },
+
+ listeners: {
+ down: '_onDown'
+ },
+
+ get _parentNoink () {
+ var parent = Polymer.dom(this).parentNode;
+ return !!parent && !!parent.noink;
+ },
+
+ _onDown: function(e) {
+ this.noink = !!this.noink || !!this._parentNoink;
+ }
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-tabs/paper-tabs-icons.html b/polymer_1.0.4/bower_components/paper-tabs/paper-tabs-icons.html
new file mode 100644
index 0000000..c299046
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-tabs/paper-tabs-icons.html
@@ -0,0 +1,18 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../iron-iconset-svg/iron-iconset-svg.html">
+
+<iron-iconset-svg name="paper-tabs" size="24">
+<svg><defs>
+<g id="chevron-left"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></g>
+<g id="chevron-right"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></g>
+</defs></svg>
+</iron-iconset-svg>
diff --git a/polymer_1.0.4/bower_components/paper-tabs/paper-tabs.html b/polymer_1.0.4/bower_components/paper-tabs/paper-tabs.html
new file mode 100644
index 0000000..ca648df
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-tabs/paper-tabs.html
@@ -0,0 +1,483 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
+<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
+<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html">
+<link rel="import" href="../iron-menu-behavior/iron-menubar-behavior.html">
+<link rel="import" href="../iron-icon/iron-icon.html">
+<link rel="import" href="../paper-icon-button/paper-icon-button.html">
+<link rel="import" href="../paper-styles/color.html">
+<link rel="import" href="paper-tabs-icons.html">
+<link rel="import" href="paper-tab.html">
+
+<!--
+`paper-tabs` makes it easy to explore and switch between different views or functional aspects of
+an app, or to browse categorized data sets.
+
+Use `selected` property to get or set the selected tab.
+
+Example:
+
+ <paper-tabs selected="0">
+ <paper-tab>TAB 1</paper-tab>
+ <paper-tab>TAB 2</paper-tab>
+ <paper-tab>TAB 3</paper-tab>
+ </paper-tabs>
+
+See <a href="#paper-tab">paper-tab</a> for more information about
+`paper-tab`.
+
+A common usage for `paper-tabs` is to use it along with `iron-pages` to switch
+between different views.
+
+ <paper-tabs selected="{{selected}}">
+ <paper-tab>Tab 1</paper-tab>
+ <paper-tab>Tab 2</paper-tab>
+ <paper-tab>Tab 3</paper-tab>
+ </paper-tabs>
+
+ <iron-pages selected="{{selected}}">
+ <div>Page 1</div>
+ <div>Page 2</div>
+ <div>Page 3</div>
+ </iron-pages>
+
+
+To use links in tabs, add `link` attribute to `paper-tab` and put an `<a>`
+element in `paper-tab`.
+
+Example:
+
+ <paper-tabs selected="0">
+ <paper-tab link>
+ <a href="#link1" class="horizontal center-center layout">TAB ONE</a>
+ </paper-tab>
+ <paper-tab link>
+ <a href="#link2" class="horizontal center-center layout">TAB TWO</a>
+ </paper-tab>
+ <paper-tab link>
+ <a href="#link3" class="horizontal center-center layout">TAB THREE</a>
+ </paper-tab>
+ </paper-tabs>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-tabs-selection-bar-color` | Color for the selection bar | `--paper-yellow-a100`
+`--paper-tabs` | Mixin applied to the tabs | `{}`
+
+@hero hero.svg
+@demo demo/index.html
+-->
+
+<dom-module id="paper-tabs">
+
+ <style>
+
+ :host {
+ @apply(--layout);
+ @apply(--layout-center);
+
+ height: 48px;
+ font-size: 14px;
+ font-weight: 500;
+ overflow: hidden;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ -webkit-tap-highlight-color: rgba(0,0,0,0);
+
+ @apply(--paper-tabs);
+ }
+
+ #tabsContainer {
+ position: relative;
+ height: 100%;
+ white-space: nowrap;
+ overflow: hidden;
+ }
+
+ #tabsContent {
+ height: 100%;
+ }
+
+ #tabsContent.scrollable {
+ position: absolute;
+ white-space: nowrap;
+ }
+
+ .hidden {
+ display: none;
+ }
+
+ .not-visible {
+ opacity: 0;
+ }
+
+ paper-icon-button {
+ width: 24px;
+ padding: 16px;
+ }
+
+ #selectionBar {
+ position: absolute;
+ height: 2px;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background-color: var(--paper-tabs-selection-bar-color, --paper-yellow-a100);
+ -webkit-transform-origin: left center;
+ transform-origin: left center;
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ transition: -webkit-transform;
+ transition: transform;
+
+ @apply(--paper-tabs-selection-bar);
+ }
+
+ #selectionBar.align-bottom {
+ top: 0;
+ bottom: auto;
+ }
+
+ #selectionBar.expand {
+ transition-duration: 0.15s;
+ transition-timing-function: cubic-bezier(0.4, 0.0, 1, 1);
+ }
+
+ #selectionBar.contract {
+ transition-duration: 0.18s;
+ transition-timing-function: cubic-bezier(0.0, 0.0, 0.2, 1);
+ }
+
+ #tabsContent > ::content > *:not(#selectionBar) {
+ height: 100%;
+ }
+
+ </style>
+
+ <template>
+
+ <paper-icon-button icon="paper-tabs:chevron-left" class$="[[_computeScrollButtonClass(_leftHidden, scrollable, hideScrollButtons)]]" on-up="_onScrollButtonUp" on-down="_onLeftScrollButtonDown"></paper-icon-button>
+
+ <div id="tabsContainer" class="flex" on-scroll="_scroll">
+
+ <div id="tabsContent" class$="[[_computeTabsContentClass(scrollable)]]">
+
+ <content select="*"></content>
+
+ <div id="selectionBar" class$="[[_computeSelectionBarClass(noBar, alignBottom)]]"
+ on-transitionend="_onBarTransitionEnd"></div>
+
+ </div>
+
+ </div>
+
+ <paper-icon-button icon="paper-tabs:chevron-right" class$="[[_computeScrollButtonClass(_rightHidden, scrollable, hideScrollButtons)]]" on-up="_onScrollButtonUp" on-down="_onRightScrollButtonDown"></paper-icon-button>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ Polymer({
+
+ is: 'paper-tabs',
+
+ behaviors: [
+ Polymer.IronResizableBehavior,
+ Polymer.IronMenubarBehavior
+ ],
+
+ properties: {
+
+ /**
+ * If true, ink ripple effect is disabled.
+ */
+ noink: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, the bottom bar to indicate the selected tab will not be shown.
+ */
+ noBar: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, the slide effect for the bottom bar is disabled.
+ */
+ noSlide: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, tabs are scrollable and the tab width is based on the label width.
+ */
+ scrollable: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, dragging on the tabs to scroll is disabled.
+ */
+ disableDrag: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, scroll buttons (left/right arrow) will be hidden for scrollable tabs.
+ */
+ hideScrollButtons: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * If true, the tabs are aligned to bottom (the selection bar appears at the top).
+ */
+ alignBottom: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Gets or sets the selected element. The default is to use the index of the item.
+ */
+ selected: {
+ type: String,
+ notify: true
+ },
+
+ selectable: {
+ type: String,
+ value: 'paper-tab'
+ },
+
+ _step: {
+ type: Number,
+ value: 10
+ },
+
+ _holdDelay: {
+ type: Number,
+ value: 1
+ },
+
+ _leftHidden: {
+ type: Boolean,
+ value: false
+ },
+
+ _rightHidden: {
+ type: Boolean,
+ value: false
+ },
+
+ _previousTab: {
+ type: Object
+ }
+ },
+
+ hostAttributes: {
+ role: 'tablist'
+ },
+
+ listeners: {
+ 'iron-resize': '_onResize',
+ 'iron-select': '_onIronSelect',
+ 'iron-deselect': '_onIronDeselect'
+ },
+
+ _computeScrollButtonClass: function(hideThisButton, scrollable, hideScrollButtons) {
+ if (!scrollable || hideScrollButtons) {
+ return 'hidden';
+ }
+
+ if (hideThisButton) {
+ return 'not-visible';
+ }
+
+ return '';
+ },
+
+ _computeTabsContentClass: function(scrollable) {
+ return scrollable ? 'scrollable' : 'horizontal layout';
+ },
+
+ _computeSelectionBarClass: function(noBar, alignBottom) {
+ if (noBar) {
+ return 'hidden';
+ } else if (alignBottom) {
+ return 'align-bottom';
+ }
+ },
+
+ // TODO(cdata): Add `track` response back in when gesture lands.
+
+ _onResize: function() {
+ this.debounce('_onResize', function() {
+ this._scroll();
+ this._tabChanged(this.selectedItem);
+ }, 10);
+ },
+
+ _onIronSelect: function(event) {
+ this._tabChanged(event.detail.item, this._previousTab);
+ this._previousTab = event.detail.item;
+ this.cancelDebouncer('tab-changed');
+ },
+
+ _onIronDeselect: function(event) {
+ this.debounce('tab-changed', function() {
+ this._tabChanged(null, this._previousTab);
+ // See polymer/polymer#1305
+ }, 1);
+ },
+
+ get _tabContainerScrollSize () {
+ return Math.max(
+ 0,
+ this.$.tabsContainer.scrollWidth -
+ this.$.tabsContainer.offsetWidth
+ );
+ },
+
+ _scroll: function() {
+ var scrollLeft;
+
+ if (!this.scrollable) {
+ return;
+ }
+
+ scrollLeft = this.$.tabsContainer.scrollLeft;
+
+ this._leftHidden = scrollLeft === 0;
+ this._rightHidden = scrollLeft === this._tabContainerScrollSize;
+ },
+
+ _onLeftScrollButtonDown: function() {
+ this._holdJob = setInterval(this._scrollToLeft.bind(this), this._holdDelay);
+ },
+
+ _onRightScrollButtonDown: function() {
+ this._holdJob = setInterval(this._scrollToRight.bind(this), this._holdDelay);
+ },
+
+ _onScrollButtonUp: function() {
+ clearInterval(this._holdJob);
+ this._holdJob = null;
+ },
+
+ _scrollToLeft: function() {
+ this.$.tabsContainer.scrollLeft -= this._step;
+ },
+
+ _scrollToRight: function() {
+ this.$.tabsContainer.scrollLeft += this._step;
+ },
+
+ _tabChanged: function(tab, old) {
+ if (!tab) {
+ this._positionBar(0, 0);
+ return;
+ }
+
+ var r = this.$.tabsContent.getBoundingClientRect();
+ var w = r.width;
+ var tabRect = tab.getBoundingClientRect();
+ var tabOffsetLeft = tabRect.left - r.left;
+
+ this._pos = {
+ width: this._calcPercent(tabRect.width, w),
+ left: this._calcPercent(tabOffsetLeft, w)
+ };
+
+ if (this.noSlide || old == null) {
+ // position bar directly without animation
+ this._positionBar(this._pos.width, this._pos.left);
+ return;
+ }
+
+ var oldRect = old.getBoundingClientRect();
+ var oldIndex = this.items.indexOf(old);
+ var index = this.items.indexOf(tab);
+ var m = 5;
+
+ // bar animation: expand
+ this.$.selectionBar.classList.add('expand');
+
+ if (oldIndex < index) {
+ this._positionBar(this._calcPercent(tabRect.left + tabRect.width - oldRect.left, w) - m,
+ this._left);
+ } else {
+ this._positionBar(this._calcPercent(oldRect.left + oldRect.width - tabRect.left, w) - m,
+ this._calcPercent(tabOffsetLeft, w) + m);
+ }
+
+ if (this.scrollable) {
+ this._scrollToSelectedIfNeeded(tabRect.width, tabOffsetLeft);
+ }
+ },
+
+ _scrollToSelectedIfNeeded: function(tabWidth, tabOffsetLeft) {
+ var l = tabOffsetLeft - this.$.tabsContainer.scrollLeft;
+ if (l < 0) {
+ this.$.tabsContainer.scrollLeft += l;
+ } else {
+ l += (tabWidth - this.$.tabsContainer.offsetWidth);
+ if (l > 0) {
+ this.$.tabsContainer.scrollLeft += l;
+ }
+ }
+ },
+
+ _calcPercent: function(w, w0) {
+ return 100 * w / w0;
+ },
+
+ _positionBar: function(width, left) {
+ this._width = width;
+ this._left = left;
+ this.transform(
+ 'translate3d(' + left + '%, 0, 0) scaleX(' + (width / 100) + ')',
+ this.$.selectionBar);
+ },
+
+ _onBarTransitionEnd: function(e) {
+ var cl = this.$.selectionBar.classList;
+ // bar animation: expand -> contract
+ if (cl.contains('expand')) {
+ cl.remove('expand');
+ cl.add('contract');
+ this._positionBar(this._pos.width, this._pos.left);
+ // bar animation done
+ } else if (cl.contains('contract')) {
+ cl.remove('contract');
+ }
+ }
+
+ });
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-tabs/test/attr-for-selected.html b/polymer_1.0.4/bower_components/paper-tabs/test/attr-for-selected.html
new file mode 100644
index 0000000..2f5aa6d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-tabs/test/attr-for-selected.html
@@ -0,0 +1,82 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <title>paper-tabs-attr-for-selected</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../paper-tabs.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="basic">
+ <template>
+ <paper-tabs attr-for-selected="name" selected="bar">
+ <paper-tab name="foo">ITEM FOO</paper-tab>
+ <paper-tab name="bar">ITEM BAR</paper-tab>
+ <paper-tab name="zot">ITEM ZOT</paper-tab>
+ </paper-tabs>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ suite('set the selected attribute', function() {
+
+ var tabs;
+
+ setup(function () {
+ tabs = fixture('basic');
+ });
+
+ test('selected value', function() {
+ assert.equal(tabs.selected, 'bar');
+ });
+
+ test('selected tab has iron-selected class', function() {
+ assert.isTrue(tabs.querySelector('[name=bar]').classList.contains('iron-selected'));
+ });
+
+ });
+
+ suite('select tab via click', function() {
+
+ var tabs, tab;
+
+ setup(function () {
+ tabs = fixture('basic');
+ tab = tabs.querySelector('[name=zot]');
+ tab.dispatchEvent(new CustomEvent('click', {bubbles: true}));
+ });
+
+ test('selected value', function() {
+ assert.equal(tabs.selected, 'zot');
+ });
+
+ test('selected tab has iron-selected class', function() {
+ assert.isTrue(tab.classList.contains('iron-selected'));
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-tabs/test/basic.html b/polymer_1.0.4/bower_components/paper-tabs/test/basic.html
new file mode 100644
index 0000000..aa74207
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-tabs/test/basic.html
@@ -0,0 +1,157 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <title>paper-tabs-basic</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../paper-tabs.html">
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="basic">
+ <template>
+ <paper-tabs>
+ <paper-tab>ITEM ONE</paper-tab>
+ <paper-tab>ITEM TWO</paper-tab>
+ <paper-tab>ITEM THREE</paper-tab>
+ </paper-tabs>
+ </template>
+ </test-fixture>
+
+ <script>
+
+ function checkSelectionBar(tabs, tab) {
+ var tabRect = tab.getBoundingClientRect();
+ var rect = Polymer.dom(tabs.root).querySelector('#selectionBar').getBoundingClientRect();
+ assert.equal(Math.round(tabRect.left), Math.round(rect.left));
+ }
+
+ suite('defaults', function() {
+
+ var tabs;
+
+ setup(function () {
+ tabs = fixture('basic');
+ });
+
+ test('to nothing selected', function() {
+ assert.equal(tabs.selected, undefined);
+ });
+
+ test('no tabs have iron-selected class', function() {
+ Array.prototype.forEach.call(tabs.querySelectorAll('paper-tab'), function(tab) {
+ assert.isFalse(tab.classList.contains('iron-selected'));
+ });
+ });
+
+ test('to false as noink', function() {
+ assert.equal(tabs.noink, false);
+ });
+
+ test('to false as noBar', function() {
+ assert.equal(tabs.noBar, false);
+ });
+
+ test('to false as noSlide', function() {
+ assert.equal(tabs.noSlide, false);
+ });
+
+ test('to false as scrollable', function() {
+ assert.equal(tabs.scrollable, false);
+ });
+
+ test('to false as disableDrag', function() {
+ assert.equal(tabs.disableDrag, false);
+ });
+
+ test('to false as hideScrollButtons', function() {
+ assert.equal(tabs.hideScrollButtons, false);
+ });
+
+ test('to false as alignBottom', function() {
+ assert.equal(tabs.alignBottom, false);
+ });
+
+ test('has role tablist', function() {
+ assert.equal(tabs.getAttribute('role'), 'tablist');
+ });
+
+ });
+
+ suite('set the selected attribute', function() {
+
+ var tabs, index = 0;
+
+ setup(function () {
+ tabs = fixture('basic');
+ tabs.selected = index;
+ });
+
+ test('selected value', function() {
+ assert.equal(tabs.selected, index);
+ });
+
+ test('selected tab has iron-selected class', function() {
+ var tab = tabs.querySelectorAll('paper-tab')[index];
+ assert.isTrue(tab.classList.contains('iron-selected'));
+ });
+
+ test('selected tab has selection bar position at the bottom of the tab', function(done) {
+ setTimeout(function() {
+ checkSelectionBar(tabs, tabs.querySelectorAll('paper-tab')[index]);
+ done();
+ }, 1000);
+ });
+
+ });
+
+ suite('select tab via click', function() {
+
+ var tabs, index = 1;
+
+ setup(function () {
+ tabs = fixture('basic');
+ var tab = tabs.querySelectorAll('paper-tab')[index];
+ tab.dispatchEvent(new CustomEvent('click', {bubbles: true}));
+ });
+
+ test('selected value', function() {
+ assert.equal(tabs.selected, index);
+ });
+
+ test('selected tab has iron-selected class', function() {
+ var tab = tabs.querySelectorAll('paper-tab')[index];
+ assert.isTrue(tab.classList.contains('iron-selected'));
+ });
+
+ test('selected tab has selection bar position at the bottom of the tab', function(done) {
+ setTimeout(function() {
+ checkSelectionBar(tabs, tabs.querySelectorAll('paper-tab')[index]);
+ done();
+ }, 1000);
+ });
+
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-tabs/test/index.html b/polymer_1.0.4/bower_components/paper-tabs/test/index.html
new file mode 100644
index 0000000..2a3282b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-tabs/test/index.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<html>
+ <head>
+
+ <meta charset="utf-8">
+ <title>Tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+
+ </head>
+ <body>
+
+ <script>
+
+ WCT.loadSuites([
+ 'basic.html',
+ 'attr-for-selected.html'
+ ]);
+
+ </script>
+
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-toast/.bower.json b/polymer_1.0.4/bower_components/paper-toast/.bower.json
new file mode 100644
index 0000000..3c32c49
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toast/.bower.json
@@ -0,0 +1,38 @@
+{
+ "name": "paper-toast",
+ "version": "1.0.0",
+ "description": "A material design notification toast",
+ "private": true,
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "toast",
+ "notification"
+ ],
+ "main": "paper-toast.html",
+ "dependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-a11y-announcer": "polymerelements/iron-a11y-announcer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "paper-button": "polymerelements/paper-button#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/paper-toast",
+ "_release": "1.0.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.0",
+ "commit": "71e6c327f7aafe9c71010c83d4c4571f63990072"
+ },
+ "_source": "git://github.com/PolymerElements/paper-toast.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-toast"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-toast/.gitignore b/polymer_1.0.4/bower_components/paper-toast/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toast/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-toast/README.md b/polymer_1.0.4/bower_components/paper-toast/README.md
new file mode 100644
index 0000000..722ec35
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toast/README.md
@@ -0,0 +1,4 @@
+paper-toast
+============
+
+A material design notification toast.
diff --git a/polymer_1.0.4/bower_components/paper-toast/bower.json b/polymer_1.0.4/bower_components/paper-toast/bower.json
new file mode 100644
index 0000000..a4fd51a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toast/bower.json
@@ -0,0 +1,28 @@
+{
+ "name": "paper-toast",
+ "version": "1.0.0",
+ "description": "A material design notification toast",
+ "private": true,
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "toast",
+ "notification"
+ ],
+ "main": "paper-toast.html",
+ "dependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0",
+ "iron-a11y-announcer": "polymerelements/iron-a11y-announcer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "polymerelements/iron-component-page#^1.0.0",
+ "paper-button": "polymerelements/paper-button#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-toast/demo/index.html b/polymer_1.0.4/bower_components/paper-toast/demo/index.html
new file mode 100644
index 0000000..fbd0f0e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toast/demo/index.html
@@ -0,0 +1,56 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <title>paper-toast</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../paper-toast.html">
+ <link rel="import" href="../../paper-button/paper-button.html" >
+
+ <style>
+ html, body {
+ height: 100%;
+ }
+
+ body {
+ overflow: hidden;
+ margin: 0;
+ font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
+ -webkit-tap-highlight-color: rgba(0,0,0,0);
+ -webkit-touch-callout: none;
+ }
+
+ paper-button {
+ margin: 20px;
+ }
+ </style>
+
+</head>
+<body>
+
+ <paper-button raised onclick="document.querySelector('#toast1').show()">Discard Draft</paper-button>
+
+ <paper-button raised onclick="document.querySelector('#toast2').show()">Get Messages</paper-button>
+
+ <paper-toast id="toast1" text="Your draft has been discarded."></paper-toast>
+
+ <paper-toast id="toast2" text="Connection timed out. Showing limited messages.">
+ <span role="button" tabindex="0" style="color: #eeff41;margin: 10px" onclick="console.log('RETRY')">Retry</span>
+ </paper-toast>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-toast/hero.svg b/polymer_1.0.4/bower_components/paper-toast/hero.svg
new file mode 100755
index 0000000..bfdc180
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toast/hero.svg
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <path d="M164,114H13V88h151V114z M15,112h147V90H15V112z"/>
+ <rect x="26" y="100" width="79" height="2"/>
+ <rect x="135" y="100" width="16" height="2"/>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-toast/index.html b/polymer_1.0.4/bower_components/paper-toast/index.html
new file mode 100644
index 0000000..e871f17
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toast/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-toast/paper-toast.html b/polymer_1.0.4/bower_components/paper-toast/paper-toast.html
new file mode 100644
index 0000000..5afdae3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toast/paper-toast.html
@@ -0,0 +1,164 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-styles/typography.html">
+<link rel="import" href="../iron-a11y-announcer/iron-a11y-announcer.html">
+
+<!--
+`paper-toast` provides a subtle notification toast.
+
+@group Paper Elements
+@element paper-toast
+@demo demo/index.html
+@hero hero.svg
+-->
+<dom-module id="paper-toast">
+ <style>
+ :host {
+ display: inline-block;
+ position: fixed;
+
+ background: #323232;
+ color: #f1f1f1;
+ min-height: 48px;
+ min-width: 288px;
+ padding: 16px 24px 12px;
+ box-sizing: border-box;
+ box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
+ border-radius: 2px;
+ bottom: 12px;
+ left: 12px;
+ font-size: 14px;
+ cursor: default;
+
+ -webkit-transition: visibility 0.3s, -webkit-transform 0.3s;
+ transition: visibility 0.3s, transform 0.3s;
+
+ -webkit-transform: translateY(100px);
+ transform: translateY(100px);
+
+ visibility: hidden;
+ }
+
+ :host(.capsule) {
+ border-radius: 24px;
+ }
+
+ :host(.fit-bottom) {
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ min-width: 0;
+ border-radius: 0;
+ }
+
+ :host(.paper-toast-open){
+ visibility: visible;
+
+ -webkit-transform: translateY(0px);
+ transform: translateY(0px);
+ }
+ </style>
+ <template>
+ <span id="label">{{text}}</span>
+ <content></content>
+ </template>
+</dom-module>
+<script>
+(function() {
+
+ var PaperToast = Polymer({
+ is: 'paper-toast',
+
+ properties: {
+ /**
+ * The duration in milliseconds to show the toast.
+ */
+ duration: {
+ type: Number,
+ value: 3000
+ },
+
+ /**
+ * The text to display in the toast.
+ */
+ text: {
+ type: String,
+ value: ""
+ },
+
+ /**
+ * True if the toast is currently visible.
+ */
+ visible: {
+ type: Boolean,
+ readOnly: true,
+ value: false,
+ observer: '_visibleChanged'
+ }
+ },
+
+ created: function() {
+ Polymer.IronA11yAnnouncer.requestAvailability();
+ },
+
+ ready: function() {
+ this.async(function() {
+ this.hide();
+ });
+ },
+
+ /**
+ * Show the toast.
+ * @method show
+ */
+ show: function() {
+ if (PaperToast.currentToast) {
+ PaperToast.currentToast.hide();
+ }
+ PaperToast.currentToast = this;
+ this.removeAttribute('aria-hidden');
+ this._setVisible(true);
+ this.fire('iron-announce', {
+ text: this.text
+ });
+ this.debounce('hide', this.hide, this.duration);
+ },
+
+ /**
+ * Hide the toast
+ */
+ hide: function() {
+ this.setAttribute('aria-hidden', 'true');
+ this._setVisible(false);
+ },
+
+ /**
+ * Toggle the opened state of the toast.
+ * @method toggle
+ */
+ toggle: function() {
+ if (!this.visible) {
+ this.show();
+ } else {
+ this.hide();
+ }
+ },
+
+ _visibleChanged: function(visible) {
+ this.toggleClass('paper-toast-open', visible);
+ }
+ });
+
+ PaperToast.currentToast = null;
+
+})();
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-toggle-button/.bower.json b/polymer_1.0.4/bower_components/paper-toggle-button/.bower.json
new file mode 100644
index 0000000..db09a19
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toggle-button/.bower.json
@@ -0,0 +1,45 @@
+{
+ "name": "paper-toggle-button",
+ "version": "1.0.3",
+ "description": "A material design toggle button control",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "toggle",
+ "control"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-toggle-button"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-toggle-button",
+ "ignore": [],
+ "dependencies": {
+ "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.3",
+ "commit": "34235a35f65be5efadc8fc5c6f6e5dee0fbb6c52"
+ },
+ "_source": "git://github.com/PolymerElements/paper-toggle-button.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-toggle-button"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-toggle-button/.gitignore b/polymer_1.0.4/bower_components/paper-toggle-button/.gitignore
new file mode 100644
index 0000000..8d4ae25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toggle-button/.gitignore
@@ -0,0 +1 @@
+bower_components
diff --git a/polymer_1.0.4/bower_components/paper-toggle-button/README.md b/polymer_1.0.4/bower_components/paper-toggle-button/README.md
new file mode 100644
index 0000000..0924fe2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toggle-button/README.md
@@ -0,0 +1,26 @@
+paper-toggle-button
+===================
+
+`paper-toggle-button` provides a ON/OFF switch that user can toggle the state
+by tapping or by dragging the swtich.
+
+Example:
+
+```html
+<paper-toggle-button></paper-toggle-button>
+```
+
+Styling toggle-button:
+
+```html
+<style is="custom-style">
+ * {
+ --paper-toggle-button-unchecked-bar-color: #FF4081;
+ --paper-toggle-button-unchecked-button-color: #9c27b0;
+ --paper-toggle-button-unchecked-ink-color: #009688;
+ --paper-toggle-button-checked-bar-color: #5677fc;
+ --paper-toggle-button-checked-button-color: #ff4081;
+ --paper-toggle-button-checked-ink-color: #ff4081;
+ }
+</style>
+```
diff --git a/polymer_1.0.4/bower_components/paper-toggle-button/bower.json b/polymer_1.0.4/bower_components/paper-toggle-button/bower.json
new file mode 100644
index 0000000..2a80170
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toggle-button/bower.json
@@ -0,0 +1,36 @@
+{
+ "name": "paper-toggle-button",
+ "version": "1.0.3",
+ "description": "A material design toggle button control",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "toggle",
+ "control"
+ ],
+ "private": true,
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-toggle-button"
+ },
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/paper-toggle-button",
+ "ignore": [],
+ "dependencies": {
+ "paper-ripple": "PolymerElements/paper-ripple#^1.0.0",
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "web-component-tester": "*",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0",
+ "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-toggle-button/demo/index.html b/polymer_1.0.4/bower_components/paper-toggle-button/demo/index.html
new file mode 100644
index 0000000..2c9c8c5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toggle-button/demo/index.html
@@ -0,0 +1,106 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <title>paper-toggle-button demo</title>
+
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+ <meta name="mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/demo-pages.html">
+ <link rel="import" href="../paper-toggle-button.html">
+
+ <style is="custom-style">
+ .line {
+ margin-bottom: 40px;
+ }
+
+ .line span {
+ margin-left: 24px;
+ }
+
+ paper-toggle-button.blue {
+ --paper-toggle-button-checked-bar-color: var(--paper-light-blue-500);
+ --paper-toggle-button-checked-button-color: var(--paper-light-blue-500);
+ --paper-toggle-button-checked-ink-color: var(--paper-light-blue-500);
+ --paper-toggle-button-unchecked-bar-color: var(--paper-light-blue-900);
+ --paper-toggle-button-unchecked-button-color: var(--paper-light-blue-900);
+ --paper-toggle-button-unchecked-ink-color: var(--paper-light-blue-900);
+ }
+
+ paper-toggle-button.red {
+ --paper-toggle-button-checked-bar-color: var(--paper-red-500);
+ --paper-toggle-button-checked-button-color: var(--paper-red-500);
+ --paper-toggle-button-checked-ink-color: var(--paper-red-500);
+ --paper-toggle-button-unchecked-bar-color: var(--paper-red-900);
+ --paper-toggle-button-unchecked-button-color: var(--paper-red-900);
+ --paper-toggle-button-unchecked-ink-color: var(--paper-red-900);
+ }
+
+ paper-toggle-button.green {
+ --paper-toggle-button-checked-bar-color: var(--paper-green-500);
+ --paper-toggle-button-checked-button-color: var(--paper-green-500);
+ --paper-toggle-button-checked-ink-color: var(--paper-green-500);
+ --paper-toggle-button-unchecked-bar-color: var(--paper-green-900);
+ --paper-toggle-button-unchecked-button-color: var(--paper-green-900);
+ --paper-toggle-button-unchecked-ink-color: var(--paper-green-900);
+ }
+
+ paper-toggle-button.orange {
+ --paper-toggle-button-checked-bar-color: var(--paper-orange-500);
+ --paper-toggle-button-checked-button-color: var(--paper-orange-500);
+ --paper-toggle-button-checked-ink-color: var(--paper-orange-500);
+ --paper-toggle-button-unchecked-bar-color: var(--paper-orange-900);
+ --paper-toggle-button-unchecked-button-color: var(--paper-orange-900);
+ --paper-toggle-button-unchecked-ink-color: var(--paper-orange-900);
+ }
+ </style>
+ </head>
+ <body>
+ <div class="horizontal center-justified layout">
+ <div>
+ <h4>Enabled</h4>
+ <div class="horizontal-section">
+ <div class="line"><paper-toggle-button></paper-toggle-button><span>Oxygen</span></div>
+ <div class="line"><paper-toggle-button></paper-toggle-button><span>Carbon</span></div>
+ <div class="line"><paper-toggle-button checked></paper-toggle-button><span>Hydrogen</span></div>
+ <div class="line"><paper-toggle-button checked></paper-toggle-button><span>Nitrogen</span></div>
+ <div class="line"><paper-toggle-button checked></paper-toggle-button><span>Calcium</span></div>
+ </div>
+ </div>
+
+ <div>
+ <h4>Disabled</h4>
+ <div class="horizontal-section">
+ <div class="line"><paper-toggle-button disabled></paper-toggle-button><span>Oxygen</span></div>
+ <div class="line"><paper-toggle-button disabled></paper-toggle-button><span>Carbon</span></div>
+ <div class="line"><paper-toggle-button checked disabled></paper-toggle-button><span>Hydrogen</span></div>
+ <div class="line"><paper-toggle-button checked disabled></paper-toggle-button><span>Nitrogen</span></div>
+ <div class="line"><paper-toggle-button checked disabled></paper-toggle-button><span>Calcium</span></div>
+ </div>
+ </div>
+
+ <div>
+ <h4>Color</h4>
+ <div class="horizontal-section">
+ <div class="line"><paper-toggle-button class="blue"></paper-toggle-button><span>Oxygen</span></div>
+ <div class="line"><paper-toggle-button class="red"></paper-toggle-button><span>Carbon</span></div>
+ <div class="line"><paper-toggle-button checked class="orange"></paper-toggle-button><span>Hydrogen</span></div>
+ <div class="line"><paper-toggle-button checked class="green"></paper-toggle-button><span>Nitrogen</span></div>
+ <div class="line"><paper-toggle-button checked class="blue"></paper-toggle-button><span>Calcium</span></div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-toggle-button/hero.svg b/polymer_1.0.4/bower_components/paper-toggle-button/hero.svg
new file mode 100755
index 0000000..21607b2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toggle-button/hero.svg
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
+<g id="background" display="none">
+ <rect display="inline" fill="#B0BEC5" width="225" height="126"/>
+</g>
+<g id="label">
+</g>
+<g id="art">
+ <g>
+ <circle cx="123.8" cy="63" r="15.7"/>
+ <path d="M123,77H98.5c-7.7,0-14-6.3-14-14s6.3-14,14-14H123c7.7,0,14,6.3,14,14S130.7,77,123,77z M98.5,51c-6.6,0-12,5.4-12,12
+ s5.4,12,12,12H123c6.6,0,12-5.4,12-12s-5.4-12-12-12H98.5z"/>
+ </g>
+ <g id="ic_x5F_add_x0D_">
+ </g>
+</g>
+<g id="Guides">
+</g>
+</svg>
diff --git a/polymer_1.0.4/bower_components/paper-toggle-button/index.html b/polymer_1.0.4/bower_components/paper-toggle-button/index.html
new file mode 100644
index 0000000..e871f17
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toggle-button/index.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-toggle-button/paper-toggle-button.css b/polymer_1.0.4/bower_components/paper-toggle-button/paper-toggle-button.css
new file mode 100644
index 0000000..bdadd9d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toggle-button/paper-toggle-button.css
@@ -0,0 +1,108 @@
+/*
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+*/
+
+:host {
+ display: inline-block;
+}
+
+:host([disabled]) {
+ pointer-events: none;
+}
+
+:host(:focus) {
+ outline:none;
+}
+
+:host .toggle-bar {
+ background-color: var(--paper-toggle-button-unchecked-bar-color, #000000);
+}
+
+:host .toggle-button {
+ background-color: var(--paper-toggle-button-unchecked-button-color, --paper-grey-50);
+}
+
+:host([checked]) .toggle-bar {
+ background-color: var(--paper-toggle-button-checked-bar-color, --google-green-500);
+}
+
+:host([checked]) .toggle-button {
+ background-color: var(--paper-toggle-button-checked-button-color, --google-green-500);
+}
+
+:host .toggle-ink {
+ color: var(--paper-toggle-button-unchecked-ink-color, --primary-text-color);
+}
+
+:host([checked]) .toggle-ink {
+ color: var(--paper-toggle-button-checked-ink-color, --google-green-500);
+}
+
+/* ID selectors should not be overriden by users. */
+
+#toggleContainer {
+ position: relative;
+ width: 36px;
+ height: 14px;
+}
+
+#toggleBar {
+ position: absolute;
+ height: 100%;
+ width: 100%;
+ border-radius: 8px;
+ pointer-events: none;
+ opacity: 0.4;
+ transition: background-color linear .08s;
+}
+
+:host([checked]) #toggleBar {
+ opacity: 0.5;
+}
+
+:host([disabled]) #toggleBar {
+ background-color: #000;
+ opacity: 0.12;
+}
+
+#toggleButton {
+ position: absolute;
+ top: -3px;
+ height: 20px;
+ width: 20px;
+ border-radius: 50%;
+ box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.6);
+ transition: -webkit-transform linear .08s, background-color linear .08s;
+ transition: transform linear .08s, background-color linear .08s;
+ will-change: transform;
+}
+
+#toggleButton.dragging {
+ -webkit-transition: none;
+ transition: none;
+}
+
+:host([checked]) #toggleButton {
+ -webkit-transform: translate(16px, 0);
+ transform: translate(16px, 0);
+}
+
+:host([disabled]) #toggleButton {
+ background-color: #bdbdbd;
+ opacity: 1;
+}
+
+#ink {
+ position: absolute;
+ top: -14px;
+ left: -14px;
+ width: 48px;
+ height: 48px;
+ opacity: 0.5;
+}
diff --git a/polymer_1.0.4/bower_components/paper-toggle-button/paper-toggle-button.html b/polymer_1.0.4/bower_components/paper-toggle-button/paper-toggle-button.html
new file mode 100644
index 0000000..a531907
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toggle-button/paper-toggle-button.html
@@ -0,0 +1,172 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-ripple/paper-ripple.html">
+<link rel="import" href="../paper-behaviors/paper-inky-focus-behavior.html">
+
+<!--
+`paper-toggle-button` provides a ON/OFF switch that user can toggle the state
+by tapping or by dragging the switch.
+
+Example:
+
+ <paper-toggle-button></paper-toggle-button>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-toggle-button-unchecked-bar-color` | Slider color when the input is not checked | `#000000`
+`--paper-toggle-button-unchecked-button-color` | Button color when the input is not checked | `--paper-grey-50`
+`--paper-toggle-button-unchecked-ink-color` | Selected/focus ripple color when the input is not checked | `--dark-primary-color`
+`--paper-toggle-button-checked-bar-color` | Slider button color when the input is checked | `--google-green-500`
+`--paper-toggle-button-checked-button-color` | Button color when the input is checked | `--google-green-500`
+`--paper-toggle-button-checked-ink-color` | Selected/focus ripple color when the input is checked | `--google-green-500`
+
+@group Paper Elements
+@element paper-toggle-button
+@hero hero.svg
+@demo demo/index.html
+-->
+
+<dom-module id="paper-toggle-button">
+
+ <link rel="import" type="css" href="paper-toggle-button.css">
+
+ <template>
+
+ <div id="toggleContainer">
+ <div id="toggleBar" class="toggle-bar"></div>
+ <div id="toggleButton" class="toggle-button">
+ <paper-ripple id="ink" class="toggle-ink circle" recenters></paper-ripple>
+ </div>
+ </div>
+
+ </template>
+
+ <script>
+ Polymer({
+ is: 'paper-toggle-button',
+
+ behaviors: [
+ Polymer.PaperInkyFocusBehavior
+ ],
+
+ hostAttributes: {
+ role: 'button',
+ 'aria-pressed': 'false',
+ tabindex: 0
+ },
+
+ properties: {
+ /**
+ * Fired when the checked state changes due to user interaction.
+ *
+ * @event change
+ */
+ /**
+ * Fired when the checked state changes.
+ *
+ * @event iron-change
+ */
+ /**
+ * Gets or sets the state, `true` is checked and `false` is unchecked.
+ *
+ * @attribute checked
+ * @type boolean
+ * @default false
+ */
+ checked: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true,
+ notify: true,
+ observer: '_checkedChanged'
+ },
+
+ /**
+ * If true, the button toggles the active state with each tap or press
+ * of the spacebar.
+ *
+ * @attribute toggles
+ * @type boolean
+ * @default true
+ */
+ toggles: {
+ type: Boolean,
+ value: true,
+ reflectToAttribute: true
+ }
+ },
+
+ listeners: {
+ track: '_ontrack'
+ },
+
+ ready: function() {
+ this._isReady = true;
+ },
+
+ // button-behavior hook
+ _buttonStateChanged: function() {
+ if (this.disabled) {
+ return;
+ }
+ if (this._isReady) {
+ this.checked = this.active;
+ }
+ },
+
+ _checkedChanged: function(checked) {
+ this.active = this.checked;
+ this.fire('iron-change');
+ },
+
+ _ontrack: function(event) {
+ var track = event.detail;
+ if (track.state === 'start') {
+ this._trackStart(track);
+ } else if (track.state === 'track') {
+ this._trackMove(track);
+ } else if (track.state === 'end') {
+ this._trackEnd(track);
+ }
+ },
+
+ _trackStart: function(track) {
+ this._width = this.$.toggleBar.offsetWidth / 2;
+ /*
+ * keep an track-only check state to keep the dragging behavior smooth
+ * while toggling activations
+ */
+ this._trackChecked = this.checked;
+ this.$.toggleButton.classList.add('dragging');
+ },
+
+ _trackMove: function(track) {
+ var dx = track.dx;
+ this._x = Math.min(this._width,
+ Math.max(0, this._trackChecked ? this._width + dx : dx));
+ this.translate3d(this._x + 'px', 0, 0, this.$.toggleButton);
+ this._userActivate(this._x > (this._width / 2));
+ },
+
+ _trackEnd: function(track) {
+ this.$.toggleButton.classList.remove('dragging');
+ this.transform('', this.$.toggleButton);
+ }
+
+ });
+ </script>
+
+</dom-module>
diff --git a/polymer_1.0.4/bower_components/paper-toggle-button/test/basic.html b/polymer_1.0.4/bower_components/paper-toggle-button/test/basic.html
new file mode 100644
index 0000000..6768491
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toggle-button/test/basic.html
@@ -0,0 +1,86 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <title>paper-toggle-button basic tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+ <script src="../../iron-test-helpers/mock-interactions.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../paper-toggle-button.html">
+
+ </head>
+ <body>
+
+ <test-fixture id="Basic">
+ <template>
+ <paper-toggle-button id="button"></paper-toggle-button>
+ </template>
+ </test-fixture>
+
+ <script>
+ suite('defaults', function() {
+ var b1;
+
+ setup(function() {
+ b1 = fixture('Basic');
+ });
+
+ test('check button via click', function() {
+ b1.addEventListener('click', function() {
+ assert.isTrue(b1.getAttribute('aria-checked'));
+ assert.isTrue(b1.checked);
+ done();
+ });
+ MockInteractions.down(b1);
+ });
+
+ test('toggle button via click', function() {
+ b1.checked = true;
+ b1.addEventListener('click', function() {
+ assert.isFalse(b1.getAttribute('aria-checked'));
+ assert.isFalse(b1.checked);
+ done();
+ });
+ MockInteractions.down(b1);
+ });
+
+ test('disabled button cannot be clicked', function() {
+ b1.disabled = true;
+ b1.addEventListener('click', function() {
+ assert.isTrue(b1.getAttribute('aria-checked'));
+ assert.isTrue(b1.checked);
+ done();
+ });
+ MockInteractions.down(b1);
+ });
+ });
+
+ suite('a11y', function() {
+ var b1;
+
+ setup(function() {
+ b1 = fixture('Basic');
+ });
+
+ test('has aria role "button"', function() {
+ console.log(b1.getAttribute('role'));
+ assert.isTrue(b1.getAttribute('role') == 'button');
+ });
+ });
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-toggle-button/test/index.html b/polymer_1.0.4/bower_components/paper-toggle-button/test/index.html
new file mode 100644
index 0000000..c2b2278
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toggle-button/test/index.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>paper-toggle-button tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+ </head>
+ <body>
+ <script>
+ WCT.loadSuites([
+ 'basic.html'
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-toolbar/.bower.json b/polymer_1.0.4/bower_components/paper-toolbar/.bower.json
new file mode 100644
index 0000000..de532ef
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toolbar/.bower.json
@@ -0,0 +1,45 @@
+{
+ "name": "paper-toolbar",
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "A material design toolbar that is easily customizable",
+ "private": true,
+ "main": [
+ "paper-toolbar.html"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "toolbar",
+ "layout"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-toolbar.git"
+ },
+ "dependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+ "paper-icon-button": "PolymerElements/paper-icon-button#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "homepage": "https://github.com/PolymerElements/paper-toolbar",
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "402eb11da736a5ae19713748bfa04cd96f3f7a0c"
+ },
+ "_source": "git://github.com/PolymerElements/paper-toolbar.git",
+ "_target": "^1.0.0",
+ "_originalSource": "PolymerElements/paper-toolbar"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/paper-toolbar/.gitignore b/polymer_1.0.4/bower_components/paper-toolbar/.gitignore
new file mode 100644
index 0000000..fbe05fc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toolbar/.gitignore
@@ -0,0 +1 @@
+bower_components/
diff --git a/polymer_1.0.4/bower_components/paper-toolbar/README.md b/polymer_1.0.4/bower_components/paper-toolbar/README.md
new file mode 100644
index 0000000..ef525f4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toolbar/README.md
@@ -0,0 +1,51 @@
+paper-toolbar
+============
+
+`paper-toolbar` is a horizontal bar containing items that can be used for
+label, navigation, search and actions. The items place inside the
+`paper-toolbar` are projected into a `class="horizontal center layout"` container inside of
+`paper-toolbar`'s Shadow DOM. You can use flex attributes to control the items'
+sizing.
+
+Example:
+
+```html
+<paper-toolbar>
+ <paper-icon-button icon="menu" on-tap="{{menuAction}}"></paper-icon-button>
+ <div class="title">Title</div>
+ <paper-icon-button icon="more" on-tap="{{moreAction}}"></paper-icon-button>
+</paper-toolbar>
+```
+
+`paper-toolbar` has a standard height, but can made be taller by setting `tall`
+class on the `paper-toolbar`. This will make the toolbar 3x the normal height.
+
+```html
+<paper-toolbar class="tall">
+ <paper-icon-button icon="menu"></paper-icon-button>
+</paper-toolbar>
+```
+
+Apply `medium-tall` class to make the toolbar medium tall. This will make the
+toolbar 2x the normal height.
+
+```html
+<paper-toolbar class="medium-tall">
+ <paper-icon-button icon="menu"></paper-icon-button>
+</paper-toolbar>
+```
+
+When `tall`, items can pin to either the top (default), middle or bottom. Use
+`middle` class for middle content and `bottom` class for bottom content.
+
+```html
+<paper-toolbar class="tall">
+ <paper-icon-button icon="menu"></paper-icon-button>
+ <div class="title middle">Middle Title</div>
+ <div class="title bottom">Bottom Title</div>
+</paper-toolbar>
+```
+
+For `medium-tall` toolbar, the middle and bottom contents overlap and are
+pinned to the bottom. But `middleJustify` and `bottomJustify` attributes are
+still honored separately.
diff --git a/polymer_1.0.4/bower_components/paper-toolbar/bower.json b/polymer_1.0.4/bower_components/paper-toolbar/bower.json
new file mode 100644
index 0000000..26a02b6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toolbar/bower.json
@@ -0,0 +1,35 @@
+{
+ "name": "paper-toolbar",
+ "version": "1.0.2",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "description": "A material design toolbar that is easily customizable",
+ "private": true,
+ "main": [
+ "paper-toolbar.html"
+ ],
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "toolbar",
+ "layout"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/PolymerElements/paper-toolbar.git"
+ },
+ "dependencies": {
+ "paper-styles": "PolymerElements/paper-styles#^1.0.0",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "iron-icons": "PolymerElements/iron-icons#^1.0.0",
+ "paper-icon-button": "PolymerElements/paper-icon-button#^1.0.0",
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
+ "test-fixture": "PolymerElements/test-fixture#^1.0.0",
+ "web-component-tester": "*",
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/paper-toolbar/demo/index.html b/polymer_1.0.4/bower_components/paper-toolbar/demo/index.html
new file mode 100644
index 0000000..104bb14
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toolbar/demo/index.html
@@ -0,0 +1,81 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
+
+ <title>paper-toolbar demo</title>
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../../iron-icons/iron-icons.html">
+ <link rel="import" href="../../paper-icon-button/paper-icon-button.html">
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../paper-toolbar.html">
+
+ <style>
+ paper-toolbar + paper-toolbar {
+ margin-top: 20px;
+ }
+ </style>
+
+</head>
+<body>
+
+ <paper-toolbar>
+ <paper-icon-button icon="menu"></paper-icon-button>
+ <span class="title">Toolbar</span>
+ <paper-icon-button icon="refresh"></paper-icon-button>
+ <paper-icon-button icon="add">+</paper-icon-button>
+ </paper-toolbar>
+
+ <paper-toolbar class="tall">
+ <paper-icon-button icon="menu"></paper-icon-button>
+ <span class="title">Toolbar: tall</span>
+ <paper-icon-button icon="refresh"></paper-icon-button>
+ <paper-icon-button icon="add">+</paper-icon-button>
+ </paper-toolbar>
+
+ <paper-toolbar class="tall">
+ <paper-icon-button icon="menu" class="bottom"></paper-icon-button>
+ <span class="bottom title">Toolbar: tall with elements pin to the bottom</span>
+ <paper-icon-button icon="refresh" class="bottom"></paper-icon-button>
+ <paper-icon-button icon="add" class="bottom">+</paper-icon-button>
+ </paper-toolbar>
+
+ <paper-toolbar class="medium-tall">
+ <paper-icon-button icon="menu"></paper-icon-button>
+ <span class="flex"></span>
+ <paper-icon-button icon="refresh"></paper-icon-button>
+ <paper-icon-button icon="add">+</paper-icon-button>
+ <span class="bottom title">Toolbar: medium-tall with label aligns to the bottom</span>
+ </paper-toolbar>
+
+ <paper-toolbar class="tall">
+ <paper-icon-button icon="menu"></paper-icon-button>
+ <div class="flex"></div>
+ <paper-icon-button icon="refresh"></paper-icon-button>
+ <paper-icon-button icon="add">+</paper-icon-button>
+ <div class="middle title">label aligns to the middle</div>
+ <div class="bottom title">some stuffs align to the bottom</div>
+ </paper-toolbar>
+
+ <paper-toolbar class="tall">
+ <paper-icon-button icon="menu"></paper-icon-button>
+ <div class="flex"></div>
+ <paper-icon-button icon="refresh"></paper-icon-button>
+ <paper-icon-button icon="add">+</paper-icon-button>
+ <div class="middle title">element (e.g. progress) fits at the bottom of the toolbar</div>
+ <div class="bottom flex" style="height: 20px; background-color: #0f9d58;"></div>
+ </paper-toolbar>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-toolbar/index.html b/polymer_1.0.4/bower_components/paper-toolbar/index.html
new file mode 100644
index 0000000..6533b73
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toolbar/index.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<!--
+ @license
+ Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ Code distributed by Google as part of the polymer project is also
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+
+ <title>paper-toolbar</title>
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+
+ <link rel="import" href="../polymer/polymer.html">
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+
+ <style>
+
+ body {
+ margin: 16px;
+ }
+
+ </style>
+
+</head>
+<body>
+
+ <iron-component-page></iron-component-page>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-toolbar/paper-toolbar.html b/polymer_1.0.4/bower_components/paper-toolbar/paper-toolbar.html
new file mode 100644
index 0000000..153305e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toolbar/paper-toolbar.html
@@ -0,0 +1,368 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../paper-styles/paper-styles.html">
+
+<!--
+`paper-toolbar` is a horizontal bar containing items that can be used for
+label, navigation, search and actions. The items place inside the
+`paper-toolbar` are projected into a `class="horizontal center layout"` container inside of
+`paper-toolbar`'s Shadow DOM. You can use flex attributes to control the items'
+sizing.
+
+Example:
+
+ <paper-toolbar>
+ <paper-icon-button icon="menu" on-tap="menuAction"></paper-icon-button>
+ <div class="title">Title</div>
+ <paper-icon-button icon="more-vert" on-tap="moreAction"></paper-icon-button>
+ </paper-toolbar>
+
+`paper-toolbar` has a standard height, but can made be taller by setting `tall`
+class on the `paper-toolbar`. This will make the toolbar 3x the normal height.
+
+ <paper-toolbar class="tall">
+ <paper-icon-button icon="menu"></paper-icon-button>
+ </paper-toolbar>
+
+Apply `medium-tall` class to make the toolbar medium tall. This will make the
+toolbar 2x the normal height.
+
+ <paper-toolbar class="medium-tall">
+ <paper-icon-button icon="menu"></paper-icon-button>
+ </paper-toolbar>
+
+When `tall`, items can pin to either the top (default), middle or bottom. Use
+`middle` class for middle content and `bottom` class for bottom content.
+
+ <paper-toolbar class="tall">
+ <paper-icon-button icon="menu"></paper-icon-button>
+ <div class="middle title">Middle Title</div>
+ <div class="bottom title">Bottom Title</div>
+ </paper-toolbar>
+
+For `medium-tall` toolbar, the middle and bottom contents overlap and are
+pinned to the bottom. But `middleJustify` and `bottomJustify` attributes are
+still honored separately.
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-toolbar-background` | Toolbar background color | `--default-primary-color`
+`--paper-toolbar-color` | Toolbar foreground color | `--text-primary-color`
+`--paper-toolbar` | Mixin applied to the toolbar | `{}`
+
+### Accessibility
+
+`<paper-toolbar>` has `role="toolbar"` by default. Any elements with the class `title` will
+be used as the label of the toolbar via `aria-labelledby`.
+
+@demo demo/index.html
+-->
+
+<dom-module id="paper-toolbar">
+
+ <style>
+ :host {
+ /* technical */
+ display: block;
+ position: relative;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+
+ /* size */
+ height: 64px;
+
+ background: var(--paper-toolbar-background, --default-primary-color);
+ color: var(--paper-toolbar-color, --text-primary-color);
+
+ @apply(--paper-toolbar);
+ }
+
+ :host(.animate) {
+ /* transition */
+ transition: height 0.18s ease-in;
+ }
+
+ :host(.medium-tall) {
+ height: 128px;
+ }
+
+ :host(.tall) {
+ height: 192px;
+ }
+
+ .toolbar-tools {
+ position: relative;
+ height: 64px;
+ padding: 0 16px;
+ pointer-events: none;
+ }
+
+ /*
+ * TODO: Where should media query breakpoints live so they can be shared between elements?
+ */
+
+ @media (max-width: 639px) {
+ :host {
+ height: 56px;
+ }
+
+ :host(.medium-tall) {
+ height: 112px;
+ }
+
+ :host(.tall) {
+ height: 168px;
+ }
+
+ .toolbar-tools {
+ height: 56px;
+ }
+ }
+
+ #topBar {
+ position: relative;
+ }
+
+ /* middle bar */
+ #middleBar {
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ }
+
+ :host(.tall) #middleBar,
+ :host(.medium-tall) #middleBar {
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+ }
+
+ /* bottom bar */
+ #bottomBar {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ }
+
+ /*
+ * make elements (e.g. buttons) respond to mouse/touch events
+ *
+ * `.toolbar-tools` disables touch events so multiple toolbars can stack and not
+ * absorb events. All children must have pointer events re-enabled to work as
+ * expected.
+ */
+ .toolbar-tools > ::content > *:not([disabled]) {
+ pointer-events: auto;
+ }
+
+ .toolbar-tools > ::content .title {
+ @apply(--paper-font-title);
+ @apply(--layout-flex);
+
+ pointer-events: none;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+
+ /*
+ * Polymer/polymer/issues/1525
+ * --paper-font-title defines a `font-weight`
+ * let's override its value, but we need `important!`
+ * because all mixins are resolved in rule's selector that has higher precedence
+ * than the current selector.
+ */
+ font-weight: 400 !important;
+ }
+
+ /**
+ * TODO: Refactor these selectors
+ * Work in progress.
+ */
+ .toolbar-tools > ::content paper-icon-button[icon=menu] {
+ margin-right: 24px;
+ }
+
+ .toolbar-tools > ::content > .title,
+ .toolbar-tools > ::content[select=".middle"] > .title,
+ .toolbar-tools > ::content[select=".bottom"] > .title {
+ margin-left: 56px;
+ }
+
+ .toolbar-tools > ::content > paper-icon-button + .title,
+ .toolbar-tools > ::content[select=".middle"] paper-icon-button + .title,
+ .toolbar-tools > ::content[select=".bottom"] paper-icon-button + .title {
+ margin-left: 0;
+ }
+ </style>
+
+ <template>
+
+ <div id="topBar" class$="[[_computeBarClassName(justify)]]">
+ <content select=":not(.middle):not(.bottom)"></content>
+ </div>
+
+ <div id="middleBar" class$="[[_computeBarClassName(middleJustify)]]">
+ <content select=".middle"></content>
+ </div>
+
+ <div id="bottomBar" class$="[[_computeBarClassName(bottomJustify)]]">
+ <content select=".bottom"></content>
+ </div>
+
+ </template>
+
+</dom-module>
+
+<script>
+
+ (function() {
+
+ 'use strict';
+
+ function classNames(obj) {
+ var classNames = [];
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key) && obj[key]) {
+ classNames.push(key);
+ }
+ }
+
+ return classNames.join(' ');
+ }
+
+ Polymer({
+
+ is: 'paper-toolbar',
+
+ hostAttributes: {
+ 'role': 'toolbar'
+ },
+
+ properties: {
+
+ /**
+ * Controls how the items are aligned horizontally when they are placed
+ * at the bottom.
+ * Options are `start`, `center`, `end`, `justified` and `around`.
+ *
+ * @attribute bottomJustify
+ * @type string
+ * @default ''
+ */
+ bottomJustify: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * Controls how the items are aligned horizontally.
+ * Options are `start`, `center`, `end`, `justified` and `around`.
+ *
+ * @attribute justify
+ * @type string
+ * @default ''
+ */
+ justify: {
+ type: String,
+ value: ''
+ },
+
+ /**
+ * Controls how the items are aligned horizontally when they are placed
+ * in the middle.
+ * Options are `start`, `center`, `end`, `justified` and `around`.
+ *
+ * @attribute middleJustify
+ * @type string
+ * @default ''
+ */
+ middleJustify: {
+ type: String,
+ value: ''
+ }
+
+ },
+
+ attached: function() {
+ this._observer = this._observe(this);
+ this._updateAriaLabelledBy();
+ },
+
+ detached: function() {
+ if (this._observer) {
+ this._observer.disconnect();
+ }
+ },
+
+ _observe: function(node) {
+ var observer = new MutationObserver(function() {
+ this._updateAriaLabelledBy();
+ }.bind(this));
+ observer.observe(node, {
+ childList: true,
+ subtree: true
+ });
+ return observer;
+ },
+
+ _updateAriaLabelledBy: function() {
+ var labelledBy = [];
+ var contents = Polymer.dom(this.root).querySelectorAll('content');
+ for (var content, index = 0; content = contents[index]; index++) {
+ var nodes = Polymer.dom(content).getDistributedNodes();
+ for (var node, jndex = 0; node = nodes[jndex]; jndex++) {
+ if (node.classList && node.classList.contains('title')) {
+ if (node.id) {
+ labelledBy.push(node.id);
+ } else {
+ var id = 'paper-toolbar-label-' + Math.floor(Math.random() * 10000);
+ node.id = id;
+ labelledBy.push(id);
+ }
+ }
+ }
+ }
+ if (labelledBy.length > 0) {
+ this.setAttribute('aria-labelledby', labelledBy.join(' '));
+ }
+ },
+
+ _computeBarClassName: function(barJustify) {
+ var classObj = {
+ center: true,
+ horizontal: true,
+ layout: true,
+ 'toolbar-tools': true
+ };
+
+ // If a blank string or any falsy value is given, no other class name is
+ // added.
+ if (barJustify) {
+ var justifyClassName = (barJustify === 'justified') ?
+ barJustify :
+ barJustify + '-justified';
+
+ classObj[justifyClassName] = true;
+ }
+
+ return classNames(classObj);
+ }
+
+ });
+
+ }());
+
+</script>
diff --git a/polymer_1.0.4/bower_components/paper-toolbar/test/index.html b/polymer_1.0.4/bower_components/paper-toolbar/test/index.html
new file mode 100644
index 0000000..a1bd42a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toolbar/test/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+ <title>paper-toolbar tests</title>
+ <script src="../../web-component-tester/browser.js"></script>
+</head>
+<body>
+ <script>
+ WCT.loadSuites([
+ 'paper-toolbar.html'
+ ]);
+ </script>
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/paper-toolbar/test/paper-toolbar.html b/polymer_1.0.4/bower_components/paper-toolbar/test/paper-toolbar.html
new file mode 100644
index 0000000..a5998c1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/paper-toolbar/test/paper-toolbar.html
@@ -0,0 +1,147 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>paper-toolbar basic tests</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+
+ <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
+ <script src="../../web-component-tester/browser.js"></script>
+ <script src="../../test-fixture/test-fixture-mocha.js"></script>
+
+ <link rel="import" href="../../test-fixture/test-fixture.html">
+ <link rel="import" href="../../polymer/polymer.html">
+ <link rel="import" href="../paper-toolbar.html">
+
+</head>
+<body>
+
+ <test-fixture id="basic">
+ <template>
+ <paper-toolbar></paper-toolbar>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="title">
+ <template>
+ <paper-toolbar>
+ <span class="title">Title</span>
+ </paper-toolbar>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="title-with-id">
+ <template>
+ <paper-toolbar>
+ <span class="title" id="title">Title</span>
+ </paper-toolbar>
+ </template>
+ </test-fixture>
+
+ <test-fixture id="multiple-titles">
+ <template>
+ <paper-toolbar>
+ <span class="title">Title 1</span>
+ <span class="title">Title 2</span>
+ </paper-toolbar>
+ </template>
+ </test-fixture>
+
+ <script>
+ 'use strict';
+
+ suite('basic', function() {
+
+ var toolbar;
+
+ setup(function() {
+ toolbar = fixture('basic');
+ });
+
+ test('has expected medium-tall height', function() {
+ var old = toolbar.offsetHeight;
+ toolbar.classList.add('medium-tall');
+ expect(toolbar.offsetHeight).to.be.eql(old * 2);
+ });
+
+ test('has expected tall height', function() {
+ var old = toolbar.offsetHeight;
+ toolbar.classList.add('tall');
+ expect(toolbar.offsetHeight).to.be.eql(old * 3);
+ });
+
+ test('distributes nodes to topBar by default', function() {
+ var item = document.createElement('div');
+ Polymer.dom(toolbar).appendChild(item);
+ Polymer.dom.flush();
+
+ var insertionPoint = Polymer.dom(item).getDestinationInsertionPoints()[0];
+ expect(Polymer.dom(insertionPoint).parentNode).to.be.eql(toolbar.$.topBar);
+ });
+
+ test('distributes nodes with "middle" class to middleBar', function() {
+ var item = document.createElement('div');
+ item.classList.add('middle');
+ Polymer.dom(toolbar).appendChild(item);
+ Polymer.dom.flush();
+
+ var insertionPoint = Polymer.dom(item).getDestinationInsertionPoints()[0];
+ expect(Polymer.dom(insertionPoint).parentNode).to.be.eql(toolbar.$.middleBar);
+ });
+
+ test('distributes nodes with "bottom" class to bottombar', function() {
+ var item = document.createElement('div');
+ item.classList.add('bottom');
+ Polymer.dom(toolbar).appendChild(item);
+ Polymer.dom.flush();
+
+ var insertionPoint = Polymer.dom(item).getDestinationInsertionPoints()[0];
+ expect(Polymer.dom(insertionPoint).parentNode).to.be.eql(toolbar.$.bottomBar);
+ });
+
+ });
+
+ suite('a11y', function() {
+
+ test('has role="toolbar"', function() {
+ var toolbar = fixture('basic');
+ assert.equal(toolbar.getAttribute('role'), 'toolbar', 'has role="toolbar"');
+ });
+
+ test('children with .title becomes the label', function() {
+ var toolbar = fixture('title');
+ assert.isTrue(toolbar.hasAttribute('aria-labelledby'), 'has aria-labelledby');
+ assert.equal(toolbar.getAttribute('aria-labelledby'), Polymer.dom(toolbar).querySelector('.title').id, 'aria-labelledby has the id of the .title element');
+ });
+
+ test('existing ids on titles are preserved', function() {
+ var toolbar = fixture('title-with-id');
+ assert.isTrue(toolbar.hasAttribute('aria-labelledby'), 'has aria-labelledby');
+ assert.equal(Polymer.dom(toolbar).querySelector('.title').id, 'title', 'id is preserved');
+ });
+
+ test('multiple children with .title becomes the label', function() {
+ var toolbar = fixture('multiple-titles');
+ assert.isTrue(toolbar.hasAttribute('aria-labelledby'), 'has aria-labelledby');
+ var ids = [];
+ var titles = Polymer.dom(toolbar).querySelectorAll('.title');
+ for (var title, index = 0; title = titles[index]; index++) {
+ ids.push(title.id);
+ }
+ assert.equal(toolbar.getAttribute('aria-labelledby'), ids.join(' '), 'aria-labelledby has the id of all .title elements');
+ });
+
+ });
+
+ </script>
+
+</body>
+</html>
diff --git a/polymer_1.0.4/bower_components/platinum-elements/.bower.json b/polymer_1.0.4/bower_components/platinum-elements/.bower.json
new file mode 100644
index 0000000..6426d02
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-elements/.bower.json
@@ -0,0 +1,30 @@
+{
+ "name": "platinum-elements",
+ "homepage": "https://github.com/PolymerElements/platinum-elements",
+ "description": "Elements to turn your web page into a true webapp, with push, offline, and more.",
+ "main": "service-worker-elements.html",
+ "keywords": [
+ "service",
+ "worker",
+ "service-worker",
+ "push",
+ "platinum"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "private": true,
+ "dependencies": {
+ "platinum-sw": "PolymerElements/platinum-sw#~1.0.1",
+ "platinum-push-messaging": "PolymerElements/platinum-push-messaging#~1.0.0"
+ },
+ "version": "1.0.1",
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "f96d330268d0d0b889bd2d12b45cd0d5ef4c5b35"
+ },
+ "_source": "git://github.com/PolymerElements/platinum-elements.git",
+ "_target": "~1.0.1",
+ "_originalSource": "PolymerElements/platinum-elements",
+ "_direct": true
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/platinum-elements/LICENSE b/polymer_1.0.4/bower_components/platinum-elements/LICENSE
new file mode 100644
index 0000000..8f71f43
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-elements/LICENSE
@@ -0,0 +1,202 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
diff --git a/polymer_1.0.4/bower_components/platinum-elements/README.md b/polymer_1.0.4/bower_components/platinum-elements/README.md
new file mode 100644
index 0000000..9ccf15b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-elements/README.md
@@ -0,0 +1,2 @@
+# platinum-elements
+Elements that provide features to turn your web page into a true webapp - with things like push notifications, offline usage, and more.
diff --git a/polymer_1.0.4/bower_components/platinum-elements/bower.json b/polymer_1.0.4/bower_components/platinum-elements/bower.json
new file mode 100644
index 0000000..164233e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-elements/bower.json
@@ -0,0 +1,19 @@
+{
+ "name": "platinum-elements",
+ "homepage": "https://github.com/PolymerElements/platinum-elements",
+ "description": "Elements to turn your web page into a true webapp, with push, offline, and more.",
+ "main": "service-worker-elements.html",
+ "keywords": [
+ "service",
+ "worker",
+ "service-worker",
+ "push",
+ "platinum"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "private": true,
+ "dependencies": {
+ "platinum-sw": "PolymerElements/platinum-sw#~1.0.1",
+ "platinum-push-messaging": "PolymerElements/platinum-push-messaging#~1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/platinum-push-messaging/.bower.json b/polymer_1.0.4/bower_components/platinum-push-messaging/.bower.json
new file mode 100644
index 0000000..6db32c4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-push-messaging/.bower.json
@@ -0,0 +1,48 @@
+{
+ "name": "platinum-push-messaging",
+ "private": true,
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "Subscribes for push messaging and handles notifications.",
+ "keywords": [
+ "push",
+ "messaging",
+ "notification",
+ "polymer",
+ "service-worker",
+ "serviceworker",
+ "web-component",
+ "web-components"
+ ],
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#~1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#~1.0.2",
+ "web-component-tester": "Polymer/web-component-tester#~3.1.3",
+ "paper-styles": "PolymerElements/paper-styles#~1.0.0",
+ "paper-material": "PolymerElements/paper-material#~1.0.0",
+ "paper-toggle-button": "PolymerElements/paper-toggle-button#~1.0.0",
+ "paper-item": "PolymerElements/paper-item#~1.0.0"
+ },
+ "homepage": "https://github.com/PolymerElements/platinum-push-messaging",
+ "version": "1.0.0",
+ "_release": "1.0.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.0",
+ "commit": "fcebba0d6d75cf1463a5b5bb0fbc5857a86eee70"
+ },
+ "_source": "git://github.com/PolymerElements/platinum-push-messaging.git",
+ "_target": "~1.0.0",
+ "_originalSource": "PolymerElements/platinum-push-messaging"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/platinum-push-messaging/README.md b/polymer_1.0.4/bower_components/platinum-push-messaging/README.md
new file mode 100644
index 0000000..21bf545
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-push-messaging/README.md
@@ -0,0 +1,4 @@
+# platinum-push-messaging
+Push Notifications with Polymer
+
+For documentation, please see https://polymerelements.github.io/platinum-push-messaging/
diff --git a/polymer_1.0.4/bower_components/platinum-push-messaging/bower.json b/polymer_1.0.4/bower_components/platinum-push-messaging/bower.json
new file mode 100644
index 0000000..3364a81
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-push-messaging/bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "platinum-push-messaging",
+ "private": true,
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "Subscribes for push messaging and handles notifications.",
+ "keywords": [
+ "push",
+ "messaging",
+ "notification",
+ "polymer",
+ "service-worker",
+ "serviceworker",
+ "web-component",
+ "web-components"
+ ],
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#~1.0.0"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#~1.0.2",
+ "web-component-tester": "Polymer/web-component-tester#~3.1.3",
+ "paper-styles": "PolymerElements/paper-styles#~1.0.0",
+ "paper-material": "PolymerElements/paper-material#~1.0.0",
+ "paper-toggle-button": "PolymerElements/paper-toggle-button#~1.0.0",
+ "paper-item": "PolymerElements/paper-item#~1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/platinum-push-messaging/demo/index.html b/polymer_1.0.4/bower_components/platinum-push-messaging/demo/index.html
new file mode 100644
index 0000000..1d8ed25
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-push-messaging/demo/index.html
@@ -0,0 +1,130 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title><platinum-push-messaging> Demo</title>
+ <script src="../../webcomponentsjs/webcomponents-lite.min.js"></script>
+ <link rel="import" href="../../paper-styles/paper-styles.html">
+ <link rel="import" href="../../paper-styles/classes/global.html">
+ <link rel="import" href="../../paper-item/paper-item.html">
+ <link rel="import" href="../../paper-material/paper-material.html">
+ <link rel="import" href="../../paper-toggle-button/paper-toggle-button.html">
+ <link rel="import" href="../platinum-push-messaging.html">
+ <link rel="manifest" href="manifest.json">
+
+ <style>
+ .warning {
+ border: 3px solid red;
+ max-width: 500px;
+ margin: 50px auto;
+ padding: 30px;
+ }
+
+ paper-material {
+ padding: 10px;
+ }
+ </style>
+ </head>
+
+ <body>
+ <platinum-push-messaging
+ title="You received a push message!"
+ message="Yay! Now you can play around customizing it"
+ >
+ </platinum-push-messaging>
+
+ <div id="unsupported" style="display: none;" class="warning">
+ Sorry, your browser doesn't support push notifications.
+ </div>
+
+ <div id="supported">
+ <paper-material elevation="1" style="margin: 20px auto; background-color: white; max-width: 800px;">
+
+ <paper-item>
+ <paper-item-body two-line class="layout vertical">
+ <div>You can sign up for push messaging with the demo as-is. However, if you want to test it and actually send a real push message you will need to provide your own details. Open up the manifest.json file and change the gcm_sender_id to your own, and then re-enable messaging to get a new subscription ID.</div>
+
+ <div>See <a href="http://updates.html5rocks.com/2015/03/push-notificatons-on-the-open-web#make-a-project-on-the-google-developer-console">the HTML5Rocks guide to push notifications</a> for details on signing up for the necessary key and sender ID.</div>
+ </paper-item-body>
+ </paper-item>
+
+ <br/>
+
+ <paper-item>
+ <paper-item-body two-line class="layout vertical">
+ <div>
+ Enable push messaging
+ </div>
+ <div>
+ <paper-toggle-button id="enable-push" toggles disabled></paper-toggle-button>
+ </div>
+ </paper-item-body>
+ </paper-item>
+ <paper-item>
+ <paper-item-body two-line class="layout vertical">
+ <div>
+ Current subscription
+ </div>
+ <div>
+ <pre class="paper-font-code1" style="overflow: auto; margin: 5px;" id="subscription"></pre>
+ </div>
+ </paper-item-body>
+ </paper-item>
+ <paper-item id="send-instructions">
+ <paper-item-body two-line class="layout vertical">
+ <div>
+ Send a push (Mac/Unix)
+ </div>
+ <div>
+ <pre class="paper-font-code1" style="overflow: auto; margin: 5px;">curl https://android.googleapis.com/gcm/send -d "registration_id=<span id="registration-id"></span>" --header "Authorization: key=[YOUR_PUBLIC_API_KEY]"</pre>
+ </div>
+ </paper-item-body>
+ </paper-item>
+ </paper-material>
+ </div>
+
+ <script>
+ document.addEventListener('WebComponentsReady', function() {
+ var ppm = document.querySelector('platinum-push-messaging');
+ var toggle = document.getElementById('enable-push');
+ var subscription = document.getElementById('subscription');
+ var registrationId = document.getElementById('registration-id');
+ var sendInstructions = document.getElementById('send-instructions');
+
+ toggle.disabled = !ppm.supported;
+
+ if (!ppm.supported) {
+ document.getElementById('supported').style.display = 'none';
+ document.getElementById('unsupported').style.display = '';
+ }
+
+ toggle.addEventListener('change', function() {
+ if (toggle.checked) {
+ ppm.enable();
+ } else {
+ ppm.disable();
+ }
+ });
+
+ ppm.addEventListener('subscription-changed', function(event) {
+ subscription.textContent = JSON.stringify(ppm.subscription || undefined, null, 2);
+ registrationId.textContent = ppm.subscription ? ppm.subscription.subscriptionId : '';
+ });
+
+ ppm.addEventListener('enabled-changed', function(event) {
+ toggle.checked = ppm.enabled;
+ sendInstructions.style.display = ppm.enabled ? '' : 'none';
+ });
+ });
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/platinum-push-messaging/demo/manifest.json b/polymer_1.0.4/bower_components/platinum-push-messaging/demo/manifest.json
new file mode 100644
index 0000000..f6e1d02
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-push-messaging/demo/manifest.json
@@ -0,0 +1,4 @@
+{
+ "gcm_sender_id": "679960499087",
+ "gcm_user_visible_only": true
+}
diff --git a/polymer_1.0.4/bower_components/platinum-push-messaging/index.html b/polymer_1.0.4/bower_components/platinum-push-messaging/index.html
new file mode 100644
index 0000000..f8a540d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-push-messaging/index.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+ </head>
+
+ <body>
+ <iron-component-page></iron-component-page>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/platinum-push-messaging/platinum-push-messaging.html b/polymer_1.0.4/bower_components/platinum-push-messaging/platinum-push-messaging.html
new file mode 100644
index 0000000..7a43a73
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-push-messaging/platinum-push-messaging.html
@@ -0,0 +1,427 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+ (function() {
+ 'use strict';
+ // TODO: Doesn't work for IE or Safari, and the usual
+ // document.getElementsByTagName('script') workaround seems to be broken by
+ // HTML imports. Not important for now as neither of those browsers support
+ // service worker yet.
+ var currentScript = document.currentScript.baseURI;
+
+ var SCOPE = new URL('./$$platinum-push-messaging$$/', currentScript).href;
+ var WORKER_URL = new URL('./service-worker.js', currentScript).href;
+
+ var BASE_URL = new URL('./', document.location.href).href;
+
+ var SUPPORTED = 'serviceWorker' in navigator &&
+ 'PushManager' in window &&
+ 'Notification' in window;
+
+ /**
+ * @const {Number} The desired version of the service worker to use. This is
+ * not strictly tied to anything except that it should be changed whenever
+ * a breaking change is made to the service worker code.
+ */
+ var VERSION = 1;
+
+ // This allows us to use the PushSubscription attribute type in browsers
+ // where it is not defined.
+ if (!('PushSubscription' in window)) {
+ window.PushSubscription = {};
+ }
+
+ /**
+ * `<platinum-push-messaging>` sets up a [push messaging][1] subscription
+ * and allows you to define what happens when a push message is received.
+ *
+ * The element can be placed anywhere, but should only be used once in a
+ * page. If there are multiple occurrences, only one will be active.
+ *
+ * # Requirements
+ * Push messaging is currently only available in Google Chrome, which
+ * requires you to configure Google Cloud Messaging. Chrome will check that
+ * your page links to a manifest file that contains a `gcm_sender_id` field.
+ * You can find full details of how to set all of this up in the [HTML5
+ * Rocks guide to push notifications][1].
+ *
+ * # Notifcation details
+ * The data for how a notification should be displayed can come from one of
+ * three places.
+ *
+ * Firstly, you can specify a URL from which to fetch the message data.
+ * ```
+ * <platinum-push-messaging
+ * message-url="notification-data.json">
+ * </platinum-push-messaging>
+ * ```
+ *
+ * The second way is to send the message data in the body of
+ * the push message from your server. In this case you do not need to
+ * configure anything in your page:
+ * ```
+ * <platinum-push-messaging></platinum-push-messaging>
+ * ```
+ * **Note that this method is not currently supported by any browser**. It
+ * is, however, defined in the
+ * [draft W3C specification](http://w3c.github.io/push-api/#the-push-event)
+ * and this element should use that data when it is implemented in the
+ * future.
+ *
+ * If a message-url is provided then the message body will be ignored in
+ * favor of the first method.
+ *
+ * Thirdly, you can manually define the attributes on the element:
+ * ```
+ * <platinum-push-messaging
+ * title="Application updated"
+ * message="The application was updated in the background"
+ * icon-url="icon.png"
+ * click-url="notification.html">
+ * </platinum-push-messaging>
+ * ```
+ * These values will also be used as defaults if one of the other methods
+ * does not provide a value for that property.
+ *
+ * # Testing
+ * If you have set up Google Cloud Messaging then you can send push messages
+ * to your browser by following the guide in the [GCM documentation][2].
+ *
+ * However, for quick client testing there are two options. You can use the
+ * `testPush` method, which allows you to simulate a push message that
+ * includes a payload.
+ *
+ * Or, at a lower level, you can open up chrome://serviceworker-internals in
+ * Chrome and use the 'Push' button for the service worker corresponding to
+ * your app.
+ *
+ * [1]: http://updates.html5rocks.com/2015/03/push-notificatons-on-the-open-web
+ * [2]: https://developer.android.com/google/gcm/http.html
+ *
+ * @demo demo/
+ */
+ Polymer({
+ is: 'platinum-push-messaging',
+
+ properties: {
+
+ /**
+ * Indicates whether the Push and Notification APIs are supported by
+ * this browser.
+ */
+ supported: {
+ readOnly: true,
+ type: Boolean,
+ value: SUPPORTED
+ },
+
+ /**
+ * The details of the current push subscription, if any.
+ */
+ subscription: {
+ readOnly: true,
+ type: PushSubscription,
+ notify: true,
+ },
+
+ /**
+ * Indicates the status of the element. If true, push messages will be
+ * received.
+ */
+ enabled: {
+ readOnly: true,
+ type: Boolean,
+ notify: true,
+ value: false
+ },
+
+
+ /**
+ * A URL from which message information can be retrieved.
+ *
+ * When a push event happens that does not contain a message body this
+ * URL will be fetched. The URL is expected to be for a JSON document in
+ * the format:
+ * ```
+ * {
+ * "title": "The title for the notification",
+ * "body": "The message to display in the notification",
+ * "url": "The URL to display when the notification is clicked",
+ * "icon": "The URL of an icon to display with the notification",
+ * "tag": "An identifier that determines which notifications can be displayed at the same time"
+ * }
+ * ```
+ */
+ messageUrl: String,
+
+ /**
+ * A default notification title.
+ */
+ title: String,
+
+ /**
+ * A default notification message.
+ */
+ message: String,
+
+ /**
+ * A default icon for notifications.
+ */
+ iconUrl: String,
+
+ /**
+ * A default URL to display when a notification is clicked.
+ */
+ clickUrl: {
+ type: String,
+ value: document.location.href
+ },
+
+ /**
+ * A default tag for the notifications that will be generated by
+ * this element. Notifications with the same tag will overwrite one
+ * another, so that only one will be shown at once.
+ */
+ tag: String
+ },
+
+ /**
+ * Fired when a notification is clicked that had the current page as the
+ * click URL.
+ *
+ * @event platinum-push-messaging-click
+ * @param {Object} The push message data used to create the notification
+ */
+
+ /**
+ * Fired when a push message is received but no notification is shown.
+ * This happens when the click URL is for this page and the page is
+ * visible to the user on the screen.
+ *
+ * @event platinum-push-messaging-push
+ * @param {Object} The push message data that was received
+ */
+
+ /**
+ * Fired when an error occurs while enabling or disabling notifications
+ *
+ * @event platinum-push-messaging-error
+ * @param {String} The error message
+ */
+
+ /**
+ * Returns a promise which will resolve to the registration object
+ * associated with our current service worker.
+ *
+ * @return {Promise<ServiceWorkerRegistration>}
+ */
+ _getRegistration: function() {
+ return navigator.serviceWorker.getRegistration(SCOPE);
+ },
+
+ /**
+ * Returns a promise that will resolve when the given registration becomes
+ * active.
+ *
+ * @param registration {ServiceWorkerRegistration}
+ * @return {Promise<undefined>}
+ */
+ _registrationReady: function(registration) {
+ if (registration.active) {
+ return Promise.resolve();
+ }
+
+ var serviceWorker = registration.installing || registration.waiting;
+
+ return new Promise(function(resolve, reject) {
+ // Because the Promise function is called on next tick there is a
+ // small chance that the worker became active already.
+ if (serviceWorker.state === 'activated') {
+ resolve();
+ }
+ var listener = function(event) {
+ if (serviceWorker.state === 'activated') {
+ resolve();
+ } else if (serviceWorker.state === 'redundant') {
+ reject(new Error('Worker became redundant'));
+ } else {
+ return;
+ }
+ serviceWorker.removeEventListener('statechange', listener);
+ };
+ serviceWorker.addEventListener('statechange', listener);
+ });
+ },
+
+ /**
+ * Event handler for the `message` event.
+ *
+ * @param event {MessageEvent}
+ */
+ _messageHandler: function(event) {
+ if (event.data && event.data.source === SCOPE) {
+ switch(event.data.type) {
+ case 'push':
+ this.fire('platinum-push-messaging-push', event.data);
+ break;
+ case 'click':
+ this.fire('platinum-push-messaging-click', event.data);
+ break;
+ }
+ }
+ },
+
+ /**
+ * Takes an options object and creates a stable JSON serialization of it.
+ * This naive algorithm will only work if the object contains only
+ * non-nested properties.
+ *
+ * @param options {Object.<String, ?(String|Number|Boolean)>}
+ * @return String
+ */
+ _serializeOptions: function(options) {
+ var props = Object.keys(options);
+ props.sort();
+ var parts = props.filter(function(propName) {
+ return !!options[propName];
+ }).map(function(propName) {
+ return JSON.stringify(propName) + ':' + JSON.stringify(options[propName]);
+ });
+ return '{' + parts.join(',') + '}';
+ },
+
+ /**
+ * Determine the URL of the worker based on the currently set parameters
+ *
+ * @return String the URL
+ */
+ _getWorkerURL: function() {
+ var options = this._serializeOptions({
+ tag: this.tag,
+ messageUrl: this.messageUrl,
+ title: this.title,
+ message: this.message,
+ iconUrl: this.iconUrl,
+ clickUrl: this.clickUrl,
+ version: VERSION,
+ baseUrl: BASE_URL
+ });
+
+ return WORKER_URL + '?' + options;
+ },
+
+ /**
+ * Update the subscription property, but only if the value has changed.
+ * This prevents triggering the subscription-changed event twice on page
+ * load.
+ */
+ _updateSubscription: function(subscription) {
+ if (JSON.stringify(subscription) !== JSON.stringify(this.subscription)) {
+ this._setSubscription(subscription);
+ }
+ },
+
+ /**
+ * Programmatically trigger a push message
+ *
+ * @param message {Object} the message payload
+ */
+ testPush: function(message) {
+ this._getRegistration().then(function(registration) {
+ registration.active.postMessage({
+ type: 'test-push',
+ message: message
+ });
+ });
+ },
+
+ /**
+ * Request push messaging to be enabled.
+ *
+ * @return {Promise<undefined>}
+ */
+ enable: function() {
+ if (!this.supported) {
+ this.fire('platinum-push-messaging-error', 'Your browser does not support push notifications');
+ return Promise.resolve();
+ }
+
+ return navigator.serviceWorker.register(this._getWorkerURL(), {scope: SCOPE}).then(function(registration) {
+ return this._registrationReady(registration).then(function() {
+ return registration.pushManager.subscribe({userVisibleOnly: true});
+ });
+ }.bind(this)).then(function(subscription) {
+ this._updateSubscription(subscription);
+ this._setEnabled(true);
+ }.bind(this)).catch(function(error) {
+ this.fire('platinum-push-messaging-error', error.message || error);
+ }.bind(this));
+ },
+
+ /**
+ * Request push messaging to be disabled.
+ *
+ * @return {Promise<undefined>}
+ */
+ disable: function() {
+ if (!this.supported) {
+ return Promise.resolve();
+ }
+
+ return this._getRegistration().then(function(registration) {
+ if (!registration) {
+ return;
+ }
+ return registration.pushManager.getSubscription().then(function(subscription) {
+ if (subscription) {
+ return subscription.unsubscribe();
+ }
+ }).then(function() {
+ return registration.unregister();
+ }).then(function() {
+ this._updateSubscription();
+ this._setEnabled(false);
+ }.bind(this)).catch(function(error) {
+ this.fire('platinum-push-messaging-error', error.message || error);
+ }.bind(this));
+ }.bind(this));
+ },
+
+ ready: function() {
+ if (this.supported) {
+ var handler = this._messageHandler.bind(this);
+ // NOTE: We add the event listener twice because the specced and
+ // implemented behaviors do not match. In Chrome 42, messages are
+ // received on window. In the current spec they are supposed to be
+ // received on navigator.serviceWorker.
+ // TODO: Remove the non-spec code in the future.
+ window.addEventListener('message', handler);
+ navigator.serviceWorker.addEventListener('message', handler);
+
+ this._getRegistration().then(function(registration) {
+ if (!registration) {
+ return;
+ }
+ if (registration.active && registration.active.scriptURL !== this._getWorkerURL()) {
+ // We have an existing worker in this scope, but it is out of date
+ return this.enable();
+ }
+ return registration.pushManager.getSubscription().then(function(subscription) {
+ this._updateSubscription(subscription);
+ this._setEnabled(true);
+ }.bind(this));
+ }.bind(this));
+ }
+ }
+ });
+ })();
+</script>
diff --git a/polymer_1.0.4/bower_components/platinum-push-messaging/service-worker.js b/polymer_1.0.4/bower_components/platinum-push-messaging/service-worker.js
new file mode 100644
index 0000000..1e20d93
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-push-messaging/service-worker.js
@@ -0,0 +1,151 @@
+/*
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+*/
+'use strict';
+
+var options = JSON.parse(decodeURIComponent(location.search.substring(1)));
+
+var DEFAULT_TAG = self.registration.scope;
+var DATA_SUPPORT = Notification.prototype.hasOwnProperty('data');
+
+self.skipWaiting();
+
+/**
+ * Resolves a URL that is relative to the registering page to an absolute URL
+ *
+ * @param url {String} a relative URL
+ * @return {String} the equivalent absolute URL
+ */
+var absUrl = function(url) {
+ if (typeof(url) === 'string') {
+ return new URL(url, options.baseUrl).href;
+ }
+};
+
+var getClientWindows = function() {
+ return clients.matchAll({
+ type: 'window',
+ includeUncontrolled: true
+ }).catch(function(error) {
+ // Couldn't get client list, possibly not yet implemented in the browser
+ return [];
+ });
+};
+
+var getVisible = function(url) {
+ return getClientWindows().then(function(clientList) {
+ for (var client of clientList) {
+ if (client.url === url && client.focused &&
+ client.visibilityState === 'visible') {
+ return client;
+ }
+ }
+ return null;
+ });
+};
+
+var messageClient = function(client, message, notificationShown) {
+ client.postMessage({
+ source: self.registration.scope,
+ message: message,
+ type: notificationShown ? 'click' : 'push'
+ });
+};
+
+var notify = function(data) {
+ var messagePromise;
+
+ if (options.messageUrl) {
+ messagePromise = fetch(absUrl(options.messageUrl)).then(function(response) {
+ return response.json();
+ });
+ } else {
+ messagePromise = data ? data.json() : Promise.resolve({});
+ }
+
+ return messagePromise.then(function(message) {
+ var detail = {
+ title: message.title || options.title || '',
+ body: message.message || options.message || '',
+ tag: message.tag || options.tag || DEFAULT_TAG,
+ icon: absUrl(message.icon || options.iconUrl),
+ data: message
+ };
+
+ var clickUrl = absUrl(message.url || options.clickUrl);
+
+ if (!DATA_SUPPORT) {
+ // If there is no 'data' property support on the notification then we have
+ // to pass the link URL (and anything else) some other way. We use the
+ // hash of the icon URL to store it.
+ var iconUrl = new URL(detail.icon || 'about:blank');
+ iconUrl.hash = encodeURIComponent(JSON.stringify(detail.data));
+ detail.icon = iconUrl.href;
+ }
+
+ return getVisible(clickUrl).then(function(visibleClient) {
+ if (visibleClient) {
+ messageClient(visibleClient, message, false);
+ } else {
+ return self.registration.showNotification(detail.title, detail);
+ }
+ });
+ });
+};
+
+var clickHandler = function(notification) {
+ notification.close();
+
+ var message;
+ if ('data' in notification) {
+ message = notification.data;
+ } else {
+ message = new URL(notification.icon).hash.substring(1);
+ message = JSON.parse(decodeURIComponent(message));
+ }
+
+ var url = absUrl(message.url || options.clickUrl);
+
+ if (!url) {
+ return;
+ }
+
+ return getClientWindows().then(function(clientList) {
+ for (var client of clientList) {
+ if (client.url === url && 'focus' in client) {
+ client.focus();
+ return client;
+ }
+ }
+ if ('openWindow' in clients) {
+ return clients.openWindow(url);
+ }
+ }).then(function(client) {
+ if (client) {
+ messageClient(client, message, true);
+ }
+ });
+};
+
+self.addEventListener('push', function(event) {
+ event.waitUntil(notify(event.data));
+});
+
+self.addEventListener('notificationclick', function(event) {
+ event.waitUntil(clickHandler(event.notification));
+});
+
+self.addEventListener('message', function(event) {
+ if (event.data.type == 'test-push') {
+ notify({
+ json: function() {
+ return Promise.resolve(event.data.message);
+ }
+ });
+ }
+});
diff --git a/polymer_1.0.4/bower_components/platinum-sw/.bower.json b/polymer_1.0.4/bower_components/platinum-sw/.bower.json
new file mode 100644
index 0000000..ce555f3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-sw/.bower.json
@@ -0,0 +1,47 @@
+{
+ "name": "platinum-sw",
+ "private": true,
+ "version": "1.0.1",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "Service worker helper elements.",
+ "main": "platinum-sw-elements.html",
+ "keywords": [
+ "caching",
+ "offline",
+ "polymer",
+ "service-worker",
+ "serviceworker",
+ "web-component",
+ "web-components"
+ ],
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "sw-toolbox": "^2.0.2"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2",
+ "marked-element": "PolymerElements/marked-element#^1.0.0",
+ "web-component-tester": "*",
+ "fetch": "^0.9.0"
+ },
+ "homepage": "https://github.com/PolymerElements/platinum-sw",
+ "_release": "1.0.1",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.1",
+ "commit": "34188bfa0db42cc517ce157f447fa395c4fee68e"
+ },
+ "_source": "git://github.com/PolymerElements/platinum-sw.git",
+ "_target": "~1.0.1",
+ "_originalSource": "PolymerElements/platinum-sw"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/platinum-sw/README.md b/polymer_1.0.4/bower_components/platinum-sw/README.md
new file mode 100644
index 0000000..c0cba27
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-sw/README.md
@@ -0,0 +1,43 @@
+# Platinum Service Worker Elements
+A set of Polymer elements that simplify service worker registration and caching, powered by the
+[`sw-toolbox` library](https://github.com/googlechrome/sw-toolbox).
+Full documentation is available at https://PolymerElements.github.io/platinum-sw/index.html
+
+# Considerations
+
+## Top-level `sw-import.js`
+While `<platinum-sw-register>` abstracts away many of the details of working with service workers,
+there is one specific requirement that developers must fulfill: it needs to register a JavaScript file
+located at the top-level of your site's web root. (Details behind this requirement can be found in
+the service worker specification [issue tracker](https://github.com/slightlyoff/ServiceWorker/issues/468#issuecomment-60276779).)
+
+In order to use `<platinum-sw-register>`, it's recommended that you create a `sw-import.js` file in
+your site's web root. The file's only contents should be
+
+ importScripts('bower_components/platinum-sw/service-worker.js');
+
+You can adjust the path to `service-worker.js` if your project has its Polymer elements
+installed somewhere other than `bower_components/`.
+
+If you have multiple subdirectories worth of pages on your site, it's recommend that you include the
+`<platinum-sw-register>` element on a top-level entry page that all visitors will access first; once
+they visit the top-level page and the service worker is registered, it will automatically apply to
+all sub-pages, which will fall under its
+[scope](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-registration-scope).
+
+## `cacheOnly` & `cacheFirst` `defaultCacheStrategy` Considered Harmful
+The [`sw-toolbox` library](https://github.com/googlechrome/sw-toolbox),
+which `<platinum-sw-cache>` is built on, supports a number of
+[caching strategies](https://github.com/googlechrome/sw-toolbox#built-in-handlers).
+Two of them, `cacheOnly` and `cacheFirst`, are strongly discouraged to be used as the `defaultCacheStrategy`
+for `<platinum-sw-cache>`. With both of those strategies, all HTTP requests, including requests for
+the page which contains the `<platinum-sw-cache>` element, are served directly from the [Cache Storage
+API](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#cache-objects) without
+first consulting the network for a fresh copy. Once the copy of the host page is cached,
+it's extremely difficult to change the configuration of the service worker (since the configuration
+depends on the page's contents), and developers could find themselves deploying sites that can never
+update.
+
+In a future release of `<platinum-sw-cache>`, using `cacheOnly` and `cacheFirst` as `defaultCacheStrategy`
+may lead to an explicit error condition, but for the meantime, please consider a more reasonable default
+(like `networkFirst`).
diff --git a/polymer_1.0.4/bower_components/platinum-sw/bootstrap/sw-toolbox-setup.js b/polymer_1.0.4/bower_components/platinum-sw/bootstrap/sw-toolbox-setup.js
new file mode 100644
index 0000000..def76c5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-sw/bootstrap/sw-toolbox-setup.js
@@ -0,0 +1,38 @@
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+var swToolboxURL = new URL('../sw-toolbox/sw-toolbox.js', params.get('baseURI')).href;
+importScripts(swToolboxURL);
+
+if (params.has('defaultCacheStrategy')) {
+ var strategy = params.get('defaultCacheStrategy');
+ toolbox.router.default = toolbox[strategy] || self[strategy];
+}
+
+if (params.has('precache')) {
+ toolbox.precache(params.get('precache'));
+}
+
+if (params.has('route')) {
+ var setsOfRouteParams = params.get('route');
+ while (setsOfRouteParams.length > 0) {
+ var routeParams = setsOfRouteParams.splice(0, 3);
+ var originParam;
+ if (routeParams[2]) {
+ originParam = {origin: new RegExp(routeParams[2])};
+ }
+ var handler = toolbox[routeParams[1]] || self[routeParams[1]];
+ if (typeof handler === 'function') {
+ toolbox.router.get(routeParams[0], handler, originParam);
+ } else {
+ console.error('Unable to register sw-toolbox route: ', routeParams);
+ }
+ }
+}
diff --git a/polymer_1.0.4/bower_components/platinum-sw/bower.json b/polymer_1.0.4/bower_components/platinum-sw/bower.json
new file mode 100644
index 0000000..d221037
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-sw/bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "platinum-sw",
+ "private": true,
+ "version": "1.0.1",
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "description": "Service worker helper elements.",
+ "main": "platinum-sw-elements.html",
+ "keywords": [
+ "caching",
+ "offline",
+ "polymer",
+ "service-worker",
+ "serviceworker",
+ "web-component",
+ "web-components"
+ ],
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "polymer": "Polymer/polymer#^1.0.0",
+ "sw-toolbox": "^2.0.2"
+ },
+ "devDependencies": {
+ "iron-component-page": "PolymerElements/iron-component-page#^1.0.2",
+ "marked-element": "PolymerElements/marked-element#^1.0.0",
+ "web-component-tester": "*",
+ "fetch": "^0.9.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/platinum-sw/demo/index.html b/polymer_1.0.4/bower_components/platinum-sw/demo/index.html
new file mode 100644
index 0000000..2eb0db3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-sw/demo/index.html
@@ -0,0 +1,91 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>Platinum Service Worker Elements Demo</title>
+
+ <script src="../../fetch/fetch.js"></script>
+ <script src="../../webcomponentsjs/webcomponents-lite.min.js"></script>
+ <link rel="import" href="../platinum-sw-elements.html">
+ <link rel="import" href="../../marked-element/marked-element.html">
+ </head>
+
+ <body>
+ <template is="dom-bind" id="page-template">
+ <platinum-sw-register skip-waiting
+ clients-claim
+ reload-on-install
+ state="{{state}}">
+ <platinum-sw-cache default-cache-strategy="networkFirst"
+ precache="{{precacheList}}"></platinum-sw-cache>
+ </platinum-sw-register>
+
+ <h1>Platinum Service Worker Elements Demo</h1>
+ <p>This is a simple offline-capable eBook reader.</p>
+ <p>
+ On browsers that support service workers, this page itself and all the books are all
+ available offline, by virtue of the <code><platinum-sw-register></code> and
+ <code><platinum-sw-cache></code> elements.
+ </p>
+ <p>
+ Service workers are meant to be a progressive enhancement, and browsers that lack service
+ worker support will still have a functional (online-only) eBook reader.
+ </p>
+
+ <template is="dom-if" if="[[state]]">
+ <select on-change="selectBook">
+ <option disabled selected>Select a Book...</option>
+ <template is="dom-repeat" id="books" items="[[books]]">
+ <option>{{item.title}}</option>
+ </template>
+ </select>
+ </template>
+
+ <marked-element markdown="{{text}}"></marked-element>
+ </template>
+
+ <script>
+ var t = document.querySelector('#page-template');
+
+ t.books = [{
+ title: 'Don Quixote',
+ url: 'https://cdn.rawgit.com/GITenberg/Don-Quixote_996/master/996.txt'
+ }, {
+ title: 'Dubliners',
+ url: 'https://cdn.rawgit.com/GITenberg/Dubliners_2814/master/2814.txt'
+ }, {
+ title: 'Pride & Prejudice',
+ url: 'https://cdn.rawgit.com/GITenberg/Pride-and-Prejudice_1342/master/1342.txt'
+ }];
+
+ t.precacheList = t.books.map(function(book) {
+ return book.url;
+ });
+
+ t.selectBook = function(e) {
+ var books = document.querySelector('#books');
+ var selectedBook = books.itemForElement(e.target.selectedOptions[0]);
+ window.fetch(selectedBook.url).then(function(response) {
+ return response.text();
+ }).then(function(text) {
+ t.text = text;
+ });
+ };
+
+ window.addEventListener('WebComponentsReady', function() {
+ // Explicitly call the register() method. We need to wait until the template's variables are
+ // all set first, since the configuration depends on bound variables.
+ document.querySelector('platinum-sw-register').register();
+ });
+ </script>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/platinum-sw/demo/sw-import.js b/polymer_1.0.4/bower_components/platinum-sw/demo/sw-import.js
new file mode 100644
index 0000000..a4676ae
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-sw/demo/sw-import.js
@@ -0,0 +1 @@
+importScripts('../service-worker.js');
diff --git a/polymer_1.0.4/bower_components/platinum-sw/index.html b/polymer_1.0.4/bower_components/platinum-sw/index.html
new file mode 100644
index 0000000..8c4a6f3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-sw/index.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
+The complete set of authors may be found at http://polymer.github.io/AUTHORS
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
+-->
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <script src="../webcomponentsjs/webcomponents-lite.js"></script>
+ <link rel="import" href="../iron-component-page/iron-component-page.html">
+ </head>
+
+ <body>
+ <iron-component-page src="platinum-sw-elements.html"></iron-component-page>
+ </body>
+</html>
diff --git a/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-cache.html b/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-cache.html
new file mode 100644
index 0000000..5769af1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-cache.html
@@ -0,0 +1,116 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+ /**
+ * The `<platinum-sw-cache>` element makes it easy to precache specific resources, perform runtime
+ * caching, and serve your cached resources when a network is unavailable.
+ * Under the hood, the [sw-toolbox](https://github.com/googlechrome/sw-toolbox) library is used
+ * for all the caching and request handling logic.
+ * `<platinum-sw-cache>` needs to be a child element of `<platinum-sw-register>`.
+ * A simple, yet useful configuration is
+ *
+ * <platinum-sw-register>
+ * <platinum-sw-cache></platinum-sw-cache>
+ * </platinum-sw-register>
+ *
+ * This is enough to have all of the (local) resources your site uses cached at runtime.
+ * (It uses the default `defaultCacheStrategy` of "networkFirst".)
+ * When there's a network available, visits to your site will go against the network copy of the
+ * resources, but if someone visits your site when they're offline, all the cached resources will
+ * be used.
+ *
+ * @demo demo/index.html An offline-capable eReader demo.
+ */
+ Polymer({
+ is: 'platinum-sw-cache',
+
+ properties: {
+ /**
+ * The caching strategy used for all local (i.e. same-origin) requests.
+ *
+ * For a list of strategies, see the [`sw-toolbox` documentation](https://github.com/GoogleChrome/sw-toolbox#built-in-handlers).
+ * Specify a strategy as a string, without the "toolbox" prefix. E.g., for
+ * `toolbox.networkFirst`, set `defaultCacheStrategy` to "networkFirst".
+ *
+ * Note that the "cacheFirst" and "cacheOnly" strategies are not recommended, and may be
+ * explicitly prevented in a future release. More information can be found at
+ * https://github.com/PolymerElements/platinum-sw#cacheonly--cachefirst-defaultcachestrategy-considered-harmful
+ *
+ * @see {@link https://github.com/GoogleChrome/sw-toolbox#built-in-handlers}
+ */
+ defaultCacheStrategy: {
+ type: String,
+ value: 'networkFirst'
+ },
+
+ /**
+ * Used to provide a list of URLs that are always precached as soon as the service worker is
+ * installed. Corresponds to [`sw-toolbox`'s `precache()` method](https://github.com/GoogleChrome/sw-toolbox#toolboxprecachearrayofurls).
+ *
+ * This is useful for URLs that that wouldn't necessarily be picked up by runtime caching,
+ * i.e. a list of resources that are needed by one of the subpages of your site, or a list of
+ * resources that are only loaded via user interaction.
+ *
+ * `precache` can be used in conjunction with `precacheFile`, and the two arrays will be
+ * concatenated.
+ *
+ * @see {@link https://github.com/GoogleChrome/sw-toolbox#toolboxprecachearrayofurls}
+ */
+ precache: {
+ type: Array,
+ value: function() { return []; }
+ },
+
+ /**
+ * Used to provide a list of URLs that are always precached as soon as the service worker is
+ * installed. Corresponds to [`sw-toolbox`'s `precache()` method](https://github.com/GoogleChrome/sw-toolbox#toolboxprecachearrayofurls).
+ *
+ * While the `precache` option supports provided the array of URLs in as an inline attribute,
+ * this option supports providing them as an array in JSON file, which is fetched at runtime.
+ * This is useful if the array is generated via a separate build step, as it's easier to
+ * write that output to a file then it is to modify inline HTML content.
+ *
+ * `precacheFile` can be used in conjunction with `precache`, and the two arrays will be
+ * concatenated.
+ *
+ * @see {@link https://github.com/GoogleChrome/sw-toolbox#toolboxprecachearrayofurls}
+ */
+ precacheFile: String
+ },
+
+ _getParameters: function(baseURI) {
+ return new Promise(function(resolve) {
+ var params = {
+ importscriptLate: new URL('bootstrap/sw-toolbox-setup.js', baseURI).href,
+ defaultCacheStrategy: this.defaultCacheStrategy,
+ precache: this.precache
+ };
+
+ if (this.precacheFile) {
+ window.fetch(this.precacheFile).then(function(response) {
+ if (!response.ok) {
+ throw Error('unable to load ' + this.precacheFile);
+ }
+ return response.json();
+ }.bind(this)).then(function(files) {
+ params.precache = params.precache.concat(files);
+ }).catch(function(error) {
+ console.info('Skipping precaching: ' + error.message);
+ }).then(function() {
+ resolve(params);
+ });
+ } else {
+ resolve(params);
+ }
+ }.bind(this));
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-elements.html b/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-elements.html
new file mode 100644
index 0000000..b8effdf
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-elements.html
@@ -0,0 +1,14 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<!-- Facilitates importing the full collection of platinum-sw elements. -->
+<link rel="import" href="platinum-sw-cache.html">
+<link rel="import" href="platinum-sw-fetch.html">
+<link rel="import" href="platinum-sw-import-script.html">
+<link rel="import" href="platinum-sw-register.html">
diff --git a/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-fetch.html b/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-fetch.html
new file mode 100644
index 0000000..35d5028
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-fetch.html
@@ -0,0 +1,130 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+ /**
+ * The `<platinum-sw-fetch>` element creates custom [`fetch` event](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#fetch-event-section)
+ * handlers for given URL patterns. Possible use cases include:
+ *
+ * - Using a special caching strategy for specific URLs.
+ * - Returning static "fallback" responses instead of network errors when a remote API
+ * is unavailable.
+ *
+ * In short, any scenario in which you'd like a service worker to intercept network
+ * requests and provide custom response handling.
+ *
+ * If you'd like a single caching policy applied to all same-origin requests, then an alternative
+ * to using `<platinum-sw-fetch>` is to use `<platinum-sw-cache>` with the `defaultCacheStategy`
+ * property set.
+ *
+ * Under the hood, the [sw-toolbox](https://github.com/googlechrome/sw-toolbox) library is used
+ * for all the request handling logic.
+ *
+ * `<platinum-sw-fetch>` needs to be a child element of `<platinum-sw-register>`.
+ *
+ * An example configuration is:
+ *
+ * <platinum-sw-register>
+ * <platinum-sw-import-script href="custom-fetch-handler.js"></platinum-sw-import-script>
+ * <platinum-sw-fetch handler="customFetchHandler"
+ * path="/(.*)/customFetch"></platinum-sw-fetch>
+ * </platinum-sw-register>
+ *
+ * This implies that there's a `custom-fetch-handler.js` file in the same directory as the current
+ * page, which defines a `sw-toolbox` compliant
+ * [request handler](https://github.com/googlechrome/sw-toolbox#request-handlers) named
+ * `customFetchHandler`. This definition is imported using `<platinum-sw-import-script>`. The
+ * `<platinum-sw-fetch>` element takes care of mapping which request paths are handled by
+ * `customFetchHandler`.
+ *
+ * Anything not matching the `path` pattern is ignored by `<platinum-sw-fetch>`,
+ * and it's possible to have multiple `<platinum-sw-fetch>` elements that each define different
+ * paths and different handlers. The path matching is performed top-down, starting with the first
+ * `<platinum-sw-fetch>` element.
+ */
+ Polymer({
+ is: 'platinum-sw-fetch',
+
+ properties: {
+ /**
+ * The name of the request handler to use. This should be a `sw-toolbox`-style
+ * [request handler](https://github.com/googlechrome/sw-toolbox#request-handlers).
+ *
+ * `handler` is a `String`, not a `function`, so you're providing the name of a function, not
+ * the function itself. It can be a function defined in the
+ * [`toolbox` scope](https://github.com/googlechrome/sw-toolbox#built-in-handlers)
+ * (e.g. 'networkFirst', 'fastest', 'networkOnly', etc.) or a function defined in the
+ * [`ServiceWorkerGlobalScope`](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#service-worker-global-scope),
+ * like a function that is defined in a file that's imported via `platinum-sw-import-script`.
+ **
+ * @see {@link https://github.com/GoogleChrome/sw-toolbox#built-in-handlers}
+ */
+ handler: String,
+
+ /**
+ * By default, `path` will only match URLs under the current host (i.e. same-origin requests).
+ * If you'd like to apply `handler` to cross-origin requests, then use `origin` to specify
+ * which hosts will match. Setting `origin` is optional.
+ *
+ * `origin` is a `String`, but it is used internally to construct a
+ * [`RegExp` object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions),
+ * which is used for the matching. To properly escape RegExp sequences like `\.`, it's
+ * necessary to add in an extra level of string-escaping first ('\\.').
+ *
+ * Note that the `origin` value will be matched against the full domain name and the protocol.
+ * If you want to match 'http' and 'https', then use 'https?://' at the start of your string.
+ *
+ * Some examples:
+ * - `origin="https?://.+\\.google\\.com"` → a RegExp that matches `http` or `https` requests
+ * made to any domain, as long as it ends in `.google.com`.
+ * - `origin="https://www\\.example\\.com" → a RegExp that will only match `https` requests to
+ * one domain, `www.example.com`.
+ *
+ * @see {@link https://github.com/googlechrome/sw-toolbox#toolboxrouterheadurlpattern-handler-options}
+ */
+ origin: String,
+
+ /**
+ * URLs with paths matching `path` will have `handler` applied to them.
+ *
+ * By default, `path` will only match same-origin URLs. If you'd like it to match
+ * cross-origin URLs, use `path` in conjunction with `origin`.
+ *
+ * As explained in the
+ * [`sw-toolbox` docs](https://github.com/googlechrome/sw-toolbox#toolboxrouterheadurlpattern-handler-options),
+ * the URL path matching is done using the [`path-to-regexp`](https://github.com/pillarjs/path-to-regexp)
+ * module, which is the same logic used in [Express-style routing](http://expressjs.com/guide/routing.html).
+ *
+ * In practice, you need to always use '/' as the first character of your `path`, and then
+ * can use '(.*)' as a wildcard.
+ *
+ * Some examples:
+ * - `path="/(.*)/customFetch"` → matches any path that ends with '/customFetch'.
+ * - `path="/customFetch(.*)"` → matches any path that starts with '/customFetch', optionally
+ * followed by other characters.
+ *
+ * @see {@link https://github.com/pillarjs/path-to-regexp}
+ */
+ path: String
+ },
+
+ _getParameters: function(baseURI) {
+ return new Promise(function(resolve) {
+ var params = {
+ importscriptLate: new URL('bootstrap/sw-toolbox-setup.js', baseURI).href
+ };
+ if (this.path && this.handler) {
+ params.route = [this.path, this.handler, this.origin];
+ }
+ resolve(params);
+ }.bind(this));
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-import-script.html b/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-import-script.html
new file mode 100644
index 0000000..2478f55
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-import-script.html
@@ -0,0 +1,57 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+ /**
+ * The `<platinum-sw-import-script>` element is used to import a JavaScript file that is executed
+ * each time the service worker starts up.
+ *
+ * `<platinum-sw-import-script>` needs to be a child element of `<platinum-sw-register>`.
+ *
+ * A common use case is to define a custom request handler for a `fetch` event, but it can be used
+ * for any type of code that you want to be executed by the service worker.
+ *
+ * <platinum-sw-register>
+ * <platinum-sw-import-script href="custom-fetch-handler.js"></platinum-sw-import-script>
+ * <platinum-sw-fetch handler="customFetchHandler"
+ * path="/(.*)/customFetch"></platinum-sw-fetch>
+ * </platinum-sw-register>
+ *
+ * You can specify multiple `<platinum-sw-import-script>` elements, each one corresponding to a
+ * different JavaScript file. The JavaScript files will be loaded in the order in which the
+ * `<platinum-sw-import-script>` elements appear. Under the hood, this results in an
+ * [`importScripts()`](https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts)
+ * call made from the context of the service worker.
+ */
+ Polymer({
+ is: 'platinum-sw-import-script',
+
+ properties: {
+ /**
+ * The URL of the JavaScript file that you want imported.
+ *
+ * Relative URLs are assumed to be
+ * relative to the service worker's script location, which will almost always be the same
+ * location as the page which includes this element.
+ */
+ href: String
+ },
+
+ _getParameters: function() {
+ return new Promise(function(resolve) {
+ var params = {};
+ if (this.href) {
+ params.importscript = this.href;
+ }
+ resolve(params);
+ }.bind(this));
+ }
+ });
+</script>
diff --git a/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-register.html b/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-register.html
new file mode 100644
index 0000000..1a93a2a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-sw/platinum-sw-register.html
@@ -0,0 +1,342 @@
+<!--
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<link rel="import" href="../polymer/polymer.html">
+
+<script>
+ (function() {
+ // Grab the URI of this file to use as a base when resolving relative paths.
+ // Fallback to './' as a default, though current browsers that don't support
+ // document.currentScript also don't support service workers.
+ var baseURI = document.currentScript ? document.currentScript.baseURI : './';
+
+ /**
+ * The `<platinum-sw-register>` element handles
+ * [service worker](http://www.html5rocks.com/en/tutorials/service-worker/introduction/)
+ * registration, reflects the overall service worker state, and coordinates the configuration
+ * provided by other Service Worker Elements.
+ * `<platinum-sw-register>` is used as a parent element for child elements in the
+ * `<platinum-sw-*>` group.
+ *
+ * <platinum-sw-register skip-waiting
+ * clients-claim
+ * auto-register
+ * state="{{state}}"
+ * on-service-worker-error="handleSWError"
+ * on-service-worker-updated="handleSWUpdated"
+ * on-service-worker-installed="handleSWInstalled">
+ * ...one or more <platinum-sw-*> children which share the service worker registration...
+ * </platinum-sw-register>
+ *
+ * Please see https://github.com/PolymerElements/platinum-sw#top-level-sw-importjs for a
+ * *crucial* prerequisite file you must create before `<platinum-sw-register>` can be used!
+ *
+ * @demo demo/index.html An offline-capable eReader demo.
+ */
+ Polymer({
+ is: 'platinum-sw-register',
+
+ // Used as an "emergency" switch if we make breaking changes in the way <platinum-sw-register>
+ // talks to service-worker.js. Otherwise, it shouldn't need to change, and isn't meant to be
+ // kept in sync with the element's release number.
+ _version: '1.0',
+
+ /**
+ * Fired when the initial service worker installation completes successfully.
+ * The service worker will normally only be installed once, the first time a page with a
+ * `<platinum-sw-register>` element is visited in a given browser. If the same page is visited
+ * again, the existing service worker will be reused, and there won't be another
+ * `service-worker-installed` fired.
+ *
+ * @event service-worker-installed
+ * @param {String} A message indicating that the installation succeeded.
+ */
+
+ /**
+ * Fired when the service worker update flow completes successfully.
+ * If you make changes to your `<platinum-sw-register>` configuration (i.e. by adding in new
+ * `<platinum-sw-*>` child elements, or changing their attributes), users who had the old
+ * service worker installed will get the update installed when they see the modified elements.
+ *
+ * @event service-worker-updated
+ * @param {String} A message indicating that the update succeeded.
+ */
+
+ /**
+ * Fired when an error prevents the service worker installation from completing.
+ *
+ * @event service-worker-error
+ * @param {String} A message indicating what went wrong.
+ */
+
+ properties: {
+ /**
+ * Whether this element should automatically register the corresponding service worker as
+ * soon as its added to a page.
+ *
+ * If set to `false`, then the service worker won't be automatically registered, and you
+ * must call this element's `register()` method if you want service worker functionality.
+ * This is useful if, for example, the service worker needs to be configured using
+ * information that isn't immediately available at the time the page loads.
+ *
+ * If set to `true`, the service worker will be automatically registered without having to
+ * call any methods.
+ */
+ autoRegister: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Whether the activated service worker should [take immediate control](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#clients-claim-method)
+ * of any pages under its scope.
+ *
+ * If this is `false`, the service worker won't have any effect until the next time the page
+ * is visited/reloaded.
+ * If this is `true`, it will take control and start handling events for the current page
+ * (and any pages under the same scope open in other tabs/windows) as soon it's active.
+ * @see {@link https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#clients-claim-method}
+ */
+ clientsClaim: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The service worker script that is [registered](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#navigator-service-worker-register).
+ * The script *should* be located at the top level of your site, to ensure that it is able
+ * to control all the pages on your site.
+ *
+ * It's *strongly* recommended that you create a top-level file named `sw-import.js`
+ * containing only:
+ *
+ * `importScripts('bower_components/platinum-sw/service-worker.js');`
+ *
+ * (adjust to match the path where your `platinum-sw` element directory can be found).
+ *
+ * This will ensure that your service worker script contains everything needed to play
+ * nicely with the Service Worker Elements group.
+ *
+ * @see {@link https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#navigator-service-worker-register}
+ */
+ href: {
+ type: String,
+ value: 'sw-import.js'
+ },
+
+ /**
+ * Whether the page should be automatically reloaded (via `window.location.reload()`) when
+ * the service worker is successfully installed.
+ *
+ * While it's perfectly valid to continue using a page with a freshly installed service
+ * worker, it's a common pattern to want to reload it immediately following the install.
+ * This ensures that, for example, if you're using a `<platinum-sw-cache>` with an on the
+ * fly caching strategy, it will get a chance to intercept all the requests needed to render
+ * your page and store them in the cache.
+ *
+ * If you don't immediately reload your page, then any resources that were loaded before the
+ * service worker was installed (e.g. this `platinum-sw-register.html` file) won't be present
+ * in the cache until the next time the page is loaded.
+ *
+ * Note that this reload will only happen when a service worker is installed for the first
+ * time. If the service worker is subsequently updated, it won't trigger another reload.
+ */
+ reloadOnInstall: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The scope of the service worker, relative to the registered service worker script.
+ * All pages that fall under this scope will be controlled by the registered service worker.
+ *
+ * Normally, this would not need to be changed, unless you want the service worker to only
+ * apply to a subset of your site.
+ *
+ * @see {@link https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#navigator-service-worker-register}
+ */
+ scope: {
+ type: String,
+ value: './'
+ },
+
+ /**
+ * Whether an updated service worker should [bypass the `waiting` state](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#service-worker-global-scope-skipwaiting)
+ * and immediately become `active`.
+ *
+ * Normally, during an update, the new service worker stays in the
+ * `waiting` state until the current page and any other tabs/windows that are using the old
+ * service worker are unloaded.
+ *
+ * If this is `false`, an updated service worker won't be activated until all instances of
+ * the old server worker have been unloaded.
+ *
+ * If this is `true`, an updated service worker will become `active` immediately.
+ * @see {@link https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#service-worker-global-scope-skipwaiting}
+ */
+ skipWaiting: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The current state of the service worker registered by this element.
+ *
+ * One of:
+ * - 'installed'
+ * - 'updated'
+ * - 'error'
+ * - 'unsupported'
+ */
+ state: {
+ notify: true,
+ readOnly: true,
+ type: String
+ }
+ },
+
+ /**
+ * Registers the service worker based on the configuration options in this element and any
+ * child elements.
+ *
+ * If you set the `autoRegister` property to `true`, then this method is called automatically
+ * at page load.
+ * It can be useful to set `autoRegister` to `false` and then explicitly call this method if
+ * there are options that are only configured after the page is loaded.
+ */
+ register: function() {
+ if ('serviceWorker' in navigator) {
+ this._constructServiceWorkerUrl().then(function(serviceWorkerUrl) {
+ this._registerServiceWorker(serviceWorkerUrl);
+ }.bind(this));
+ } else {
+ this._setState('unsupported');
+ this.fire('service-worker-error', 'Service workers are not available in the current browser.');
+ }
+ },
+
+ _constructServiceWorkerUrl: function() {
+ var paramsPromises = [];
+ var children = Polymer.dom(this).childNodes;
+ for (var i = 0; i < children.length; i++) {
+ if (typeof children[i]._getParameters === 'function') {
+ paramsPromises.push(children[i]._getParameters(baseURI));
+ }
+ }
+
+ return Promise.all(paramsPromises).then(function(paramsResolutions) {
+ var params = {
+ baseURI: baseURI,
+ version: this._version
+ };
+
+ paramsResolutions.forEach(function(childParams) {
+ Object.keys(childParams).forEach(function(key) {
+ if (Array.isArray(params[key])) {
+ params[key].push(childParams[key]);
+ } else {
+ params[key] = [childParams[key]];
+ }
+ });
+ });
+
+ return params;
+ }.bind(this)).then(function(params) {
+ if (params.importscriptLate) {
+ if (params.importscript) {
+ params.importscript = params.importscript.concat(params.importscriptLate);
+ } else {
+ params.importscript = params.importscriptLate;
+ }
+ }
+
+ if (params.importscript) {
+ params.importscript = this._unique(params.importscript);
+ }
+
+ params.clientsClaim = this.clientsClaim;
+ params.skipWaiting = this.skipWaiting;
+
+ var serviceWorkerUrl = new URL(this.href, window.location);
+ // It's very important to ensure that the serialization is stable.
+ // Serializing the same settings should always produce the same URL.
+ // Serializing different settings should always produce a different URL.
+ // This ensures that the service worker upgrade flow is triggered when settings change.
+ serviceWorkerUrl.search = this._serializeUrlParams(params);
+
+ return serviceWorkerUrl;
+ }.bind(this));
+ },
+
+ _unique: function(arr) {
+ return arr.filter(function(item, index) {
+ return arr.indexOf(item) === index;
+ });
+ },
+
+ _serializeUrlParams: function(params) {
+ return Object.keys(params).sort().map(function(key) {
+ // encodeURIComponent(['a', 'b']) => 'a%2Cb',
+ // so this will still work when the values are Arrays.
+ // TODO: It won't work if the values in the Arrays have ',' characters in them.
+ return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
+ }).join('&');
+ },
+
+ _registerServiceWorker: function(serviceWorkerUrl) {
+ navigator.serviceWorker.register(serviceWorkerUrl, {scope: this.scope}).then(function(registration) {
+ if (registration.active) {
+ this._setState('installed');
+ }
+
+ registration.onupdatefound = function() {
+ var installingWorker = registration.installing;
+ installingWorker.onstatechange = function() {
+ switch (installingWorker.state) {
+ case 'installed':
+ if (navigator.serviceWorker.controller) {
+ this._setState('updated');
+ this.fire('service-worker-updated',
+ 'A new service worker was installed, replacing the old service worker.');
+ } else {
+ if (this.reloadOnInstall) {
+ window.location.reload();
+ } else {
+ this._setState('installed');
+ this.fire('service-worker-installed', 'A new service worker was installed.');
+ }
+ }
+ break;
+
+ case 'redundant':
+ this._setState('error');
+ this.fire('service-worker-error', 'The installing service worker became redundant.');
+ break;
+ }
+ }.bind(this);
+ }.bind(this);
+ }.bind(this)).catch(function(error) {
+ this._setState('error');
+ this.fire('service-worker-error', error.toString());
+ if (error.name === 'NetworkError') {
+ var location = serviceWorkerUrl.origin + serviceWorkerUrl.pathname;
+ console.error('A valid service worker script was not found at ' + location + '\n' +
+ 'To learn how to fix this, please see\n' +
+ 'https://github.com/PolymerElements/platinum-sw#top-level-sw-importjs');
+ }
+ }.bind(this));
+ },
+
+ attached: function() {
+ if (this.autoRegister) {
+ this.async(this.register);
+ }
+ }
+ });
+ })();
+</script>
diff --git a/polymer_1.0.4/bower_components/platinum-sw/service-worker.js b/polymer_1.0.4/bower_components/platinum-sw/service-worker.js
new file mode 100644
index 0000000..9766e60
--- /dev/null
+++ b/polymer_1.0.4/bower_components/platinum-sw/service-worker.js
@@ -0,0 +1,52 @@
+/**
+ * @license
+ * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+var VERSION = '1.0';
+
+function deserializeUrlParams(queryString) {
+ return new Map(queryString.split('&').map(function(keyValuePair) {
+ var splits = keyValuePair.split('=');
+ var key = decodeURIComponent(splits[0]);
+ var value = decodeURIComponent(splits[1]);
+ if (value.indexOf(',') >= 0) {
+ value = value.split(',');
+ }
+
+ return [key, value];
+ }));
+}
+
+self.params = deserializeUrlParams(location.search.substring(1));
+
+if (params.get('version') !== VERSION) {
+ throw 'The registered script is version ' + VERSION +
+ ' and cannot be used with <platinum-sw-register> version ' + params.get('version');
+}
+
+if (params.has('importscript')) {
+ var scripts = params.get('importscript');
+ if (Array.isArray(scripts)) {
+ importScripts.apply(null, scripts);
+ } else {
+ importScripts(scripts);
+ }
+}
+
+if (params.get('skipWaiting') === 'true' && self.skipWaiting) {
+ self.addEventListener('install', function(e) {
+ e.waitUntil(self.skipWaiting());
+ });
+}
+
+if (params.get('clientsClaim') === 'true' && self.clients && self.clients.claim) {
+ self.addEventListener('activate', function(e) {
+ e.waitUntil(self.clients.claim());
+ });
+}
diff --git a/polymer_1.0.4/bower_components/polymer/.bower.json b/polymer_1.0.4/bower_components/polymer/.bower.json
new file mode 100644
index 0000000..49970f2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/polymer/.bower.json
@@ -0,0 +1,36 @@
+{
+ "name": "polymer",
+ "version": "1.0.4",
+ "main": [
+ "polymer.html"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "authors": [
+ "The Polymer Authors (http://polymer.github.io/AUTHORS.txt)"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/Polymer/polymer.git"
+ },
+ "dependencies": {
+ "webcomponentsjs": "^0.7.2"
+ },
+ "devDependencies": {
+ "web-component-tester": "*"
+ },
+ "private": true,
+ "homepage": "https://github.com/polymer/polymer",
+ "_release": "1.0.4",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.4",
+ "commit": "cdabb91ad8ddf9bbefa308a25c5633d768501e7d"
+ },
+ "_source": "git://github.com/polymer/polymer.git",
+ "_target": "^1.0.0",
+ "_originalSource": "polymer/polymer"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/polymer/LICENSE.txt b/polymer_1.0.4/bower_components/polymer/LICENSE.txt
new file mode 100644
index 0000000..95987ba
--- /dev/null
+++ b/polymer_1.0.4/bower_components/polymer/LICENSE.txt
@@ -0,0 +1,27 @@
+// Copyright (c) 2014 The Polymer Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/polymer_1.0.4/bower_components/polymer/bower.json b/polymer_1.0.4/bower_components/polymer/bower.json
new file mode 100644
index 0000000..fc37f18
--- /dev/null
+++ b/polymer_1.0.4/bower_components/polymer/bower.json
@@ -0,0 +1,26 @@
+{
+ "name": "polymer",
+ "version": "1.0.4",
+ "main": [
+ "polymer.html"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "ignore": [
+ "/.*",
+ "/test/"
+ ],
+ "authors": [
+ "The Polymer Authors (http://polymer.github.io/AUTHORS.txt)"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/Polymer/polymer.git"
+ },
+ "dependencies": {
+ "webcomponentsjs": "^0.7.2"
+ },
+ "devDependencies": {
+ "web-component-tester": "*"
+ },
+ "private": true
+}
diff --git a/polymer_1.0.4/bower_components/polymer/build.log b/polymer_1.0.4/bower_components/polymer/build.log
new file mode 100644
index 0000000..039beaa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/polymer/build.log
@@ -0,0 +1,26 @@
+BUILD LOG
+---------
+Build Time: 2015-06-17T16:52:02-0700
+
+NODEJS INFORMATION
+==================
+nodejs: v0.12.2
+gulp-audit: 1.0.0
+gulp-rename: 1.2.2
+gulp-replace: 0.5.3
+gulp-vulcanize: 6.0.1
+lazypipe: 0.2.3
+run-sequence: 1.1.0
+del: 1.2.0
+gulp: 3.9.0
+polyclean: 1.2.0
+
+REPO REVISIONS
+==============
+polymer: ea8a40372a2adc5b64a00286442fecb8f0ec75c8
+
+BUILD HASHES
+============
+polymer-mini.html: 44c03aa7229b6b4aa6d64efb90d3f1544d2c143b
+polymer-micro.html: d176197b360ac2f2928a727bc84549cb6c68e276
+polymer.html: 22ef66ee16aea1c4e50f606a0f0cf5573e02ba79
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/polymer/polymer-micro.html b/polymer_1.0.4/bower_components/polymer/polymer-micro.html
new file mode 100644
index 0000000..e16f5b1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/polymer/polymer-micro.html
@@ -0,0 +1,523 @@
+<!--
+@license
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+--><script>(function () {
+function resolve() {
+document.body.removeAttribute('unresolved');
+}
+if (window.WebComponents) {
+addEventListener('WebComponentsReady', resolve);
+} else {
+if (document.readyState === 'interactive' || document.readyState === 'complete') {
+resolve();
+} else {
+addEventListener('DOMContentLoaded', resolve);
+}
+}
+}());
+Polymer = {
+Settings: function () {
+var user = window.Polymer || {};
+location.search.slice(1).split('&').forEach(function (o) {
+o = o.split('=');
+o[0] && (user[o[0]] = o[1] || true);
+});
+var wantShadow = user.dom === 'shadow';
+var hasShadow = Boolean(Element.prototype.createShadowRoot);
+var nativeShadow = hasShadow && !window.ShadowDOMPolyfill;
+var useShadow = wantShadow && hasShadow;
+var hasNativeImports = Boolean('import' in document.createElement('link'));
+var useNativeImports = hasNativeImports;
+var useNativeCustomElements = !window.CustomElements || window.CustomElements.useNative;
+return {
+wantShadow: wantShadow,
+hasShadow: hasShadow,
+nativeShadow: nativeShadow,
+useShadow: useShadow,
+useNativeShadow: useShadow && nativeShadow,
+useNativeImports: useNativeImports,
+useNativeCustomElements: useNativeCustomElements
+};
+}()
+};
+(function () {
+var userPolymer = window.Polymer;
+window.Polymer = function (prototype) {
+var ctor = desugar(prototype);
+prototype = ctor.prototype;
+var options = { prototype: prototype };
+if (prototype.extends) {
+options.extends = prototype.extends;
+}
+Polymer.telemetry._registrate(prototype);
+document.registerElement(prototype.is, options);
+return ctor;
+};
+var desugar = function (prototype) {
+prototype = Polymer.Base.chainObject(prototype, Polymer.Base);
+prototype.registerCallback();
+return prototype.constructor;
+};
+window.Polymer = Polymer;
+if (userPolymer) {
+for (var i in userPolymer) {
+Polymer[i] = userPolymer[i];
+}
+}
+Polymer.Class = desugar;
+}());
+Polymer.telemetry = {
+registrations: [],
+_regLog: function (prototype) {
+console.log('[' + prototype.is + ']: registered');
+},
+_registrate: function (prototype) {
+this.registrations.push(prototype);
+Polymer.log && this._regLog(prototype);
+},
+dumpRegistrations: function () {
+this.registrations.forEach(this._regLog);
+}
+};
+Object.defineProperty(window, 'currentImport', {
+enumerable: true,
+configurable: true,
+get: function () {
+return (document._currentScript || document.currentScript).ownerDocument;
+}
+});
+Polymer.Base = {
+_addFeature: function (feature) {
+this.extend(this, feature);
+},
+registerCallback: function () {
+this._registerFeatures();
+this._doBehavior('registered');
+},
+createdCallback: function () {
+Polymer.telemetry.instanceCount++;
+this.root = this;
+this._doBehavior('created');
+this._initFeatures();
+},
+attachedCallback: function () {
+this.isAttached = true;
+this._doBehavior('attached');
+},
+detachedCallback: function () {
+this.isAttached = false;
+this._doBehavior('detached');
+},
+attributeChangedCallback: function (name) {
+this._setAttributeToProperty(this, name);
+this._doBehavior('attributeChanged', arguments);
+},
+extend: function (prototype, api) {
+if (prototype && api) {
+Object.getOwnPropertyNames(api).forEach(function (n) {
+this.copyOwnProperty(n, api, prototype);
+}, this);
+}
+return prototype || api;
+},
+copyOwnProperty: function (name, source, target) {
+var pd = Object.getOwnPropertyDescriptor(source, name);
+if (pd) {
+Object.defineProperty(target, name, pd);
+}
+},
+_log: console.log.apply.bind(console.log, console),
+_warn: console.warn.apply.bind(console.warn, console),
+_error: console.error.apply.bind(console.error, console),
+_logf: function () {
+return this._logPrefix.concat([this.is]).concat(Array.prototype.slice.call(arguments, 0));
+}
+};
+Polymer.Base._logPrefix = function () {
+var color = window.chrome || /firefox/i.test(navigator.userAgent);
+return color ? [
+'%c[%s::%s]:',
+'font-weight: bold; background-color:#EEEE00;'
+] : ['[%s::%s]:'];
+}();
+Polymer.Base.chainObject = function (object, inherited) {
+if (object && inherited && object !== inherited) {
+if (!Object.__proto__) {
+object = Polymer.Base.extend(Object.create(inherited), object);
+}
+object.__proto__ = inherited;
+}
+return object;
+};
+Polymer.Base = Polymer.Base.chainObject(Polymer.Base, HTMLElement.prototype);
+Polymer.telemetry.instanceCount = 0;
+(function () {
+var modules = {};
+var DomModule = function () {
+return document.createElement('dom-module');
+};
+DomModule.prototype = Object.create(HTMLElement.prototype);
+DomModule.prototype.constructor = DomModule;
+DomModule.prototype.createdCallback = function () {
+var id = this.id || this.getAttribute('name') || this.getAttribute('is');
+if (id) {
+this.id = id;
+modules[id] = this;
+}
+};
+DomModule.prototype.import = function (id, slctr) {
+var m = modules[id];
+if (!m) {
+forceDocumentUpgrade();
+m = modules[id];
+}
+if (m && slctr) {
+m = m.querySelector(slctr);
+}
+return m;
+};
+var cePolyfill = window.CustomElements && !CustomElements.useNative;
+if (cePolyfill) {
+var ready = CustomElements.ready;
+CustomElements.ready = true;
+}
+document.registerElement('dom-module', DomModule);
+if (cePolyfill) {
+CustomElements.ready = ready;
+}
+function forceDocumentUpgrade() {
+if (cePolyfill) {
+var script = document._currentScript || document.currentScript;
+if (script) {
+CustomElements.upgradeAll(script.ownerDocument);
+}
+}
+}
+}());
+Polymer.Base._addFeature({
+_prepIs: function () {
+if (!this.is) {
+var module = (document._currentScript || document.currentScript).parentNode;
+if (module.localName === 'dom-module') {
+var id = module.id || module.getAttribute('name') || module.getAttribute('is');
+this.is = id;
+}
+}
+}
+});
+Polymer.Base._addFeature({
+behaviors: [],
+_prepBehaviors: function () {
+if (this.behaviors.length) {
+this.behaviors = this._flattenBehaviorsList(this.behaviors);
+}
+this._prepAllBehaviors(this.behaviors);
+},
+_flattenBehaviorsList: function (behaviors) {
+var flat = [];
+behaviors.forEach(function (b) {
+if (b instanceof Array) {
+flat = flat.concat(this._flattenBehaviorsList(b));
+} else if (b) {
+flat.push(b);
+} else {
+this._warn(this._logf('_flattenBehaviorsList', 'behavior is null, check for missing or 404 import'));
+}
+}, this);
+return flat;
+},
+_prepAllBehaviors: function (behaviors) {
+for (var i = behaviors.length - 1; i >= 0; i--) {
+this._mixinBehavior(behaviors[i]);
+}
+for (var i = 0, l = behaviors.length; i < l; i++) {
+this._prepBehavior(behaviors[i]);
+}
+this._prepBehavior(this);
+},
+_mixinBehavior: function (b) {
+Object.getOwnPropertyNames(b).forEach(function (n) {
+switch (n) {
+case 'hostAttributes':
+case 'registered':
+case 'properties':
+case 'observers':
+case 'listeners':
+case 'created':
+case 'attached':
+case 'detached':
+case 'attributeChanged':
+case 'configure':
+case 'ready':
+break;
+default:
+if (!this.hasOwnProperty(n)) {
+this.copyOwnProperty(n, b, this);
+}
+break;
+}
+}, this);
+},
+_doBehavior: function (name, args) {
+this.behaviors.forEach(function (b) {
+this._invokeBehavior(b, name, args);
+}, this);
+this._invokeBehavior(this, name, args);
+},
+_invokeBehavior: function (b, name, args) {
+var fn = b[name];
+if (fn) {
+fn.apply(this, args || Polymer.nar);
+}
+},
+_marshalBehaviors: function () {
+this.behaviors.forEach(function (b) {
+this._marshalBehavior(b);
+}, this);
+this._marshalBehavior(this);
+}
+});
+Polymer.Base._addFeature({
+_prepExtends: function () {
+if (this.extends) {
+this.__proto__ = this._getExtendedPrototype(this.extends);
+}
+},
+_getExtendedPrototype: function (tag) {
+return this._getExtendedNativePrototype(tag);
+},
+_nativePrototypes: {},
+_getExtendedNativePrototype: function (tag) {
+var p = this._nativePrototypes[tag];
+if (!p) {
+var np = this.getNativePrototype(tag);
+p = this.extend(Object.create(np), Polymer.Base);
+this._nativePrototypes[tag] = p;
+}
+return p;
+},
+getNativePrototype: function (tag) {
+return Object.getPrototypeOf(document.createElement(tag));
+}
+});
+Polymer.Base._addFeature({
+_prepConstructor: function () {
+this._factoryArgs = this.extends ? [
+this.extends,
+this.is
+] : [this.is];
+var ctor = function () {
+return this._factory(arguments);
+};
+if (this.hasOwnProperty('extends')) {
+ctor.extends = this.extends;
+}
+Object.defineProperty(this, 'constructor', {
+value: ctor,
+writable: true,
+configurable: true
+});
+ctor.prototype = this;
+},
+_factory: function (args) {
+var elt = document.createElement.apply(document, this._factoryArgs);
+if (this.factoryImpl) {
+this.factoryImpl.apply(elt, args);
+}
+return elt;
+}
+});
+Polymer.nob = Object.create(null);
+Polymer.Base._addFeature({
+properties: {},
+getPropertyInfo: function (property) {
+var info = this._getPropertyInfo(property, this.properties);
+if (!info) {
+this.behaviors.some(function (b) {
+return info = this._getPropertyInfo(property, b.properties);
+}, this);
+}
+return info || Polymer.nob;
+},
+_getPropertyInfo: function (property, properties) {
+var p = properties && properties[property];
+if (typeof p === 'function') {
+p = properties[property] = { type: p };
+}
+if (p) {
+p.defined = true;
+}
+return p;
+}
+});
+Polymer.CaseMap = {
+_caseMap: {},
+dashToCamelCase: function (dash) {
+var mapped = Polymer.CaseMap._caseMap[dash];
+if (mapped) {
+return mapped;
+}
+if (dash.indexOf('-') < 0) {
+return Polymer.CaseMap._caseMap[dash] = dash;
+}
+return Polymer.CaseMap._caseMap[dash] = dash.replace(/-([a-z])/g, function (m) {
+return m[1].toUpperCase();
+});
+},
+camelToDashCase: function (camel) {
+var mapped = Polymer.CaseMap._caseMap[camel];
+if (mapped) {
+return mapped;
+}
+return Polymer.CaseMap._caseMap[camel] = camel.replace(/([a-z][A-Z])/g, function (g) {
+return g[0] + '-' + g[1].toLowerCase();
+});
+}
+};
+Polymer.Base._addFeature({
+_prepAttributes: function () {
+this._aggregatedAttributes = {};
+},
+_addHostAttributes: function (attributes) {
+if (attributes) {
+this.mixin(this._aggregatedAttributes, attributes);
+}
+},
+_marshalHostAttributes: function () {
+this._applyAttributes(this, this._aggregatedAttributes);
+},
+_applyAttributes: function (node, attr$) {
+for (var n in attr$) {
+if (!this.hasAttribute(n) && n !== 'class') {
+this.serializeValueToAttribute(attr$[n], n, this);
+}
+}
+},
+_marshalAttributes: function () {
+this._takeAttributesToModel(this);
+},
+_takeAttributesToModel: function (model) {
+for (var i = 0, l = this.attributes.length; i < l; i++) {
+this._setAttributeToProperty(model, this.attributes[i].name);
+}
+},
+_setAttributeToProperty: function (model, attrName) {
+if (!this._serializing) {
+var propName = Polymer.CaseMap.dashToCamelCase(attrName);
+var info = this.getPropertyInfo(propName);
+if (info.defined || this._propertyEffects && this._propertyEffects[propName]) {
+var val = this.getAttribute(attrName);
+model[propName] = this.deserialize(val, info.type);
+}
+}
+},
+_serializing: false,
+reflectPropertyToAttribute: function (name) {
+this._serializing = true;
+this.serializeValueToAttribute(this[name], Polymer.CaseMap.camelToDashCase(name));
+this._serializing = false;
+},
+serializeValueToAttribute: function (value, attribute, node) {
+var str = this.serialize(value);
+(node || this)[str === undefined ? 'removeAttribute' : 'setAttribute'](attribute, str);
+},
+deserialize: function (value, type) {
+switch (type) {
+case Number:
+value = Number(value);
+break;
+case Boolean:
+value = value !== null;
+break;
+case Object:
+try {
+value = JSON.parse(value);
+} catch (x) {
+}
+break;
+case Array:
+try {
+value = JSON.parse(value);
+} catch (x) {
+value = null;
+console.warn('Polymer::Attributes: couldn`t decode Array as JSON');
+}
+break;
+case Date:
+value = new Date(value);
+break;
+case String:
+default:
+break;
+}
+return value;
+},
+serialize: function (value) {
+switch (typeof value) {
+case 'boolean':
+return value ? '' : undefined;
+case 'object':
+if (value instanceof Date) {
+return value;
+} else if (value) {
+try {
+return JSON.stringify(value);
+} catch (x) {
+return '';
+}
+}
+default:
+return value != null ? value : undefined;
+}
+}
+});
+Polymer.Base._addFeature({
+_setupDebouncers: function () {
+this._debouncers = {};
+},
+debounce: function (jobName, callback, wait) {
+this._debouncers[jobName] = Polymer.Debounce.call(this, this._debouncers[jobName], callback, wait);
+},
+isDebouncerActive: function (jobName) {
+var debouncer = this._debouncers[jobName];
+return debouncer && debouncer.finish;
+},
+flushDebouncer: function (jobName) {
+var debouncer = this._debouncers[jobName];
+if (debouncer) {
+debouncer.complete();
+}
+},
+cancelDebouncer: function (jobName) {
+var debouncer = this._debouncers[jobName];
+if (debouncer) {
+debouncer.stop();
+}
+}
+});
+Polymer.version = '1.0.4';
+Polymer.Base._addFeature({
+_registerFeatures: function () {
+this._prepIs();
+this._prepAttributes();
+this._prepBehaviors();
+this._prepExtends();
+this._prepConstructor();
+},
+_prepBehavior: function (b) {
+this._addHostAttributes(b.hostAttributes);
+},
+_marshalBehavior: function (b) {
+},
+_initFeatures: function () {
+this._marshalHostAttributes();
+this._setupDebouncers();
+this._marshalBehaviors();
+}
+});</script>
+
diff --git a/polymer_1.0.4/bower_components/polymer/polymer-mini.html b/polymer_1.0.4/bower_components/polymer/polymer-mini.html
new file mode 100644
index 0000000..2539312
--- /dev/null
+++ b/polymer_1.0.4/bower_components/polymer/polymer-mini.html
@@ -0,0 +1,1396 @@
+<!--
+@license
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+--><link rel="import" href="polymer-micro.html">
+
+<script>Polymer.Base._addFeature({
+_prepTemplate: function () {
+this._template = this._template || Polymer.DomModule.import(this.is, 'template');
+if (this._template && this._template.hasAttribute('is')) {
+this._warn(this._logf('_prepTemplate', 'top-level Polymer template ' + 'must not be a type-extension, found', this._template, 'Move inside simple <template>.'));
+}
+},
+_stampTemplate: function () {
+if (this._template) {
+this.root = this.instanceTemplate(this._template);
+}
+},
+instanceTemplate: function (template) {
+var dom = document.importNode(template._content || template.content, true);
+return dom;
+}
+});
+(function () {
+var baseAttachedCallback = Polymer.Base.attachedCallback;
+Polymer.Base._addFeature({
+_hostStack: [],
+ready: function () {
+},
+_pushHost: function (host) {
+this.dataHost = host = host || Polymer.Base._hostStack[Polymer.Base._hostStack.length - 1];
+if (host && host._clients) {
+host._clients.push(this);
+}
+this._beginHost();
+},
+_beginHost: function () {
+Polymer.Base._hostStack.push(this);
+if (!this._clients) {
+this._clients = [];
+}
+},
+_popHost: function () {
+Polymer.Base._hostStack.pop();
+},
+_tryReady: function () {
+if (this._canReady()) {
+this._ready();
+}
+},
+_canReady: function () {
+return !this.dataHost || this.dataHost._clientsReadied;
+},
+_ready: function () {
+this._beforeClientsReady();
+this._setupRoot();
+this._readyClients();
+this._afterClientsReady();
+this._readySelf();
+},
+_readyClients: function () {
+this._beginDistribute();
+var c$ = this._clients;
+for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
+c._ready();
+}
+this._finishDistribute();
+this._clientsReadied = true;
+this._clients = null;
+},
+_readySelf: function () {
+this._doBehavior('ready');
+this._readied = true;
+if (this._attachedPending) {
+this._attachedPending = false;
+this.attachedCallback();
+}
+},
+_beforeClientsReady: function () {
+},
+_afterClientsReady: function () {
+},
+_beforeAttached: function () {
+},
+attachedCallback: function () {
+if (this._readied) {
+this._beforeAttached();
+baseAttachedCallback.call(this);
+} else {
+this._attachedPending = true;
+}
+}
+});
+}());
+Polymer.ArraySplice = function () {
+function newSplice(index, removed, addedCount) {
+return {
+index: index,
+removed: removed,
+addedCount: addedCount
+};
+}
+var EDIT_LEAVE = 0;
+var EDIT_UPDATE = 1;
+var EDIT_ADD = 2;
+var EDIT_DELETE = 3;
+function ArraySplice() {
+}
+ArraySplice.prototype = {
+calcEditDistances: function (current, currentStart, currentEnd, old, oldStart, oldEnd) {
+var rowCount = oldEnd - oldStart + 1;
+var columnCount = currentEnd - currentStart + 1;
+var distances = new Array(rowCount);
+for (var i = 0; i < rowCount; i++) {
+distances[i] = new Array(columnCount);
+distances[i][0] = i;
+}
+for (var j = 0; j < columnCount; j++)
+distances[0][j] = j;
+for (var i = 1; i < rowCount; i++) {
+for (var j = 1; j < columnCount; j++) {
+if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1]))
+distances[i][j] = distances[i - 1][j - 1];
+else {
+var north = distances[i - 1][j] + 1;
+var west = distances[i][j - 1] + 1;
+distances[i][j] = north < west ? north : west;
+}
+}
+}
+return distances;
+},
+spliceOperationsFromEditDistances: function (distances) {
+var i = distances.length - 1;
+var j = distances[0].length - 1;
+var current = distances[i][j];
+var edits = [];
+while (i > 0 || j > 0) {
+if (i == 0) {
+edits.push(EDIT_ADD);
+j--;
+continue;
+}
+if (j == 0) {
+edits.push(EDIT_DELETE);
+i--;
+continue;
+}
+var northWest = distances[i - 1][j - 1];
+var west = distances[i - 1][j];
+var north = distances[i][j - 1];
+var min;
+if (west < north)
+min = west < northWest ? west : northWest;
+else
+min = north < northWest ? north : northWest;
+if (min == northWest) {
+if (northWest == current) {
+edits.push(EDIT_LEAVE);
+} else {
+edits.push(EDIT_UPDATE);
+current = northWest;
+}
+i--;
+j--;
+} else if (min == west) {
+edits.push(EDIT_DELETE);
+i--;
+current = west;
+} else {
+edits.push(EDIT_ADD);
+j--;
+current = north;
+}
+}
+edits.reverse();
+return edits;
+},
+calcSplices: function (current, currentStart, currentEnd, old, oldStart, oldEnd) {
+var prefixCount = 0;
+var suffixCount = 0;
+var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);
+if (currentStart == 0 && oldStart == 0)
+prefixCount = this.sharedPrefix(current, old, minLength);
+if (currentEnd == current.length && oldEnd == old.length)
+suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);
+currentStart += prefixCount;
+oldStart += prefixCount;
+currentEnd -= suffixCount;
+oldEnd -= suffixCount;
+if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0)
+return [];
+if (currentStart == currentEnd) {
+var splice = newSplice(currentStart, [], 0);
+while (oldStart < oldEnd)
+splice.removed.push(old[oldStart++]);
+return [splice];
+} else if (oldStart == oldEnd)
+return [newSplice(currentStart, [], currentEnd - currentStart)];
+var ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));
+var splice = undefined;
+var splices = [];
+var index = currentStart;
+var oldIndex = oldStart;
+for (var i = 0; i < ops.length; i++) {
+switch (ops[i]) {
+case EDIT_LEAVE:
+if (splice) {
+splices.push(splice);
+splice = undefined;
+}
+index++;
+oldIndex++;
+break;
+case EDIT_UPDATE:
+if (!splice)
+splice = newSplice(index, [], 0);
+splice.addedCount++;
+index++;
+splice.removed.push(old[oldIndex]);
+oldIndex++;
+break;
+case EDIT_ADD:
+if (!splice)
+splice = newSplice(index, [], 0);
+splice.addedCount++;
+index++;
+break;
+case EDIT_DELETE:
+if (!splice)
+splice = newSplice(index, [], 0);
+splice.removed.push(old[oldIndex]);
+oldIndex++;
+break;
+}
+}
+if (splice) {
+splices.push(splice);
+}
+return splices;
+},
+sharedPrefix: function (current, old, searchLength) {
+for (var i = 0; i < searchLength; i++)
+if (!this.equals(current[i], old[i]))
+return i;
+return searchLength;
+},
+sharedSuffix: function (current, old, searchLength) {
+var index1 = current.length;
+var index2 = old.length;
+var count = 0;
+while (count < searchLength && this.equals(current[--index1], old[--index2]))
+count++;
+return count;
+},
+calculateSplices: function (current, previous) {
+return this.calcSplices(current, 0, current.length, previous, 0, previous.length);
+},
+equals: function (currentValue, previousValue) {
+return currentValue === previousValue;
+}
+};
+return new ArraySplice();
+}();
+Polymer.EventApi = function () {
+var Settings = Polymer.Settings;
+var EventApi = function (event) {
+this.event = event;
+};
+if (Settings.useShadow) {
+EventApi.prototype = {
+get rootTarget() {
+return this.event.path[0];
+},
+get localTarget() {
+return this.event.target;
+},
+get path() {
+return this.event.path;
+}
+};
+} else {
+EventApi.prototype = {
+get rootTarget() {
+return this.event.target;
+},
+get localTarget() {
+var current = this.event.currentTarget;
+var currentRoot = current && Polymer.dom(current).getOwnerRoot();
+var p$ = this.path;
+for (var i = 0; i < p$.length; i++) {
+if (Polymer.dom(p$[i]).getOwnerRoot() === currentRoot) {
+return p$[i];
+}
+}
+},
+get path() {
+if (!this.event._path) {
+var path = [];
+var o = this.rootTarget;
+while (o) {
+path.push(o);
+o = Polymer.dom(o).parentNode || o.host;
+}
+path.push(window);
+this.event._path = path;
+}
+return this.event._path;
+}
+};
+}
+var factory = function (event) {
+if (!event.__eventApi) {
+event.__eventApi = new EventApi(event);
+}
+return event.__eventApi;
+};
+return { factory: factory };
+}();
+Polymer.domInnerHTML = function () {
+var escapeAttrRegExp = /[&\u00A0"]/g;
+var escapeDataRegExp = /[&\u00A0<>]/g;
+function escapeReplace(c) {
+switch (c) {
+case '&':
+return '&';
+case '<':
+return '<';
+case '>':
+return '>';
+case '"':
+return '"';
+case '\xA0':
+return ' ';
+}
+}
+function escapeAttr(s) {
+return s.replace(escapeAttrRegExp, escapeReplace);
+}
+function escapeData(s) {
+return s.replace(escapeDataRegExp, escapeReplace);
+}
+function makeSet(arr) {
+var set = {};
+for (var i = 0; i < arr.length; i++) {
+set[arr[i]] = true;
+}
+return set;
+}
+var voidElements = makeSet([
+'area',
+'base',
+'br',
+'col',
+'command',
+'embed',
+'hr',
+'img',
+'input',
+'keygen',
+'link',
+'meta',
+'param',
+'source',
+'track',
+'wbr'
+]);
+var plaintextParents = makeSet([
+'style',
+'script',
+'xmp',
+'iframe',
+'noembed',
+'noframes',
+'plaintext',
+'noscript'
+]);
+function getOuterHTML(node, parentNode, composed) {
+switch (node.nodeType) {
+case Node.ELEMENT_NODE:
+var tagName = node.localName;
+var s = '<' + tagName;
+var attrs = node.attributes;
+for (var i = 0, attr; attr = attrs[i]; i++) {
+s += ' ' + attr.name + '="' + escapeAttr(attr.value) + '"';
+}
+s += '>';
+if (voidElements[tagName]) {
+return s;
+}
+return s + getInnerHTML(node, composed) + '</' + tagName + '>';
+case Node.TEXT_NODE:
+var data = node.data;
+if (parentNode && plaintextParents[parentNode.localName]) {
+return data;
+}
+return escapeData(data);
+case Node.COMMENT_NODE:
+return '<!--' + node.data + '-->';
+default:
+console.error(node);
+throw new Error('not implemented');
+}
+}
+function getInnerHTML(node, composed) {
+if (node instanceof HTMLTemplateElement)
+node = node.content;
+var s = '';
+var c$ = Polymer.dom(node).childNodes;
+c$ = composed ? node._composedChildren : c$;
+for (var i = 0, l = c$.length, child; i < l && (child = c$[i]); i++) {
+s += getOuterHTML(child, node, composed);
+}
+return s;
+}
+return { getInnerHTML: getInnerHTML };
+}();
+Polymer.DomApi = function () {
+'use strict';
+var Settings = Polymer.Settings;
+var getInnerHTML = Polymer.domInnerHTML.getInnerHTML;
+var nativeInsertBefore = Element.prototype.insertBefore;
+var nativeRemoveChild = Element.prototype.removeChild;
+var nativeAppendChild = Element.prototype.appendChild;
+var dirtyRoots = [];
+var DomApi = function (node) {
+this.node = node;
+if (this.patch) {
+this.patch();
+}
+};
+DomApi.prototype = {
+flush: function () {
+for (var i = 0, host; i < dirtyRoots.length; i++) {
+host = dirtyRoots[i];
+host.flushDebouncer('_distribute');
+}
+dirtyRoots = [];
+},
+_lazyDistribute: function (host) {
+if (host.shadyRoot && host.shadyRoot._distributionClean) {
+host.shadyRoot._distributionClean = false;
+host.debounce('_distribute', host._distributeContent);
+dirtyRoots.push(host);
+}
+},
+appendChild: function (node) {
+var handled;
+this._removeNodeFromHost(node, true);
+if (this._nodeIsInLogicalTree(this.node)) {
+this._addLogicalInfo(node, this.node);
+this._addNodeToHost(node);
+handled = this._maybeDistribute(node, this.node);
+}
+if (!handled && !this._tryRemoveUndistributedNode(node)) {
+var container = this.node._isShadyRoot ? this.node.host : this.node;
+addToComposedParent(container, node);
+nativeAppendChild.call(container, node);
+}
+return node;
+},
+insertBefore: function (node, ref_node) {
+if (!ref_node) {
+return this.appendChild(node);
+}
+var handled;
+this._removeNodeFromHost(node, true);
+if (this._nodeIsInLogicalTree(this.node)) {
+saveLightChildrenIfNeeded(this.node);
+var children = this.childNodes;
+var index = children.indexOf(ref_node);
+if (index < 0) {
+throw Error('The ref_node to be inserted before is not a child ' + 'of this node');
+}
+this._addLogicalInfo(node, this.node, index);
+this._addNodeToHost(node);
+handled = this._maybeDistribute(node, this.node);
+}
+if (!handled && !this._tryRemoveUndistributedNode(node)) {
+ref_node = ref_node.localName === CONTENT ? this._firstComposedNode(ref_node) : ref_node;
+var container = this.node._isShadyRoot ? this.node.host : this.node;
+addToComposedParent(container, node, ref_node);
+nativeInsertBefore.call(container, node, ref_node);
+}
+return node;
+},
+removeChild: function (node) {
+if (factory(node).parentNode !== this.node) {
+console.warn('The node to be removed is not a child of this node', node);
+}
+var handled;
+if (this._nodeIsInLogicalTree(this.node)) {
+this._removeNodeFromHost(node);
+handled = this._maybeDistribute(node, this.node);
+}
+if (!handled) {
+var container = this.node._isShadyRoot ? this.node.host : this.node;
+if (container === node.parentNode) {
+removeFromComposedParent(container, node);
+nativeRemoveChild.call(container, node);
+}
+}
+return node;
+},
+replaceChild: function (node, ref_node) {
+this.insertBefore(node, ref_node);
+this.removeChild(ref_node);
+return node;
+},
+getOwnerRoot: function () {
+return this._ownerShadyRootForNode(this.node);
+},
+_ownerShadyRootForNode: function (node) {
+if (!node) {
+return;
+}
+if (node._ownerShadyRoot === undefined) {
+var root;
+if (node._isShadyRoot) {
+root = node;
+} else {
+var parent = Polymer.dom(node).parentNode;
+if (parent) {
+root = parent._isShadyRoot ? parent : this._ownerShadyRootForNode(parent);
+} else {
+root = null;
+}
+}
+node._ownerShadyRoot = root;
+}
+return node._ownerShadyRoot;
+},
+_maybeDistribute: function (node, parent) {
+var fragContent = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && node.querySelector(CONTENT);
+var wrappedContent = fragContent && fragContent.parentNode.nodeType !== Node.DOCUMENT_FRAGMENT_NODE;
+var hasContent = fragContent || node.localName === CONTENT;
+if (hasContent) {
+var root = this._ownerShadyRootForNode(parent);
+if (root) {
+var host = root.host;
+this._updateInsertionPoints(host);
+this._lazyDistribute(host);
+}
+}
+var parentNeedsDist = this._parentNeedsDistribution(parent);
+if (parentNeedsDist) {
+this._lazyDistribute(parent);
+}
+return parentNeedsDist || hasContent && !wrappedContent;
+},
+_tryRemoveUndistributedNode: function (node) {
+if (this.node.shadyRoot) {
+if (node.parentNode) {
+nativeRemoveChild.call(node.parentNode, node);
+}
+return true;
+}
+},
+_updateInsertionPoints: function (host) {
+host.shadyRoot._insertionPoints = factory(host.shadyRoot).querySelectorAll(CONTENT);
+},
+_nodeIsInLogicalTree: function (node) {
+return Boolean(node._lightParent || node._isShadyRoot || this._ownerShadyRootForNode(node) || node.shadyRoot);
+},
+_parentNeedsDistribution: function (parent) {
+return parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot);
+},
+_removeNodeFromHost: function (node, ensureComposedRemoval) {
+var hostNeedsDist;
+var root;
+var parent = node._lightParent;
+if (parent) {
+root = this._ownerShadyRootForNode(node);
+if (root) {
+root.host._elementRemove(node);
+hostNeedsDist = this._removeDistributedChildren(root, node);
+}
+this._removeLogicalInfo(node, node._lightParent);
+}
+this._removeOwnerShadyRoot(node);
+if (root && hostNeedsDist) {
+this._updateInsertionPoints(root.host);
+this._lazyDistribute(root.host);
+} else if (ensureComposedRemoval) {
+removeFromComposedParent(parent || node.parentNode, node);
+}
+},
+_removeDistributedChildren: function (root, container) {
+var hostNeedsDist;
+var ip$ = root._insertionPoints;
+for (var i = 0; i < ip$.length; i++) {
+var content = ip$[i];
+if (this._contains(container, content)) {
+var dc$ = factory(content).getDistributedNodes();
+for (var j = 0; j < dc$.length; j++) {
+hostNeedsDist = true;
+var node = dc$[i];
+var parent = node.parentNode;
+if (parent) {
+removeFromComposedParent(parent, node);
+nativeRemoveChild.call(parent, node);
+}
+}
+}
+}
+return hostNeedsDist;
+},
+_contains: function (container, node) {
+while (node) {
+if (node == container) {
+return true;
+}
+node = factory(node).parentNode;
+}
+},
+_addNodeToHost: function (node) {
+var checkNode = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE ? node.firstChild : node;
+var root = this._ownerShadyRootForNode(checkNode);
+if (root) {
+root.host._elementAdd(node);
+}
+},
+_addLogicalInfo: function (node, container, index) {
+saveLightChildrenIfNeeded(container);
+var children = factory(container).childNodes;
+index = index === undefined ? children.length : index;
+if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
+var c$ = Array.prototype.slice.call(node.childNodes);
+for (var i = 0, n; i < c$.length && (n = c$[i]); i++) {
+children.splice(index++, 0, n);
+n._lightParent = container;
+}
+} else {
+children.splice(index, 0, node);
+node._lightParent = container;
+}
+},
+_removeLogicalInfo: function (node, container) {
+var children = factory(container).childNodes;
+var index = children.indexOf(node);
+if (index < 0 || container !== node._lightParent) {
+throw Error('The node to be removed is not a child of this node');
+}
+children.splice(index, 1);
+node._lightParent = null;
+},
+_removeOwnerShadyRoot: function (node) {
+var hasCachedRoot = factory(node).getOwnerRoot() !== undefined;
+if (hasCachedRoot) {
+var c$ = factory(node).childNodes;
+for (var i = 0, l = c$.length, n; i < l && (n = c$[i]); i++) {
+this._removeOwnerShadyRoot(n);
+}
+}
+node._ownerShadyRoot = undefined;
+},
+_firstComposedNode: function (content) {
+var n$ = factory(content).getDistributedNodes();
+for (var i = 0, l = n$.length, n, p$; i < l && (n = n$[i]); i++) {
+p$ = factory(n).getDestinationInsertionPoints();
+if (p$[p$.length - 1] === content) {
+return n;
+}
+}
+},
+querySelector: function (selector) {
+return this.querySelectorAll(selector)[0];
+},
+querySelectorAll: function (selector) {
+return this._query(function (n) {
+return matchesSelector.call(n, selector);
+}, this.node);
+},
+_query: function (matcher, node) {
+node = node || this.node;
+var list = [];
+this._queryElements(factory(node).childNodes, matcher, list);
+return list;
+},
+_queryElements: function (elements, matcher, list) {
+for (var i = 0, l = elements.length, c; i < l && (c = elements[i]); i++) {
+if (c.nodeType === Node.ELEMENT_NODE) {
+this._queryElement(c, matcher, list);
+}
+}
+},
+_queryElement: function (node, matcher, list) {
+if (matcher(node)) {
+list.push(node);
+}
+this._queryElements(factory(node).childNodes, matcher, list);
+},
+getDestinationInsertionPoints: function () {
+return this.node._destinationInsertionPoints || [];
+},
+getDistributedNodes: function () {
+return this.node._distributedNodes || [];
+},
+queryDistributedElements: function (selector) {
+var c$ = this.childNodes;
+var list = [];
+this._distributedFilter(selector, c$, list);
+for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
+if (c.localName === CONTENT) {
+this._distributedFilter(selector, factory(c).getDistributedNodes(), list);
+}
+}
+return list;
+},
+_distributedFilter: function (selector, list, results) {
+results = results || [];
+for (var i = 0, l = list.length, d; i < l && (d = list[i]); i++) {
+if (d.nodeType === Node.ELEMENT_NODE && d.localName !== CONTENT && matchesSelector.call(d, selector)) {
+results.push(d);
+}
+}
+return results;
+},
+_clear: function () {
+while (this.childNodes.length) {
+this.removeChild(this.childNodes[0]);
+}
+},
+setAttribute: function (name, value) {
+this.node.setAttribute(name, value);
+this._distributeParent();
+},
+removeAttribute: function (name) {
+this.node.removeAttribute(name);
+this._distributeParent();
+},
+_distributeParent: function () {
+if (this._parentNeedsDistribution(this.parentNode)) {
+this._lazyDistribute(this.parentNode);
+}
+}
+};
+Object.defineProperty(DomApi.prototype, 'classList', {
+get: function () {
+if (!this._classList) {
+this._classList = new DomApi.ClassList(this);
+}
+return this._classList;
+},
+configurable: true
+});
+DomApi.ClassList = function (host) {
+this.domApi = host;
+this.node = host.node;
+};
+DomApi.ClassList.prototype = {
+add: function () {
+this.node.classList.add.apply(this.node.classList, arguments);
+this.domApi._distributeParent();
+},
+remove: function () {
+this.node.classList.remove.apply(this.node.classList, arguments);
+this.domApi._distributeParent();
+},
+toggle: function () {
+this.node.classList.toggle.apply(this.node.classList, arguments);
+this.domApi._distributeParent();
+}
+};
+if (!Settings.useShadow) {
+Object.defineProperties(DomApi.prototype, {
+childNodes: {
+get: function () {
+var c$ = getLightChildren(this.node);
+return Array.isArray(c$) ? c$ : Array.prototype.slice.call(c$);
+},
+configurable: true
+},
+children: {
+get: function () {
+return Array.prototype.filter.call(this.childNodes, function (n) {
+return n.nodeType === Node.ELEMENT_NODE;
+});
+},
+configurable: true
+},
+parentNode: {
+get: function () {
+return this.node._lightParent || (this.node.__patched ? this.node._composedParent : this.node.parentNode);
+},
+configurable: true
+},
+firstChild: {
+get: function () {
+return this.childNodes[0];
+},
+configurable: true
+},
+lastChild: {
+get: function () {
+var c$ = this.childNodes;
+return c$[c$.length - 1];
+},
+configurable: true
+},
+nextSibling: {
+get: function () {
+var c$ = this.parentNode && factory(this.parentNode).childNodes;
+if (c$) {
+return c$[Array.prototype.indexOf.call(c$, this.node) + 1];
+}
+},
+configurable: true
+},
+previousSibling: {
+get: function () {
+var c$ = this.parentNode && factory(this.parentNode).childNodes;
+if (c$) {
+return c$[Array.prototype.indexOf.call(c$, this.node) - 1];
+}
+},
+configurable: true
+},
+firstElementChild: {
+get: function () {
+return this.children[0];
+},
+configurable: true
+},
+lastElementChild: {
+get: function () {
+var c$ = this.children;
+return c$[c$.length - 1];
+},
+configurable: true
+},
+nextElementSibling: {
+get: function () {
+var c$ = this.parentNode && factory(this.parentNode).children;
+if (c$) {
+return c$[Array.prototype.indexOf.call(c$, this.node) + 1];
+}
+},
+configurable: true
+},
+previousElementSibling: {
+get: function () {
+var c$ = this.parentNode && factory(this.parentNode).children;
+if (c$) {
+return c$[Array.prototype.indexOf.call(c$, this.node) - 1];
+}
+},
+configurable: true
+},
+textContent: {
+get: function () {
+if (this.node.nodeType === Node.TEXT_NODE) {
+return this.node.textContent;
+} else {
+return Array.prototype.map.call(this.childNodes, function (c) {
+return c.textContent;
+}).join('');
+}
+},
+set: function (text) {
+this._clear();
+if (text) {
+this.appendChild(document.createTextNode(text));
+}
+},
+configurable: true
+},
+innerHTML: {
+get: function () {
+if (this.node.nodeType === Node.TEXT_NODE) {
+return null;
+} else {
+return getInnerHTML(this.node);
+}
+},
+set: function (text) {
+if (this.node.nodeType !== Node.TEXT_NODE) {
+this._clear();
+var d = document.createElement('div');
+d.innerHTML = text;
+for (var e = d.firstChild; e; e = e.nextSibling) {
+this.appendChild(e);
+}
+}
+},
+configurable: true
+}
+});
+DomApi.prototype._getComposedInnerHTML = function () {
+return getInnerHTML(this.node, true);
+};
+} else {
+DomApi.prototype.querySelectorAll = function (selector) {
+return Array.prototype.slice.call(this.node.querySelectorAll(selector));
+};
+DomApi.prototype.getOwnerRoot = function () {
+var n = this.node;
+while (n) {
+if (n.nodeType === Node.DOCUMENT_FRAGMENT_NODE && n.host) {
+return n;
+}
+n = n.parentNode;
+}
+};
+DomApi.prototype.getDestinationInsertionPoints = function () {
+var n$ = this.node.getDestinationInsertionPoints();
+return n$ ? Array.prototype.slice.call(n$) : [];
+};
+DomApi.prototype.getDistributedNodes = function () {
+var n$ = this.node.getDistributedNodes();
+return n$ ? Array.prototype.slice.call(n$) : [];
+};
+DomApi.prototype._distributeParent = function () {
+};
+Object.defineProperties(DomApi.prototype, {
+childNodes: {
+get: function () {
+return Array.prototype.slice.call(this.node.childNodes);
+},
+configurable: true
+},
+children: {
+get: function () {
+return Array.prototype.slice.call(this.node.children);
+},
+configurable: true
+},
+textContent: {
+get: function () {
+return this.node.textContent;
+},
+set: function (value) {
+return this.node.textContent = value;
+},
+configurable: true
+},
+innerHTML: {
+get: function () {
+return this.node.innerHTML;
+},
+set: function (value) {
+return this.node.innerHTML = value;
+},
+configurable: true
+}
+});
+var forwards = [
+'parentNode',
+'firstChild',
+'lastChild',
+'nextSibling',
+'previousSibling',
+'firstElementChild',
+'lastElementChild',
+'nextElementSibling',
+'previousElementSibling'
+];
+forwards.forEach(function (name) {
+Object.defineProperty(DomApi.prototype, name, {
+get: function () {
+return this.node[name];
+},
+configurable: true
+});
+});
+}
+var CONTENT = 'content';
+var factory = function (node, patch) {
+node = node || document;
+if (!node.__domApi) {
+node.__domApi = new DomApi(node, patch);
+}
+return node.__domApi;
+};
+Polymer.dom = function (obj, patch) {
+if (obj instanceof Event) {
+return Polymer.EventApi.factory(obj);
+} else {
+return factory(obj, patch);
+}
+};
+Polymer.dom.flush = DomApi.prototype.flush;
+function getLightChildren(node) {
+var children = node._lightChildren;
+return children ? children : node.childNodes;
+}
+function getComposedChildren(node) {
+if (!node._composedChildren) {
+node._composedChildren = Array.prototype.slice.call(node.childNodes);
+}
+return node._composedChildren;
+}
+function addToComposedParent(parent, node, ref_node) {
+var children = getComposedChildren(parent);
+var i = ref_node ? children.indexOf(ref_node) : -1;
+if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
+var fragChildren = getComposedChildren(node);
+for (var j = 0; j < fragChildren.length; j++) {
+addNodeToComposedChildren(fragChildren[j], parent, children, i + j);
+}
+node._composedChildren = null;
+} else {
+addNodeToComposedChildren(node, parent, children, i);
+}
+}
+function addNodeToComposedChildren(node, parent, children, i) {
+node._composedParent = parent;
+children.splice(i >= 0 ? i : children.length, 0, node);
+}
+function removeFromComposedParent(parent, node) {
+node._composedParent = null;
+if (parent) {
+var children = getComposedChildren(parent);
+var i = children.indexOf(node);
+if (i >= 0) {
+children.splice(i, 1);
+}
+}
+}
+function saveLightChildrenIfNeeded(node) {
+if (!node._lightChildren) {
+var c$ = Array.prototype.slice.call(node.childNodes);
+for (var i = 0, l = c$.length, child; i < l && (child = c$[i]); i++) {
+child._lightParent = child._lightParent || node;
+}
+node._lightChildren = c$;
+}
+}
+function hasInsertionPoint(root) {
+return Boolean(root._insertionPoints.length);
+}
+var p = Element.prototype;
+var matchesSelector = p.matches || p.matchesSelector || p.mozMatchesSelector || p.msMatchesSelector || p.oMatchesSelector || p.webkitMatchesSelector;
+return {
+getLightChildren: getLightChildren,
+getComposedChildren: getComposedChildren,
+removeFromComposedParent: removeFromComposedParent,
+saveLightChildrenIfNeeded: saveLightChildrenIfNeeded,
+matchesSelector: matchesSelector,
+hasInsertionPoint: hasInsertionPoint,
+ctor: DomApi,
+factory: factory
+};
+}();
+(function () {
+Polymer.Base._addFeature({
+_prepShady: function () {
+this._useContent = this._useContent || Boolean(this._template);
+if (this._useContent) {
+this._template._hasInsertionPoint = this._template.content.querySelector('content');
+}
+},
+_poolContent: function () {
+if (this._useContent) {
+saveLightChildrenIfNeeded(this);
+}
+},
+_setupRoot: function () {
+if (this._useContent) {
+this._createLocalRoot();
+if (!this.dataHost) {
+upgradeLightChildren(this._lightChildren);
+}
+}
+},
+_createLocalRoot: function () {
+this.shadyRoot = this.root;
+this.shadyRoot._distributionClean = false;
+this.shadyRoot._isShadyRoot = true;
+this.shadyRoot._dirtyRoots = [];
+this.shadyRoot._insertionPoints = this._template._hasInsertionPoint ? this.shadyRoot.querySelectorAll('content') : [];
+saveLightChildrenIfNeeded(this.shadyRoot);
+this.shadyRoot.host = this;
+},
+get domHost() {
+var root = Polymer.dom(this).getOwnerRoot();
+return root && root.host;
+},
+distributeContent: function (updateInsertionPoints) {
+if (this.shadyRoot) {
+var dom = Polymer.dom(this);
+if (updateInsertionPoints) {
+dom._updateInsertionPoints(this);
+}
+var host = getTopDistributingHost(this);
+dom._lazyDistribute(host);
+}
+},
+_distributeContent: function () {
+if (this._useContent && !this.shadyRoot._distributionClean) {
+this._beginDistribute();
+this._distributeDirtyRoots();
+this._finishDistribute();
+}
+},
+_beginDistribute: function () {
+if (this._useContent && hasInsertionPoint(this.shadyRoot)) {
+this._resetDistribution();
+this._distributePool(this.shadyRoot, this._collectPool());
+}
+},
+_distributeDirtyRoots: function () {
+var c$ = this.shadyRoot._dirtyRoots;
+for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
+c._distributeContent();
+}
+this.shadyRoot._dirtyRoots = [];
+},
+_finishDistribute: function () {
+if (this._useContent) {
+if (hasInsertionPoint(this.shadyRoot)) {
+this._composeTree();
+} else {
+if (!this.shadyRoot._hasDistributed) {
+this.textContent = '';
+this._composedChildren = null;
+this.appendChild(this.shadyRoot);
+} else {
+var children = this._composeNode(this);
+this._updateChildNodes(this, children);
+}
+}
+this.shadyRoot._hasDistributed = true;
+this.shadyRoot._distributionClean = true;
+}
+},
+elementMatches: function (selector, node) {
+node = node || this;
+return matchesSelector.call(node, selector);
+},
+_resetDistribution: function () {
+var children = getLightChildren(this);
+for (var i = 0; i < children.length; i++) {
+var child = children[i];
+if (child._destinationInsertionPoints) {
+child._destinationInsertionPoints = undefined;
+}
+if (isInsertionPoint(child)) {
+clearDistributedDestinationInsertionPoints(child);
+}
+}
+var root = this.shadyRoot;
+var p$ = root._insertionPoints;
+for (var j = 0; j < p$.length; j++) {
+p$[j]._distributedNodes = [];
+}
+},
+_collectPool: function () {
+var pool = [];
+var children = getLightChildren(this);
+for (var i = 0; i < children.length; i++) {
+var child = children[i];
+if (isInsertionPoint(child)) {
+pool.push.apply(pool, child._distributedNodes);
+} else {
+pool.push(child);
+}
+}
+return pool;
+},
+_distributePool: function (node, pool) {
+var p$ = node._insertionPoints;
+for (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) {
+this._distributeInsertionPoint(p, pool);
+maybeRedistributeParent(p, this);
+}
+},
+_distributeInsertionPoint: function (content, pool) {
+var anyDistributed = false;
+for (var i = 0, l = pool.length, node; i < l; i++) {
+node = pool[i];
+if (!node) {
+continue;
+}
+if (this._matchesContentSelect(node, content)) {
+distributeNodeInto(node, content);
+pool[i] = undefined;
+anyDistributed = true;
+}
+}
+if (!anyDistributed) {
+var children = getLightChildren(content);
+for (var j = 0; j < children.length; j++) {
+distributeNodeInto(children[j], content);
+}
+}
+},
+_composeTree: function () {
+this._updateChildNodes(this, this._composeNode(this));
+var p$ = this.shadyRoot._insertionPoints;
+for (var i = 0, l = p$.length, p, parent; i < l && (p = p$[i]); i++) {
+parent = p._lightParent || p.parentNode;
+if (!parent._useContent && parent !== this && parent !== this.shadyRoot) {
+this._updateChildNodes(parent, this._composeNode(parent));
+}
+}
+},
+_composeNode: function (node) {
+var children = [];
+var c$ = getLightChildren(node.shadyRoot || node);
+for (var i = 0; i < c$.length; i++) {
+var child = c$[i];
+if (isInsertionPoint(child)) {
+var distributedNodes = child._distributedNodes;
+for (var j = 0; j < distributedNodes.length; j++) {
+var distributedNode = distributedNodes[j];
+if (isFinalDestination(child, distributedNode)) {
+children.push(distributedNode);
+}
+}
+} else {
+children.push(child);
+}
+}
+return children;
+},
+_updateChildNodes: function (container, children) {
+var composed = getComposedChildren(container);
+var splices = Polymer.ArraySplice.calculateSplices(children, composed);
+for (var i = 0, d = 0, s; i < splices.length && (s = splices[i]); i++) {
+for (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) {
+remove(n);
+composed.splice(s.index + d, 1);
+}
+d -= s.addedCount;
+}
+for (var i = 0, s, next; i < splices.length && (s = splices[i]); i++) {
+next = composed[s.index];
+for (var j = s.index, n; j < s.index + s.addedCount; j++) {
+n = children[j];
+insertBefore(container, n, next);
+composed.splice(j, 0, n);
+}
+}
+},
+_matchesContentSelect: function (node, contentElement) {
+var select = contentElement.getAttribute('select');
+if (!select) {
+return true;
+}
+select = select.trim();
+if (!select) {
+return true;
+}
+if (!(node instanceof Element)) {
+return false;
+}
+var validSelectors = /^(:not\()?[*.#[a-zA-Z_|]/;
+if (!validSelectors.test(select)) {
+return false;
+}
+return this.elementMatches(select, node);
+},
+_elementAdd: function () {
+},
+_elementRemove: function () {
+}
+});
+var saveLightChildrenIfNeeded = Polymer.DomApi.saveLightChildrenIfNeeded;
+var getLightChildren = Polymer.DomApi.getLightChildren;
+var matchesSelector = Polymer.DomApi.matchesSelector;
+var hasInsertionPoint = Polymer.DomApi.hasInsertionPoint;
+var getComposedChildren = Polymer.DomApi.getComposedChildren;
+var removeFromComposedParent = Polymer.DomApi.removeFromComposedParent;
+function distributeNodeInto(child, insertionPoint) {
+insertionPoint._distributedNodes.push(child);
+var points = child._destinationInsertionPoints;
+if (!points) {
+child._destinationInsertionPoints = [insertionPoint];
+} else {
+points.push(insertionPoint);
+}
+}
+function clearDistributedDestinationInsertionPoints(content) {
+var e$ = content._distributedNodes;
+if (e$) {
+for (var i = 0; i < e$.length; i++) {
+var d = e$[i]._destinationInsertionPoints;
+if (d) {
+d.splice(d.indexOf(content) + 1, d.length);
+}
+}
+}
+}
+function maybeRedistributeParent(content, host) {
+var parent = content._lightParent;
+if (parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot) && parent.shadyRoot._distributionClean) {
+parent.shadyRoot._distributionClean = false;
+host.shadyRoot._dirtyRoots.push(parent);
+}
+}
+function isFinalDestination(insertionPoint, node) {
+var points = node._destinationInsertionPoints;
+return points && points[points.length - 1] === insertionPoint;
+}
+function isInsertionPoint(node) {
+return node.localName == 'content';
+}
+var nativeInsertBefore = Element.prototype.insertBefore;
+var nativeRemoveChild = Element.prototype.removeChild;
+function insertBefore(parentNode, newChild, refChild) {
+var newChildParent = getComposedParent(newChild);
+if (newChildParent !== parentNode) {
+removeFromComposedParent(newChildParent, newChild);
+}
+remove(newChild);
+saveLightChildrenIfNeeded(parentNode);
+nativeInsertBefore.call(parentNode, newChild, refChild || null);
+newChild._composedParent = parentNode;
+}
+function remove(node) {
+var parentNode = getComposedParent(node);
+if (parentNode) {
+saveLightChildrenIfNeeded(parentNode);
+node._composedParent = null;
+nativeRemoveChild.call(parentNode, node);
+}
+}
+function getComposedParent(node) {
+return node.__patched ? node._composedParent : node.parentNode;
+}
+function getTopDistributingHost(host) {
+while (host && hostNeedsRedistribution(host)) {
+host = host.domHost;
+}
+return host;
+}
+function hostNeedsRedistribution(host) {
+var c$ = Polymer.dom(host).children;
+for (var i = 0, c; i < c$.length; i++) {
+c = c$[i];
+if (c.localName === 'content') {
+return host.domHost;
+}
+}
+}
+var needsUpgrade = window.CustomElements && !CustomElements.useNative;
+function upgradeLightChildren(children) {
+if (needsUpgrade && children) {
+for (var i = 0; i < children.length; i++) {
+CustomElements.upgrade(children[i]);
+}
+}
+}
+}());
+if (Polymer.Settings.useShadow) {
+Polymer.Base._addFeature({
+_poolContent: function () {
+},
+_beginDistribute: function () {
+},
+distributeContent: function () {
+},
+_distributeContent: function () {
+},
+_finishDistribute: function () {
+},
+_createLocalRoot: function () {
+this.createShadowRoot();
+this.shadowRoot.appendChild(this.root);
+this.root = this.shadowRoot;
+}
+});
+}
+Polymer.DomModule = document.createElement('dom-module');
+Polymer.Base._addFeature({
+_registerFeatures: function () {
+this._prepIs();
+this._prepAttributes();
+this._prepBehaviors();
+this._prepExtends();
+this._prepConstructor();
+this._prepTemplate();
+this._prepShady();
+},
+_prepBehavior: function (b) {
+this._addHostAttributes(b.hostAttributes);
+},
+_initFeatures: function () {
+this._poolContent();
+this._pushHost();
+this._stampTemplate();
+this._popHost();
+this._marshalHostAttributes();
+this._setupDebouncers();
+this._marshalBehaviors();
+this._tryReady();
+},
+_marshalBehavior: function (b) {
+}
+});</script>
+
diff --git a/polymer_1.0.4/bower_components/polymer/polymer.html b/polymer_1.0.4/bower_components/polymer/polymer.html
new file mode 100644
index 0000000..9d59e33
--- /dev/null
+++ b/polymer_1.0.4/bower_components/polymer/polymer.html
@@ -0,0 +1,3897 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+--><!--
+@license
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+--><link rel="import" href="polymer-mini.html">
+
+<script>Polymer.nar = [];
+Polymer.Annotations = {
+parseAnnotations: function (template) {
+var list = [];
+var content = template._content || template.content;
+this._parseNodeAnnotations(content, list);
+return list;
+},
+_parseNodeAnnotations: function (node, list) {
+return node.nodeType === Node.TEXT_NODE ? this._parseTextNodeAnnotation(node, list) : this._parseElementAnnotations(node, list);
+},
+_testEscape: function (value) {
+var escape = value.slice(0, 2);
+if (escape === '{{' || escape === '[[') {
+return escape;
+}
+},
+_parseTextNodeAnnotation: function (node, list) {
+var v = node.textContent;
+var escape = this._testEscape(v);
+if (escape) {
+node.textContent = ' ';
+var annote = {
+bindings: [{
+kind: 'text',
+mode: escape[0],
+value: v.slice(2, -2).trim()
+}]
+};
+list.push(annote);
+return annote;
+}
+},
+_parseElementAnnotations: function (element, list) {
+var annote = {
+bindings: [],
+events: []
+};
+this._parseChildNodesAnnotations(element, annote, list);
+if (element.attributes) {
+this._parseNodeAttributeAnnotations(element, annote, list);
+if (this.prepElement) {
+this.prepElement(element);
+}
+}
+if (annote.bindings.length || annote.events.length || annote.id) {
+list.push(annote);
+}
+return annote;
+},
+_parseChildNodesAnnotations: function (root, annote, list, callback) {
+if (root.firstChild) {
+for (var i = 0, node = root.firstChild; node; node = node.nextSibling, i++) {
+if (node.localName === 'template' && !node.hasAttribute('preserve-content')) {
+this._parseTemplate(node, i, list, annote);
+}
+var childAnnotation = this._parseNodeAnnotations(node, list, callback);
+if (childAnnotation) {
+childAnnotation.parent = annote;
+childAnnotation.index = i;
+}
+}
+}
+},
+_parseTemplate: function (node, index, list, parent) {
+var content = document.createDocumentFragment();
+content._notes = this.parseAnnotations(node);
+content.appendChild(node.content);
+list.push({
+bindings: Polymer.nar,
+events: Polymer.nar,
+templateContent: content,
+parent: parent,
+index: index
+});
+},
+_parseNodeAttributeAnnotations: function (node, annotation) {
+for (var i = node.attributes.length - 1, a; a = node.attributes[i]; i--) {
+var n = a.name, v = a.value;
+if (n === 'id' && !this._testEscape(v)) {
+annotation.id = v;
+} else if (n.slice(0, 3) === 'on-') {
+node.removeAttribute(n);
+annotation.events.push({
+name: n.slice(3),
+value: v
+});
+} else {
+var b = this._parseNodeAttributeAnnotation(node, n, v);
+if (b) {
+annotation.bindings.push(b);
+}
+}
+}
+},
+_parseNodeAttributeAnnotation: function (node, n, v) {
+var escape = this._testEscape(v);
+if (escape) {
+var customEvent;
+var name = n;
+var mode = escape[0];
+v = v.slice(2, -2).trim();
+var not = false;
+if (v[0] == '!') {
+v = v.substring(1);
+not = true;
+}
+var kind = 'property';
+if (n[n.length - 1] == '$') {
+name = n.slice(0, -1);
+kind = 'attribute';
+}
+var notifyEvent, colon;
+if (mode == '{' && (colon = v.indexOf('::')) > 0) {
+notifyEvent = v.substring(colon + 2);
+v = v.substring(0, colon);
+customEvent = true;
+}
+if (node.localName == 'input' && n == 'value') {
+node.setAttribute(n, '');
+}
+node.removeAttribute(n);
+if (kind === 'property') {
+name = Polymer.CaseMap.dashToCamelCase(name);
+}
+return {
+kind: kind,
+mode: mode,
+name: name,
+value: v,
+negate: not,
+event: notifyEvent,
+customEvent: customEvent
+};
+}
+},
+_localSubTree: function (node, host) {
+return node === host ? node.childNodes : node._lightChildren || node.childNodes;
+},
+findAnnotatedNode: function (root, annote) {
+var parent = annote.parent && Polymer.Annotations.findAnnotatedNode(root, annote.parent);
+return !parent ? root : Polymer.Annotations._localSubTree(parent, root)[annote.index];
+}
+};
+(function () {
+function resolveCss(cssText, ownerDocument) {
+return cssText.replace(CSS_URL_RX, function (m, pre, url, post) {
+return pre + '\'' + resolve(url.replace(/["']/g, ''), ownerDocument) + '\'' + post;
+});
+}
+function resolveAttrs(element, ownerDocument) {
+for (var name in URL_ATTRS) {
+var a$ = URL_ATTRS[name];
+for (var i = 0, l = a$.length, a, at, v; i < l && (a = a$[i]); i++) {
+if (name === '*' || element.localName === name) {
+at = element.attributes[a];
+v = at && at.value;
+if (v && v.search(BINDING_RX) < 0) {
+at.value = a === 'style' ? resolveCss(v, ownerDocument) : resolve(v, ownerDocument);
+}
+}
+}
+}
+}
+function resolve(url, ownerDocument) {
+if (url && url[0] === '#') {
+return url;
+}
+var resolver = getUrlResolver(ownerDocument);
+resolver.href = url;
+return resolver.href || url;
+}
+var tempDoc;
+var tempDocBase;
+function resolveUrl(url, baseUri) {
+if (!tempDoc) {
+tempDoc = document.implementation.createHTMLDocument('temp');
+tempDocBase = tempDoc.createElement('base');
+tempDoc.head.appendChild(tempDocBase);
+}
+tempDocBase.href = baseUri;
+return resolve(url, tempDoc);
+}
+function getUrlResolver(ownerDocument) {
+return ownerDocument.__urlResolver || (ownerDocument.__urlResolver = ownerDocument.createElement('a'));
+}
+var CSS_URL_RX = /(url\()([^)]*)(\))/g;
+var URL_ATTRS = {
+'*': [
+'href',
+'src',
+'style',
+'url'
+],
+form: ['action']
+};
+var BINDING_RX = /\{\{|\[\[/;
+Polymer.ResolveUrl = {
+resolveCss: resolveCss,
+resolveAttrs: resolveAttrs,
+resolveUrl: resolveUrl
+};
+}());
+Polymer.Base._addFeature({
+_prepAnnotations: function () {
+if (!this._template) {
+this._notes = [];
+} else {
+Polymer.Annotations.prepElement = this._prepElement.bind(this);
+this._notes = Polymer.Annotations.parseAnnotations(this._template);
+this._processAnnotations(this._notes);
+Polymer.Annotations.prepElement = null;
+}
+},
+_processAnnotations: function (notes) {
+for (var i = 0; i < notes.length; i++) {
+var note = notes[i];
+for (var j = 0; j < note.bindings.length; j++) {
+var b = note.bindings[j];
+b.signature = this._parseMethod(b.value);
+if (!b.signature) {
+b.model = this._modelForPath(b.value);
+}
+}
+if (note.templateContent) {
+this._processAnnotations(note.templateContent._notes);
+var pp = note.templateContent._parentProps = this._discoverTemplateParentProps(note.templateContent._notes);
+var bindings = [];
+for (var prop in pp) {
+bindings.push({
+index: note.index,
+kind: 'property',
+mode: '{',
+name: '_parent_' + prop,
+model: prop,
+value: prop
+});
+}
+note.bindings = note.bindings.concat(bindings);
+}
+}
+},
+_discoverTemplateParentProps: function (notes) {
+var pp = {};
+notes.forEach(function (n) {
+n.bindings.forEach(function (b) {
+if (b.signature) {
+var args = b.signature.args;
+for (var k = 0; k < args.length; k++) {
+pp[args[k].model] = true;
+}
+} else {
+pp[b.model] = true;
+}
+});
+if (n.templateContent) {
+var tpp = n.templateContent._parentProps;
+Polymer.Base.mixin(pp, tpp);
+}
+});
+return pp;
+},
+_prepElement: function (element) {
+Polymer.ResolveUrl.resolveAttrs(element, this._template.ownerDocument);
+},
+_findAnnotatedNode: Polymer.Annotations.findAnnotatedNode,
+_marshalAnnotationReferences: function () {
+if (this._template) {
+this._marshalIdNodes();
+this._marshalAnnotatedNodes();
+this._marshalAnnotatedListeners();
+}
+},
+_configureAnnotationReferences: function () {
+this._configureTemplateContent();
+},
+_configureTemplateContent: function () {
+this._notes.forEach(function (note, i) {
+if (note.templateContent) {
+this._nodes[i]._content = note.templateContent;
+}
+}, this);
+},
+_marshalIdNodes: function () {
+this.$ = {};
+this._notes.forEach(function (a) {
+if (a.id) {
+this.$[a.id] = this._findAnnotatedNode(this.root, a);
+}
+}, this);
+},
+_marshalAnnotatedNodes: function () {
+if (this._nodes) {
+this._nodes = this._nodes.map(function (a) {
+return this._findAnnotatedNode(this.root, a);
+}, this);
+}
+},
+_marshalAnnotatedListeners: function () {
+this._notes.forEach(function (a) {
+if (a.events && a.events.length) {
+var node = this._findAnnotatedNode(this.root, a);
+a.events.forEach(function (e) {
+this.listen(node, e.name, e.value);
+}, this);
+}
+}, this);
+}
+});
+Polymer.Base._addFeature({
+listeners: {},
+_listenListeners: function (listeners) {
+var node, name, key;
+for (key in listeners) {
+if (key.indexOf('.') < 0) {
+node = this;
+name = key;
+} else {
+name = key.split('.');
+node = this.$[name[0]];
+name = name[1];
+}
+this.listen(node, name, listeners[key]);
+}
+},
+listen: function (node, eventName, methodName) {
+this._listen(node, eventName, this._createEventHandler(node, eventName, methodName));
+},
+_boundListenerKey: function (eventName, methodName) {
+return eventName + ':' + methodName;
+},
+_recordEventHandler: function (host, eventName, target, methodName, handler) {
+var hbl = host.__boundListeners;
+if (!hbl) {
+hbl = host.__boundListeners = new WeakMap();
+}
+var bl = hbl.get(target);
+if (!bl) {
+bl = {};
+hbl.set(target, bl);
+}
+var key = this._boundListenerKey(eventName, methodName);
+bl[key] = handler;
+},
+_recallEventHandler: function (host, eventName, target, methodName) {
+var hbl = host.__boundListeners;
+if (!hbl) {
+return;
+}
+var bl = hbl.get(target);
+if (!bl) {
+return;
+}
+var key = this._boundListenerKey(eventName, methodName);
+return bl[key];
+},
+_createEventHandler: function (node, eventName, methodName) {
+var host = this;
+var handler = function (e) {
+if (host[methodName]) {
+host[methodName](e, e.detail);
+} else {
+host._warn(host._logf('_createEventHandler', 'listener method `' + methodName + '` not defined'));
+}
+};
+this._recordEventHandler(host, eventName, node, methodName, handler);
+return handler;
+},
+unlisten: function (node, eventName, methodName) {
+var handler = this._recallEventHandler(this, eventName, node, methodName);
+if (handler) {
+this._unlisten(node, eventName, handler);
+}
+},
+_listen: function (node, eventName, handler) {
+node.addEventListener(eventName, handler);
+},
+_unlisten: function (node, eventName, handler) {
+node.removeEventListener(eventName, handler);
+}
+});
+(function () {
+'use strict';
+var HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';
+var GESTURE_KEY = '__polymerGestures';
+var HANDLED_OBJ = '__polymerGesturesHandled';
+var TOUCH_ACTION = '__polymerGesturesTouchAction';
+var TAP_DISTANCE = 25;
+var TRACK_DISTANCE = 5;
+var TRACK_LENGTH = 2;
+var MOUSE_TIMEOUT = 2500;
+var MOUSE_EVENTS = [
+'mousedown',
+'mousemove',
+'mouseup',
+'click'
+];
+var mouseCanceller = function (mouseEvent) {
+mouseEvent[HANDLED_OBJ] = { skip: true };
+if (mouseEvent.type === 'click') {
+var path = Polymer.dom(mouseEvent).path;
+for (var i = 0; i < path.length; i++) {
+if (path[i] === POINTERSTATE.mouse.target) {
+return;
+}
+}
+mouseEvent.preventDefault();
+mouseEvent.stopPropagation();
+}
+};
+function setupTeardownMouseCanceller(setup) {
+for (var i = 0, en; i < MOUSE_EVENTS.length; i++) {
+en = MOUSE_EVENTS[i];
+if (setup) {
+document.addEventListener(en, mouseCanceller, true);
+} else {
+document.removeEventListener(en, mouseCanceller, true);
+}
+}
+}
+function ignoreMouse() {
+if (!POINTERSTATE.mouse.mouseIgnoreJob) {
+setupTeardownMouseCanceller(true);
+}
+var unset = function () {
+setupTeardownMouseCanceller();
+POINTERSTATE.mouse.target = null;
+POINTERSTATE.mouse.mouseIgnoreJob = null;
+};
+POINTERSTATE.mouse.mouseIgnoreJob = Polymer.Debounce(POINTERSTATE.mouse.mouseIgnoreJob, unset, MOUSE_TIMEOUT);
+}
+var POINTERSTATE = {
+mouse: {
+target: null,
+mouseIgnoreJob: null
+},
+touch: {
+x: 0,
+y: 0,
+id: -1,
+scrollDecided: false
+}
+};
+function firstTouchAction(ev) {
+var path = Polymer.dom(ev).path;
+var ta = 'auto';
+for (var i = 0, n; i < path.length; i++) {
+n = path[i];
+if (n[TOUCH_ACTION]) {
+ta = n[TOUCH_ACTION];
+break;
+}
+}
+return ta;
+}
+var Gestures = {
+gestures: {},
+recognizers: [],
+deepTargetFind: function (x, y) {
+var node = document.elementFromPoint(x, y);
+var next = node;
+while (next && next.shadowRoot) {
+next = next.shadowRoot.elementFromPoint(x, y);
+if (next) {
+node = next;
+}
+}
+return node;
+},
+handleNative: function (ev) {
+var handled;
+var type = ev.type;
+var node = ev.currentTarget;
+var gobj = node[GESTURE_KEY];
+var gs = gobj[type];
+if (!gs) {
+return;
+}
+if (!ev[HANDLED_OBJ]) {
+ev[HANDLED_OBJ] = {};
+if (type.slice(0, 5) === 'touch') {
+var t = ev.changedTouches[0];
+if (type === 'touchstart') {
+if (ev.touches.length === 1) {
+POINTERSTATE.touch.id = t.identifier;
+}
+}
+if (POINTERSTATE.touch.id !== t.identifier) {
+return;
+}
+if (!HAS_NATIVE_TA) {
+if (type === 'touchstart' || type === 'touchmove') {
+Gestures.handleTouchAction(ev);
+}
+}
+if (type === 'touchend') {
+POINTERSTATE.mouse.target = Polymer.dom(ev).rootTarget;
+ignoreMouse(true);
+}
+}
+}
+handled = ev[HANDLED_OBJ];
+if (handled.skip) {
+return;
+}
+var recognizers = Gestures.recognizers;
+for (var i = 0, r; i < recognizers.length; i++) {
+r = recognizers[i];
+if (gs[r.name] && !handled[r.name]) {
+handled[r.name] = true;
+r[type](ev);
+}
+}
+},
+handleTouchAction: function (ev) {
+var t = ev.changedTouches[0];
+var type = ev.type;
+if (type === 'touchstart') {
+POINTERSTATE.touch.x = t.clientX;
+POINTERSTATE.touch.y = t.clientY;
+POINTERSTATE.touch.scrollDecided = false;
+} else if (type === 'touchmove') {
+if (POINTERSTATE.touch.scrollDecided) {
+return;
+}
+POINTERSTATE.touch.scrollDecided = true;
+var ta = firstTouchAction(ev);
+var prevent = false;
+var dx = Math.abs(POINTERSTATE.touch.x - t.clientX);
+var dy = Math.abs(POINTERSTATE.touch.y - t.clientY);
+if (!ev.cancelable) {
+} else if (ta === 'none') {
+prevent = true;
+} else if (ta === 'pan-x') {
+prevent = dy > dx;
+} else if (ta === 'pan-y') {
+prevent = dx > dy;
+}
+if (prevent) {
+ev.preventDefault();
+}
+}
+},
+add: function (node, evType, handler) {
+var recognizer = this.gestures[evType];
+var deps = recognizer.deps;
+var name = recognizer.name;
+var gobj = node[GESTURE_KEY];
+if (!gobj) {
+node[GESTURE_KEY] = gobj = {};
+}
+for (var i = 0, dep, gd; i < deps.length; i++) {
+dep = deps[i];
+gd = gobj[dep];
+if (!gd) {
+gobj[dep] = gd = {};
+node.addEventListener(dep, this.handleNative);
+}
+gd[name] = (gd[name] || 0) + 1;
+}
+node.addEventListener(evType, handler);
+if (recognizer.touchAction) {
+this.setTouchAction(node, recognizer.touchAction);
+}
+},
+remove: function (node, evType, handler) {
+var recognizer = this.gestures[evType];
+var deps = recognizer.deps;
+var name = recognizer.name;
+var gobj = node[GESTURE_KEY];
+if (gobj) {
+for (var i = 0, dep, gd; i < deps.length; i++) {
+dep = deps[i];
+gd = gobj[dep];
+if (gd && gd[name]) {
+gd[name] = (gd[name] || 1) - 1;
+if (gd[name] === 0) {
+node.removeEventListener(dep, this.handleNative);
+}
+}
+}
+}
+node.removeEventListener(evType, handler);
+},
+register: function (recog) {
+this.recognizers.push(recog);
+for (var i = 0; i < recog.emits.length; i++) {
+this.gestures[recog.emits[i]] = recog;
+}
+},
+findRecognizerByEvent: function (evName) {
+for (var i = 0, r; i < this.recognizers.length; i++) {
+r = this.recognizers[i];
+for (var j = 0, n; j < r.emits.length; j++) {
+n = r.emits[j];
+if (n === evName) {
+return r;
+}
+}
+}
+return null;
+},
+setTouchAction: function (node, value) {
+if (HAS_NATIVE_TA) {
+node.style.touchAction = value;
+}
+node[TOUCH_ACTION] = value;
+},
+fire: function (target, type, detail) {
+var ev = Polymer.Base.fire(type, detail, {
+node: target,
+bubbles: true,
+cancelable: true
+});
+if (ev.defaultPrevented) {
+var se = detail.sourceEvent;
+if (se && se.preventDefault) {
+se.preventDefault();
+}
+}
+},
+prevent: function (evName) {
+var recognizer = this.findRecognizerByEvent(evName);
+if (recognizer.info) {
+recognizer.info.prevent = true;
+}
+}
+};
+Gestures.register({
+name: 'downup',
+deps: [
+'mousedown',
+'touchstart',
+'touchend'
+],
+emits: [
+'down',
+'up'
+],
+mousedown: function (e) {
+var t = e.currentTarget;
+var self = this;
+var upfn = function upfn(e) {
+self.fire('up', t, e);
+document.removeEventListener('mouseup', upfn);
+};
+document.addEventListener('mouseup', upfn);
+this.fire('down', t, e);
+},
+touchstart: function (e) {
+this.fire('down', e.currentTarget, e.changedTouches[0]);
+},
+touchend: function (e) {
+this.fire('up', e.currentTarget, e.changedTouches[0]);
+},
+fire: function (type, target, event) {
+var self = this;
+Gestures.fire(target, type, {
+x: event.clientX,
+y: event.clientY,
+sourceEvent: event,
+prevent: Gestures.prevent.bind(Gestures)
+});
+}
+});
+Gestures.register({
+name: 'track',
+touchAction: 'none',
+deps: [
+'mousedown',
+'touchstart',
+'touchmove',
+'touchend'
+],
+emits: ['track'],
+info: {
+x: 0,
+y: 0,
+state: 'start',
+started: false,
+moves: [],
+addMove: function (move) {
+if (this.moves.length > TRACK_LENGTH) {
+this.moves.shift();
+}
+this.moves.push(move);
+},
+prevent: false
+},
+clearInfo: function () {
+this.info.state = 'start';
+this.info.started = false;
+this.info.moves = [];
+this.info.x = 0;
+this.info.y = 0;
+this.info.prevent = false;
+},
+hasMovedEnough: function (x, y) {
+if (this.info.prevent) {
+return false;
+}
+if (this.info.started) {
+return true;
+}
+var dx = Math.abs(this.info.x - x);
+var dy = Math.abs(this.info.y - y);
+return dx >= TRACK_DISTANCE || dy >= TRACK_DISTANCE;
+},
+mousedown: function (e) {
+var t = e.currentTarget;
+var self = this;
+var movefn = function movefn(e) {
+var x = e.clientX, y = e.clientY;
+if (self.hasMovedEnough(x, y)) {
+self.info.state = self.info.started ? e.type === 'mouseup' ? 'end' : 'track' : 'start';
+self.info.addMove({
+x: x,
+y: y
+});
+self.fire(t, e);
+self.info.started = true;
+}
+};
+var upfn = function upfn(e) {
+if (self.info.started) {
+Gestures.prevent('tap');
+movefn(e);
+}
+self.clearInfo();
+document.removeEventListener('mousemove', movefn);
+document.removeEventListener('mouseup', upfn);
+};
+document.addEventListener('mousemove', movefn);
+document.addEventListener('mouseup', upfn);
+this.info.x = e.clientX;
+this.info.y = e.clientY;
+},
+touchstart: function (e) {
+var ct = e.changedTouches[0];
+this.info.x = ct.clientX;
+this.info.y = ct.clientY;
+},
+touchmove: function (e) {
+var t = e.currentTarget;
+var ct = e.changedTouches[0];
+var x = ct.clientX, y = ct.clientY;
+if (this.hasMovedEnough(x, y)) {
+this.info.addMove({
+x: x,
+y: y
+});
+this.fire(t, ct);
+this.info.state = 'track';
+this.info.started = true;
+}
+},
+touchend: function (e) {
+var t = e.currentTarget;
+var ct = e.changedTouches[0];
+if (this.info.started) {
+Gestures.prevent('tap');
+this.info.state = 'end';
+this.info.addMove({
+x: ct.clientX,
+y: ct.clientY
+});
+this.fire(t, ct);
+}
+this.clearInfo();
+},
+fire: function (target, touch) {
+var secondlast = this.info.moves[this.info.moves.length - 2];
+var lastmove = this.info.moves[this.info.moves.length - 1];
+var dx = lastmove.x - this.info.x;
+var dy = lastmove.y - this.info.y;
+var ddx, ddy = 0;
+if (secondlast) {
+ddx = lastmove.x - secondlast.x;
+ddy = lastmove.y - secondlast.y;
+}
+return Gestures.fire(target, 'track', {
+state: this.info.state,
+x: touch.clientX,
+y: touch.clientY,
+dx: dx,
+dy: dy,
+ddx: ddx,
+ddy: ddy,
+sourceEvent: touch,
+hover: function () {
+return Gestures.deepTargetFind(touch.clientX, touch.clientY);
+}
+});
+}
+});
+Gestures.register({
+name: 'tap',
+deps: [
+'mousedown',
+'click',
+'touchstart',
+'touchend'
+],
+emits: ['tap'],
+info: {
+x: NaN,
+y: NaN,
+prevent: false
+},
+reset: function () {
+this.info.x = NaN;
+this.info.y = NaN;
+this.info.prevent = false;
+},
+save: function (e) {
+this.info.x = e.clientX;
+this.info.y = e.clientY;
+},
+mousedown: function (e) {
+this.save(e);
+},
+click: function (e) {
+this.forward(e);
+},
+touchstart: function (e) {
+this.save(e.changedTouches[0]);
+},
+touchend: function (e) {
+this.forward(e.changedTouches[0]);
+},
+forward: function (e) {
+var dx = Math.abs(e.clientX - this.info.x);
+var dy = Math.abs(e.clientY - this.info.y);
+if (isNaN(dx) || isNaN(dy) || dx <= TAP_DISTANCE && dy <= TAP_DISTANCE) {
+if (!this.info.prevent) {
+Gestures.fire(e.target, 'tap', {
+x: e.clientX,
+y: e.clientY,
+sourceEvent: e
+});
+}
+}
+this.reset();
+}
+});
+var DIRECTION_MAP = {
+x: 'pan-x',
+y: 'pan-y',
+none: 'none',
+all: 'auto'
+};
+Polymer.Base._addFeature({
+_listen: function (node, eventName, handler) {
+if (Gestures.gestures[eventName]) {
+Gestures.add(node, eventName, handler);
+} else {
+node.addEventListener(eventName, handler);
+}
+},
+_unlisten: function (node, eventName, handler) {
+if (Gestures.gestures[eventName]) {
+Gestures.remove(node, eventName, handler);
+} else {
+node.removeEventListener(eventName, handler);
+}
+},
+setScrollDirection: function (direction, node) {
+node = node || this;
+Gestures.setTouchAction(node, DIRECTION_MAP[direction] || 'auto');
+}
+});
+Polymer.Gestures = Gestures;
+}());
+Polymer.Async = function () {
+var currVal = 0;
+var lastVal = 0;
+var callbacks = [];
+var twiddle = document.createTextNode('');
+function runAsync(callback, waitTime) {
+if (waitTime > 0) {
+return ~setTimeout(callback, waitTime);
+} else {
+twiddle.textContent = currVal++;
+callbacks.push(callback);
+return currVal - 1;
+}
+}
+function cancelAsync(handle) {
+if (handle < 0) {
+clearTimeout(~handle);
+} else {
+var idx = handle - lastVal;
+if (idx >= 0) {
+if (!callbacks[idx]) {
+throw 'invalid async handle: ' + handle;
+}
+callbacks[idx] = null;
+}
+}
+}
+function atEndOfMicrotask() {
+var len = callbacks.length;
+for (var i = 0; i < len; i++) {
+var cb = callbacks[i];
+if (cb) {
+cb();
+}
+}
+callbacks.splice(0, len);
+lastVal += len;
+}
+new (window.MutationObserver || JsMutationObserver)(atEndOfMicrotask).observe(twiddle, { characterData: true });
+return {
+run: runAsync,
+cancel: cancelAsync
+};
+}();
+Polymer.Debounce = function () {
+var Async = Polymer.Async;
+var Debouncer = function (context) {
+this.context = context;
+this.boundComplete = this.complete.bind(this);
+};
+Debouncer.prototype = {
+go: function (callback, wait) {
+var h;
+this.finish = function () {
+Async.cancel(h);
+};
+h = Async.run(this.boundComplete, wait);
+this.callback = callback;
+},
+stop: function () {
+if (this.finish) {
+this.finish();
+this.finish = null;
+}
+},
+complete: function () {
+if (this.finish) {
+this.stop();
+this.callback.call(this.context);
+}
+}
+};
+function debounce(debouncer, callback, wait) {
+if (debouncer) {
+debouncer.stop();
+} else {
+debouncer = new Debouncer(this);
+}
+debouncer.go(callback, wait);
+return debouncer;
+}
+return debounce;
+}();
+Polymer.Base._addFeature({
+$$: function (slctr) {
+return Polymer.dom(this.root).querySelector(slctr);
+},
+toggleClass: function (name, bool, node) {
+node = node || this;
+if (arguments.length == 1) {
+bool = !node.classList.contains(name);
+}
+if (bool) {
+Polymer.dom(node).classList.add(name);
+} else {
+Polymer.dom(node).classList.remove(name);
+}
+},
+toggleAttribute: function (name, bool, node) {
+node = node || this;
+if (arguments.length == 1) {
+bool = !node.hasAttribute(name);
+}
+if (bool) {
+Polymer.dom(node).setAttribute(name, '');
+} else {
+Polymer.dom(node).removeAttribute(name);
+}
+},
+classFollows: function (name, toElement, fromElement) {
+if (fromElement) {
+Polymer.dom(fromElement).classList.remove(name);
+}
+if (toElement) {
+Polymer.dom(toElement).classList.add(name);
+}
+},
+attributeFollows: function (name, toElement, fromElement) {
+if (fromElement) {
+Polymer.dom(fromElement).removeAttribute(name);
+}
+if (toElement) {
+Polymer.dom(toElement).setAttribute(name, '');
+}
+},
+getContentChildNodes: function (slctr) {
+return Polymer.dom(Polymer.dom(this.root).querySelector(slctr || 'content')).getDistributedNodes();
+},
+getContentChildren: function (slctr) {
+return this.getContentChildNodes(slctr).filter(function (n) {
+return n.nodeType === Node.ELEMENT_NODE;
+});
+},
+fire: function (type, detail, options) {
+options = options || Polymer.nob;
+var node = options.node || this;
+var detail = detail === null || detail === undefined ? Polymer.nob : detail;
+var bubbles = options.bubbles === undefined ? true : options.bubbles;
+var cancelable = Boolean(options.cancelable);
+var event = new CustomEvent(type, {
+bubbles: Boolean(bubbles),
+cancelable: cancelable,
+detail: detail
+});
+node.dispatchEvent(event);
+return event;
+},
+async: function (callback, waitTime) {
+return Polymer.Async.run(callback.bind(this), waitTime);
+},
+cancelAsync: function (handle) {
+Polymer.Async.cancel(handle);
+},
+arrayDelete: function (path, item) {
+var index;
+if (Array.isArray(path)) {
+index = path.indexOf(item);
+if (index >= 0) {
+return path.splice(index, 1);
+}
+} else {
+var arr = this.get(path);
+index = arr.indexOf(item);
+if (index >= 0) {
+return this.splice(path, index, 1);
+}
+}
+},
+transform: function (transform, node) {
+node = node || this;
+node.style.webkitTransform = transform;
+node.style.transform = transform;
+},
+translate3d: function (x, y, z, node) {
+node = node || this;
+this.transform('translate3d(' + x + ',' + y + ',' + z + ')', node);
+},
+importHref: function (href, onload, onerror) {
+var l = document.createElement('link');
+l.rel = 'import';
+l.href = href;
+if (onload) {
+l.onload = onload.bind(this);
+}
+if (onerror) {
+l.onerror = onerror.bind(this);
+}
+document.head.appendChild(l);
+return l;
+},
+create: function (tag, props) {
+var elt = document.createElement(tag);
+if (props) {
+for (var n in props) {
+elt[n] = props[n];
+}
+}
+return elt;
+},
+mixin: function (target, source) {
+for (var i in source) {
+target[i] = source[i];
+}
+}
+});
+Polymer.Bind = {
+prepareModel: function (model) {
+model._propertyEffects = {};
+model._bindListeners = [];
+var api = this._modelApi;
+for (var n in api) {
+model[n] = api[n];
+}
+},
+_modelApi: {
+_notifyChange: function (property) {
+var eventName = Polymer.CaseMap.camelToDashCase(property) + '-changed';
+this.fire(eventName, { value: this[property] }, { bubbles: false });
+},
+_propertySet: function (property, value, effects) {
+var old = this.__data__[property];
+if (old !== value && (old === old || value === value)) {
+this.__data__[property] = value;
+if (typeof value == 'object') {
+this._clearPath(property);
+}
+if (this._propertyChanged) {
+this._propertyChanged(property, value, old);
+}
+if (effects) {
+this._effectEffects(property, value, effects, old);
+}
+}
+return old;
+},
+_effectEffects: function (property, value, effects, old) {
+effects.forEach(function (fx) {
+var fn = Polymer.Bind['_' + fx.kind + 'Effect'];
+if (fn) {
+fn.call(this, property, value, fx.effect, old);
+}
+}, this);
+},
+_clearPath: function (path) {
+for (var prop in this.__data__) {
+if (prop.indexOf(path + '.') === 0) {
+this.__data__[prop] = undefined;
+}
+}
+}
+},
+ensurePropertyEffects: function (model, property) {
+var fx = model._propertyEffects[property];
+if (!fx) {
+fx = model._propertyEffects[property] = [];
+}
+return fx;
+},
+addPropertyEffect: function (model, property, kind, effect) {
+var fx = this.ensurePropertyEffects(model, property);
+fx.push({
+kind: kind,
+effect: effect
+});
+},
+createBindings: function (model) {
+var fx$ = model._propertyEffects;
+if (fx$) {
+for (var n in fx$) {
+var fx = fx$[n];
+fx.sort(this._sortPropertyEffects);
+this._createAccessors(model, n, fx);
+}
+}
+},
+_sortPropertyEffects: function () {
+var EFFECT_ORDER = {
+'compute': 0,
+'annotation': 1,
+'computedAnnotation': 2,
+'reflect': 3,
+'notify': 4,
+'observer': 5,
+'complexObserver': 6,
+'function': 7
+};
+return function (a, b) {
+return EFFECT_ORDER[a.kind] - EFFECT_ORDER[b.kind];
+};
+}(),
+_createAccessors: function (model, property, effects) {
+var defun = {
+get: function () {
+return this.__data__[property];
+}
+};
+var setter = function (value) {
+this._propertySet(property, value, effects);
+};
+if (model.getPropertyInfo && model.getPropertyInfo(property).readOnly) {
+model['_set' + this.upper(property)] = setter;
+} else {
+defun.set = setter;
+}
+Object.defineProperty(model, property, defun);
+},
+upper: function (name) {
+return name[0].toUpperCase() + name.substring(1);
+},
+_addAnnotatedListener: function (model, index, property, path, event) {
+var fn = this._notedListenerFactory(property, path, this._isStructured(path), this._isEventBogus);
+var eventName = event || Polymer.CaseMap.camelToDashCase(property) + '-changed';
+model._bindListeners.push({
+index: index,
+property: property,
+path: path,
+changedFn: fn,
+event: eventName
+});
+},
+_isStructured: function (path) {
+return path.indexOf('.') > 0;
+},
+_isEventBogus: function (e, target) {
+return e.path && e.path[0] !== target;
+},
+_notedListenerFactory: function (property, path, isStructured, bogusTest) {
+return function (e, target) {
+if (!bogusTest(e, target)) {
+if (e.detail && e.detail.path) {
+this.notifyPath(this._fixPath(path, property, e.detail.path), e.detail.value);
+} else {
+var value = target[property];
+if (!isStructured) {
+this[path] = target[property];
+} else {
+if (this.__data__[path] != value) {
+this.set(path, value);
+}
+}
+}
+}
+};
+},
+prepareInstance: function (inst) {
+inst.__data__ = Object.create(null);
+},
+setupBindListeners: function (inst) {
+inst._bindListeners.forEach(function (info) {
+var node = inst._nodes[info.index];
+node.addEventListener(info.event, inst._notifyListener.bind(inst, info.changedFn));
+});
+}
+};
+Polymer.Base.extend(Polymer.Bind, {
+_shouldAddListener: function (effect) {
+return effect.name && effect.mode === '{' && !effect.negate && effect.kind != 'attribute';
+},
+_annotationEffect: function (source, value, effect) {
+if (source != effect.value) {
+value = this.get(effect.value);
+this.__data__[effect.value] = value;
+}
+var calc = effect.negate ? !value : value;
+if (!effect.customEvent || this._nodes[effect.index][effect.name] !== calc) {
+return this._applyEffectValue(calc, effect);
+}
+},
+_reflectEffect: function (source) {
+this.reflectPropertyToAttribute(source);
+},
+_notifyEffect: function (source) {
+this._notifyChange(source);
+},
+_functionEffect: function (source, value, fn, old) {
+fn.call(this, source, value, old);
+},
+_observerEffect: function (source, value, effect, old) {
+var fn = this[effect.method];
+if (fn) {
+fn.call(this, value, old);
+} else {
+this._warn(this._logf('_observerEffect', 'observer method `' + effect.method + '` not defined'));
+}
+},
+_complexObserverEffect: function (source, value, effect) {
+var fn = this[effect.method];
+if (fn) {
+var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
+if (args) {
+fn.apply(this, args);
+}
+} else {
+this._warn(this._logf('_complexObserverEffect', 'observer method `' + effect.method + '` not defined'));
+}
+},
+_computeEffect: function (source, value, effect) {
+var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
+if (args) {
+var fn = this[effect.method];
+if (fn) {
+this[effect.property] = fn.apply(this, args);
+} else {
+this._warn(this._logf('_computeEffect', 'compute method `' + effect.method + '` not defined'));
+}
+}
+},
+_annotatedComputationEffect: function (source, value, effect) {
+var computedHost = this._rootDataHost || this;
+var fn = computedHost[effect.method];
+if (fn) {
+var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
+if (args) {
+var computedvalue = fn.apply(computedHost, args);
+if (effect.negate) {
+computedvalue = !computedvalue;
+}
+this._applyEffectValue(computedvalue, effect);
+}
+} else {
+computedHost._warn(computedHost._logf('_annotatedComputationEffect', 'compute method `' + effect.method + '` not defined'));
+}
+},
+_marshalArgs: function (model, effect, path, value) {
+var values = [];
+var args = effect.args;
+for (var i = 0, l = args.length; i < l; i++) {
+var arg = args[i];
+var name = arg.name;
+var v;
+if (arg.literal) {
+v = arg.value;
+} else if (arg.structured) {
+v = Polymer.Base.get(name, model);
+} else {
+v = model[name];
+}
+if (args.length > 1 && v === undefined) {
+return;
+}
+if (arg.wildcard) {
+var baseChanged = name.indexOf(path + '.') === 0;
+var matches = effect.trigger.name.indexOf(name) === 0 && !baseChanged;
+values[i] = {
+path: matches ? path : name,
+value: matches ? value : v,
+base: v
+};
+} else {
+values[i] = v;
+}
+}
+return values;
+}
+});
+Polymer.Base._addFeature({
+_addPropertyEffect: function (property, kind, effect) {
+Polymer.Bind.addPropertyEffect(this, property, kind, effect);
+},
+_prepEffects: function () {
+Polymer.Bind.prepareModel(this);
+this._addAnnotationEffects(this._notes);
+},
+_prepBindings: function () {
+Polymer.Bind.createBindings(this);
+},
+_addPropertyEffects: function (properties) {
+if (properties) {
+for (var p in properties) {
+var prop = properties[p];
+if (prop.observer) {
+this._addObserverEffect(p, prop.observer);
+}
+if (prop.computed) {
+this._addComputedEffect(p, prop.computed);
+}
+if (prop.notify) {
+this._addPropertyEffect(p, 'notify');
+}
+if (prop.reflectToAttribute) {
+this._addPropertyEffect(p, 'reflect');
+}
+if (prop.readOnly) {
+Polymer.Bind.ensurePropertyEffects(this, p);
+}
+}
+}
+},
+_addComputedEffect: function (name, expression) {
+var sig = this._parseMethod(expression);
+sig.args.forEach(function (arg) {
+this._addPropertyEffect(arg.model, 'compute', {
+method: sig.method,
+args: sig.args,
+trigger: arg,
+property: name
+});
+}, this);
+},
+_addObserverEffect: function (property, observer) {
+this._addPropertyEffect(property, 'observer', {
+method: observer,
+property: property
+});
+},
+_addComplexObserverEffects: function (observers) {
+if (observers) {
+observers.forEach(function (observer) {
+this._addComplexObserverEffect(observer);
+}, this);
+}
+},
+_addComplexObserverEffect: function (observer) {
+var sig = this._parseMethod(observer);
+sig.args.forEach(function (arg) {
+this._addPropertyEffect(arg.model, 'complexObserver', {
+method: sig.method,
+args: sig.args,
+trigger: arg
+});
+}, this);
+},
+_addAnnotationEffects: function (notes) {
+this._nodes = [];
+notes.forEach(function (note) {
+var index = this._nodes.push(note) - 1;
+note.bindings.forEach(function (binding) {
+this._addAnnotationEffect(binding, index);
+}, this);
+}, this);
+},
+_addAnnotationEffect: function (note, index) {
+if (Polymer.Bind._shouldAddListener(note)) {
+Polymer.Bind._addAnnotatedListener(this, index, note.name, note.value, note.event);
+}
+if (note.signature) {
+this._addAnnotatedComputationEffect(note, index);
+} else {
+note.index = index;
+this._addPropertyEffect(note.model, 'annotation', note);
+}
+},
+_addAnnotatedComputationEffect: function (note, index) {
+var sig = note.signature;
+if (sig.static) {
+this.__addAnnotatedComputationEffect('__static__', index, note, sig, null);
+} else {
+sig.args.forEach(function (arg) {
+if (!arg.literal) {
+this.__addAnnotatedComputationEffect(arg.model, index, note, sig, arg);
+}
+}, this);
+}
+},
+__addAnnotatedComputationEffect: function (property, index, note, sig, trigger) {
+this._addPropertyEffect(property, 'annotatedComputation', {
+index: index,
+kind: note.kind,
+property: note.name,
+negate: note.negate,
+method: sig.method,
+args: sig.args,
+trigger: trigger
+});
+},
+_parseMethod: function (expression) {
+var m = expression.match(/(\w*)\((.*)\)/);
+if (m) {
+var sig = {
+method: m[1],
+static: true
+};
+if (m[2].trim()) {
+var args = m[2].replace(/\\,/g, ',').split(',');
+return this._parseArgs(args, sig);
+} else {
+sig.args = Polymer.nar;
+return sig;
+}
+}
+},
+_parseArgs: function (argList, sig) {
+sig.args = argList.map(function (rawArg) {
+var arg = this._parseArg(rawArg);
+if (!arg.literal) {
+sig.static = false;
+}
+return arg;
+}, this);
+return sig;
+},
+_parseArg: function (rawArg) {
+var arg = rawArg.trim().replace(/,/g, ',').replace(/\\(.)/g, '$1');
+var a = {
+name: arg,
+model: this._modelForPath(arg)
+};
+var fc = arg[0];
+if (fc >= '0' && fc <= '9') {
+fc = '#';
+}
+switch (fc) {
+case '\'':
+case '"':
+a.value = arg.slice(1, -1);
+a.literal = true;
+break;
+case '#':
+a.value = Number(arg);
+a.literal = true;
+break;
+}
+if (!a.literal) {
+a.structured = arg.indexOf('.') > 0;
+if (a.structured) {
+a.wildcard = arg.slice(-2) == '.*';
+if (a.wildcard) {
+a.name = arg.slice(0, -2);
+}
+}
+}
+return a;
+},
+_marshalInstanceEffects: function () {
+Polymer.Bind.prepareInstance(this);
+Polymer.Bind.setupBindListeners(this);
+},
+_applyEffectValue: function (value, info) {
+var node = this._nodes[info.index];
+var property = info.property || info.name || 'textContent';
+if (info.kind == 'attribute') {
+this.serializeValueToAttribute(value, property, node);
+} else {
+if (property === 'className') {
+value = this._scopeElementClass(node, value);
+}
+if (property === 'textContent' || node.localName == 'input' && property == 'value') {
+value = value == undefined ? '' : value;
+}
+return node[property] = value;
+}
+},
+_executeStaticEffects: function () {
+if (this._propertyEffects.__static__) {
+this._effectEffects('__static__', null, this._propertyEffects.__static__);
+}
+}
+});
+Polymer.Base._addFeature({
+_setupConfigure: function (initialConfig) {
+this._config = initialConfig || {};
+this._handlers = [];
+},
+_marshalAttributes: function () {
+this._takeAttributesToModel(this._config);
+},
+_configValue: function (name, value) {
+this._config[name] = value;
+},
+_beforeClientsReady: function () {
+this._configure();
+},
+_configure: function () {
+this._configureAnnotationReferences();
+var config = {};
+this.behaviors.forEach(function (b) {
+this._configureProperties(b.properties, config);
+}, this);
+this._configureProperties(this.properties, config);
+this._mixinConfigure(config, this._config);
+this._config = config;
+this._distributeConfig(this._config);
+},
+_configureProperties: function (properties, config) {
+for (var i in properties) {
+var c = properties[i];
+if (c.value !== undefined) {
+var value = c.value;
+if (typeof value == 'function') {
+value = value.call(this, this._config);
+}
+config[i] = value;
+}
+}
+},
+_mixinConfigure: function (a, b) {
+for (var prop in b) {
+if (!this.getPropertyInfo(prop).readOnly) {
+a[prop] = b[prop];
+}
+}
+},
+_distributeConfig: function (config) {
+var fx$ = this._propertyEffects;
+if (fx$) {
+for (var p in config) {
+var fx = fx$[p];
+if (fx) {
+for (var i = 0, l = fx.length, x; i < l && (x = fx[i]); i++) {
+if (x.kind === 'annotation') {
+var node = this._nodes[x.effect.index];
+if (node._configValue) {
+var value = p === x.effect.value ? config[p] : this.get(x.effect.value, config);
+node._configValue(x.effect.name, value);
+}
+}
+}
+}
+}
+}
+},
+_afterClientsReady: function () {
+this._executeStaticEffects();
+this._applyConfig(this._config);
+this._flushHandlers();
+},
+_applyConfig: function (config) {
+for (var n in config) {
+if (this[n] === undefined) {
+var effects = this._propertyEffects[n];
+if (effects) {
+this._propertySet(n, config[n], effects);
+} else {
+this[n] = config[n];
+}
+}
+}
+},
+_notifyListener: function (fn, e) {
+if (!this._clientsReadied) {
+this._queueHandler([
+fn,
+e,
+e.target
+]);
+} else {
+return fn.call(this, e, e.target);
+}
+},
+_queueHandler: function (args) {
+this._handlers.push(args);
+},
+_flushHandlers: function () {
+var h$ = this._handlers;
+for (var i = 0, l = h$.length, h; i < l && (h = h$[i]); i++) {
+h[0].call(this, h[1], h[2]);
+}
+}
+});
+(function () {
+'use strict';
+Polymer.Base._addFeature({
+notifyPath: function (path, value, fromAbove) {
+var old = this._propertySet(path, value);
+if (old !== value && (old === old || value === value)) {
+this._pathEffector(path, value);
+if (!fromAbove) {
+this._notifyPath(path, value);
+}
+}
+},
+_getPathParts: function (path) {
+if (Array.isArray(path)) {
+var parts = [];
+for (var i = 0; i < path.length; i++) {
+var args = path[i].toString().split('.');
+for (var j = 0; j < args.length; j++) {
+parts.push(args[j]);
+}
+}
+return parts;
+} else {
+return path.toString().split('.');
+}
+},
+set: function (path, value, root) {
+var prop = root || this;
+var parts = this._getPathParts(path);
+var array;
+var last = parts[parts.length - 1];
+if (parts.length > 1) {
+for (var i = 0; i < parts.length - 1; i++) {
+prop = prop[parts[i]];
+if (array) {
+parts[i] = Polymer.Collection.get(array).getKey(prop);
+}
+if (!prop) {
+return;
+}
+array = Array.isArray(prop) ? prop : null;
+}
+prop[last] = value;
+if (!root) {
+this.notifyPath(parts.join('.'), value);
+}
+} else {
+prop[path] = value;
+}
+},
+get: function (path, root) {
+var prop = root || this;
+var parts = this._getPathParts(path);
+var last = parts.pop();
+while (parts.length) {
+prop = prop[parts.shift()];
+if (!prop) {
+return;
+}
+}
+return prop[last];
+},
+_pathEffector: function (path, value) {
+var model = this._modelForPath(path);
+var fx$ = this._propertyEffects[model];
+if (fx$) {
+fx$.forEach(function (fx) {
+var fxFn = this['_' + fx.kind + 'PathEffect'];
+if (fxFn) {
+fxFn.call(this, path, value, fx.effect);
+}
+}, this);
+}
+if (this._boundPaths) {
+this._notifyBoundPaths(path, value);
+}
+},
+_annotationPathEffect: function (path, value, effect) {
+if (effect.value === path || effect.value.indexOf(path + '.') === 0) {
+Polymer.Bind._annotationEffect.call(this, path, value, effect);
+} else if (path.indexOf(effect.value + '.') === 0 && !effect.negate) {
+var node = this._nodes[effect.index];
+if (node && node.notifyPath) {
+var p = this._fixPath(effect.name, effect.value, path);
+node.notifyPath(p, value, true);
+}
+}
+},
+_complexObserverPathEffect: function (path, value, effect) {
+if (this._pathMatchesEffect(path, effect)) {
+Polymer.Bind._complexObserverEffect.call(this, path, value, effect);
+}
+},
+_computePathEffect: function (path, value, effect) {
+if (this._pathMatchesEffect(path, effect)) {
+Polymer.Bind._computeEffect.call(this, path, value, effect);
+}
+},
+_annotatedComputationPathEffect: function (path, value, effect) {
+if (this._pathMatchesEffect(path, effect)) {
+Polymer.Bind._annotatedComputationEffect.call(this, path, value, effect);
+}
+},
+_pathMatchesEffect: function (path, effect) {
+var effectArg = effect.trigger.name;
+return effectArg == path || effectArg.indexOf(path + '.') === 0 || effect.trigger.wildcard && path.indexOf(effectArg) === 0;
+},
+linkPaths: function (to, from) {
+this._boundPaths = this._boundPaths || {};
+if (from) {
+this._boundPaths[to] = from;
+} else {
+this.unbindPath(to);
+}
+},
+unlinkPaths: function (path) {
+if (this._boundPaths) {
+delete this._boundPaths[path];
+}
+},
+_notifyBoundPaths: function (path, value) {
+var from, to;
+for (var a in this._boundPaths) {
+var b = this._boundPaths[a];
+if (path.indexOf(a + '.') == 0) {
+from = a;
+to = b;
+break;
+}
+if (path.indexOf(b + '.') == 0) {
+from = b;
+to = a;
+break;
+}
+}
+if (from && to) {
+var p = this._fixPath(to, from, path);
+this.notifyPath(p, value);
+}
+},
+_fixPath: function (property, root, path) {
+return property + path.slice(root.length);
+},
+_notifyPath: function (path, value) {
+var rootName = this._modelForPath(path);
+var dashCaseName = Polymer.CaseMap.camelToDashCase(rootName);
+var eventName = dashCaseName + this._EVENT_CHANGED;
+this.fire(eventName, {
+path: path,
+value: value
+}, { bubbles: false });
+},
+_modelForPath: function (path) {
+var dot = path.indexOf('.');
+return dot < 0 ? path : path.slice(0, dot);
+},
+_EVENT_CHANGED: '-changed',
+_notifySplice: function (array, path, index, added, removed) {
+var splices = [{
+index: index,
+addedCount: added,
+removed: removed,
+object: array,
+type: 'splice'
+}];
+var change = {
+keySplices: Polymer.Collection.applySplices(array, splices),
+indexSplices: splices
+};
+this.set(path + '.splices', change);
+if (added != removed.length) {
+this.notifyPath(path + '.length', array.length);
+}
+change.keySplices = null;
+change.indexSplices = null;
+},
+push: function (path) {
+var array = this.get(path);
+var args = Array.prototype.slice.call(arguments, 1);
+var len = array.length;
+var ret = array.push.apply(array, args);
+this._notifySplice(array, path, len, args.length, []);
+return ret;
+},
+pop: function (path) {
+var array = this.get(path);
+var args = Array.prototype.slice.call(arguments, 1);
+var rem = array.slice(-1);
+var ret = array.pop.apply(array, args);
+this._notifySplice(array, path, array.length, 0, rem);
+return ret;
+},
+splice: function (path, start, deleteCount) {
+var array = this.get(path);
+var args = Array.prototype.slice.call(arguments, 1);
+var rem = array.slice(start, start + deleteCount);
+var ret = array.splice.apply(array, args);
+this._notifySplice(array, path, start, args.length - 2, rem);
+return ret;
+},
+shift: function (path) {
+var array = this.get(path);
+var args = Array.prototype.slice.call(arguments, 1);
+var ret = array.shift.apply(array, args);
+this._notifySplice(array, path, 0, 0, [ret]);
+return ret;
+},
+unshift: function (path) {
+var array = this.get(path);
+var args = Array.prototype.slice.call(arguments, 1);
+var ret = array.unshift.apply(array, args);
+this._notifySplice(array, path, 0, args.length, []);
+return ret;
+}
+});
+}());
+Polymer.Base._addFeature({
+resolveUrl: function (url) {
+var module = Polymer.DomModule.import(this.is);
+var root = '';
+if (module) {
+var assetPath = module.getAttribute('assetpath') || '';
+root = Polymer.ResolveUrl.resolveUrl(assetPath, module.ownerDocument.baseURI);
+}
+return Polymer.ResolveUrl.resolveUrl(url, root);
+}
+});
+Polymer.CssParse = function () {
+var api = {
+parse: function (text) {
+text = this._clean(text);
+return this._parseCss(this._lex(text), text);
+},
+_clean: function (cssText) {
+return cssText.replace(rx.comments, '').replace(rx.port, '');
+},
+_lex: function (text) {
+var root = {
+start: 0,
+end: text.length
+};
+var n = root;
+for (var i = 0, s = 0, l = text.length; i < l; i++) {
+switch (text[i]) {
+case this.OPEN_BRACE:
+if (!n.rules) {
+n.rules = [];
+}
+var p = n;
+var previous = p.rules[p.rules.length - 1];
+n = {
+start: i + 1,
+parent: p,
+previous: previous
+};
+p.rules.push(n);
+break;
+case this.CLOSE_BRACE:
+n.end = i + 1;
+n = n.parent || root;
+break;
+}
+}
+return root;
+},
+_parseCss: function (node, text) {
+var t = text.substring(node.start, node.end - 1);
+node.parsedCssText = node.cssText = t.trim();
+if (node.parent) {
+var ss = node.previous ? node.previous.end : node.parent.start;
+t = text.substring(ss, node.start - 1);
+t = t.substring(t.lastIndexOf(';') + 1);
+var s = node.parsedSelector = node.selector = t.trim();
+node.atRule = s.indexOf(AT_START) === 0;
+if (node.atRule) {
+if (s.indexOf(MEDIA_START) === 0) {
+node.type = this.types.MEDIA_RULE;
+} else if (s.match(rx.keyframesRule)) {
+node.type = this.types.KEYFRAMES_RULE;
+}
+} else {
+if (s.indexOf(VAR_START) === 0) {
+node.type = this.types.MIXIN_RULE;
+} else {
+node.type = this.types.STYLE_RULE;
+}
+}
+}
+var r$ = node.rules;
+if (r$) {
+for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
+this._parseCss(r, text);
+}
+}
+return node;
+},
+stringify: function (node, preserveProperties, text) {
+text = text || '';
+var cssText = '';
+if (node.cssText || node.rules) {
+var r$ = node.rules;
+if (r$ && (preserveProperties || !hasMixinRules(r$))) {
+for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
+cssText = this.stringify(r, preserveProperties, cssText);
+}
+} else {
+cssText = preserveProperties ? node.cssText : removeCustomProps(node.cssText);
+cssText = cssText.trim();
+if (cssText) {
+cssText = ' ' + cssText + '\n';
+}
+}
+}
+if (cssText) {
+if (node.selector) {
+text += node.selector + ' ' + this.OPEN_BRACE + '\n';
+}
+text += cssText;
+if (node.selector) {
+text += this.CLOSE_BRACE + '\n\n';
+}
+}
+return text;
+},
+types: {
+STYLE_RULE: 1,
+KEYFRAMES_RULE: 7,
+MEDIA_RULE: 4,
+MIXIN_RULE: 1000
+},
+OPEN_BRACE: '{',
+CLOSE_BRACE: '}'
+};
+function hasMixinRules(rules) {
+return rules[0].selector.indexOf(VAR_START) >= 0;
+}
+function removeCustomProps(cssText) {
+return cssText.replace(rx.customProp, '').replace(rx.mixinProp, '').replace(rx.mixinApply, '').replace(rx.varApply, '');
+}
+var VAR_START = '--';
+var MEDIA_START = '@media';
+var AT_START = '@';
+var rx = {
+comments: /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,
+port: /@import[^;]*;/gim,
+customProp: /(?:^|[\s;])--[^;{]*?:[^{};]*?;/gim,
+mixinProp: /(?:^|[\s;])--[^;{]*?:[^{;]*?{[^}]*?};?/gim,
+mixinApply: /@apply[\s]*\([^)]*?\)[\s]*;/gim,
+varApply: /[^;:]*?:[^;]*var[^;]*;/gim,
+keyframesRule: /^@[^\s]*keyframes/
+};
+return api;
+}();
+Polymer.StyleUtil = function () {
+return {
+MODULE_STYLES_SELECTOR: 'style, link[rel=import][type~=css]',
+toCssText: function (rules, callback, preserveProperties) {
+if (typeof rules === 'string') {
+rules = this.parser.parse(rules);
+}
+if (callback) {
+this.forEachStyleRule(rules, callback);
+}
+return this.parser.stringify(rules, preserveProperties);
+},
+forRulesInStyles: function (styles, callback) {
+for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) {
+this.forEachStyleRule(this.rulesForStyle(s), callback);
+}
+},
+rulesForStyle: function (style) {
+if (!style.__cssRules && style.textContent) {
+style.__cssRules = this.parser.parse(style.textContent);
+}
+return style.__cssRules;
+},
+clearStyleRules: function (style) {
+style.__cssRules = null;
+},
+forEachStyleRule: function (node, callback) {
+var s = node.selector;
+var skipRules = false;
+if (node.type === this.ruleTypes.STYLE_RULE) {
+callback(node);
+} else if (node.type === this.ruleTypes.KEYFRAMES_RULE || node.type === this.ruleTypes.MIXIN_RULE) {
+skipRules = true;
+}
+var r$ = node.rules;
+if (r$ && !skipRules) {
+for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
+this.forEachStyleRule(r, callback);
+}
+}
+},
+applyCss: function (cssText, moniker, target, afterNode) {
+var style = document.createElement('style');
+if (moniker) {
+style.setAttribute('scope', moniker);
+}
+style.textContent = cssText;
+target = target || document.head;
+if (!afterNode) {
+var n$ = target.querySelectorAll('style[scope]');
+afterNode = n$[n$.length - 1];
+}
+target.insertBefore(style, afterNode && afterNode.nextSibling || target.firstChild);
+return style;
+},
+cssFromModule: function (moduleId) {
+var m = Polymer.DomModule.import(moduleId);
+if (m && !m._cssText) {
+var cssText = '';
+var e$ = Array.prototype.slice.call(m.querySelectorAll(this.MODULE_STYLES_SELECTOR));
+for (var i = 0, e; i < e$.length; i++) {
+e = e$[i];
+if (e.localName === 'style') {
+e = e.__appliedElement || e;
+e.parentNode.removeChild(e);
+} else {
+e = e.import && e.import.body;
+}
+if (e) {
+cssText += Polymer.ResolveUrl.resolveCss(e.textContent, e.ownerDocument);
+}
+}
+m._cssText = cssText;
+}
+return m && m._cssText || '';
+},
+parser: Polymer.CssParse,
+ruleTypes: Polymer.CssParse.types
+};
+}();
+Polymer.StyleTransformer = function () {
+var nativeShadow = Polymer.Settings.useNativeShadow;
+var styleUtil = Polymer.StyleUtil;
+var api = {
+dom: function (node, scope, useAttr, shouldRemoveScope) {
+this._transformDom(node, scope || '', useAttr, shouldRemoveScope);
+},
+_transformDom: function (node, selector, useAttr, shouldRemoveScope) {
+if (node.setAttribute) {
+this.element(node, selector, useAttr, shouldRemoveScope);
+}
+var c$ = Polymer.dom(node).childNodes;
+for (var i = 0; i < c$.length; i++) {
+this._transformDom(c$[i], selector, useAttr, shouldRemoveScope);
+}
+},
+element: function (element, scope, useAttr, shouldRemoveScope) {
+if (useAttr) {
+if (shouldRemoveScope) {
+element.removeAttribute(SCOPE_NAME);
+} else {
+element.setAttribute(SCOPE_NAME, scope);
+}
+} else {
+if (scope) {
+if (element.classList) {
+if (shouldRemoveScope) {
+element.classList.remove(SCOPE_NAME);
+element.classList.remove(scope);
+} else {
+element.classList.add(SCOPE_NAME);
+element.classList.add(scope);
+}
+} else if (element.getAttribute) {
+var c = element.getAttribute(CLASS);
+if (shouldRemoveScope) {
+if (c) {
+element.setAttribute(CLASS, c.replace(SCOPE_NAME, '').replace(scope, ''));
+}
+} else {
+element.setAttribute(CLASS, c + (c ? ' ' : '') + SCOPE_NAME + ' ' + scope);
+}
+}
+}
+}
+},
+elementStyles: function (element, callback) {
+var styles = element._styles;
+var cssText = '';
+for (var i = 0, l = styles.length, s, text; i < l && (s = styles[i]); i++) {
+var rules = styleUtil.rulesForStyle(s);
+cssText += nativeShadow ? styleUtil.toCssText(rules, callback) : this.css(rules, element.is, element.extends, callback, element._scopeCssViaAttr) + '\n\n';
+}
+return cssText.trim();
+},
+css: function (rules, scope, ext, callback, useAttr) {
+var hostScope = this._calcHostScope(scope, ext);
+scope = this._calcElementScope(scope, useAttr);
+var self = this;
+return styleUtil.toCssText(rules, function (rule) {
+if (!rule.isScoped) {
+self.rule(rule, scope, hostScope);
+rule.isScoped = true;
+}
+if (callback) {
+callback(rule, scope, hostScope);
+}
+});
+},
+_calcElementScope: function (scope, useAttr) {
+if (scope) {
+return useAttr ? CSS_ATTR_PREFIX + scope + CSS_ATTR_SUFFIX : CSS_CLASS_PREFIX + scope;
+} else {
+return '';
+}
+},
+_calcHostScope: function (scope, ext) {
+return ext ? '[is=' + scope + ']' : scope;
+},
+rule: function (rule, scope, hostScope) {
+this._transformRule(rule, this._transformComplexSelector, scope, hostScope);
+},
+_transformRule: function (rule, transformer, scope, hostScope) {
+var p$ = rule.selector.split(COMPLEX_SELECTOR_SEP);
+for (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) {
+p$[i] = transformer.call(this, p, scope, hostScope);
+}
+rule.selector = p$.join(COMPLEX_SELECTOR_SEP);
+},
+_transformComplexSelector: function (selector, scope, hostScope) {
+var stop = false;
+var self = this;
+selector = selector.replace(SIMPLE_SELECTOR_SEP, function (m, c, s) {
+if (!stop) {
+var o = self._transformCompoundSelector(s, c, scope, hostScope);
+if (o.stop) {
+stop = true;
+}
+c = o.combinator;
+s = o.value;
+} else {
+s = s.replace(SCOPE_JUMP, ' ');
+}
+return c + s;
+});
+return selector;
+},
+_transformCompoundSelector: function (selector, combinator, scope, hostScope) {
+var jumpIndex = selector.search(SCOPE_JUMP);
+if (selector.indexOf(HOST) >= 0) {
+selector = selector.replace(HOST_PAREN, function (m, host, paren) {
+return hostScope + paren;
+});
+selector = selector.replace(HOST, hostScope);
+} else if (jumpIndex !== 0) {
+selector = scope ? this._transformSimpleSelector(selector, scope) : selector;
+}
+if (selector.indexOf(CONTENT) >= 0) {
+combinator = '';
+}
+var stop;
+if (jumpIndex >= 0) {
+selector = selector.replace(SCOPE_JUMP, ' ');
+stop = true;
+}
+return {
+value: selector,
+combinator: combinator,
+stop: stop
+};
+},
+_transformSimpleSelector: function (selector, scope) {
+var p$ = selector.split(PSEUDO_PREFIX);
+p$[0] += scope;
+return p$.join(PSEUDO_PREFIX);
+},
+documentRule: function (rule) {
+rule.selector = rule.parsedSelector;
+this.normalizeRootSelector(rule);
+if (!nativeShadow) {
+this._transformRule(rule, this._transformDocumentSelector);
+}
+},
+normalizeRootSelector: function (rule) {
+if (rule.selector === ROOT) {
+rule.selector = 'body';
+}
+},
+_transformDocumentSelector: function (selector) {
+return selector.match(SCOPE_JUMP) ? this._transformComplexSelector(selector, SCOPE_DOC_SELECTOR) : this._transformSimpleSelector(selector.trim(), SCOPE_DOC_SELECTOR);
+},
+SCOPE_NAME: 'style-scope'
+};
+var SCOPE_NAME = api.SCOPE_NAME;
+var SCOPE_DOC_SELECTOR = ':not([' + SCOPE_NAME + '])' + ':not(.' + SCOPE_NAME + ')';
+var COMPLEX_SELECTOR_SEP = ',';
+var SIMPLE_SELECTOR_SEP = /(^|[\s>+~]+)([^\s>+~]+)/g;
+var HOST = ':host';
+var ROOT = ':root';
+var HOST_PAREN = /(\:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;
+var CONTENT = '::content';
+var SCOPE_JUMP = /\:\:content|\:\:shadow|\/deep\//;
+var CSS_CLASS_PREFIX = '.';
+var CSS_ATTR_PREFIX = '[' + SCOPE_NAME + '~=';
+var CSS_ATTR_SUFFIX = ']';
+var PSEUDO_PREFIX = ':';
+var CLASS = 'class';
+return api;
+}();
+Polymer.StyleExtends = function () {
+var styleUtil = Polymer.StyleUtil;
+return {
+hasExtends: function (cssText) {
+return Boolean(cssText.match(this.rx.EXTEND));
+},
+transform: function (style) {
+var rules = styleUtil.rulesForStyle(style);
+var self = this;
+styleUtil.forEachStyleRule(rules, function (rule) {
+var map = self._mapRule(rule);
+if (rule.parent) {
+var m;
+while (m = self.rx.EXTEND.exec(rule.cssText)) {
+var extend = m[1];
+var extendor = self._findExtendor(extend, rule);
+if (extendor) {
+self._extendRule(rule, extendor);
+}
+}
+}
+rule.cssText = rule.cssText.replace(self.rx.EXTEND, '');
+});
+return styleUtil.toCssText(rules, function (rule) {
+if (rule.selector.match(self.rx.STRIP)) {
+rule.cssText = '';
+}
+}, true);
+},
+_mapRule: function (rule) {
+if (rule.parent) {
+var map = rule.parent.map || (rule.parent.map = {});
+var parts = rule.selector.split(',');
+for (var i = 0, p; i < parts.length; i++) {
+p = parts[i];
+map[p.trim()] = rule;
+}
+return map;
+}
+},
+_findExtendor: function (extend, rule) {
+return rule.parent && rule.parent.map && rule.parent.map[extend] || this._findExtendor(extend, rule.parent);
+},
+_extendRule: function (target, source) {
+if (target.parent !== source.parent) {
+this._cloneAndAddRuleToParent(source, target.parent);
+}
+target.extends = target.extends || (target.extends = []);
+target.extends.push(source);
+source.selector = source.selector.replace(this.rx.STRIP, '');
+source.selector = (source.selector && source.selector + ',\n') + target.selector;
+if (source.extends) {
+source.extends.forEach(function (e) {
+this._extendRule(target, e);
+}, this);
+}
+},
+_cloneAndAddRuleToParent: function (rule, parent) {
+rule = Object.create(rule);
+rule.parent = parent;
+if (rule.extends) {
+rule.extends = rule.extends.slice();
+}
+parent.rules.push(rule);
+},
+rx: {
+EXTEND: /@extends\(([^)]*)\)\s*?;/gim,
+STRIP: /%[^,]*$/
+}
+};
+}();
+(function () {
+var prepElement = Polymer.Base._prepElement;
+var nativeShadow = Polymer.Settings.useNativeShadow;
+var styleUtil = Polymer.StyleUtil;
+var styleTransformer = Polymer.StyleTransformer;
+var styleExtends = Polymer.StyleExtends;
+Polymer.Base._addFeature({
+_prepElement: function (element) {
+if (this._encapsulateStyle) {
+styleTransformer.element(element, this.is, this._scopeCssViaAttr);
+}
+prepElement.call(this, element);
+},
+_prepStyles: function () {
+if (this._encapsulateStyle === undefined) {
+this._encapsulateStyle = !nativeShadow && Boolean(this._template);
+}
+this._styles = this._collectStyles();
+var cssText = styleTransformer.elementStyles(this);
+if (cssText && this._template) {
+var style = styleUtil.applyCss(cssText, this.is, nativeShadow ? this._template.content : null);
+if (!nativeShadow) {
+this._scopeStyle = style;
+}
+}
+},
+_collectStyles: function () {
+var styles = [];
+var cssText = '', m$ = this.styleModules;
+if (m$) {
+for (var i = 0, l = m$.length, m; i < l && (m = m$[i]); i++) {
+cssText += styleUtil.cssFromModule(m);
+}
+}
+cssText += styleUtil.cssFromModule(this.is);
+if (cssText) {
+var style = document.createElement('style');
+style.textContent = cssText;
+if (styleExtends.hasExtends(style.textContent)) {
+cssText = styleExtends.transform(style);
+}
+styles.push(style);
+}
+return styles;
+},
+_elementAdd: function (node) {
+if (this._encapsulateStyle) {
+if (node.__styleScoped) {
+node.__styleScoped = false;
+} else {
+styleTransformer.dom(node, this.is, this._scopeCssViaAttr);
+}
+}
+},
+_elementRemove: function (node) {
+if (this._encapsulateStyle) {
+styleTransformer.dom(node, this.is, this._scopeCssViaAttr, true);
+}
+},
+scopeSubtree: function (container, shouldObserve) {
+if (nativeShadow) {
+return;
+}
+var self = this;
+var scopify = function (node) {
+if (node.nodeType === Node.ELEMENT_NODE) {
+node.className = self._scopeElementClass(node, node.className);
+var n$ = node.querySelectorAll('*');
+Array.prototype.forEach.call(n$, function (n) {
+n.className = self._scopeElementClass(n, n.className);
+});
+}
+};
+scopify(container);
+if (shouldObserve) {
+var mo = new MutationObserver(function (mxns) {
+mxns.forEach(function (m) {
+if (m.addedNodes) {
+for (var i = 0; i < m.addedNodes.length; i++) {
+scopify(m.addedNodes[i]);
+}
+}
+});
+});
+mo.observe(container, {
+childList: true,
+subtree: true
+});
+return mo;
+}
+}
+});
+}());
+Polymer.StyleProperties = function () {
+'use strict';
+var nativeShadow = Polymer.Settings.useNativeShadow;
+var matchesSelector = Polymer.DomApi.matchesSelector;
+var styleUtil = Polymer.StyleUtil;
+var styleTransformer = Polymer.StyleTransformer;
+return {
+decorateStyles: function (styles) {
+var self = this, props = {};
+styleUtil.forRulesInStyles(styles, function (rule) {
+self.decorateRule(rule);
+self.collectPropertiesInCssText(rule.propertyInfo.cssText, props);
+});
+var names = [];
+for (var i in props) {
+names.push(i);
+}
+return names;
+},
+decorateRule: function (rule) {
+if (rule.propertyInfo) {
+return rule.propertyInfo;
+}
+var info = {}, properties = {};
+var hasProperties = this.collectProperties(rule, properties);
+if (hasProperties) {
+info.properties = properties;
+rule.rules = null;
+}
+info.cssText = this.collectCssText(rule);
+rule.propertyInfo = info;
+return info;
+},
+collectProperties: function (rule, properties) {
+var info = rule.propertyInfo;
+if (info) {
+if (info.properties) {
+Polymer.Base.mixin(properties, info.properties);
+return true;
+}
+} else {
+var m, rx = this.rx.VAR_ASSIGN;
+var cssText = rule.parsedCssText;
+var any;
+while (m = rx.exec(cssText)) {
+properties[m[1]] = (m[2] || m[3]).trim();
+any = true;
+}
+return any;
+}
+},
+collectCssText: function (rule) {
+var customCssText = '';
+var cssText = rule.parsedCssText;
+cssText = cssText.replace(this.rx.BRACKETED, '').replace(this.rx.VAR_ASSIGN, '');
+var parts = cssText.split(';');
+for (var i = 0, p; i < parts.length; i++) {
+p = parts[i];
+if (p.match(this.rx.MIXIN_MATCH) || p.match(this.rx.VAR_MATCH)) {
+customCssText += p + ';\n';
+}
+}
+return customCssText;
+},
+collectPropertiesInCssText: function (cssText, props) {
+var m;
+while (m = this.rx.VAR_CAPTURE.exec(cssText)) {
+props[m[1]] = true;
+var def = m[2];
+if (def && def.match(this.rx.IS_VAR)) {
+props[def] = true;
+}
+}
+},
+reify: function (props) {
+var names = Object.getOwnPropertyNames(props);
+for (var i = 0, n; i < names.length; i++) {
+n = names[i];
+props[n] = this.valueForProperty(props[n], props);
+}
+},
+valueForProperty: function (property, props) {
+if (property) {
+if (property.indexOf(';') >= 0) {
+property = this.valueForProperties(property, props);
+} else {
+var self = this;
+var fn = function (all, prefix, value, fallback) {
+var propertyValue = self.valueForProperty(props[value], props) || (props[fallback] ? self.valueForProperty(props[fallback], props) : fallback);
+return prefix + (propertyValue || '');
+};
+property = property.replace(this.rx.VAR_MATCH, fn);
+}
+}
+return property && property.trim() || '';
+},
+valueForProperties: function (property, props) {
+var parts = property.split(';');
+for (var i = 0, p, m; i < parts.length && (p = parts[i]); i++) {
+m = p.match(this.rx.MIXIN_MATCH);
+if (m) {
+p = this.valueForProperty(props[m[1]], props);
+} else {
+var pp = p.split(':');
+if (pp[1]) {
+pp[1] = pp[1].trim();
+pp[1] = this.valueForProperty(pp[1], props) || pp[1];
+}
+p = pp.join(':');
+}
+parts[i] = p && p.lastIndexOf(';') === p.length - 1 ? p.slice(0, -1) : p || '';
+}
+return parts.join(';');
+},
+applyProperties: function (rule, props) {
+var output = '';
+if (!rule.propertyInfo) {
+this.decorateRule(rule);
+}
+if (rule.propertyInfo.cssText) {
+output = this.valueForProperties(rule.propertyInfo.cssText, props);
+}
+rule.cssText = output;
+},
+propertyDataFromStyles: function (styles, element) {
+var props = {}, self = this;
+var o = [], i = 0;
+styleUtil.forRulesInStyles(styles, function (rule) {
+if (!rule.propertyInfo) {
+self.decorateRule(rule);
+}
+if (element && rule.propertyInfo.properties && matchesSelector.call(element, rule.selector)) {
+self.collectProperties(rule, props);
+addToBitMask(i, o);
+}
+i++;
+});
+return {
+properties: props,
+key: o
+};
+},
+scopePropertiesFromStyles: function (styles) {
+if (!styles._scopeStyleProperties) {
+styles._scopeStyleProperties = this.selectedPropertiesFromStyles(styles, this.SCOPE_SELECTORS);
+}
+return styles._scopeStyleProperties;
+},
+hostPropertiesFromStyles: function (styles) {
+if (!styles._hostStyleProperties) {
+styles._hostStyleProperties = this.selectedPropertiesFromStyles(styles, this.HOST_SELECTORS);
+}
+return styles._hostStyleProperties;
+},
+selectedPropertiesFromStyles: function (styles, selectors) {
+var props = {}, self = this;
+styleUtil.forRulesInStyles(styles, function (rule) {
+if (!rule.propertyInfo) {
+self.decorateRule(rule);
+}
+for (var i = 0; i < selectors.length; i++) {
+if (rule.parsedSelector === selectors[i]) {
+self.collectProperties(rule, props);
+return;
+}
+}
+});
+return props;
+},
+transformStyles: function (element, properties, scopeSelector) {
+var self = this;
+var hostSelector = styleTransformer._calcHostScope(element.is, element.extends);
+var rxHostSelector = element.extends ? '\\' + hostSelector.slice(0, -1) + '\\]' : hostSelector;
+var hostRx = new RegExp(this.rx.HOST_PREFIX + rxHostSelector + this.rx.HOST_SUFFIX);
+return styleTransformer.elementStyles(element, function (rule) {
+self.applyProperties(rule, properties);
+if (rule.cssText && !nativeShadow) {
+self._scopeSelector(rule, hostRx, hostSelector, element._scopeCssViaAttr, scopeSelector);
+}
+});
+},
+_scopeSelector: function (rule, hostRx, hostSelector, viaAttr, scopeId) {
+rule.transformedSelector = rule.transformedSelector || rule.selector;
+var selector = rule.transformedSelector;
+var scope = viaAttr ? '[' + styleTransformer.SCOPE_NAME + '~=' + scopeId + ']' : '.' + scopeId;
+var parts = selector.split(',');
+for (var i = 0, l = parts.length, p; i < l && (p = parts[i]); i++) {
+parts[i] = p.match(hostRx) ? p.replace(hostSelector, hostSelector + scope) : scope + ' ' + p;
+}
+rule.selector = parts.join(',');
+},
+applyElementScopeSelector: function (element, selector, old, viaAttr) {
+var c = viaAttr ? element.getAttribute(styleTransformer.SCOPE_NAME) : element.className;
+var v = old ? c.replace(old, selector) : (c ? c + ' ' : '') + this.XSCOPE_NAME + ' ' + selector;
+if (c !== v) {
+if (viaAttr) {
+element.setAttribute(styleTransformer.SCOPE_NAME, v);
+} else {
+element.className = v;
+}
+}
+},
+applyElementStyle: function (element, properties, selector, style) {
+var cssText = style ? style.textContent || '' : this.transformStyles(element, properties, selector);
+var s = element._customStyle;
+if (s && !nativeShadow && s !== style) {
+s._useCount--;
+if (s._useCount <= 0) {
+s.parentNode.removeChild(s);
+}
+}
+if (nativeShadow || (!style || !style.parentNode)) {
+if (nativeShadow && element._customStyle) {
+element._customStyle.textContent = cssText;
+style = element._customStyle;
+} else if (cssText) {
+style = styleUtil.applyCss(cssText, selector, nativeShadow ? element.root : null, element._scopeStyle);
+}
+}
+if (style) {
+style._useCount = style._useCount || 0;
+if (element._customStyle != style) {
+style._useCount++;
+}
+element._customStyle = style;
+}
+return style;
+},
+rx: {
+VAR_ASSIGN: /(?:^|;\s*)(--[^\:;]*?):\s*?(?:([^;{]*?)|{([^}]*)})(?=;)/gim,
+MIXIN_MATCH: /(?:^|\W+)@apply[\s]*\(([^)]*)\);?/im,
+VAR_MATCH: /(^|\W+)var\([\s]*([^,)]*)[\s]*,?[\s]*((?:[^,)]*)|(?:[^;]*\([^;)]*\)))[\s]*?\)/gim,
+VAR_CAPTURE: /\([\s]*(--[^,\s)]*)(?:,[\s]*(--[^,\s)]*))?(?:\)|,)/gim,
+IS_VAR: /^--/,
+BRACKETED: /\{[^}]*\}/g,
+HOST_PREFIX: '(?:^|[^.])',
+HOST_SUFFIX: '($|[.:[\\s>+~])'
+},
+HOST_SELECTORS: [':host'],
+SCOPE_SELECTORS: [':root'],
+XSCOPE_NAME: 'x-scope'
+};
+function addToBitMask(n, bits) {
+var o = parseInt(n / 32);
+var v = 1 << n % 32;
+bits[o] = (bits[o] || 0) | v;
+}
+}();
+Polymer.StyleDefaults = function () {
+var styleProperties = Polymer.StyleProperties;
+var styleUtil = Polymer.StyleUtil;
+var api = {
+_styles: [],
+_properties: null,
+addStyle: function (style) {
+this._styles.push(style);
+this._properties = null;
+},
+get _styleProperties() {
+if (!this._properties) {
+styleProperties.decorateStyles(this._styles);
+this._styles._scopeStyleProperties = null;
+this._properties = styleProperties.scopePropertiesFromStyles(this._styles);
+styleProperties.reify(this._properties);
+}
+return this._properties;
+},
+_needsStyleProperties: function () {
+},
+_computeStyleProperties: function () {
+return this._styleProperties;
+},
+updateStyles: function () {
+this._styleCache.clear();
+for (var i = 0, s; i < this._styles.length; i++) {
+s = this._styles[i];
+s = s.__importElement || s;
+s._apply();
+}
+}
+};
+return api;
+}();
+(function () {
+Polymer.StyleCache = function () {
+this.cache = {};
+};
+Polymer.StyleCache.prototype = {
+MAX: 100,
+store: function (is, data, keyValues, keyStyles) {
+data.keyValues = keyValues;
+data.styles = keyStyles;
+var s$ = this.cache[is] = this.cache[is] || [];
+s$.push(data);
+if (s$.length > this.MAX) {
+s$.shift();
+}
+},
+retrieve: function (is, keyValues, keyStyles) {
+var cache = this.cache[is];
+if (cache) {
+for (var i = cache.length - 1, data; i >= 0; i--) {
+data = cache[i];
+if (keyStyles === data.styles && this._objectsEqual(keyValues, data.keyValues)) {
+return data;
+}
+}
+}
+},
+clear: function () {
+this.cache = {};
+},
+_objectsEqual: function (target, source) {
+for (var i in target) {
+if (target[i] !== source[i]) {
+return false;
+}
+}
+if (Array.isArray(target)) {
+return target.length === source.length;
+}
+return true;
+}
+};
+}());
+(function () {
+'use strict';
+var serializeValueToAttribute = Polymer.Base.serializeValueToAttribute;
+var propertyUtils = Polymer.StyleProperties;
+var styleTransformer = Polymer.StyleTransformer;
+var styleUtil = Polymer.StyleUtil;
+var styleDefaults = Polymer.StyleDefaults;
+var nativeShadow = Polymer.Settings.useNativeShadow;
+Polymer.Base._addFeature({
+_prepStyleProperties: function () {
+this._ownStylePropertyNames = this._styles ? propertyUtils.decorateStyles(this._styles) : [];
+},
+_setupStyleProperties: function () {
+this.customStyle = {};
+},
+_needsStyleProperties: function () {
+return Boolean(this._ownStylePropertyNames && this._ownStylePropertyNames.length);
+},
+_beforeAttached: function () {
+if (!this._scopeSelector && this._needsStyleProperties()) {
+this._updateStyleProperties();
+}
+},
+_updateStyleProperties: function () {
+var info, scope = this.domHost || styleDefaults;
+if (!scope._styleCache) {
+scope._styleCache = new Polymer.StyleCache();
+}
+var scopeData = propertyUtils.propertyDataFromStyles(scope._styles, this);
+info = scope._styleCache.retrieve(this.is, scopeData.key, this._styles);
+var scopeCached = Boolean(info);
+if (scopeCached) {
+this._styleProperties = info._styleProperties;
+} else {
+this._computeStyleProperties(scopeData.properties);
+}
+this._computeOwnStyleProperties();
+if (!scopeCached) {
+info = styleCache.retrieve(this.is, this._ownStyleProperties, this._styles);
+}
+var globalCached = Boolean(info) && !scopeCached;
+var style = this._applyStyleProperties(info);
+if (!scopeCached) {
+var cacheableStyle = style;
+if (nativeShadow) {
+cacheableStyle = style.cloneNode ? style.cloneNode(true) : Object.create(style || null);
+}
+info = {
+style: cacheableStyle,
+_scopeSelector: this._scopeSelector,
+_styleProperties: this._styleProperties
+};
+scope._styleCache.store(this.is, info, scopeData.key, this._styles);
+if (!globalCached) {
+styleCache.store(this.is, Object.create(info), this._ownStyleProperties, this._styles);
+}
+}
+},
+_computeStyleProperties: function (scopeProps) {
+var scope = this.domHost || styleDefaults;
+if (!scope._styleProperties) {
+scope._computeStyleProperties();
+}
+var props = Object.create(scope._styleProperties);
+this.mixin(props, propertyUtils.hostPropertiesFromStyles(this._styles));
+scopeProps = scopeProps || propertyUtils.propertyDataFromStyles(scope._styles, this).properties;
+this.mixin(props, scopeProps);
+this.mixin(props, propertyUtils.scopePropertiesFromStyles(this._styles));
+this.mixin(props, this.customStyle);
+propertyUtils.reify(props);
+this._styleProperties = props;
+},
+_computeOwnStyleProperties: function () {
+var props = {};
+for (var i = 0, n; i < this._ownStylePropertyNames.length; i++) {
+n = this._ownStylePropertyNames[i];
+props[n] = this._styleProperties[n];
+}
+this._ownStyleProperties = props;
+},
+_scopeCount: 0,
+_applyStyleProperties: function (info) {
+var oldScopeSelector = this._scopeSelector;
+this._scopeSelector = info ? info._scopeSelector : this.is + '-' + this.__proto__._scopeCount++;
+var style = propertyUtils.applyElementStyle(this, this._styleProperties, this._scopeSelector, info && info.style);
+if ((style || oldScopeSelector) && !nativeShadow) {
+propertyUtils.applyElementScopeSelector(this, this._scopeSelector, oldScopeSelector, this._scopeCssViaAttr);
+}
+return style || {};
+},
+serializeValueToAttribute: function (value, attribute, node) {
+node = node || this;
+if (attribute === 'class') {
+var host = node === this ? this.domHost || this.dataHost : this;
+if (host) {
+value = host._scopeElementClass(node, value);
+}
+}
+node = Polymer.dom(node);
+serializeValueToAttribute.call(this, value, attribute, node);
+},
+_scopeElementClass: function (element, selector) {
+if (!nativeShadow && !this._scopeCssViaAttr) {
+selector += (selector ? ' ' : '') + SCOPE_NAME + ' ' + this.is + (element._scopeSelector ? ' ' + XSCOPE_NAME + ' ' + element._scopeSelector : '');
+}
+return selector;
+},
+updateStyles: function () {
+if (this.isAttached) {
+if (this._needsStyleProperties()) {
+this._updateStyleProperties();
+} else {
+this._styleProperties = null;
+}
+if (this._styleCache) {
+this._styleCache.clear();
+}
+this._updateRootStyles();
+}
+},
+_updateRootStyles: function (root) {
+root = root || this.root;
+var c$ = Polymer.dom(root)._query(function (e) {
+return e.shadyRoot || e.shadowRoot;
+});
+for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
+if (c.updateStyles) {
+c.updateStyles();
+}
+}
+}
+});
+Polymer.updateStyles = function () {
+styleDefaults.updateStyles();
+Polymer.Base._updateRootStyles(document);
+};
+var styleCache = new Polymer.StyleCache();
+Polymer.customStyleCache = styleCache;
+var SCOPE_NAME = styleTransformer.SCOPE_NAME;
+var XSCOPE_NAME = propertyUtils.XSCOPE_NAME;
+}());
+Polymer.Base._addFeature({
+_registerFeatures: function () {
+this._prepIs();
+this._prepAttributes();
+this._prepExtends();
+this._prepConstructor();
+this._prepTemplate();
+this._prepStyles();
+this._prepStyleProperties();
+this._prepAnnotations();
+this._prepEffects();
+this._prepBehaviors();
+this._prepBindings();
+this._prepShady();
+},
+_prepBehavior: function (b) {
+this._addPropertyEffects(b.properties);
+this._addComplexObserverEffects(b.observers);
+this._addHostAttributes(b.hostAttributes);
+},
+_initFeatures: function () {
+this._poolContent();
+this._setupConfigure();
+this._setupStyleProperties();
+this._pushHost();
+this._stampTemplate();
+this._popHost();
+this._marshalAnnotationReferences();
+this._marshalHostAttributes();
+this._setupDebouncers();
+this._marshalInstanceEffects();
+this._marshalBehaviors();
+this._marshalAttributes();
+this._tryReady();
+},
+_marshalBehavior: function (b) {
+this._listenListeners(b.listeners);
+}
+});
+(function () {
+var nativeShadow = Polymer.Settings.useNativeShadow;
+var propertyUtils = Polymer.StyleProperties;
+var styleUtil = Polymer.StyleUtil;
+var styleDefaults = Polymer.StyleDefaults;
+var styleTransformer = Polymer.StyleTransformer;
+Polymer({
+is: 'custom-style',
+extends: 'style',
+created: function () {
+this._tryApply();
+},
+attached: function () {
+this._tryApply();
+},
+_tryApply: function () {
+if (!this._appliesToDocument) {
+if (this.parentNode && this.parentNode.localName !== 'dom-module') {
+this._appliesToDocument = true;
+var e = this.__appliedElement || this;
+styleDefaults.addStyle(e);
+if (e.textContent) {
+this._apply();
+} else {
+var observer = new MutationObserver(function () {
+observer.disconnect();
+this._apply();
+}.bind(this));
+observer.observe(e, { childList: true });
+}
+}
+}
+},
+_apply: function () {
+var e = this.__appliedElement || this;
+this._computeStyleProperties();
+var props = this._styleProperties;
+var self = this;
+e.textContent = styleUtil.toCssText(styleUtil.rulesForStyle(e), function (rule) {
+var css = rule.cssText = rule.parsedCssText;
+if (rule.propertyInfo && rule.propertyInfo.cssText) {
+css = css.replace(propertyUtils.rx.VAR_ASSIGN, '');
+rule.cssText = propertyUtils.valueForProperties(css, props);
+}
+styleTransformer.documentRule(rule);
+});
+}
+});
+}());
+Polymer.Templatizer = {
+properties: { _hideTemplateChildren: { observer: '_showHideChildren' } },
+_templatizerStatic: {
+count: 0,
+callbacks: {},
+debouncer: null
+},
+_instanceProps: Polymer.nob,
+created: function () {
+this._templatizerId = this._templatizerStatic.count++;
+},
+templatize: function (template) {
+if (!template._content) {
+template._content = template.content;
+}
+if (template._content._ctor) {
+this.ctor = template._content._ctor;
+this._prepParentProperties(this.ctor.prototype, template);
+return;
+}
+var archetype = Object.create(Polymer.Base);
+this._customPrepAnnotations(archetype, template);
+archetype._prepEffects();
+this._customPrepEffects(archetype);
+archetype._prepBehaviors();
+archetype._prepBindings();
+this._prepParentProperties(archetype, template);
+archetype._notifyPath = this._notifyPathImpl;
+archetype._scopeElementClass = this._scopeElementClassImpl;
+archetype.listen = this._listenImpl;
+var _constructor = this._constructorImpl;
+var ctor = function TemplateInstance(model, host) {
+_constructor.call(this, model, host);
+};
+ctor.prototype = archetype;
+archetype.constructor = ctor;
+template._content._ctor = ctor;
+this.ctor = ctor;
+},
+_getRootDataHost: function () {
+return this.dataHost && this.dataHost._rootDataHost || this.dataHost;
+},
+_showHideChildren: function (hidden) {
+},
+_debounceTemplate: function (fn) {
+this._templatizerStatic.callbacks[this._templatizerId] = fn.bind(this);
+this._templatizerStatic.debouncer = Polymer.Debounce(this._templatizerStatic.debouncer, this._flushTemplates.bind(this, true));
+},
+_flushTemplates: function (debouncerExpired) {
+var db = this._templatizerStatic.debouncer;
+while (debouncerExpired || db && db.finish) {
+db.stop();
+var cbs = this._templatizerStatic.callbacks;
+this._templatizerStatic.callbacks = {};
+for (var id in cbs) {
+cbs[id]();
+}
+debouncerExpired = false;
+}
+},
+_customPrepEffects: function (archetype) {
+var parentProps = archetype._parentProps;
+for (var prop in parentProps) {
+archetype._addPropertyEffect(prop, 'function', this._createHostPropEffector(prop));
+}
+},
+_customPrepAnnotations: function (archetype, template) {
+archetype._template = template;
+var c = template._content;
+if (!c._notes) {
+var rootDataHost = archetype._rootDataHost;
+if (rootDataHost) {
+Polymer.Annotations.prepElement = rootDataHost._prepElement.bind(rootDataHost);
+}
+c._notes = Polymer.Annotations.parseAnnotations(template);
+Polymer.Annotations.prepElement = null;
+this._processAnnotations(c._notes);
+}
+archetype._notes = c._notes;
+archetype._parentProps = c._parentProps;
+},
+_prepParentProperties: function (archetype, template) {
+var parentProps = this._parentProps = archetype._parentProps;
+if (this._forwardParentProp && parentProps) {
+var proto = archetype._parentPropProto;
+var prop;
+if (!proto) {
+for (prop in this._instanceProps) {
+delete parentProps[prop];
+}
+proto = archetype._parentPropProto = Object.create(null);
+if (template != this) {
+Polymer.Bind.prepareModel(proto);
+}
+for (prop in parentProps) {
+var parentProp = '_parent_' + prop;
+var effects = [
+{
+kind: 'function',
+effect: this._createForwardPropEffector(prop)
+},
+{ kind: 'notify' }
+];
+Polymer.Bind._createAccessors(proto, parentProp, effects);
+}
+}
+if (template != this) {
+Polymer.Bind.prepareInstance(template);
+template._forwardParentProp = this._forwardParentProp.bind(this);
+}
+this._extendTemplate(template, proto);
+}
+},
+_createForwardPropEffector: function (prop) {
+return function (source, value) {
+this._forwardParentProp(prop, value);
+};
+},
+_createHostPropEffector: function (prop) {
+return function (source, value) {
+this.dataHost['_parent_' + prop] = value;
+};
+},
+_extendTemplate: function (template, proto) {
+Object.getOwnPropertyNames(proto).forEach(function (n) {
+var val = template[n];
+var pd = Object.getOwnPropertyDescriptor(proto, n);
+Object.defineProperty(template, n, pd);
+if (val !== undefined) {
+template._propertySet(n, val);
+}
+});
+},
+_forwardInstancePath: function (inst, path, value) {
+},
+_notifyPathImpl: function (path, value) {
+var dataHost = this.dataHost;
+var dot = path.indexOf('.');
+var root = dot < 0 ? path : path.slice(0, dot);
+dataHost._forwardInstancePath.call(dataHost, this, path, value);
+if (root in dataHost._parentProps) {
+dataHost.notifyPath('_parent_' + path, value);
+}
+},
+_pathEffector: function (path, value, fromAbove) {
+if (this._forwardParentPath) {
+if (path.indexOf('_parent_') === 0) {
+this._forwardParentPath(path.substring(8), value);
+}
+}
+Polymer.Base._pathEffector.apply(this, arguments);
+},
+_constructorImpl: function (model, host) {
+this._rootDataHost = host._getRootDataHost();
+this._setupConfigure(model);
+this._pushHost(host);
+this.root = this.instanceTemplate(this._template);
+this.root.__styleScoped = true;
+this._popHost();
+this._marshalAnnotatedNodes();
+this._marshalInstanceEffects();
+this._marshalAnnotatedListeners();
+var children = [];
+for (var n = this.root.firstChild; n; n = n.nextSibling) {
+children.push(n);
+n._templateInstance = this;
+}
+this._children = children;
+this._tryReady();
+},
+_listenImpl: function (node, eventName, methodName) {
+var model = this;
+var host = this._rootDataHost;
+var handler = host._createEventHandler(node, eventName, methodName);
+var decorated = function (e) {
+e.model = model;
+handler(e);
+};
+host._listen(node, eventName, decorated);
+},
+_scopeElementClassImpl: function (node, value) {
+var host = this._rootDataHost;
+if (host) {
+return host._scopeElementClass(node, value);
+}
+},
+stamp: function (model) {
+model = model || {};
+if (this._parentProps) {
+for (var prop in this._parentProps) {
+model[prop] = this['_parent_' + prop];
+}
+}
+return new this.ctor(model, this);
+}
+};
+Polymer({
+is: 'dom-template',
+extends: 'template',
+behaviors: [Polymer.Templatizer],
+ready: function () {
+this.templatize(this);
+}
+});
+Polymer._collections = new WeakMap();
+Polymer.Collection = function (userArray) {
+Polymer._collections.set(userArray, this);
+this.userArray = userArray;
+this.store = userArray.slice();
+this.initMap();
+};
+Polymer.Collection.prototype = {
+constructor: Polymer.Collection,
+initMap: function () {
+var omap = this.omap = new WeakMap();
+var pmap = this.pmap = {};
+var s = this.store;
+for (var i = 0; i < s.length; i++) {
+var item = s[i];
+if (item && typeof item == 'object') {
+omap.set(item, i);
+} else {
+pmap[item] = i;
+}
+}
+},
+add: function (item) {
+var key = this.store.push(item) - 1;
+if (item && typeof item == 'object') {
+this.omap.set(item, key);
+} else {
+this.pmap[item] = key;
+}
+return key;
+},
+removeKey: function (key) {
+this._removeFromMap(this.store[key]);
+delete this.store[key];
+},
+_removeFromMap: function (item) {
+if (typeof item == 'object') {
+this.omap.delete(item);
+} else {
+delete this.pmap[item];
+}
+},
+remove: function (item) {
+var key = this.getKey(item);
+this.removeKey(key);
+return key;
+},
+getKey: function (item) {
+if (typeof item == 'object') {
+return this.omap.get(item);
+} else {
+return this.pmap[item];
+}
+},
+getKeys: function () {
+return Object.keys(this.store);
+},
+setItem: function (key, value) {
+this.store[key] = value;
+},
+getItem: function (key) {
+return this.store[key];
+},
+getItems: function () {
+var items = [], store = this.store;
+for (var key in store) {
+items.push(store[key]);
+}
+return items;
+},
+_applySplices: function (splices) {
+var keySplices = [];
+for (var i = 0; i < splices.length; i++) {
+var j, o, key, s = splices[i];
+var removed = [];
+for (j = 0; j < s.removed.length; j++) {
+o = s.removed[j];
+key = this.remove(o);
+removed.push(key);
+}
+var added = [];
+for (j = 0; j < s.addedCount; j++) {
+o = this.userArray[s.index + j];
+key = this.add(o);
+added.push(key);
+}
+keySplices.push({
+index: s.index,
+removed: removed,
+removedItems: s.removed,
+added: added
+});
+}
+return keySplices;
+}
+};
+Polymer.Collection.get = function (userArray) {
+return Polymer._collections.get(userArray) || new Polymer.Collection(userArray);
+};
+Polymer.Collection.applySplices = function (userArray, splices) {
+var coll = Polymer._collections.get(userArray);
+return coll ? coll._applySplices(splices) : null;
+};
+Polymer({
+is: 'dom-repeat',
+extends: 'template',
+properties: {
+items: { type: Array },
+as: {
+type: String,
+value: 'item'
+},
+indexAs: {
+type: String,
+value: 'index'
+},
+sort: {
+type: Function,
+observer: '_sortChanged'
+},
+filter: {
+type: Function,
+observer: '_filterChanged'
+},
+observe: {
+type: String,
+observer: '_observeChanged'
+},
+delay: Number
+},
+behaviors: [Polymer.Templatizer],
+observers: ['_itemsChanged(items.*)'],
+detached: function () {
+if (this.rows) {
+for (var i = 0; i < this.rows.length; i++) {
+this._detachRow(i);
+}
+}
+},
+attached: function () {
+if (this.rows) {
+var parentNode = Polymer.dom(this).parentNode;
+for (var i = 0; i < this.rows.length; i++) {
+Polymer.dom(parentNode).insertBefore(this.rows[i].root, this);
+}
+}
+},
+ready: function () {
+this._instanceProps = { __key__: true };
+this._instanceProps[this.as] = true;
+this._instanceProps[this.indexAs] = true;
+if (!this.ctor) {
+this.templatize(this);
+}
+},
+_sortChanged: function () {
+var dataHost = this._getRootDataHost();
+var sort = this.sort;
+this._sortFn = sort && (typeof sort == 'function' ? sort : function () {
+return dataHost[sort].apply(dataHost, arguments);
+});
+this._fullRefresh = true;
+if (this.items) {
+this._debounceTemplate(this._render);
+}
+},
+_filterChanged: function () {
+var dataHost = this._getRootDataHost();
+var filter = this.filter;
+this._filterFn = filter && (typeof filter == 'function' ? filter : function () {
+return dataHost[filter].apply(dataHost, arguments);
+});
+this._fullRefresh = true;
+if (this.items) {
+this._debounceTemplate(this._render);
+}
+},
+_observeChanged: function () {
+this._observePaths = this.observe && this.observe.replace('.*', '.').split(' ');
+},
+_itemsChanged: function (change) {
+if (change.path == 'items') {
+if (Array.isArray(this.items)) {
+this.collection = Polymer.Collection.get(this.items);
+} else if (!this.items) {
+this.collection = null;
+} else {
+this._error(this._logf('dom-repeat', 'expected array for `items`,' + ' found', this.items));
+}
+this._splices = [];
+this._fullRefresh = true;
+this._debounceTemplate(this._render);
+} else if (change.path == 'items.splices') {
+this._splices = this._splices.concat(change.value.keySplices);
+this._debounceTemplate(this._render);
+} else {
+var subpath = change.path.slice(6);
+this._forwardItemPath(subpath, change.value);
+this._checkObservedPaths(subpath);
+}
+},
+_checkObservedPaths: function (path) {
+if (this._observePaths) {
+path = path.substring(path.indexOf('.') + 1);
+var paths = this._observePaths;
+for (var i = 0; i < paths.length; i++) {
+if (path.indexOf(paths[i]) === 0) {
+this._fullRefresh = true;
+if (this.delay) {
+this.debounce('render', this._render, this.delay);
+} else {
+this._debounceTemplate(this._render);
+}
+return;
+}
+}
+}
+},
+render: function () {
+this._fullRefresh = true;
+this.debounce('render', this._render);
+this._flushTemplates();
+},
+_render: function () {
+var c = this.collection;
+if (!this._fullRefresh) {
+if (this._sortFn) {
+this._applySplicesViewSort(this._splices);
+} else {
+if (this._filterFn) {
+this._fullRefresh = true;
+} else {
+this._applySplicesArraySort(this._splices);
+}
+}
+}
+if (this._fullRefresh) {
+this._sortAndFilter();
+this._fullRefresh = false;
+}
+this._splices = [];
+var rowForKey = this._rowForKey = {};
+var keys = this._orderedKeys;
+this.rows = this.rows || [];
+for (var i = 0; i < keys.length; i++) {
+var key = keys[i];
+var item = c.getItem(key);
+var row = this.rows[i];
+rowForKey[key] = i;
+if (!row) {
+this.rows.push(row = this._insertRow(i, null, item));
+}
+row[this.as] = item;
+row.__key__ = key;
+row[this.indexAs] = i;
+}
+for (; i < this.rows.length; i++) {
+this._detachRow(i);
+}
+this.rows.splice(keys.length, this.rows.length - keys.length);
+this.fire('dom-change');
+},
+_sortAndFilter: function () {
+var c = this.collection;
+if (!this._sortFn) {
+this._orderedKeys = [];
+var items = this.items;
+if (items) {
+for (var i = 0; i < items.length; i++) {
+this._orderedKeys.push(c.getKey(items[i]));
+}
+}
+} else {
+this._orderedKeys = c ? c.getKeys() : [];
+}
+if (this._filterFn) {
+this._orderedKeys = this._orderedKeys.filter(function (a) {
+return this._filterFn(c.getItem(a));
+}, this);
+}
+if (this._sortFn) {
+this._orderedKeys.sort(function (a, b) {
+return this._sortFn(c.getItem(a), c.getItem(b));
+}.bind(this));
+}
+},
+_keySort: function (a, b) {
+return this.collection.getKey(a) - this.collection.getKey(b);
+},
+_applySplicesViewSort: function (splices) {
+var c = this.collection;
+var keys = this._orderedKeys;
+var rows = this.rows;
+var removedRows = [];
+var addedKeys = [];
+var pool = [];
+var sortFn = this._sortFn || this._keySort.bind(this);
+splices.forEach(function (s) {
+for (var i = 0; i < s.removed.length; i++) {
+var idx = this._rowForKey[s.removed[i]];
+if (idx != null) {
+removedRows.push(idx);
+}
+}
+for (var i = 0; i < s.added.length; i++) {
+addedKeys.push(s.added[i]);
+}
+}, this);
+if (removedRows.length) {
+removedRows.sort();
+for (var i = removedRows.length - 1; i >= 0; i--) {
+var idx = removedRows[i];
+pool.push(this._detachRow(idx));
+rows.splice(idx, 1);
+keys.splice(idx, 1);
+}
+}
+if (addedKeys.length) {
+if (this._filterFn) {
+addedKeys = addedKeys.filter(function (a) {
+return this._filterFn(c.getItem(a));
+}, this);
+}
+addedKeys.sort(function (a, b) {
+return this._sortFn(c.getItem(a), c.getItem(b));
+}.bind(this));
+var start = 0;
+for (var i = 0; i < addedKeys.length; i++) {
+start = this._insertRowIntoViewSort(start, addedKeys[i], pool);
+}
+}
+},
+_insertRowIntoViewSort: function (start, key, pool) {
+var c = this.collection;
+var item = c.getItem(key);
+var end = this.rows.length - 1;
+var idx = -1;
+var sortFn = this._sortFn || this._keySort.bind(this);
+while (start <= end) {
+var mid = start + end >> 1;
+var midKey = this._orderedKeys[mid];
+var cmp = sortFn(c.getItem(midKey), item);
+if (cmp < 0) {
+start = mid + 1;
+} else if (cmp > 0) {
+end = mid - 1;
+} else {
+idx = mid;
+break;
+}
+}
+if (idx < 0) {
+idx = end + 1;
+}
+this._orderedKeys.splice(idx, 0, key);
+this.rows.splice(idx, 0, this._insertRow(idx, pool, c.getItem(key)));
+return idx;
+},
+_applySplicesArraySort: function (splices) {
+var keys = this._orderedKeys;
+var pool = [];
+splices.forEach(function (s) {
+for (var i = 0; i < s.removed.length; i++) {
+pool.push(this._detachRow(s.index + i));
+}
+this.rows.splice(s.index, s.removed.length);
+}, this);
+var c = this.collection;
+splices.forEach(function (s) {
+var args = [
+s.index,
+s.removed.length
+].concat(s.added);
+keys.splice.apply(keys, args);
+for (var i = 0; i < s.added.length; i++) {
+var item = c.getItem(s.added[i]);
+var row = this._insertRow(s.index + i, pool, item);
+this.rows.splice(s.index + i, 0, row);
+}
+}, this);
+},
+_detachRow: function (idx) {
+var row = this.rows[idx];
+var parentNode = Polymer.dom(this).parentNode;
+for (var i = 0; i < row._children.length; i++) {
+var el = row._children[i];
+Polymer.dom(row.root).appendChild(el);
+}
+return row;
+},
+_insertRow: function (idx, pool, item) {
+var row = pool && pool.pop() || this._generateRow(idx, item);
+var beforeRow = this.rows[idx];
+var beforeNode = beforeRow ? beforeRow._children[0] : this;
+var parentNode = Polymer.dom(this).parentNode;
+Polymer.dom(parentNode).insertBefore(row.root, beforeNode);
+return row;
+},
+_generateRow: function (idx, item) {
+var model = { __key__: this.collection.getKey(item) };
+model[this.as] = item;
+model[this.indexAs] = idx;
+var row = this.stamp(model);
+return row;
+},
+_showHideChildren: function (hidden) {
+if (this.rows) {
+for (var i = 0; i < this.rows.length; i++) {
+var c$ = this.rows[i]._children;
+for (var j = 0; j < c$.length; j++) {
+var c = c$[j];
+if (c.style) {
+c.style.display = hidden ? 'none' : '';
+}
+c._hideTemplateChildren = hidden;
+}
+}
+}
+},
+_forwardInstancePath: function (row, path, value) {
+if (path.indexOf(this.as + '.') === 0) {
+this.notifyPath('items.' + row.__key__ + '.' + path.slice(this.as.length + 1), value);
+return true;
+}
+},
+_forwardParentProp: function (prop, value) {
+if (this.rows) {
+this.rows.forEach(function (row) {
+row[prop] = value;
+}, this);
+}
+},
+_forwardParentPath: function (path, value) {
+if (this.rows) {
+this.rows.forEach(function (row) {
+row.notifyPath(path, value, true);
+}, this);
+}
+},
+_forwardItemPath: function (path, value) {
+if (this._rowForKey) {
+var dot = path.indexOf('.');
+var key = path.substring(0, dot < 0 ? path.length : dot);
+var idx = this._rowForKey[key];
+var row = this.rows[idx];
+if (row) {
+if (dot >= 0) {
+path = this.as + '.' + path.substring(dot + 1);
+row.notifyPath(path, value, true);
+} else {
+row[this.as] = value;
+}
+}
+}
+},
+modelForElement: function (el) {
+var model;
+while (el) {
+if (model = el._templateInstance) {
+if (model.dataHost != this) {
+el = model.dataHost;
+} else {
+return model;
+}
+} else {
+el = el.parentNode;
+}
+}
+},
+itemForElement: function (el) {
+var instance = this.modelForElement(el);
+return instance && instance[this.as];
+},
+keyForElement: function (el) {
+var instance = this.modelForElement(el);
+return instance && instance.__key__;
+},
+indexForElement: function (el) {
+var instance = this.modelForElement(el);
+return instance && instance[this.indexAs];
+}
+});
+Polymer({
+is: 'array-selector',
+properties: {
+items: {
+type: Array,
+observer: '_itemsChanged'
+},
+selected: {
+type: Object,
+notify: true
+},
+toggle: Boolean,
+multi: Boolean
+},
+_itemsChanged: function () {
+if (Array.isArray(this.selected)) {
+for (var i = 0; i < this.selected.length; i++) {
+this.unlinkPaths('selected.' + i);
+}
+} else {
+this.unlinkPaths('selected');
+}
+if (this.multi) {
+this.selected = [];
+} else {
+this.selected = null;
+}
+},
+deselect: function (item) {
+if (this.multi) {
+var scol = Polymer.Collection.get(this.selected);
+var sidx = this.selected.indexOf(item);
+if (sidx >= 0) {
+var skey = scol.getKey(item);
+this.splice('selected', sidx, 1);
+this.unlinkPaths('selected.' + skey);
+return true;
+}
+} else {
+this.selected = null;
+this.unlinkPaths('selected');
+}
+},
+select: function (item) {
+var icol = Polymer.Collection.get(this.items);
+var key = icol.getKey(item);
+if (this.multi) {
+var scol = Polymer.Collection.get(this.selected);
+var skey = scol.getKey(item);
+if (skey >= 0) {
+if (this.toggle) {
+this.deselect(item);
+}
+} else {
+this.push('selected', item);
+this.async(function () {
+skey = scol.getKey(item);
+this.linkPaths('selected.' + skey, 'items.' + key);
+});
+}
+} else {
+if (this.toggle && item == this.selected) {
+this.deselect();
+} else {
+this.linkPaths('selected', 'items.' + key);
+this.selected = item;
+}
+}
+}
+});
+Polymer({
+is: 'dom-if',
+extends: 'template',
+properties: {
+'if': {
+type: Boolean,
+value: false
+},
+restamp: {
+type: Boolean,
+value: false
+}
+},
+behaviors: [Polymer.Templatizer],
+observers: ['_queueRender(if, restamp)'],
+_queueRender: function () {
+this._debounceTemplate(this._render);
+},
+detached: function () {
+this._teardownInstance();
+},
+attached: function () {
+if (this.if && this.ctor) {
+this.async(this._ensureInstance);
+}
+},
+render: function () {
+this._flushTemplates();
+},
+_render: function () {
+if (this.if) {
+if (!this.ctor) {
+this._wrapTextNodes(this._content || this.content);
+this.templatize(this);
+}
+this._ensureInstance();
+this._showHideChildren();
+} else if (this.restamp) {
+this._teardownInstance();
+}
+if (!this.restamp && this._instance) {
+this._showHideChildren();
+}
+if (this.if != this._lastIf) {
+this.fire('dom-change');
+this._lastIf = this.if;
+}
+},
+_ensureInstance: function () {
+if (!this._instance) {
+this._instance = this.stamp();
+var root = this._instance.root;
+var parent = Polymer.dom(Polymer.dom(this).parentNode);
+parent.insertBefore(root, this);
+}
+},
+_teardownInstance: function () {
+if (this._instance) {
+var c = this._instance._children;
+if (c) {
+var parent = Polymer.dom(Polymer.dom(c[0]).parentNode);
+c.forEach(function (n) {
+parent.removeChild(n);
+});
+}
+this._instance = null;
+}
+},
+_wrapTextNodes: function (root) {
+for (var n = root.firstChild; n; n = n.nextSibling) {
+if (n.nodeType === Node.TEXT_NODE) {
+var s = document.createElement('span');
+root.insertBefore(s, n);
+s.appendChild(n);
+n = s;
+}
+}
+},
+_showHideChildren: function () {
+var hidden = this._hideTemplateChildren || !this.if;
+if (this._instance) {
+var c$ = this._instance._children;
+for (var i = 0; i < c$.length; i++) {
+var c = c$[i];
+c.style.display = hidden ? 'none' : '';
+c._hideTemplateChildren = hidden;
+}
+}
+},
+_forwardParentProp: function (prop, value) {
+if (this._instance) {
+this._instance[prop] = value;
+}
+},
+_forwardParentPath: function (path, value) {
+if (this._instance) {
+this._instance.notifyPath(path, value, true);
+}
+}
+});
+Polymer.ImportStatus = {
+_ready: false,
+_callbacks: [],
+whenLoaded: function (cb) {
+if (this._ready) {
+cb();
+} else {
+this._callbacks.push(cb);
+}
+},
+_importsLoaded: function () {
+this._ready = true;
+this._callbacks.forEach(function (cb) {
+cb();
+});
+this._callbacks = [];
+}
+};
+window.addEventListener('load', function () {
+Polymer.ImportStatus._importsLoaded();
+});
+if (window.HTMLImports) {
+HTMLImports.whenReady(function () {
+Polymer.ImportStatus._importsLoaded();
+});
+}
+Polymer({
+is: 'dom-bind',
+extends: 'template',
+created: function () {
+Polymer.ImportStatus.whenLoaded(this._readySelf.bind(this));
+},
+_registerFeatures: function () {
+this._prepExtends();
+this._prepConstructor();
+},
+_insertChildren: function () {
+var parentDom = Polymer.dom(Polymer.dom(this).parentNode);
+parentDom.insertBefore(this.root, this);
+},
+_removeChildren: function () {
+if (this._children) {
+for (var i = 0; i < this._children.length; i++) {
+this.root.appendChild(this._children[i]);
+}
+}
+},
+_initFeatures: function () {
+},
+_scopeElementClass: function (element, selector) {
+if (this.dataHost) {
+return this.dataHost._scopeElementClass(element, selector);
+} else {
+return selector;
+}
+},
+_prepConfigure: function () {
+var config = {};
+for (var prop in this._propertyEffects) {
+config[prop] = this[prop];
+}
+this._setupConfigure = this._setupConfigure.bind(this, config);
+},
+attached: function () {
+if (!this._children) {
+this._template = this;
+this._prepAnnotations();
+this._prepEffects();
+this._prepBehaviors();
+this._prepConfigure();
+this._prepBindings();
+Polymer.Base._initFeatures.call(this);
+this._children = Array.prototype.slice.call(this.root.childNodes);
+}
+this._insertChildren();
+this.fire('dom-change');
+},
+detached: function () {
+this._removeChildren();
+}
+});</script>
diff --git a/polymer_1.0.4/bower_components/prism-element/.bower.json b/polymer_1.0.4/bower_components/prism-element/.bower.json
new file mode 100644
index 0000000..d17f176
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism-element/.bower.json
@@ -0,0 +1,38 @@
+{
+ "name": "prism-element",
+ "description": "Prism.js import and syntax highlighting",
+ "version": "1.0.2",
+ "authors": [
+ "The Polymer Project Authors (https://polymer.github.io/AUTHORS.txt)"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "prism",
+ "molecule"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/prism-highlighter",
+ "main": "prism-highlighter.html",
+ "ignore": [
+ "/.*",
+ "/test/",
+ "/demo/"
+ ],
+ "dependencies": {
+ "prism": "*",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ },
+ "_release": "1.0.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.2",
+ "commit": "99b65dae91ef36fb009a5c277e924d84aa5e2672"
+ },
+ "_source": "git://github.com/PolymerElements/prism-element.git",
+ "_target": "^1.0.2",
+ "_originalSource": "PolymerElements/prism-element"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism-element/README.md b/polymer_1.0.4/bower_components/prism-element/README.md
new file mode 100644
index 0000000..db77712
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism-element/README.md
@@ -0,0 +1,13 @@
+# prism-element
+
+Syntax highlighting via [Prism](http://prismjs.com/).
+
+Place a `<prism-highlighter>` in your document, preferably as a direct child of
+`<body>`. It will listen for `syntax-highlight` events on its parent element,
+and annotate the code being provided via that event.
+
+The `syntax-highlight` event's detail is expected to have a `code` property
+containing the source to highlight. The event detail can optionally contain a
+`lang` property, containing a string like `"html"`, `"js"`, etc.
+
+This flow is supported by [`<marked-element>`](https://github.com/PolymerElements/marked-element).
diff --git a/polymer_1.0.4/bower_components/prism-element/bower.json b/polymer_1.0.4/bower_components/prism-element/bower.json
new file mode 100644
index 0000000..2ffca76
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism-element/bower.json
@@ -0,0 +1,29 @@
+{
+ "name": "prism-element",
+ "description": "Prism.js import and syntax highlighting",
+ "version": "1.0.2",
+ "authors": [
+ "The Polymer Project Authors (https://polymer.github.io/AUTHORS.txt)"
+ ],
+ "keywords": [
+ "web-components",
+ "polymer",
+ "prism",
+ "molecule"
+ ],
+ "license": "http://polymer.github.io/LICENSE.txt",
+ "homepage": "https://github.com/PolymerElements/prism-highlighter",
+ "main": "prism-highlighter.html",
+ "ignore": [
+ "/.*",
+ "/test/",
+ "/demo/"
+ ],
+ "dependencies": {
+ "prism": "*",
+ "polymer": "Polymer/polymer#^1.0.0"
+ },
+ "devDependencies": {
+ "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/prism-element/prism-highlighter.html b/polymer_1.0.4/bower_components/prism-element/prism-highlighter.html
new file mode 100644
index 0000000..dd4be81
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism-element/prism-highlighter.html
@@ -0,0 +1,95 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+
+<link rel="import" href="prism-import.html">
+
+<!--
+Syntax highlighting via [Prism](http://prismjs.com/).
+
+Place a `<prism-highlighter>` in your document, preferably as a direct child of
+`<body>`. It will listen for `syntax-highlight` events on its parent element,
+and annotate the code being provided via that event.
+
+The `syntax-highlight` event's detail is expected to have a `code` property
+containing the source to highlight. The event detail can optionally contain a
+`lang` property, containing a string like `"html"`, `"js"`, etc.
+
+This flow is supported by [`<marked-element>`](https://github.com/PolymerElements/marked-element).
+-->
+<script>
+(function() {
+
+ 'use strict';
+
+ var HIGHLIGHT_EVENT = 'syntax-highlight';
+
+ Polymer({
+
+ is: 'prism-highlighter',
+
+ ready: function() {
+ this._handler = this._highlight.bind(this);
+ },
+
+ attached: function() {
+ (this.parentElement || this.parentNode.host).addEventListener(HIGHLIGHT_EVENT, this._handler);
+ },
+
+ detached: function() {
+ (this.parentElement || this.parentNode.host).removeEventListener(HIGHLIGHT_EVENT, this._handler);
+ },
+
+ /**
+ * Handle the highlighting event, if we can.
+ *
+ * @param {!CustomEvent} event
+ */
+ _highlight: function(event) {
+ if (!event.detail || !event.detail.code) {
+ console.warn('Malformed', HIGHLIGHT_EVENT, 'event:', event.detail);
+ return;
+ }
+
+ var detail = event.detail;
+ detail.code = Prism.highlight(detail.code, this._detectLang(detail.code, detail.lang));
+ },
+
+ /**
+ * Picks a Prism formatter based on the `lang` hint and `code`.
+ *
+ * @param {string} code The source being highlighted.
+ * @param {string=} lang A language hint (e.g. ````LANG`).
+ * @return {!prism.Lang}
+ */
+ _detectLang: function(code, lang) {
+ if (!lang) {
+ // Stupid simple detection if we have no lang, courtesy of:
+ // https://github.com/robdodson/mark-down/blob/ac2eaa/mark-down.html#L93-101
+ return code.match(/^\s*</) ? Prism.languages.markup : Prism.languages.javascript;
+ }
+
+ if (lang === 'js' || lang.substr(0, 2) === 'es') {
+ return Prism.languages.javascript;
+ } else if (lang === 'css') {
+ return Prism.languages.css;
+ } else if (lang === 'c') {
+ return Prism.langauges.clike;
+ } else {
+ // The assumption is that you're mostly documenting HTML when in HTML.
+ return Prism.languages.markup;
+ }
+ },
+
+ });
+
+})();
+</script>
diff --git a/polymer_1.0.4/bower_components/prism-element/prism-import.html b/polymer_1.0.4/bower_components/prism-element/prism-import.html
new file mode 100644
index 0000000..98ecdeb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism-element/prism-import.html
@@ -0,0 +1,11 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+<script src="../prism/prism.js" data-manual></script>
+<link rel="stylesheet" href="../prism/themes/prism.css">
diff --git a/polymer_1.0.4/bower_components/prism/.bower.json b/polymer_1.0.4/bower_components/prism/.bower.json
new file mode 100644
index 0000000..bb51b30
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/.bower.json
@@ -0,0 +1,35 @@
+{
+ "name": "prism",
+ "version": "1.0.0",
+ "main": [
+ "prism.js",
+ "themes/prism.css"
+ ],
+ "homepage": "http://prismjs.com",
+ "authors": "Lea Verou",
+ "description": "Lightweight, robust, elegant syntax highlighting. A spin-off project from Dabblet.",
+ "license": "MIT",
+ "ignore": [
+ "**/.*",
+ "img",
+ "templates",
+ "CNAME",
+ "*.html",
+ "style.css",
+ "favicon.png",
+ "logo.svg",
+ "download.js",
+ "prefixfree.min.js",
+ "utopia.js",
+ "code.js"
+ ],
+ "_release": "1.0.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.0",
+ "commit": "534f34cd35526481e4a32ac4d1eaf447a5a64bf2"
+ },
+ "_source": "git://github.com/LeaVerou/prism.git",
+ "_target": "*",
+ "_originalSource": "prism"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/LICENSE b/polymer_1.0.4/bower_components/prism/LICENSE
new file mode 100644
index 0000000..eab2c31
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/LICENSE
@@ -0,0 +1,21 @@
+MIT LICENSE
+
+Copyright (c) 2012-2013 Lea Verou
+
+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.
diff --git a/polymer_1.0.4/bower_components/prism/README.md b/polymer_1.0.4/bower_components/prism/README.md
new file mode 100644
index 0000000..3c97a68
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/README.md
@@ -0,0 +1,22 @@
+# [Prism](http://prismjs.com/)
+
+Prism is a lightweight, robust, elegant syntax highlighting library. It's a spin-off project from [Dabblet](http://dabblet.com/).
+
+You can learn more on http://prismjs.com/.
+
+Why another syntax highlighter?: http://lea.verou.me/2012/07/introducing-prism-an-awesome-new-syntax-highlighter/#more-1841
+
+## Contribute to Prism!
+
+Prism depends on community contributions to expand and cover a wider array of use cases. If you like it, considering giving back by sending a pull request. Here are a few tips:
+
+- Read the [documentation](http://prismjs.com/extending.html). Prism was designed to be extensible.
+- Do not edit prism.js, it’s just the version of Prism used by the Prism website and is built automatically. Limit your changes to the unminified files in the components/ folder. The minified files are also generated automatically.
+- Currently the build system building prism.js and the minified files is just a bunch of local settings in CodeKit. If someone wants to help export them to a config file, please contact me by opening an issue.
+- Please follow the code conventions used in the files already. For example, I use [tabs for indentation and spaces for alignment](http://lea.verou.me/2012/01/why-tabs-are-clearly-superior/). Opening braces are on the same line, closing braces on their own line regardless of construct. There is a space before the opening brace. etc etc.
+- Please try to err towards more smaller PRs rather than few huge PRs. If a PR includes changes I want to merge and changes I don't, handling it becomes difficult.
+- My time is very limited these days, so it might take a long time to review longer PRs (short ones are usually merged very quickly), especially those modifying the Prism Core. This doesn't mean your PR is rejected.
+- If you contribute a new language definition, you will be responsible for handling bug reports about that language definition. Soon I plan to add usernames of project owners for themes, plugins and language definitions so this becomes more clear to users.
+- If you add a new language definition, theme or plugin, you need to add it to `components.js` as well, so that it becomes available to the download build page.
+
+Thank you so much for contributing!!
diff --git a/polymer_1.0.4/bower_components/prism/bower.json b/polymer_1.0.4/bower_components/prism/bower.json
new file mode 100644
index 0000000..822afac
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/bower.json
@@ -0,0 +1,26 @@
+{
+ "name": "prism",
+ "version": "0.0.1",
+ "main": [
+ "prism.js",
+ "themes/prism.css"
+ ],
+ "homepage": "http://prismjs.com",
+ "authors": "Lea Verou",
+ "description": "Lightweight, robust, elegant syntax highlighting. A spin-off project from Dabblet.",
+ "license": "MIT",
+ "ignore": [
+ "**/.*",
+ "img",
+ "templates",
+ "CNAME",
+ "*.html",
+ "style.css",
+ "favicon.png",
+ "logo.svg",
+ "download.js",
+ "prefixfree.min.js",
+ "utopia.js",
+ "code.js"
+ ]
+}
diff --git a/polymer_1.0.4/bower_components/prism/components.js b/polymer_1.0.4/bower_components/prism/components.js
new file mode 100644
index 0000000..7be1869
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components.js
@@ -0,0 +1,362 @@
+var components = {
+ "core": {
+ "meta": {
+ "path": "components/prism-core.js",
+ "option": "mandatory"
+ },
+ "core": "Core"
+ },
+ "themes": {
+ "meta": {
+ "path": "themes/{id}.css",
+ "link": "index.html?theme={id}",
+ "exclusive": true
+ },
+ "prism": {
+ "title": "Default",
+ "option": "default"
+ },
+ "prism-dark": "Dark",
+ "prism-funky": "Funky",
+ "prism-okaidia": {
+ "title": "Okaidia",
+ "owner": "ocodia"
+ },
+ "prism-twilight": {
+ "title": "Twilight",
+ "owner": "remybach"
+ },
+ "prism-coy": {
+ "title": "Coy",
+ "owner": "tshedor"
+ }
+ },
+ "languages": {
+ "meta": {
+ "path": "components/prism-{id}",
+ "noCSS": true,
+ "examplesPath": "examples/prism-{id}"
+ },
+ "markup": {
+ "title": "Markup",
+ "option": "default"
+ },
+ "css": {
+ "title": "CSS",
+ "option": "default"
+ },
+ "clike": {
+ "title": "C-like",
+ "option": "default"
+ },
+ "javascript": {
+ "title": "JavaScript",
+ "option": "default",
+ "require": "clike"
+ },
+
+ // ---
+
+ "actionscript": {
+ "title": "ActionScript",
+ "require": "javascript",
+ "owner": "Golmote"
+ },
+ "apacheconf": {
+ "title": "Apache Configuration",
+ "owner": "GuiTeK"
+ },
+ "applescript": {
+ "title": "AppleScript",
+ "owner": "Golmote"
+ },
+ "aspnet": {
+ "title": "ASP.NET (C#)",
+ "require": "markup",
+ "owner": "nauzilus"
+ },
+ "autohotkey": {
+ "title": "AutoHotkey",
+ "owner": "aviaryan"
+ },
+ "bash": {
+ "title": "Bash",
+ "require": "clike",
+ "owner": "zeitgeist87"
+ },
+ "c": {
+ "title": "C",
+ "require": "clike",
+ "owner": "zeitgeist87"
+ },
+ "csharp": {
+ "title": "C#",
+ "require": "clike",
+ "owner": "mvalipour"
+ },
+ "cpp": {
+ "title": "C++",
+ "require": "c",
+ "owner": "zeitgeist87"
+ },
+ "coffeescript": {
+ "title": "CoffeeScript",
+ "require": "javascript",
+ "owner": "R-osey"
+ },
+ "css-extras": {
+ "title": "CSS Extras",
+ "require": "css",
+ "owner": "milesj"
+ },
+ "dart": {
+ "title": "Dart",
+ "require": "clike",
+ "owner": "Golmote"
+ },
+ "eiffel": {
+ "title": "Eiffel",
+ "owner": "Conaclos"
+ },
+ "erlang": {
+ "title": "Erlang",
+ "owner": "Golmote"
+ },
+ "fsharp": {
+ "title": "F#",
+ "require": "clike",
+ "owner": "simonreynolds7"
+ },
+ "fortran": {
+ "title": "Fortran",
+ "owner": "Golmote"
+ },
+ "gherkin": {
+ "title": "Gherkin",
+ "owner": "hason"
+ },
+ "git": {
+ "title": "Git",
+ "owner": "lgiraudel"
+ },
+ "go": {
+ "title": "Go",
+ "require": "clike",
+ "owner": "arnehormann"
+ },
+ "groovy": {
+ "title": "Groovy",
+ "require": "clike",
+ "owner": "robfletcher"
+ },
+ "haml": {
+ "title": "Haml",
+ "require": "ruby",
+ "owner": "Golmote"
+ },
+ "handlebars": {
+ "title": "Handlebars",
+ "require": "markup",
+ "owner": "Golmote"
+ },
+ "haskell": {
+ "title": "Haskell",
+ "owner": "bholst"
+ },
+ "http": {
+ "title": "HTTP",
+ "owner": "danielgtaylor"
+ },
+ "ini": {
+ "title": "Ini",
+ "owner": "aviaryan"
+ },
+ "jade": {
+ "title": "Jade",
+ "require": "javascript",
+ "owner": "Golmote"
+ },
+ "java": {
+ "title": "Java",
+ "require": "clike",
+ "owner": "sherblot"
+ },
+ "julia": {
+ "title": "Julia",
+ "owner": "cdagnino"
+ },
+ "latex": {
+ "title": "LaTeX",
+ "owner": "japborst"
+ },
+ "less": {
+ "title": "Less",
+ "require": "css",
+ "owner": "Golmote"
+ },
+ "lolcode": {
+ "title": "LOLCODE",
+ "owner": "Golmote"
+ },
+ "markdown": {
+ "title": "Markdown",
+ "require": "markup",
+ "owner": "Golmote"
+ },
+ "matlab": {
+ "title": "MATLAB",
+ "owner": "Golmote"
+ },
+ "nasm": {
+ "title": "NASM",
+ "owner": "rbmj"
+ },
+ "nsis": {
+ "title": "NSIS",
+ "owner": "idleberg"
+ },
+ "objectivec": {
+ "title": "Objective-C",
+ "require": "c",
+ "owner": "uranusjr"
+ },
+ "pascal": {
+ "title": "Pascal",
+ "owner": "Golmote"
+ },
+ "perl": {
+ "title": "Perl",
+ "owner": "Golmote"
+ },
+ "php": {
+ "title": "PHP",
+ "require": "clike",
+ "owner": "milesj"
+ },
+ "php-extras": {
+ "title": "PHP Extras",
+ "require": "php",
+ "owner": "milesj"
+ },
+ "powershell": {
+ "title": "PowerShell",
+ "owner": "nauzilus"
+ },
+ "python": {
+ "title": "Python",
+ "owner": "multipetros"
+ },
+ "r": {
+ "title": "R",
+ "owner": "Golmote"
+ },
+ "jsx":{
+ "title": "React JSX",
+ "require": ["markup", "javascript"],
+ "owner": "vkbansal"
+ },
+ "rest": {
+ "title": "reST (reStructuredText)",
+ "owner": "Golmote"
+ },
+ "rip": {
+ "title": "Rip",
+ "owner": "ravinggenius"
+ },
+ "ruby": {
+ "title": "Ruby",
+ "require": "clike",
+ "owner": "samflores"
+ },
+ "rust": {
+ "title": "Rust",
+ "owner": "Golmote"
+ },
+ "sas": {
+ "title": "SAS",
+ "owner": "Golmote"
+ },
+ "scss": {
+ "title": "Sass (Scss)",
+ "require": "css",
+ "owner": "MoOx"
+ },
+ "scala": {
+ "title": "Scala",
+ "require": "java",
+ "owner": "jozic"
+ },
+ "scheme" : {
+ "title": "Scheme",
+ "owner" : "bacchus123"
+ },
+ "smalltalk": {
+ "title": "Smalltalk",
+ "owner": "Golmote"
+ },
+ "smarty": {
+ "title": "Smarty",
+ "require": "markup",
+ "owner": "Golmote"
+ },
+ "sql": {
+ "title": "SQL",
+ "owner": "multipetros"
+ },
+ "stylus" : {
+ "title": "Stylus",
+ "owner": "vkbansal"
+ },
+ "swift": {
+ "title": "Swift",
+ "require": "clike",
+ "owner": "chrischares"
+ },
+ "twig": {
+ "title": "Twig",
+ "require": "markup",
+ "owner": "brandonkelly"
+ },
+ "typescript":{
+ "title": "TypeScript",
+ "require": "javascript",
+ "owner": "vkbansal"
+ },
+ "wiki": {
+ "title": "Wiki markup",
+ "require": "markup",
+ "owner": "Golmote"
+ },
+ "yaml": {
+ "title": "YAML",
+ "owner": "hason"
+ }
+ },
+ "plugins": {
+ "meta": {
+ "path": "plugins/{id}/prism-{id}",
+ "link": "plugins/{id}/"
+ },
+ "line-highlight": "Line Highlight",
+ "line-numbers": {
+ "title": "Line Numbers",
+ "owner": "kuba-kubula"
+ },
+ "show-invisibles": "Show Invisibles",
+ "autolinker": "Autolinker",
+ "wpd": "WebPlatform Docs",
+ "file-highlight": {
+ "title": "File Highlight",
+ "noCSS": true
+ },
+ "show-language": {
+ "title": "Show Language",
+ "owner": "nauzilus"
+ },
+ "highlight-keywords": {
+ "title": "Highlight Keywords",
+ "owner": "vkbansal",
+ "noCSS": true
+ }
+ }
+};
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-actionscript.js b/polymer_1.0.4/bower_components/prism/components/prism-actionscript.js
new file mode 100644
index 0000000..66b3f72
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-actionscript.js
@@ -0,0 +1,20 @@
+/* TODO
+ Fix XML highlighting
+ */
+
+Prism.languages.actionscript = Prism.languages.extend('javascript', {
+ 'keyword': /\b(?:as|break|case|catch|class|const|default|delete|do|else|extends|finally|for|function|if|implements|import|in|instanceof|interface|internal|is|native|new|null|package|private|protected|public|return|super|switch|this|throw|try|typeof|use|var|void|while|with|dynamic|each|final|get|include|namespace|native|override|set|static)\b/,
+ 'operator': /(?:[+\-*\/%^]|&&?|\|\|?|<<?|>>?>?|[!=]=)=?|[=~?@]/
+});
+Prism.languages.actionscript['class-name'].alias = 'function';
+
+if (Prism.languages.markup) {
+ Prism.languages.insertBefore('actionscript', 'operator', {
+ 'xml': {
+ pattern: /(^|[^.])<[\s\S]*>(?=\s*($|[\r\n,.;\]})<]))/,
+ inside: {
+ rest: Prism.languages.markup
+ }
+ }
+ });
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-actionscript.min.js b/polymer_1.0.4/bower_components/prism/components/prism-actionscript.min.js
new file mode 100644
index 0000000..cbe958c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-actionscript.min.js
@@ -0,0 +1 @@
+Prism.languages.actionscript=Prism.languages.extend("javascript",{keyword:/\b(?:as|break|case|catch|class|const|default|delete|do|else|extends|finally|for|function|if|implements|import|in|instanceof|interface|internal|is|native|new|null|package|private|protected|public|return|super|switch|this|throw|try|typeof|use|var|void|while|with|dynamic|each|final|get|include|namespace|native|override|set|static)\b/,operator:/(?:[+\-*\/%^]|&&?|\|\|?|<<?|>>?>?|[!=]=)=?|[=~?@]/}),Prism.languages.actionscript["class-name"].alias="function",Prism.languages.markup&&Prism.languages.insertBefore("actionscript","operator",{xml:{pattern:/(^|[^.])<[\s\S]*>(?=\s*($|[\r\n,.;\]})<]))/,inside:{rest:Prism.languages.markup}}});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-apacheconf.js b/polymer_1.0.4/bower_components/prism/components/prism-apacheconf.js
new file mode 100644
index 0000000..8fac6df
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-apacheconf.js
@@ -0,0 +1,46 @@
+Prism.languages.apacheconf = {
+ 'comment': /#.*/,
+ 'directive-inline': {
+ pattern: /^\s*\b(AcceptFilter|AcceptPathInfo|AccessFileName|Action|AddAlt|AddAltByEncoding|AddAltByType|AddCharset|AddDefaultCharset|AddDescription|AddEncoding|AddHandler|AddIcon|AddIconByEncoding|AddIconByType|AddInputFilter|AddLanguage|AddModuleInfo|AddOutputFilter|AddOutputFilterByType|AddType|Alias|AliasMatch|Allow|AllowCONNECT|AllowEncodedSlashes|AllowMethods|AllowOverride|AllowOverrideList|Anonymous|Anonymous_LogEmail|Anonymous_MustGiveEmail|Anonymous_NoUserID|Anonymous_VerifyEmail|AsyncRequestWorkerFactor|AuthBasicAuthoritative|AuthBasicFake|AuthBasicProvider|AuthBasicUseDigestAlgorithm|AuthDBDUserPWQuery|AuthDBDUserRealmQuery|AuthDBMGroupFile|AuthDBMType|AuthDBMUserFile|AuthDigestAlgorithm|AuthDigestDomain|AuthDigestNonceLifetime|AuthDigestProvider|AuthDigestQop|AuthDigestShmemSize|AuthFormAuthoritative|AuthFormBody|AuthFormDisableNoStore|AuthFormFakeBasicAuth|AuthFormLocation|AuthFormLoginRequiredLocation|AuthFormLoginSuccessLocation|AuthFormLogoutLocation|AuthFormMethod|AuthFormMimetype|AuthFormPassword|AuthFormProvider|AuthFormSitePassphrase|AuthFormSize|AuthFormUsername|AuthGroupFile|AuthLDAPAuthorizePrefix|AuthLDAPBindAuthoritative|AuthLDAPBindDN|AuthLDAPBindPassword|AuthLDAPCharsetConfig|AuthLDAPCompareAsUser|AuthLDAPCompareDNOnServer|AuthLDAPDereferenceAliases|AuthLDAPGroupAttribute|AuthLDAPGroupAttributeIsDN|AuthLDAPInitialBindAsUser|AuthLDAPInitialBindPattern|AuthLDAPMaxSubGroupDepth|AuthLDAPRemoteUserAttribute|AuthLDAPRemoteUserIsDN|AuthLDAPSearchAsUser|AuthLDAPSubGroupAttribute|AuthLDAPSubGroupClass|AuthLDAPUrl|AuthMerging|AuthName|AuthnCacheContext|AuthnCacheEnable|AuthnCacheProvideFor|AuthnCacheSOCache|AuthnCacheTimeout|AuthnzFcgiCheckAuthnProvider|AuthnzFcgiDefineProvider|AuthType|AuthUserFile|AuthzDBDLoginToReferer|AuthzDBDQuery|AuthzDBDRedirectQuery|AuthzDBMType|AuthzSendForbiddenOnFailure|BalancerGrowth|BalancerInherit|BalancerMember|BalancerPersist|BrowserMatch|BrowserMatchNoCase|BufferedLogs|BufferSize|CacheDefaultExpire|CacheDetailHeader|CacheDirLength|CacheDirLevels|CacheDisable|CacheEnable|CacheFile|CacheHeader|CacheIgnoreCacheControl|CacheIgnoreHeaders|CacheIgnoreNoLastMod|CacheIgnoreQueryString|CacheIgnoreURLSessionIdentifiers|CacheKeyBaseURL|CacheLastModifiedFactor|CacheLock|CacheLockMaxAge|CacheLockPath|CacheMaxExpire|CacheMaxFileSize|CacheMinExpire|CacheMinFileSize|CacheNegotiatedDocs|CacheQuickHandler|CacheReadSize|CacheReadTime|CacheRoot|CacheSocache|CacheSocacheMaxSize|CacheSocacheMaxTime|CacheSocacheMinTime|CacheSocacheReadSize|CacheSocacheReadTime|CacheStaleOnError|CacheStoreExpired|CacheStoreNoStore|CacheStorePrivate|CGIDScriptTimeout|CGIMapExtension|CharsetDefault|CharsetOptions|CharsetSourceEnc|CheckCaseOnly|CheckSpelling|ChrootDir|ContentDigest|CookieDomain|CookieExpires|CookieName|CookieStyle|CookieTracking|CoreDumpDirectory|CustomLog|Dav|DavDepthInfinity|DavGenericLockDB|DavLockDB|DavMinTimeout|DBDExptime|DBDInitSQL|DBDKeep|DBDMax|DBDMin|DBDParams|DBDPersist|DBDPrepareSQL|DBDriver|DefaultIcon|DefaultLanguage|DefaultRuntimeDir|DefaultType|Define|DeflateBufferSize|DeflateCompressionLevel|DeflateFilterNote|DeflateInflateLimitRequestBody|DeflateInflateRatioBurst|DeflateInflateRatioLimit|DeflateMemLevel|DeflateWindowSize|Deny|DirectoryCheckHandler|DirectoryIndex|DirectoryIndexRedirect|DirectorySlash|DocumentRoot|DTracePrivileges|DumpIOInput|DumpIOOutput|EnableExceptionHook|EnableMMAP|EnableSendfile|Error|ErrorDocument|ErrorLog|ErrorLogFormat|Example|ExpiresActive|ExpiresByType|ExpiresDefault|ExtendedStatus|ExtFilterDefine|ExtFilterOptions|FallbackResource|FileETag|FilterChain|FilterDeclare|FilterProtocol|FilterProvider|FilterTrace|ForceLanguagePriority|ForceType|ForensicLog|GprofDir|GracefulShutdownTimeout|Group|Header|HeaderName|HeartbeatAddress|HeartbeatListen|HeartbeatMaxServers|HeartbeatStorage|HeartbeatStorage|HostnameLookups|IdentityCheck|IdentityCheckTimeout|ImapBase|ImapDefault|ImapMenu|Include|IncludeOptional|IndexHeadInsert|IndexIgnore|IndexIgnoreReset|IndexOptions|IndexOrderDefault|IndexStyleSheet|InputSed|ISAPIAppendLogToErrors|ISAPIAppendLogToQuery|ISAPICacheFile|ISAPIFakeAsync|ISAPILogNotSupported|ISAPIReadAheadBuffer|KeepAlive|KeepAliveTimeout|KeptBodySize|LanguagePriority|LDAPCacheEntries|LDAPCacheTTL|LDAPConnectionPoolTTL|LDAPConnectionTimeout|LDAPLibraryDebug|LDAPOpCacheEntries|LDAPOpCacheTTL|LDAPReferralHopLimit|LDAPReferrals|LDAPRetries|LDAPRetryDelay|LDAPSharedCacheFile|LDAPSharedCacheSize|LDAPTimeout|LDAPTrustedClientCert|LDAPTrustedGlobalCert|LDAPTrustedMode|LDAPVerifyServerCert|LimitInternalRecursion|LimitRequestBody|LimitRequestFields|LimitRequestFieldSize|LimitRequestLine|LimitXMLRequestBody|Listen|ListenBackLog|LoadFile|LoadModule|LogFormat|LogLevel|LogMessage|LuaAuthzProvider|LuaCodeCache|LuaHookAccessChecker|LuaHookAuthChecker|LuaHookCheckUserID|LuaHookFixups|LuaHookInsertFilter|LuaHookLog|LuaHookMapToStorage|LuaHookTranslateName|LuaHookTypeChecker|LuaInherit|LuaInputFilter|LuaMapHandler|LuaOutputFilter|LuaPackageCPath|LuaPackagePath|LuaQuickHandler|LuaRoot|LuaScope|MaxConnectionsPerChild|MaxKeepAliveRequests|MaxMemFree|MaxRangeOverlaps|MaxRangeReversals|MaxRanges|MaxRequestWorkers|MaxSpareServers|MaxSpareThreads|MaxThreads|MergeTrailers|MetaDir|MetaFiles|MetaSuffix|MimeMagicFile|MinSpareServers|MinSpareThreads|MMapFile|ModemStandard|ModMimeUsePathInfo|MultiviewsMatch|Mutex|NameVirtualHost|NoProxy|NWSSLTrustedCerts|NWSSLUpgradeable|Options|Order|OutputSed|PassEnv|PidFile|PrivilegesMode|Protocol|ProtocolEcho|ProxyAddHeaders|ProxyBadHeader|ProxyBlock|ProxyDomain|ProxyErrorOverride|ProxyExpressDBMFile|ProxyExpressDBMType|ProxyExpressEnable|ProxyFtpDirCharset|ProxyFtpEscapeWildcards|ProxyFtpListOnWildcard|ProxyHTMLBufSize|ProxyHTMLCharsetOut|ProxyHTMLDocType|ProxyHTMLEnable|ProxyHTMLEvents|ProxyHTMLExtended|ProxyHTMLFixups|ProxyHTMLInterp|ProxyHTMLLinks|ProxyHTMLMeta|ProxyHTMLStripComments|ProxyHTMLURLMap|ProxyIOBufferSize|ProxyMaxForwards|ProxyPass|ProxyPassInherit|ProxyPassInterpolateEnv|ProxyPassMatch|ProxyPassReverse|ProxyPassReverseCookieDomain|ProxyPassReverseCookiePath|ProxyPreserveHost|ProxyReceiveBufferSize|ProxyRemote|ProxyRemoteMatch|ProxyRequests|ProxySCGIInternalRedirect|ProxySCGISendfile|ProxySet|ProxySourceAddress|ProxyStatus|ProxyTimeout|ProxyVia|ReadmeName|ReceiveBufferSize|Redirect|RedirectMatch|RedirectPermanent|RedirectTemp|ReflectorHeader|RemoteIPHeader|RemoteIPInternalProxy|RemoteIPInternalProxyList|RemoteIPProxiesHeader|RemoteIPTrustedProxy|RemoteIPTrustedProxyList|RemoveCharset|RemoveEncoding|RemoveHandler|RemoveInputFilter|RemoveLanguage|RemoveOutputFilter|RemoveType|RequestHeader|RequestReadTimeout|Require|RewriteBase|RewriteCond|RewriteEngine|RewriteMap|RewriteOptions|RewriteRule|RLimitCPU|RLimitMEM|RLimitNPROC|Satisfy|ScoreBoardFile|Script|ScriptAlias|ScriptAliasMatch|ScriptInterpreterSource|ScriptLog|ScriptLogBuffer|ScriptLogLength|ScriptSock|SecureListen|SeeRequestTail|SendBufferSize|ServerAdmin|ServerAlias|ServerLimit|ServerName|ServerPath|ServerRoot|ServerSignature|ServerTokens|Session|SessionCookieName|SessionCookieName2|SessionCookieRemove|SessionCryptoCipher|SessionCryptoDriver|SessionCryptoPassphrase|SessionCryptoPassphraseFile|SessionDBDCookieName|SessionDBDCookieName2|SessionDBDCookieRemove|SessionDBDDeleteLabel|SessionDBDInsertLabel|SessionDBDPerUser|SessionDBDSelectLabel|SessionDBDUpdateLabel|SessionEnv|SessionExclude|SessionHeader|SessionInclude|SessionMaxAge|SetEnv|SetEnvIf|SetEnvIfExpr|SetEnvIfNoCase|SetHandler|SetInputFilter|SetOutputFilter|SSIEndTag|SSIErrorMsg|SSIETag|SSILastModified|SSILegacyExprParser|SSIStartTag|SSITimeFormat|SSIUndefinedEcho|SSLCACertificateFile|SSLCACertificatePath|SSLCADNRequestFile|SSLCADNRequestPath|SSLCARevocationCheck|SSLCARevocationFile|SSLCARevocationPath|SSLCertificateChainFile|SSLCertificateFile|SSLCertificateKeyFile|SSLCipherSuite|SSLCompression|SSLCryptoDevice|SSLEngine|SSLFIPS|SSLHonorCipherOrder|SSLInsecureRenegotiation|SSLOCSPDefaultResponder|SSLOCSPEnable|SSLOCSPOverrideResponder|SSLOCSPResponderTimeout|SSLOCSPResponseMaxAge|SSLOCSPResponseTimeSkew|SSLOCSPUseRequestNonce|SSLOpenSSLConfCmd|SSLOptions|SSLPassPhraseDialog|SSLProtocol|SSLProxyCACertificateFile|SSLProxyCACertificatePath|SSLProxyCARevocationCheck|SSLProxyCARevocationFile|SSLProxyCARevocationPath|SSLProxyCheckPeerCN|SSLProxyCheckPeerExpire|SSLProxyCheckPeerName|SSLProxyCipherSuite|SSLProxyEngine|SSLProxyMachineCertificateChainFile|SSLProxyMachineCertificateFile|SSLProxyMachineCertificatePath|SSLProxyProtocol|SSLProxyVerify|SSLProxyVerifyDepth|SSLRandomSeed|SSLRenegBufferSize|SSLRequire|SSLRequireSSL|SSLSessionCache|SSLSessionCacheTimeout|SSLSessionTicketKeyFile|SSLSRPUnknownUserSeed|SSLSRPVerifierFile|SSLStaplingCache|SSLStaplingErrorCacheTimeout|SSLStaplingFakeTryLater|SSLStaplingForceURL|SSLStaplingResponderTimeout|SSLStaplingResponseMaxAge|SSLStaplingResponseTimeSkew|SSLStaplingReturnResponderErrors|SSLStaplingStandardCacheTimeout|SSLStrictSNIVHostCheck|SSLUserName|SSLUseStapling|SSLVerifyClient|SSLVerifyDepth|StartServers|StartThreads|Substitute|Suexec|SuexecUserGroup|ThreadLimit|ThreadsPerChild|ThreadStackSize|TimeOut|TraceEnable|TransferLog|TypesConfig|UnDefine|UndefMacro|UnsetEnv|Use|UseCanonicalName|UseCanonicalPhysicalPort|User|UserDir|VHostCGIMode|VHostCGIPrivs|VHostGroup|VHostPrivs|VHostSecure|VHostUser|VirtualDocumentRoot|VirtualDocumentRootIP|VirtualScriptAlias|VirtualScriptAliasIP|WatchdogInterval|XBitHack|xml2EncAlias|xml2EncDefault|xml2StartParse)\b/mi,
+ alias: 'property'
+ },
+ 'directive-block': {
+ pattern: /<\/?\b(AuthnProviderAlias|AuthzProviderAlias|Directory|DirectoryMatch|Else|ElseIf|Files|FilesMatch|If|IfDefine|IfModule|IfVersion|Limit|LimitExcept|Location|LocationMatch|Macro|Proxy|RequireAll|RequireAny|RequireNone|VirtualHost)\b *.*>/i,
+ inside: {
+ 'directive-block': {
+ pattern: /^<\/?\w+/,
+ inside: {
+ 'punctuation': /^<\/?/
+ },
+ alias: 'tag'
+ },
+ 'directive-block-parameter': {
+ pattern: /.*[^>]/,
+ inside: {
+ 'punctuation': /:/,
+ 'string': {
+ pattern: /("|').*\1/,
+ inside: {
+ 'variable': /(\$|%)\{?(\w\.?(\+|\-|:)?)+\}?/
+ }
+ }
+ },
+ alias: 'attr-value'
+ },
+ 'punctuation': />/
+ },
+ alias: 'tag'
+ },
+ 'directive-flags': {
+ pattern: /\[(\w,?)+\]/,
+ alias: 'keyword'
+ },
+ 'string': {
+ pattern: /("|').*\1/,
+ inside: {
+ 'variable': /(\$|%)\{?(\w\.?(\+|\-|:)?)+\}?/
+ }
+ },
+ 'variable': /(\$|%)\{?(\w\.?(\+|\-|:)?)+\}?/,
+ 'regex': /\^?.*\$|\^.*\$?/
+};
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-apacheconf.min.js b/polymer_1.0.4/bower_components/prism/components/prism-apacheconf.min.js
new file mode 100644
index 0000000..6ccefa7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-apacheconf.min.js
@@ -0,0 +1 @@
+Prism.languages.apacheconf={comment:/#.*/,"directive-inline":{pattern:/^\s*\b(AcceptFilter|AcceptPathInfo|AccessFileName|Action|AddAlt|AddAltByEncoding|AddAltByType|AddCharset|AddDefaultCharset|AddDescription|AddEncoding|AddHandler|AddIcon|AddIconByEncoding|AddIconByType|AddInputFilter|AddLanguage|AddModuleInfo|AddOutputFilter|AddOutputFilterByType|AddType|Alias|AliasMatch|Allow|AllowCONNECT|AllowEncodedSlashes|AllowMethods|AllowOverride|AllowOverrideList|Anonymous|Anonymous_LogEmail|Anonymous_MustGiveEmail|Anonymous_NoUserID|Anonymous_VerifyEmail|AsyncRequestWorkerFactor|AuthBasicAuthoritative|AuthBasicFake|AuthBasicProvider|AuthBasicUseDigestAlgorithm|AuthDBDUserPWQuery|AuthDBDUserRealmQuery|AuthDBMGroupFile|AuthDBMType|AuthDBMUserFile|AuthDigestAlgorithm|AuthDigestDomain|AuthDigestNonceLifetime|AuthDigestProvider|AuthDigestQop|AuthDigestShmemSize|AuthFormAuthoritative|AuthFormBody|AuthFormDisableNoStore|AuthFormFakeBasicAuth|AuthFormLocation|AuthFormLoginRequiredLocation|AuthFormLoginSuccessLocation|AuthFormLogoutLocation|AuthFormMethod|AuthFormMimetype|AuthFormPassword|AuthFormProvider|AuthFormSitePassphrase|AuthFormSize|AuthFormUsername|AuthGroupFile|AuthLDAPAuthorizePrefix|AuthLDAPBindAuthoritative|AuthLDAPBindDN|AuthLDAPBindPassword|AuthLDAPCharsetConfig|AuthLDAPCompareAsUser|AuthLDAPCompareDNOnServer|AuthLDAPDereferenceAliases|AuthLDAPGroupAttribute|AuthLDAPGroupAttributeIsDN|AuthLDAPInitialBindAsUser|AuthLDAPInitialBindPattern|AuthLDAPMaxSubGroupDepth|AuthLDAPRemoteUserAttribute|AuthLDAPRemoteUserIsDN|AuthLDAPSearchAsUser|AuthLDAPSubGroupAttribute|AuthLDAPSubGroupClass|AuthLDAPUrl|AuthMerging|AuthName|AuthnCacheContext|AuthnCacheEnable|AuthnCacheProvideFor|AuthnCacheSOCache|AuthnCacheTimeout|AuthnzFcgiCheckAuthnProvider|AuthnzFcgiDefineProvider|AuthType|AuthUserFile|AuthzDBDLoginToReferer|AuthzDBDQuery|AuthzDBDRedirectQuery|AuthzDBMType|AuthzSendForbiddenOnFailure|BalancerGrowth|BalancerInherit|BalancerMember|BalancerPersist|BrowserMatch|BrowserMatchNoCase|BufferedLogs|BufferSize|CacheDefaultExpire|CacheDetailHeader|CacheDirLength|CacheDirLevels|CacheDisable|CacheEnable|CacheFile|CacheHeader|CacheIgnoreCacheControl|CacheIgnoreHeaders|CacheIgnoreNoLastMod|CacheIgnoreQueryString|CacheIgnoreURLSessionIdentifiers|CacheKeyBaseURL|CacheLastModifiedFactor|CacheLock|CacheLockMaxAge|CacheLockPath|CacheMaxExpire|CacheMaxFileSize|CacheMinExpire|CacheMinFileSize|CacheNegotiatedDocs|CacheQuickHandler|CacheReadSize|CacheReadTime|CacheRoot|CacheSocache|CacheSocacheMaxSize|CacheSocacheMaxTime|CacheSocacheMinTime|CacheSocacheReadSize|CacheSocacheReadTime|CacheStaleOnError|CacheStoreExpired|CacheStoreNoStore|CacheStorePrivate|CGIDScriptTimeout|CGIMapExtension|CharsetDefault|CharsetOptions|CharsetSourceEnc|CheckCaseOnly|CheckSpelling|ChrootDir|ContentDigest|CookieDomain|CookieExpires|CookieName|CookieStyle|CookieTracking|CoreDumpDirectory|CustomLog|Dav|DavDepthInfinity|DavGenericLockDB|DavLockDB|DavMinTimeout|DBDExptime|DBDInitSQL|DBDKeep|DBDMax|DBDMin|DBDParams|DBDPersist|DBDPrepareSQL|DBDriver|DefaultIcon|DefaultLanguage|DefaultRuntimeDir|DefaultType|Define|DeflateBufferSize|DeflateCompressionLevel|DeflateFilterNote|DeflateInflateLimitRequestBody|DeflateInflateRatioBurst|DeflateInflateRatioLimit|DeflateMemLevel|DeflateWindowSize|Deny|DirectoryCheckHandler|DirectoryIndex|DirectoryIndexRedirect|DirectorySlash|DocumentRoot|DTracePrivileges|DumpIOInput|DumpIOOutput|EnableExceptionHook|EnableMMAP|EnableSendfile|Error|ErrorDocument|ErrorLog|ErrorLogFormat|Example|ExpiresActive|ExpiresByType|ExpiresDefault|ExtendedStatus|ExtFilterDefine|ExtFilterOptions|FallbackResource|FileETag|FilterChain|FilterDeclare|FilterProtocol|FilterProvider|FilterTrace|ForceLanguagePriority|ForceType|ForensicLog|GprofDir|GracefulShutdownTimeout|Group|Header|HeaderName|HeartbeatAddress|HeartbeatListen|HeartbeatMaxServers|HeartbeatStorage|HeartbeatStorage|HostnameLookups|IdentityCheck|IdentityCheckTimeout|ImapBase|ImapDefault|ImapMenu|Include|IncludeOptional|IndexHeadInsert|IndexIgnore|IndexIgnoreReset|IndexOptions|IndexOrderDefault|IndexStyleSheet|InputSed|ISAPIAppendLogToErrors|ISAPIAppendLogToQuery|ISAPICacheFile|ISAPIFakeAsync|ISAPILogNotSupported|ISAPIReadAheadBuffer|KeepAlive|KeepAliveTimeout|KeptBodySize|LanguagePriority|LDAPCacheEntries|LDAPCacheTTL|LDAPConnectionPoolTTL|LDAPConnectionTimeout|LDAPLibraryDebug|LDAPOpCacheEntries|LDAPOpCacheTTL|LDAPReferralHopLimit|LDAPReferrals|LDAPRetries|LDAPRetryDelay|LDAPSharedCacheFile|LDAPSharedCacheSize|LDAPTimeout|LDAPTrustedClientCert|LDAPTrustedGlobalCert|LDAPTrustedMode|LDAPVerifyServerCert|LimitInternalRecursion|LimitRequestBody|LimitRequestFields|LimitRequestFieldSize|LimitRequestLine|LimitXMLRequestBody|Listen|ListenBackLog|LoadFile|LoadModule|LogFormat|LogLevel|LogMessage|LuaAuthzProvider|LuaCodeCache|LuaHookAccessChecker|LuaHookAuthChecker|LuaHookCheckUserID|LuaHookFixups|LuaHookInsertFilter|LuaHookLog|LuaHookMapToStorage|LuaHookTranslateName|LuaHookTypeChecker|LuaInherit|LuaInputFilter|LuaMapHandler|LuaOutputFilter|LuaPackageCPath|LuaPackagePath|LuaQuickHandler|LuaRoot|LuaScope|MaxConnectionsPerChild|MaxKeepAliveRequests|MaxMemFree|MaxRangeOverlaps|MaxRangeReversals|MaxRanges|MaxRequestWorkers|MaxSpareServers|MaxSpareThreads|MaxThreads|MergeTrailers|MetaDir|MetaFiles|MetaSuffix|MimeMagicFile|MinSpareServers|MinSpareThreads|MMapFile|ModemStandard|ModMimeUsePathInfo|MultiviewsMatch|Mutex|NameVirtualHost|NoProxy|NWSSLTrustedCerts|NWSSLUpgradeable|Options|Order|OutputSed|PassEnv|PidFile|PrivilegesMode|Protocol|ProtocolEcho|ProxyAddHeaders|ProxyBadHeader|ProxyBlock|ProxyDomain|ProxyErrorOverride|ProxyExpressDBMFile|ProxyExpressDBMType|ProxyExpressEnable|ProxyFtpDirCharset|ProxyFtpEscapeWildcards|ProxyFtpListOnWildcard|ProxyHTMLBufSize|ProxyHTMLCharsetOut|ProxyHTMLDocType|ProxyHTMLEnable|ProxyHTMLEvents|ProxyHTMLExtended|ProxyHTMLFixups|ProxyHTMLInterp|ProxyHTMLLinks|ProxyHTMLMeta|ProxyHTMLStripComments|ProxyHTMLURLMap|ProxyIOBufferSize|ProxyMaxForwards|ProxyPass|ProxyPassInherit|ProxyPassInterpolateEnv|ProxyPassMatch|ProxyPassReverse|ProxyPassReverseCookieDomain|ProxyPassReverseCookiePath|ProxyPreserveHost|ProxyReceiveBufferSize|ProxyRemote|ProxyRemoteMatch|ProxyRequests|ProxySCGIInternalRedirect|ProxySCGISendfile|ProxySet|ProxySourceAddress|ProxyStatus|ProxyTimeout|ProxyVia|ReadmeName|ReceiveBufferSize|Redirect|RedirectMatch|RedirectPermanent|RedirectTemp|ReflectorHeader|RemoteIPHeader|RemoteIPInternalProxy|RemoteIPInternalProxyList|RemoteIPProxiesHeader|RemoteIPTrustedProxy|RemoteIPTrustedProxyList|RemoveCharset|RemoveEncoding|RemoveHandler|RemoveInputFilter|RemoveLanguage|RemoveOutputFilter|RemoveType|RequestHeader|RequestReadTimeout|Require|RewriteBase|RewriteCond|RewriteEngine|RewriteMap|RewriteOptions|RewriteRule|RLimitCPU|RLimitMEM|RLimitNPROC|Satisfy|ScoreBoardFile|Script|ScriptAlias|ScriptAliasMatch|ScriptInterpreterSource|ScriptLog|ScriptLogBuffer|ScriptLogLength|ScriptSock|SecureListen|SeeRequestTail|SendBufferSize|ServerAdmin|ServerAlias|ServerLimit|ServerName|ServerPath|ServerRoot|ServerSignature|ServerTokens|Session|SessionCookieName|SessionCookieName2|SessionCookieRemove|SessionCryptoCipher|SessionCryptoDriver|SessionCryptoPassphrase|SessionCryptoPassphraseFile|SessionDBDCookieName|SessionDBDCookieName2|SessionDBDCookieRemove|SessionDBDDeleteLabel|SessionDBDInsertLabel|SessionDBDPerUser|SessionDBDSelectLabel|SessionDBDUpdateLabel|SessionEnv|SessionExclude|SessionHeader|SessionInclude|SessionMaxAge|SetEnv|SetEnvIf|SetEnvIfExpr|SetEnvIfNoCase|SetHandler|SetInputFilter|SetOutputFilter|SSIEndTag|SSIErrorMsg|SSIETag|SSILastModified|SSILegacyExprParser|SSIStartTag|SSITimeFormat|SSIUndefinedEcho|SSLCACertificateFile|SSLCACertificatePath|SSLCADNRequestFile|SSLCADNRequestPath|SSLCARevocationCheck|SSLCARevocationFile|SSLCARevocationPath|SSLCertificateChainFile|SSLCertificateFile|SSLCertificateKeyFile|SSLCipherSuite|SSLCompression|SSLCryptoDevice|SSLEngine|SSLFIPS|SSLHonorCipherOrder|SSLInsecureRenegotiation|SSLOCSPDefaultResponder|SSLOCSPEnable|SSLOCSPOverrideResponder|SSLOCSPResponderTimeout|SSLOCSPResponseMaxAge|SSLOCSPResponseTimeSkew|SSLOCSPUseRequestNonce|SSLOpenSSLConfCmd|SSLOptions|SSLPassPhraseDialog|SSLProtocol|SSLProxyCACertificateFile|SSLProxyCACertificatePath|SSLProxyCARevocationCheck|SSLProxyCARevocationFile|SSLProxyCARevocationPath|SSLProxyCheckPeerCN|SSLProxyCheckPeerExpire|SSLProxyCheckPeerName|SSLProxyCipherSuite|SSLProxyEngine|SSLProxyMachineCertificateChainFile|SSLProxyMachineCertificateFile|SSLProxyMachineCertificatePath|SSLProxyProtocol|SSLProxyVerify|SSLProxyVerifyDepth|SSLRandomSeed|SSLRenegBufferSize|SSLRequire|SSLRequireSSL|SSLSessionCache|SSLSessionCacheTimeout|SSLSessionTicketKeyFile|SSLSRPUnknownUserSeed|SSLSRPVerifierFile|SSLStaplingCache|SSLStaplingErrorCacheTimeout|SSLStaplingFakeTryLater|SSLStaplingForceURL|SSLStaplingResponderTimeout|SSLStaplingResponseMaxAge|SSLStaplingResponseTimeSkew|SSLStaplingReturnResponderErrors|SSLStaplingStandardCacheTimeout|SSLStrictSNIVHostCheck|SSLUserName|SSLUseStapling|SSLVerifyClient|SSLVerifyDepth|StartServers|StartThreads|Substitute|Suexec|SuexecUserGroup|ThreadLimit|ThreadsPerChild|ThreadStackSize|TimeOut|TraceEnable|TransferLog|TypesConfig|UnDefine|UndefMacro|UnsetEnv|Use|UseCanonicalName|UseCanonicalPhysicalPort|User|UserDir|VHostCGIMode|VHostCGIPrivs|VHostGroup|VHostPrivs|VHostSecure|VHostUser|VirtualDocumentRoot|VirtualDocumentRootIP|VirtualScriptAlias|VirtualScriptAliasIP|WatchdogInterval|XBitHack|xml2EncAlias|xml2EncDefault|xml2StartParse)\b/im,alias:"property"},"directive-block":{pattern:/<\/?\b(AuthnProviderAlias|AuthzProviderAlias|Directory|DirectoryMatch|Else|ElseIf|Files|FilesMatch|If|IfDefine|IfModule|IfVersion|Limit|LimitExcept|Location|LocationMatch|Macro|Proxy|RequireAll|RequireAny|RequireNone|VirtualHost)\b *.*>/i,inside:{"directive-block":{pattern:/^<\/?\w+/,inside:{punctuation:/^<\/?/},alias:"tag"},"directive-block-parameter":{pattern:/.*[^>]/,inside:{punctuation:/:/,string:{pattern:/("|').*\1/,inside:{variable:/(\$|%)\{?(\w\.?(\+|\-|:)?)+\}?/}}},alias:"attr-value"},punctuation:/>/},alias:"tag"},"directive-flags":{pattern:/\[(\w,?)+\]/,alias:"keyword"},string:{pattern:/("|').*\1/,inside:{variable:/(\$|%)\{?(\w\.?(\+|\-|:)?)+\}?/}},variable:/(\$|%)\{?(\w\.?(\+|\-|:)?)+\}?/,regex:/\^?.*\$|\^.*\$?/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-applescript.js b/polymer_1.0.4/bower_components/prism/components/prism-applescript.js
new file mode 100644
index 0000000..5d74020
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-applescript.js
@@ -0,0 +1,23 @@
+/* TODO
+ Add support for nested block comments...
+*/
+
+Prism.languages.applescript = {
+ 'comment': [
+ /\(\*[\w\W]*?\*\)/,
+ /--.+/,
+ /#.+/
+ ],
+ 'string': /"(?:\\?.)*?"/,
+ 'operator': [
+ /[&=≠≤≥*+\-\/÷^]|[<>]=?/,
+ /\b(?:(?:start|begin|end)s? with|(?:(?:does not|doesn't) contain|contains?)|(?:is|isn't|is not) (?:in|contained by)|(?:(?:is|isn't|is not) )?(?:greater|less) than(?: or equal)?(?: to)?|(?:(?:does not|doesn't) come|comes) (?:before|after)|(?:is|isn't|is not) equal(?: to)?|(?:(?:does not|doesn't) equal|equals|equal to|isn't|is not)|(?:a )?(?:ref(?: to)?|reference to)|(?:and|or|div|mod|as|not))\b/
+ ],
+ 'keyword': /\b(?:about|above|after|against|and|apart from|around|as|aside from|at|back|before|beginning|behind|below|beneath|beside|between|but|by|considering|contain|contains|continue|copy|div|does|eighth|else|end|equal|equals|error|every|exit|false|fifth|first|for|fourth|from|front|get|given|global|if|ignoring|in|instead of|into|is|it|its|last|local|me|middle|mod|my|ninth|not|of|on|onto|or|out of|over|prop|property|put|ref|reference|repeat|return|returning|script|second|set|seventh|since|sixth|some|tell|tenth|that|the|then|third|through|thru|timeout|times|to|transaction|true|try|until|where|while|whose|with|without)\b/,
+ 'class': {
+ pattern: /\b(?:alias|application|boolean|class|constant|date|file|integer|list|number|POSIX file|real|record|reference|RGB color|script|text|centimetres|centimeters|feet|inches|kilometres|kilometers|metres|meters|miles|yards|square feet|square kilometres|square kilometers|square metres|square meters|square miles|square yards|cubic centimetres|cubic centimeters|cubic feet|cubic inches|cubic metres|cubic meters|cubic yards|gallons|litres|liters|quarts|grams|kilograms|ounces|pounds|degrees Celsius|degrees Fahrenheit|degrees Kelvin)\b/,
+ alias: 'builtin'
+ },
+ 'number': /\b-?\d*\.?\d+([Ee]-?\d+)?\b/,
+ 'punctuation': /[{}():,¬«»《》]/
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-applescript.min.js b/polymer_1.0.4/bower_components/prism/components/prism-applescript.min.js
new file mode 100644
index 0000000..30e1ffd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-applescript.min.js
@@ -0,0 +1 @@
+Prism.languages.applescript={comment:[/\(\*[\w\W]*?\*\)/,/--.+/,/#.+/],string:/"(?:\\?.)*?"/,operator:[/[&=≠≤≥*+\-\/÷^]|[<>]=?/,/\b(?:(?:start|begin|end)s? with|(?:(?:does not|doesn't) contain|contains?)|(?:is|isn't|is not) (?:in|contained by)|(?:(?:is|isn't|is not) )?(?:greater|less) than(?: or equal)?(?: to)?|(?:(?:does not|doesn't) come|comes) (?:before|after)|(?:is|isn't|is not) equal(?: to)?|(?:(?:does not|doesn't) equal|equals|equal to|isn't|is not)|(?:a )?(?:ref(?: to)?|reference to)|(?:and|or|div|mod|as|not))\b/],keyword:/\b(?:about|above|after|against|and|apart from|around|as|aside from|at|back|before|beginning|behind|below|beneath|beside|between|but|by|considering|contain|contains|continue|copy|div|does|eighth|else|end|equal|equals|error|every|exit|false|fifth|first|for|fourth|from|front|get|given|global|if|ignoring|in|instead of|into|is|it|its|last|local|me|middle|mod|my|ninth|not|of|on|onto|or|out of|over|prop|property|put|ref|reference|repeat|return|returning|script|second|set|seventh|since|sixth|some|tell|tenth|that|the|then|third|through|thru|timeout|times|to|transaction|true|try|until|where|while|whose|with|without)\b/,"class":{pattern:/\b(?:alias|application|boolean|class|constant|date|file|integer|list|number|POSIX file|real|record|reference|RGB color|script|text|centimetres|centimeters|feet|inches|kilometres|kilometers|metres|meters|miles|yards|square feet|square kilometres|square kilometers|square metres|square meters|square miles|square yards|cubic centimetres|cubic centimeters|cubic feet|cubic inches|cubic metres|cubic meters|cubic yards|gallons|litres|liters|quarts|grams|kilograms|ounces|pounds|degrees Celsius|degrees Fahrenheit|degrees Kelvin)\b/,alias:"builtin"},number:/\b-?\d*\.?\d+([Ee]-?\d+)?\b/,punctuation:/[{}():,¬«»《》]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-aspnet.js b/polymer_1.0.4/bower_components/prism/components/prism-aspnet.js
new file mode 100644
index 0000000..534a46c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-aspnet.js
@@ -0,0 +1,49 @@
+Prism.languages.aspnet = Prism.languages.extend('markup', {
+ 'page-directive tag': {
+ pattern: /<%\s*@.*%>/i,
+ inside: {
+ 'page-directive tag': /<%\s*@\s*(?:Assembly|Control|Implements|Import|Master|MasterType|OutputCache|Page|PreviousPageType|Reference|Register)?|%>/i,
+ rest: Prism.languages.markup.tag.inside
+ }
+ },
+ 'directive tag': {
+ pattern: /<%.*%>/i,
+ inside: {
+ 'directive tag': /<%\s*?[$=%#:]{0,2}|%>/i,
+ rest: Prism.languages.csharp
+ }
+ }
+});
+
+// match directives of attribute value foo="<% Bar %>"
+Prism.languages.insertBefore('inside', 'punctuation', {
+ 'directive tag': Prism.languages.aspnet['directive tag']
+}, Prism.languages.aspnet.tag.inside["attr-value"]);
+
+Prism.languages.insertBefore('aspnet', 'comment', {
+ 'asp comment': /<%--[\w\W]*?--%>/
+});
+
+// script runat="server" contains csharp, not javascript
+Prism.languages.insertBefore('aspnet', Prism.languages.javascript ? 'script' : 'tag', {
+ 'asp script': {
+ pattern: /<script(?=.*runat=['"]?server['"]?)[\w\W]*?>[\w\W]*?<\/script>/i,
+ inside: {
+ tag: {
+ pattern: /<\/?script\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|\w+))?\s*)*\/?>/i,
+ inside: Prism.languages.aspnet.tag.inside
+ },
+ rest: Prism.languages.csharp || {}
+ }
+ }
+});
+
+// Hacks to fix eager tag matching finishing too early: <script src="<% Foo.Bar %>"> => <script src="<% Foo.Bar %>
+if ( Prism.languages.aspnet.style ) {
+ Prism.languages.aspnet.style.inside.tag.pattern = /<\/?style\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|\w+))?\s*)*\/?>/i;
+ Prism.languages.aspnet.style.inside.tag.inside = Prism.languages.aspnet.tag.inside;
+}
+if ( Prism.languages.aspnet.script ) {
+ Prism.languages.aspnet.script.inside.tag.pattern = Prism.languages.aspnet['asp script'].inside.tag.pattern;
+ Prism.languages.aspnet.script.inside.tag.inside = Prism.languages.aspnet.tag.inside;
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-aspnet.min.js b/polymer_1.0.4/bower_components/prism/components/prism-aspnet.min.js
new file mode 100644
index 0000000..71adac9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-aspnet.min.js
@@ -0,0 +1 @@
+Prism.languages.aspnet=Prism.languages.extend("markup",{"page-directive tag":{pattern:/<%\s*@.*%>/i,inside:{"page-directive tag":/<%\s*@\s*(?:Assembly|Control|Implements|Import|Master|MasterType|OutputCache|Page|PreviousPageType|Reference|Register)?|%>/i,rest:Prism.languages.markup.tag.inside}},"directive tag":{pattern:/<%.*%>/i,inside:{"directive tag":/<%\s*?[$=%#:]{0,2}|%>/i,rest:Prism.languages.csharp}}}),Prism.languages.insertBefore("inside","punctuation",{"directive tag":Prism.languages.aspnet["directive tag"]},Prism.languages.aspnet.tag.inside["attr-value"]),Prism.languages.insertBefore("aspnet","comment",{"asp comment":/<%--[\w\W]*?--%>/}),Prism.languages.insertBefore("aspnet",Prism.languages.javascript?"script":"tag",{"asp script":{pattern:/<script(?=.*runat=['"]?server['"]?)[\w\W]*?>[\w\W]*?<\/script>/i,inside:{tag:{pattern:/<\/?script\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|\w+))?\s*)*\/?>/i,inside:Prism.languages.aspnet.tag.inside},rest:Prism.languages.csharp||{}}}}),Prism.languages.aspnet.style&&(Prism.languages.aspnet.style.inside.tag.pattern=/<\/?style\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|\w+))?\s*)*\/?>/i,Prism.languages.aspnet.style.inside.tag.inside=Prism.languages.aspnet.tag.inside),Prism.languages.aspnet.script&&(Prism.languages.aspnet.script.inside.tag.pattern=Prism.languages.aspnet["asp script"].inside.tag.pattern,Prism.languages.aspnet.script.inside.tag.inside=Prism.languages.aspnet.tag.inside);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-autohotkey.js b/polymer_1.0.4/bower_components/prism/components/prism-autohotkey.js
new file mode 100644
index 0000000..39751ee
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-autohotkey.js
@@ -0,0 +1,27 @@
+// NOTES - follows first-first highlight method, block is locked after highlight, different from SyntaxHl
+Prism.languages.autohotkey= {
+ 'comment': {
+ pattern: /(^[^";\n]*("[^"\n]*?"[^"\n]*?)*)(;.*$|^\s*\/\*[\s\S]*\n\*\/)/m,
+ lookbehind: true
+ },
+ 'string': /"(([^"\n\r]|"")*)"/m,
+ 'function': /[^\(\); \t,\n\+\*\-=\?>:\\\/<&%\[\]]+?(?=\()/m, //function - don't use .*\) in the end bcoz string locks it
+ 'tag': /^[ \t]*[^\s:]+?(?=:[^:])/m, //labels
+ 'variable': /%\w+%/,
+ 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,
+ 'operator': /[\+\-\*\\\/:=\?&\|<>]/,
+ 'punctuation': /[\{}[\]\(\):]/,
+ 'boolean': /\b(true|false)\b/,
+
+ 'selector': /\b(AutoTrim|BlockInput|Break|Click|ClipWait|Continue|Control|ControlClick|ControlFocus|ControlGet|ControlGetFocus|ControlGetPos|ControlGetText|ControlMove|ControlSend|ControlSendRaw|ControlSetText|CoordMode|Critical|DetectHiddenText|DetectHiddenWindows|Drive|DriveGet|DriveSpaceFree|EnvAdd|EnvDiv|EnvGet|EnvMult|EnvSet|EnvSub|EnvUpdate|Exit|ExitApp|FileAppend|FileCopy|FileCopyDir|FileCreateDir|FileCreateShortcut|FileDelete|FileEncoding|FileGetAttrib|FileGetShortcut|FileGetSize|FileGetTime|FileGetVersion|FileInstall|FileMove|FileMoveDir|FileRead|FileReadLine|FileRecycle|FileRecycleEmpty|FileRemoveDir|FileSelectFile|FileSelectFolder|FileSetAttrib|FileSetTime|FormatTime|GetKeyState|Gosub|Goto|GroupActivate|GroupAdd|GroupClose|GroupDeactivate|Gui|GuiControl|GuiControlGet|Hotkey|ImageSearch|IniDelete|IniRead|IniWrite|Input|InputBox|KeyWait|ListHotkeys|ListLines|ListVars|Loop|Menu|MouseClick|MouseClickDrag|MouseGetPos|MouseMove|MsgBox|OnExit|OutputDebug|Pause|PixelGetColor|PixelSearch|PostMessage|Process|Progress|Random|RegDelete|RegRead|RegWrite|Reload|Repeat|Return|Run|RunAs|RunWait|Send|SendEvent|SendInput|SendMessage|SendMode|SendPlay|SendRaw|SetBatchLines|SetCapslockState|SetControlDelay|SetDefaultMouseSpeed|SetEnv|SetFormat|SetKeyDelay|SetMouseDelay|SetNumlockState|SetScrollLockState|SetStoreCapslockMode|SetTimer|SetTitleMatchMode|SetWinDelay|SetWorkingDir|Shutdown|Sleep|Sort|SoundBeep|SoundGet|SoundGetWaveVolume|SoundPlay|SoundSet|SoundSetWaveVolume|SplashImage|SplashTextOff|SplashTextOn|SplitPath|StatusBarGetText|StatusBarWait|StringCaseSense|StringGetPos|StringLeft|StringLen|StringLower|StringMid|StringReplace|StringRight|StringSplit|StringTrimLeft|StringTrimRight|StringUpper|Suspend|SysGet|Thread|ToolTip|Transform|TrayTip|URLDownloadToFile|WinActivate|WinActivateBottom|WinClose|WinGet|WinGetActiveStats|WinGetActiveTitle|WinGetClass|WinGetPos|WinGetText|WinGetTitle|WinHide|WinKill|WinMaximize|WinMenuSelectItem|WinMinimize|WinMinimizeAll|WinMinimizeAllUndo|WinMove|WinRestore|WinSet|WinSetTitle|WinShow|WinWait|WinWaitActive|WinWaitClose|WinWaitNotActive)\b/i,
+
+ 'constant': /\b(a_ahkpath|a_ahkversion|a_appdata|a_appdatacommon|a_autotrim|a_batchlines|a_caretx|a_carety|a_computername|a_controldelay|a_cursor|a_dd|a_ddd|a_dddd|a_defaultmousespeed|a_desktop|a_desktopcommon|a_detecthiddentext|a_detecthiddenwindows|a_endchar|a_eventinfo|a_exitreason|a_formatfloat|a_formatinteger|a_gui|a_guievent|a_guicontrol|a_guicontrolevent|a_guiheight|a_guiwidth|a_guix|a_guiy|a_hour|a_iconfile|a_iconhidden|a_iconnumber|a_icontip|a_index|a_ipaddress1|a_ipaddress2|a_ipaddress3|a_ipaddress4|a_isadmin|a_iscompiled|a_iscritical|a_ispaused|a_issuspended|a_isunicode|a_keydelay|a_language|a_lasterror|a_linefile|a_linenumber|a_loopfield|a_loopfileattrib|a_loopfiledir|a_loopfileext|a_loopfilefullpath|a_loopfilelongpath|a_loopfilename|a_loopfileshortname|a_loopfileshortpath|a_loopfilesize|a_loopfilesizekb|a_loopfilesizemb|a_loopfiletimeaccessed|a_loopfiletimecreated|a_loopfiletimemodified|a_loopreadline|a_loopregkey|a_loopregname|a_loopregsubkey|a_loopregtimemodified|a_loopregtype|a_mday|a_min|a_mm|a_mmm|a_mmmm|a_mon|a_mousedelay|a_msec|a_mydocuments|a_now|a_nowutc|a_numbatchlines|a_ostype|a_osversion|a_priorhotkey|programfiles|a_programfiles|a_programs|a_programscommon|a_screenheight|a_screenwidth|a_scriptdir|a_scriptfullpath|a_scriptname|a_sec|a_space|a_startmenu|a_startmenucommon|a_startup|a_startupcommon|a_stringcasesense|a_tab|a_temp|a_thisfunc|a_thishotkey|a_thislabel|a_thismenu|a_thismenuitem|a_thismenuitempos|a_tickcount|a_timeidle|a_timeidlephysical|a_timesincepriorhotkey|a_timesincethishotkey|a_titlematchmode|a_titlematchmodespeed|a_username|a_wday|a_windelay|a_windir|a_workingdir|a_yday|a_year|a_yweek|a_yyyy|clipboard|clipboardall|comspec|errorlevel)\b/i,
+
+ 'builtin': /\b(abs|acos|asc|asin|atan|ceil|chr|class|cos|dllcall|exp|fileexist|Fileopen|floor|getkeystate|il_add|il_create|il_destroy|instr|substr|isfunc|islabel|IsObject|ln|log|lv_add|lv_delete|lv_deletecol|lv_getcount|lv_getnext|lv_gettext|lv_insert|lv_insertcol|lv_modify|lv_modifycol|lv_setimagelist|mod|onmessage|numget|numput|registercallback|regexmatch|regexreplace|round|sin|tan|sqrt|strlen|sb_seticon|sb_setparts|sb_settext|strsplit|tv_add|tv_delete|tv_getchild|tv_getcount|tv_getnext|tv_get|tv_getparent|tv_getprev|tv_getselection|tv_gettext|tv_modify|varsetcapacity|winactive|winexist|__New|__Call|__Get|__Set)\b/i,
+
+ 'symbol': /\b(alt|altdown|altup|appskey|backspace|browser_back|browser_favorites|browser_forward|browser_home|browser_refresh|browser_search|browser_stop|bs|capslock|control|ctrl|ctrlbreak|ctrldown|ctrlup|del|delete|down|end|enter|esc|escape|f1|f10|f11|f12|f13|f14|f15|f16|f17|f18|f19|f2|f20|f21|f22|f23|f24|f3|f4|f5|f6|f7|f8|f9|home|ins|insert|joy1|joy10|joy11|joy12|joy13|joy14|joy15|joy16|joy17|joy18|joy19|joy2|joy20|joy21|joy22|joy23|joy24|joy25|joy26|joy27|joy28|joy29|joy3|joy30|joy31|joy32|joy4|joy5|joy6|joy7|joy8|joy9|joyaxes|joybuttons|joyinfo|joyname|joypov|joyr|joyu|joyv|joyx|joyy|joyz|lalt|launch_app1|launch_app2|launch_mail|launch_media|lbutton|lcontrol|lctrl|left|lshift|lwin|lwindown|lwinup|mbutton|media_next|media_play_pause|media_prev|media_stop|numlock|numpad0|numpad1|numpad2|numpad3|numpad4|numpad5|numpad6|numpad7|numpad8|numpad9|numpadadd|numpadclear|numpaddel|numpaddiv|numpaddot|numpaddown|numpadend|numpadenter|numpadhome|numpadins|numpadleft|numpadmult|numpadpgdn|numpadpgup|numpadright|numpadsub|numpadup|pause|pgdn|pgup|printscreen|ralt|rbutton|rcontrol|rctrl|right|rshift|rwin|rwindown|rwinup|scrolllock|shift|shiftdown|shiftup|space|tab|up|volume_down|volume_mute|volume_up|wheeldown|wheelleft|wheelright|wheelup|xbutton1|xbutton2)\b/i,
+
+ 'important': /#\b(AllowSameLineComments|ClipboardTimeout|CommentFlag|ErrorStdOut|EscapeChar|HotkeyInterval|HotkeyModifierTimeout|Hotstring|IfWinActive|IfWinExist|IfWinNotActive|IfWinNotExist|Include|IncludeAgain|InstallKeybdHook|InstallMouseHook|KeyHistory|LTrim|MaxHotkeysPerInterval|MaxMem|MaxThreads|MaxThreadsBuffer|MaxThreadsPerHotkey|NoEnv|NoTrayIcon|Persistent|SingleInstance|UseHook|WinActivateForce)\b/i,
+
+ 'keyword': /\b(Abort|AboveNormal|Add|ahk_class|ahk_group|ahk_id|ahk_pid|All|Alnum|Alpha|AltSubmit|AltTab|AltTabAndMenu|AltTabMenu|AltTabMenuDismiss|AlwaysOnTop|AutoSize|Background|BackgroundTrans|BelowNormal|between|BitAnd|BitNot|BitOr|BitShiftLeft|BitShiftRight|BitXOr|Bold|Border|Button|ByRef|Checkbox|Checked|CheckedGray|Choose|ChooseString|Click|Close|Color|ComboBox|Contains|ControlList|Count|Date|DateTime|Days|DDL|Default|Delete|DeleteAll|Delimiter|Deref|Destroy|Digit|Disable|Disabled|DropDownList|Edit|Eject|Else|Enable|Enabled|Error|Exist|Exp|Expand|ExStyle|FileSystem|First|Flash|Float|FloatFast|Focus|Font|for|global|Grid|Group|GroupBox|GuiClose|GuiContextMenu|GuiDropFiles|GuiEscape|GuiSize|Hdr|Hidden|Hide|High|HKCC|HKCR|HKCU|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_LOCAL_MACHINE|HKEY_USERS|HKLM|HKU|Hours|HScroll|Icon|IconSmall|ID|IDLast|If|IfEqual|IfExist|IfGreater|IfGreaterOrEqual|IfInString|IfLess|IfLessOrEqual|IfMsgBox|IfNotEqual|IfNotExist|IfNotInString|IfWinActive|IfWinExist|IfWinNotActive|IfWinNotExist|Ignore|ImageList|in|Integer|IntegerFast|Interrupt|is|italic|Join|Label|LastFound|LastFoundExist|Limit|Lines|List|ListBox|ListView|Ln|local|Lock|Logoff|Low|Lower|Lowercase|MainWindow|Margin|Maximize|MaximizeBox|MaxSize|Minimize|MinimizeBox|MinMax|MinSize|Minutes|MonthCal|Mouse|Move|Multi|NA|No|NoActivate|NoDefault|NoHide|NoIcon|NoMainWindow|norm|Normal|NoSort|NoSortHdr|NoStandard|Not|NoTab|NoTimers|Number|Off|Ok|On|OwnDialogs|Owner|Parse|Password|Picture|Pixel|Pos|Pow|Priority|ProcessName|Radio|Range|Read|ReadOnly|Realtime|Redraw|REG_BINARY|REG_DWORD|REG_EXPAND_SZ|REG_MULTI_SZ|REG_SZ|Region|Relative|Rename|Report|Resize|Restore|Retry|RGB|Right|Screen|Seconds|Section|Serial|SetLabel|ShiftAltTab|Show|Single|Slider|SortDesc|Standard|static|Status|StatusBar|StatusCD|strike|Style|Submit|SysMenu|Tab|Tab2|TabStop|Text|Theme|Tile|ToggleCheck|ToggleEnable|ToolWindow|Top|Topmost|TransColor|Transparent|Tray|TreeView|TryAgain|Type|UnCheck|underline|Unicode|Unlock|UpDown|Upper|Uppercase|UseErrorLevel|Vis|VisFirst|Visible|VScroll|Wait|WaitClose|WantCtrlA|WantF2|WantReturn|While|Wrap|Xdigit|xm|xp|xs|Yes|ym|yp|ys)\b/i
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-autohotkey.min.js b/polymer_1.0.4/bower_components/prism/components/prism-autohotkey.min.js
new file mode 100644
index 0000000..be03637
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-autohotkey.min.js
@@ -0,0 +1 @@
+Prism.languages.autohotkey={comment:{pattern:/(^[^";\n]*("[^"\n]*?"[^"\n]*?)*)(;.*$|^\s*\/\*[\s\S]*\n\*\/)/m,lookbehind:!0},string:/"(([^"\n\r]|"")*)"/m,"function":/[^\(\); \t,\n\+\*\-=\?>:\\\/<&%\[\]]+?(?=\()/m,tag:/^[ \t]*[^\s:]+?(?=:[^:])/m,variable:/%\w+%/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,operator:/[\+\-\*\\\/:=\?&\|<>]/,punctuation:/[\{}[\]\(\):]/,"boolean":/\b(true|false)\b/,selector:/\b(AutoTrim|BlockInput|Break|Click|ClipWait|Continue|Control|ControlClick|ControlFocus|ControlGet|ControlGetFocus|ControlGetPos|ControlGetText|ControlMove|ControlSend|ControlSendRaw|ControlSetText|CoordMode|Critical|DetectHiddenText|DetectHiddenWindows|Drive|DriveGet|DriveSpaceFree|EnvAdd|EnvDiv|EnvGet|EnvMult|EnvSet|EnvSub|EnvUpdate|Exit|ExitApp|FileAppend|FileCopy|FileCopyDir|FileCreateDir|FileCreateShortcut|FileDelete|FileEncoding|FileGetAttrib|FileGetShortcut|FileGetSize|FileGetTime|FileGetVersion|FileInstall|FileMove|FileMoveDir|FileRead|FileReadLine|FileRecycle|FileRecycleEmpty|FileRemoveDir|FileSelectFile|FileSelectFolder|FileSetAttrib|FileSetTime|FormatTime|GetKeyState|Gosub|Goto|GroupActivate|GroupAdd|GroupClose|GroupDeactivate|Gui|GuiControl|GuiControlGet|Hotkey|ImageSearch|IniDelete|IniRead|IniWrite|Input|InputBox|KeyWait|ListHotkeys|ListLines|ListVars|Loop|Menu|MouseClick|MouseClickDrag|MouseGetPos|MouseMove|MsgBox|OnExit|OutputDebug|Pause|PixelGetColor|PixelSearch|PostMessage|Process|Progress|Random|RegDelete|RegRead|RegWrite|Reload|Repeat|Return|Run|RunAs|RunWait|Send|SendEvent|SendInput|SendMessage|SendMode|SendPlay|SendRaw|SetBatchLines|SetCapslockState|SetControlDelay|SetDefaultMouseSpeed|SetEnv|SetFormat|SetKeyDelay|SetMouseDelay|SetNumlockState|SetScrollLockState|SetStoreCapslockMode|SetTimer|SetTitleMatchMode|SetWinDelay|SetWorkingDir|Shutdown|Sleep|Sort|SoundBeep|SoundGet|SoundGetWaveVolume|SoundPlay|SoundSet|SoundSetWaveVolume|SplashImage|SplashTextOff|SplashTextOn|SplitPath|StatusBarGetText|StatusBarWait|StringCaseSense|StringGetPos|StringLeft|StringLen|StringLower|StringMid|StringReplace|StringRight|StringSplit|StringTrimLeft|StringTrimRight|StringUpper|Suspend|SysGet|Thread|ToolTip|Transform|TrayTip|URLDownloadToFile|WinActivate|WinActivateBottom|WinClose|WinGet|WinGetActiveStats|WinGetActiveTitle|WinGetClass|WinGetPos|WinGetText|WinGetTitle|WinHide|WinKill|WinMaximize|WinMenuSelectItem|WinMinimize|WinMinimizeAll|WinMinimizeAllUndo|WinMove|WinRestore|WinSet|WinSetTitle|WinShow|WinWait|WinWaitActive|WinWaitClose|WinWaitNotActive)\b/i,constant:/\b(a_ahkpath|a_ahkversion|a_appdata|a_appdatacommon|a_autotrim|a_batchlines|a_caretx|a_carety|a_computername|a_controldelay|a_cursor|a_dd|a_ddd|a_dddd|a_defaultmousespeed|a_desktop|a_desktopcommon|a_detecthiddentext|a_detecthiddenwindows|a_endchar|a_eventinfo|a_exitreason|a_formatfloat|a_formatinteger|a_gui|a_guievent|a_guicontrol|a_guicontrolevent|a_guiheight|a_guiwidth|a_guix|a_guiy|a_hour|a_iconfile|a_iconhidden|a_iconnumber|a_icontip|a_index|a_ipaddress1|a_ipaddress2|a_ipaddress3|a_ipaddress4|a_isadmin|a_iscompiled|a_iscritical|a_ispaused|a_issuspended|a_isunicode|a_keydelay|a_language|a_lasterror|a_linefile|a_linenumber|a_loopfield|a_loopfileattrib|a_loopfiledir|a_loopfileext|a_loopfilefullpath|a_loopfilelongpath|a_loopfilename|a_loopfileshortname|a_loopfileshortpath|a_loopfilesize|a_loopfilesizekb|a_loopfilesizemb|a_loopfiletimeaccessed|a_loopfiletimecreated|a_loopfiletimemodified|a_loopreadline|a_loopregkey|a_loopregname|a_loopregsubkey|a_loopregtimemodified|a_loopregtype|a_mday|a_min|a_mm|a_mmm|a_mmmm|a_mon|a_mousedelay|a_msec|a_mydocuments|a_now|a_nowutc|a_numbatchlines|a_ostype|a_osversion|a_priorhotkey|programfiles|a_programfiles|a_programs|a_programscommon|a_screenheight|a_screenwidth|a_scriptdir|a_scriptfullpath|a_scriptname|a_sec|a_space|a_startmenu|a_startmenucommon|a_startup|a_startupcommon|a_stringcasesense|a_tab|a_temp|a_thisfunc|a_thishotkey|a_thislabel|a_thismenu|a_thismenuitem|a_thismenuitempos|a_tickcount|a_timeidle|a_timeidlephysical|a_timesincepriorhotkey|a_timesincethishotkey|a_titlematchmode|a_titlematchmodespeed|a_username|a_wday|a_windelay|a_windir|a_workingdir|a_yday|a_year|a_yweek|a_yyyy|clipboard|clipboardall|comspec|errorlevel)\b/i,builtin:/\b(abs|acos|asc|asin|atan|ceil|chr|class|cos|dllcall|exp|fileexist|Fileopen|floor|getkeystate|il_add|il_create|il_destroy|instr|substr|isfunc|islabel|IsObject|ln|log|lv_add|lv_delete|lv_deletecol|lv_getcount|lv_getnext|lv_gettext|lv_insert|lv_insertcol|lv_modify|lv_modifycol|lv_setimagelist|mod|onmessage|numget|numput|registercallback|regexmatch|regexreplace|round|sin|tan|sqrt|strlen|sb_seticon|sb_setparts|sb_settext|strsplit|tv_add|tv_delete|tv_getchild|tv_getcount|tv_getnext|tv_get|tv_getparent|tv_getprev|tv_getselection|tv_gettext|tv_modify|varsetcapacity|winactive|winexist|__New|__Call|__Get|__Set)\b/i,symbol:/\b(alt|altdown|altup|appskey|backspace|browser_back|browser_favorites|browser_forward|browser_home|browser_refresh|browser_search|browser_stop|bs|capslock|control|ctrl|ctrlbreak|ctrldown|ctrlup|del|delete|down|end|enter|esc|escape|f1|f10|f11|f12|f13|f14|f15|f16|f17|f18|f19|f2|f20|f21|f22|f23|f24|f3|f4|f5|f6|f7|f8|f9|home|ins|insert|joy1|joy10|joy11|joy12|joy13|joy14|joy15|joy16|joy17|joy18|joy19|joy2|joy20|joy21|joy22|joy23|joy24|joy25|joy26|joy27|joy28|joy29|joy3|joy30|joy31|joy32|joy4|joy5|joy6|joy7|joy8|joy9|joyaxes|joybuttons|joyinfo|joyname|joypov|joyr|joyu|joyv|joyx|joyy|joyz|lalt|launch_app1|launch_app2|launch_mail|launch_media|lbutton|lcontrol|lctrl|left|lshift|lwin|lwindown|lwinup|mbutton|media_next|media_play_pause|media_prev|media_stop|numlock|numpad0|numpad1|numpad2|numpad3|numpad4|numpad5|numpad6|numpad7|numpad8|numpad9|numpadadd|numpadclear|numpaddel|numpaddiv|numpaddot|numpaddown|numpadend|numpadenter|numpadhome|numpadins|numpadleft|numpadmult|numpadpgdn|numpadpgup|numpadright|numpadsub|numpadup|pause|pgdn|pgup|printscreen|ralt|rbutton|rcontrol|rctrl|right|rshift|rwin|rwindown|rwinup|scrolllock|shift|shiftdown|shiftup|space|tab|up|volume_down|volume_mute|volume_up|wheeldown|wheelleft|wheelright|wheelup|xbutton1|xbutton2)\b/i,important:/#\b(AllowSameLineComments|ClipboardTimeout|CommentFlag|ErrorStdOut|EscapeChar|HotkeyInterval|HotkeyModifierTimeout|Hotstring|IfWinActive|IfWinExist|IfWinNotActive|IfWinNotExist|Include|IncludeAgain|InstallKeybdHook|InstallMouseHook|KeyHistory|LTrim|MaxHotkeysPerInterval|MaxMem|MaxThreads|MaxThreadsBuffer|MaxThreadsPerHotkey|NoEnv|NoTrayIcon|Persistent|SingleInstance|UseHook|WinActivateForce)\b/i,keyword:/\b(Abort|AboveNormal|Add|ahk_class|ahk_group|ahk_id|ahk_pid|All|Alnum|Alpha|AltSubmit|AltTab|AltTabAndMenu|AltTabMenu|AltTabMenuDismiss|AlwaysOnTop|AutoSize|Background|BackgroundTrans|BelowNormal|between|BitAnd|BitNot|BitOr|BitShiftLeft|BitShiftRight|BitXOr|Bold|Border|Button|ByRef|Checkbox|Checked|CheckedGray|Choose|ChooseString|Click|Close|Color|ComboBox|Contains|ControlList|Count|Date|DateTime|Days|DDL|Default|Delete|DeleteAll|Delimiter|Deref|Destroy|Digit|Disable|Disabled|DropDownList|Edit|Eject|Else|Enable|Enabled|Error|Exist|Exp|Expand|ExStyle|FileSystem|First|Flash|Float|FloatFast|Focus|Font|for|global|Grid|Group|GroupBox|GuiClose|GuiContextMenu|GuiDropFiles|GuiEscape|GuiSize|Hdr|Hidden|Hide|High|HKCC|HKCR|HKCU|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_LOCAL_MACHINE|HKEY_USERS|HKLM|HKU|Hours|HScroll|Icon|IconSmall|ID|IDLast|If|IfEqual|IfExist|IfGreater|IfGreaterOrEqual|IfInString|IfLess|IfLessOrEqual|IfMsgBox|IfNotEqual|IfNotExist|IfNotInString|IfWinActive|IfWinExist|IfWinNotActive|IfWinNotExist|Ignore|ImageList|in|Integer|IntegerFast|Interrupt|is|italic|Join|Label|LastFound|LastFoundExist|Limit|Lines|List|ListBox|ListView|Ln|local|Lock|Logoff|Low|Lower|Lowercase|MainWindow|Margin|Maximize|MaximizeBox|MaxSize|Minimize|MinimizeBox|MinMax|MinSize|Minutes|MonthCal|Mouse|Move|Multi|NA|No|NoActivate|NoDefault|NoHide|NoIcon|NoMainWindow|norm|Normal|NoSort|NoSortHdr|NoStandard|Not|NoTab|NoTimers|Number|Off|Ok|On|OwnDialogs|Owner|Parse|Password|Picture|Pixel|Pos|Pow|Priority|ProcessName|Radio|Range|Read|ReadOnly|Realtime|Redraw|REG_BINARY|REG_DWORD|REG_EXPAND_SZ|REG_MULTI_SZ|REG_SZ|Region|Relative|Rename|Report|Resize|Restore|Retry|RGB|Right|Screen|Seconds|Section|Serial|SetLabel|ShiftAltTab|Show|Single|Slider|SortDesc|Standard|static|Status|StatusBar|StatusCD|strike|Style|Submit|SysMenu|Tab|Tab2|TabStop|Text|Theme|Tile|ToggleCheck|ToggleEnable|ToolWindow|Top|Topmost|TransColor|Transparent|Tray|TreeView|TryAgain|Type|UnCheck|underline|Unicode|Unlock|UpDown|Upper|Uppercase|UseErrorLevel|Vis|VisFirst|Visible|VScroll|Wait|WaitClose|WantCtrlA|WantF2|WantReturn|While|Wrap|Xdigit|xm|xp|xs|Yes|ym|yp|ys)\b/i};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-bash.js b/polymer_1.0.4/bower_components/prism/components/prism-bash.js
new file mode 100644
index 0000000..5ca19ea
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-bash.js
@@ -0,0 +1,31 @@
+Prism.languages.bash = Prism.languages.extend('clike', {
+ 'comment': {
+ pattern: /(^|[^"{\\])(#.*?(\r?\n|$))/,
+ lookbehind: true
+ },
+ 'string': {
+ //allow multiline string
+ pattern: /("|')(\\?[\s\S])*?\1/,
+ inside: {
+ //'property' class reused for bash variables
+ 'property': /\$([a-zA-Z0-9_#\?\-\*!@]+|\{[^\}]+\})/
+ }
+ },
+ // Redefined to prevent highlighting of numbers in filenames
+ 'number': {
+ pattern: /([^\w\.])-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,
+ lookbehind: true
+ },
+ // Originally based on http://ss64.com/bash/
+ 'function': /\b(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|cut|date|dc|dd|ddrescue|declare|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|echo|egrep|eject|enable|env|ethtool|eval|exec|exit|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|select|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|until|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)\b/,
+ 'keyword': /\b(if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)\b/
+});
+
+Prism.languages.insertBefore('bash', 'keyword', {
+ //'property' class reused for bash variables
+ 'property': /\$([a-zA-Z0-9_#\?\-\*!@]+|\{[^}]+\})/
+});
+Prism.languages.insertBefore('bash', 'comment', {
+ //shebang must be before comment, 'important' class from css reused
+ 'important': /(^#!\s*\/bin\/bash)|(^#!\s*\/bin\/sh)/
+});
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-bash.min.js b/polymer_1.0.4/bower_components/prism/components/prism-bash.min.js
new file mode 100644
index 0000000..1571eec
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-bash.min.js
@@ -0,0 +1 @@
+Prism.languages.bash=Prism.languages.extend("clike",{comment:{pattern:/(^|[^"{\\])(#.*?(\r?\n|$))/,lookbehind:!0},string:{pattern:/("|')(\\?[\s\S])*?\1/,inside:{property:/\$([a-zA-Z0-9_#\?\-\*!@]+|\{[^\}]+\})/}},number:{pattern:/([^\w\.])-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,lookbehind:!0},"function":/\b(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|cut|date|dc|dd|ddrescue|declare|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|echo|egrep|eject|enable|env|ethtool|eval|exec|exit|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|select|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|until|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)\b/,keyword:/\b(if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)\b/}),Prism.languages.insertBefore("bash","keyword",{property:/\$([a-zA-Z0-9_#\?\-\*!@]+|\{[^}]+\})/}),Prism.languages.insertBefore("bash","comment",{important:/(^#!\s*\/bin\/bash)|(^#!\s*\/bin\/sh)/});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-c.js b/polymer_1.0.4/bower_components/prism/components/prism-c.js
new file mode 100644
index 0000000..e9a0190
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-c.js
@@ -0,0 +1,26 @@
+Prism.languages.c = Prism.languages.extend('clike', {
+ // allow for c multiline strings
+ 'string': /("|')([^\n\\\1]|\\.|\\\r*\n)*?\1/,
+ 'keyword': /\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,
+ 'operator': /[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\//
+});
+
+Prism.languages.insertBefore('c', 'string', {
+ // property class reused for macro statements
+ 'property': {
+ // allow for multiline macro definitions
+ // spaces after the # character compile fine with gcc
+ pattern: /((^|\n)\s*)#\s*[a-z]+([^\n\\]|\\.|\\\r*\n)*/i,
+ lookbehind: true,
+ inside: {
+ // highlight the path of the include statement as a string
+ 'string': {
+ pattern: /(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/,
+ lookbehind: true
+ }
+ }
+ }
+});
+
+delete Prism.languages.c['class-name'];
+delete Prism.languages.c['boolean'];
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-c.min.js b/polymer_1.0.4/bower_components/prism/components/prism-c.min.js
new file mode 100644
index 0000000..a90b67d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-c.min.js
@@ -0,0 +1 @@
+Prism.languages.c=Prism.languages.extend("clike",{string:/("|')([^\n\\\1]|\\.|\\\r*\n)*?\1/,keyword:/\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,operator:/[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\//}),Prism.languages.insertBefore("c","string",{property:{pattern:/((^|\n)\s*)#\s*[a-z]+([^\n\\]|\\.|\\\r*\n)*/i,lookbehind:!0,inside:{string:{pattern:/(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/,lookbehind:!0}}}}),delete Prism.languages.c["class-name"],delete Prism.languages.c["boolean"];
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-clike.js b/polymer_1.0.4/bower_components/prism/components/prism-clike.js
new file mode 100644
index 0000000..5c0a03a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-clike.js
@@ -0,0 +1,32 @@
+Prism.languages.clike = {
+ 'comment': [
+ {
+ pattern: /(^|[^\\])\/\*[\w\W]*?\*\//,
+ lookbehind: true
+ },
+ {
+ pattern: /(^|[^\\:])\/\/.*/,
+ lookbehind: true
+ }
+ ],
+ 'string': /("|')(\\\n|\\?.)*?\1/,
+ 'class-name': {
+ pattern: /((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,
+ lookbehind: true,
+ inside: {
+ punctuation: /(\.|\\)/
+ }
+ },
+ 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
+ 'boolean': /\b(true|false)\b/,
+ 'function': {
+ pattern: /[a-z0-9_]+\(/i,
+ inside: {
+ punctuation: /\(/
+ }
+ },
+ 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,
+ 'operator': /[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/,
+ 'ignore': /&(lt|gt|amp);/i,
+ 'punctuation': /[{}[\];(),.:]/
+};
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-clike.min.js b/polymer_1.0.4/bower_components/prism/components/prism-clike.min.js
new file mode 100644
index 0000000..83c9747
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-clike.min.js
@@ -0,0 +1 @@
+Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:/("|')(\\\n|\\?.)*?\1/,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":{pattern:/[a-z0-9_]+\(/i,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/,ignore:/&(lt|gt|amp);/i,punctuation:/[{}[\];(),.:]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-coffeescript.js b/polymer_1.0.4/bower_components/prism/components/prism-coffeescript.js
new file mode 100644
index 0000000..da31f6b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-coffeescript.js
@@ -0,0 +1,83 @@
+(function(Prism) {
+
+// Ignore comments starting with { to privilege string interpolation highlighting
+var comment = /#(?!\{).+/,
+ interpolation = {
+ pattern: /#\{[^}]+\}/,
+ alias: 'variable'
+ };
+
+Prism.languages.coffeescript = Prism.languages.extend('javascript', {
+ 'comment': comment,
+ 'string': [
+
+ // Strings are multiline
+ /'(?:\\?[\s\S])*?'/,
+
+ {
+ // Strings are multiline
+ pattern: /"(?:\\?[\s\S])*?"/,
+ inside: {
+ 'interpolation': interpolation
+ }
+ }
+ ],
+ 'keyword': /\b(and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,
+ 'class-member': {
+ pattern: /@(?!\d)\w+/,
+ alias: 'variable'
+ }
+});
+
+Prism.languages.insertBefore('coffeescript', 'comment', {
+ 'multiline-comment': {
+ pattern: /###[\s\S]+?###/,
+ alias: 'comment'
+ },
+
+ // Block regexp can contain comments and interpolation
+ 'block-regex': {
+ pattern: /\/{3}[\s\S]*?\/{3}/,
+ alias: 'regex',
+ inside: {
+ 'comment': comment,
+ 'interpolation': interpolation
+ }
+ }
+});
+
+Prism.languages.insertBefore('coffeescript', 'string', {
+ 'inline-javascript': {
+ pattern: /`(?:\\?[\s\S])*?`/,
+ inside: {
+ 'delimiter': {
+ pattern: /^`|`$/,
+ alias: 'punctuation'
+ },
+ rest: Prism.languages.javascript
+ }
+ },
+
+ // Block strings
+ 'multiline-string': [
+ {
+ pattern: /'''[\s\S]*?'''/,
+ alias: 'string'
+ },
+ {
+ pattern: /"""[\s\S]*?"""/,
+ alias: 'string',
+ inside: {
+ interpolation: interpolation
+ }
+ }
+ ]
+
+});
+
+Prism.languages.insertBefore('coffeescript', 'keyword', {
+ // Object property
+ 'property': /(?!\d)\w+(?=\s*:(?!:))/
+});
+
+}(Prism));
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-coffeescript.min.js b/polymer_1.0.4/bower_components/prism/components/prism-coffeescript.min.js
new file mode 100644
index 0000000..7819039
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-coffeescript.min.js
@@ -0,0 +1 @@
+!function(e){var n=/#(?!\{).+/,t={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:n,string:[/'(?:\\?[\s\S])*?'/,{pattern:/"(?:\\?[\s\S])*?"/,inside:{interpolation:t}}],keyword:/\b(and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:n,interpolation:t}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\?[\s\S])*?`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},rest:e.languages.javascript}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,alias:"string"},{pattern:/"""[\s\S]*?"""/,alias:"string",inside:{interpolation:t}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/})}(Prism);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-core.js b/polymer_1.0.4/bower_components/prism/components/prism-core.js
new file mode 100644
index 0000000..750ebb1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-core.js
@@ -0,0 +1,426 @@
+self = (typeof window !== 'undefined')
+ ? window // if in browser
+ : (
+ (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
+ ? self // if in worker
+ : {} // if in node js
+ );
+
+/**
+ * Prism: Lightweight, robust, elegant syntax highlighting
+ * MIT license http://www.opensource.org/licenses/mit-license.php/
+ * @author Lea Verou http://lea.verou.me
+ */
+
+var Prism = (function(){
+
+// Private helper vars
+var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i;
+
+var _ = self.Prism = {
+ util: {
+ encode: function (tokens) {
+ if (tokens instanceof Token) {
+ return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias);
+ } else if (_.util.type(tokens) === 'Array') {
+ return tokens.map(_.util.encode);
+ } else {
+ return tokens.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' ');
+ }
+ },
+
+ type: function (o) {
+ return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1];
+ },
+
+ // Deep clone a language definition (e.g. to extend it)
+ clone: function (o) {
+ var type = _.util.type(o);
+
+ switch (type) {
+ case 'Object':
+ var clone = {};
+
+ for (var key in o) {
+ if (o.hasOwnProperty(key)) {
+ clone[key] = _.util.clone(o[key]);
+ }
+ }
+
+ return clone;
+
+ case 'Array':
+ return o.map(function(v) { return _.util.clone(v); });
+ }
+
+ return o;
+ }
+ },
+
+ languages: {
+ extend: function (id, redef) {
+ var lang = _.util.clone(_.languages[id]);
+
+ for (var key in redef) {
+ lang[key] = redef[key];
+ }
+
+ return lang;
+ },
+
+ /**
+ * Insert a token before another token in a language literal
+ * As this needs to recreate the object (we cannot actually insert before keys in object literals),
+ * we cannot just provide an object, we need anobject and a key.
+ * @param inside The key (or language id) of the parent
+ * @param before The key to insert before. If not provided, the function appends instead.
+ * @param insert Object with the key/value pairs to insert
+ * @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
+ */
+ insertBefore: function (inside, before, insert, root) {
+ root = root || _.languages;
+ var grammar = root[inside];
+
+ if (arguments.length == 2) {
+ insert = arguments[1];
+
+ for (var newToken in insert) {
+ if (insert.hasOwnProperty(newToken)) {
+ grammar[newToken] = insert[newToken];
+ }
+ }
+
+ return grammar;
+ }
+
+ var ret = {};
+
+ for (var token in grammar) {
+
+ if (grammar.hasOwnProperty(token)) {
+
+ if (token == before) {
+
+ for (var newToken in insert) {
+
+ if (insert.hasOwnProperty(newToken)) {
+ ret[newToken] = insert[newToken];
+ }
+ }
+ }
+
+ ret[token] = grammar[token];
+ }
+ }
+
+ // Update references in other language definitions
+ _.languages.DFS(_.languages, function(key, value) {
+ if (value === root[inside] && key != inside) {
+ this[key] = ret;
+ }
+ });
+
+ return root[inside] = ret;
+ },
+
+ // Traverse a language definition with Depth First Search
+ DFS: function(o, callback, type) {
+ for (var i in o) {
+ if (o.hasOwnProperty(i)) {
+ callback.call(o, i, o[i], type || i);
+
+ if (_.util.type(o[i]) === 'Object') {
+ _.languages.DFS(o[i], callback);
+ }
+ else if (_.util.type(o[i]) === 'Array') {
+ _.languages.DFS(o[i], callback, i);
+ }
+ }
+ }
+ }
+ },
+
+ highlightAll: function(async, callback) {
+ var elements = document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');
+
+ for (var i=0, element; element = elements[i++];) {
+ _.highlightElement(element, async === true, callback);
+ }
+ },
+
+ highlightElement: function(element, async, callback) {
+ // Find language
+ var language, grammar, parent = element;
+
+ while (parent && !lang.test(parent.className)) {
+ parent = parent.parentNode;
+ }
+
+ if (parent) {
+ language = (parent.className.match(lang) || [,''])[1];
+ grammar = _.languages[language];
+ }
+
+ if (!grammar) {
+ return;
+ }
+
+ // Set language on the element, if not present
+ element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
+
+ // Set language on the parent, for styling
+ parent = element.parentNode;
+
+ if (/pre/i.test(parent.nodeName)) {
+ parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
+ }
+
+ var code = element.textContent;
+
+ if(!code) {
+ return;
+ }
+
+ code = code.replace(/^(?:\r?\n|\r)/,'');
+
+ var env = {
+ element: element,
+ language: language,
+ grammar: grammar,
+ code: code
+ };
+
+ _.hooks.run('before-highlight', env);
+
+ if (async && self.Worker) {
+ var worker = new Worker(_.filename);
+
+ worker.onmessage = function(evt) {
+ env.highlightedCode = Token.stringify(JSON.parse(evt.data), language);
+
+ _.hooks.run('before-insert', env);
+
+ env.element.innerHTML = env.highlightedCode;
+
+ callback && callback.call(env.element);
+ _.hooks.run('after-highlight', env);
+ };
+
+ worker.postMessage(JSON.stringify({
+ language: env.language,
+ code: env.code
+ }));
+ }
+ else {
+ env.highlightedCode = _.highlight(env.code, env.grammar, env.language);
+
+ _.hooks.run('before-insert', env);
+
+ env.element.innerHTML = env.highlightedCode;
+
+ callback && callback.call(element);
+
+ _.hooks.run('after-highlight', env);
+ }
+ },
+
+ highlight: function (text, grammar, language) {
+ var tokens = _.tokenize(text, grammar);
+ return Token.stringify(_.util.encode(tokens), language);
+ },
+
+ tokenize: function(text, grammar, language) {
+ var Token = _.Token;
+
+ var strarr = [text];
+
+ var rest = grammar.rest;
+
+ if (rest) {
+ for (var token in rest) {
+ grammar[token] = rest[token];
+ }
+
+ delete grammar.rest;
+ }
+
+ tokenloop: for (var token in grammar) {
+ if(!grammar.hasOwnProperty(token) || !grammar[token]) {
+ continue;
+ }
+
+ var patterns = grammar[token];
+ patterns = (_.util.type(patterns) === "Array") ? patterns : [patterns];
+
+ for (var j = 0; j < patterns.length; ++j) {
+ var pattern = patterns[j],
+ inside = pattern.inside,
+ lookbehind = !!pattern.lookbehind,
+ lookbehindLength = 0,
+ alias = pattern.alias;
+
+ pattern = pattern.pattern || pattern;
+
+ for (var i=0; i<strarr.length; i++) { // Don’t cache length as it changes during the loop
+
+ var str = strarr[i];
+
+ if (strarr.length > text.length) {
+ // Something went terribly wrong, ABORT, ABORT!
+ break tokenloop;
+ }
+
+ if (str instanceof Token) {
+ continue;
+ }
+
+ pattern.lastIndex = 0;
+
+ var match = pattern.exec(str);
+
+ if (match) {
+ if(lookbehind) {
+ lookbehindLength = match[1].length;
+ }
+
+ var from = match.index - 1 + lookbehindLength,
+ match = match[0].slice(lookbehindLength),
+ len = match.length,
+ to = from + len,
+ before = str.slice(0, from + 1),
+ after = str.slice(to + 1);
+
+ var args = [i, 1];
+
+ if (before) {
+ args.push(before);
+ }
+
+ var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias);
+
+ args.push(wrapped);
+
+ if (after) {
+ args.push(after);
+ }
+
+ Array.prototype.splice.apply(strarr, args);
+ }
+ }
+ }
+ }
+
+ return strarr;
+ },
+
+ hooks: {
+ all: {},
+
+ add: function (name, callback) {
+ var hooks = _.hooks.all;
+
+ hooks[name] = hooks[name] || [];
+
+ hooks[name].push(callback);
+ },
+
+ run: function (name, env) {
+ var callbacks = _.hooks.all[name];
+
+ if (!callbacks || !callbacks.length) {
+ return;
+ }
+
+ for (var i=0, callback; callback = callbacks[i++];) {
+ callback(env);
+ }
+ }
+ }
+};
+
+var Token = _.Token = function(type, content, alias) {
+ this.type = type;
+ this.content = content;
+ this.alias = alias;
+};
+
+Token.stringify = function(o, language, parent) {
+ if (typeof o == 'string') {
+ return o;
+ }
+
+ if (_.util.type(o) === 'Array') {
+ return o.map(function(element) {
+ return Token.stringify(element, language, o);
+ }).join('');
+ }
+
+ var env = {
+ type: o.type,
+ content: Token.stringify(o.content, language, parent),
+ tag: 'span',
+ classes: ['token', o.type],
+ attributes: {},
+ language: language,
+ parent: parent
+ };
+
+ if (env.type == 'comment') {
+ env.attributes['spellcheck'] = 'true';
+ }
+
+ if (o.alias) {
+ var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias];
+ Array.prototype.push.apply(env.classes, aliases);
+ }
+
+ _.hooks.run('wrap', env);
+
+ var attributes = '';
+
+ for (var name in env.attributes) {
+ attributes += name + '="' + (env.attributes[name] || '') + '"';
+ }
+
+ return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + '</' + env.tag + '>';
+
+};
+
+if (!self.document) {
+ if (!self.addEventListener) {
+ // in Node.js
+ return self.Prism;
+ }
+ // In worker
+ self.addEventListener('message', function(evt) {
+ var message = JSON.parse(evt.data),
+ lang = message.language,
+ code = message.code;
+
+ self.postMessage(JSON.stringify(_.util.encode(_.tokenize(code, _.languages[lang]))));
+ self.close();
+ }, false);
+
+ return self.Prism;
+}
+
+// Get current script and highlight
+var script = document.getElementsByTagName('script');
+
+script = script[script.length - 1];
+
+if (script) {
+ _.filename = script.src;
+
+ if (document.addEventListener && !script.hasAttribute('data-manual')) {
+ document.addEventListener('DOMContentLoaded', _.highlightAll);
+ }
+}
+
+return self.Prism;
+
+})();
+
+if (typeof module !== 'undefined' && module.exports) {
+ module.exports = Prism;
+}
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-core.min.js b/polymer_1.0.4/bower_components/prism/components/prism-core.min.js
new file mode 100644
index 0000000..703d143
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-core.min.js
@@ -0,0 +1 @@
+self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},clone:function(e){var n=t.util.type(e);switch(n){case"Object":var a={};for(var r in e)e.hasOwnProperty(r)&&(a[r]=t.util.clone(e[r]));return a;case"Array":return e.map(function(e){return t.util.clone(e)})}return e}},languages:{extend:function(e,n){var a=t.util.clone(t.languages[e]);for(var r in n)a[r]=n[r];return a},insertBefore:function(e,n,a,r){r=r||t.languages;var i=r[e];if(2==arguments.length){a=arguments[1];for(var l in a)a.hasOwnProperty(l)&&(i[l]=a[l]);return i}var s={};for(var o in i)if(i.hasOwnProperty(o)){if(o==n)for(var l in a)a.hasOwnProperty(l)&&(s[l]=a[l]);s[o]=i[o]}return t.languages.DFS(t.languages,function(t,n){n===r[e]&&t!=e&&(this[t]=s)}),r[e]=s},DFS:function(e,n,a){for(var r in e)e.hasOwnProperty(r)&&(n.call(e,r,e[r],a||r),"Object"===t.util.type(e[r])?t.languages.DFS(e[r],n):"Array"===t.util.type(e[r])&&t.languages.DFS(e[r],n,r))}},highlightAll:function(e,n){for(var a,r=document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'),i=0;a=r[i++];)t.highlightElement(a,e===!0,n)},highlightElement:function(a,r,i){for(var l,s,o=a;o&&!e.test(o.className);)o=o.parentNode;if(o&&(l=(o.className.match(e)||[,""])[1],s=t.languages[l]),s){a.className=a.className.replace(e,"").replace(/\s+/g," ")+" language-"+l,o=a.parentNode,/pre/i.test(o.nodeName)&&(o.className=o.className.replace(e,"").replace(/\s+/g," ")+" language-"+l);var u=a.textContent;if(u){u=u.replace(/^(?:\r?\n|\r)/,"");var g={element:a,language:l,grammar:s,code:u};if(t.hooks.run("before-highlight",g),r&&self.Worker){var c=new Worker(t.filename);c.onmessage=function(e){g.highlightedCode=n.stringify(JSON.parse(e.data),l),t.hooks.run("before-insert",g),g.element.innerHTML=g.highlightedCode,i&&i.call(g.element),t.hooks.run("after-highlight",g)},c.postMessage(JSON.stringify({language:g.language,code:g.code}))}else g.highlightedCode=t.highlight(g.code,g.grammar,g.language),t.hooks.run("before-insert",g),g.element.innerHTML=g.highlightedCode,i&&i.call(a),t.hooks.run("after-highlight",g)}}},highlight:function(e,a,r){var i=t.tokenize(e,a);return n.stringify(t.util.encode(i),r)},tokenize:function(e,n){var a=t.Token,r=[e],i=n.rest;if(i){for(var l in i)n[l]=i[l];delete n.rest}e:for(var l in n)if(n.hasOwnProperty(l)&&n[l]){var s=n[l];s="Array"===t.util.type(s)?s:[s];for(var o=0;o<s.length;++o){var u=s[o],g=u.inside,c=!!u.lookbehind,f=0,h=u.alias;u=u.pattern||u;for(var p=0;p<r.length;p++){var d=r[p];if(r.length>e.length)break e;if(!(d instanceof a)){u.lastIndex=0;var m=u.exec(d);if(m){c&&(f=m[1].length);var y=m.index-1+f,m=m[0].slice(f),v=m.length,k=y+v,b=d.slice(0,y+1),w=d.slice(k+1),N=[p,1];b&&N.push(b);var O=new a(l,g?t.tokenize(m,g):m,h);N.push(O),w&&N.push(w),Array.prototype.splice.apply(r,N)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var i={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}t.hooks.run("wrap",i);var s="";for(var o in i.attributes)s+=o+'="'+(i.attributes[o]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+s+">"+i.content+"</"+i.tag+">"},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(r,t.languages[a])))),self.close()},!1),self.Prism):self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-cpp.js b/polymer_1.0.4/bower_components/prism/components/prism-cpp.js
new file mode 100644
index 0000000..ba0707c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-cpp.js
@@ -0,0 +1,12 @@
+Prism.languages.cpp = Prism.languages.extend('c', {
+ 'keyword': /\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|delete\[\]|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|new\[\]|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,
+ 'boolean': /\b(true|false)\b/,
+ 'operator': /[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/
+});
+
+Prism.languages.insertBefore('cpp', 'keyword', {
+ 'class-name': {
+ pattern: /(class\s+)[a-z0-9_]+/i,
+ lookbehind: true
+ }
+});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-cpp.min.js b/polymer_1.0.4/bower_components/prism/components/prism-cpp.min.js
new file mode 100644
index 0000000..3d02e12
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-cpp.min.js
@@ -0,0 +1 @@
+Prism.languages.cpp=Prism.languages.extend("c",{keyword:/\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|delete\[\]|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|new\[\]|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,"boolean":/\b(true|false)\b/,operator:/[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/}),Prism.languages.insertBefore("cpp","keyword",{"class-name":{pattern:/(class\s+)[a-z0-9_]+/i,lookbehind:!0}});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-csharp.js b/polymer_1.0.4/bower_components/prism/components/prism-csharp.js
new file mode 100644
index 0000000..50ee493
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-csharp.js
@@ -0,0 +1,9 @@
+Prism.languages.csharp = Prism.languages.extend('clike', {
+ 'keyword': /\b(abstract|as|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|async|await|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)\b/,
+ 'string': [
+ /@("|')(\1\1|\\\1|\\?(?!\1)[\s\S])*\1/,
+ /("|')(\\?.)*?\1/
+ ],
+ 'preprocessor': /^\s*#.*/m,
+ 'number': /\b-?(0x[\da-f]+|\d*\.?\d+)\b/i
+});
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-csharp.min.js b/polymer_1.0.4/bower_components/prism/components/prism-csharp.min.js
new file mode 100644
index 0000000..abde3d0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-csharp.min.js
@@ -0,0 +1 @@
+Prism.languages.csharp=Prism.languages.extend("clike",{keyword:/\b(abstract|as|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|async|await|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)\b/,string:[/@("|')(\1\1|\\\1|\\?(?!\1)[\s\S])*\1/,/("|')(\\?.)*?\1/],preprocessor:/^\s*#.*/m,number:/\b-?(0x[\da-f]+|\d*\.?\d+)\b/i});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-css-extras.js b/polymer_1.0.4/bower_components/prism/components/prism-css-extras.js
new file mode 100644
index 0000000..766a5b0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-css-extras.js
@@ -0,0 +1,15 @@
+Prism.languages.css.selector = {
+ pattern: /[^\{\}\s][^\{\}]*(?=\s*\{)/,
+ inside: {
+ 'pseudo-element': /:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,
+ 'pseudo-class': /:[-\w]+(?:\(.*\))?/,
+ 'class': /\.[-:\.\w]+/,
+ 'id': /#[-:\.\w]+/
+ }
+};
+
+Prism.languages.insertBefore('css', 'function', {
+ 'hexcode': /#[\da-f]{3,6}/i,
+ 'entity': /\\[\da-f]{1,8}/i,
+ 'number': /[\d%\.]+/
+});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-css-extras.min.js b/polymer_1.0.4/bower_components/prism/components/prism-css-extras.min.js
new file mode 100644
index 0000000..0a753ea
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-css-extras.min.js
@@ -0,0 +1 @@
+Prism.languages.css.selector={pattern:/[^\{\}\s][^\{\}]*(?=\s*\{)/,inside:{"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+(?:\(.*\))?/,"class":/\.[-:\.\w]+/,id:/#[-:\.\w]+/}},Prism.languages.insertBefore("css","function",{hexcode:/#[\da-f]{3,6}/i,entity:/\\[\da-f]{1,8}/i,number:/[\d%\.]+/});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-css.js b/polymer_1.0.4/bower_components/prism/components/prism-css.js
new file mode 100644
index 0000000..4b0b721
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-css.js
@@ -0,0 +1,50 @@
+Prism.languages.css = {
+ 'comment': /\/\*[\w\W]*?\*\//,
+ 'atrule': {
+ pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i,
+ inside: {
+ 'punctuation': /[;:]/
+ }
+ },
+ 'url': /url\((?:(["'])(\\\n|\\?.)*?\1|.*?)\)/i,
+ 'selector': /[^\{\}\s][^\{\};]*(?=\s*\{)/,
+ 'string': /("|')(\\\n|\\?.)*?\1/,
+ 'property': /(\b|\B)[\w-]+(?=\s*:)/i,
+ 'important': /\B!important\b/i,
+ 'punctuation': /[\{\};:]/,
+ 'function': /[-a-z0-9]+(?=\()/i
+};
+
+if (Prism.languages.markup) {
+ Prism.languages.insertBefore('markup', 'tag', {
+ 'style': {
+ pattern: /<style[\w\W]*?>[\w\W]*?<\/style>/i,
+ inside: {
+ 'tag': {
+ pattern: /<style[\w\W]*?>|<\/style>/i,
+ inside: Prism.languages.markup.tag.inside
+ },
+ rest: Prism.languages.css
+ },
+ alias: 'language-css'
+ }
+ });
+
+ Prism.languages.insertBefore('inside', 'attr-value', {
+ 'style-attr': {
+ pattern: /\s*style=("|').*?\1/i,
+ inside: {
+ 'attr-name': {
+ pattern: /^\s*style/i,
+ inside: Prism.languages.markup.tag.inside
+ },
+ 'punctuation': /^\s*=\s*['"]|['"]\s*$/,
+ 'attr-value': {
+ pattern: /.+/i,
+ inside: Prism.languages.css
+ }
+ },
+ alias: 'language-css'
+ }
+ }, Prism.languages.markup.tag);
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-css.min.js b/polymer_1.0.4/bower_components/prism/components/prism-css.min.js
new file mode 100644
index 0000000..a7d624b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-css.min.js
@@ -0,0 +1 @@
+Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{punctuation:/[;:]/}},url:/url\((?:(["'])(\\\n|\\?.)*?\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/,string:/("|')(\\\n|\\?.)*?\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,punctuation:/[\{\};:]/,"function":/[-a-z0-9]+(?=\()/i},Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/<style[\w\W]*?>[\w\W]*?<\/style>/i,inside:{tag:{pattern:/<style[\w\W]*?>|<\/style>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css},alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag));
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-dart.js b/polymer_1.0.4/bower_components/prism/components/prism-dart.js
new file mode 100644
index 0000000..5a6e68a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-dart.js
@@ -0,0 +1,18 @@
+Prism.languages.dart = Prism.languages.extend('clike', {
+ 'string': [
+ /r?("""|''')[\s\S]*?\1/,
+ /r?("|')(\\?.)*?\1/
+ ],
+ 'keyword': [
+ /\b(?:async|sync|yield)\*/,
+ /\b(?:abstract|assert|async|await|break|case|catch|class|const|continue|default|deferred|do|dynamic|else|enum|export|external|extends|factory|final|finally|for|get|if|implements|import|in|library|new|null|operator|part|rethrow|return|set|static|super|switch|this|throw|try|typedef|var|void|while|with|yield)\b/
+ ],
+ 'operator': /\bis!|\b(?:as|is)\b|\+\+|--|&&|\|\||<<=?|>>=?|~(?:\/=?)?|[+\-*\/%&^|=!<>]=?|\?/
+});
+
+Prism.languages.insertBefore('dart','function',{
+ 'metadata': {
+ pattern: /@\w+/,
+ alias: 'symbol'
+ }
+});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-dart.min.js b/polymer_1.0.4/bower_components/prism/components/prism-dart.min.js
new file mode 100644
index 0000000..78dda7f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-dart.min.js
@@ -0,0 +1 @@
+Prism.languages.dart=Prism.languages.extend("clike",{string:[/r?("""|''')[\s\S]*?\1/,/r?("|')(\\?.)*?\1/],keyword:[/\b(?:async|sync|yield)\*/,/\b(?:abstract|assert|async|await|break|case|catch|class|const|continue|default|deferred|do|dynamic|else|enum|export|external|extends|factory|final|finally|for|get|if|implements|import|in|library|new|null|operator|part|rethrow|return|set|static|super|switch|this|throw|try|typedef|var|void|while|with|yield)\b/],operator:/\bis!|\b(?:as|is)\b|\+\+|--|&&|\|\||<<=?|>>=?|~(?:\/=?)?|[+\-*\/%&^|=!<>]=?|\?/}),Prism.languages.insertBefore("dart","function",{metadata:{pattern:/@\w+/,alias:"symbol"}});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-eiffel.js b/polymer_1.0.4/bower_components/prism/components/prism-eiffel.js
new file mode 100644
index 0000000..a6da3f6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-eiffel.js
@@ -0,0 +1,24 @@
+Prism.languages.eiffel = {
+ 'string': [
+ // Single-line string
+ /"(?:%\s+%|%"|.)*?"/,
+ // Aligned-verbatim-strings
+ /"([^[]*)\[[\s\S]+?\]\1"/,
+ // Non-aligned-verbatim-strings
+ /"([^{]*)\{[\s\S]+?\}\1"/
+ ],
+ // (comments including quoted strings not supported)
+ 'comment': /--.*/,
+ // normal char | special char | char code
+ 'char': /'(?:%'|.)+?'/,
+ 'keyword': /\b(?:across|agent|alias|all|and|attached|as|assign|attribute|check|class|convert|create|Current|debug|deferred|detachable|do|else|elseif|end|ensure|expanded|export|external|feature|from|frozen|if|implies|inherit|inspect|invariant|like|local|loop|not|note|obsolete|old|once|or|Precursor|redefine|rename|require|rescue|Result|retry|select|separate|some|then|undefine|until|variant|Void|when|xor)\b/i,
+ 'boolean': /\b(?:True|False)\b/i,
+ 'number': [
+ // hexa | octal | bin
+ /\b0[xcb][\da-f](?:_*[\da-f])*\b/i,
+ // Decimal
+ /(?:\d(?:_*\d)*)?\.(?:(?:\d(?:_*\d)*)?[eE][+-]?)?\d(?:_*\d)*|\d(?:_*\d)*\.?/
+ ],
+ 'punctuation': /:=|<<|>>|\(\||\|\)|->|\.(?=\w)|[{}[\];(),:?]/,
+ 'operator': /\\\\|\|\.\.\||\.\.|\/[~\/]?|[><\/]=?|[-+*^=~]/
+};
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-eiffel.min.js b/polymer_1.0.4/bower_components/prism/components/prism-eiffel.min.js
new file mode 100644
index 0000000..d9c8ab3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-eiffel.min.js
@@ -0,0 +1 @@
+Prism.languages.eiffel={string:[/"(?:%\s+%|%"|.)*?"/,/"([^[]*)\[[\s\S]+?\]\1"/,/"([^{]*)\{[\s\S]+?\}\1"/],comment:/--.*/,"char":/'(?:%'|.)+?'/,keyword:/\b(?:across|agent|alias|all|and|attached|as|assign|attribute|check|class|convert|create|Current|debug|deferred|detachable|do|else|elseif|end|ensure|expanded|export|external|feature|from|frozen|if|implies|inherit|inspect|invariant|like|local|loop|not|note|obsolete|old|once|or|Precursor|redefine|rename|require|rescue|Result|retry|select|separate|some|then|undefine|until|variant|Void|when|xor)\b/i,"boolean":/\b(?:True|False)\b/i,number:[/\b0[xcb][\da-f](?:_*[\da-f])*\b/i,/(?:\d(?:_*\d)*)?\.(?:(?:\d(?:_*\d)*)?[eE][+-]?)?\d(?:_*\d)*|\d(?:_*\d)*\.?/],punctuation:/:=|<<|>>|\(\||\|\)|->|\.(?=\w)|[{}[\];(),:?]/,operator:/\\\\|\|\.\.\||\.\.|\/[~\/]?|[><\/]=?|[-+*^=~]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-erlang.js b/polymer_1.0.4/bower_components/prism/components/prism-erlang.js
new file mode 100644
index 0000000..deea6aa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-erlang.js
@@ -0,0 +1,35 @@
+Prism.languages.erlang = {
+ 'comment': /%.+/,
+ 'string': /"(?:\\?.)*?"/,
+ 'quoted-function': {
+ pattern: /'[^']+'(?=\()/,
+ alias: 'function'
+ },
+ 'quoted-atom': {
+ pattern: /'[^']+'/,
+ alias: 'atom'
+ },
+ 'boolean': /\b(?:true|false)\b/,
+ 'keyword': /\b(?:fun|when|case|of|end|if|receive|after|try|catch)\b/,
+ 'number': [
+ /\$\\?./,
+ /\d+#[a-z0-9]+/i,
+ /(?:\b|-)\d*\.?\d+([Ee][+-]?\d+)?\b/
+ ],
+ 'function': /\b[a-z][\w@]*(?=\()/,
+ 'variable': /(?:\b|\?)[A-Z_][\w@]*/,
+ 'operator': [
+ /[=\/>:]=|>=|=[:\/]=|\+\+?|--?|[=*\/!]|\b(?:bnot|div|rem|band|bor|bxor|bsl|bsr|not|and|or|xor|orelse|andalso)\b/,
+ {
+ pattern: /(^|(?!<).)<(?!<)/,
+ lookbehind: true
+ },
+ {
+ pattern: /(^|(?!>).)>(?!>)/,
+ lookbehind: true
+ }
+ ],
+ 'atom': /\b[a-z][\w@]*/,
+ 'punctuation': /[()[\]{}:;,.#|]|<<|>>/
+
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-erlang.min.js b/polymer_1.0.4/bower_components/prism/components/prism-erlang.min.js
new file mode 100644
index 0000000..6a072b6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-erlang.min.js
@@ -0,0 +1 @@
+Prism.languages.erlang={comment:/%.+/,string:/"(?:\\?.)*?"/,"quoted-function":{pattern:/'[^']+'(?=\()/,alias:"function"},"quoted-atom":{pattern:/'[^']+'/,alias:"atom"},"boolean":/\b(?:true|false)\b/,keyword:/\b(?:fun|when|case|of|end|if|receive|after|try|catch)\b/,number:[/\$\\?./,/\d+#[a-z0-9]+/i,/(?:\b|-)\d*\.?\d+([Ee][+-]?\d+)?\b/],"function":/\b[a-z][\w@]*(?=\()/,variable:/(?:\b|\?)[A-Z_][\w@]*/,operator:[/[=\/>:]=|>=|=[:\/]=|\+\+?|--?|[=*\/!]|\b(?:bnot|div|rem|band|bor|bxor|bsl|bsr|not|and|or|xor|orelse|andalso)\b/,{pattern:/(^|(?!<).)<(?!<)/,lookbehind:!0},{pattern:/(^|(?!>).)>(?!>)/,lookbehind:!0}],atom:/\b[a-z][\w@]*/,punctuation:/[()[\]{}:;,.#|]|<<|>>/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-fortran.js b/polymer_1.0.4/bower_components/prism/components/prism-fortran.js
new file mode 100644
index 0000000..6448dad
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-fortran.js
@@ -0,0 +1,34 @@
+Prism.languages.fortran = {
+ 'quoted-number': {
+ pattern: /[BOZ](['"])[A-F0-9]+\1/i,
+ alias: 'number'
+ },
+ 'string': {
+ pattern: /(?:\w+_)?(['"])(?:\1\1|&\n(?:\s*!.+\n)?|(?!\1).)*(?:\1|&)/,
+ inside: {
+ 'comment': /!.*/
+ }
+ },
+ 'comment': /!.*/,
+ 'boolean': /\.(?:TRUE|FALSE)\.(?:_\w+)?/i,
+ 'number': /(?:\b|[+-])(?:\d+(?:\.\d*)?|\.\d+)(?:[ED][+-]?\d+)?(?:_\w+)?/i,
+ 'keyword': [
+ // Types
+ /\b(?:INTEGER|REAL|DOUBLE ?PRECISION|COMPLEX|CHARACTER|LOGICAL)\b/i,
+ // Statements
+ /\b(?:ALLOCATABLE|ALLOCATE|BACKSPACE|CALL|CASE|CLOSE|COMMON|CONTAINS|CONTINUE|CYCLE|DATA|DEALLOCATE|DIMENSION|DO|END|EQUIVALENCE|EXIT|EXTERNAL|FORMAT|GO ?TO|IMPLICIT(?: NONE)?|INQUIRE|INTENT|INTRINSIC|MODULE PROCEDURE|NAMELIST|NULLIFY|OPEN|OPTIONAL|PARAMETER|POINTER|PRINT|PRIVATE|PUBLIC|READ|RETURN|REWIND|SAVE|SELECT|STOP|TARGET|WHILE|WRITE)\b/i,
+ // END statements
+ /\b(?:END ?)?(?:BLOCK ?DATA|DO|FILE|FORALL|FUNCTION|IF|INTERFACE|MODULE|PROGRAM|SELECT|SUBROUTINE|TYPE|WHERE)\b/i,
+ // Others
+ /\b(?:ASSIGNMENT|DEFAULT|ELEMENTAL|ELSE|ELSEWHERE|ELSEIF|ENTRY|IN|INCLUDE|INOUT|KIND|NULL|ONLY|OPERATOR|OUT|PURE|RECURSIVE|RESULT|SEQUENCE|STAT|THEN|USE)\b/i
+ ],
+ 'operator': [
+ /\*\*|\/\/|=>|[=\/]=|[<>]=?|::|[+\-*=%]|\.(?:EQ|NE|LT|LE|GT|GE|NOT|AND|OR|EQV|NEQV)\.|\.[A-Z]+\./i,
+ {
+ // Use lookbehind to prevent confusion with (/ /)
+ pattern: /(^|(?!\().)\/(?!\))/,
+ lookbehind: true
+ }
+ ],
+ 'punctuation': /\(\/|\/\)|[(),;:&]/
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-fortran.min.js b/polymer_1.0.4/bower_components/prism/components/prism-fortran.min.js
new file mode 100644
index 0000000..407cc96
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-fortran.min.js
@@ -0,0 +1 @@
+Prism.languages.fortran={"quoted-number":{pattern:/[BOZ](['"])[A-F0-9]+\1/i,alias:"number"},string:{pattern:/(?:\w+_)?(['"])(?:\1\1|&\n(?:\s*!.+\n)?|(?!\1).)*(?:\1|&)/,inside:{comment:/!.*/}},comment:/!.*/,"boolean":/\.(?:TRUE|FALSE)\.(?:_\w+)?/i,number:/(?:\b|[+-])(?:\d+(?:\.\d*)?|\.\d+)(?:[ED][+-]?\d+)?(?:_\w+)?/i,keyword:[/\b(?:INTEGER|REAL|DOUBLE ?PRECISION|COMPLEX|CHARACTER|LOGICAL)\b/i,/\b(?:ALLOCATABLE|ALLOCATE|BACKSPACE|CALL|CASE|CLOSE|COMMON|CONTAINS|CONTINUE|CYCLE|DATA|DEALLOCATE|DIMENSION|DO|END|EQUIVALENCE|EXIT|EXTERNAL|FORMAT|GO ?TO|IMPLICIT(?: NONE)?|INQUIRE|INTENT|INTRINSIC|MODULE PROCEDURE|NAMELIST|NULLIFY|OPEN|OPTIONAL|PARAMETER|POINTER|PRINT|PRIVATE|PUBLIC|READ|RETURN|REWIND|SAVE|SELECT|STOP|TARGET|WHILE|WRITE)\b/i,/\b(?:END ?)?(?:BLOCK ?DATA|DO|FILE|FORALL|FUNCTION|IF|INTERFACE|MODULE|PROGRAM|SELECT|SUBROUTINE|TYPE|WHERE)\b/i,/\b(?:ASSIGNMENT|DEFAULT|ELEMENTAL|ELSE|ELSEWHERE|ELSEIF|ENTRY|IN|INCLUDE|INOUT|KIND|NULL|ONLY|OPERATOR|OUT|PURE|RECURSIVE|RESULT|SEQUENCE|STAT|THEN|USE)\b/i],operator:[/\*\*|\/\/|=>|[=\/]=|[<>]=?|::|[+\-*=%]|\.(?:EQ|NE|LT|LE|GT|GE|NOT|AND|OR|EQV|NEQV)\.|\.[A-Z]+\./i,{pattern:/(^|(?!\().)\/(?!\))/,lookbehind:!0}],punctuation:/\(\/|\/\)|[(),;:&]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-fsharp.js b/polymer_1.0.4/bower_components/prism/components/prism-fsharp.js
new file mode 100644
index 0000000..cb4f5d5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-fsharp.js
@@ -0,0 +1,21 @@
+Prism.languages.fsharp = Prism.languages.extend('clike', {
+ 'comment': [
+ {
+ pattern: /(^|[^\\])\(\*[\w\W]*?\*\)/,
+ lookbehind: true
+ },
+ {
+ pattern: /(^|[^\\:])\/\/.*/,
+ lookbehind: true
+ }
+ ],
+ 'keyword': /\b(abstract|and|as|assert|base|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|global|if|in|inherit|inline|interface|internal|lazy|let|let!|match|member|module|mutable|namespace|new|not|null|of|open|or|override|private|public|rec|return|return!|select|static|struct|then|to|true|try|type|upcast|use|use!|val|void|when|while|with|yield|yield!|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|include|method|mixin|object|parallel|process|protected|pure|sealed|tailcall|trait|virtual|volatile)\b/,
+ 'string': /@?("""|"|')((\\|\n)?.)*?\1B?/,
+ 'preprocessor': /^\s*#.*/m,
+ 'number': [
+ /\b-?0x[\da-fA-F]+(un|lf|LF)?\b/,
+ /\b-?0b[01]+(y|uy)?\b/,
+ /\b-?(\d+\.|\d*\.?\d+)([fFmM]|[eE][+-]?\d+)?\b/,
+ /\b-?\d+(y|uy|s|us|l|u|ul|L|UL|I)?\b/
+ ]
+});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-fsharp.min.js b/polymer_1.0.4/bower_components/prism/components/prism-fsharp.min.js
new file mode 100644
index 0000000..785f391
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-fsharp.min.js
@@ -0,0 +1 @@
+Prism.languages.fsharp=Prism.languages.extend("clike",{comment:[{pattern:/(^|[^\\])\(\*[\w\W]*?\*\)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],keyword:/\b(abstract|and|as|assert|base|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|global|if|in|inherit|inline|interface|internal|lazy|let|let!|match|member|module|mutable|namespace|new|not|null|of|open|or|override|private|public|rec|return|return!|select|static|struct|then|to|true|try|type|upcast|use|use!|val|void|when|while|with|yield|yield!|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|include|method|mixin|object|parallel|process|protected|pure|sealed|tailcall|trait|virtual|volatile)\b/,string:/@?("""|"|')((\\|\n)?.)*?\1B?/,preprocessor:/^\s*#.*/m,number:[/\b-?0x[\da-fA-F]+(un|lf|LF)?\b/,/\b-?0b[01]+(y|uy)?\b/,/\b-?(\d+\.|\d*\.?\d+)([fFmM]|[eE][+-]?\d+)?\b/,/\b-?\d+(y|uy|s|us|l|u|ul|L|UL|I)?\b/]});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-gherkin.js b/polymer_1.0.4/bower_components/prism/components/prism-gherkin.js
new file mode 100644
index 0000000..f0793ee
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-gherkin.js
@@ -0,0 +1,78 @@
+Prism.languages.gherkin = {
+ 'pystring': {
+ pattern: /("""|''')[\s\S]+?\1/,
+ alias: 'string'
+ },
+ 'comment': {
+ pattern: /((^|\n)[ \t]*)#.*/,
+ lookbehind: true
+ },
+ 'tag': {
+ pattern: /((^|\n)[ \t]*)@.*/,
+ lookbehind: true
+ },
+ 'feature': {
+ pattern: /((^|\n)[ \t]*)(Ability|Ahoy matey!|Arwedd|Aspekt|Besigheid Behoefte|Business Need|Caracteristica|Característica|Egenskab|Egenskap|Eiginleiki|Feature|Fīča|Fitur|Fonctionnalité|Fonksyonalite|Funcionalidade|Funcionalitat|Functionalitate|Funcţionalitate|Funcționalitate|Functionaliteit|Fungsi|Funkcia|Funkcija|Funkcionalitāte|Funkcionalnost|Funkcja|Funksie|Funktionalität|Funktionalitéit|Funzionalità|Hwaet|Hwæt|Jellemző|Karakteristik|laH|Lastnost|Mak|Mogucnost|Mogućnost|Moznosti|Možnosti|OH HAI|Omadus|Ominaisuus|Osobina|Özellik|perbogh|poQbogh malja'|Potrzeba biznesowa|Požadavek|Požiadavka|Pretty much|Qap|Qu'meH 'ut|Savybė|Tính năng|Trajto|Vermoë|Vlastnosť|Właściwość|Značilnost|Δυνατότητα|Λειτουργία|Могућност|Мөмкинлек|Особина|Свойство|Үзенчәлеклелек|Функционал|Функционалност|Функция|Функціонал|תכונה|خاصية|خصوصیت|صلاحیت|کاروبار کی ضرورت|وِیژگی|रूप लेख|ਖਾਸੀਅਤ|ਨਕਸ਼ ਨੁਹਾਰ|ਮੁਹਾਂਦਰਾ|గుణము|ಹೆಚ್ಚಳ|ความต้องการทางธุรกิจ|ความสามารถ|โครงหลัก|기능|フィーチャ|功能|機能):([^:]+\n)*/,
+ lookbehind: true,
+ inside: {
+ 'important': {
+ pattern: /(:)[^\n]+/,
+ lookbehind: true
+ },
+ keyword: /[^:\n]+:/
+ }
+ },
+ 'scenario': {
+ pattern: /((^|\n)[ \t]*)(Abstract Scenario|Abstrakt Scenario|Achtergrond|Aer|Ær|Agtergrond|All y'all|Antecedentes|Antecedents|Atburðarás|Atburðarásir|Awww, look mate|B4|Background|Baggrund|Bakgrund|Bakgrunn|Bakgrunnur|Beispiele|Beispiller|Bối cảnh|Cefndir|Cenario|Cenário|Cenario de Fundo|Cenário de Fundo|Cenarios|Cenários|Contesto|Context|Contexte|Contexto|Conto|Contoh|Contone|Dæmi|Dasar|Dead men tell no tales|Delineacao do Cenario|Delineação do Cenário|Dis is what went down|Dữ liệu|Dyagram senaryo|Dyagram Senaryo|Egzanp|Ejemplos|Eksempler|Ekzemploj|Enghreifftiau|Esbozo do escenario|Escenari|Escenario|Esempi|Esquema de l'escenari|Esquema del escenario|Esquema do Cenario|Esquema do Cenário|Examples|EXAMPLZ|Exempel|Exemple|Exemples|Exemplos|First off|Fono|Forgatókönyv|Forgatókönyv vázlat|Fundo|Geçmiş|ghantoH|Grundlage|Hannergrond|Háttér|Heave to|Istorik|Juhtumid|Keadaan|Khung kịch bản|Khung tình huống|Kịch bản|Koncept|Konsep skenario|Kontèks|Kontekst|Kontekstas|Konteksts|Kontext|Konturo de la scenaro|Latar Belakang|lut|lut chovnatlh|lutmey|Lýsing Atburðarásar|Lýsing Dæma|Menggariskan Senario|MISHUN|MISHUN SRSLY|mo'|Náčrt Scenára|Náčrt Scénáře|Náčrt Scenáru|Oris scenarija|Örnekler|Osnova|Osnova Scenára|Osnova scénáře|Osnutek|Ozadje|Paraugs|Pavyzdžiai|Példák|Piemēri|Plan du scénario|Plan du Scénario|Plan senaryo|Plan Senaryo|Plang vum Szenario|Pozadí|Pozadie|Pozadina|Príklady|Příklady|Primer|Primeri|Primjeri|Przykłady|Raamstsenaarium|Reckon it's like|Rerefons|Scenár|Scénář|Scenarie|Scenarij|Scenarijai|Scenarijaus šablonas|Scenariji|Scenārijs|Scenārijs pēc parauga|Scenarijus|Scenario|Scénario|Scenario Amlinellol|Scenario Outline|Scenario Template|Scenariomal|Scenariomall|Scenarios|Scenariu|Scenariusz|Scenaro|Schema dello scenario|Se ðe|Se the|Se þe|Senario|Senaryo|Senaryo deskripsyon|Senaryo Deskripsyon|Senaryo taslağı|Shiver me timbers|Situācija|Situai|Situasie|Situasie Uiteensetting|Skenario|Skenario konsep|Skica|Structura scenariu|Structură scenariu|Struktura scenarija|Stsenaarium|Swa|Swa hwaer swa|Swa hwær swa|Szablon scenariusza|Szenario|Szenariogrundriss|Tapaukset|Tapaus|Tapausaihio|Taust|Tausta|Template Keadaan|Template Senario|Template Situai|The thing of it is|Tình huống|Variantai|Voorbeelde|Voorbeelden|Wharrimean is|Yo\-ho\-ho|You'll wanna|Założenia|Παραδείγματα|Περιγραφή Σεναρίου|Σενάρια|Σενάριο|Υπόβαθρο|Кереш|Контекст|Концепт|Мисаллар|Мисоллар|Основа|Передумова|Позадина|Предистория|Предыстория|Приклади|Пример|Примери|Примеры|Рамка на сценарий|Скица|Структура сценарија|Структура сценария|Структура сценарію|Сценарий|Сценарий структураси|Сценарийның төзелеше|Сценарији|Сценарио|Сценарій|Тарих|Үрнәкләр|דוגמאות|רקע|תבנית תרחיש|תרחיש|الخلفية|الگوی سناریو|امثلة|پس منظر|زمینه|سناریو|سيناريو|سيناريو مخطط|مثالیں|منظر نامے کا خاکہ|منظرنامہ|نمونه ها|उदाहरण|परिदृश्य|परिदृश्य रूपरेखा|पृष्ठभूमि|ਉਦਾਹਰਨਾਂ|ਪਟਕਥਾ|ਪਟਕਥਾ ਢਾਂਚਾ|ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ|ਪਿਛੋਕੜ|ఉదాహరణలు|కథనం|నేపథ్యం|సన్నివేశం|ಉದಾಹರಣೆಗಳು|ಕಥಾಸಾರಾಂಶ|ವಿವರಣೆ|ಹಿನ್ನೆಲೆ|โครงสร้างของเหตุการณ์|ชุดของตัวอย่าง|ชุดของเหตุการณ์|แนวคิด|สรุปเหตุการณ์|เหตุการณ์|배경|시나리오|시나리오 개요|예|サンプル|シナリオ|シナリオアウトライン|シナリオテンプレ|シナリオテンプレート|テンプレ|例|例子|剧本|剧本大纲|劇本|劇本大綱|场景|场景大纲|場景|場景大綱|背景):[^:\n]*/,
+ lookbehind: true,
+ inside: {
+ 'important': {
+ pattern: /(:)[^\n]*/,
+ lookbehind: true
+ },
+ keyword: /[^:\n]+:/
+ }
+ },
+ 'table-body': {
+ pattern: /(\n[ \t]*\|.+\|[^\n]*)+/,
+ lookbehind: true,
+ inside: {
+ 'outline': {
+ pattern: /<[^>]+?>/,
+ alias: 'variable'
+ },
+ 'td': {
+ pattern: /[^|]+/,
+ alias: 'string'
+ },
+ 'punctuation': /\|/
+ }
+ },
+ 'table-head': {
+ pattern: /(\n[ \t]*\|.+\|[^\n]*)/,
+ inside: {
+ 'th': {
+ pattern: /[^|]+/,
+ alias: 'variable'
+ },
+ 'punctuation': /\|/
+ }
+ },
+ 'atrule': {
+ pattern: /(\n[ \t]+)('ach|'a|'ej|7|a|A také|A taktiež|A tiež|A zároveň|Aber|Ac|Adott|Akkor|Ak|Aleshores|Ale|Ali|Allora|Alors|Als|Ama|Amennyiben|Amikor|Ampak|an|AN|Ananging|And y'all|And|Angenommen|Anrhegedig a|An|Apabila|Atès|Atesa|Atunci|Avast!|Aye|A|awer|Bagi|Banjur|Bet|Biết|Blimey!|Buh|But at the end of the day I reckon|But y'all|But|BUT|Cal|Când|Cando|Cand|Ce|Cuando|Če|Ða ðe|Ða|Dadas|Dada|Dados|Dado|DaH ghu' bejlu'|dann|Dann|Dano|Dan|Dar|Dat fiind|Data|Date fiind|Date|Dati fiind|Dati|Daţi fiind|Dați fiind|Dato|DEN|Den youse gotta|Dengan|De|Diberi|Diyelim ki|Donada|Donat|Donitaĵo|Do|Dun|Duota|Ðurh|Eeldades|Ef|Eğer ki|Entao|Então|Entón|Entonces|En|Epi|E|És|Etant donnée|Etant donné|Et|Étant données|Étant donnée|Étant donné|Etant données|Etant donnés|Étant donnés|Fakat|Gangway!|Gdy|Gegeben seien|Gegeben sei|Gegeven|Gegewe|ghu' noblu'|Gitt|Given y'all|Given|Givet|Givun|Ha|Cho|I CAN HAZ|In|Ir|It's just unbelievable|I|Ja|Jeśli|Jeżeli|Kadar|Kada|Kad|Kai|Kaj|Když|Keď|Kemudian|Ketika|Khi|Kiedy|Ko|Kuid|Kui|Kun|Lan|latlh|Le sa a|Let go and haul|Le|Lè sa a|Lè|Logo|Lorsqu'<|Lorsque|mä|Maar|Mais|Mając|Majd|Maka|Manawa|Mas|Ma|Menawa|Men|Mutta|Nalikaning|Nalika|Nanging|Når|När|Nato|Nhưng|Niin|Njuk|O zaman|Og|Och|Oletetaan|Onda|Ond|Oraz|Pak|Pero|Però|Podano|Pokiaľ|Pokud|Potem|Potom|Privzeto|Pryd|qaSDI'|Quando|Quand|Quan|Så|Sed|Se|Siis|Sipoze ke|Sipoze Ke|Sipoze|Si|Şi|Și|Soit|Stel|Tada|Tad|Takrat|Tak|Tapi|Ter|Tetapi|Tha the|Tha|Then y'all|Then|Thì|Thurh|Toda|Too right|ugeholl|Und|Un|Và|vaj|Vendar|Ve|wann|Wanneer|WEN|Wenn|When y'all|When|Wtedy|Wun|Y'know|Yeah nah|Yna|Youse know like when|Youse know when youse got|Y|Za predpokladu|Za předpokladu|Zadani|Zadano|Zadan|Zadate|Zadato|Zakładając|Zaradi|Zatati|Þa|Þá|Þa þe|Þegar|Þurh|Αλλά|Δεδομένου|Και|Όταν|Τότε|А також|Агар|Але|Али|Аммо|А|Әгәр|Әйтик|Әмма|Бирок|Ва|Вә|Дадено|Дано|Допустим|Если|Задате|Задати|Задато|И|І|К тому же|Када|Кад|Когато|Когда|Коли|Ләкин|Лекин|Нәтиҗәдә|Нехай|Но|Онда|Припустимо, що|Припустимо|Пусть|Также|Та|Тогда|Тоді|То|Унда|Һәм|Якщо|אבל|אזי|אז|בהינתן|וגם|כאשר|آنگاه|اذاً|اگر|اما|اور|با فرض|بالفرض|بفرض|پھر|تب|ثم|جب|عندما|فرض کیا|لكن|لیکن|متى|هنگامی|و|अगर|और|कदा|किन्तु|चूंकि|जब|तथा|तदा|तब|परन्तु|पर|यदि|ਅਤੇ|ਜਦੋਂ|ਜਿਵੇਂ ਕਿ|ਜੇਕਰ|ਤਦ|ਪਰ|అప్పుడు|ఈ పరిస్థితిలో|కాని|చెప్పబడినది|మరియు|ಆದರೆ|ನಂತರ|ನೀಡಿದ|ಮತ್ತು|ಸ್ಥಿತಿಯನ್ನು|กำหนดให้|ดังนั้น|แต่|เมื่อ|และ|그러면<|그리고<|단<|만약<|만일<|먼저<|조건<|하지만<|かつ<|しかし<|ただし<|ならば<|もし<|並且<|但し<|但是<|假如<|假定<|假設<|假设<|前提<|同时<|同時<|并且<|当<|當<|而且<|那么<|那麼<)(?=[ \t]+)/,
+ lookbehind: true
+ },
+ 'string': {
+ pattern: /("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')/,
+ inside: {
+ 'outline': {
+ pattern: /<[^>]+?>/,
+ alias: 'variable'
+ }
+ }
+ },
+ 'outline': {
+ pattern: /<[^>]+?>/,
+ alias: 'variable'
+ }
+};
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-gherkin.min.js b/polymer_1.0.4/bower_components/prism/components/prism-gherkin.min.js
new file mode 100644
index 0000000..6e278d6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-gherkin.min.js
@@ -0,0 +1 @@
+Prism.languages.gherkin={pystring:{pattern:/("""|''')[\s\S]+?\1/,alias:"string"},comment:{pattern:/((^|\n)[ \t]*)#.*/,lookbehind:!0},tag:{pattern:/((^|\n)[ \t]*)@.*/,lookbehind:!0},feature:{pattern:/((^|\n)[ \t]*)(Ability|Ahoy matey!|Arwedd|Aspekt|Besigheid Behoefte|Business Need|Caracteristica|Característica|Egenskab|Egenskap|Eiginleiki|Feature|Fīča|Fitur|Fonctionnalité|Fonksyonalite|Funcionalidade|Funcionalitat|Functionalitate|Funcţionalitate|Funcționalitate|Functionaliteit|Fungsi|Funkcia|Funkcija|Funkcionalitāte|Funkcionalnost|Funkcja|Funksie|Funktionalität|Funktionalitéit|Funzionalità|Hwaet|Hwæt|Jellemző|Karakteristik|laH|Lastnost|Mak|Mogucnost|Mogućnost|Moznosti|Možnosti|OH HAI|Omadus|Ominaisuus|Osobina|Özellik|perbogh|poQbogh malja'|Potrzeba biznesowa|Požadavek|Požiadavka|Pretty much|Qap|Qu'meH 'ut|Savybė|Tính năng|Trajto|Vermoë|Vlastnosť|Właściwość|Značilnost|Δυνατότητα|Λειτουργία|Могућност|Мөмкинлек|Особина|Свойство|Үзенчәлеклелек|Функционал|Функционалност|Функция|Функціонал|תכונה|خاصية|خصوصیت|صلاحیت|کاروبار کی ضرورت|وِیژگی|रूप लेख|ਖਾਸੀਅਤ|ਨਕਸ਼ ਨੁਹਾਰ|ਮੁਹਾਂਦਰਾ|గుణము|ಹೆಚ್ಚಳ|ความต้องการทางธุรกิจ|ความสามารถ|โครงหลัก|기능|フィーチャ|功能|機能):([^:]+\n)*/,lookbehind:!0,inside:{important:{pattern:/(:)[^\n]+/,lookbehind:!0},keyword:/[^:\n]+:/}},scenario:{pattern:/((^|\n)[ \t]*)(Abstract Scenario|Abstrakt Scenario|Achtergrond|Aer|Ær|Agtergrond|All y'all|Antecedentes|Antecedents|Atburðarás|Atburðarásir|Awww, look mate|B4|Background|Baggrund|Bakgrund|Bakgrunn|Bakgrunnur|Beispiele|Beispiller|Bối cảnh|Cefndir|Cenario|Cenário|Cenario de Fundo|Cenário de Fundo|Cenarios|Cenários|Contesto|Context|Contexte|Contexto|Conto|Contoh|Contone|Dæmi|Dasar|Dead men tell no tales|Delineacao do Cenario|Delineação do Cenário|Dis is what went down|Dữ liệu|Dyagram senaryo|Dyagram Senaryo|Egzanp|Ejemplos|Eksempler|Ekzemploj|Enghreifftiau|Esbozo do escenario|Escenari|Escenario|Esempi|Esquema de l'escenari|Esquema del escenario|Esquema do Cenario|Esquema do Cenário|Examples|EXAMPLZ|Exempel|Exemple|Exemples|Exemplos|First off|Fono|Forgatókönyv|Forgatókönyv vázlat|Fundo|Geçmiş|ghantoH|Grundlage|Hannergrond|Háttér|Heave to|Istorik|Juhtumid|Keadaan|Khung kịch bản|Khung tình huống|Kịch bản|Koncept|Konsep skenario|Kontèks|Kontekst|Kontekstas|Konteksts|Kontext|Konturo de la scenaro|Latar Belakang|lut|lut chovnatlh|lutmey|Lýsing Atburðarásar|Lýsing Dæma|Menggariskan Senario|MISHUN|MISHUN SRSLY|mo'|Náčrt Scenára|Náčrt Scénáře|Náčrt Scenáru|Oris scenarija|Örnekler|Osnova|Osnova Scenára|Osnova scénáře|Osnutek|Ozadje|Paraugs|Pavyzdžiai|Példák|Piemēri|Plan du scénario|Plan du Scénario|Plan senaryo|Plan Senaryo|Plang vum Szenario|Pozadí|Pozadie|Pozadina|Príklady|Příklady|Primer|Primeri|Primjeri|Przykłady|Raamstsenaarium|Reckon it's like|Rerefons|Scenár|Scénář|Scenarie|Scenarij|Scenarijai|Scenarijaus šablonas|Scenariji|Scenārijs|Scenārijs pēc parauga|Scenarijus|Scenario|Scénario|Scenario Amlinellol|Scenario Outline|Scenario Template|Scenariomal|Scenariomall|Scenarios|Scenariu|Scenariusz|Scenaro|Schema dello scenario|Se ðe|Se the|Se þe|Senario|Senaryo|Senaryo deskripsyon|Senaryo Deskripsyon|Senaryo taslağı|Shiver me timbers|Situācija|Situai|Situasie|Situasie Uiteensetting|Skenario|Skenario konsep|Skica|Structura scenariu|Structură scenariu|Struktura scenarija|Stsenaarium|Swa|Swa hwaer swa|Swa hwær swa|Szablon scenariusza|Szenario|Szenariogrundriss|Tapaukset|Tapaus|Tapausaihio|Taust|Tausta|Template Keadaan|Template Senario|Template Situai|The thing of it is|Tình huống|Variantai|Voorbeelde|Voorbeelden|Wharrimean is|Yo\-ho\-ho|You'll wanna|Założenia|Παραδείγματα|Περιγραφή Σεναρίου|Σενάρια|Σενάριο|Υπόβαθρο|Кереш|Контекст|Концепт|Мисаллар|Мисоллар|Основа|Передумова|Позадина|Предистория|Предыстория|Приклади|Пример|Примери|Примеры|Рамка на сценарий|Скица|Структура сценарија|Структура сценария|Структура сценарію|Сценарий|Сценарий структураси|Сценарийның төзелеше|Сценарији|Сценарио|Сценарій|Тарих|Үрнәкләр|דוגמאות|רקע|תבנית תרחיש|תרחיש|الخلفية|الگوی سناریو|امثلة|پس منظر|زمینه|سناریو|سيناريو|سيناريو مخطط|مثالیں|منظر نامے کا خاکہ|منظرنامہ|نمونه ها|उदाहरण|परिदृश्य|परिदृश्य रूपरेखा|पृष्ठभूमि|ਉਦਾਹਰਨਾਂ|ਪਟਕਥਾ|ਪਟਕਥਾ ਢਾਂਚਾ|ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ|ਪਿਛੋਕੜ|ఉదాహరణలు|కథనం|నేపథ్యం|సన్నివేశం|ಉದಾಹರಣೆಗಳು|ಕಥಾಸಾರಾಂಶ|ವಿವರಣೆ|ಹಿನ್ನೆಲೆ|โครงสร้างของเหตุการณ์|ชุดของตัวอย่าง|ชุดของเหตุการณ์|แนวคิด|สรุปเหตุการณ์|เหตุการณ์|배경|시나리오|시나리오 개요|예|サンプル|シナリオ|シナリオアウトライン|シナリオテンプレ|シナリオテンプレート|テンプレ|例|例子|剧本|剧本大纲|劇本|劇本大綱|场景|场景大纲|場景|場景大綱|背景):[^:\n]*/,lookbehind:!0,inside:{important:{pattern:/(:)[^\n]*/,lookbehind:!0},keyword:/[^:\n]+:/}},"table-body":{pattern:/(\n[ \t]*\|.+\|[^\n]*)+/,lookbehind:!0,inside:{outline:{pattern:/<[^>]+?>/,alias:"variable"},td:{pattern:/[^|]+/,alias:"string"},punctuation:/\|/}},"table-head":{pattern:/(\n[ \t]*\|.+\|[^\n]*)/,inside:{th:{pattern:/[^|]+/,alias:"variable"},punctuation:/\|/}},atrule:{pattern:/(\n[ \t]+)('ach|'a|'ej|7|a|A také|A taktiež|A tiež|A zároveň|Aber|Ac|Adott|Akkor|Ak|Aleshores|Ale|Ali|Allora|Alors|Als|Ama|Amennyiben|Amikor|Ampak|an|AN|Ananging|And y'all|And|Angenommen|Anrhegedig a|An|Apabila|Atès|Atesa|Atunci|Avast!|Aye|A|awer|Bagi|Banjur|Bet|Biết|Blimey!|Buh|But at the end of the day I reckon|But y'all|But|BUT|Cal|Când|Cando|Cand|Ce|Cuando|Če|Ða ðe|Ða|Dadas|Dada|Dados|Dado|DaH ghu' bejlu'|dann|Dann|Dano|Dan|Dar|Dat fiind|Data|Date fiind|Date|Dati fiind|Dati|Daţi fiind|Dați fiind|Dato|DEN|Den youse gotta|Dengan|De|Diberi|Diyelim ki|Donada|Donat|Donitaĵo|Do|Dun|Duota|Ðurh|Eeldades|Ef|Eğer ki|Entao|Então|Entón|Entonces|En|Epi|E|És|Etant donnée|Etant donné|Et|Étant données|Étant donnée|Étant donné|Etant données|Etant donnés|Étant donnés|Fakat|Gangway!|Gdy|Gegeben seien|Gegeben sei|Gegeven|Gegewe|ghu' noblu'|Gitt|Given y'all|Given|Givet|Givun|Ha|Cho|I CAN HAZ|In|Ir|It's just unbelievable|I|Ja|Jeśli|Jeżeli|Kadar|Kada|Kad|Kai|Kaj|Když|Keď|Kemudian|Ketika|Khi|Kiedy|Ko|Kuid|Kui|Kun|Lan|latlh|Le sa a|Let go and haul|Le|Lè sa a|Lè|Logo|Lorsqu'<|Lorsque|mä|Maar|Mais|Mając|Majd|Maka|Manawa|Mas|Ma|Menawa|Men|Mutta|Nalikaning|Nalika|Nanging|Når|När|Nato|Nhưng|Niin|Njuk|O zaman|Og|Och|Oletetaan|Onda|Ond|Oraz|Pak|Pero|Però|Podano|Pokiaľ|Pokud|Potem|Potom|Privzeto|Pryd|qaSDI'|Quando|Quand|Quan|Så|Sed|Se|Siis|Sipoze ke|Sipoze Ke|Sipoze|Si|Şi|Și|Soit|Stel|Tada|Tad|Takrat|Tak|Tapi|Ter|Tetapi|Tha the|Tha|Then y'all|Then|Thì|Thurh|Toda|Too right|ugeholl|Und|Un|Và|vaj|Vendar|Ve|wann|Wanneer|WEN|Wenn|When y'all|When|Wtedy|Wun|Y'know|Yeah nah|Yna|Youse know like when|Youse know when youse got|Y|Za predpokladu|Za předpokladu|Zadani|Zadano|Zadan|Zadate|Zadato|Zakładając|Zaradi|Zatati|Þa|Þá|Þa þe|Þegar|Þurh|Αλλά|Δεδομένου|Και|Όταν|Τότε|А також|Агар|Але|Али|Аммо|А|Әгәр|Әйтик|Әмма|Бирок|Ва|Вә|Дадено|Дано|Допустим|Если|Задате|Задати|Задато|И|І|К тому же|Када|Кад|Когато|Когда|Коли|Ләкин|Лекин|Нәтиҗәдә|Нехай|Но|Онда|Припустимо, що|Припустимо|Пусть|Также|Та|Тогда|Тоді|То|Унда|Һәм|Якщо|אבל|אזי|אז|בהינתן|וגם|כאשר|آنگاه|اذاً|اگر|اما|اور|با فرض|بالفرض|بفرض|پھر|تب|ثم|جب|عندما|فرض کیا|لكن|لیکن|متى|هنگامی|و|अगर|और|कदा|किन्तु|चूंकि|जब|तथा|तदा|तब|परन्तु|पर|यदि|ਅਤੇ|ਜਦੋਂ|ਜਿਵੇਂ ਕਿ|ਜੇਕਰ|ਤਦ|ਪਰ|అప్పుడు|ఈ పరిస్థితిలో|కాని|చెప్పబడినది|మరియు|ಆದರೆ|ನಂತರ|ನೀಡಿದ|ಮತ್ತು|ಸ್ಥಿತಿಯನ್ನು|กำหนดให้|ดังนั้น|แต่|เมื่อ|และ|그러면<|그리고<|단<|만약<|만일<|먼저<|조건<|하지만<|かつ<|しかし<|ただし<|ならば<|もし<|並且<|但し<|但是<|假如<|假定<|假設<|假设<|前提<|同时<|同時<|并且<|当<|當<|而且<|那么<|那麼<)(?=[ \t]+)/,lookbehind:!0},string:{pattern:/("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')/,inside:{outline:{pattern:/<[^>]+?>/,alias:"variable"}}},outline:{pattern:/<[^>]+?>/,alias:"variable"}};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-git.js b/polymer_1.0.4/bower_components/prism/components/prism-git.js
new file mode 100644
index 0000000..0d2ecb1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-git.js
@@ -0,0 +1,68 @@
+Prism.languages.git = {
+ /*
+ * A simple one line comment like in a git status command
+ * For instance:
+ * $ git status
+ * # On branch infinite-scroll
+ * # Your branch and 'origin/sharedBranches/frontendTeam/infinite-scroll' have diverged,
+ * # and have 1 and 2 different commits each, respectively.
+ * nothing to commit (working directory clean)
+ */
+ 'comment': /^#.*$/m,
+
+ /*
+ * a string (double and simple quote)
+ */
+ 'string': /("|')(\\?.)*?\1/m,
+
+ /*
+ * a git command. It starts with a random prompt finishing by a $, then "git" then some other parameters
+ * For instance:
+ * $ git add file.txt
+ */
+ 'command': {
+ pattern: /^.*\$ git .*$/m,
+ inside: {
+ /*
+ * A git command can contain a parameter starting by a single or a double dash followed by a string
+ * For instance:
+ * $ git diff --cached
+ * $ git log -p
+ */
+ 'parameter': /\s(--|-)\w+/m
+ }
+ },
+
+ /*
+ * Coordinates displayed in a git diff command
+ * For instance:
+ * $ git diff
+ * diff --git file.txt file.txt
+ * index 6214953..1d54a52 100644
+ * --- file.txt
+ * +++ file.txt
+ * @@ -1 +1,2 @@
+ * -Here's my tetx file
+ * +Here's my text file
+ * +And this is the second line
+ */
+ 'coord': /^@@.*@@$/m,
+
+ /*
+ * Regexp to match the changed lines in a git diff output. Check the example above.
+ */
+ 'deleted': /^-(?!-).+$/m,
+ 'inserted': /^\+(?!\+).+$/m,
+
+ /*
+ * Match a "commit [SHA1]" line in a git log output.
+ * For instance:
+ * $ git log
+ * commit a11a14ef7e26f2ca62d4b35eac455ce636d0dc09
+ * Author: lgiraudel
+ * Date: Mon Feb 17 11:18:34 2014 +0100
+ *
+ * Add of a new line
+ */
+ 'commit_sha1': /^commit \w{40}$/m
+};
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-git.min.js b/polymer_1.0.4/bower_components/prism/components/prism-git.min.js
new file mode 100644
index 0000000..44468b9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-git.min.js
@@ -0,0 +1 @@
+Prism.languages.git={comment:/^#.*$/m,string:/("|')(\\?.)*?\1/m,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s(--|-)\w+/m}},coord:/^@@.*@@$/m,deleted:/^-(?!-).+$/m,inserted:/^\+(?!\+).+$/m,commit_sha1:/^commit \w{40}$/m};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-go.js b/polymer_1.0.4/bower_components/prism/components/prism-go.js
new file mode 100644
index 0000000..089560a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-go.js
@@ -0,0 +1,9 @@
+Prism.languages.go = Prism.languages.extend('clike', {
+ 'keyword': /\b(break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,
+ 'builtin': /\b(bool|byte|complex(64|128)|error|float(32|64)|rune|string|u?int(8|16|32|64|)|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(ln)?|real|recover)\b/,
+ 'boolean': /\b(_|iota|nil|true|false)\b/,
+ 'operator': /([(){}\[\]]|[*\/%^!]=?|\+[=+]?|-[>=-]?|\|[=|]?|>[=>]?|<(<|[=-])?|==?|&(&|=|^=?)?|\.(\.\.)?|[,;]|:=?)/,
+ 'number': /\b(-?(0x[a-f\d]+|(\d+\.?\d*|\.\d+)(e[-+]?\d+)?)i?)\b/i,
+ 'string': /("|'|`)(\\?.|\r|\n)*?\1/
+});
+delete Prism.languages.go['class-name'];
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-go.min.js b/polymer_1.0.4/bower_components/prism/components/prism-go.min.js
new file mode 100644
index 0000000..530a2b7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-go.min.js
@@ -0,0 +1 @@
+Prism.languages.go=Prism.languages.extend("clike",{keyword:/\b(break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,builtin:/\b(bool|byte|complex(64|128)|error|float(32|64)|rune|string|u?int(8|16|32|64|)|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(ln)?|real|recover)\b/,"boolean":/\b(_|iota|nil|true|false)\b/,operator:/([(){}\[\]]|[*\/%^!]=?|\+[=+]?|-[>=-]?|\|[=|]?|>[=>]?|<(<|[=-])?|==?|&(&|=|^=?)?|\.(\.\.)?|[,;]|:=?)/,number:/\b(-?(0x[a-f\d]+|(\d+\.?\d*|\.\d+)(e[-+]?\d+)?)i?)\b/i,string:/("|'|`)(\\?.|\r|\n)*?\1/}),delete Prism.languages.go["class-name"];
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-groovy.js b/polymer_1.0.4/bower_components/prism/components/prism-groovy.js
new file mode 100644
index 0000000..3d5890f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-groovy.js
@@ -0,0 +1,50 @@
+Prism.languages.groovy = Prism.languages.extend('clike', {
+ 'keyword': /\b(as|def|in|abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|trait|transient|try|void|volatile|while)\b/,
+ 'string': /("""|''')[\W\w]*?\1|("|'|\/)(?:\\?.)*?\2|(\$\/)(\$\/\$|[\W\w])*?\/\$/,
+ 'number': /\b0b[01_]+\b|\b0x[\da-f_]+(\.[\da-f_p\-]+)?\b|\b[\d_]+(\.[\d_]+[e]?[\d]*)?[glidf]\b|[\d_]+(\.[\d_]+)?\b/i,
+ 'operator': {
+ pattern: /(^|[^.])(={0,2}~|\?\.|\*?\.@|\.&|\.{1,2}(?!\.)|\.{2}<?(?=\w)|->|\?:|[-+]{1,2}|!|<=>|>{1,3}|<{1,2}|={1,2}|&{1,2}|\|{1,2}|\?|\*{1,2}|\/|\^|%)/,
+ lookbehind: true
+ },
+ 'punctuation': /\.+|[{}[\];(),:$]/
+});
+
+Prism.languages.insertBefore('groovy', 'string', {
+ 'shebang': {
+ pattern: /#!.+/,
+ alias: 'comment'
+ }
+});
+
+Prism.languages.insertBefore('groovy', 'punctuation', {
+ 'spock-block': /\b(setup|given|when|then|and|cleanup|expect|where):/
+});
+
+Prism.languages.insertBefore('groovy', 'function', {
+ 'annotation': {
+ pattern: /(^|[^.])@\w+/,
+ lookbehind: true
+ }
+});
+
+Prism.hooks.add('wrap', function(env) {
+ if (env.language === 'groovy' && env.type === 'string') {
+ var delimiter = env.content[0];
+
+ if (delimiter != "'") {
+ var pattern = /([^\\])(\$(\{.*?\}|[\w\.]+))/;
+ if (delimiter === '$') {
+ pattern = /([^\$])(\$(\{.*?\}|[\w\.]+))/;
+ }
+ env.content = Prism.highlight(env.content, {
+ 'expression': {
+ pattern: pattern,
+ lookbehind: true,
+ inside: Prism.languages.groovy
+ }
+ });
+
+ env.classes.push(delimiter === '/' ? 'regex' : 'gstring');
+ }
+ }
+});
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-groovy.min.js b/polymer_1.0.4/bower_components/prism/components/prism-groovy.min.js
new file mode 100644
index 0000000..63ed199
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-groovy.min.js
@@ -0,0 +1 @@
+Prism.languages.groovy=Prism.languages.extend("clike",{keyword:/\b(as|def|in|abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|trait|transient|try|void|volatile|while)\b/,string:/("""|''')[\W\w]*?\1|("|'|\/)(?:\\?.)*?\2|(\$\/)(\$\/\$|[\W\w])*?\/\$/,number:/\b0b[01_]+\b|\b0x[\da-f_]+(\.[\da-f_p\-]+)?\b|\b[\d_]+(\.[\d_]+[e]?[\d]*)?[glidf]\b|[\d_]+(\.[\d_]+)?\b/i,operator:{pattern:/(^|[^.])(={0,2}~|\?\.|\*?\.@|\.&|\.{1,2}(?!\.)|\.{2}<?(?=\w)|->|\?:|[-+]{1,2}|!|<=>|>{1,3}|<{1,2}|={1,2}|&{1,2}|\|{1,2}|\?|\*{1,2}|\/|\^|%)/,lookbehind:!0},punctuation:/\.+|[{}[\];(),:$]/}),Prism.languages.insertBefore("groovy","string",{shebang:{pattern:/#!.+/,alias:"comment"}}),Prism.languages.insertBefore("groovy","punctuation",{"spock-block":/\b(setup|given|when|then|and|cleanup|expect|where):/}),Prism.languages.insertBefore("groovy","function",{annotation:{pattern:/(^|[^.])@\w+/,lookbehind:!0}}),Prism.hooks.add("wrap",function(e){if("groovy"===e.language&&"string"===e.type){var t=e.content[0];if("'"!=t){var n=/([^\\])(\$(\{.*?\}|[\w\.]+))/;"$"===t&&(n=/([^\$])(\$(\{.*?\}|[\w\.]+))/),e.content=Prism.highlight(e.content,{expression:{pattern:n,lookbehind:!0,inside:Prism.languages.groovy}}),e.classes.push("/"===t?"regex":"gstring")}}});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-haml.js b/polymer_1.0.4/bower_components/prism/components/prism-haml.js
new file mode 100644
index 0000000..eb0b9a9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-haml.js
@@ -0,0 +1,161 @@
+/* TODO
+ Handle multiline code after tag
+ %foo= some |
+ multiline |
+ code |
+*/
+
+(function(Prism) {
+
+ Prism.languages.haml = {
+ // Multiline stuff should appear before the rest
+
+ 'multiline-comment': [
+ {
+ pattern: /((?:^|\n)([\t ]*))\/.*(\n\2[\t ]+.+)*/,
+ lookbehind: true,
+ alias: 'comment'
+ },
+ {
+ pattern: /((?:^|\n)([\t ]*))-#.*(\n\2[\t ]+.+)*/,
+ lookbehind: true,
+ alias: 'comment'
+ }
+ ],
+
+ 'multiline-code': [
+ {
+ pattern: /((?:^|\n)([\t ]*)(?:[~-]|[&!]?=)).*,[\t ]*(\n\2[\t ]+.*,[\t ]*)*(\n\2[\t ]+.+)/,
+ lookbehind: true,
+ inside: {
+ rest: Prism.languages.ruby
+ }
+ },
+ {
+ pattern: /((?:^|\n)([\t ]*)(?:[~-]|[&!]?=)).*\|[\t ]*(\n\2[\t ]+.*\|[\t ]*)*/,
+ lookbehind: true,
+ inside: {
+ rest: Prism.languages.ruby
+ }
+ }
+ ],
+
+ // See at the end of the file for known filters
+ 'filter': {
+ pattern: /((?:^|\n)([\t ]*)):[\w-]+(\n(?:\2[\t ]+.+|\s*?(?=\n)))+/,
+ lookbehind: true,
+ inside: {
+ 'filter-name': {
+ pattern: /^:[\w-]+/,
+ alias: 'variable'
+ }
+ }
+ },
+
+ 'markup': {
+ pattern: /((?:^|\n)[\t ]*)<.+/,
+ lookbehind: true,
+ inside: {
+ rest: Prism.languages.markup
+ }
+ },
+ 'doctype': {
+ pattern: /((?:^|\n)[\t ]*)!!!(?: .+)?/,
+ lookbehind: true
+ },
+ 'tag': {
+ // Allows for one nested group of braces
+ pattern: /((?:^|\n)[\t ]*)[%.#][\w\-#.]*[\w\-](?:\([^)]+\)|\{(?:\{[^}]+\}|[^}])+\}|\[[^\]]+\])*[\/<>]*/,
+ lookbehind: true,
+ inside: {
+ 'attributes': [
+ {
+ // Lookbehind tries to prevent interpolations for breaking it all
+ // Allows for one nested group of braces
+ pattern: /(^|[^#])\{(?:\{[^}]+\}|[^}])+\}/,
+ lookbehind: true,
+ inside: {
+ rest: Prism.languages.ruby
+ }
+ },
+ {
+ pattern: /\([^)]+\)/,
+ inside: {
+ 'attr-value': {
+ pattern: /(=\s*)(?:"(?:\\?.)*?"|[^)\s]+)/,
+ lookbehind: true
+ },
+ 'attr-name': /[\w:-]+(?=\s*!?=|\s*[,)])/,
+ 'punctuation': /[=(),]/
+ }
+ },
+ {
+ pattern: /\[[^\]]+\]/,
+ inside: {
+ rest: Prism.languages.ruby
+ }
+ }
+ ],
+ 'punctuation': /[<>]/
+ }
+ },
+ 'code': {
+ pattern: /((?:^|\n)[\t ]*(?:[~-]|[&!]?=)).+/,
+ lookbehind: true,
+ inside: {
+ rest: Prism.languages.ruby
+ }
+ },
+ // Interpolations in plain text
+ 'interpolation': {
+ pattern: /#\{[^}]+\}/,
+ inside: {
+ 'delimiter': {
+ pattern: /^#\{|\}$/,
+ alias: 'punctuation'
+ },
+ rest: Prism.languages.ruby
+ }
+ },
+ 'punctuation': {
+ pattern: /((?:^|\n)[\t ]*)[~=\-&!]/,
+ lookbehind: true
+ }
+ };
+
+ var filter_pattern = '((?:^|\\n)([\\t ]*)):{{filter_name}}(\\n(?:\\2[\\t ]+.+|\\s*?(?=\\n)))+';
+
+ // Non exhaustive list of available filters and associated languages
+ var filters = [
+ 'css',
+ {filter:'coffee',language:'coffeescript'},
+ 'erb',
+ 'javascript',
+ 'less',
+ 'markdown',
+ 'ruby',
+ 'scss',
+ 'textile'
+ ];
+ var all_filters = {};
+ for (var i = 0, l = filters.length; i < l; i++) {
+ var filter = filters[i];
+ filter = typeof filter === 'string' ? {filter: filter, language: filter} : filter;
+ if (Prism.languages[filter.language]) {
+ all_filters['filter-' + filter.filter] = {
+ pattern: RegExp(filter_pattern.replace('{{filter_name}}', filter.filter)),
+ lookbehind: true,
+ inside: {
+ 'filter-name': {
+ pattern: /^:[\w-]+/,
+ alias: 'variable'
+ },
+ rest: Prism.languages[filter.language]
+ }
+ }
+ }
+ }
+
+ Prism.languages.insertBefore('haml', 'filter', all_filters);
+
+}(Prism));
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-haml.min.js b/polymer_1.0.4/bower_components/prism/components/prism-haml.min.js
new file mode 100644
index 0000000..9af046e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-haml.min.js
@@ -0,0 +1 @@
+!function(e){e.languages.haml={"multiline-comment":[{pattern:/((?:^|\n)([\t ]*))\/.*(\n\2[\t ]+.+)*/,lookbehind:!0,alias:"comment"},{pattern:/((?:^|\n)([\t ]*))-#.*(\n\2[\t ]+.+)*/,lookbehind:!0,alias:"comment"}],"multiline-code":[{pattern:/((?:^|\n)([\t ]*)(?:[~-]|[&!]?=)).*,[\t ]*(\n\2[\t ]+.*,[\t ]*)*(\n\2[\t ]+.+)/,lookbehind:!0,inside:{rest:e.languages.ruby}},{pattern:/((?:^|\n)([\t ]*)(?:[~-]|[&!]?=)).*\|[\t ]*(\n\2[\t ]+.*\|[\t ]*)*/,lookbehind:!0,inside:{rest:e.languages.ruby}}],filter:{pattern:/((?:^|\n)([\t ]*)):[\w-]+(\n(?:\2[\t ]+.+|\s*?(?=\n)))+/,lookbehind:!0,inside:{"filter-name":{pattern:/^:[\w-]+/,alias:"variable"}}},markup:{pattern:/((?:^|\n)[\t ]*)<.+/,lookbehind:!0,inside:{rest:e.languages.markup}},doctype:{pattern:/((?:^|\n)[\t ]*)!!!(?: .+)?/,lookbehind:!0},tag:{pattern:/((?:^|\n)[\t ]*)[%.#][\w\-#.]*[\w\-](?:\([^)]+\)|\{(?:\{[^}]+\}|[^}])+\}|\[[^\]]+\])*[\/<>]*/,lookbehind:!0,inside:{attributes:[{pattern:/(^|[^#])\{(?:\{[^}]+\}|[^}])+\}/,lookbehind:!0,inside:{rest:e.languages.ruby}},{pattern:/\([^)]+\)/,inside:{"attr-value":{pattern:/(=\s*)(?:"(?:\\?.)*?"|[^)\s]+)/,lookbehind:!0},"attr-name":/[\w:-]+(?=\s*!?=|\s*[,)])/,punctuation:/[=(),]/}},{pattern:/\[[^\]]+\]/,inside:{rest:e.languages.ruby}}],punctuation:/[<>]/}},code:{pattern:/((?:^|\n)[\t ]*(?:[~-]|[&!]?=)).+/,lookbehind:!0,inside:{rest:e.languages.ruby}},interpolation:{pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"},rest:e.languages.ruby}},punctuation:{pattern:/((?:^|\n)[\t ]*)[~=\-&!]/,lookbehind:!0}};for(var t="((?:^|\\n)([\\t ]*)):{{filter_name}}(\\n(?:\\2[\\t ]+.+|\\s*?(?=\\n)))+",n=["css",{filter:"coffee",language:"coffeescript"},"erb","javascript","less","markdown","ruby","scss","textile"],a={},i=0,r=n.length;r>i;i++){var l=n[i];l="string"==typeof l?{filter:l,language:l}:l,e.languages[l.language]&&(a["filter-"+l.filter]={pattern:RegExp(t.replace("{{filter_name}}",l.filter)),lookbehind:!0,inside:{"filter-name":{pattern:/^:[\w-]+/,alias:"variable"},rest:e.languages[l.language]}})}e.languages.insertBefore("haml","filter",a)}(Prism);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-handlebars.js b/polymer_1.0.4/bower_components/prism/components/prism-handlebars.js
new file mode 100644
index 0000000..3154940
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-handlebars.js
@@ -0,0 +1,82 @@
+(function(Prism) {
+
+ var handlebars_pattern = /\{\{\{[\w\W]+?\}\}\}|\{\{[\w\W]+?\}\}/g;
+
+ Prism.languages.handlebars = Prism.languages.extend('markup', {
+ 'handlebars': {
+ pattern: handlebars_pattern,
+ inside: {
+ 'delimiter': {
+ pattern: /^\{\{\{?|\}\}\}?$/i,
+ alias: 'punctuation'
+ },
+ 'string': /(["'])(\\?.)+?\1/,
+ 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,
+ 'boolean': /\b(true|false)\b/,
+ 'block': {
+ pattern: /^(\s*~?\s*)[#\/]\w+/i,
+ lookbehind: true,
+ alias: 'keyword'
+ },
+ 'brackets': {
+ pattern: /\[[^\]]+\]/,
+ inside: {
+ punctuation: /\[|\]/,
+ variable: /[\w\W]+/
+ }
+ },
+ 'punctuation': /[!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]/,
+ 'variable': /[^!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]+/
+ }
+ }
+ });
+
+ // Comments are inserted at top so that they can
+ // surround markup
+ Prism.languages.insertBefore('handlebars', 'tag', {
+ 'handlebars-comment': {
+ pattern: /\{\{![\w\W]*?\}\}/,
+ alias: ['handlebars','comment']
+ }
+ });
+
+ // Tokenize all inline Handlebars expressions that are wrapped in {{ }} or {{{ }}}
+ // This allows for easy Handlebars + markup highlighting
+ Prism.hooks.add('before-highlight', function(env) {
+ if (env.language !== 'handlebars') {
+ return;
+ }
+
+ env.tokenStack = [];
+
+ env.backupCode = env.code;
+ env.code = env.code.replace(handlebars_pattern, function(match) {
+ env.tokenStack.push(match);
+
+ return '___HANDLEBARS' + env.tokenStack.length + '___';
+ });
+ });
+
+ // Restore env.code for other plugins (e.g. line-numbers)
+ Prism.hooks.add('before-insert', function(env) {
+ if (env.language === 'handlebars') {
+ env.code = env.backupCode;
+ delete env.backupCode;
+ }
+ });
+
+ // Re-insert the tokens after highlighting
+ // and highlight them with defined grammar
+ Prism.hooks.add('after-highlight', function(env) {
+ if (env.language !== 'handlebars') {
+ return;
+ }
+
+ for (var i = 0, t; t = env.tokenStack[i]; i++) {
+ env.highlightedCode = env.highlightedCode.replace('___HANDLEBARS' + (i + 1) + '___', Prism.highlight(t, env.grammar, 'handlebars'));
+ }
+
+ env.element.innerHTML = env.highlightedCode;
+ });
+
+}(Prism));
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-handlebars.min.js b/polymer_1.0.4/bower_components/prism/components/prism-handlebars.min.js
new file mode 100644
index 0000000..d303e50
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-handlebars.min.js
@@ -0,0 +1 @@
+!function(e){var a=/\{\{\{[\w\W]+?\}\}\}|\{\{[\w\W]+?\}\}/g;e.languages.handlebars=e.languages.extend("markup",{handlebars:{pattern:a,inside:{delimiter:{pattern:/^\{\{\{?|\}\}\}?$/i,alias:"punctuation"},string:/(["'])(\\?.)+?\1/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,"boolean":/\b(true|false)\b/,block:{pattern:/^(\s*~?\s*)[#\/]\w+/i,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\w\W]+/}},punctuation:/[!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]+/}}}),e.languages.insertBefore("handlebars","tag",{"handlebars-comment":{pattern:/\{\{![\w\W]*?\}\}/,alias:["handlebars","comment"]}}),e.hooks.add("before-highlight",function(e){"handlebars"===e.language&&(e.tokenStack=[],e.backupCode=e.code,e.code=e.code.replace(a,function(a){return e.tokenStack.push(a),"___HANDLEBARS"+e.tokenStack.length+"___"}))}),e.hooks.add("before-insert",function(e){"handlebars"===e.language&&(e.code=e.backupCode,delete e.backupCode)}),e.hooks.add("after-highlight",function(a){if("handlebars"===a.language){for(var n,t=0;n=a.tokenStack[t];t++)a.highlightedCode=a.highlightedCode.replace("___HANDLEBARS"+(t+1)+"___",e.highlight(n,a.grammar,"handlebars"));a.element.innerHTML=a.highlightedCode}})}(Prism);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-haskell.js b/polymer_1.0.4/bower_components/prism/components/prism-haskell.js
new file mode 100644
index 0000000..cc2452a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-haskell.js
@@ -0,0 +1,32 @@
+Prism.languages.haskell= {
+ 'comment': {
+ pattern: /(^|[^-!#$%*+=\?&@|~.:<>^\\])(--[^-!#$%*+=\?&@|~.:<>^\\].*(\r?\n|$)|{-[\w\W]*?-})/m,
+ lookbehind: true
+ },
+ 'char': /'([^\\"]|\\([abfnrtv\\"'&]|\^[A-Z@[\]\^_]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|\d+|o[0-7]+|x[0-9a-fA-F]+))'/,
+ 'string': /"([^\\"]|\\([abfnrtv\\"'&]|\^[A-Z@[\]\^_]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|\d+|o[0-7]+|x[0-9a-fA-F]+)|\\\s+\\)*"/,
+ 'keyword' : /\b(case|class|data|deriving|do|else|if|in|infixl|infixr|instance|let|module|newtype|of|primitive|then|type|where)\b/,
+ 'import_statement' : {
+ // The imported or hidden names are not included in this import
+ // statement. This is because we want to highlight those exactly like
+ // we do for the names in the program.
+ pattern: /(\n|^)\s*(import)\s+(qualified\s+)?(([A-Z][_a-zA-Z0-9']*)(\.[A-Z][_a-zA-Z0-9']*)*)(\s+(as)\s+(([A-Z][_a-zA-Z0-9']*)(\.[A-Z][_a-zA-Z0-9']*)*))?(\s+hiding\b)?/m,
+ inside: {
+ 'keyword': /\b(import|qualified|as|hiding)\b/
+ }
+ },
+ // These are builtin variables only. Constructors are highlighted later as a constant.
+ 'builtin': /\b(abs|acos|acosh|all|and|any|appendFile|approxRational|asTypeOf|asin|asinh|atan|atan2|atanh|basicIORun|break|catch|ceiling|chr|compare|concat|concatMap|const|cos|cosh|curry|cycle|decodeFloat|denominator|digitToInt|div|divMod|drop|dropWhile|either|elem|encodeFloat|enumFrom|enumFromThen|enumFromThenTo|enumFromTo|error|even|exp|exponent|fail|filter|flip|floatDigits|floatRadix|floatRange|floor|fmap|foldl|foldl1|foldr|foldr1|fromDouble|fromEnum|fromInt|fromInteger|fromIntegral|fromRational|fst|gcd|getChar|getContents|getLine|group|head|id|inRange|index|init|intToDigit|interact|ioError|isAlpha|isAlphaNum|isAscii|isControl|isDenormalized|isDigit|isHexDigit|isIEEE|isInfinite|isLower|isNaN|isNegativeZero|isOctDigit|isPrint|isSpace|isUpper|iterate|last|lcm|length|lex|lexDigits|lexLitChar|lines|log|logBase|lookup|map|mapM|mapM_|max|maxBound|maximum|maybe|min|minBound|minimum|mod|negate|not|notElem|null|numerator|odd|or|ord|otherwise|pack|pi|pred|primExitWith|print|product|properFraction|putChar|putStr|putStrLn|quot|quotRem|range|rangeSize|read|readDec|readFile|readFloat|readHex|readIO|readInt|readList|readLitChar|readLn|readOct|readParen|readSigned|reads|readsPrec|realToFrac|recip|rem|repeat|replicate|return|reverse|round|scaleFloat|scanl|scanl1|scanr|scanr1|seq|sequence|sequence_|show|showChar|showInt|showList|showLitChar|showParen|showSigned|showString|shows|showsPrec|significand|signum|sin|sinh|snd|sort|span|splitAt|sqrt|subtract|succ|sum|tail|take|takeWhile|tan|tanh|threadToIOResult|toEnum|toInt|toInteger|toLower|toRational|toUpper|truncate|uncurry|undefined|unlines|until|unwords|unzip|unzip3|userError|words|writeFile|zip|zip3|zipWith|zipWith3)\b/,
+ // decimal integers and floating point numbers | octal integers | hexadecimal integers
+ 'number' : /\b(\d+(\.\d+)?([eE][+-]?\d+)?|0[Oo][0-7]+|0[Xx][0-9a-fA-F]+)\b/,
+ // Most of this is needed because of the meaning of a single '.'.
+ // If it stands alone freely, it is the function composition.
+ // It may also be a separator between a module name and an identifier => no
+ // operator. If it comes together with other special characters it is an
+ // operator too.
+ 'operator' : /\s\.\s|([-!#$%*+=\?&@|~:<>^\\]*\.[-!#$%*+=\?&@|~:<>^\\]+)|([-!#$%*+=\?&@|~:<>^\\]+\.[-!#$%*+=\?&@|~:<>^\\]*)|[-!#$%*+=\?&@|~:<>^\\]+|(`([A-Z][_a-zA-Z0-9']*\.)*[_a-z][_a-zA-Z0-9']*`)/,
+ // In Haskell, nearly everything is a variable, do not highlight these.
+ 'hvariable': /\b([A-Z][_a-zA-Z0-9']*\.)*[_a-z][_a-zA-Z0-9']*\b/,
+ 'constant': /\b([A-Z][_a-zA-Z0-9']*\.)*[A-Z][_a-zA-Z0-9']*\b/,
+ 'punctuation' : /[{}[\];(),.:]/
+};
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-haskell.min.js b/polymer_1.0.4/bower_components/prism/components/prism-haskell.min.js
new file mode 100644
index 0000000..5661b7e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-haskell.min.js
@@ -0,0 +1 @@
+Prism.languages.haskell={comment:{pattern:/(^|[^-!#$%*+=\?&@|~.:<>^\\])(--[^-!#$%*+=\?&@|~.:<>^\\].*(\r?\n|$)|{-[\w\W]*?-})/m,lookbehind:!0},"char":/'([^\\"]|\\([abfnrtv\\"'&]|\^[A-Z@[\]\^_]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|\d+|o[0-7]+|x[0-9a-fA-F]+))'/,string:/"([^\\"]|\\([abfnrtv\\"'&]|\^[A-Z@[\]\^_]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|\d+|o[0-7]+|x[0-9a-fA-F]+)|\\\s+\\)*"/,keyword:/\b(case|class|data|deriving|do|else|if|in|infixl|infixr|instance|let|module|newtype|of|primitive|then|type|where)\b/,import_statement:{pattern:/(\n|^)\s*(import)\s+(qualified\s+)?(([A-Z][_a-zA-Z0-9']*)(\.[A-Z][_a-zA-Z0-9']*)*)(\s+(as)\s+(([A-Z][_a-zA-Z0-9']*)(\.[A-Z][_a-zA-Z0-9']*)*))?(\s+hiding\b)?/m,inside:{keyword:/\b(import|qualified|as|hiding)\b/}},builtin:/\b(abs|acos|acosh|all|and|any|appendFile|approxRational|asTypeOf|asin|asinh|atan|atan2|atanh|basicIORun|break|catch|ceiling|chr|compare|concat|concatMap|const|cos|cosh|curry|cycle|decodeFloat|denominator|digitToInt|div|divMod|drop|dropWhile|either|elem|encodeFloat|enumFrom|enumFromThen|enumFromThenTo|enumFromTo|error|even|exp|exponent|fail|filter|flip|floatDigits|floatRadix|floatRange|floor|fmap|foldl|foldl1|foldr|foldr1|fromDouble|fromEnum|fromInt|fromInteger|fromIntegral|fromRational|fst|gcd|getChar|getContents|getLine|group|head|id|inRange|index|init|intToDigit|interact|ioError|isAlpha|isAlphaNum|isAscii|isControl|isDenormalized|isDigit|isHexDigit|isIEEE|isInfinite|isLower|isNaN|isNegativeZero|isOctDigit|isPrint|isSpace|isUpper|iterate|last|lcm|length|lex|lexDigits|lexLitChar|lines|log|logBase|lookup|map|mapM|mapM_|max|maxBound|maximum|maybe|min|minBound|minimum|mod|negate|not|notElem|null|numerator|odd|or|ord|otherwise|pack|pi|pred|primExitWith|print|product|properFraction|putChar|putStr|putStrLn|quot|quotRem|range|rangeSize|read|readDec|readFile|readFloat|readHex|readIO|readInt|readList|readLitChar|readLn|readOct|readParen|readSigned|reads|readsPrec|realToFrac|recip|rem|repeat|replicate|return|reverse|round|scaleFloat|scanl|scanl1|scanr|scanr1|seq|sequence|sequence_|show|showChar|showInt|showList|showLitChar|showParen|showSigned|showString|shows|showsPrec|significand|signum|sin|sinh|snd|sort|span|splitAt|sqrt|subtract|succ|sum|tail|take|takeWhile|tan|tanh|threadToIOResult|toEnum|toInt|toInteger|toLower|toRational|toUpper|truncate|uncurry|undefined|unlines|until|unwords|unzip|unzip3|userError|words|writeFile|zip|zip3|zipWith|zipWith3)\b/,number:/\b(\d+(\.\d+)?([eE][+-]?\d+)?|0[Oo][0-7]+|0[Xx][0-9a-fA-F]+)\b/,operator:/\s\.\s|([-!#$%*+=\?&@|~:<>^\\]*\.[-!#$%*+=\?&@|~:<>^\\]+)|([-!#$%*+=\?&@|~:<>^\\]+\.[-!#$%*+=\?&@|~:<>^\\]*)|[-!#$%*+=\?&@|~:<>^\\]+|(`([A-Z][_a-zA-Z0-9']*\.)*[_a-z][_a-zA-Z0-9']*`)/,hvariable:/\b([A-Z][_a-zA-Z0-9']*\.)*[_a-z][_a-zA-Z0-9']*\b/,constant:/\b([A-Z][_a-zA-Z0-9']*\.)*[A-Z][_a-zA-Z0-9']*\b/,punctuation:/[{}[\];(),.:]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-http.js b/polymer_1.0.4/bower_components/prism/components/prism-http.js
new file mode 100644
index 0000000..f94f6de
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-http.js
@@ -0,0 +1,44 @@
+Prism.languages.http = {
+ 'request-line': {
+ pattern: /^(POST|GET|PUT|DELETE|OPTIONS|PATCH|TRACE|CONNECT)\b\shttps?:\/\/\S+\sHTTP\/[0-9.]+/,
+ inside: {
+ // HTTP Verb
+ property: /^\b(POST|GET|PUT|DELETE|OPTIONS|PATCH|TRACE|CONNECT)\b/,
+ // Path or query argument
+ 'attr-name': /:\w+/
+ }
+ },
+ 'response-status': {
+ pattern: /^HTTP\/1.[01] [0-9]+.*/,
+ inside: {
+ // Status, e.g. 200 OK
+ property: /[0-9]+[A-Z\s-]+$/i
+ }
+ },
+ // HTTP header name
+ keyword: /^[\w-]+:(?=.+)/m
+};
+
+// Create a mapping of Content-Type headers to language definitions
+var httpLanguages = {
+ 'application/json': Prism.languages.javascript,
+ 'application/xml': Prism.languages.markup,
+ 'text/xml': Prism.languages.markup,
+ 'text/html': Prism.languages.markup
+};
+
+// Insert each content type parser that has its associated language
+// currently loaded.
+for (var contentType in httpLanguages) {
+ if (httpLanguages[contentType]) {
+ var options = {};
+ options[contentType] = {
+ pattern: new RegExp('(content-type:\\s*' + contentType + '[\\w\\W]*?)\\n\\n[\\w\\W]*', 'i'),
+ lookbehind: true,
+ inside: {
+ rest: httpLanguages[contentType]
+ }
+ };
+ Prism.languages.insertBefore('http', 'keyword', options);
+ }
+}
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-http.min.js b/polymer_1.0.4/bower_components/prism/components/prism-http.min.js
new file mode 100644
index 0000000..05a0d74
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-http.min.js
@@ -0,0 +1 @@
+Prism.languages.http={"request-line":{pattern:/^(POST|GET|PUT|DELETE|OPTIONS|PATCH|TRACE|CONNECT)\b\shttps?:\/\/\S+\sHTTP\/[0-9.]+/,inside:{property:/^\b(POST|GET|PUT|DELETE|OPTIONS|PATCH|TRACE|CONNECT)\b/,"attr-name":/:\w+/}},"response-status":{pattern:/^HTTP\/1.[01] [0-9]+.*/,inside:{property:/[0-9]+[A-Z\s-]+$/i}},keyword:/^[\w-]+:(?=.+)/m};var httpLanguages={"application/json":Prism.languages.javascript,"application/xml":Prism.languages.markup,"text/xml":Prism.languages.markup,"text/html":Prism.languages.markup};for(var contentType in httpLanguages)if(httpLanguages[contentType]){var options={};options[contentType]={pattern:new RegExp("(content-type:\\s*"+contentType+"[\\w\\W]*?)\\n\\n[\\w\\W]*","i"),lookbehind:!0,inside:{rest:httpLanguages[contentType]}},Prism.languages.insertBefore("http","keyword",options)}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-ini.js b/polymer_1.0.4/bower_components/prism/components/prism-ini.js
new file mode 100644
index 0000000..0cf75dc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-ini.js
@@ -0,0 +1,11 @@
+Prism.languages.ini= {
+ 'comment': /^\s*;.*$/m,
+ 'important': /\[.*?\]/m,
+ 'constant': /^\s*[^\s=]+?(?=[ \t]*=)/m,
+ 'attr-value': {
+ pattern: /=.*/m,
+ inside: {
+ 'punctuation': /^[=]/
+ }
+ }
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-ini.min.js b/polymer_1.0.4/bower_components/prism/components/prism-ini.min.js
new file mode 100644
index 0000000..9f0fb2f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-ini.min.js
@@ -0,0 +1 @@
+Prism.languages.ini={comment:/^\s*;.*$/m,important:/\[.*?\]/m,constant:/^\s*[^\s=]+?(?=[ \t]*=)/m,"attr-value":{pattern:/=.*/m,inside:{punctuation:/^[=]/}}};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-jade.js b/polymer_1.0.4/bower_components/prism/components/prism-jade.js
new file mode 100644
index 0000000..e734706
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-jade.js
@@ -0,0 +1,196 @@
+(function(Prism) {
+ Prism.languages.jade = {
+
+ // Multiline stuff should appear before the rest
+
+ 'multiline-comment': {
+ pattern: /((?:^|\n)([\t ]*))\/\/.*(\n\2[\t ]+.+)*/,
+ lookbehind: true,
+ alias: 'comment'
+ },
+
+ // All the tag-related part is in lookbehind
+ // so that it can be highlighted by the "tag" pattern
+ 'multiline-script': {
+ pattern: /((?:^|\n)([\t ]*)script\b.*\.[\t ]*)(\n(?:\2[\t ]+.+|\s*?(?=\n)))+/,
+ lookbehind: true,
+ inside: {
+ rest: Prism.languages.javascript
+ }
+ },
+
+ // See at the end of the file for known filters
+ 'filter': {
+ pattern: /((?:^|\n)([\t ]*)):.+(\n(?:\2[\t ]+.+|\s*?(?=\n)))+/,
+ lookbehind: true,
+ inside: {
+ 'filter-name': {
+ pattern: /^:[\w-]+/,
+ alias: 'variable'
+ }
+ }
+ },
+
+ 'multiline-plain-text': {
+ pattern: /((?:^|\n)([\t ]*)[\w\-#.]+\.[\t ]*)(\n(?:\2[\t ]+.+|\s*?(?=\n)))+/,
+ lookbehind: true
+ },
+ 'markup': {
+ pattern: /((?:^|\n)[\t ]*)<.+/,
+ lookbehind: true,
+ inside: {
+ rest: Prism.languages.markup
+ }
+ },
+ 'comment': {
+ pattern: /((?:^|\n)[\t ]*)\/\/.+/,
+ lookbehind: true
+ },
+ 'doctype': {
+ pattern: /((?:^|\n)[\t ]*)doctype(?: .+)?/,
+ lookbehind: true
+ },
+
+ // This handle all conditional and loop keywords
+ 'flow-control': {
+ pattern: /((?:^|\n)[\t ]*)(?:if|unless|else|case|when|default|each|while)(?: .+)?/,
+ lookbehind: true,
+ inside: {
+ 'each': {
+ pattern: /((?:^|\n)[\t ]*)each .+? in\b/,
+ lookbehind: true,
+ inside: {
+ 'keyword': /\b(?:each|in)\b/,
+ 'punctuation': /,/
+ }
+ },
+ 'branch': {
+ pattern: /((?:^|\n)[\t ]*)(?:if|unless|else|case|when|default|while)/,
+ lookbehind: true,
+ alias: 'keyword'
+ },
+ rest: Prism.languages.javascript
+ }
+ },
+ 'keyword': {
+ pattern: /((?:^|\n)[\t ]*)(?:block|extends|include|append|prepend)\b.+/,
+ lookbehind: true
+ },
+ 'mixin': [
+ // Declaration
+ {
+ pattern: /((?:^|\n)[\t ]*)mixin .+/,
+ lookbehind: true,
+ inside: {
+ 'keyword': /^mixin/,
+ 'function': /\w+(?=\s*\(|\s*$)/,
+ 'punctuation': /[(),.]/
+ }
+ },
+ // Usage
+ {
+ pattern: /((?:^|\n)[\t ]*)\+.+/,
+ lookbehind: true,
+ inside: {
+ 'name': {
+ pattern: /^\+\w+/,
+ alias: 'function'
+ },
+ 'rest': Prism.languages.javascript
+ }
+ }
+ ],
+ 'script': {
+ pattern: /((?:^|\n)[\t ]*script(?:(?:&[^(]+)?\([^)]+\))*) .+/,
+ lookbehind: true,
+ inside: {
+ rest: Prism.languages.javascript
+ }
+ },
+
+ 'plain-text': {
+ pattern: /((?:^|\n)[\t ]*(?!-)[\w\-#.]*[\w\-](?:(?:&[^(]+)?\([^)]+\))*\/?[\t ]+).+/,
+ lookbehind: true
+ },
+ 'tag': {
+ pattern: /((?:^|\n)[\t ]*)(?!-)[\w\-#.]*[\w\-](?:(?:&[^(]+)?\([^)]+\))*\/?:?/,
+ lookbehind: true,
+ inside: {
+ 'attributes': [
+ {
+ pattern: /&[^(]+\([^)]+\)/,
+ inside: {
+ rest: Prism.languages.javascript
+ }
+ },
+ {
+ pattern: /\([^)]+\)/,
+ inside: {
+ 'attr-value': {
+ pattern: /(=\s*)(?:\{[^}]*\}|[^,)\n]+)/,
+ lookbehind: true,
+ inside: {
+ rest: Prism.languages.javascript
+ }
+ },
+ 'attr-name': /[\w-]+(?=\s*!?=|\s*[,)])/,
+ 'punctuation': /[!=(),]/
+ }
+ }
+ ],
+ 'punctuation': /[:]/
+ }
+ },
+ 'code': [
+ {
+ pattern: /((?:^|\n)[\t ]*(?:-|!?=)).+/,
+ lookbehind: true,
+ inside: {
+ rest: Prism.languages.javascript
+ }
+ }
+ ],
+ 'punctuation': /[.\-!=|]/
+ };
+
+ var filter_pattern = '((?:^|\\n)([\\t ]*)):{{filter_name}}(\\n(?:\\2[\\t ]+.+|\\s*?(?=\\n)))+';
+
+ // Non exhaustive list of available filters and associated languages
+ var filters = [
+ {filter:'atpl',language:'twig'},
+ {filter:'coffee',language:'coffeescript'},
+ 'ejs',
+ 'handlebars',
+ 'hogan',
+ 'less',
+ 'livescript',
+ 'markdown',
+ 'mustache',
+ 'plates',
+ {filter:'sass',language:'scss'},
+ 'stylus',
+ 'swig'
+
+ ];
+ var all_filters = {};
+ for (var i = 0, l = filters.length; i < l; i++) {
+ var filter = filters[i];
+ filter = typeof filter === 'string' ? {filter: filter, language: filter} : filter;
+ if (Prism.languages[filter.language]) {
+ all_filters['filter-' + filter.filter] = {
+ pattern: RegExp(filter_pattern.replace('{{filter_name}}', filter.filter)),
+ lookbehind: true,
+ inside: {
+ 'filter-name': {
+ pattern: /^:[\w-]+/,
+ alias: 'variable'
+ },
+ rest: Prism.languages[filter.language]
+ }
+ }
+ }
+ }
+
+ Prism.languages.insertBefore('jade', 'filter', all_filters);
+
+}(Prism));
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-jade.min.js b/polymer_1.0.4/bower_components/prism/components/prism-jade.min.js
new file mode 100644
index 0000000..a2bbbfa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-jade.min.js
@@ -0,0 +1 @@
+!function(e){e.languages.jade={"multiline-comment":{pattern:/((?:^|\n)([\t ]*))\/\/.*(\n\2[\t ]+.+)*/,lookbehind:!0,alias:"comment"},"multiline-script":{pattern:/((?:^|\n)([\t ]*)script\b.*\.[\t ]*)(\n(?:\2[\t ]+.+|\s*?(?=\n)))+/,lookbehind:!0,inside:{rest:e.languages.javascript}},filter:{pattern:/((?:^|\n)([\t ]*)):.+(\n(?:\2[\t ]+.+|\s*?(?=\n)))+/,lookbehind:!0,inside:{"filter-name":{pattern:/^:[\w-]+/,alias:"variable"}}},"multiline-plain-text":{pattern:/((?:^|\n)([\t ]*)[\w\-#.]+\.[\t ]*)(\n(?:\2[\t ]+.+|\s*?(?=\n)))+/,lookbehind:!0},markup:{pattern:/((?:^|\n)[\t ]*)<.+/,lookbehind:!0,inside:{rest:e.languages.markup}},comment:{pattern:/((?:^|\n)[\t ]*)\/\/.+/,lookbehind:!0},doctype:{pattern:/((?:^|\n)[\t ]*)doctype(?: .+)?/,lookbehind:!0},"flow-control":{pattern:/((?:^|\n)[\t ]*)(?:if|unless|else|case|when|default|each|while)(?: .+)?/,lookbehind:!0,inside:{each:{pattern:/((?:^|\n)[\t ]*)each .+? in\b/,lookbehind:!0,inside:{keyword:/\b(?:each|in)\b/,punctuation:/,/}},branch:{pattern:/((?:^|\n)[\t ]*)(?:if|unless|else|case|when|default|while)/,lookbehind:!0,alias:"keyword"},rest:e.languages.javascript}},keyword:{pattern:/((?:^|\n)[\t ]*)(?:block|extends|include|append|prepend)\b.+/,lookbehind:!0},mixin:[{pattern:/((?:^|\n)[\t ]*)mixin .+/,lookbehind:!0,inside:{keyword:/^mixin/,"function":/\w+(?=\s*\(|\s*$)/,punctuation:/[(),.]/}},{pattern:/((?:^|\n)[\t ]*)\+.+/,lookbehind:!0,inside:{name:{pattern:/^\+\w+/,alias:"function"},rest:e.languages.javascript}}],script:{pattern:/((?:^|\n)[\t ]*script(?:(?:&[^(]+)?\([^)]+\))*) .+/,lookbehind:!0,inside:{rest:e.languages.javascript}},"plain-text":{pattern:/((?:^|\n)[\t ]*(?!-)[\w\-#.]*[\w\-](?:(?:&[^(]+)?\([^)]+\))*\/?[\t ]+).+/,lookbehind:!0},tag:{pattern:/((?:^|\n)[\t ]*)(?!-)[\w\-#.]*[\w\-](?:(?:&[^(]+)?\([^)]+\))*\/?:?/,lookbehind:!0,inside:{attributes:[{pattern:/&[^(]+\([^)]+\)/,inside:{rest:e.languages.javascript}},{pattern:/\([^)]+\)/,inside:{"attr-value":{pattern:/(=\s*)(?:\{[^}]*\}|[^,)\n]+)/,lookbehind:!0,inside:{rest:e.languages.javascript}},"attr-name":/[\w-]+(?=\s*!?=|\s*[,)])/,punctuation:/[!=(),]/}}],punctuation:/[:]/}},code:[{pattern:/((?:^|\n)[\t ]*(?:-|!?=)).+/,lookbehind:!0,inside:{rest:e.languages.javascript}}],punctuation:/[.\-!=|]/};for(var t="((?:^|\\n)([\\t ]*)):{{filter_name}}(\\n(?:\\2[\\t ]+.+|\\s*?(?=\\n)))+",n=[{filter:"atpl",language:"twig"},{filter:"coffee",language:"coffeescript"},"ejs","handlebars","hogan","less","livescript","markdown","mustache","plates",{filter:"sass",language:"scss"},"stylus","swig"],a={},i=0,s=n.length;s>i;i++){var l=n[i];l="string"==typeof l?{filter:l,language:l}:l,e.languages[l.language]&&(a["filter-"+l.filter]={pattern:RegExp(t.replace("{{filter_name}}",l.filter)),lookbehind:!0,inside:{"filter-name":{pattern:/^:[\w-]+/,alias:"variable"},rest:e.languages[l.language]}})}e.languages.insertBefore("jade","filter",a)}(Prism);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-java.js b/polymer_1.0.4/bower_components/prism/components/prism-java.js
new file mode 100644
index 0000000..8bc51ae
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-java.js
@@ -0,0 +1,8 @@
+Prism.languages.java = Prism.languages.extend('clike', {
+ 'keyword': /\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,
+ 'number': /\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+[e]?[\d]*[df]\b|\b\d*\.?\d+\b/i,
+ 'operator': {
+ pattern: /(^|[^\.])(?:\+=|\+\+?|-=|--?|!=?|<{1,2}=?|>{1,3}=?|==?|&=|&&?|\|=|\|\|?|\?|\*=?|\/=?|%=?|\^=?|:|~)/m,
+ lookbehind: true
+ }
+});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-java.min.js b/polymer_1.0.4/bower_components/prism/components/prism-java.min.js
new file mode 100644
index 0000000..215ee2b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-java.min.js
@@ -0,0 +1 @@
+Prism.languages.java=Prism.languages.extend("clike",{keyword:/\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,number:/\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+[e]?[\d]*[df]\b|\b\d*\.?\d+\b/i,operator:{pattern:/(^|[^\.])(?:\+=|\+\+?|-=|--?|!=?|<{1,2}=?|>{1,3}=?|==?|&=|&&?|\|=|\|\|?|\?|\*=?|\/=?|%=?|\^=?|:|~)/m,lookbehind:!0}});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-javascript.js b/polymer_1.0.4/bower_components/prism/components/prism-javascript.js
new file mode 100644
index 0000000..754ff0e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-javascript.js
@@ -0,0 +1,28 @@
+Prism.languages.javascript = Prism.languages.extend('clike', {
+ 'keyword': /\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,
+ 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|-?Infinity)\b/,
+ 'function': /(?!\d)[a-z0-9_$]+(?=\()/i
+});
+
+Prism.languages.insertBefore('javascript', 'keyword', {
+ 'regex': {
+ pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,
+ lookbehind: true
+ }
+});
+
+if (Prism.languages.markup) {
+ Prism.languages.insertBefore('markup', 'tag', {
+ 'script': {
+ pattern: /<script[\w\W]*?>[\w\W]*?<\/script>/i,
+ inside: {
+ 'tag': {
+ pattern: /<script[\w\W]*?>|<\/script>/i,
+ inside: Prism.languages.markup.tag.inside
+ },
+ rest: Prism.languages.javascript
+ },
+ alias: 'language-javascript'
+ }
+ });
+}
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-javascript.min.js b/polymer_1.0.4/bower_components/prism/components/prism-javascript.min.js
new file mode 100644
index 0000000..a8669d7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-javascript.min.js
@@ -0,0 +1 @@
+Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|-?Infinity)\b/,"function":/(?!\d)[a-z0-9_$]+(?=\()/i}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/<script[\w\W]*?>[\w\W]*?<\/script>/i,inside:{tag:{pattern:/<script[\w\W]*?>|<\/script>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript},alias:"language-javascript"}});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-jsx.js b/polymer_1.0.4/bower_components/prism/components/prism-jsx.js
new file mode 100644
index 0000000..10c5f09
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-jsx.js
@@ -0,0 +1,22 @@
+(function(Prism) {
+
+var javascript = Prism.util.clone(Prism.languages.javascript);
+
+Prism.languages.jsx = Prism.languages.extend('markup', javascript);
+Prism.languages.jsx.tag.pattern= /<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+|(\{[\w\W]*?\})))?\s*)*\/?>/i;
+
+Prism.languages.jsx.tag.inside['attr-value'].pattern = /=[^\{](?:('|")[\w\W]*?(\1)|[^\s>]+)/i;
+
+Prism.languages.insertBefore('inside', 'attr-value',{
+ 'script': {
+ pattern: /=(\{[\w\W]*?\})/i,
+ inside: {
+ 'function' : Prism.languages.javascript.function,
+ 'punctuation': /[={}[\];(),.:]/,
+ 'keyword': Prism.languages.javascript.keyword
+ },
+ 'alias': 'language-javascript'
+ }
+}, Prism.languages.jsx.tag);
+
+}(Prism));
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-jsx.min.js b/polymer_1.0.4/bower_components/prism/components/prism-jsx.min.js
new file mode 100644
index 0000000..72c7889
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-jsx.min.js
@@ -0,0 +1 @@
+!function(a){var s=a.util.clone(a.languages.javascript);a.languages.jsx=a.languages.extend("markup",s),a.languages.jsx.tag.pattern=/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+|(\{[\w\W]*?\})))?\s*)*\/?>/i,a.languages.jsx.tag.inside["attr-value"].pattern=/=[^\{](?:('|")[\w\W]*?(\1)|[^\s>]+)/i,a.languages.insertBefore("inside","attr-value",{script:{pattern:/=(\{[\w\W]*?\})/i,inside:{"function":a.languages.javascript.function,punctuation:/[={}[\];(),.:]/,keyword:a.languages.javascript.keyword},alias:"language-javascript"}},a.languages.jsx.tag)}(Prism);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-julia.js b/polymer_1.0.4/bower_components/prism/components/prism-julia.js
new file mode 100644
index 0000000..e437310
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-julia.js
@@ -0,0 +1,12 @@
+Prism.languages.julia= {
+ 'comment': {
+ pattern: /(^|[^\\])#.*?(\r?\n|$)/,
+ lookbehind: true
+ },
+ 'string': /"""[\s\S]+?"""|'''[\s\S]+?'''|("|')(\\?.)*?\1/,
+ 'keyword' : /\b(abstract|baremodule|begin|bitstype|break|catch|ccall|const|continue|do|else|elseif|end|export|finally|for|function|global|if|immutable|import|importall|let|local|macro|module|print|println|quote|return|try|type|typealias|using|while)\b/,
+ 'boolean' : /\b(true|false)\b/,
+ 'number' : /\b-?(0[box])?(?:[\da-f]+\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,
+ 'operator' : /[-+]{1,2}|=?<|=?>|!|={1,2}|&{1,2}|\|?\||\?|\*|\/|~|\^|%|\b(or|and|not)\b/,
+ 'punctuation' : /[{}[\];(),.:]/
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-julia.min.js b/polymer_1.0.4/bower_components/prism/components/prism-julia.min.js
new file mode 100644
index 0000000..4739081
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-julia.min.js
@@ -0,0 +1 @@
+Prism.languages.julia={comment:{pattern:/(^|[^\\])#.*?(\r?\n|$)/,lookbehind:!0},string:/"""[\s\S]+?"""|'''[\s\S]+?'''|("|')(\\?.)*?\1/,keyword:/\b(abstract|baremodule|begin|bitstype|break|catch|ccall|const|continue|do|else|elseif|end|export|finally|for|function|global|if|immutable|import|importall|let|local|macro|module|print|println|quote|return|try|type|typealias|using|while)\b/,"boolean":/\b(true|false)\b/,number:/\b-?(0[box])?(?:[\da-f]+\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+]{1,2}|=?<|=?>|!|={1,2}|&{1,2}|\|?\||\?|\*|\/|~|\^|%|\b(or|and|not)\b/,punctuation:/[{}[\];(),.:]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-latex.js b/polymer_1.0.4/bower_components/prism/components/prism-latex.js
new file mode 100644
index 0000000..faeec07
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-latex.js
@@ -0,0 +1,6 @@
+Prism.languages.latex = {
+ 'comment': /%.*?(\r?\n|$)$/m,
+ 'string': /(\$)(\\?.)*?\1/,
+ 'punctuation': /[{}]/,
+ 'selector': /\\[a-z;,:\.]*/i
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-latex.min.js b/polymer_1.0.4/bower_components/prism/components/prism-latex.min.js
new file mode 100644
index 0000000..baaa28d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-latex.min.js
@@ -0,0 +1 @@
+Prism.languages.latex={comment:/%.*?(\r?\n|$)$/m,string:/(\$)(\\?.)*?\1/,punctuation:/[{}]/,selector:/\\[a-z;,:\.]*/i};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-less.js b/polymer_1.0.4/bower_components/prism/components/prism-less.js
new file mode 100644
index 0000000..0ed468c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-less.js
@@ -0,0 +1,60 @@
+/* FIXME :
+ :extend() is not handled specifically : its highlighting is buggy.
+ Mixin usage must be inside a ruleset to be highlighted.
+ At-rules (e.g. import) containing interpolations are buggy.
+ Detached rulesets are highlighted as at-rules.
+ A comment before a mixin usage prevents the latter to be properly highlighted.
+ */
+
+Prism.languages.less = Prism.languages.extend('css', {
+ 'comment': [
+ /\/\*[\w\W]*?\*\//,
+ {
+ pattern: /(^|[^\\])\/\/.*/,
+ lookbehind: true
+ }
+ ],
+ 'atrule': {
+ pattern: /@[\w-]+?(?:\([^{}]+\)|[^(){};])*?(?=\s*\{)/i,
+ inside: {
+ 'punctuation': /[:()]/
+ }
+ },
+ // selectors and mixins are considered the same
+ 'selector': {
+ pattern: /(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\([^{}]*\)|[^{};@])*?(?=\s*\{)/,
+ inside: {
+ // mixin parameters
+ 'variable': /@+[\w-]+/
+ }
+ },
+
+ 'property': /(\b|\B)(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/i,
+ 'punctuation': /[{}();:,]/,
+ 'operator': /[+\-*\/]/
+});
+
+// Invert function and punctuation positions
+Prism.languages.insertBefore('less', 'punctuation', {
+ 'function': Prism.languages.less.function
+});
+
+Prism.languages.insertBefore('less', 'property', {
+ 'variable': [
+ // Variable declaration (the colon must be consumed!)
+ {
+ pattern: /@[\w-]+\s*:/,
+ inside: {
+ "punctuation": /:/
+ }
+ },
+
+ // Variable usage
+ /@@?[\w-]+/
+ ],
+ 'mixin-usage': {
+ pattern: /([{;]\s*)[.#](?!\d)[\w-]+.*?(?=[(;])/,
+ lookbehind: true,
+ alias: 'function'
+ }
+});
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-less.min.js b/polymer_1.0.4/bower_components/prism/components/prism-less.min.js
new file mode 100644
index 0000000..e470eab
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-less.min.js
@@ -0,0 +1 @@
+Prism.languages.less=Prism.languages.extend("css",{comment:[/\/\*[\w\W]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-]+?(?:\([^{}]+\)|[^(){};])*?(?=\s*\{)/i,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\([^{}]*\)|[^{};@])*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(\b|\B)(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/i,punctuation:/[{}();:,]/,operator:/[+\-*\/]/}),Prism.languages.insertBefore("less","punctuation",{"function":Prism.languages.less.function}),Prism.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-]+.*?(?=[(;])/,lookbehind:!0,alias:"function"}});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-lolcode.js b/polymer_1.0.4/bower_components/prism/components/prism-lolcode.js
new file mode 100644
index 0000000..09e3433
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-lolcode.js
@@ -0,0 +1,54 @@
+Prism.languages.lolcode = {
+ 'comment': [
+ /\bOBTW\s+[\s\S]*?\s+TLDR\b/,
+ /\bBTW.+/
+ ],
+ 'string': {
+ pattern: /"(?::.|[^"])*"/,
+ inside: {
+ 'variable': /:\{[^}]+\}/,
+ 'symbol': [
+ /:\([a-f\d]+\)/i,
+ /:\[[^\]]+\]/,
+ /:[)>o":]/
+ ]
+ }
+ },
+ 'number': /(-|\b)\d*\.?\d+/,
+ 'symbol': {
+ pattern: /(^|\s)(?:A )?(?:YARN|NUMBR|NUMBAR|TROOF|BUKKIT|NOOB)(?=\s|,|$)/,
+ lookbehind: true,
+ inside: {
+ 'keyword': /A(?=\s)/
+ }
+ },
+ 'label': {
+ pattern: /((?:^|\s)(?:IM IN YR|IM OUTTA YR) )[a-zA-Z]\w*/,
+ lookbehind: true,
+ alias: 'string'
+ },
+ 'function': {
+ pattern: /((?:^|\s)(?:I IZ|HOW IZ I|IZ) )[a-zA-Z]\w*/,
+ lookbehind: true
+ },
+ 'keyword': [
+ {
+ pattern: /(^|\s)(?:O HAI IM|KTHX|HAI|KTHXBYE|I HAS A|ITZ(?: A)?|R|AN|MKAY|SMOOSH|MAEK|IS NOW(?: A)?|VISIBLE|GIMMEH|O RLY\?|YA RLY|NO WAI|OIC|MEBBE|WTF\?|OMG|OMGWTF|GTFO|IM IN YR|IM OUTTA YR|FOUND YR|YR|TIL|WILE|UPPIN|NERFIN|I IZ|HOW IZ I|IF U SAY SO|SRS|HAS A|LIEK(?: A)?|IZ)(?=\s|,|$)/,
+ lookbehind: true
+ },
+ /'Z(?=\s|,|$)/
+ ],
+ 'boolean': {
+ pattern: /(^|\s)(?:WIN|FAIL)(?=\s|,|$)/,
+ lookbehind: true
+ },
+ 'variable': {
+ pattern: /(^|\s)(?:IT)(?=\s|,|$)/,
+ lookbehind: true
+ },
+ 'operator': {
+ pattern: /(^|\s)(?:NOT|BOTH SAEM|DIFFRINT|(?:SUM|DIFF|PRODUKT|QUOSHUNT|MOD|BIGGR|SMALLR|BOTH|EITHER|WON|ALL|ANY) OF)(?=\s|,|$)/,
+ lookbehind: true
+ },
+ 'punctuation': /\.{3}|\u2026|,|!/
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-lolcode.min.js b/polymer_1.0.4/bower_components/prism/components/prism-lolcode.min.js
new file mode 100644
index 0000000..76cd604
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-lolcode.min.js
@@ -0,0 +1 @@
+Prism.languages.lolcode={comment:[/\bOBTW\s+[\s\S]*?\s+TLDR\b/,/\bBTW.+/],string:{pattern:/"(?::.|[^"])*"/,inside:{variable:/:\{[^}]+\}/,symbol:[/:\([a-f\d]+\)/i,/:\[[^\]]+\]/,/:[)>o":]/]}},number:/(-|\b)\d*\.?\d+/,symbol:{pattern:/(^|\s)(?:A )?(?:YARN|NUMBR|NUMBAR|TROOF|BUKKIT|NOOB)(?=\s|,|$)/,lookbehind:!0,inside:{keyword:/A(?=\s)/}},label:{pattern:/((?:^|\s)(?:IM IN YR|IM OUTTA YR) )[a-zA-Z]\w*/,lookbehind:!0,alias:"string"},"function":{pattern:/((?:^|\s)(?:I IZ|HOW IZ I|IZ) )[a-zA-Z]\w*/,lookbehind:!0},keyword:[{pattern:/(^|\s)(?:O HAI IM|KTHX|HAI|KTHXBYE|I HAS A|ITZ(?: A)?|R|AN|MKAY|SMOOSH|MAEK|IS NOW(?: A)?|VISIBLE|GIMMEH|O RLY\?|YA RLY|NO WAI|OIC|MEBBE|WTF\?|OMG|OMGWTF|GTFO|IM IN YR|IM OUTTA YR|FOUND YR|YR|TIL|WILE|UPPIN|NERFIN|I IZ|HOW IZ I|IF U SAY SO|SRS|HAS A|LIEK(?: A)?|IZ)(?=\s|,|$)/,lookbehind:!0},/'Z(?=\s|,|$)/],"boolean":{pattern:/(^|\s)(?:WIN|FAIL)(?=\s|,|$)/,lookbehind:!0},variable:{pattern:/(^|\s)(?:IT)(?=\s|,|$)/,lookbehind:!0},operator:{pattern:/(^|\s)(?:NOT|BOTH SAEM|DIFFRINT|(?:SUM|DIFF|PRODUKT|QUOSHUNT|MOD|BIGGR|SMALLR|BOTH|EITHER|WON|ALL|ANY) OF)(?=\s|,|$)/,lookbehind:!0},punctuation:/\.{3}|\u2026|,|!/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-markdown.js b/polymer_1.0.4/bower_components/prism/components/prism-markdown.js
new file mode 100644
index 0000000..94a7154
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-markdown.js
@@ -0,0 +1,122 @@
+Prism.languages.markdown = Prism.languages.extend('markup', {});
+Prism.languages.insertBefore('markdown', 'prolog', {
+ 'blockquote': {
+ // > ...
+ pattern: /(^|\n)>(?:[\t ]*>)*/,
+ lookbehind: true,
+ alias: 'punctuation'
+ },
+ 'code': [
+ {
+ // Prefixed by 4 spaces or 1 tab
+ pattern: /(^|\n)(?: {4}|\t).+/,
+ lookbehind: true,
+ alias: 'keyword'
+ },
+ {
+ // `code`
+ // ``code``
+ pattern: /``.+?``|`[^`\n]+`/,
+ alias: 'keyword'
+ }
+ ],
+ 'title': [
+ {
+ // title 1
+ // =======
+
+ // title 2
+ // -------
+ pattern: /\w+.*\n(?:==+|--+)/,
+ alias: 'important',
+ inside: {
+ punctuation: /==+$|--+$/
+ }
+ },
+ {
+ // # title 1
+ // ###### title 6
+ pattern: /((?:^|\n)\s*)#+.+/,
+ lookbehind: true,
+ alias: 'important',
+ inside: {
+ punctuation: /^#+|#+$/
+ }
+ }
+ ],
+ 'hr': {
+ // ***
+ // ---
+ // * * *
+ // -----------
+ pattern: /((?:^|\n)\s*)([*-])([\t ]*\2){2,}(?=\s*(?:\n|$))/,
+ lookbehind: true,
+ alias: 'punctuation'
+ },
+ 'list': {
+ // * item
+ // + item
+ // - item
+ // 1. item
+ pattern: /((?:^|\n)\s*)(?:[*+-]|\d+\.)(?=[\t ].)/,
+ lookbehind: true,
+ alias: 'punctuation'
+ },
+ 'url-reference': {
+ // [id]: http://example.com "Optional title"
+ // [id]: http://example.com 'Optional title'
+ // [id]: http://example.com (Optional title)
+ // [id]: <http://example.com> "Optional title"
+ pattern: /!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:[^>]|\\>)+>)(?:[\t ]+(?:"(?:[^"]|\\")*"|'(?:[^']|\\')*'|\((?:[^)]|\\\))*\)))?/,
+ inside: {
+ 'variable': {
+ pattern: /^(!?\[)[^\]]+/,
+ lookbehind: true
+ },
+ 'string': /(?:"(?:[^"]|\\")*"|'(?:[^']|\\')*'|\((?:[^)]|\\\))*\))$/,
+ 'punctuation': /[[\]\(\)<>:]/
+ },
+ alias: 'url'
+ },
+ 'bold': {
+ // **strong**
+ // __strong__
+
+ // Allow only one line break
+ pattern: /(^|[^\\])(\*\*|__)(?:\n(?!\n)|.)+?\2/,
+ lookbehind: true,
+ inside: {
+ 'punctuation': /^\*\*|^__|\*\*\s*$|__\s*$/
+ }
+ },
+ 'italic': {
+ // *em*
+ // _em_
+
+ // Allow only one line break
+ pattern: /(^|[^\\])(?:\*(?:\n(?!\n)|.)+?\*|_(?:\n(?!\n)|.)+?_)/,
+ lookbehind: true,
+ inside: {
+ 'punctuation': /^[*_]|[*_]$/
+ }
+ },
+ 'url': {
+ // [example](http://example.com "Optional title")
+ // [example] [id]
+ pattern: /!?\[[^\]]+\](?:\([^\s)]+(?:[\t ]+"(?:[^"]|\\")*")?\)| ?\[[^\]\n]*\])/,
+ inside: {
+ 'variable': {
+ pattern: /(!?\[)[^\]]+(?=\]$)/,
+ lookbehind: true
+ },
+ 'string': {
+ pattern: /"(?:[^"]|\\")*"(?=\)$)/
+ }
+ }
+ }
+});
+
+Prism.languages.markdown['bold'].inside['url'] = Prism.util.clone(Prism.languages.markdown['url']);
+Prism.languages.markdown['italic'].inside['url'] = Prism.util.clone(Prism.languages.markdown['url']);
+Prism.languages.markdown['bold'].inside['italic'] = Prism.util.clone(Prism.languages.markdown['italic']);
+Prism.languages.markdown['italic'].inside['bold'] = Prism.util.clone(Prism.languages.markdown['bold']);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-markdown.min.js b/polymer_1.0.4/bower_components/prism/components/prism-markdown.min.js
new file mode 100644
index 0000000..b685298
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-markdown.min.js
@@ -0,0 +1 @@
+Prism.languages.markdown=Prism.languages.extend("markup",{}),Prism.languages.insertBefore("markdown","prolog",{blockquote:{pattern:/(^|\n)>(?:[\t ]*>)*/,lookbehind:!0,alias:"punctuation"},code:[{pattern:/(^|\n)(?: {4}|\t).+/,lookbehind:!0,alias:"keyword"},{pattern:/``.+?``|`[^`\n]+`/,alias:"keyword"}],title:[{pattern:/\w+.*\n(?:==+|--+)/,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/((?:^|\n)\s*)#+.+/,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/((?:^|\n)\s*)([*-])([\t ]*\2){2,}(?=\s*(?:\n|$))/,lookbehind:!0,alias:"punctuation"},list:{pattern:/((?:^|\n)\s*)(?:[*+-]|\d+\.)(?=[\t ].)/,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:[^>]|\\>)+>)(?:[\t ]+(?:"(?:[^"]|\\")*"|'(?:[^']|\\')*'|\((?:[^)]|\\\))*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:[^"]|\\")*"|'(?:[^']|\\')*'|\((?:[^)]|\\\))*\))$/,punctuation:/[[\]\(\)<>:]/},alias:"url"},bold:{pattern:/(^|[^\\])(\*\*|__)(?:\n(?!\n)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^\*\*|^__|\*\*\s*$|__\s*$/}},italic:{pattern:/(^|[^\\])(?:\*(?:\n(?!\n)|.)+?\*|_(?:\n(?!\n)|.)+?_)/,lookbehind:!0,inside:{punctuation:/^[*_]|[*_]$/}},url:{pattern:/!?\[[^\]]+\](?:\([^\s)]+(?:[\t ]+"(?:[^"]|\\")*")?\)| ?\[[^\]\n]*\])/,inside:{variable:{pattern:/(!?\[)[^\]]+(?=\]$)/,lookbehind:!0},string:{pattern:/"(?:[^"]|\\")*"(?=\)$)/}}}}),Prism.languages.markdown.bold.inside.url=Prism.util.clone(Prism.languages.markdown.url),Prism.languages.markdown.italic.inside.url=Prism.util.clone(Prism.languages.markdown.url),Prism.languages.markdown.bold.inside.italic=Prism.util.clone(Prism.languages.markdown.italic),Prism.languages.markdown.italic.inside.bold=Prism.util.clone(Prism.languages.markdown.bold);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-markup.js b/polymer_1.0.4/bower_components/prism/components/prism-markup.js
new file mode 100644
index 0000000..f4ab4f3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-markup.js
@@ -0,0 +1,41 @@
+Prism.languages.markup = {
+ 'comment': /<!--[\w\W]*?-->/,
+ 'prolog': /<\?.+?\?>/,
+ 'doctype': /<!DOCTYPE.+?>/,
+ 'cdata': /<!\[CDATA\[[\w\W]*?]]>/i,
+ 'tag': {
+ pattern: /<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/i,
+ inside: {
+ 'tag': {
+ pattern: /^<\/?[\w:-]+/i,
+ inside: {
+ 'punctuation': /^<\/?/,
+ 'namespace': /^[\w-]+?:/
+ }
+ },
+ 'attr-value': {
+ pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,
+ inside: {
+ 'punctuation': /=|>|"/
+ }
+ },
+ 'punctuation': /\/?>/,
+ 'attr-name': {
+ pattern: /[\w:-]+/,
+ inside: {
+ 'namespace': /^[\w-]+?:/
+ }
+ }
+
+ }
+ },
+ 'entity': /&#?[\da-z]{1,8};/i
+};
+
+// Plugin to make entity title show the real entity, idea by Roman Komarov
+Prism.hooks.add('wrap', function(env) {
+
+ if (env.type === 'entity') {
+ env.attributes['title'] = env.content.replace(/&/, '&');
+ }
+});
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-markup.min.js b/polymer_1.0.4/bower_components/prism/components/prism-markup.min.js
new file mode 100644
index 0000000..fbf3055
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-markup.min.js
@@ -0,0 +1 @@
+Prism.languages.markup={comment:/<!--[\w\W]*?-->/,prolog:/<\?.+?\?>/,doctype:/<!DOCTYPE.+?>/,cdata:/<!\[CDATA\[[\w\W]*?]]>/i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/i,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/=|>|"/}},punctuation:/\/?>/,"attr-name":{pattern:/[\w:-]+/,inside:{namespace:/^[\w-]+?:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(t){"entity"===t.type&&(t.attributes.title=t.content.replace(/&/,"&"))});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-matlab.js b/polymer_1.0.4/bower_components/prism/components/prism-matlab.js
new file mode 100644
index 0000000..b75b109
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-matlab.js
@@ -0,0 +1,17 @@
+Prism.languages.matlab = {
+ // We put string before comment, because of printf() patterns that contain "%"
+ 'string': {
+ pattern: /(^|\W)'(?:''|[^'\n])*'/,
+ lookbehind: true
+ },
+ 'comment': [
+ /%\{[\s\S]*?\}%/,
+ /%.+/
+ ],
+ // FIXME We could handle imaginary numbers as a whole
+ 'number': /\b-?(?:\d*\.?\d+(?:[eE][+-]?\d+)?(?:[ij])?|[ij])\b/,
+ 'keyword': /\b(?:break|case|catch|continue|else|elseif|end|for|function|if|inf|NaN|otherwise|parfor|pause|pi|return|switch|try|while)\b/,
+ 'function': /(?!\d)\w+(?=\s*\()/,
+ 'operator': /\.?[*^\/\\']|[+\-:@]|[<>=~]=?|&&?|\|\|?/,
+ 'punctuation': /\.{3}|[.,;\[\](){}!]/
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-matlab.min.js b/polymer_1.0.4/bower_components/prism/components/prism-matlab.min.js
new file mode 100644
index 0000000..4fa7d4a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-matlab.min.js
@@ -0,0 +1 @@
+Prism.languages.matlab={string:{pattern:/(^|\W)'(?:''|[^'\n])*'/,lookbehind:!0},comment:[/%\{[\s\S]*?\}%/,/%.+/],number:/\b-?(?:\d*\.?\d+(?:[eE][+-]?\d+)?(?:[ij])?|[ij])\b/,keyword:/\b(?:break|case|catch|continue|else|elseif|end|for|function|if|inf|NaN|otherwise|parfor|pause|pi|return|switch|try|while)\b/,"function":/(?!\d)\w+(?=\s*\()/,operator:/\.?[*^\/\\']|[+\-:@]|[<>=~]=?|&&?|\|\|?/,punctuation:/\.{3}|[.,;\[\](){}!]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-nasm.js b/polymer_1.0.4/bower_components/prism/components/prism-nasm.js
new file mode 100644
index 0000000..b107254
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-nasm.js
@@ -0,0 +1,20 @@
+Prism.languages.nasm = {
+ 'comment': /;.*$/m,
+ 'string': /("|'|`)(\\?.)*?\1/m,
+ 'label': {
+ pattern: /^\s*[A-Za-z\._\?\$][\w\.\?\$@~#]*:/m,
+ alias: 'function'
+ },
+ 'keyword': [
+ /\[?BITS (16|32|64)\]?/m,
+ /^\s*section\s*[a-zA-Z\.]+:?/im,
+ /(?:extern|global)[^;]*/im,
+ /(?:CPU|FLOAT|DEFAULT).*$/m
+ ],
+ 'register': {
+ pattern: /\b(?:st\d|[xyz]mm\d\d?|[cdt]r\d|r\d\d?[bwd]?|[er]?[abcd]x|[abcd][hl]|[er]?(bp|sp|si|di)|[cdefgs]s)\b/i,
+ alias: 'variable'
+ },
+ 'number': /(\b|-|(?=\$))(0[hx][\da-f]*\.?[\da-f]+(p[+-]?\d+)?|\d[\da-f]+[hx]|\$\d[\da-f]*|0[oq][0-7]+|[0-7]+[oq]|0[by][01]+|[01]+[by]|0[dt]\d+|\d*\.?\d+(\.?e[+-]?\d+)?[dt]?)\b/i,
+ 'operator': /[\[\]\*+\-\/%<>=&|\$!]/m
+};
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-nasm.min.js b/polymer_1.0.4/bower_components/prism/components/prism-nasm.min.js
new file mode 100644
index 0000000..3296069
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-nasm.min.js
@@ -0,0 +1 @@
+Prism.languages.nasm={comment:/;.*$/m,string:/("|'|`)(\\?.)*?\1/m,label:{pattern:/^\s*[A-Za-z\._\?\$][\w\.\?\$@~#]*:/m,alias:"function"},keyword:[/\[?BITS (16|32|64)\]?/m,/^\s*section\s*[a-zA-Z\.]+:?/im,/(?:extern|global)[^;]*/im,/(?:CPU|FLOAT|DEFAULT).*$/m],register:{pattern:/\b(?:st\d|[xyz]mm\d\d?|[cdt]r\d|r\d\d?[bwd]?|[er]?[abcd]x|[abcd][hl]|[er]?(bp|sp|si|di)|[cdefgs]s)\b/i,alias:"variable"},number:/(\b|-|(?=\$))(0[hx][\da-f]*\.?[\da-f]+(p[+-]?\d+)?|\d[\da-f]+[hx]|\$\d[\da-f]*|0[oq][0-7]+|[0-7]+[oq]|0[by][01]+|[01]+[by]|0[dt]\d+|\d*\.?\d+(\.?e[+-]?\d+)?[dt]?)\b/i,operator:/[\[\]\*+\-\/%<>=&|\$!]/m};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-nsis.js b/polymer_1.0.4/bower_components/prism/components/prism-nsis.js
new file mode 100644
index 0000000..6afa00a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-nsis.js
@@ -0,0 +1,19 @@
+/**
+ * Original by Jan T. Sott (http://github.com/idleberg)
+ *
+ * Includes all commands and plug-ins shipped with NSIS 3.0a2
+ */
+ Prism.languages.nsis = {
+ 'comment': {
+ pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])(#|;).*?(\r?\n|$))/,
+ lookbehind: true
+ },
+ 'string': /("|')(\\?.)*?\1/,
+ 'keyword': /\b(Abort|Add(BrandingImage|Size)|AdvSplash|Allow(RootDirInstall|SkipFiles)|AutoCloseWindow|Banner|BG(Font|Gradient|Image)|BrandingText|BringToFront|Call(\b|InstDLL)|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|Create(Directory|Font|ShortCut)|Delete(\b|INISec|INIStr|RegKey|RegValue)|Detail(Print|sButtonText)|Dialer|Dir(Text|Var|Verify)|EnableWindow|Enum(RegKey|RegValue)|Exch|Exec(\b|Shell|Wait)|ExpandEnvStrings|File(\b|BufSize|Close|ErrorText|Open|Read|ReadByte|ReadUTF16LE|ReadWord|WriteUTF16LE|Seek|Write|WriteByte|WriteWord)|Find(Close|First|Next|Window)|FlushINI|Get(CurInstType|CurrentAddress|DlgItem|DLLVersion|DLLVersionLocal|ErrorLevel|FileTime|FileTimeLocal|FullPathName|Function(\b|Address|End)|InstDirError|LabelAddress|TempFileName)|Goto|HideWindow|Icon|If(Abort|Errors|FileExists|RebootFlag|Silent)|InitPluginsDir|Install(ButtonText|Colors|Dir|DirRegKey)|InstProgressFlags|Inst(Type|TypeGetText|TypeSetText)|Int(Cmp|CmpU|Fmt|Op)|IsWindow|Lang(DLL|String)|License(BkColor|Data|ForceSelection|LangString|Text)|LoadLanguageFile|LockWindow|Log(Set|Text)|Manifest(DPIAware|SupportedOS)|Math|MessageBox|MiscButtonText|Name|Nop|ns(Dialogs|Exec)|NSISdl|OutFile|Page(\b|Callbacks)|Pop|Push|Quit|Read(EnvStr|INIStr|RegDWORD|RegStr)|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|Section(\b|End|GetFlags|GetInstTypes|GetSize|GetText|Group|In|SetFlags|SetInstTypes|SetSize|SetText)|SendMessage|Set(AutoClose|BrandingImage|Compress|Compressor|CompressorDictSize|CtlColors|CurInstType|DatablockOptimize|DateSave|DetailsPrint|DetailsView|ErrorLevel|Errors|FileAttributes|Font|OutPath|Overwrite|PluginUnload|RebootFlag|RegView|ShellVarContext|Silent)|Show(InstDetails|UninstDetails|Window)|Silent(Install|UnInstall)|Sleep|SpaceTexts|Splash|StartMenu|Str(Cmp|CmpS|Cpy|Len)|SubCaption|System|Unicode|Uninstall(ButtonText|Caption|Icon|SubCaption|Text)|UninstPage|UnRegDLL|UserInfo|Var|VI(AddVersionKey|FileVersion|ProductVersion)|VPatch|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|Write(RegStr|Uninstaller)|XPStyle)\b/,
+ 'property': /\b(admin|all|auto|both|colored|false|force|hide|highest|lastused|leave|listonly|none|normal|notset|off|on|open|print|show|silent|silentlog|smooth|textonly|true|user|ARCHIVE|FILE_(ATTRIBUTE_ARCHIVE|ATTRIBUTE_NORMAL|ATTRIBUTE_OFFLINE|ATTRIBUTE_READONLY|ATTRIBUTE_SYSTEM|ATTRIBUTE_TEMPORARY)|HK(CR|CU|DD|LM|PD|U)|HKEY_(CLASSES_ROOT|CURRENT_CONFIG|CURRENT_USER|DYN_DATA|LOCAL_MACHINE|PERFORMANCE_DATA|USERS)|ID(ABORT|CANCEL|IGNORE|NO|OK|RETRY|YES)|MB_(ABORTRETRYIGNORE|DEFBUTTON1|DEFBUTTON2|DEFBUTTON3|DEFBUTTON4|ICONEXCLAMATION|ICONINFORMATION|ICONQUESTION|ICONSTOP|OK|OKCANCEL|RETRYCANCEL|RIGHT|RTLREADING|SETFOREGROUND|TOPMOST|USERICON|YESNO)|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SYSTEM|TEMPORARY)\b/,
+ 'variable': /(\$(\(|\{)?[-_\w]+)(\)|\})?/i,
+ 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,
+ 'operator': /[-+]{1,2}|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/,
+ 'punctuation': /[{}[\];(),.:]/,
+ 'important': /!(addincludedir|addplugindir|appendfile|cd|define|delfile|echo|else|endif|error|execute|finalize|getdllversionsystem|ifdef|ifmacrodef|ifmacrondef|ifndef|if|include|insertmacro|macroend|macro|makensis|packhdr|searchparse|searchreplace|tempfile|undef|verbose|warning)\b/i
+};
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-nsis.min.js b/polymer_1.0.4/bower_components/prism/components/prism-nsis.min.js
new file mode 100644
index 0000000..7d342ed
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-nsis.min.js
@@ -0,0 +1 @@
+Prism.languages.nsis={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])(#|;).*?(\r?\n|$))/,lookbehind:!0},string:/("|')(\\?.)*?\1/,keyword:/\b(Abort|Add(BrandingImage|Size)|AdvSplash|Allow(RootDirInstall|SkipFiles)|AutoCloseWindow|Banner|BG(Font|Gradient|Image)|BrandingText|BringToFront|Call(\b|InstDLL)|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|Create(Directory|Font|ShortCut)|Delete(\b|INISec|INIStr|RegKey|RegValue)|Detail(Print|sButtonText)|Dialer|Dir(Text|Var|Verify)|EnableWindow|Enum(RegKey|RegValue)|Exch|Exec(\b|Shell|Wait)|ExpandEnvStrings|File(\b|BufSize|Close|ErrorText|Open|Read|ReadByte|ReadUTF16LE|ReadWord|WriteUTF16LE|Seek|Write|WriteByte|WriteWord)|Find(Close|First|Next|Window)|FlushINI|Get(CurInstType|CurrentAddress|DlgItem|DLLVersion|DLLVersionLocal|ErrorLevel|FileTime|FileTimeLocal|FullPathName|Function(\b|Address|End)|InstDirError|LabelAddress|TempFileName)|Goto|HideWindow|Icon|If(Abort|Errors|FileExists|RebootFlag|Silent)|InitPluginsDir|Install(ButtonText|Colors|Dir|DirRegKey)|InstProgressFlags|Inst(Type|TypeGetText|TypeSetText)|Int(Cmp|CmpU|Fmt|Op)|IsWindow|Lang(DLL|String)|License(BkColor|Data|ForceSelection|LangString|Text)|LoadLanguageFile|LockWindow|Log(Set|Text)|Manifest(DPIAware|SupportedOS)|Math|MessageBox|MiscButtonText|Name|Nop|ns(Dialogs|Exec)|NSISdl|OutFile|Page(\b|Callbacks)|Pop|Push|Quit|Read(EnvStr|INIStr|RegDWORD|RegStr)|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|Section(\b|End|GetFlags|GetInstTypes|GetSize|GetText|Group|In|SetFlags|SetInstTypes|SetSize|SetText)|SendMessage|Set(AutoClose|BrandingImage|Compress|Compressor|CompressorDictSize|CtlColors|CurInstType|DatablockOptimize|DateSave|DetailsPrint|DetailsView|ErrorLevel|Errors|FileAttributes|Font|OutPath|Overwrite|PluginUnload|RebootFlag|RegView|ShellVarContext|Silent)|Show(InstDetails|UninstDetails|Window)|Silent(Install|UnInstall)|Sleep|SpaceTexts|Splash|StartMenu|Str(Cmp|CmpS|Cpy|Len)|SubCaption|System|Unicode|Uninstall(ButtonText|Caption|Icon|SubCaption|Text)|UninstPage|UnRegDLL|UserInfo|Var|VI(AddVersionKey|FileVersion|ProductVersion)|VPatch|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|Write(RegStr|Uninstaller)|XPStyle)\b/,property:/\b(admin|all|auto|both|colored|false|force|hide|highest|lastused|leave|listonly|none|normal|notset|off|on|open|print|show|silent|silentlog|smooth|textonly|true|user|ARCHIVE|FILE_(ATTRIBUTE_ARCHIVE|ATTRIBUTE_NORMAL|ATTRIBUTE_OFFLINE|ATTRIBUTE_READONLY|ATTRIBUTE_SYSTEM|ATTRIBUTE_TEMPORARY)|HK(CR|CU|DD|LM|PD|U)|HKEY_(CLASSES_ROOT|CURRENT_CONFIG|CURRENT_USER|DYN_DATA|LOCAL_MACHINE|PERFORMANCE_DATA|USERS)|ID(ABORT|CANCEL|IGNORE|NO|OK|RETRY|YES)|MB_(ABORTRETRYIGNORE|DEFBUTTON1|DEFBUTTON2|DEFBUTTON3|DEFBUTTON4|ICONEXCLAMATION|ICONINFORMATION|ICONQUESTION|ICONSTOP|OK|OKCANCEL|RETRYCANCEL|RIGHT|RTLREADING|SETFOREGROUND|TOPMOST|USERICON|YESNO)|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SYSTEM|TEMPORARY)\b/,variable:/(\$(\(|\{)?[-_\w]+)(\)|\})?/i,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,operator:/[-+]{1,2}|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/,important:/!(addincludedir|addplugindir|appendfile|cd|define|delfile|echo|else|endif|error|execute|finalize|getdllversionsystem|ifdef|ifmacrodef|ifmacrondef|ifndef|if|include|insertmacro|macroend|macro|makensis|packhdr|searchparse|searchreplace|tempfile|undef|verbose|warning)\b/i};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-objectivec.js b/polymer_1.0.4/bower_components/prism/components/prism-objectivec.js
new file mode 100644
index 0000000..5f5db4b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-objectivec.js
@@ -0,0 +1,5 @@
+Prism.languages.objectivec = Prism.languages.extend('c', {
+ 'keyword': /(\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while|in|self|super)\b)|((?=[\w|@])(@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b)/,
+ 'string': /(?:("|')([^\n\\\1]|\\.|\\\r*\n)*?\1)|(@"([^\n\\"]|\\.|\\\r*\n)*?")/,
+ 'operator': /[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|@/
+});
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-objectivec.min.js b/polymer_1.0.4/bower_components/prism/components/prism-objectivec.min.js
new file mode 100644
index 0000000..0bf208c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-objectivec.min.js
@@ -0,0 +1 @@
+Prism.languages.objectivec=Prism.languages.extend("c",{keyword:/(\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while|in|self|super)\b)|((?=[\w|@])(@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b)/,string:/(?:("|')([^\n\\\1]|\\.|\\\r*\n)*?\1)|(@"([^\n\\"]|\\.|\\\r*\n)*?")/,operator:/[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|@/});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-pascal.js b/polymer_1.0.4/bower_components/prism/components/prism-pascal.js
new file mode 100644
index 0000000..47164fe
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-pascal.js
@@ -0,0 +1,54 @@
+// Based on Free Pascal
+
+/* TODO
+ Support inline asm ?
+*/
+
+Prism.languages.pascal = {
+ 'comment': [
+ /\(\*[\s\S]+?\*\)/,
+ /\{[\s\S]+?\}/,
+ /\/\/.*/
+ ],
+ 'string': [
+ /(?:'(?:''|[^'\n])*'|#[&$%]?[a-f\d]+)+/i,
+ // Char
+ /\^[a-z]/i
+ ],
+ 'keyword': [
+ {
+ // Turbo Pascal
+ pattern: /(^|(?!&)[\s\S])\b(?:absolute|array|asm|begin|case|const|constructor|destructor|do|downto|else|end|file|for|function|goto|if|implementation|inherited|inline|interface|label|nil|object|of|operator|packed|procedure|program|record|reintroduce|repeat|self|set|string|then|to|type|unit|until|uses|var|while|with)\b/i,
+ lookbehind: true
+ },
+ {
+ // Free Pascal
+ pattern: /(^|(?!&)[\s\S])\b(?:dispose|exit|false|new|true)\b/i,
+ lookbehind: true
+ },
+ {
+ // Object Pascal
+ pattern: /(^|(?!&)[\s\S])\b(?:class|dispinterface|except|exports|finalization|finally|initialization|inline|library|on|out|packed|property|raise|resourcestring|threadvar|try)\b/i,
+ lookbehind: true
+ },
+ {
+ // Modifiers
+ pattern: /(^|(?!&)[\s\S])\b(?:absolute|abstract|alias|assembler|bitpacked|break|cdecl|continue|cppdecl|cvar|default|deprecated|dynamic|enumerator|experimental|export|external|far|far16|forward|generic|helper|implements|index|interrupt|iochecks|local|message|name|near|nodefault|noreturn|nostackframe|oldfpccall|otherwise|overload|override|pascal|platform|private|protected|public|published|read|register|reintroduce|result|safecall|saveregisters|softfloat|specialize|static|stdcall|stored|strict|unaligned|unimplemented|varargs|virtual|write)\b/i,
+ lookbehind: true
+ }
+ ],
+ 'number': [
+ // Hexadecimal, octal and binary
+ /[+-]?(?:[&%]\d+|\$[a-f\d]+)/i,
+ // Decimal
+ /([+-]|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?/i
+ ],
+ 'operator': [
+ /\.\.|\*\*|:=|[<>]{2}|[<>+\-*\/]=?|[@^=]/i,
+ {
+ pattern: /(^|(?!&)[\s\S])\b(?:and|as|div|exclude|in|include|is|mod|not|or|shl|shr|xor)\b/,
+ lookbehind: true
+ }
+ ],
+ 'punctuation': /\(\.|\.\)|[()\[\]:;,.]/
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-pascal.min.js b/polymer_1.0.4/bower_components/prism/components/prism-pascal.min.js
new file mode 100644
index 0000000..d16b865
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-pascal.min.js
@@ -0,0 +1 @@
+Prism.languages.pascal={comment:[/\(\*[\s\S]+?\*\)/,/\{[\s\S]+?\}/,/\/\/.*/],string:[/(?:'(?:''|[^'\n])*'|#[&$%]?[a-f\d]+)+/i,/\^[a-z]/i],keyword:[{pattern:/(^|(?!&)[\s\S])\b(?:absolute|array|asm|begin|case|const|constructor|destructor|do|downto|else|end|file|for|function|goto|if|implementation|inherited|inline|interface|label|nil|object|of|operator|packed|procedure|program|record|reintroduce|repeat|self|set|string|then|to|type|unit|until|uses|var|while|with)\b/i,lookbehind:!0},{pattern:/(^|(?!&)[\s\S])\b(?:dispose|exit|false|new|true)\b/i,lookbehind:!0},{pattern:/(^|(?!&)[\s\S])\b(?:class|dispinterface|except|exports|finalization|finally|initialization|inline|library|on|out|packed|property|raise|resourcestring|threadvar|try)\b/i,lookbehind:!0},{pattern:/(^|(?!&)[\s\S])\b(?:absolute|abstract|alias|assembler|bitpacked|break|cdecl|continue|cppdecl|cvar|default|deprecated|dynamic|enumerator|experimental|export|external|far|far16|forward|generic|helper|implements|index|interrupt|iochecks|local|message|name|near|nodefault|noreturn|nostackframe|oldfpccall|otherwise|overload|override|pascal|platform|private|protected|public|published|read|register|reintroduce|result|safecall|saveregisters|softfloat|specialize|static|stdcall|stored|strict|unaligned|unimplemented|varargs|virtual|write)\b/i,lookbehind:!0}],number:[/[+-]?(?:[&%]\d+|\$[a-f\d]+)/i,/([+-]|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?/i],operator:[/\.\.|\*\*|:=|[<>]{2}|[<>+\-*\/]=?|[@^=]/i,{pattern:/(^|(?!&)[\s\S])\b(?:and|as|div|exclude|in|include|is|mod|not|or|shl|shr|xor)\b/,lookbehind:!0}],punctuation:/\(\.|\.\)|[()\[\]:;,.]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-perl.js b/polymer_1.0.4/bower_components/prism/components/prism-perl.js
new file mode 100644
index 0000000..d435e80
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-perl.js
@@ -0,0 +1,112 @@
+Prism.languages.perl = {
+ 'comment': [
+ {
+ // POD
+ pattern: /((?:^|\n)\s*)=\w+[\s\S]*?=cut.*/,
+ lookbehind: true
+ },
+ {
+ pattern: /(^|[^\\$])#.*?(\r?\n|$)/,
+ lookbehind: true
+ }
+ ],
+ // TODO Could be nice to handle Heredoc too.
+ 'string': [
+ // q/.../
+ /\b(?:q|qq|qx|qw)\s*([^a-zA-Z0-9\s\{\(\[<])(\\?.)*?\s*\1/,
+
+ // q a...a
+ /\b(?:q|qq|qx|qw)\s+([a-zA-Z0-9])(\\?.)*?\s*\1/,
+
+ // q(...)
+ /\b(?:q|qq|qx|qw)\s*\(([^()]|\\.)*\s*\)/,
+
+ // q{...}
+ /\b(?:q|qq|qx|qw)\s*\{([^{}]|\\.)*\s*\}/,
+
+ // q[...]
+ /\b(?:q|qq|qx|qw)\s*\[([^[\]]|\\.)*\s*\]/,
+
+ // q<...>
+ /\b(?:q|qq|qx|qw)\s*<([^<>]|\\.)*\s*>/,
+
+ // "...", '...', `...`
+ /("|'|`)(\\?.)*?\1/
+ ],
+ 'regex': [
+ // m/.../
+ /\b(?:m|qr)\s*([^a-zA-Z0-9\s\{\(\[<])(\\?.)*?\s*\1[msixpodualgc]*/,
+
+ // m a...a
+ /\b(?:m|qr)\s+([a-zA-Z0-9])(\\?.)*?\s*\1[msixpodualgc]*/,
+
+ // m(...)
+ /\b(?:m|qr)\s*\(([^()]|\\.)*\s*\)[msixpodualgc]*/,
+
+ // m{...}
+ /\b(?:m|qr)\s*\{([^{}]|\\.)*\s*\}[msixpodualgc]*/,
+
+ // m[...]
+ /\b(?:m|qr)\s*\[([^[\]]|\\.)*\s*\][msixpodualgc]*/,
+
+ // m<...>
+ /\b(?:m|qr)\s*<([^<>]|\\.)*\s*>[msixpodualgc]*/,
+
+ // s/.../.../
+ /\b(?:s|tr|y)\s*([^a-zA-Z0-9\s\{\(\[<])(\\?.)*?\s*\1\s*((?!\1).|\\.)*\s*\1[msixpodualgcer]*/,
+
+ // s a...a...a
+ /\b(?:s|tr|y)\s+([a-zA-Z0-9])(\\?.)*?\s*\1\s*((?!\1).|\\.)*\s*\1[msixpodualgcer]*/,
+
+ // s(...)(...)
+ /\b(?:s|tr|y)\s*\(([^()]|\\.)*\s*\)\s*\(\s*([^()]|\\.)*\s*\)[msixpodualgcer]*/,
+
+ // s{...}{...}
+ /\b(?:s|tr|y)\s*\{([^{}]|\\.)*\s*\}\s*\{\s*([^{}]|\\.)*\s*\}[msixpodualgcer]*/,
+
+ // s[...][...]
+ /\b(?:s|tr|y)\s*\[([^[\]]|\\.)*\s*\]\s*\[\s*([^[\]]|\\.)*\s*\][msixpodualgcer]*/,
+
+ // s<...><...>
+ /\b(?:s|tr|y)\s*<([^<>]|\\.)*\s*>\s*<\s*([^<>]|\\.)*\s*>[msixpodualgcer]*/,
+
+ // /.../
+ /\/(\[.+?]|\\.|[^\/\r\n])*\/[msixpodualgc]*(?=\s*($|[\r\n,.;})&|\-+*=~<>!?^]|(lt|gt|le|ge|eq|ne|cmp|not|and|or|xor|x)\b))/
+ ],
+
+ // FIXME Not sure about the handling of ::, ', and #
+ 'variable': [
+ // ${^POSTMATCH}
+ /[&*\$@%]\{\^[A-Z]+\}/,
+ // $^V
+ /[&*\$@%]\^[A-Z_]/,
+ // ${...}
+ /[&*\$@%]#?(?=\{)/,
+ // $foo
+ /[&*\$@%]#?((::)*'?(?!\d)[\w$]+)+(::)*/i,
+ // $1
+ /[&*\$@%]\d+/,
+ // $_, @_, %!
+ /[\$@%][!"#\$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~]/
+ ],
+ 'filehandle': {
+ // <>, <FOO>, _
+ pattern: /<(?!=).*>|\b_\b/,
+ alias: 'symbol'
+ },
+ 'vstring': {
+ // v1.2, 1.2.3
+ pattern: /v\d+(\.\d+)*|\d+(\.\d+){2,}/,
+ alias: 'string'
+ },
+ 'function': {
+ pattern: /sub [a-z0-9_]+/i,
+ inside: {
+ keyword: /sub/
+ }
+ },
+ 'keyword': /\b(any|break|continue|default|delete|die|do|else|elsif|eval|for|foreach|given|goto|if|last|local|my|next|our|package|print|redo|require|say|state|sub|switch|undef|unless|until|use|when|while)\b/,
+ 'number': /(\n|\b)-?(0x[\dA-Fa-f](_?[\dA-Fa-f])*|0b[01](_?[01])*|(\d(_?\d)*)?\.?\d(_?\d)*([Ee]-?\d+)?)\b/,
+ 'operator': /-[rwxoRWXOezsfdlpSbctugkTBMAC]\b|[-+*=~\/|&]{1,2}|<=?|>=?|\.{1,3}|[!?\\^]|\b(lt|gt|le|ge|eq|ne|cmp|not|and|or|xor|x)\b/,
+ 'punctuation': /[{}[\];(),:]/
+};
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-perl.min.js b/polymer_1.0.4/bower_components/prism/components/prism-perl.min.js
new file mode 100644
index 0000000..f71a20f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-perl.min.js
@@ -0,0 +1 @@
+Prism.languages.perl={comment:[{pattern:/((?:^|\n)\s*)=\w+[\s\S]*?=cut.*/,lookbehind:!0},{pattern:/(^|[^\\$])#.*?(\r?\n|$)/,lookbehind:!0}],string:[/\b(?:q|qq|qx|qw)\s*([^a-zA-Z0-9\s\{\(\[<])(\\?.)*?\s*\1/,/\b(?:q|qq|qx|qw)\s+([a-zA-Z0-9])(\\?.)*?\s*\1/,/\b(?:q|qq|qx|qw)\s*\(([^()]|\\.)*\s*\)/,/\b(?:q|qq|qx|qw)\s*\{([^{}]|\\.)*\s*\}/,/\b(?:q|qq|qx|qw)\s*\[([^[\]]|\\.)*\s*\]/,/\b(?:q|qq|qx|qw)\s*<([^<>]|\\.)*\s*>/,/("|'|`)(\\?.)*?\1/],regex:[/\b(?:m|qr)\s*([^a-zA-Z0-9\s\{\(\[<])(\\?.)*?\s*\1[msixpodualgc]*/,/\b(?:m|qr)\s+([a-zA-Z0-9])(\\?.)*?\s*\1[msixpodualgc]*/,/\b(?:m|qr)\s*\(([^()]|\\.)*\s*\)[msixpodualgc]*/,/\b(?:m|qr)\s*\{([^{}]|\\.)*\s*\}[msixpodualgc]*/,/\b(?:m|qr)\s*\[([^[\]]|\\.)*\s*\][msixpodualgc]*/,/\b(?:m|qr)\s*<([^<>]|\\.)*\s*>[msixpodualgc]*/,/\b(?:s|tr|y)\s*([^a-zA-Z0-9\s\{\(\[<])(\\?.)*?\s*\1\s*((?!\1).|\\.)*\s*\1[msixpodualgcer]*/,/\b(?:s|tr|y)\s+([a-zA-Z0-9])(\\?.)*?\s*\1\s*((?!\1).|\\.)*\s*\1[msixpodualgcer]*/,/\b(?:s|tr|y)\s*\(([^()]|\\.)*\s*\)\s*\(\s*([^()]|\\.)*\s*\)[msixpodualgcer]*/,/\b(?:s|tr|y)\s*\{([^{}]|\\.)*\s*\}\s*\{\s*([^{}]|\\.)*\s*\}[msixpodualgcer]*/,/\b(?:s|tr|y)\s*\[([^[\]]|\\.)*\s*\]\s*\[\s*([^[\]]|\\.)*\s*\][msixpodualgcer]*/,/\b(?:s|tr|y)\s*<([^<>]|\\.)*\s*>\s*<\s*([^<>]|\\.)*\s*>[msixpodualgcer]*/,/\/(\[.+?]|\\.|[^\/\r\n])*\/[msixpodualgc]*(?=\s*($|[\r\n,.;})&|\-+*=~<>!?^]|(lt|gt|le|ge|eq|ne|cmp|not|and|or|xor|x)\b))/],variable:[/[&*\$@%]\{\^[A-Z]+\}/,/[&*\$@%]\^[A-Z_]/,/[&*\$@%]#?(?=\{)/,/[&*\$@%]#?((::)*'?(?!\d)[\w$]+)+(::)*/i,/[&*\$@%]\d+/,/[\$@%][!"#\$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~]/],filehandle:{pattern:/<(?!=).*>|\b_\b/,alias:"symbol"},vstring:{pattern:/v\d+(\.\d+)*|\d+(\.\d+){2,}/,alias:"string"},"function":{pattern:/sub [a-z0-9_]+/i,inside:{keyword:/sub/}},keyword:/\b(any|break|continue|default|delete|die|do|else|elsif|eval|for|foreach|given|goto|if|last|local|my|next|our|package|print|redo|require|say|state|sub|switch|undef|unless|until|use|when|while)\b/,number:/(\n|\b)-?(0x[\dA-Fa-f](_?[\dA-Fa-f])*|0b[01](_?[01])*|(\d(_?\d)*)?\.?\d(_?\d)*([Ee]-?\d+)?)\b/,operator:/-[rwxoRWXOezsfdlpSbctugkTBMAC]\b|[-+*=~\/|&]{1,2}|<=?|>=?|\.{1,3}|[!?\\^]|\b(lt|gt|le|ge|eq|ne|cmp|not|and|or|xor|x)\b/,punctuation:/[{}[\];(),:]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-php-extras.js b/polymer_1.0.4/bower_components/prism/components/prism-php-extras.js
new file mode 100644
index 0000000..914172e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-php-extras.js
@@ -0,0 +1,11 @@
+Prism.languages.insertBefore('php', 'variable', {
+ 'this': /\$this/,
+ 'global': /\$_?(GLOBALS|SERVER|GET|POST|FILES|REQUEST|SESSION|ENV|COOKIE|HTTP_RAW_POST_DATA|argc|argv|php_errormsg|http_response_header)/,
+ 'scope': {
+ pattern: /\b[\w\\]+::/,
+ inside: {
+ keyword: /(static|self|parent)/,
+ punctuation: /(::|\\)/
+ }
+ }
+});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-php-extras.min.js b/polymer_1.0.4/bower_components/prism/components/prism-php-extras.min.js
new file mode 100644
index 0000000..54ef980
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-php-extras.min.js
@@ -0,0 +1 @@
+Prism.languages.insertBefore("php","variable",{"this":/\$this/,global:/\$_?(GLOBALS|SERVER|GET|POST|FILES|REQUEST|SESSION|ENV|COOKIE|HTTP_RAW_POST_DATA|argc|argv|php_errormsg|http_response_header)/,scope:{pattern:/\b[\w\\]+::/,inside:{keyword:/(static|self|parent)/,punctuation:/(::|\\)/}}});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-php.js b/polymer_1.0.4/bower_components/prism/components/prism-php.js
new file mode 100644
index 0000000..825729f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-php.js
@@ -0,0 +1,109 @@
+/**
+ * Original by Aaron Harun: http://aahacreative.com/2012/07/31/php-syntax-highlighting-prism/
+ * Modified by Miles Johnson: http://milesj.me
+ *
+ * Supports the following:
+ * - Extends clike syntax
+ * - Support for PHP 5.3+ (namespaces, traits, generators, etc)
+ * - Smarter constant and function matching
+ *
+ * Adds the following new token classes:
+ * constant, delimiter, variable, function, package
+ */
+
+Prism.languages.php = Prism.languages.extend('clike', {
+ 'keyword': /\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,
+ 'constant': /\b[A-Z0-9_]{2,}\b/,
+ 'comment': {
+ pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])(\/\/).*?(\r?\n|$))/,
+ lookbehind: true
+ }
+});
+
+// Shell-like comments are matched after strings, because they are less
+// common than strings containing hashes...
+Prism.languages.insertBefore('php', 'class-name', {
+ 'shell-comment': {
+ pattern: /(^|[^\\])#.*?(\r?\n|$)/,
+ lookbehind: true,
+ alias: 'comment'
+ }
+});
+
+Prism.languages.insertBefore('php', 'keyword', {
+ 'delimiter': /(\?>|<\?php|<\?)/i,
+ 'variable': /(\$\w+)\b/i,
+ 'package': {
+ pattern: /(\\|namespace\s+|use\s+)[\w\\]+/,
+ lookbehind: true,
+ inside: {
+ punctuation: /\\/
+ }
+ }
+});
+
+// Must be defined after the function pattern
+Prism.languages.insertBefore('php', 'operator', {
+ 'property': {
+ pattern: /(->)[\w]+/,
+ lookbehind: true
+ }
+});
+
+// Add HTML support of the markup language exists
+if (Prism.languages.markup) {
+
+ // Tokenize all inline PHP blocks that are wrapped in <?php ?>
+ // This allows for easy PHP + markup highlighting
+ Prism.hooks.add('before-highlight', function(env) {
+ if (env.language !== 'php') {
+ return;
+ }
+
+ env.tokenStack = [];
+
+ env.backupCode = env.code;
+ env.code = env.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/ig, function(match) {
+ env.tokenStack.push(match);
+
+ return '{{{PHP' + env.tokenStack.length + '}}}';
+ });
+ });
+
+ // Restore env.code for other plugins (e.g. line-numbers)
+ Prism.hooks.add('before-insert', function(env) {
+ if (env.language === 'php') {
+ env.code = env.backupCode;
+ delete env.backupCode;
+ }
+ });
+
+ // Re-insert the tokens after highlighting
+ Prism.hooks.add('after-highlight', function(env) {
+ if (env.language !== 'php') {
+ return;
+ }
+
+ for (var i = 0, t; t = env.tokenStack[i]; i++) {
+ env.highlightedCode = env.highlightedCode.replace('{{{PHP' + (i + 1) + '}}}', Prism.highlight(t, env.grammar, 'php'));
+ }
+
+ env.element.innerHTML = env.highlightedCode;
+ });
+
+ // Wrap tokens in classes that are missing them
+ Prism.hooks.add('wrap', function(env) {
+ if (env.language === 'php' && env.type === 'markup') {
+ env.content = env.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g, "<span class=\"token php\">$1</span>");
+ }
+ });
+
+ // Add the rules before all others
+ Prism.languages.insertBefore('php', 'comment', {
+ 'markup': {
+ pattern: /<[^?]\/?(.*?)>/,
+ inside: Prism.languages.markup
+ },
+ 'php': /\{\{\{PHP[0-9]+\}\}\}/
+ });
+}
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-php.min.js b/polymer_1.0.4/bower_components/prism/components/prism-php.min.js
new file mode 100644
index 0000000..0ac8a2a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-php.min.js
@@ -0,0 +1 @@
+Prism.languages.php=Prism.languages.extend("clike",{keyword:/\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,constant:/\b[A-Z0-9_]{2,}\b/,comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])(\/\/).*?(\r?\n|$))/,lookbehind:!0}}),Prism.languages.insertBefore("php","class-name",{"shell-comment":{pattern:/(^|[^\\])#.*?(\r?\n|$)/,lookbehind:!0,alias:"comment"}}),Prism.languages.insertBefore("php","keyword",{delimiter:/(\?>|<\?php|<\?)/i,variable:/(\$\w+)\b/i,"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/,lookbehind:!0,inside:{punctuation:/\\/}}}),Prism.languages.insertBefore("php","operator",{property:{pattern:/(->)[\w]+/,lookbehind:!0}}),Prism.languages.markup&&(Prism.hooks.add("before-highlight",function(e){"php"===e.language&&(e.tokenStack=[],e.backupCode=e.code,e.code=e.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/gi,function(n){return e.tokenStack.push(n),"{{{PHP"+e.tokenStack.length+"}}}"}))}),Prism.hooks.add("before-insert",function(e){"php"===e.language&&(e.code=e.backupCode,delete e.backupCode)}),Prism.hooks.add("after-highlight",function(e){if("php"===e.language){for(var n,a=0;n=e.tokenStack[a];a++)e.highlightedCode=e.highlightedCode.replace("{{{PHP"+(a+1)+"}}}",Prism.highlight(n,e.grammar,"php"));e.element.innerHTML=e.highlightedCode}}),Prism.hooks.add("wrap",function(e){"php"===e.language&&"markup"===e.type&&(e.content=e.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g,'<span class="token php">$1</span>'))}),Prism.languages.insertBefore("php","comment",{markup:{pattern:/<[^?]\/?(.*?)>/,inside:Prism.languages.markup},php:/\{\{\{PHP[0-9]+\}\}\}/}));
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-powershell.js b/polymer_1.0.4/bower_components/prism/components/prism-powershell.js
new file mode 100644
index 0000000..615c46f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-powershell.js
@@ -0,0 +1,34 @@
+Prism.languages.powershell = {
+ 'comment': [
+ {
+ pattern: /(^|[^`])<#[\w\W]*?#>/,
+ lookbehind: true
+ },
+ {
+ pattern: /(^|[^`])#.*?(\r?\n|$)/,
+ lookbehind: true
+ }
+ ],
+ 'string': {
+ pattern: /("|')(`?[\w\W])*?\1/m,
+ inside: {}
+ },
+ // Matches name spaces as well as casts, attribute decorators. Force starting with letter to avoid matching array indices
+ 'namespace': /\[[a-z][\w\W]*?\]/i,
+ 'boolean': /\$(true|false)\b/i,
+ 'variable': /\$\w+\b/i,
+ // per http://technet.microsoft.com/en-us/library/hh847744.aspx
+ 'keyword': /\b(Begin|Break|Catch|Class|Continue|Data|Define|Do|DynamicParam|Else|ElseIf|End|Exit|Filter|Finally|For|ForEach|From|Function|If|In|InlineScript|Parallel|Param|Process|Return|Sequence|Switch|Throw|Trap|Try|Until|Using|Var|While|Workflow)\b/i,
+ // Cmdlets and aliases. Aliases should come last, otherwise "write" gets preferred over "write-host" for example
+ // Get-Command | ?{ $_.ModuleName -match "Microsoft.PowerShell.(Util|Core|Management)" }
+ // Get-Alias | ?{ $_.ReferencedCommand.Module.Name -match "Microsoft.PowerShell.(Util|Core|Management)" }
+ 'function': /\b(Add-(Computer|Content|History|Member|PSSnapin|Type)|Checkpoint-(Computer|Content|EventLog|History|Item|ItemProperty|Variable)|Compare-(Object)|Complete-(Transaction)|Connect-(PSSession)|ConvertFrom-(Csv|Json|StringData)|Convert-(Path)|ConvertTo-(Csv|Html|Json|Xml)|Copy-(Item|ItemProperty)|Debug-(Process)|Disable-(ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)|Disconnect-(PSSession)|Enable-(ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)|Enter-(PSSession)|Exit-(PSSession)|Export-(Alias|Clixml|Console|Csv|FormatData|ModuleMember|PSSession)|ForEach-(Object)|Format-(Custom|List|Table|Wide)|Get-(Alias|ChildItem|Command|ComputerRestorePoint|Content|ControlPanelItem|Culture|Date|Event|EventLog|EventSubscriber|FormatData|Help|History|Host|HotFix|Item|ItemProperty|Job|Location|Member|Module|Process|PSBreakpoint|PSCallStack|PSDrive|PSProvider|PSSession|PSSessionConfiguration|PSSnapin|Random|Service|TraceSource|Transaction|TypeData|UICulture|Unique|Variable|WmiObject)|Group-(Object)|Import-(Alias|Clixml|Csv|LocalizedData|Module|PSSession)|Invoke-(Command|Expression|History|Item|RestMethod|WebRequest|WmiMethod)|Join-(Path)|Limit-(EventLog)|Measure-(Command)|Measure-(Object)|Move-(Item|ItemProperty)|New-(Alias|Event|EventLog|Item|ItemProperty|Module|ModuleManifest|Object|PSDrive|PSSession|PSSessionConfigurationFile|PSSessionOption|PSTransportOption|Service|TimeSpan|Variable|WebServiceProxy)|Out-(Default|File|GridView|Host|Null|Printer|String)|Pop-(Location)|Push-(Location)|Read-(Host)|Receive-(Job)|Receive-(PSSession)|Register-(EngineEvent|ObjectEvent|PSSessionConfiguration|WmiEvent)|Remove-(Computer|Event|EventLog|Item|ItemProperty|Job|Module|PSBreakpoint|PSDrive|PSSession|PSSnapin|TypeData|Variable|WmiObject)|Rename-(Computer|Item|ItemProperty)|Reset-(ComputerMachinePassword)|Resolve-(Path)|Restart-(Computer|Service)|Restore-(Computer)|Resume-(Job|Service)|Save-(Help)|Select-(Object|String|Xml)|Send-(MailMessage)|Set-(Alias|Content|Date|Item|ItemProperty|Location|PSBreakpoint|PSDebug|PSSessionConfiguration|Service|StrictMode|TraceSource|Variable|WmiInstance)|Show-(Command|ControlPanelItem|EventLog)|Sort-(Object)|Split-(Path)|Start-(Job|Process|Service|Sleep|Transaction)|Stop-(Computer|Job|Process|Service)|Suspend-(Job|Service)|Tee-(Object)|Test-(ComputerSecureChannel|Connection|ModuleManifest|Path|PSSessionConfigurationFile)|Trace-(Command)|Unblock-(File)|Undo-(Transaction)|Unregister-(Event|PSSessionConfiguration)|Update-(FormatData)|Update-(Help|List|TypeData)|Use-(Transaction)|Wait-(Event|Job|Process)|Where-(Object)|Write-(Debug|Error|EventLog|Host|Output|Progress|Verbose|Warning)|ac|cat|cd|chdir|clc|cli|clp|clv|compare|copy|cp|cpi|cpp|cvpa|dbp|del|diff|dir|ebp|echo|epal|epcsv|epsn|erase|fc|fl|ft|fw|gal|gbp|gc|gci|gcs|gdr|gi|gl|gm|gp|gps|group|gsv|gu|gv|gwmi|iex|ii|ipal|ipcsv|ipsn|irm|iwmi|iwr|kill|lp|ls|measure|mi|mount|move|mp|mv|nal|ndr|ni|nv|ogv|popd|ps|pushd|pwd|rbp|rd|rdr|ren|ri|rm|rmdir|rni|rnp|rp|rv|rvpa|rwmi|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls|sort|sp|spps|spsv|start|sv|swmi|tee|trcm|type|write)\b/i,
+ 'operator': {
+ pattern: /(\W)-(and|x?or|not|eq|ne|gt|ge|lt|le|Like|(Not)?(Like|Match|Contains|In)|Replace)\b/i,
+ lookbehind: true
+ },
+ 'punctuation': /[|{}[\];(),.]/
+};
+// Variable interpolation inside strings
+Prism.languages.powershell.string.inside.boolean = Prism.languages.powershell.boolean;
+Prism.languages.powershell.string.inside.variable = Prism.languages.powershell.variable;
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-powershell.min.js b/polymer_1.0.4/bower_components/prism/components/prism-powershell.min.js
new file mode 100644
index 0000000..cbaf60c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-powershell.min.js
@@ -0,0 +1 @@
+Prism.languages.powershell={comment:[{pattern:/(^|[^`])<#[\w\W]*?#>/,lookbehind:!0},{pattern:/(^|[^`])#.*?(\r?\n|$)/,lookbehind:!0}],string:{pattern:/("|')(`?[\w\W])*?\1/m,inside:{}},namespace:/\[[a-z][\w\W]*?\]/i,"boolean":/\$(true|false)\b/i,variable:/\$\w+\b/i,keyword:/\b(Begin|Break|Catch|Class|Continue|Data|Define|Do|DynamicParam|Else|ElseIf|End|Exit|Filter|Finally|For|ForEach|From|Function|If|In|InlineScript|Parallel|Param|Process|Return|Sequence|Switch|Throw|Trap|Try|Until|Using|Var|While|Workflow)\b/i,"function":/\b(Add-(Computer|Content|History|Member|PSSnapin|Type)|Checkpoint-(Computer|Content|EventLog|History|Item|ItemProperty|Variable)|Compare-(Object)|Complete-(Transaction)|Connect-(PSSession)|ConvertFrom-(Csv|Json|StringData)|Convert-(Path)|ConvertTo-(Csv|Html|Json|Xml)|Copy-(Item|ItemProperty)|Debug-(Process)|Disable-(ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)|Disconnect-(PSSession)|Enable-(ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)|Enter-(PSSession)|Exit-(PSSession)|Export-(Alias|Clixml|Console|Csv|FormatData|ModuleMember|PSSession)|ForEach-(Object)|Format-(Custom|List|Table|Wide)|Get-(Alias|ChildItem|Command|ComputerRestorePoint|Content|ControlPanelItem|Culture|Date|Event|EventLog|EventSubscriber|FormatData|Help|History|Host|HotFix|Item|ItemProperty|Job|Location|Member|Module|Process|PSBreakpoint|PSCallStack|PSDrive|PSProvider|PSSession|PSSessionConfiguration|PSSnapin|Random|Service|TraceSource|Transaction|TypeData|UICulture|Unique|Variable|WmiObject)|Group-(Object)|Import-(Alias|Clixml|Csv|LocalizedData|Module|PSSession)|Invoke-(Command|Expression|History|Item|RestMethod|WebRequest|WmiMethod)|Join-(Path)|Limit-(EventLog)|Measure-(Command)|Measure-(Object)|Move-(Item|ItemProperty)|New-(Alias|Event|EventLog|Item|ItemProperty|Module|ModuleManifest|Object|PSDrive|PSSession|PSSessionConfigurationFile|PSSessionOption|PSTransportOption|Service|TimeSpan|Variable|WebServiceProxy)|Out-(Default|File|GridView|Host|Null|Printer|String)|Pop-(Location)|Push-(Location)|Read-(Host)|Receive-(Job)|Receive-(PSSession)|Register-(EngineEvent|ObjectEvent|PSSessionConfiguration|WmiEvent)|Remove-(Computer|Event|EventLog|Item|ItemProperty|Job|Module|PSBreakpoint|PSDrive|PSSession|PSSnapin|TypeData|Variable|WmiObject)|Rename-(Computer|Item|ItemProperty)|Reset-(ComputerMachinePassword)|Resolve-(Path)|Restart-(Computer|Service)|Restore-(Computer)|Resume-(Job|Service)|Save-(Help)|Select-(Object|String|Xml)|Send-(MailMessage)|Set-(Alias|Content|Date|Item|ItemProperty|Location|PSBreakpoint|PSDebug|PSSessionConfiguration|Service|StrictMode|TraceSource|Variable|WmiInstance)|Show-(Command|ControlPanelItem|EventLog)|Sort-(Object)|Split-(Path)|Start-(Job|Process|Service|Sleep|Transaction)|Stop-(Computer|Job|Process|Service)|Suspend-(Job|Service)|Tee-(Object)|Test-(ComputerSecureChannel|Connection|ModuleManifest|Path|PSSessionConfigurationFile)|Trace-(Command)|Unblock-(File)|Undo-(Transaction)|Unregister-(Event|PSSessionConfiguration)|Update-(FormatData)|Update-(Help|List|TypeData)|Use-(Transaction)|Wait-(Event|Job|Process)|Where-(Object)|Write-(Debug|Error|EventLog|Host|Output|Progress|Verbose|Warning)|ac|cat|cd|chdir|clc|cli|clp|clv|compare|copy|cp|cpi|cpp|cvpa|dbp|del|diff|dir|ebp|echo|epal|epcsv|epsn|erase|fc|fl|ft|fw|gal|gbp|gc|gci|gcs|gdr|gi|gl|gm|gp|gps|group|gsv|gu|gv|gwmi|iex|ii|ipal|ipcsv|ipsn|irm|iwmi|iwr|kill|lp|ls|measure|mi|mount|move|mp|mv|nal|ndr|ni|nv|ogv|popd|ps|pushd|pwd|rbp|rd|rdr|ren|ri|rm|rmdir|rni|rnp|rp|rv|rvpa|rwmi|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls|sort|sp|spps|spsv|start|sv|swmi|tee|trcm|type|write)\b/i,operator:{pattern:/(\W)-(and|x?or|not|eq|ne|gt|ge|lt|le|Like|(Not)?(Like|Match|Contains|In)|Replace)\b/i,lookbehind:!0},punctuation:/[|{}[\];(),.]/},Prism.languages.powershell.string.inside.boolean=Prism.languages.powershell.boolean,Prism.languages.powershell.string.inside.variable=Prism.languages.powershell.variable;
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-python.js b/polymer_1.0.4/bower_components/prism/components/prism-python.js
new file mode 100644
index 0000000..f04765b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-python.js
@@ -0,0 +1,13 @@
+Prism.languages.python= {
+ 'comment': {
+ pattern: /(^|[^\\])#.*?(\r?\n|$)/,
+ lookbehind: true
+ },
+ 'string': /"""[\s\S]+?"""|'''[\s\S]+?'''|("|')(\\?.)*?\1/,
+ 'keyword' : /\b(as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/,
+ 'boolean' : /\b(True|False)\b/,
+ 'number' : /\b-?(0[box])?(?:[\da-f]+\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,
+ 'operator' : /[-+]|<=?|>=?|!|={1,2}|&{1,2}|\|?\||\?|\*|\/|~|\^|%|\b(or|and|not)\b/,
+ 'punctuation' : /[{}[\];(),.:]/
+};
+
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-python.min.js b/polymer_1.0.4/bower_components/prism/components/prism-python.min.js
new file mode 100644
index 0000000..3bd60b4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-python.min.js
@@ -0,0 +1 @@
+Prism.languages.python={comment:{pattern:/(^|[^\\])#.*?(\r?\n|$)/,lookbehind:!0},string:/"""[\s\S]+?"""|'''[\s\S]+?'''|("|')(\\?.)*?\1/,keyword:/\b(as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/,"boolean":/\b(True|False)\b/,number:/\b-?(0[box])?(?:[\da-f]+\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+]|<=?|>=?|!|={1,2}|&{1,2}|\|?\||\?|\*|\/|~|\^|%|\b(or|and|not)\b/,punctuation:/[{}[\];(),.:]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-r.js b/polymer_1.0.4/bower_components/prism/components/prism-r.js
new file mode 100644
index 0000000..f6d9e20
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-r.js
@@ -0,0 +1,19 @@
+Prism.languages.r = {
+ 'comment': /#.+/,
+ 'string': /(['"])(?:\\?.)*?\1/,
+ 'percent-operator': {
+ // Includes user-defined operators
+ // and %%, %*%, %/%, %in%, %o%, %x%
+ pattern: /%[^%]*?%/,
+ alias: 'operator'
+ },
+ 'boolean': /\b(?:TRUE|FALSE)\b/,
+ 'ellipsis': /\.\.(?:\.|\d+)/,
+ 'number': [
+ /\b(?:NaN|Inf)\b/,
+ /\b(?:0x[\dA-Fa-f]+(?:\.\d*)?|\d*\.?\d+)(?:[EePp][+-]??\d+)?[iL]?\b/
+ ],
+ 'keyword': /\b(?:if|else|repeat|while|function|for|in|next|break|NULL|NA|NA_integer_|NA_real_|NA_complex_|NA_character_)\b/,
+ 'operator': /->>?|<?<-|[<>!=]=?|::?|&&?|\|\|?|[+\-*\/^$@~]/,
+ 'punctuation': /[(){}\[\],;]/
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-r.min.js b/polymer_1.0.4/bower_components/prism/components/prism-r.min.js
new file mode 100644
index 0000000..6784b40
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-r.min.js
@@ -0,0 +1 @@
+Prism.languages.r={comment:/#.+/,string:/(['"])(?:\\?.)*?\1/,"percent-operator":{pattern:/%[^%]*?%/,alias:"operator"},"boolean":/\b(?:TRUE|FALSE)\b/,ellipsis:/\.\.(?:\.|\d+)/,number:[/\b(?:NaN|Inf)\b/,/\b(?:0x[\dA-Fa-f]+(?:\.\d*)?|\d*\.?\d+)(?:[EePp][+-]??\d+)?[iL]?\b/],keyword:/\b(?:if|else|repeat|while|function|for|in|next|break|NULL|NA|NA_integer_|NA_real_|NA_complex_|NA_character_)\b/,operator:/->>?|<?<-|[<>!=]=?|::?|&&?|\|\|?|[+\-*\/^$@~]/,punctuation:/[(){}\[\],;]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-rest.js b/polymer_1.0.4/bower_components/prism/components/prism-rest.js
new file mode 100644
index 0000000..6693dc9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-rest.js
@@ -0,0 +1,204 @@
+Prism.languages.rest = {
+ 'table': [
+ {
+ pattern: /(\s*)(?:\+[=-]+)+\+(?:\r?\n|\r)(?:\1(?:[+|].+)+[+|](?:\r?\n|\r))+\1(?:\+[=-]+)+\+/,
+ lookbehind: true,
+ inside: {
+ 'punctuation': /\||(?:\+[=-]+)+\+/
+ }
+ },
+ {
+ pattern: /(\s*)(?:=+ +)+=+((?:\r?\n|\r)\1.+)+(?:\r?\n|\r)\1(?:=+ +)+=+(?=(?:\r?\n|\r){2}|\s*$)/,
+ lookbehind: true,
+ inside: {
+ 'punctuation': /[=-]+/
+ }
+ }
+ ],
+
+ // Directive-like patterns
+
+ 'substitution-def': {
+ pattern: /(^\s*\.\. )\|(?:[^|\s]|[^|\s][^|]*[^|\s])\| [^:]+::/m,
+ lookbehind: true,
+ inside: {
+ 'substitution': {
+ pattern: /^\|(?:[^|\s]|[^|\s][^|]*[^|\s])\|/,
+ alias: 'attr-value',
+ inside: {
+ 'punctuation': /^\||\|$/
+ }
+ },
+ 'directive': {
+ pattern: /( )[^:]+::/,
+ lookbehind: true,
+ alias: 'function',
+ inside: {
+ 'punctuation': /::$/
+ }
+ }
+ }
+ },
+ 'link-target': [
+ {
+ pattern: /(^\s*\.\. )\[[^\]]+\]/m,
+ lookbehind: true,
+ alias: 'string',
+ inside: {
+ 'punctuation': /^\[|\]$/
+ }
+ },
+ {
+ pattern: /(^\s*\.\. )_(?:`[^`]+`|(?:\\:|[^:])+):/m,
+ lookbehind: true,
+ alias: 'string',
+ inside: {
+ 'punctuation': /^_|:$/
+ }
+ }
+ ],
+ 'directive': {
+ pattern: /(^\s*\.\. )[^:]+::/m,
+ lookbehind: true,
+ alias: 'function',
+ inside: {
+ 'punctuation': /::$/
+ }
+ },
+ 'comment': {
+ pattern: /(^\s*\.\.\s).*(?:(?:\r?\n|\r).*)*?(?=(?:\r?\n|\r){2}|$)/m,
+ lookbehind: true
+ },
+
+ 'title': [
+ // Overlined and underlined
+ {
+ pattern: /^([!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]{2,})(?:\r?\n|\r).+(?:\r?\n|\r)\1$/m,
+ inside: {
+ 'punctuation': /^[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]+|[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]+$/,
+ 'important': /.+/
+ }
+ },
+
+ // Underlined only
+ {
+ pattern: /(^|(?:\r?\n|\r){2}).+(?:\r?\n|\r)[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]{2,}(?=\r?\n|\r|$)/,
+ lookbehind: true,
+ inside: {
+ 'punctuation': /[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]+$/,
+ 'important': /.+/
+ }
+ }
+ ],
+ 'hr': {
+ pattern: /((?:\r?\n|\r){2})[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]{4,}(?=(?:\r?\n|\r){2})/,
+ lookbehind: true,
+ alias: 'punctuation'
+ },
+ 'list-bullet': {
+ pattern: /(^\s*)(?:[*+\-•‣⁃]|\(?(?:\d+|[a-z]|[ivxdclm]+)\)|(?:\d+|[a-z]|[ivxdclm]+)\.)(?= )/im,
+ lookbehind: true,
+ alias: 'punctuation'
+ },
+ 'field': {
+ pattern: /(^\s*):[^:]+:(?= )/m,
+ lookbehind: true,
+ alias: 'attr-name'
+ },
+ 'command-line-option': {
+ pattern: /(^\s*)(?:[+-][a-z\d]|(?:\-\-|\/)[a-z\d-]+)(?:[ =](?:[a-z][a-z\d_-]*|<[^<>]+>))?(?:, (?:[+-][a-z\d]|(?:\-\-|\/)[a-z\d-]+)(?:[ =](?:[a-z][a-z\d_-]*|<[^<>]+>))?)*(?=(?:\r?\n|\r)? {2,}[\S])/im,
+ lookbehind: true,
+ alias: 'symbol'
+ },
+ 'literal-block': {
+ pattern: /::(?:\r?\n|\r){2}([ \t]+).+(?:(?:\r?\n|\r)\1.+)*/,
+ inside: {
+ 'literal-block-punctuation': {
+ pattern: /^::/,
+ alias: 'punctuation'
+ }
+ }
+ },
+ 'quoted-literal-block': {
+ pattern: /::(?:\r?\n|\r){2}([!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]).*(?:(?:\r?\n|\r)\1.*)*/,
+ inside: {
+ 'literal-block-punctuation': {
+ pattern: /^(?:::|[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~])/m,
+ alias: 'punctuation'
+ }
+ }
+ },
+ 'doctest-block': {
+ pattern: /(^\s*)>>> .+(?:(?:\r?\n|\r).+)*/m,
+ lookbehind: true,
+ inside: {
+ 'punctuation': /^>>>/
+ }
+ },
+
+ 'inline': [
+ {
+ pattern: /(^|[\s\-:\/'"<(\[{])(?::[^:]+:`.*?`|`.*?`:[^:]+:|(\*\*?|``?|\|)(?!\s).*?[^\s]\2(?=[\s\-.,:;!?\\\/'")\]}]|$))/m,
+ lookbehind: true,
+ inside: {
+ 'bold': {
+ pattern: /(^\*\*).+(?=\*\*$)/,
+ lookbehind: true
+ },
+ 'italic': {
+ pattern: /(^\*).+(?=\*$)/,
+ lookbehind: true
+ },
+ 'inline-literal': {
+ pattern: /(^``).+(?=``$)/,
+ lookbehind: true,
+ alias: 'symbol'
+ },
+ 'role': {
+ pattern: /^:[^:]+:|:[^:]+:$/,
+ alias: 'function',
+ inside: {
+ 'punctuation': /^:|:$/
+ }
+ },
+ 'interpreted-text': {
+ pattern: /(^`).+(?=`$)/,
+ lookbehind: true,
+ alias: 'attr-value'
+ },
+ 'substitution': {
+ pattern: /(^\|).+(?=\|$)/,
+ lookbehind: true,
+ alias: 'attr-value'
+ },
+ 'punctuation': /\*\*?|``?|\|/
+ }
+ }
+ ],
+
+ 'link': [
+ {
+ pattern: /\[[^\]]+\]_(?=[\s\-.,:;!?\\\/'")\]}]|$)/,
+ alias: 'string',
+ inside: {
+ 'punctuation': /^\[|\]_$/
+ }
+ },
+ {
+ pattern: /(?:\b[a-z\d](?:[_.:+]?[a-z\d]+)?_?_|`[^`]+`_?_|_`[^`]+`)(?=[\s\-.,:;!?\\\/'")\]}]|$)/i,
+ alias: 'string',
+ inside: {
+ 'punctuation': /^_?`|`?_?_$/
+ }
+ }
+ ],
+
+ // Line block start,
+ // quote attribution,
+ // explicit markup start,
+ // and anonymous hyperlink target shortcut (__)
+ 'punctuation': {
+ pattern: /(^\s*)(?:\|(?= |$)|(?:---?|—|\.\.|__)(?= )|\.\.$)/m,
+ lookbehind: true
+ }
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-rest.min.js b/polymer_1.0.4/bower_components/prism/components/prism-rest.min.js
new file mode 100644
index 0000000..77f3bf8
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-rest.min.js
@@ -0,0 +1 @@
+Prism.languages.rest={table:[{pattern:/(\s*)(?:\+[=-]+)+\+(?:\r?\n|\r)(?:\1(?:[+|].+)+[+|](?:\r?\n|\r))+\1(?:\+[=-]+)+\+/,lookbehind:!0,inside:{punctuation:/\||(?:\+[=-]+)+\+/}},{pattern:/(\s*)(?:=+ +)+=+((?:\r?\n|\r)\1.+)+(?:\r?\n|\r)\1(?:=+ +)+=+(?=(?:\r?\n|\r){2}|\s*$)/,lookbehind:!0,inside:{punctuation:/[=-]+/}}],"substitution-def":{pattern:/(^\s*\.\. )\|(?:[^|\s]|[^|\s][^|]*[^|\s])\| [^:]+::/m,lookbehind:!0,inside:{substitution:{pattern:/^\|(?:[^|\s]|[^|\s][^|]*[^|\s])\|/,alias:"attr-value",inside:{punctuation:/^\||\|$/}},directive:{pattern:/( )[^:]+::/,lookbehind:!0,alias:"function",inside:{punctuation:/::$/}}}},"link-target":[{pattern:/(^\s*\.\. )\[[^\]]+\]/m,lookbehind:!0,alias:"string",inside:{punctuation:/^\[|\]$/}},{pattern:/(^\s*\.\. )_(?:`[^`]+`|(?:\\:|[^:])+):/m,lookbehind:!0,alias:"string",inside:{punctuation:/^_|:$/}}],directive:{pattern:/(^\s*\.\. )[^:]+::/m,lookbehind:!0,alias:"function",inside:{punctuation:/::$/}},comment:{pattern:/(^\s*\.\.\s).*(?:(?:\r?\n|\r).*)*?(?=(?:\r?\n|\r){2}|$)/m,lookbehind:!0},title:[{pattern:/^([!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]{2,})(?:\r?\n|\r).+(?:\r?\n|\r)\1$/m,inside:{punctuation:/^[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]+|[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]+$/,important:/.+/}},{pattern:/(^|(?:\r?\n|\r){2}).+(?:\r?\n|\r)[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]{2,}(?=\r?\n|\r|$)/,lookbehind:!0,inside:{punctuation:/[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]+$/,important:/.+/}}],hr:{pattern:/((?:\r?\n|\r){2})[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]{4,}(?=(?:\r?\n|\r){2})/,lookbehind:!0,alias:"punctuation"},"list-bullet":{pattern:/(^\s*)(?:[*+\-•‣⁃]|\(?(?:\d+|[a-z]|[ivxdclm]+)\)|(?:\d+|[a-z]|[ivxdclm]+)\.)(?= )/im,lookbehind:!0,alias:"punctuation"},field:{pattern:/(^\s*):[^:]+:(?= )/m,lookbehind:!0,alias:"attr-name"},"command-line-option":{pattern:/(^\s*)(?:[+-][a-z\d]|(?:\-\-|\/)[a-z\d-]+)(?:[ =](?:[a-z][a-z\d_-]*|<[^<>]+>))?(?:, (?:[+-][a-z\d]|(?:\-\-|\/)[a-z\d-]+)(?:[ =](?:[a-z][a-z\d_-]*|<[^<>]+>))?)*(?=(?:\r?\n|\r)? {2,}[\S])/im,lookbehind:!0,alias:"symbol"},"literal-block":{pattern:/::(?:\r?\n|\r){2}([ \t]+).+(?:(?:\r?\n|\r)\1.+)*/,inside:{"literal-block-punctuation":{pattern:/^::/,alias:"punctuation"}}},"quoted-literal-block":{pattern:/::(?:\r?\n|\r){2}([!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]).*(?:(?:\r?\n|\r)\1.*)*/,inside:{"literal-block-punctuation":{pattern:/^(?:::|[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~])/m,alias:"punctuation"}}},"doctest-block":{pattern:/(^\s*)>>> .+(?:(?:\r?\n|\r).+)*/m,lookbehind:!0,inside:{punctuation:/^>>>/}},inline:[{pattern:/(^|[\s\-:\/'"<(\[{])(?::[^:]+:`.*?`|`.*?`:[^:]+:|(\*\*?|``?|\|)(?!\s).*?[^\s]\2(?=[\s\-.,:;!?\\\/'")\]}]|$))/m,lookbehind:!0,inside:{bold:{pattern:/(^\*\*).+(?=\*\*$)/,lookbehind:!0},italic:{pattern:/(^\*).+(?=\*$)/,lookbehind:!0},"inline-literal":{pattern:/(^``).+(?=``$)/,lookbehind:!0,alias:"symbol"},role:{pattern:/^:[^:]+:|:[^:]+:$/,alias:"function",inside:{punctuation:/^:|:$/}},"interpreted-text":{pattern:/(^`).+(?=`$)/,lookbehind:!0,alias:"attr-value"},substitution:{pattern:/(^\|).+(?=\|$)/,lookbehind:!0,alias:"attr-value"},punctuation:/\*\*?|``?|\|/}}],link:[{pattern:/\[[^\]]+\]_(?=[\s\-.,:;!?\\\/'")\]}]|$)/,alias:"string",inside:{punctuation:/^\[|\]_$/}},{pattern:/(?:\b[a-z\d](?:[_.:+]?[a-z\d]+)?_?_|`[^`]+`_?_|_`[^`]+`)(?=[\s\-.,:;!?\\\/'")\]}]|$)/i,alias:"string",inside:{punctuation:/^_?`|`?_?_$/}}],punctuation:{pattern:/(^\s*)(?:\|(?= |$)|(?:---?|—|\.\.|__)(?= )|\.\.$)/m,lookbehind:!0}};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-rip.js b/polymer_1.0.4/bower_components/prism/components/prism-rip.js
new file mode 100644
index 0000000..0caadb1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-rip.js
@@ -0,0 +1,29 @@
+Prism.languages.rip = {
+ 'comment': /#[^\r\n]*(\r?\n|$)/,
+
+ 'keyword': /(?:=>|->)|\b(?:class|if|else|switch|case|return|exit|try|catch|finally|raise)\b/,
+
+ 'builtin': /\b(@|System)\b/,
+
+ 'boolean': /\b(true|false)\b/,
+
+ 'date': /\b\d{4}-\d{2}-\d{2}\b/,
+ 'time': /\b\d{2}:\d{2}:\d{2}\b/,
+ 'datetime': /\b\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\b/,
+
+ 'number': /[+-]?(?:(?:\d+\.\d+)|(?:\d+))/,
+
+ 'character': /\B`[^\s`'",.:;#\/\\()<>\[\]{}]\b/,
+
+ 'regex': {
+ pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/(?=\s*($|[\r\n,.;})]))/,
+ lookbehind: true
+ },
+
+ 'symbol': /:[^\d\s`'",.:;#\/\\()<>\[\]{}][^\s`'",.:;#\/\\()<>\[\]{}]*/,
+ 'string': /("|')(\\?.)*?\1/,
+
+ 'punctuation': /(?:\.{2,3})|[`,.:;=\/\\()<>\[\]{}]/,
+
+ 'reference': /[^\d\s`'",.:;#\/\\()<>\[\]{}][^\s`'",.:;#\/\\()<>\[\]{}]*/
+};
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-rip.min.js b/polymer_1.0.4/bower_components/prism/components/prism-rip.min.js
new file mode 100644
index 0000000..389a552
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-rip.min.js
@@ -0,0 +1 @@
+Prism.languages.rip={comment:/#[^\r\n]*(\r?\n|$)/,keyword:/(?:=>|->)|\b(?:class|if|else|switch|case|return|exit|try|catch|finally|raise)\b/,builtin:/\b(@|System)\b/,"boolean":/\b(true|false)\b/,date:/\b\d{4}-\d{2}-\d{2}\b/,time:/\b\d{2}:\d{2}:\d{2}\b/,datetime:/\b\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\b/,number:/[+-]?(?:(?:\d+\.\d+)|(?:\d+))/,character:/\B`[^\s`'",.:;#\/\\()<>\[\]{}]\b/,regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/(?=\s*($|[\r\n,.;})]))/,lookbehind:!0},symbol:/:[^\d\s`'",.:;#\/\\()<>\[\]{}][^\s`'",.:;#\/\\()<>\[\]{}]*/,string:/("|')(\\?.)*?\1/,punctuation:/(?:\.{2,3})|[`,.:;=\/\\()<>\[\]{}]/,reference:/[^\d\s`'",.:;#\/\\()<>\[\]{}][^\s`'",.:;#\/\\()<>\[\]{}]*/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-ruby.js b/polymer_1.0.4/bower_components/prism/components/prism-ruby.js
new file mode 100644
index 0000000..554d687
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-ruby.js
@@ -0,0 +1,21 @@
+/**
+ * Original by Samuel Flores
+ *
+ * Adds the following new token classes:
+ * constant, builtin, variable, symbol, regex
+ */
+Prism.languages.ruby = Prism.languages.extend('clike', {
+ 'comment': /#[^\r\n]*(\r?\n|$)/,
+ 'keyword': /\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/,
+ 'builtin': /\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,
+ 'constant': /\b[A-Z][a-zA-Z_0-9]*[?!]?\b/
+});
+
+Prism.languages.insertBefore('ruby', 'keyword', {
+ 'regex': {
+ pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,
+ lookbehind: true
+ },
+ 'variable': /[@$]+\b[a-zA-Z_][a-zA-Z_0-9]*[?!]?\b/,
+ 'symbol': /:\b[a-zA-Z_][a-zA-Z_0-9]*[?!]?\b/
+});
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-ruby.min.js b/polymer_1.0.4/bower_components/prism/components/prism-ruby.min.js
new file mode 100644
index 0000000..4e551c4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-ruby.min.js
@@ -0,0 +1 @@
+Prism.languages.ruby=Prism.languages.extend("clike",{comment:/#[^\r\n]*(\r?\n|$)/,keyword:/\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/,builtin:/\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z][a-zA-Z_0-9]*[?!]?\b/}),Prism.languages.insertBefore("ruby","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0},variable:/[@$]+\b[a-zA-Z_][a-zA-Z_0-9]*[?!]?\b/,symbol:/:\b[a-zA-Z_][a-zA-Z_0-9]*[?!]?\b/});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-rust.js b/polymer_1.0.4/bower_components/prism/components/prism-rust.js
new file mode 100644
index 0000000..0c320d2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-rust.js
@@ -0,0 +1,53 @@
+/* TODO
+ Add support for Markdown notation inside doc comments
+ Add support for nested block comments...
+ Match closure params even when not followed by dash or brace
+ Add better support for macro definition
+*/
+
+Prism.languages.rust = {
+ 'comment': [
+ {
+ pattern: /(^|[^\\])\/\*[\w\W]*?\*\//,
+ lookbehind: true
+ },
+ {
+ pattern: /(^|[^\\:])\/\/.*?(\r?\n|$)/,
+ lookbehind: true
+ }
+ ],
+ 'string': [
+ /b?r(#*)"(?:\\?.)*?"\1/,
+ /b?("|')(?:\\?.)*?\1/
+ ],
+ 'keyword': /\b(?:abstract|alignof|as|be|box|break|const|continue|crate|do|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|match|mod|move|mut|offsetof|once|override|priv|pub|pure|ref|return|sizeof|static|self|struct|super|true|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\b/,
+
+ 'attribute': {
+ pattern: /#!?\[.+?\]/,
+ alias: 'attr-name'
+ },
+
+ 'function': [
+ /[a-z0-9_]+(?=\s*\()/i,
+ // Macros can use parens or brackets
+ /[a-z0-9_]+!(?=\s*\(|\[)/i
+ ],
+ 'macro-rules': {
+ pattern: /[a-z0-9_]+!/i,
+ alias: 'function'
+ },
+
+ // Hex, oct, bin, dec numbers with visual separators and type suffix
+ 'number': /\b-?(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(\d(_?\d)*)?\.?\d(_?\d)*([Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32)?|f32|f64))?\b/,
+
+ // Closure params should not be confused with bitwise OR |
+ 'closure-params': {
+ pattern: /\|[^|]*\|(?=\s*[{-])/,
+ inside: {
+ 'punctuation': /[\|:,]/,
+ 'operator': /[&*]/
+ }
+ },
+ 'punctuation': /[{}[\];(),.:]|->/,
+ 'operator': /[-+]{1,2}|!=?|<=?|>=?|={1,3}|&&?|\|\|?|\*|\/|\^|%|<<|>>@/
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-rust.min.js b/polymer_1.0.4/bower_components/prism/components/prism-rust.min.js
new file mode 100644
index 0000000..bf38d45
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-rust.min.js
@@ -0,0 +1 @@
+Prism.languages.rust={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*?(\r?\n|$)/,lookbehind:!0}],string:[/b?r(#*)"(?:\\?.)*?"\1/,/b?("|')(?:\\?.)*?\1/],keyword:/\b(?:abstract|alignof|as|be|box|break|const|continue|crate|do|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|match|mod|move|mut|offsetof|once|override|priv|pub|pure|ref|return|sizeof|static|self|struct|super|true|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\b/,attribute:{pattern:/#!?\[.+?\]/,alias:"attr-name"},"function":[/[a-z0-9_]+(?=\s*\()/i,/[a-z0-9_]+!(?=\s*\(|\[)/i],"macro-rules":{pattern:/[a-z0-9_]+!/i,alias:"function"},number:/\b-?(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(\d(_?\d)*)?\.?\d(_?\d)*([Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32)?|f32|f64))?\b/,"closure-params":{pattern:/\|[^|]*\|(?=\s*[{-])/,inside:{punctuation:/[\|:,]/,operator:/[&*]/}},punctuation:/[{}[\];(),.:]|->/,operator:/[-+]{1,2}|!=?|<=?|>=?|={1,3}|&&?|\|\|?|\*|\/|\^|%|<<|>>@/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-sas.js b/polymer_1.0.4/bower_components/prism/components/prism-sas.js
new file mode 100644
index 0000000..e8696d2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-sas.js
@@ -0,0 +1,35 @@
+Prism.languages.sas = {
+ 'datalines': {
+ pattern: /(^|[\r\n])\s*(?:(?:data)?lines|cards);[\s\S]+?[\r\n];/i,
+ lookbehind: true,
+ inside: {
+ 'keyword': {
+ pattern: /^(\s*)(?:(?:data)?lines|cards)/i,
+ lookbehind: true
+ },
+ 'punctuation': /;/,
+ 'data': {
+ pattern: /[\s\S]+/,
+ alias: 'string'
+ }
+ }
+ },
+ 'comment': [
+ {
+ pattern: /(^\s*|;\s*)\*.*;/m,
+ lookbehind: true
+ },
+ /\/\*[\s\S]+?\*\//
+ ],
+ 'datetime': {
+ // '1jan2013'd, '9:25:19pm't, '18jan2003:9:27:05am'dt
+ pattern: /'[^']+'(?:d|d?t)\b/i,
+ alias: 'number'
+ },
+ 'string': /(["'])(?:\1\1|(?!\1)[\s\S])*\1/,
+ 'keyword': /\b(?:data|else|format|if|input|proc|run|then)\b/i,
+ // Decimal (1.2e23), hexadecimal (0c1x)
+ 'number': /(?:\B-|\b)(?:[\da-f]+x|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,
+ 'operator': /\*\*|\|\||!!|¦¦|<>|><|[~¬^<>]?=|[*\/+\-<>&\|!¦~¬^]|\b(?:eq|ne|gt|lt|ge|le|in|not)\b/i,
+ 'punctuation': /[$%@.(){}\[\];,\\]/
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-sas.min.js b/polymer_1.0.4/bower_components/prism/components/prism-sas.min.js
new file mode 100644
index 0000000..edb975c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-sas.min.js
@@ -0,0 +1 @@
+Prism.languages.sas={datalines:{pattern:/(^|[\r\n])\s*(?:(?:data)?lines|cards);[\s\S]+?[\r\n];/i,lookbehind:!0,inside:{keyword:{pattern:/^(\s*)(?:(?:data)?lines|cards)/i,lookbehind:!0},punctuation:/;/,data:{pattern:/[\s\S]+/,alias:"string"}}},comment:[{pattern:/(^\s*|;\s*)\*.*;/m,lookbehind:!0},/\/\*[\s\S]+?\*\//],datetime:{pattern:/'[^']+'(?:d|d?t)\b/i,alias:"number"},string:/(["'])(?:\1\1|(?!\1)[\s\S])*\1/,keyword:/\b(?:data|else|format|if|input|proc|run|then)\b/i,number:/(?:\B-|\b)(?:[\da-f]+x|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,operator:/\*\*|\|\||!!|¦¦|<>|><|[~¬^<>]?=|[*\/+\-<>&\|!¦~¬^]|\b(?:eq|ne|gt|lt|ge|le|in|not)\b/i,punctuation:/[$%@.(){}\[\];,\\]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-scala.js b/polymer_1.0.4/bower_components/prism/components/prism-scala.js
new file mode 100644
index 0000000..62070a2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-scala.js
@@ -0,0 +1,9 @@
+Prism.languages.scala = Prism.languages.extend('java', {
+ 'keyword': /(<-|=>)|\b(abstract|case|catch|class|def|do|else|extends|final|finally|for|forSome|if|implicit|import|lazy|match|new|null|object|override|package|private|protected|return|sealed|self|super|this|throw|trait|try|type|val|var|while|with|yield)\b/,
+ 'builtin': /\b(String|Int|Long|Short|Byte|Boolean|Double|Float|Char|Any|AnyRef|AnyVal|Unit|Nothing)\b/,
+ 'number': /\b0x[\da-f]*\.?[\da-f\-]+\b|\b\d*\.?\d+[e]?[\d]*[dfl]?\b/i,
+ 'symbol': /'([^\d\s]\w*)/,
+ 'string': /(""")[\W\w]*?\1|("|\/)[\W\w]*?\2|('.')/
+});
+delete Prism.languages.scala['class-name'];
+delete Prism.languages.scala['function'];
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-scala.min.js b/polymer_1.0.4/bower_components/prism/components/prism-scala.min.js
new file mode 100644
index 0000000..014c793
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-scala.min.js
@@ -0,0 +1 @@
+Prism.languages.scala=Prism.languages.extend("java",{keyword:/(<-|=>)|\b(abstract|case|catch|class|def|do|else|extends|final|finally|for|forSome|if|implicit|import|lazy|match|new|null|object|override|package|private|protected|return|sealed|self|super|this|throw|trait|try|type|val|var|while|with|yield)\b/,builtin:/\b(String|Int|Long|Short|Byte|Boolean|Double|Float|Char|Any|AnyRef|AnyVal|Unit|Nothing)\b/,number:/\b0x[\da-f]*\.?[\da-f\-]+\b|\b\d*\.?\d+[e]?[\d]*[dfl]?\b/i,symbol:/'([^\d\s]\w*)/,string:/(""")[\W\w]*?\1|("|\/)[\W\w]*?\2|('.')/}),delete Prism.languages.scala["class-name"],delete Prism.languages.scala["function"];
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-scheme.js b/polymer_1.0.4/bower_components/prism/components/prism-scheme.js
new file mode 100644
index 0000000..c3b592f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-scheme.js
@@ -0,0 +1,24 @@
+Prism.languages.scheme = {
+ 'boolean' : /#(t|f){1}/,
+ 'comment' : /;.*/,
+ 'keyword' : {
+ pattern : /([(])(define(-syntax|-library|-values)?|(case-)?lambda|let(-values|(rec)?(\*)?)?|else|if|cond|begin|delay|delay-force|parameterize|guard|set!|(quasi-)?quote|syntax-rules)/,
+ lookbehind : true
+ },
+ 'builtin' : {
+ pattern : /([(])(cons|car|cdr|null\?|pair\?|boolean\?|eof-object\?|char\?|procedure\?|number\?|port\?|string\?|vector\?|symbol\?|bytevector\?|list|call-with-current-continuation|call\/cc|append|abs|apply|eval)\b/,
+ lookbehind : true
+ },
+ 'string' : /(["])(?:(?=(\\?))\2.)*?\1|'[^('|\s)]+/, //thanks http://stackoverflow.com/questions/171480/regex-grabbing-values-between-quotation-marks
+ 'number' : /(\s|\))[-+]?[0-9]*\.?[0-9]+((\s*)[-+]{1}(\s*)[0-9]*\.?[0-9]+i)?/,
+ 'operator': /(\*|\+|\-|%|\/|<=|=>|>=|<|=|>)/,
+ 'function' : {
+ pattern : /([(])[^(\s|\))]*\s/,
+ lookbehind : true
+ },
+ 'punctuation' : /[()]/
+};
+
+
+
+
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-scheme.min.js b/polymer_1.0.4/bower_components/prism/components/prism-scheme.min.js
new file mode 100644
index 0000000..7000c58
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-scheme.min.js
@@ -0,0 +1 @@
+Prism.languages.scheme={"boolean":/#(t|f){1}/,comment:/;.*/,keyword:{pattern:/([(])(define(-syntax|-library|-values)?|(case-)?lambda|let(-values|(rec)?(\*)?)?|else|if|cond|begin|delay|delay-force|parameterize|guard|set!|(quasi-)?quote|syntax-rules)/,lookbehind:!0},builtin:{pattern:/([(])(cons|car|cdr|null\?|pair\?|boolean\?|eof-object\?|char\?|procedure\?|number\?|port\?|string\?|vector\?|symbol\?|bytevector\?|list|call-with-current-continuation|call\/cc|append|abs|apply|eval)\b/,lookbehind:!0},string:/(["])(?:(?=(\\?))\2.)*?\1|'[^('|\s)]+/,number:/(\s|\))[-+]?[0-9]*\.?[0-9]+((\s*)[-+]{1}(\s*)[0-9]*\.?[0-9]+i)?/,operator:/(\*|\+|\-|%|\/|<=|=>|>=|<|=|>)/,"function":{pattern:/([(])[^(\s|\))]*\s/,lookbehind:!0},punctuation:/[()]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-scss.js b/polymer_1.0.4/bower_components/prism/components/prism-scss.js
new file mode 100644
index 0000000..69ea3c7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-scss.js
@@ -0,0 +1,36 @@
+Prism.languages.scss = Prism.languages.extend('css', {
+ 'comment': {
+ pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/,
+ lookbehind: true
+ },
+ // aturle is just the @***, not the entire rule (to highlight var & stuffs)
+ // + add ability to highlight number & unit for media queries
+ 'atrule': /@[\w-]+(?=\s+(\(|\{|;))/i,
+ // url, compassified
+ 'url': /([-a-z]+-)*url(?=\()/i,
+ // CSS selector regex is not appropriate for Sass
+ // since there can be lot more things (var, @ directive, nesting..)
+ // a selector must start at the end of a property or after a brace (end of other rules or nesting)
+ // it can contain some caracters that aren't used for defining rules or end of selector, & (parent selector), or interpolated variable
+ // the end of a selector is found when there is no rules in it ( {} or {\s}) or if there is a property (because an interpolated var
+ // can "pass" as a selector- e.g: proper#{$erty})
+ // this one was ard to do, so please be careful if you edit this one :)
+ 'selector': /([^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+)(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m
+});
+
+Prism.languages.insertBefore('scss', 'atrule', {
+ 'keyword': /@(if|else if|else|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)|(?=@for\s+\$[-_\w]+\s)+from/i
+});
+
+Prism.languages.insertBefore('scss', 'property', {
+ // var and interpolated vars
+ 'variable': /((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i
+});
+
+Prism.languages.insertBefore('scss', 'function', {
+ 'placeholder': /%[-_\w]+/i,
+ 'statement': /\B!(default|optional)\b/i,
+ 'boolean': /\b(true|false)\b/,
+ 'null': /\b(null)\b/,
+ 'operator': /\s+([-+]{1,2}|={1,2}|!=|\|?\||\?|\*|\/|%)\s+/
+});
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-scss.min.js b/polymer_1.0.4/bower_components/prism/components/prism-scss.min.js
new file mode 100644
index 0000000..7d0d82b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-scss.min.js
@@ -0,0 +1 @@
+Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/,lookbehind:!0},atrule:/@[\w-]+(?=\s+(\(|\{|;))/i,url:/([-a-z]+-)*url(?=\()/i,selector:/([^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+)(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m}),Prism.languages.insertBefore("scss","atrule",{keyword:/@(if|else if|else|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)|(?=@for\s+\$[-_\w]+\s)+from/i}),Prism.languages.insertBefore("scss","property",{variable:/((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i}),Prism.languages.insertBefore("scss","function",{placeholder:/%[-_\w]+/i,statement:/\B!(default|optional)\b/i,"boolean":/\b(true|false)\b/,"null":/\b(null)\b/,operator:/\s+([-+]{1,2}|={1,2}|!=|\|?\||\?|\*|\/|%)\s+/});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-smalltalk.js b/polymer_1.0.4/bower_components/prism/components/prism-smalltalk.js
new file mode 100644
index 0000000..0ffc59d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-smalltalk.js
@@ -0,0 +1,31 @@
+Prism.languages.smalltalk = {
+ 'comment': /"(?:""|[^"])+"/,
+ 'string': /'(?:''|[^'])+'/,
+ 'symbol': /#[\da-z]+|#(?:-|([+\/\\*~<>=@%|&?!])\1?)|#(?=\()/i,
+ 'block-arguments': {
+ pattern: /(\[\s*)(?=:)[^\[|]+?\|/,
+ lookbehind: true,
+ inside: {
+ 'variable': /:[\da-z]+/i,
+ 'punctuation': /\|/
+ }
+ },
+ 'temporary-variables': {
+ pattern: /\|[^|]+\|/,
+ inside: {
+ 'variable': /[\da-z]+/i,
+ 'punctuation': /\|/
+ }
+ },
+ 'keyword': /\b(?:nil|true|false|self|super|new)\b/,
+ 'character': {
+ pattern: /\$./,
+ alias: 'string'
+ },
+ 'number': [
+ /\d+r-?[\dA-Z]+(?:\.[\dA-Z]+)?(?:e-?\d+)?/,
+ /(?:\B-|\b)\d+(?:\.\d+)?(?:e-?\d+)?/
+ ],
+ 'operator': /[:=~<>]=|~~|\/\/|\\\\|>>|[!^=<>+\-*\/&|,@]/,
+ 'punctuation': /[.;:?\[\](){}]/
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-smalltalk.min.js b/polymer_1.0.4/bower_components/prism/components/prism-smalltalk.min.js
new file mode 100644
index 0000000..505460c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-smalltalk.min.js
@@ -0,0 +1 @@
+Prism.languages.smalltalk={comment:/"(?:""|[^"])+"/,string:/'(?:''|[^'])+'/,symbol:/#[\da-z]+|#(?:-|([+\/\\*~<>=@%|&?!])\1?)|#(?=\()/i,"block-arguments":{pattern:/(\[\s*)(?=:)[^\[|]+?\|/,lookbehind:!0,inside:{variable:/:[\da-z]+/i,punctuation:/\|/}},"temporary-variables":{pattern:/\|[^|]+\|/,inside:{variable:/[\da-z]+/i,punctuation:/\|/}},keyword:/\b(?:nil|true|false|self|super|new)\b/,character:{pattern:/\$./,alias:"string"},number:[/\d+r-?[\dA-Z]+(?:\.[\dA-Z]+)?(?:e-?\d+)?/,/(?:\B-|\b)\d+(?:\.\d+)?(?:e-?\d+)?/],operator:/[:=~<>]=|~~|\/\/|\\\\|>>|[!^=<>+\-*\/&|,@]/,punctuation:/[.;:?\[\](){}]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-smarty.js b/polymer_1.0.4/bower_components/prism/components/prism-smarty.js
new file mode 100644
index 0000000..a38049c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-smarty.js
@@ -0,0 +1,124 @@
+/* TODO
+ Add support for variables inside double quoted strings
+ Add support for {php}
+*/
+
+(function(Prism) {
+
+ var smarty_pattern = /\{\*[\w\W]+?\*\}|\{[\w\W]+?\}/g;
+ var smarty_litteral_start = '{literal}';
+ var smarty_litteral_end = '{/literal}';
+ var smarty_litteral_mode = false;
+
+ Prism.languages.smarty = Prism.languages.extend('markup', {
+ 'smarty': {
+ pattern: smarty_pattern,
+ inside: {
+ 'delimiter': {
+ pattern: /^\{|\}$/i,
+ alias: 'punctuation'
+ },
+ 'string': /(["'])(\\?.)*?\1/,
+ 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,
+ 'variable': [
+ /\$(?!\d)\w+/,
+ /#(?!\d)\w+#/,
+ {
+ pattern: /(\.|->)(?!\d)\w+/,
+ lookbehind: true
+ },
+ {
+ pattern: /(\[)(?!\d)\w+(?=\])/,
+ lookbehind: true
+ }
+ ],
+ 'function': [
+ {
+ pattern: /(\|\s*)@?(?!\d)\w+/,
+ lookbehind: true
+ },
+ /^\/?(?!\d)\w+/,
+ /(?!\d)\w+(?=\()/
+ ],
+ 'attr-name': {
+ // Value is made optional because it may have already been tokenized
+ pattern: /\w+\s*=\s*(?:(?!\d)\w+)?/,
+ inside: {
+ "variable": {
+ pattern: /(=\s*)(?!\d)\w+/,
+ lookbehind: true
+ },
+ "punctuation": /=/
+ }
+ },
+ 'punctuation': /[\[\]().,=\|:`]|\->/,
+ 'operator': [
+ /[+\-*\/%]|===?|[!<>]=?|&&|\|\|/,
+ /\bis\s+(?:not\s+)?(?:div|even|odd)(?:\s+by)?\b/,
+ /\b(?:eq|neq?|gt|lt|gt?e|lt?e|not|mod|or|and)\b/
+ ],
+ 'keyword': /\b(?:false|off|on|no|true|yes)\b/
+ }
+ }
+ });
+
+ // Comments are inserted at top so that they can
+ // surround markup
+ Prism.languages.insertBefore('smarty', 'tag', {
+ 'smarty-comment': {
+ pattern: /\{\*[\w\W]*?\*\}/,
+ alias: ['smarty','comment']
+ }
+ });
+
+ // Tokenize all inline Smarty expressions
+ Prism.hooks.add('before-highlight', function(env) {
+ if (env.language !== 'smarty') {
+ return;
+ }
+
+ env.tokenStack = [];
+
+ env.backupCode = env.code;
+ env.code = env.code.replace(smarty_pattern, function(match) {
+
+ // Smarty tags inside {literal} block are ignored
+ if(match === smarty_litteral_end) {
+ smarty_litteral_mode = false;
+ }
+
+ if(!smarty_litteral_mode) {
+ if(match === smarty_litteral_start) {
+ smarty_litteral_mode = true;
+ }
+ env.tokenStack.push(match);
+
+ return '___SMARTY' + env.tokenStack.length + '___';
+ }
+ return match;
+ });
+ });
+
+ // Restore env.code for other plugins (e.g. line-numbers)
+ Prism.hooks.add('before-insert', function(env) {
+ if (env.language === 'smarty') {
+ env.code = env.backupCode;
+ delete env.backupCode;
+ }
+ });
+
+ // Re-insert the tokens after highlighting
+ // and highlight them with defined grammar
+ Prism.hooks.add('after-highlight', function(env) {
+ if (env.language !== 'smarty') {
+ return;
+ }
+
+ for (var i = 0, t; t = env.tokenStack[i]; i++) {
+ env.highlightedCode = env.highlightedCode.replace('___SMARTY' + (i + 1) + '___', Prism.highlight(t, env.grammar, 'smarty'));
+ }
+
+ env.element.innerHTML = env.highlightedCode;
+ });
+
+}(Prism));
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-smarty.min.js b/polymer_1.0.4/bower_components/prism/components/prism-smarty.min.js
new file mode 100644
index 0000000..6d09e8d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-smarty.min.js
@@ -0,0 +1 @@
+!function(e){var t=/\{\*[\w\W]+?\*\}|\{[\w\W]+?\}/g,a="{literal}",n="{/literal}",o=!1;e.languages.smarty=e.languages.extend("markup",{smarty:{pattern:t,inside:{delimiter:{pattern:/^\{|\}$/i,alias:"punctuation"},string:/(["'])(\\?.)*?\1/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,variable:[/\$(?!\d)\w+/,/#(?!\d)\w+#/,{pattern:/(\.|->)(?!\d)\w+/,lookbehind:!0},{pattern:/(\[)(?!\d)\w+(?=\])/,lookbehind:!0}],"function":[{pattern:/(\|\s*)@?(?!\d)\w+/,lookbehind:!0},/^\/?(?!\d)\w+/,/(?!\d)\w+(?=\()/],"attr-name":{pattern:/\w+\s*=\s*(?:(?!\d)\w+)?/,inside:{variable:{pattern:/(=\s*)(?!\d)\w+/,lookbehind:!0},punctuation:/=/}},punctuation:/[\[\]().,=\|:`]|\->/,operator:[/[+\-*\/%]|===?|[!<>]=?|&&|\|\|/,/\bis\s+(?:not\s+)?(?:div|even|odd)(?:\s+by)?\b/,/\b(?:eq|neq?|gt|lt|gt?e|lt?e|not|mod|or|and)\b/],keyword:/\b(?:false|off|on|no|true|yes)\b/}}}),e.languages.insertBefore("smarty","tag",{"smarty-comment":{pattern:/\{\*[\w\W]*?\*\}/,alias:["smarty","comment"]}}),e.hooks.add("before-highlight",function(e){"smarty"===e.language&&(e.tokenStack=[],e.backupCode=e.code,e.code=e.code.replace(t,function(t){return t===n&&(o=!1),o?t:(t===a&&(o=!0),e.tokenStack.push(t),"___SMARTY"+e.tokenStack.length+"___")}))}),e.hooks.add("before-insert",function(e){"smarty"===e.language&&(e.code=e.backupCode,delete e.backupCode)}),e.hooks.add("after-highlight",function(t){if("smarty"===t.language){for(var a,n=0;a=t.tokenStack[n];n++)t.highlightedCode=t.highlightedCode.replace("___SMARTY"+(n+1)+"___",e.highlight(a,t.grammar,"smarty"));t.element.innerHTML=t.highlightedCode}})}(Prism);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-sql.js b/polymer_1.0.4/bower_components/prism/components/prism-sql.js
new file mode 100644
index 0000000..2b34ce1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-sql.js
@@ -0,0 +1,17 @@
+Prism.languages.sql= {
+ 'comment': {
+ pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|((--)|(\/\/)|#).*?(\r?\n|$))/,
+ lookbehind: true
+ },
+ 'string' : {
+ pattern: /(^|[^@])("|')(\\?[\s\S])*?\2/,
+ lookbehind: true
+ },
+ 'variable': /@[\w.$]+|@("|'|`)(\\?[\s\S])+?\1/,
+ 'function': /\b(?:COUNT|SUM|AVG|MIN|MAX|FIRST|LAST|UCASE|LCASE|MID|LEN|ROUND|NOW|FORMAT)(?=\s*\()/i, // Should we highlight user defined functions too?
+ 'keyword': /\b(?:ACTION|ADD|AFTER|ALGORITHM|ALTER|ANALYZE|APPLY|AS|ASC|AUTHORIZATION|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADE|CASCADED|CASE|CHAIN|CHAR VARYING|CHARACTER VARYING|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLUMN|COLUMNS|COMMENT|COMMIT|COMMITTED|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATA|DATABASE|DATABASES|DATETIME|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DOUBLE PRECISION|DROP|DUMMY|DUMP|DUMPFILE|DUPLICATE KEY|ELSE|ENABLE|ENCLOSED BY|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPE|ESCAPED BY|EXCEPT|EXEC|EXECUTE|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR|FOR EACH ROW|FORCE|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GEOMETRY|GEOMETRYCOLLECTION|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|IDENTITY|IDENTITY_INSERT|IDENTITYCOL|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTO|INVOKER|ISOLATION LEVEL|JOIN|KEY|KEYS|KILL|LANGUAGE SQL|LAST|LEFT|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONGBLOB|LONGTEXT|MATCH|MATCHED|MEDIUMBLOB|MEDIUMINT|MEDIUMTEXT|MERGE|MIDDLEINT|MODIFIES SQL DATA|MODIFY|MULTILINESTRING|MULTIPOINT|MULTIPOLYGON|NATIONAL|NATIONAL CHAR VARYING|NATIONAL CHARACTER|NATIONAL CHARACTER VARYING|NATIONAL VARCHAR|NATURAL|NCHAR|NCHAR VARCHAR|NEXT|NO|NO SQL|NOCHECK|NOCYCLE|NONCLUSTERED|NULLIF|NUMERIC|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPTIMIZE|OPTION|OPTIONALLY|ORDER|OUT|OUTER|OUTFILE|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREV|PRIMARY|PRINT|PRIVILEGES|PROC|PROCEDURE|PUBLIC|PURGE|QUICK|RAISERROR|READ|READS SQL DATA|READTEXT|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEATABLE|REPLICATION|REQUIRE|RESTORE|RESTRICT|RETURN|RETURNS|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROWCOUNT|ROWGUIDCOL|ROWS?|RTREE|RULE|SAVE|SAVEPOINT|SCHEMA|SELECT|SERIAL|SERIALIZABLE|SESSION|SESSION_USER|SET|SETUSER|SHARE MODE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|START|STARTING BY|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLE|TABLES|TABLESPACE|TEMP(?:ORARY)?|TEMPTABLE|TERMINATED BY|TEXT|TEXTSIZE|THEN|TIMESTAMP|TINYBLOB|TINYINT|TINYTEXT|TO|TOP|TRAN|TRANSACTION|TRANSACTIONS|TRIGGER|TRUNCATE|TSEQUAL|TYPE|TYPES|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNPIVOT|UPDATE|UPDATETEXT|USAGE|USE|USER|USING|VALUE|VALUES|VARBINARY|VARCHAR|VARCHARACTER|VARYING|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH|WITH ROLLUP|WITHIN|WORK|WRITE|WRITETEXT)\b/i,
+ 'boolean': /\b(?:TRUE|FALSE|NULL)\b/i,
+ 'number': /\b-?(0x)?\d*\.?[\da-f]+\b/,
+ 'operator': /\b(?:ALL|AND|ANY|BETWEEN|EXISTS|IN|LIKE|NOT|OR|IS|UNIQUE|CHARACTER SET|COLLATE|DIV|OFFSET|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b|[-+]|!|[=<>]{1,2}|(&){1,2}|\|?\||\?|\*|\//i,
+ 'punctuation': /[;[\]()`,.]/
+};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-sql.min.js b/polymer_1.0.4/bower_components/prism/components/prism-sql.min.js
new file mode 100644
index 0000000..79723f0
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-sql.min.js
@@ -0,0 +1 @@
+Prism.languages.sql={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|((--)|(\/\/)|#).*?(\r?\n|$))/,lookbehind:!0},string:{pattern:/(^|[^@])("|')(\\?[\s\S])*?\2/,lookbehind:!0},variable:/@[\w.$]+|@("|'|`)(\\?[\s\S])+?\1/,"function":/\b(?:COUNT|SUM|AVG|MIN|MAX|FIRST|LAST|UCASE|LCASE|MID|LEN|ROUND|NOW|FORMAT)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALTER|ANALYZE|APPLY|AS|ASC|AUTHORIZATION|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADE|CASCADED|CASE|CHAIN|CHAR VARYING|CHARACTER VARYING|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLUMN|COLUMNS|COMMENT|COMMIT|COMMITTED|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATA|DATABASE|DATABASES|DATETIME|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DOUBLE PRECISION|DROP|DUMMY|DUMP|DUMPFILE|DUPLICATE KEY|ELSE|ENABLE|ENCLOSED BY|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPE|ESCAPED BY|EXCEPT|EXEC|EXECUTE|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR|FOR EACH ROW|FORCE|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GEOMETRY|GEOMETRYCOLLECTION|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|IDENTITY|IDENTITY_INSERT|IDENTITYCOL|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTO|INVOKER|ISOLATION LEVEL|JOIN|KEY|KEYS|KILL|LANGUAGE SQL|LAST|LEFT|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONGBLOB|LONGTEXT|MATCH|MATCHED|MEDIUMBLOB|MEDIUMINT|MEDIUMTEXT|MERGE|MIDDLEINT|MODIFIES SQL DATA|MODIFY|MULTILINESTRING|MULTIPOINT|MULTIPOLYGON|NATIONAL|NATIONAL CHAR VARYING|NATIONAL CHARACTER|NATIONAL CHARACTER VARYING|NATIONAL VARCHAR|NATURAL|NCHAR|NCHAR VARCHAR|NEXT|NO|NO SQL|NOCHECK|NOCYCLE|NONCLUSTERED|NULLIF|NUMERIC|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPTIMIZE|OPTION|OPTIONALLY|ORDER|OUT|OUTER|OUTFILE|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREV|PRIMARY|PRINT|PRIVILEGES|PROC|PROCEDURE|PUBLIC|PURGE|QUICK|RAISERROR|READ|READS SQL DATA|READTEXT|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEATABLE|REPLICATION|REQUIRE|RESTORE|RESTRICT|RETURN|RETURNS|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROWCOUNT|ROWGUIDCOL|ROWS?|RTREE|RULE|SAVE|SAVEPOINT|SCHEMA|SELECT|SERIAL|SERIALIZABLE|SESSION|SESSION_USER|SET|SETUSER|SHARE MODE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|START|STARTING BY|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLE|TABLES|TABLESPACE|TEMP(?:ORARY)?|TEMPTABLE|TERMINATED BY|TEXT|TEXTSIZE|THEN|TIMESTAMP|TINYBLOB|TINYINT|TINYTEXT|TO|TOP|TRAN|TRANSACTION|TRANSACTIONS|TRIGGER|TRUNCATE|TSEQUAL|TYPE|TYPES|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNPIVOT|UPDATE|UPDATETEXT|USAGE|USE|USER|USING|VALUE|VALUES|VARBINARY|VARCHAR|VARCHARACTER|VARYING|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH|WITH ROLLUP|WITHIN|WORK|WRITE|WRITETEXT)\b/i,"boolean":/\b(?:TRUE|FALSE|NULL)\b/i,number:/\b-?(0x)?\d*\.?[\da-f]+\b/,operator:/\b(?:ALL|AND|ANY|BETWEEN|EXISTS|IN|LIKE|NOT|OR|IS|UNIQUE|CHARACTER SET|COLLATE|DIV|OFFSET|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b|[-+]|!|[=<>]{1,2}|(&){1,2}|\|?\||\?|\*|\//i,punctuation:/[;[\]()`,.]/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-stylus.js b/polymer_1.0.4/bower_components/prism/components/prism-stylus.js
new file mode 100644
index 0000000..fd04d78
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-stylus.js
@@ -0,0 +1,61 @@
+Prism.languages.stylus = {
+ 'comment': {
+ pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/g,
+ lookbehind: true
+ },
+ 'keyword': /(px|r?em|ex|ch|vw|vh|vmin|vmax|deg|grad|rad|turn|m?s|k?Hz|dpi|dppx|dpcm)\b|\b(is|defined|not|isnt|and|or|unless|for|in)\b/g,
+ 'atrule': /@[\w-]+(?=\s+\S+)/gi,
+ 'url': /url\((["']?).*?\1\)/gi,
+ 'variable': /^\s*([\w-]+)(?=\s*[+-\\]?=)/gm,
+ 'string': /("|')(\\\n|\\?.)*?\1/g,
+ 'important': /\B!important\b/gi,
+ 'hexcode': /#[\da-f]{3,6}/gi,
+ 'entity': /\\[\da-f]{1,8}/gi,
+ 'number': /\d+\.?\d*%?/g,
+ 'selector': [
+ {
+ pattern: /::?(after|before|first-letter|first-line|selection)/g,
+ alias: 'pseudo-element'
+ },{
+ pattern: /:(?:active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|in-range|invalid|lang|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-of-type|only-child|optional|out-of-range|read-only|read-write|required|root|target|valid|visited)(?:\(.*\))?/g,
+ alias:'pseudo-class'
+ },{
+ pattern: /\[[\w-]+?\s*[*~$^|=]?(?:=\s*\S+)?\]/g,
+ inside: {
+ "attr-name":
+ {
+ pattern: /(\[)([\w-]+)(?=\s*[*~$^|=]{0,2})/g,
+ lookbehind: true
+ },
+ "punctuation": /\[|\]/g,
+ "operator": /[*~$^|=]/g,
+ "attr-value": {
+ pattern: /\S+/
+ },
+ },
+ alias: 'attr'
+ },
+ {
+ pattern: /\.[a-z-]+/i,
+ alias: 'class'
+ },
+ {
+ pattern: /#[a-z-]+/i,
+ alias: 'id'
+ },
+ {
+ pattern: /\b(html|head|title|base|link|meta|style|script|noscript|template|body|section|nav|article|aside|h[1-6]|header|footer|address|main|p|hr|pre|blockquote|ol|ul|li|dl|dt|dd|figure|figcaption|div|a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|dbo|span|br|wbr|ins|del|image|iframe|embed|object|param|video|audio|source|track|canvas|map|area|sv|math|table|caption|colgroup|col|tbody|thead|tfoot|tr|td|th|form|fieldset|legeng|label|input|button|select|datalist|optgroup|option|textarea|keygen|output|progress|meter|details|summary|menuitem|menu)\b/g,
+ alias: 'tag'
+ },
+ ],
+ 'property': [
+ /^\s*([a-z-]+)(?=\s+[\w\W]+|\s*:)(?!\s*\{|\r?\n)/mig,
+ {
+ pattern: /(\(\s*)([a-z-]+)(?=\s*:)/ig,
+ lookbehind: true
+ }
+ ],
+ 'function': /[-a-z0-9]+(?=\()/ig,
+ 'punctuation': /[\{\};:]/g,
+ 'operator': /[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/g
+}
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-stylus.min.js b/polymer_1.0.4/bower_components/prism/components/prism-stylus.min.js
new file mode 100644
index 0000000..ed5c27a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-stylus.min.js
@@ -0,0 +1 @@
+Prism.languages.stylus={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/g,lookbehind:!0},keyword:/(px|r?em|ex|ch|vw|vh|vmin|vmax|deg|grad|rad|turn|m?s|k?Hz|dpi|dppx|dpcm)\b|\b(is|defined|not|isnt|and|or|unless|for|in)\b/g,atrule:/@[\w-]+(?=\s+\S+)/gi,url:/url\((["']?).*?\1\)/gi,variable:/^\s*([\w-]+)(?=\s*[+-\\]?=)/gm,string:/("|')(\\\n|\\?.)*?\1/g,important:/\B!important\b/gi,hexcode:/#[\da-f]{3,6}/gi,entity:/\\[\da-f]{1,8}/gi,number:/\d+\.?\d*%?/g,selector:[{pattern:/::?(after|before|first-letter|first-line|selection)/g,alias:"pseudo-element"},{pattern:/:(?:active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|in-range|invalid|lang|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-of-type|only-child|optional|out-of-range|read-only|read-write|required|root|target|valid|visited)(?:\(.*\))?/g,alias:"pseudo-class"},{pattern:/\[[\w-]+?\s*[*~$^|=]?(?:=\s*\S+)?\]/g,inside:{"attr-name":{pattern:/(\[)([\w-]+)(?=\s*[*~$^|=]{0,2})/g,lookbehind:!0},punctuation:/\[|\]/g,operator:/[*~$^|=]/g,"attr-value":{pattern:/\S+/}},alias:"attr"},{pattern:/\.[a-z-]+/i,alias:"class"},{pattern:/#[a-z-]+/i,alias:"id"},{pattern:/\b(html|head|title|base|link|meta|style|script|noscript|template|body|section|nav|article|aside|h[1-6]|header|footer|address|main|p|hr|pre|blockquote|ol|ul|li|dl|dt|dd|figure|figcaption|div|a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|dbo|span|br|wbr|ins|del|image|iframe|embed|object|param|video|audio|source|track|canvas|map|area|sv|math|table|caption|colgroup|col|tbody|thead|tfoot|tr|td|th|form|fieldset|legeng|label|input|button|select|datalist|optgroup|option|textarea|keygen|output|progress|meter|details|summary|menuitem|menu)\b/g,alias:"tag"}],property:[/^\s*([a-z-]+)(?=\s+[\w\W]+|\s*:)(?!\s*\{|\r?\n)/gim,{pattern:/(\(\s*)([a-z-]+)(?=\s*:)/gi,lookbehind:!0}],"function":/[-a-z0-9]+(?=\()/gi,punctuation:/[\{\};:]/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/g};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-swift.js b/polymer_1.0.4/bower_components/prism/components/prism-swift.js
new file mode 100644
index 0000000..dc2f790
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-swift.js
@@ -0,0 +1,8 @@
+// issues: nested multiline comments, highlighting inside string interpolations
+Prism.languages.swift = Prism.languages.extend('clike', {
+ 'keyword': /\b(as|associativity|break|case|class|continue|convenience|default|deinit|didSet|do|dynamicType|else|enum|extension|fallthrough|final|for|func|get|if|import|in|infix|init|inout|internal|is|lazy|left|let|mutating|new|none|nonmutating|operator|optional|override|postfix|precedence|prefix|private|protocol|public|required|return|right|safe|self|Self|set|static|struct|subscript|super|switch|Type|typealias|unowned|unowned|unsafe|var|weak|where|while|willSet|__COLUMN__|__FILE__|__FUNCTION__|__LINE__)\b/,
+ 'number': /\b([\d_]+(\.[\de_]+)?|0x[a-f0-9_]+(\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,
+ 'constant': /\b(nil|[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,
+ 'atrule': /@\b(IBOutlet|IBDesignable|IBAction|IBInspectable|class_protocol|exported|noreturn|NSCopying|NSManaged|objc|UIApplicationMain|auto_closure)\b/,
+ 'builtin': /\b([A-Z]\S+|abs|advance|alignof|alignofValue|assert|contains|count|countElements|debugPrint|debugPrintln|distance|dropFirst|dropLast|dump|enumerate|equal|filter|find|first|getVaList|indices|isEmpty|join|last|lazy|lexicographicalCompare|map|max|maxElement|min|minElement|numericCast|overlaps|partition|prefix|print|println|reduce|reflect|reverse|sizeof|sizeofValue|sort|sorted|split|startsWith|stride|strideof|strideofValue|suffix|swap|toDebugString|toString|transcode|underestimateCount|unsafeBitCast|withExtendedLifetime|withUnsafeMutablePointer|withUnsafeMutablePointers|withUnsafePointer|withUnsafePointers|withVaList)\b/
+});
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-swift.min.js b/polymer_1.0.4/bower_components/prism/components/prism-swift.min.js
new file mode 100644
index 0000000..4e17687
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-swift.min.js
@@ -0,0 +1 @@
+Prism.languages.swift=Prism.languages.extend("clike",{keyword:/\b(as|associativity|break|case|class|continue|convenience|default|deinit|didSet|do|dynamicType|else|enum|extension|fallthrough|final|for|func|get|if|import|in|infix|init|inout|internal|is|lazy|left|let|mutating|new|none|nonmutating|operator|optional|override|postfix|precedence|prefix|private|protocol|public|required|return|right|safe|self|Self|set|static|struct|subscript|super|switch|Type|typealias|unowned|unowned|unsafe|var|weak|where|while|willSet|__COLUMN__|__FILE__|__FUNCTION__|__LINE__)\b/,number:/\b([\d_]+(\.[\de_]+)?|0x[a-f0-9_]+(\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,constant:/\b(nil|[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,atrule:/@\b(IBOutlet|IBDesignable|IBAction|IBInspectable|class_protocol|exported|noreturn|NSCopying|NSManaged|objc|UIApplicationMain|auto_closure)\b/,builtin:/\b([A-Z]\S+|abs|advance|alignof|alignofValue|assert|contains|count|countElements|debugPrint|debugPrintln|distance|dropFirst|dropLast|dump|enumerate|equal|filter|find|first|getVaList|indices|isEmpty|join|last|lazy|lexicographicalCompare|map|max|maxElement|min|minElement|numericCast|overlaps|partition|prefix|print|println|reduce|reflect|reverse|sizeof|sizeofValue|sort|sorted|split|startsWith|stride|strideof|strideofValue|suffix|swap|toDebugString|toString|transcode|underestimateCount|unsafeBitCast|withExtendedLifetime|withUnsafeMutablePointer|withUnsafeMutablePointers|withUnsafePointer|withUnsafePointers|withVaList)\b/});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-twig.js b/polymer_1.0.4/bower_components/prism/components/prism-twig.js
new file mode 100644
index 0000000..b2fc48f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-twig.js
@@ -0,0 +1,46 @@
+Prism.languages.twig = {
+ 'comment': /\{#[\s\S]*?#\}/,
+ 'tag': {
+ pattern: /(\{\{[\s\S]*?\}\}|\{%[\s\S]*?%\})/,
+ inside: {
+ 'ld': {
+ pattern: /^(\{\{\-?|\{%\-?\s*\w+)/,
+ inside: {
+ 'punctuation': /^(\{\{|\{%)\-?/,
+ 'keyword': /\w+/
+ }
+ },
+ 'rd': {
+ pattern: /\-?(%\}|\}\})$/,
+ inside: {
+ 'punctuation': /.*/
+ }
+ },
+ 'string': {
+ pattern: /("|')(\\?.)*?\1/,
+ inside: {
+ 'punctuation': /^('|")|('|")$/
+ }
+ },
+ 'keyword': /\b(if)\b/,
+ 'boolean': /\b(true|false|null)\b/,
+ 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,
+ 'operator': /==|=|!=|<|>|>=|<=|\+|\-|~|\*|\/|\/\/|%|\*\*|\|/,
+ 'space-operator': {
+ pattern: /(\s)(\b(not|b\-and|b\-xor|b\-or|and|or|in|matches|starts with|ends with|is)\b|\?|:|\?:)(?=\s)/,
+ lookbehind: true,
+ inside: {
+ 'operator': /.*/
+ }
+ },
+ 'property': /\b[a-zA-Z_][a-zA-Z0-9_]*\b/,
+ 'punctuation': /\(|\)|\[\]|\[|\]|\{|\}|:|\.|,/
+ }
+ },
+
+ // The rest can be parsed as HTML
+ 'other': {
+ pattern: /[\s\S]*/,
+ inside: Prism.languages.markup
+ }
+};
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-twig.min.js b/polymer_1.0.4/bower_components/prism/components/prism-twig.min.js
new file mode 100644
index 0000000..db8f500
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-twig.min.js
@@ -0,0 +1 @@
+Prism.languages.twig={comment:/\{#[\s\S]*?#\}/,tag:{pattern:/(\{\{[\s\S]*?\}\}|\{%[\s\S]*?%\})/,inside:{ld:{pattern:/^(\{\{\-?|\{%\-?\s*\w+)/,inside:{punctuation:/^(\{\{|\{%)\-?/,keyword:/\w+/}},rd:{pattern:/\-?(%\}|\}\})$/,inside:{punctuation:/.*/}},string:{pattern:/("|')(\\?.)*?\1/,inside:{punctuation:/^('|")|('|")$/}},keyword:/\b(if)\b/,"boolean":/\b(true|false|null)\b/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,operator:/==|=|!=|<|>|>=|<=|\+|\-|~|\*|\/|\/\/|%|\*\*|\|/,"space-operator":{pattern:/(\s)(\b(not|b\-and|b\-xor|b\-or|and|or|in|matches|starts with|ends with|is)\b|\?|:|\?:)(?=\s)/,lookbehind:!0,inside:{operator:/.*/}},property:/\b[a-zA-Z_][a-zA-Z0-9_]*\b/,punctuation:/\(|\)|\[\]|\[|\]|\{|\}|:|\.|,/}},other:{pattern:/[\s\S]*/,inside:Prism.languages.markup}};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-typescript.js b/polymer_1.0.4/bower_components/prism/components/prism-typescript.js
new file mode 100755
index 0000000..7f7b582
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-typescript.js
@@ -0,0 +1,3 @@
+Prism.languages.typescript = Prism.languages.extend('javascript', {
+ 'keyword': /\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield|module|declare|constructor|string|Function|any|number|boolean|Array|enum)\b/
+});
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-typescript.min.js b/polymer_1.0.4/bower_components/prism/components/prism-typescript.min.js
new file mode 100755
index 0000000..8b6575e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-typescript.min.js
@@ -0,0 +1 @@
+Prism.languages.typescript=Prism.languages.extend("javascript",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield|module|declare|constructor|string|Function|any|number|boolean|Array|enum)\b/});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-wiki.js b/polymer_1.0.4/bower_components/prism/components/prism-wiki.js
new file mode 100644
index 0000000..5ee9787
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-wiki.js
@@ -0,0 +1,80 @@
+Prism.languages.wiki = Prism.languages.extend('markup', {
+ 'block-comment': {
+ pattern: /(^|[^\\])\/\*[\w\W]*?\*\//,
+ lookbehind: true,
+ alias: 'comment'
+ },
+ 'heading': {
+ pattern: /^(=+).+?\1/m,
+ inside: {
+ 'punctuation': /^=+|=+$/,
+ 'important': /.+/
+ }
+ },
+ 'emphasis': {
+ pattern: /('{2,4}).+?\1/,
+ inside: {
+ 'bold italic': {
+ pattern: /('''').+?(?=\1)/,
+ lookbehind: true
+ },
+ 'bold': {
+ pattern: /(''').+?(?=\1)/,
+ lookbehind: true
+ },
+ 'italic': {
+ pattern: /('').+?(?=\1)/,
+ lookbehind: true
+ },
+ 'punctuation': /^''+|''+$/
+ }
+ },
+ 'hr': {
+ pattern: /^-{4,}/m,
+ alias: 'punctuation'
+ },
+ 'url': [
+ /ISBN +(?:97[89][ -]?)?(?:\d[ -]?){9}[\dx]\b/i,
+ /(?:RFC|PMID) +\d+/,
+ /\[\[.+?\]\]/,
+ /\[.+?\]/
+ ],
+ 'variable': [
+ /__[A-Z]+__/,
+ /\{{3}.+?\}{3}/,
+ /\{\{.+?}}/
+ ],
+ 'symbol': [
+ /^#redirect/im,
+ /~{3,5}/
+ ],
+ // Handle table attrs:
+ // {|
+ // ! style="text-align:left;"| Item
+ // |}
+ 'table-tag': {
+ pattern: /((?:^|[|!])[|!])[^|\r\n]+\|(?!\|)/m,
+ lookbehind: true,
+ inside: {
+ 'table-bar': {
+ pattern: /\|$/,
+ alias: 'punctuation'
+ },
+ rest: Prism.languages.markup['tag'].inside
+ }
+ },
+ 'punctuation': /^(?:\{\||\|\}|\|-|[*#:;!|])|\|\||!!/m
+});
+
+Prism.languages.insertBefore('wiki', 'tag', {
+ // Prevent highlighting inside <nowiki>, <source> and <pre> tags
+ 'nowiki': {
+ pattern: /<(nowiki|pre|source)\b[\w\W]*?>[\w\W]*?<\/\1>/i,
+ inside: {
+ 'tag': {
+ pattern: /<(?:nowiki|pre|source)\b[\w\W]*?>|<\/(?:nowiki|pre|source)>/i,
+ inside: Prism.languages.markup['tag'].inside
+ }
+ }
+ }
+});
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-wiki.min.js b/polymer_1.0.4/bower_components/prism/components/prism-wiki.min.js
new file mode 100644
index 0000000..3f1bf26
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-wiki.min.js
@@ -0,0 +1 @@
+Prism.languages.wiki=Prism.languages.extend("markup",{"block-comment":{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0,alias:"comment"},heading:{pattern:/^(=+).+?\1/m,inside:{punctuation:/^=+|=+$/,important:/.+/}},emphasis:{pattern:/('{2,4}).+?\1/,inside:{"bold italic":{pattern:/('''').+?(?=\1)/,lookbehind:!0},bold:{pattern:/(''').+?(?=\1)/,lookbehind:!0},italic:{pattern:/('').+?(?=\1)/,lookbehind:!0},punctuation:/^''+|''+$/}},hr:{pattern:/^-{4,}/m,alias:"punctuation"},url:[/ISBN +(?:97[89][ -]?)?(?:\d[ -]?){9}[\dx]\b/i,/(?:RFC|PMID) +\d+/,/\[\[.+?\]\]/,/\[.+?\]/],variable:[/__[A-Z]+__/,/\{{3}.+?\}{3}/,/\{\{.+?}}/],symbol:[/^#redirect/im,/~{3,5}/],"table-tag":{pattern:/((?:^|[|!])[|!])[^|\r\n]+\|(?!\|)/m,lookbehind:!0,inside:{"table-bar":{pattern:/\|$/,alias:"punctuation"},rest:Prism.languages.markup.tag.inside}},punctuation:/^(?:\{\||\|\}|\|-|[*#:;!|])|\|\||!!/m}),Prism.languages.insertBefore("wiki","tag",{nowiki:{pattern:/<(nowiki|pre|source)\b[\w\W]*?>[\w\W]*?<\/\1>/i,inside:{tag:{pattern:/<(?:nowiki|pre|source)\b[\w\W]*?>|<\/(?:nowiki|pre|source)>/i,inside:Prism.languages.markup.tag.inside}}}});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-yaml.js b/polymer_1.0.4/bower_components/prism/components/prism-yaml.js
new file mode 100644
index 0000000..6b45e8a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-yaml.js
@@ -0,0 +1,44 @@
+Prism.languages.yaml = {
+ 'scalar': {
+ pattern: /([\-:]\s*(![^\s]+)?[ \t]*[|>])[ \t]*(?:(\n[ \t]+)[^\r\n]+(?:\3[^\r\n]+)*)/,
+ lookbehind: true,
+ alias: 'string'
+ },
+ 'comment': /#[^\n]+/,
+ 'key': {
+ pattern: /(\s*[:\-,[{\n?][ \t]*(![^\s]+)?[ \t]*)[^\n{[\]},#]+?(?=\s*:\s)/,
+ lookbehind: true,
+ alias: 'atrule'
+ },
+ 'directive': {
+ pattern: /((^|\n)[ \t]*)%[^\n]+/,
+ lookbehind: true,
+ alias: 'important'
+ },
+ 'datetime': {
+ pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)(\d{4}-\d\d?-\d\d?([tT]|[ \t]+)\d\d?:\d{2}:\d{2}(\.\d*)?[ \t]*(Z|[-+]\d\d?(:\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(:\d{2}(\.\d*)?)?)(?=[ \t]*(\n|$|,|]|}))/,
+ lookbehind: true,
+ alias: 'number'
+ },
+ 'boolean': {
+ pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)(true|false)[ \t]*(?=\n|$|,|]|})/i,
+ lookbehind: true,
+ alias: 'important'
+ },
+ 'null': {
+ pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)(null|~)[ \t]*(?=\n|$|,|]|})/i,
+ lookbehind: true,
+ alias: 'important'
+ },
+ 'string': {
+ pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')(?=[ \t]*(\n|$|,|]|}))/,
+ lookbehind: true
+ },
+ 'number': {
+ pattern: /([:\-,[{]\s*(![^\s]+)?[ \t]*)[+\-]?(0x[\dA-Fa-f]+|0o[0-7]+|(\d+\.?\d*|\.?\d+)(e[\+\-]?\d+)?|\.inf|\.nan)[ \t]*(?=\n|$|,|]|})/i,
+ lookbehind: true
+ },
+ 'tag': /![^\s]+/,
+ 'important': /[&*][\w]+/,
+ 'punctuation': /([:[\]{}\-,|>?]|---|\.\.\.)/
+};
diff --git a/polymer_1.0.4/bower_components/prism/components/prism-yaml.min.js b/polymer_1.0.4/bower_components/prism/components/prism-yaml.min.js
new file mode 100644
index 0000000..2fd09f7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/components/prism-yaml.min.js
@@ -0,0 +1 @@
+Prism.languages.yaml={scalar:{pattern:/([\-:]\s*(![^\s]+)?[ \t]*[|>])[ \t]*(?:(\n[ \t]+)[^\r\n]+(?:\3[^\r\n]+)*)/,lookbehind:!0,alias:"string"},comment:/#[^\n]+/,key:{pattern:/(\s*[:\-,[{\n?][ \t]*(![^\s]+)?[ \t]*)[^\n{[\]},#]+?(?=\s*:\s)/,lookbehind:!0,alias:"atrule"},directive:{pattern:/((^|\n)[ \t]*)%[^\n]+/,lookbehind:!0,alias:"important"},datetime:{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)(\d{4}-\d\d?-\d\d?([tT]|[ \t]+)\d\d?:\d{2}:\d{2}(\.\d*)?[ \t]*(Z|[-+]\d\d?(:\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(:\d{2}(\.\d*)?)?)(?=[ \t]*(\n|$|,|]|}))/,lookbehind:!0,alias:"number"},"boolean":{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)(true|false)[ \t]*(?=\n|$|,|]|})/i,lookbehind:!0,alias:"important"},"null":{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)(null|~)[ \t]*(?=\n|$|,|]|})/i,lookbehind:!0,alias:"important"},string:{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')(?=[ \t]*(\n|$|,|]|}))/,lookbehind:!0},number:{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)[+\-]?(0x[\dA-Fa-f]+|0o[0-7]+|(\d+\.?\d*|\.?\d+)(e[\+\-]?\d+)?|\.inf|\.nan)[ \t]*(?=\n|$|,|]|})/i,lookbehind:!0},tag:/![^\s]+/,important:/[&*][\w]+/,punctuation:/([:[\]{}\-,|>?]|---|\.\.\.)/};
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/examples.js b/polymer_1.0.4/bower_components/prism/examples.js
new file mode 100644
index 0000000..a686fa7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/examples.js
@@ -0,0 +1,181 @@
+/**
+ * Manage examples
+ */
+
+(function() {
+
+var examples = {};
+
+var treeURL = 'https://api.github.com/repos/PrismJS/prism/git/trees/gh-pages?recursive=1';
+var treePromise = new Promise(function (resolve) {
+ $u.xhr({
+ url: treeURL,
+ callback: function (xhr) {
+ if (xhr.status < 400) {
+ resolve(JSON.parse(xhr.responseText).tree);
+ }
+ }
+ });
+});
+
+var languages = components.languages;
+
+for (var id in languages) {
+ if (id === 'meta') {
+ continue;
+ }
+
+ (function (id) {
+ var language = languages[id];
+ var checked = false;
+
+ if (language.option === 'default') {
+ checked = true;
+ }
+
+ language.enabled = checked;
+ language.path = languages.meta.path.replace(/\{id}/g, id) + '.js';
+ language.examplesPath = languages.meta.examplesPath.replace(/\{id}/g, id) + '.html';
+
+ fileExists(language.examplesPath).then(function (exists) {
+ $u.element.create('label', {
+ attributes: {
+ 'data-id': id,
+ 'title': !exists ? 'No examples are available for this language.' : ''
+ },
+ className: !exists ? 'unavailable' : '',
+ contents: [
+ {
+ tag: 'input',
+ properties: {
+ type: 'checkbox',
+ name: 'language',
+ value: id,
+ checked: checked && exists,
+ disabled: !exists,
+ onclick: function () {
+ $$('input[name="' + this.name + '"]').forEach(function (input) {
+ languages[input.value].enabled = input.checked;
+ });
+
+ update(id);
+ }
+ }
+ },
+ language.title
+ ],
+ inside: '#languages'
+ });
+ examples[id] = $u.element.create('section', {
+ 'id': 'language-' + id,
+ 'className': 'language-' + id,
+ inside: '#examples'
+ });
+ if (checked) {
+ update(id);
+ }
+ });
+ }(id));
+}
+
+function fileExists(filepath) {
+ return treePromise.then(function (tree) {
+ for (var i = 0, l = tree.length; i < l; i++) {
+ if (tree[i].path === filepath) {
+ return true;
+ }
+ }
+ return false;
+ });
+}
+
+function getFileContents(filepath) {
+ return new Promise(function (resolve, reject) {
+ $u.xhr({
+ url: filepath,
+ callback: function (xhr) {
+ if (xhr.status < 400 && xhr.responseText) {
+ resolve(xhr.responseText);
+ } else {
+ reject();
+ }
+ }
+ });
+ });
+}
+
+function update(id) {
+ var language = languages[id];
+ if (language.enabled) {
+ if (!language.examplesPromise) {
+ language.examplesPromise = getFileContents(language.examplesPath);
+ }
+ language.examplesPromise.then(function (contents) {
+ examples[id].innerHTML = contents;
+
+ loadLanguage(id).then(function () {
+ var elements = examples[id].querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');
+
+ for (var i=0, element; element = elements[i++];) {
+ Prism.highlightElement(element);
+ }
+ });
+ });
+ } else {
+ examples[id].innerHTML = '';
+ }
+}
+
+/**
+ * Loads a language, including all dependencies
+ *
+ * @param {string} lang the language to load
+ * @type {Promise} the promise which resolves as soon as everything is loaded
+ */
+function loadLanguage (lang)
+{
+ // at first we need to fetch all dependencies for the main language
+ // Note: we need to do this, even if the main language already is loaded (just to be sure..)
+ //
+ // We load an array of all dependencies and call recursively this function on each entry
+ //
+ // dependencies is now an (possibly empty) array of loading-promises
+ var dependencies = getDependenciesOfLanguage(lang).map(loadLanguage);
+
+ // We create a promise, which will resolve, as soon as all dependencies are loaded.
+ // They need to be fully loaded because the main language may extend them.
+ return Promise.all(dependencies)
+ .then(function () {
+
+ // If the main language itself isn't already loaded, load it now
+ // and return the newly created promise (we chain the promises).
+ // If the language is already loaded, just do nothing - the next .then()
+ // will immediately be called
+ if (!Prism.languages[lang]) {
+ return new Promise(function (resolve) {
+ $u.script('components/prism-' + lang + '.js', resolve);
+ });
+ }
+ });
+}
+
+
+/**
+ * Returns all dependencies (as identifiers) of a specific language
+ *
+ * @param {string} lang
+ * @returns {Array.<string>} the list of dependencies. Empty if the language has none.
+ */
+function getDependenciesOfLanguage (lang)
+{
+ if (!components.languages[lang] || !components.languages[lang].require)
+ {
+ return [];
+ }
+
+ return ($u.type(components.languages[lang].require) === "array")
+ ? components.languages[lang].require
+ : [components.languages[lang].require];
+}
+
+}());
diff --git a/polymer_1.0.4/bower_components/prism/gulpfile.js b/polymer_1.0.4/bower_components/prism/gulpfile.js
new file mode 100644
index 0000000..25de6e5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/gulpfile.js
@@ -0,0 +1,48 @@
+var gulp = require('gulp'),
+ rename = require('gulp-rename'),
+ uglify = require('gulp-uglify'),
+ header = require('gulp-header'),
+ concat = require('gulp-concat'),
+
+ paths = {
+ components: ['components/**/*.js', '!components/**/*.min.js'],
+ main: [
+ 'components/prism-core.js',
+ 'components/prism-markup.js',
+ 'components/prism-css.js',
+ 'components/prism-clike.js',
+ 'components/prism-javascript.js',
+ 'plugins/file-highlight/prism-file-highlight.js'
+ ],
+ plugins: ['plugins/**/*.js', '!plugins/**/*.min.js']
+ };
+
+gulp.task('components', function() {
+ return gulp.src(paths.components)
+ .pipe(uglify())
+ .pipe(rename({ suffix: '.min' }))
+ .pipe(gulp.dest('components'));
+});
+
+gulp.task('build', function() {
+ return gulp.src(paths.main)
+ .pipe(header('\n/* **********************************************\n' +
+ ' Begin <%= file.relative %>\n' +
+ '********************************************** */\n\n'))
+ .pipe(concat('prism.js'))
+ .pipe(gulp.dest('./'));
+});
+
+gulp.task('plugins', function() {
+ return gulp.src(paths.plugins)
+ .pipe(uglify())
+ .pipe(rename({ suffix: '.min' }))
+ .pipe(gulp.dest('plugins'));
+});
+
+gulp.task('watch', function() {
+ gulp.watch(paths.components, ['components', 'build']);
+ gulp.watch(paths.plugins, ['plugins', 'build']);
+});
+
+gulp.task('default', ['components', 'plugins', 'build']);
diff --git a/polymer_1.0.4/bower_components/prism/package.json b/polymer_1.0.4/bower_components/prism/package.json
new file mode 100644
index 0000000..06152b4
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "prismjs",
+ "version": "0.0.1",
+ "description": "Lightweight, robust, elegant syntax highlighting. A spin-off project from Dabblet.",
+ "main": "prism.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/LeaVerou/prism.git"
+ },
+ "keywords": [
+ "prism",
+ "highlight"
+ ],
+ "author": "Lea Verou",
+ "license": "MIT",
+ "readmeFilename": "README.md",
+ "devDependencies": {
+ "gulp": "^3.8.6",
+ "gulp-concat": "^2.3.4",
+ "gulp-header": "^1.0.5",
+ "gulp-rename": "^1.2.0",
+ "gulp-uglify": "^0.3.1"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/prism/plugins/autolinker/prism-autolinker.css b/polymer_1.0.4/bower_components/prism/plugins/autolinker/prism-autolinker.css
new file mode 100644
index 0000000..b5f7630
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/autolinker/prism-autolinker.css
@@ -0,0 +1,3 @@
+.token a {
+ color: inherit;
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/autolinker/prism-autolinker.js b/polymer_1.0.4/bower_components/prism/plugins/autolinker/prism-autolinker.js
new file mode 100644
index 0000000..a26b263
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/autolinker/prism-autolinker.js
@@ -0,0 +1,66 @@
+(function(){
+
+if (!self.Prism) {
+ return;
+}
+
+var url = /\b([a-z]{3,7}:\/\/|tel:)[\w\-+%~/.:#=?&]+/,
+ email = /\b\S+@[\w.]+[a-z]{2}/,
+ linkMd = /\[([^\]]+)]\(([^)]+)\)/,
+
+ // Tokens that may contain URLs and emails
+ candidates = ['comment', 'url', 'attr-value', 'string'];
+
+for (var language in Prism.languages) {
+ var tokens = Prism.languages[language];
+
+ Prism.languages.DFS(tokens, function (key, def, type) {
+ if (candidates.indexOf(type) > -1 && Prism.util.type(def) !== 'Array') {
+ if (!def.pattern) {
+ def = this[key] = {
+ pattern: def
+ };
+ }
+
+ def.inside = def.inside || {};
+
+ if (type == 'comment') {
+ def.inside['md-link'] = linkMd;
+ }
+ if (type == 'attr-value') {
+ Prism.languages.insertBefore('inside', 'punctuation', { 'url-link': url }, def);
+ }
+ else {
+ def.inside['url-link'] = url;
+ }
+
+ def.inside['email-link'] = email;
+ }
+ });
+
+ tokens['url-link'] = url;
+ tokens['email-link'] = email;
+}
+
+Prism.hooks.add('wrap', function(env) {
+ if (/-link$/.test(env.type)) {
+ env.tag = 'a';
+
+ var href = env.content;
+
+ if (env.type == 'email-link' && href.indexOf('mailto:') != 0) {
+ href = 'mailto:' + href;
+ }
+ else if (env.type == 'md-link') {
+ // Markdown
+ var match = env.content.match(linkMd);
+
+ href = match[2];
+ env.content = match[1];
+ }
+
+ env.attributes.href = href;
+ }
+});
+
+})();
diff --git a/polymer_1.0.4/bower_components/prism/plugins/autolinker/prism-autolinker.min.js b/polymer_1.0.4/bower_components/prism/plugins/autolinker/prism-autolinker.min.js
new file mode 100644
index 0000000..2b985be
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/autolinker/prism-autolinker.min.js
@@ -0,0 +1 @@
+!function(){if(self.Prism){var i=/\b([a-z]{3,7}:\/\/|tel:)[\w\-+%~/.:#=?&]+/,n=/\b\S+@[\w.]+[a-z]{2}/,t=/\[([^\]]+)]\(([^)]+)\)/,e=["comment","url","attr-value","string"];for(var a in Prism.languages){var r=Prism.languages[a];Prism.languages.DFS(r,function(a,r,l){e.indexOf(l)>-1&&"Array"!==Prism.util.type(r)&&(r.pattern||(r=this[a]={pattern:r}),r.inside=r.inside||{},"comment"==l&&(r.inside["md-link"]=t),"attr-value"==l?Prism.languages.insertBefore("inside","punctuation",{"url-link":i},r):r.inside["url-link"]=i,r.inside["email-link"]=n)}),r["url-link"]=i,r["email-link"]=n}Prism.hooks.add("wrap",function(i){if(/-link$/.test(i.type)){i.tag="a";var n=i.content;if("email-link"==i.type&&0!=n.indexOf("mailto:"))n="mailto:"+n;else if("md-link"==i.type){var e=i.content.match(t);n=e[2],i.content=e[1]}i.attributes.href=n}})}}();
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/file-highlight/prism-file-highlight.js b/polymer_1.0.4/bower_components/prism/plugins/file-highlight/prism-file-highlight.js
new file mode 100644
index 0000000..c81dd01
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/file-highlight/prism-file-highlight.js
@@ -0,0 +1,61 @@
+(function () {
+ if (!self.Prism || !self.document || !document.querySelector) {
+ return;
+ }
+
+ self.Prism.fileHighlight = function() {
+
+ var Extensions = {
+ 'js': 'javascript',
+ 'html': 'markup',
+ 'svg': 'markup',
+ 'xml': 'markup',
+ 'py': 'python',
+ 'rb': 'ruby',
+ 'ps1': 'powershell',
+ 'psm1': 'powershell'
+ };
+
+ Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function(pre) {
+ var src = pre.getAttribute('data-src');
+ var extension = (src.match(/\.(\w+)$/) || [,''])[1];
+ var language = Extensions[extension] || extension;
+
+ var code = document.createElement('code');
+ code.className = 'language-' + language;
+
+ pre.textContent = '';
+
+ code.textContent = 'Loading…';
+
+ pre.appendChild(code);
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', src, true);
+
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+
+ if (xhr.status < 400 && xhr.responseText) {
+ code.textContent = xhr.responseText;
+
+ Prism.highlightElement(code);
+ }
+ else if (xhr.status >= 400) {
+ code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
+ }
+ else {
+ code.textContent = '✖ Error: File does not exist or is empty';
+ }
+ }
+ };
+
+ xhr.send(null);
+ });
+
+ };
+
+ self.Prism.fileHighlight();
+
+})();
diff --git a/polymer_1.0.4/bower_components/prism/plugins/file-highlight/prism-file-highlight.min.js b/polymer_1.0.4/bower_components/prism/plugins/file-highlight/prism-file-highlight.min.js
new file mode 100644
index 0000000..a14cc13
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/file-highlight/prism-file-highlight.min.js
@@ -0,0 +1 @@
+!function(){self.Prism&&self.document&&document.querySelector&&(self.Prism.fileHighlight=function(){var e={js:"javascript",html:"markup",svg:"markup",xml:"markup",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell"};Array.prototype.slice.call(document.querySelectorAll("pre[data-src]")).forEach(function(t){var r=t.getAttribute("data-src"),s=(r.match(/\.(\w+)$/)||[,""])[1],n=e[s]||s,a=document.createElement("code");a.className="language-"+n,t.textContent="",a.textContent="Loading…",t.appendChild(a);var l=new XMLHttpRequest;l.open("GET",r,!0),l.onreadystatechange=function(){4==l.readyState&&(l.status<400&&l.responseText?(a.textContent=l.responseText,Prism.highlightElement(a)):a.textContent=l.status>=400?"✖ Error "+l.status+" while fetching file: "+l.statusText:"✖ Error: File does not exist or is empty")},l.send(null)})},self.Prism.fileHighlight())}();
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/highlight-keywords/prism-highlight-keywords.js b/polymer_1.0.4/bower_components/prism/plugins/highlight-keywords/prism-highlight-keywords.js
new file mode 100644
index 0000000..58c9ad9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/highlight-keywords/prism-highlight-keywords.js
@@ -0,0 +1,14 @@
+(function(){
+
+if (!self.Prism) {
+ return;
+}
+
+Prism.hooks.add('wrap', function(env) {
+ if (env.type !== "keyword") {
+ return;
+ }
+ env.classes.push('keyword-' + env.content);
+});
+
+})();
diff --git a/polymer_1.0.4/bower_components/prism/plugins/highlight-keywords/prism-highlight-keywords.min.js b/polymer_1.0.4/bower_components/prism/plugins/highlight-keywords/prism-highlight-keywords.min.js
new file mode 100644
index 0000000..3e6a382
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/highlight-keywords/prism-highlight-keywords.min.js
@@ -0,0 +1 @@
+!function(){self.Prism&&Prism.hooks.add("wrap",function(s){"keyword"===s.type&&s.classes.push("keyword-"+s.content)})}();
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/ie8/prism-ie8.css b/polymer_1.0.4/bower_components/prism/plugins/ie8/prism-ie8.css
new file mode 100644
index 0000000..b5f7630
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/ie8/prism-ie8.css
@@ -0,0 +1,3 @@
+.token a {
+ color: inherit;
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/ie8/prism-ie8.js b/polymer_1.0.4/bower_components/prism/plugins/ie8/prism-ie8.js
new file mode 100644
index 0000000..0cd83ec
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/ie8/prism-ie8.js
@@ -0,0 +1,42 @@
+(function(){
+
+if (!window.Prism) {
+ return;
+}
+
+var dummy = document.createElement('header');
+
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return this.replace(/^\s+/g, '').replace(/\s+$/g, '');
+ };
+}
+
+// textContent polyfill
+if (!('textContent' in dummy) && ('innerText' in dummy) && Object.defineProperty) {
+ Object.defineProperty(Element.prototype, 'textContent', {
+ get: function() {
+ return this.innerText;
+ },
+ set: function(text) {
+ this.innerText = text;
+ }
+ });
+}
+
+// IE8 doesn't have DOMContentLoaded
+if (!document.addEventListener && 'textContent' in dummy) {
+ setTimeout(Prism.highlightAll, 10);
+}
+
+// Test if innerHTML line break bug is present
+dummy.innerHTML = '\r\n';
+
+if (dummy.textContent.indexOf('\n') === -1) {
+ // IE8 innerHTML bug: Discards line breaks
+ Prism.hooks.add('after-highlight', function(env) {
+ env.element.innerHTML = env.highlightedCode.replace(/\r?\n/g, '<br>');
+ });
+}
+
+})();
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/ie8/prism-ie8.min.js b/polymer_1.0.4/bower_components/prism/plugins/ie8/prism-ie8.min.js
new file mode 100644
index 0000000..2bd5c62
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/ie8/prism-ie8.min.js
@@ -0,0 +1 @@
+!function(){if(window.Prism){var e=document.createElement("header");String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+/g,"").replace(/\s+$/g,"")}),!("textContent"in e)&&"innerText"in e&&Object.defineProperty&&Object.defineProperty(Element.prototype,"textContent",{get:function(){return this.innerText},set:function(e){this.innerText=e}}),!document.addEventListener&&"textContent"in e&&setTimeout(Prism.highlightAll,10),e.innerHTML="\r\n",-1===e.textContent.indexOf("\n")&&Prism.hooks.add("after-highlight",function(e){e.element.innerHTML=e.highlightedCode.replace(/\r?\n/g,"<br>")})}}();
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/line-highlight/prism-line-highlight.css b/polymer_1.0.4/bower_components/prism/plugins/line-highlight/prism-line-highlight.css
new file mode 100644
index 0000000..9eb3173
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/line-highlight/prism-line-highlight.css
@@ -0,0 +1,47 @@
+pre[data-line] {
+ position: relative;
+ padding: 1em 0 1em 3em;
+}
+
+.line-highlight {
+ position: absolute;
+ left: 0;
+ right: 0;
+ padding: inherit 0;
+ margin-top: 1em; /* Same as .prism’s padding-top */
+
+ background: hsla(24, 20%, 50%,.08);
+ background: -moz-linear-gradient(left, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
+ background: -webkit-linear-gradient(left, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
+ background: -o-linear-gradient(left, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
+ background: linear-gradient(left, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
+
+ pointer-events: none;
+
+ line-height: inherit;
+ white-space: pre;
+}
+
+ .line-highlight:before,
+ .line-highlight[data-end]:after {
+ content: attr(data-start);
+ position: absolute;
+ top: .4em;
+ left: .6em;
+ min-width: 1em;
+ padding: 0 .5em;
+ background-color: hsla(24, 20%, 50%,.4);
+ color: hsl(24, 20%, 95%);
+ font: bold 65%/1.5 sans-serif;
+ text-align: center;
+ vertical-align: .3em;
+ border-radius: 999px;
+ text-shadow: none;
+ box-shadow: 0 1px white;
+ }
+
+ .line-highlight[data-end]:after {
+ content: attr(data-end);
+ top: auto;
+ bottom: .4em;
+ }
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/line-highlight/prism-line-highlight.js b/polymer_1.0.4/bower_components/prism/plugins/line-highlight/prism-line-highlight.js
new file mode 100644
index 0000000..b8dddeb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/line-highlight/prism-line-highlight.js
@@ -0,0 +1,109 @@
+(function(){
+
+if(!window.Prism) {
+ return;
+}
+
+function $$(expr, con) {
+ return Array.prototype.slice.call((con || document).querySelectorAll(expr));
+}
+
+function hasClass(element, className) {
+ className = " " + className + " ";
+ return (" " + element.className + " ").replace(/[\n\t]/g, " ").indexOf(className) > -1
+}
+
+var CRLF = crlf = /\r?\n|\r/g;
+
+function highlightLines(pre, lines, classes) {
+ var ranges = lines.replace(/\s+/g, '').split(','),
+ offset = +pre.getAttribute('data-line-offset') || 0;
+
+ var lineHeight = parseFloat(getComputedStyle(pre).lineHeight);
+
+ for (var i=0, range; range = ranges[i++];) {
+ range = range.split('-');
+
+ var start = +range[0],
+ end = +range[1] || start;
+
+ var line = document.createElement('div');
+
+ line.textContent = Array(end - start + 2).join(' \r\n');
+ line.className = (classes || '') + ' line-highlight';
+
+ //if the line-numbers plugin is enabled, then there is no reason for this plugin to display the line numbers
+ if(!hasClass(pre, 'line-numbers')) {
+ line.setAttribute('data-start', start);
+
+ if(end > start) {
+ line.setAttribute('data-end', end);
+ }
+ }
+
+ line.style.top = (start - offset - 1) * lineHeight + 'px';
+
+ //allow this to play nicely with the line-numbers plugin
+ if(hasClass(pre, 'line-numbers')) {
+ //need to attack to pre as when line-numbers is enabled, the code tag is relatively which screws up the positioning
+ pre.appendChild(line);
+ } else {
+ (pre.querySelector('code') || pre).appendChild(line);
+ }
+ }
+}
+
+function applyHash() {
+ var hash = location.hash.slice(1);
+
+ // Remove pre-existing temporary lines
+ $$('.temporary.line-highlight').forEach(function (line) {
+ line.parentNode.removeChild(line);
+ });
+
+ var range = (hash.match(/\.([\d,-]+)$/) || [,''])[1];
+
+ if (!range || document.getElementById(hash)) {
+ return;
+ }
+
+ var id = hash.slice(0, hash.lastIndexOf('.')),
+ pre = document.getElementById(id);
+
+ if (!pre) {
+ return;
+ }
+
+ if (!pre.hasAttribute('data-line')) {
+ pre.setAttribute('data-line', '');
+ }
+
+ highlightLines(pre, range, 'temporary ');
+
+ document.querySelector('.temporary.line-highlight').scrollIntoView();
+}
+
+var fakeTimer = 0; // Hack to limit the number of times applyHash() runs
+
+Prism.hooks.add('after-highlight', function(env) {
+ var pre = env.element.parentNode;
+ var lines = pre && pre.getAttribute('data-line');
+
+ if (!pre || !lines || !/pre/i.test(pre.nodeName)) {
+ return;
+ }
+
+ clearTimeout(fakeTimer);
+
+ $$('.line-highlight', pre).forEach(function (line) {
+ line.parentNode.removeChild(line);
+ });
+
+ highlightLines(pre, lines);
+
+ fakeTimer = setTimeout(applyHash, 1);
+});
+
+addEventListener('hashchange', applyHash);
+
+})();
diff --git a/polymer_1.0.4/bower_components/prism/plugins/line-highlight/prism-line-highlight.min.js b/polymer_1.0.4/bower_components/prism/plugins/line-highlight/prism-line-highlight.min.js
new file mode 100644
index 0000000..9432b40
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/line-highlight/prism-line-highlight.min.js
@@ -0,0 +1 @@
+!function(){function e(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function t(e,t){return t=" "+t+" ",(" "+e.className+" ").replace(/[\n\t]/g," ").indexOf(t)>-1}function n(e,n,r){for(var i,a=n.replace(/\s+/g,"").split(","),l=+e.getAttribute("data-line-offset")||0,o=parseFloat(getComputedStyle(e).lineHeight),d=0;i=a[d++];){i=i.split("-");var c=+i[0],h=+i[1]||c,s=document.createElement("div");s.textContent=Array(h-c+2).join(" \r\n"),s.className=(r||"")+" line-highlight",t(e,"line-numbers")||(s.setAttribute("data-start",c),h>c&&s.setAttribute("data-end",h)),s.style.top=(c-l-1)*o+"px",t(e,"line-numbers")?e.appendChild(s):(e.querySelector("code")||e).appendChild(s)}}function r(){var t=location.hash.slice(1);e(".temporary.line-highlight").forEach(function(e){e.parentNode.removeChild(e)});var r=(t.match(/\.([\d,-]+)$/)||[,""])[1];if(r&&!document.getElementById(t)){var i=t.slice(0,t.lastIndexOf(".")),a=document.getElementById(i);a&&(a.hasAttribute("data-line")||a.setAttribute("data-line",""),n(a,r,"temporary "),document.querySelector(".temporary.line-highlight").scrollIntoView())}}if(window.Prism){var i=(crlf=/\r?\n|\r/g,0);Prism.hooks.add("after-highlight",function(t){var a=t.element.parentNode,l=a&&a.getAttribute("data-line");a&&l&&/pre/i.test(a.nodeName)&&(clearTimeout(i),e(".line-highlight",a).forEach(function(e){e.parentNode.removeChild(e)}),n(a,l),i=setTimeout(r,1))}),addEventListener("hashchange",r)}}();
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/line-numbers/prism-line-numbers.css b/polymer_1.0.4/bower_components/prism/plugins/line-numbers/prism-line-numbers.css
new file mode 100644
index 0000000..284cc0a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/line-numbers/prism-line-numbers.css
@@ -0,0 +1,40 @@
+pre.line-numbers {
+ position: relative;
+ padding-left: 3.8em;
+ counter-reset: linenumber;
+}
+
+pre.line-numbers > code {
+ position: relative;
+}
+
+.line-numbers .line-numbers-rows {
+ position: absolute;
+ pointer-events: none;
+ top: 0;
+ font-size: 100%;
+ left: -3.8em;
+ width: 3em; /* works for line-numbers below 1000 lines */
+ letter-spacing: -1px;
+ border-right: 1px solid #999;
+
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+
+}
+
+ .line-numbers-rows > span {
+ pointer-events: none;
+ display: block;
+ counter-increment: linenumber;
+ }
+
+ .line-numbers-rows > span:before {
+ content: counter(linenumber);
+ color: #999;
+ display: block;
+ padding-right: 0.8em;
+ text-align: right;
+ }
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/line-numbers/prism-line-numbers.js b/polymer_1.0.4/bower_components/prism/plugins/line-numbers/prism-line-numbers.js
new file mode 100644
index 0000000..9443deb
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/line-numbers/prism-line-numbers.js
@@ -0,0 +1,38 @@
+Prism.hooks.add('after-highlight', function (env) {
+ // works only for <code> wrapped inside <pre> (not inline)
+ var pre = env.element.parentNode;
+ var clsReg = /\s*\bline-numbers\b\s*/;
+ if (
+ !pre || !/pre/i.test(pre.nodeName) ||
+ // Abort only if nor the <pre> nor the <code> have the class
+ (!clsReg.test(pre.className) && !clsReg.test(env.element.className))
+ ) {
+ return;
+ }
+
+ if (clsReg.test(env.element.className)) {
+ // Remove the class "line-numbers" from the <code>
+ env.element.className = env.element.className.replace(clsReg, '');
+ }
+ if (!clsReg.test(pre.className)) {
+ // Add the class "line-numbers" to the <pre>
+ pre.className += ' line-numbers';
+ }
+
+ var linesNum = (1 + env.code.split('\n').length);
+ var lineNumbersWrapper;
+
+ var lines = new Array(linesNum);
+ lines = lines.join('<span></span>');
+
+ lineNumbersWrapper = document.createElement('span');
+ lineNumbersWrapper.className = 'line-numbers-rows';
+ lineNumbersWrapper.innerHTML = lines;
+
+ if (pre.hasAttribute('data-start')) {
+ pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
+ }
+
+ env.element.appendChild(lineNumbersWrapper);
+
+});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/line-numbers/prism-line-numbers.min.js b/polymer_1.0.4/bower_components/prism/plugins/line-numbers/prism-line-numbers.min.js
new file mode 100644
index 0000000..26f0a22
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/line-numbers/prism-line-numbers.min.js
@@ -0,0 +1 @@
+Prism.hooks.add("after-highlight",function(e){var t=e.element.parentNode,s=/\s*\bline-numbers\b\s*/;if(t&&/pre/i.test(t.nodeName)&&(s.test(t.className)||s.test(e.element.className))){s.test(e.element.className)&&(e.element.className=e.element.className.replace(s,"")),s.test(t.className)||(t.className+=" line-numbers");var a,n=1+e.code.split("\n").length,l=new Array(n);l=l.join("<span></span>"),a=document.createElement("span"),a.className="line-numbers-rows",a.innerHTML=l,t.hasAttribute("data-start")&&(t.style.counterReset="linenumber "+(parseInt(t.getAttribute("data-start"),10)-1)),e.element.appendChild(a)}});
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/show-invisibles/prism-show-invisibles.css b/polymer_1.0.4/bower_components/prism/plugins/show-invisibles/prism-show-invisibles.css
new file mode 100644
index 0000000..bea2338
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/show-invisibles/prism-show-invisibles.css
@@ -0,0 +1,20 @@
+.token.tab:not(:empty):before,
+.token.cr:before,
+.token.lf:before {
+ color: hsl(24, 20%, 85%);
+}
+
+.token.tab:not(:empty):before {
+ content: '\21E5';
+}
+
+.token.cr:before {
+ content: '\240D';
+}
+
+.token.crlf:before {
+ content: '\240D\240A';
+}
+.token.lf:before {
+ content: '\240A';
+}
diff --git a/polymer_1.0.4/bower_components/prism/plugins/show-invisibles/prism-show-invisibles.js b/polymer_1.0.4/bower_components/prism/plugins/show-invisibles/prism-show-invisibles.js
new file mode 100644
index 0000000..0fbe25e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/show-invisibles/prism-show-invisibles.js
@@ -0,0 +1,16 @@
+(function(){
+
+if(!window.Prism) {
+ return;
+}
+
+for (var language in Prism.languages) {
+ var tokens = Prism.languages[language];
+
+ tokens.tab = /\t/g;
+ tokens.crlf = /\r\n/g;
+ tokens.lf = /\n/g;
+ tokens.cr = /\r/g;
+}
+
+})();
diff --git a/polymer_1.0.4/bower_components/prism/plugins/show-invisibles/prism-show-invisibles.min.js b/polymer_1.0.4/bower_components/prism/plugins/show-invisibles/prism-show-invisibles.min.js
new file mode 100644
index 0000000..bf68c7c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/show-invisibles/prism-show-invisibles.min.js
@@ -0,0 +1 @@
+!function(){if(window.Prism)for(var r in Prism.languages){var g=Prism.languages[r];g.tab=/\t/g,g.crlf=/\r\n/g,g.lf=/\n/g,g.cr=/\r/g}}();
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/show-language/prism-show-language.css b/polymer_1.0.4/bower_components/prism/plugins/show-language/prism-show-language.css
new file mode 100644
index 0000000..4a3c2f2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/show-language/prism-show-language.css
@@ -0,0 +1,16 @@
+pre[class*='language-'] {
+ position: relative;
+}
+pre[class*='language-'][data-language]::before {
+ content: attr(data-language);
+ color: black;
+ background-color: #CFCFCF;
+ display: inline-block;
+ position: absolute;
+ top: 0;
+ right: 0;
+ font-size: 0.9em;
+ border-radius: 0 0 0 5px;
+ padding: 0 0.5em;
+ text-shadow: none;
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/show-language/prism-show-language.js b/polymer_1.0.4/bower_components/prism/plugins/show-language/prism-show-language.js
new file mode 100644
index 0000000..7b345d3
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/show-language/prism-show-language.js
@@ -0,0 +1,20 @@
+(function(){
+
+if (!self.Prism) {
+ return;
+}
+
+var Languages = {
+ 'csharp': 'C#',
+ 'cpp': 'C++'
+};
+Prism.hooks.add('before-highlight', function(env) {
+ var pre = env.element.parentNode;
+ if (!pre || !/pre/i.test(pre.nodeName)) {
+ return;
+ }
+ var language = Languages[env.language] || env.language;
+ pre.setAttribute('data-language', language);
+});
+
+})();
diff --git a/polymer_1.0.4/bower_components/prism/plugins/show-language/prism-show-language.min.css b/polymer_1.0.4/bower_components/prism/plugins/show-language/prism-show-language.min.css
new file mode 100644
index 0000000..16a7f46
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/show-language/prism-show-language.min.css
@@ -0,0 +1 @@
+pre[class*=language-]{position:relative}pre[class*=language-][data-language]::before{content:attr(data-language);color:#000;background-color:#CFCFCF;display:inline-block;position:absolute;top:0;right:0;font-size:.9em;border-radius:0 0 0 5px;padding:0 .5em;text-shadow:none}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/show-language/prism-show-language.min.js b/polymer_1.0.4/bower_components/prism/plugins/show-language/prism-show-language.min.js
new file mode 100644
index 0000000..3f9280d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/show-language/prism-show-language.min.js
@@ -0,0 +1 @@
+!function(){if(self.Prism){var e={csharp:"C#",cpp:"C++"};Prism.hooks.add("before-highlight",function(a){var t=a.element.parentNode;if(t&&/pre/i.test(t.nodeName)){var i=e[a.language]||a.language;t.setAttribute("data-language",i)}})}}();
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/wpd/prism-wpd.css b/polymer_1.0.4/bower_components/prism/plugins/wpd/prism-wpd.css
new file mode 100644
index 0000000..43b7165
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/wpd/prism-wpd.css
@@ -0,0 +1,11 @@
+code[class*="language-"] a[href],
+pre[class*="language-"] a[href] {
+ cursor: help;
+ text-decoration: none;
+}
+
+code[class*="language-"] a[href]:hover,
+pre[class*="language-"] a[href]:hover {
+ cursor: help;
+ text-decoration: underline;
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/wpd/prism-wpd.js b/polymer_1.0.4/bower_components/prism/plugins/wpd/prism-wpd.js
new file mode 100644
index 0000000..9c2c307
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/wpd/prism-wpd.js
@@ -0,0 +1,163 @@
+(function(){
+
+if (!self.Prism) {
+ return;
+}
+
+if (Prism.languages.css) {
+ Prism.languages.css.atrule.inside['atrule-id'] = /^@[\w-]+/;
+
+ // check whether the selector is an advanced pattern before extending it
+ if (Prism.languages.css.selector.pattern)
+ {
+ Prism.languages.css.selector.inside['pseudo-class'] = /:[\w-]+/;
+ Prism.languages.css.selector.inside['pseudo-element'] = /::[\w-]+/;
+ }
+ else
+ {
+ Prism.languages.css.selector = {
+ pattern: Prism.languages.css.selector,
+ inside: {
+ 'pseudo-class': /:[\w-]+/,
+ 'pseudo-element': /::[\w-]+/
+ }
+ };
+ }
+}
+
+if (Prism.languages.markup) {
+ Prism.languages.markup.tag.inside.tag.inside['tag-id'] = /[\w-]+/;
+
+ var Tags = {
+ HTML: {
+ 'a': 1, 'abbr': 1, 'acronym': 1, 'b': 1, 'basefont': 1, 'bdo': 1, 'big': 1, 'blink': 1, 'cite': 1, 'code': 1, 'dfn': 1, 'em': 1, 'kbd': 1, 'i': 1,
+ 'rp': 1, 'rt': 1, 'ruby': 1, 's': 1, 'samp': 1, 'small': 1, 'spacer': 1, 'strike': 1, 'strong': 1, 'sub': 1, 'sup': 1, 'time': 1, 'tt': 1, 'u': 1,
+ 'var': 1, 'wbr': 1, 'noframes': 1, 'summary': 1, 'command': 1, 'dt': 1, 'dd': 1, 'figure': 1, 'figcaption': 1, 'center': 1, 'section': 1, 'nav': 1,
+ 'article': 1, 'aside': 1, 'hgroup': 1, 'header': 1, 'footer': 1, 'address': 1, 'noscript': 1, 'isIndex': 1, 'main': 1, 'mark': 1, 'marquee': 1,
+ 'meter': 1, 'menu': 1
+ },
+ SVG: {
+ 'animateColor': 1, 'animateMotion': 1, 'animateTransform': 1, 'glyph': 1, 'feBlend': 1, 'feColorMatrix': 1, 'feComponentTransfer': 1,
+ 'feFuncR': 1, 'feFuncG': 1, 'feFuncB': 1, 'feFuncA': 1, 'feComposite': 1, 'feConvolveMatrix': 1, 'feDiffuseLighting': 1, 'feDisplacementMap': 1,
+ 'feFlood': 1, 'feGaussianBlur': 1, 'feImage': 1, 'feMerge': 1, 'feMergeNode': 1, 'feMorphology': 1, 'feOffset': 1, 'feSpecularLighting': 1,
+ 'feTile': 1, 'feTurbulence': 1, 'feDistantLight': 1, 'fePointLight': 1, 'feSpotLight': 1, 'linearGradient': 1, 'radialGradient': 1, 'altGlyph': 1,
+ 'textPath': 1, 'tref': 1, 'altglyph': 1, 'textpath': 1, 'tref': 1, 'altglyphdef': 1, 'altglyphitem': 1, 'clipPath': 1, 'color-profile': 1, 'cursor': 1,
+ 'font-face': 1, 'font-face-format': 1, 'font-face-name': 1, 'font-face-src': 1, 'font-face-uri': 1, 'foreignObject': 1, 'glyph': 1, 'glyphRef': 1,
+ 'hkern': 1, 'vkern': 1,
+ },
+ MathML: {}
+ }
+}
+
+var language;
+
+Prism.hooks.add('wrap', function(env) {
+ if ((['tag-id'].indexOf(env.type) > -1
+ || (env.type == 'property' && env.content.indexOf('-') != 0)
+ || (env.type == 'atrule-id'&& env.content.indexOf('@-') != 0)
+ || (env.type == 'pseudo-class'&& env.content.indexOf(':-') != 0)
+ || (env.type == 'pseudo-element'&& env.content.indexOf('::-') != 0)
+ || (env.type == 'attr-name' && env.content.indexOf('data-') != 0)
+ ) && env.content.indexOf('<') === -1
+ ) {
+ var searchURL = 'w/index.php?fulltext&search=';
+
+ env.tag = 'a';
+
+ var href = 'http://docs.webplatform.org/';
+
+ if (env.language == 'css') {
+ href += 'wiki/css/'
+
+ if (env.type == 'property') {
+ href += 'properties/';
+ }
+ else if (env.type == 'atrule-id') {
+ href += 'atrules/';
+ }
+ else if (env.type == 'pseudo-class') {
+ href += 'selectors/pseudo-classes/';
+ }
+ else if (env.type == 'pseudo-element') {
+ href += 'selectors/pseudo-elements/';
+ }
+ }
+ else if (env.language == 'markup') {
+ if (env.type == 'tag-id') {
+ // Check language
+ language = getLanguage(env.content) || language;
+
+ if (language) {
+ href += 'wiki/' + language + '/elements/';
+ }
+ else {
+ href += searchURL;
+ }
+ }
+ else if (env.type == 'attr-name') {
+ if (language) {
+ href += 'wiki/' + language + '/attributes/';
+ }
+ else {
+ href += searchURL;
+ }
+ }
+ }
+
+ href += env.content;
+
+ env.attributes.href = href;
+ env.attributes.target = '_blank';
+ }
+});
+
+function getLanguage(tag) {
+ var tagL = tag.toLowerCase();
+
+ if (Tags.HTML[tagL]) {
+ return 'html';
+ }
+ else if (Tags.SVG[tag]) {
+ return 'svg';
+ }
+ else if (Tags.MathML[tag]) {
+ return 'mathml';
+ }
+
+ // Not in dictionary, perform check
+ if (Tags.HTML[tagL] !== 0) {
+ var htmlInterface = (document.createElement(tag).toString().match(/\[object HTML(.+)Element\]/) || [])[1];
+
+ if (htmlInterface && htmlInterface != 'Unknown') {
+ Tags.HTML[tagL] = 1;
+ return 'html';
+ }
+ }
+
+ Tags.HTML[tagL] = 0;
+
+ if (Tags.SVG[tag] !== 0) {
+ var svgInterface = (document.createElementNS('http://www.w3.org/2000/svg', tag).toString().match(/\[object SVG(.+)Element\]/) || [])[1];
+
+ if (svgInterface && svgInterface != 'Unknown') {
+ Tags.SVG[tag] = 1;
+ return 'svg';
+ }
+ }
+
+ Tags.SVG[tag] = 0;
+
+ // Lame way to detect MathML, but browsers don’t expose interface names there :(
+ if (Tags.MathML[tag] !== 0) {
+ if (tag.indexOf('m') === 0) {
+ Tags.MathML[tag] = 1;
+ return 'mathml';
+ }
+ }
+
+ Tags.MathML[tag] = 0;
+
+ return null;
+}
+
+})();
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/plugins/wpd/prism-wpd.min.js b/polymer_1.0.4/bower_components/prism/plugins/wpd/prism-wpd.min.js
new file mode 100644
index 0000000..8b3eeaa
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/plugins/wpd/prism-wpd.min.js
@@ -0,0 +1 @@
+!function(){function e(e){var a=e.toLowerCase();if(t.HTML[a])return"html";if(t.SVG[e])return"svg";if(t.MathML[e])return"mathml";if(0!==t.HTML[a]){var n=(document.createElement(e).toString().match(/\[object HTML(.+)Element\]/)||[])[1];if(n&&"Unknown"!=n)return t.HTML[a]=1,"html"}if(t.HTML[a]=0,0!==t.SVG[e]){var r=(document.createElementNS("http://www.w3.org/2000/svg",e).toString().match(/\[object SVG(.+)Element\]/)||[])[1];if(r&&"Unknown"!=r)return t.SVG[e]=1,"svg"}return t.SVG[e]=0,0!==t.MathML[e]&&0===e.indexOf("m")?(t.MathML[e]=1,"mathml"):(t.MathML[e]=0,null)}if(self.Prism){if(Prism.languages.css&&(Prism.languages.css.atrule.inside["atrule-id"]=/^@[\w-]+/,Prism.languages.css.selector.pattern?(Prism.languages.css.selector.inside["pseudo-class"]=/:[\w-]+/,Prism.languages.css.selector.inside["pseudo-element"]=/::[\w-]+/):Prism.languages.css.selector={pattern:Prism.languages.css.selector,inside:{"pseudo-class":/:[\w-]+/,"pseudo-element":/::[\w-]+/}}),Prism.languages.markup){Prism.languages.markup.tag.inside.tag.inside["tag-id"]=/[\w-]+/;var t={HTML:{a:1,abbr:1,acronym:1,b:1,basefont:1,bdo:1,big:1,blink:1,cite:1,code:1,dfn:1,em:1,kbd:1,i:1,rp:1,rt:1,ruby:1,s:1,samp:1,small:1,spacer:1,strike:1,strong:1,sub:1,sup:1,time:1,tt:1,u:1,"var":1,wbr:1,noframes:1,summary:1,command:1,dt:1,dd:1,figure:1,figcaption:1,center:1,section:1,nav:1,article:1,aside:1,hgroup:1,header:1,footer:1,address:1,noscript:1,isIndex:1,main:1,mark:1,marquee:1,meter:1,menu:1},SVG:{animateColor:1,animateMotion:1,animateTransform:1,glyph:1,feBlend:1,feColorMatrix:1,feComponentTransfer:1,feFuncR:1,feFuncG:1,feFuncB:1,feFuncA:1,feComposite:1,feConvolveMatrix:1,feDiffuseLighting:1,feDisplacementMap:1,feFlood:1,feGaussianBlur:1,feImage:1,feMerge:1,feMergeNode:1,feMorphology:1,feOffset:1,feSpecularLighting:1,feTile:1,feTurbulence:1,feDistantLight:1,fePointLight:1,feSpotLight:1,linearGradient:1,radialGradient:1,altGlyph:1,textPath:1,tref:1,altglyph:1,textpath:1,tref:1,altglyphdef:1,altglyphitem:1,clipPath:1,"color-profile":1,cursor:1,"font-face":1,"font-face-format":1,"font-face-name":1,"font-face-src":1,"font-face-uri":1,foreignObject:1,glyph:1,glyphRef:1,hkern:1,vkern:1},MathML:{}}}var a;Prism.hooks.add("wrap",function(t){if((["tag-id"].indexOf(t.type)>-1||"property"==t.type&&0!=t.content.indexOf("-")||"atrule-id"==t.type&&0!=t.content.indexOf("@-")||"pseudo-class"==t.type&&0!=t.content.indexOf(":-")||"pseudo-element"==t.type&&0!=t.content.indexOf("::-")||"attr-name"==t.type&&0!=t.content.indexOf("data-"))&&-1===t.content.indexOf("<")){var n="w/index.php?fulltext&search=";t.tag="a";var r="http://docs.webplatform.org/";"css"==t.language?(r+="wiki/css/","property"==t.type?r+="properties/":"atrule-id"==t.type?r+="atrules/":"pseudo-class"==t.type?r+="selectors/pseudo-classes/":"pseudo-element"==t.type&&(r+="selectors/pseudo-elements/")):"markup"==t.language&&("tag-id"==t.type?(a=e(t.content)||a,r+=a?"wiki/"+a+"/elements/":n):"attr-name"==t.type&&(r+=a?"wiki/"+a+"/attributes/":n)),r+=t.content,t.attributes.href=r,t.attributes.target="_blank"}})}}();
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/prism.js b/polymer_1.0.4/bower_components/prism/prism.js
new file mode 100644
index 0000000..e74f7cd
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/prism.js
@@ -0,0 +1,672 @@
+
+/* **********************************************
+ Begin prism-core.js
+********************************************** */
+
+self = (typeof window !== 'undefined')
+ ? window // if in browser
+ : (
+ (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
+ ? self // if in worker
+ : {} // if in node js
+ );
+
+/**
+ * Prism: Lightweight, robust, elegant syntax highlighting
+ * MIT license http://www.opensource.org/licenses/mit-license.php/
+ * @author Lea Verou http://lea.verou.me
+ */
+
+var Prism = (function(){
+
+// Private helper vars
+var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i;
+
+var _ = self.Prism = {
+ util: {
+ encode: function (tokens) {
+ if (tokens instanceof Token) {
+ return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias);
+ } else if (_.util.type(tokens) === 'Array') {
+ return tokens.map(_.util.encode);
+ } else {
+ return tokens.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' ');
+ }
+ },
+
+ type: function (o) {
+ return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1];
+ },
+
+ // Deep clone a language definition (e.g. to extend it)
+ clone: function (o) {
+ var type = _.util.type(o);
+
+ switch (type) {
+ case 'Object':
+ var clone = {};
+
+ for (var key in o) {
+ if (o.hasOwnProperty(key)) {
+ clone[key] = _.util.clone(o[key]);
+ }
+ }
+
+ return clone;
+
+ case 'Array':
+ return o.map(function(v) { return _.util.clone(v); });
+ }
+
+ return o;
+ }
+ },
+
+ languages: {
+ extend: function (id, redef) {
+ var lang = _.util.clone(_.languages[id]);
+
+ for (var key in redef) {
+ lang[key] = redef[key];
+ }
+
+ return lang;
+ },
+
+ /**
+ * Insert a token before another token in a language literal
+ * As this needs to recreate the object (we cannot actually insert before keys in object literals),
+ * we cannot just provide an object, we need anobject and a key.
+ * @param inside The key (or language id) of the parent
+ * @param before The key to insert before. If not provided, the function appends instead.
+ * @param insert Object with the key/value pairs to insert
+ * @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
+ */
+ insertBefore: function (inside, before, insert, root) {
+ root = root || _.languages;
+ var grammar = root[inside];
+
+ if (arguments.length == 2) {
+ insert = arguments[1];
+
+ for (var newToken in insert) {
+ if (insert.hasOwnProperty(newToken)) {
+ grammar[newToken] = insert[newToken];
+ }
+ }
+
+ return grammar;
+ }
+
+ var ret = {};
+
+ for (var token in grammar) {
+
+ if (grammar.hasOwnProperty(token)) {
+
+ if (token == before) {
+
+ for (var newToken in insert) {
+
+ if (insert.hasOwnProperty(newToken)) {
+ ret[newToken] = insert[newToken];
+ }
+ }
+ }
+
+ ret[token] = grammar[token];
+ }
+ }
+
+ // Update references in other language definitions
+ _.languages.DFS(_.languages, function(key, value) {
+ if (value === root[inside] && key != inside) {
+ this[key] = ret;
+ }
+ });
+
+ return root[inside] = ret;
+ },
+
+ // Traverse a language definition with Depth First Search
+ DFS: function(o, callback, type) {
+ for (var i in o) {
+ if (o.hasOwnProperty(i)) {
+ callback.call(o, i, o[i], type || i);
+
+ if (_.util.type(o[i]) === 'Object') {
+ _.languages.DFS(o[i], callback);
+ }
+ else if (_.util.type(o[i]) === 'Array') {
+ _.languages.DFS(o[i], callback, i);
+ }
+ }
+ }
+ }
+ },
+
+ highlightAll: function(async, callback) {
+ var elements = document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');
+
+ for (var i=0, element; element = elements[i++];) {
+ _.highlightElement(element, async === true, callback);
+ }
+ },
+
+ highlightElement: function(element, async, callback) {
+ // Find language
+ var language, grammar, parent = element;
+
+ while (parent && !lang.test(parent.className)) {
+ parent = parent.parentNode;
+ }
+
+ if (parent) {
+ language = (parent.className.match(lang) || [,''])[1];
+ grammar = _.languages[language];
+ }
+
+ if (!grammar) {
+ return;
+ }
+
+ // Set language on the element, if not present
+ element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
+
+ // Set language on the parent, for styling
+ parent = element.parentNode;
+
+ if (/pre/i.test(parent.nodeName)) {
+ parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
+ }
+
+ var code = element.textContent;
+
+ if(!code) {
+ return;
+ }
+
+ code = code.replace(/^(?:\r?\n|\r)/,'');
+
+ var env = {
+ element: element,
+ language: language,
+ grammar: grammar,
+ code: code
+ };
+
+ _.hooks.run('before-highlight', env);
+
+ if (async && self.Worker) {
+ var worker = new Worker(_.filename);
+
+ worker.onmessage = function(evt) {
+ env.highlightedCode = Token.stringify(JSON.parse(evt.data), language);
+
+ _.hooks.run('before-insert', env);
+
+ env.element.innerHTML = env.highlightedCode;
+
+ callback && callback.call(env.element);
+ _.hooks.run('after-highlight', env);
+ };
+
+ worker.postMessage(JSON.stringify({
+ language: env.language,
+ code: env.code
+ }));
+ }
+ else {
+ env.highlightedCode = _.highlight(env.code, env.grammar, env.language);
+
+ _.hooks.run('before-insert', env);
+
+ env.element.innerHTML = env.highlightedCode;
+
+ callback && callback.call(element);
+
+ _.hooks.run('after-highlight', env);
+ }
+ },
+
+ highlight: function (text, grammar, language) {
+ var tokens = _.tokenize(text, grammar);
+ return Token.stringify(_.util.encode(tokens), language);
+ },
+
+ tokenize: function(text, grammar, language) {
+ var Token = _.Token;
+
+ var strarr = [text];
+
+ var rest = grammar.rest;
+
+ if (rest) {
+ for (var token in rest) {
+ grammar[token] = rest[token];
+ }
+
+ delete grammar.rest;
+ }
+
+ tokenloop: for (var token in grammar) {
+ if(!grammar.hasOwnProperty(token) || !grammar[token]) {
+ continue;
+ }
+
+ var patterns = grammar[token];
+ patterns = (_.util.type(patterns) === "Array") ? patterns : [patterns];
+
+ for (var j = 0; j < patterns.length; ++j) {
+ var pattern = patterns[j],
+ inside = pattern.inside,
+ lookbehind = !!pattern.lookbehind,
+ lookbehindLength = 0,
+ alias = pattern.alias;
+
+ pattern = pattern.pattern || pattern;
+
+ for (var i=0; i<strarr.length; i++) { // Don’t cache length as it changes during the loop
+
+ var str = strarr[i];
+
+ if (strarr.length > text.length) {
+ // Something went terribly wrong, ABORT, ABORT!
+ break tokenloop;
+ }
+
+ if (str instanceof Token) {
+ continue;
+ }
+
+ pattern.lastIndex = 0;
+
+ var match = pattern.exec(str);
+
+ if (match) {
+ if(lookbehind) {
+ lookbehindLength = match[1].length;
+ }
+
+ var from = match.index - 1 + lookbehindLength,
+ match = match[0].slice(lookbehindLength),
+ len = match.length,
+ to = from + len,
+ before = str.slice(0, from + 1),
+ after = str.slice(to + 1);
+
+ var args = [i, 1];
+
+ if (before) {
+ args.push(before);
+ }
+
+ var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias);
+
+ args.push(wrapped);
+
+ if (after) {
+ args.push(after);
+ }
+
+ Array.prototype.splice.apply(strarr, args);
+ }
+ }
+ }
+ }
+
+ return strarr;
+ },
+
+ hooks: {
+ all: {},
+
+ add: function (name, callback) {
+ var hooks = _.hooks.all;
+
+ hooks[name] = hooks[name] || [];
+
+ hooks[name].push(callback);
+ },
+
+ run: function (name, env) {
+ var callbacks = _.hooks.all[name];
+
+ if (!callbacks || !callbacks.length) {
+ return;
+ }
+
+ for (var i=0, callback; callback = callbacks[i++];) {
+ callback(env);
+ }
+ }
+ }
+};
+
+var Token = _.Token = function(type, content, alias) {
+ this.type = type;
+ this.content = content;
+ this.alias = alias;
+};
+
+Token.stringify = function(o, language, parent) {
+ if (typeof o == 'string') {
+ return o;
+ }
+
+ if (_.util.type(o) === 'Array') {
+ return o.map(function(element) {
+ return Token.stringify(element, language, o);
+ }).join('');
+ }
+
+ var env = {
+ type: o.type,
+ content: Token.stringify(o.content, language, parent),
+ tag: 'span',
+ classes: ['token', o.type],
+ attributes: {},
+ language: language,
+ parent: parent
+ };
+
+ if (env.type == 'comment') {
+ env.attributes['spellcheck'] = 'true';
+ }
+
+ if (o.alias) {
+ var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias];
+ Array.prototype.push.apply(env.classes, aliases);
+ }
+
+ _.hooks.run('wrap', env);
+
+ var attributes = '';
+
+ for (var name in env.attributes) {
+ attributes += name + '="' + (env.attributes[name] || '') + '"';
+ }
+
+ return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + '</' + env.tag + '>';
+
+};
+
+if (!self.document) {
+ if (!self.addEventListener) {
+ // in Node.js
+ return self.Prism;
+ }
+ // In worker
+ self.addEventListener('message', function(evt) {
+ var message = JSON.parse(evt.data),
+ lang = message.language,
+ code = message.code;
+
+ self.postMessage(JSON.stringify(_.util.encode(_.tokenize(code, _.languages[lang]))));
+ self.close();
+ }, false);
+
+ return self.Prism;
+}
+
+// Get current script and highlight
+var script = document.getElementsByTagName('script');
+
+script = script[script.length - 1];
+
+if (script) {
+ _.filename = script.src;
+
+ if (document.addEventListener && !script.hasAttribute('data-manual')) {
+ document.addEventListener('DOMContentLoaded', _.highlightAll);
+ }
+}
+
+return self.Prism;
+
+})();
+
+if (typeof module !== 'undefined' && module.exports) {
+ module.exports = Prism;
+}
+
+
+/* **********************************************
+ Begin prism-markup.js
+********************************************** */
+
+Prism.languages.markup = {
+ 'comment': /<!--[\w\W]*?-->/,
+ 'prolog': /<\?.+?\?>/,
+ 'doctype': /<!DOCTYPE.+?>/,
+ 'cdata': /<!\[CDATA\[[\w\W]*?]]>/i,
+ 'tag': {
+ pattern: /<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/i,
+ inside: {
+ 'tag': {
+ pattern: /^<\/?[\w:-]+/i,
+ inside: {
+ 'punctuation': /^<\/?/,
+ 'namespace': /^[\w-]+?:/
+ }
+ },
+ 'attr-value': {
+ pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,
+ inside: {
+ 'punctuation': /=|>|"/
+ }
+ },
+ 'punctuation': /\/?>/,
+ 'attr-name': {
+ pattern: /[\w:-]+/,
+ inside: {
+ 'namespace': /^[\w-]+?:/
+ }
+ }
+
+ }
+ },
+ 'entity': /&#?[\da-z]{1,8};/i
+};
+
+// Plugin to make entity title show the real entity, idea by Roman Komarov
+Prism.hooks.add('wrap', function(env) {
+
+ if (env.type === 'entity') {
+ env.attributes['title'] = env.content.replace(/&/, '&');
+ }
+});
+
+
+/* **********************************************
+ Begin prism-css.js
+********************************************** */
+
+Prism.languages.css = {
+ 'comment': /\/\*[\w\W]*?\*\//,
+ 'atrule': {
+ pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i,
+ inside: {
+ 'punctuation': /[;:]/
+ }
+ },
+ 'url': /url\((?:(["'])(\\\n|\\?.)*?\1|.*?)\)/i,
+ 'selector': /[^\{\}\s][^\{\};]*(?=\s*\{)/,
+ 'string': /("|')(\\\n|\\?.)*?\1/,
+ 'property': /(\b|\B)[\w-]+(?=\s*:)/i,
+ 'important': /\B!important\b/i,
+ 'punctuation': /[\{\};:]/,
+ 'function': /[-a-z0-9]+(?=\()/i
+};
+
+if (Prism.languages.markup) {
+ Prism.languages.insertBefore('markup', 'tag', {
+ 'style': {
+ pattern: /<style[\w\W]*?>[\w\W]*?<\/style>/i,
+ inside: {
+ 'tag': {
+ pattern: /<style[\w\W]*?>|<\/style>/i,
+ inside: Prism.languages.markup.tag.inside
+ },
+ rest: Prism.languages.css
+ },
+ alias: 'language-css'
+ }
+ });
+
+ Prism.languages.insertBefore('inside', 'attr-value', {
+ 'style-attr': {
+ pattern: /\s*style=("|').*?\1/i,
+ inside: {
+ 'attr-name': {
+ pattern: /^\s*style/i,
+ inside: Prism.languages.markup.tag.inside
+ },
+ 'punctuation': /^\s*=\s*['"]|['"]\s*$/,
+ 'attr-value': {
+ pattern: /.+/i,
+ inside: Prism.languages.css
+ }
+ },
+ alias: 'language-css'
+ }
+ }, Prism.languages.markup.tag);
+}
+
+/* **********************************************
+ Begin prism-clike.js
+********************************************** */
+
+Prism.languages.clike = {
+ 'comment': [
+ {
+ pattern: /(^|[^\\])\/\*[\w\W]*?\*\//,
+ lookbehind: true
+ },
+ {
+ pattern: /(^|[^\\:])\/\/.*/,
+ lookbehind: true
+ }
+ ],
+ 'string': /("|')(\\\n|\\?.)*?\1/,
+ 'class-name': {
+ pattern: /((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,
+ lookbehind: true,
+ inside: {
+ punctuation: /(\.|\\)/
+ }
+ },
+ 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
+ 'boolean': /\b(true|false)\b/,
+ 'function': {
+ pattern: /[a-z0-9_]+\(/i,
+ inside: {
+ punctuation: /\(/
+ }
+ },
+ 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,
+ 'operator': /[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/,
+ 'ignore': /&(lt|gt|amp);/i,
+ 'punctuation': /[{}[\];(),.:]/
+};
+
+
+/* **********************************************
+ Begin prism-javascript.js
+********************************************** */
+
+Prism.languages.javascript = Prism.languages.extend('clike', {
+ 'keyword': /\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,
+ 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|-?Infinity)\b/,
+ 'function': /(?!\d)[a-z0-9_$]+(?=\()/i
+});
+
+Prism.languages.insertBefore('javascript', 'keyword', {
+ 'regex': {
+ pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,
+ lookbehind: true
+ }
+});
+
+if (Prism.languages.markup) {
+ Prism.languages.insertBefore('markup', 'tag', {
+ 'script': {
+ pattern: /<script[\w\W]*?>[\w\W]*?<\/script>/i,
+ inside: {
+ 'tag': {
+ pattern: /<script[\w\W]*?>|<\/script>/i,
+ inside: Prism.languages.markup.tag.inside
+ },
+ rest: Prism.languages.javascript
+ },
+ alias: 'language-javascript'
+ }
+ });
+}
+
+
+/* **********************************************
+ Begin prism-file-highlight.js
+********************************************** */
+
+(function () {
+ if (!self.Prism || !self.document || !document.querySelector) {
+ return;
+ }
+
+ self.Prism.fileHighlight = function() {
+
+ var Extensions = {
+ 'js': 'javascript',
+ 'html': 'markup',
+ 'svg': 'markup',
+ 'xml': 'markup',
+ 'py': 'python',
+ 'rb': 'ruby',
+ 'ps1': 'powershell',
+ 'psm1': 'powershell'
+ };
+
+ Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function(pre) {
+ var src = pre.getAttribute('data-src');
+ var extension = (src.match(/\.(\w+)$/) || [,''])[1];
+ var language = Extensions[extension] || extension;
+
+ var code = document.createElement('code');
+ code.className = 'language-' + language;
+
+ pre.textContent = '';
+
+ code.textContent = 'Loading…';
+
+ pre.appendChild(code);
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', src, true);
+
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+
+ if (xhr.status < 400 && xhr.responseText) {
+ code.textContent = xhr.responseText;
+
+ Prism.highlightElement(code);
+ }
+ else if (xhr.status >= 400) {
+ code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
+ }
+ else {
+ code.textContent = '✖ Error: File does not exist or is empty';
+ }
+ }
+ };
+
+ xhr.send(null);
+ });
+
+ };
+
+ self.Prism.fileHighlight();
+
+})();
diff --git a/polymer_1.0.4/bower_components/prism/themes/prism-coy.css b/polymer_1.0.4/bower_components/prism/themes/prism-coy.css
new file mode 100644
index 0000000..8db555e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/themes/prism-coy.css
@@ -0,0 +1,231 @@
+/**
+ * prism.js Coy theme for JavaScript, CoffeeScript, CSS and HTML
+ * Based on https://github.com/tshedor/workshop-wp-theme (Example: http://workshop.kansan.com/category/sessions/basics or http://workshop.timshedor.com/category/sessions/basics);
+ * @author Tim Shedor
+ */
+
+code[class*="language-"],
+pre[class*="language-"] {
+ color: black;
+ font-family: Consolas, Monaco, 'Andale Mono', monospace;
+ direction: ltr;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ line-height: 1.5;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+ position: relative;
+ margin: .5em 0;
+ -webkit-box-shadow: -1px 0px 0px 0px #358ccb, 0px 0px 0px 1px #dfdfdf;
+ -moz-box-shadow: -1px 0px 0px 0px #358ccb, 0px 0px 0px 1px #dfdfdf;
+ box-shadow: -1px 0px 0px 0px #358ccb, 0px 0px 0px 1px #dfdfdf;
+ border-left: 10px solid #358ccb;
+ background-color: #fdfdfd;
+ background-image: -webkit-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
+ background-image: -moz-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
+ background-image: -ms-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
+ background-image: -o-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
+ background-image: linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
+ background-size: 3em 3em;
+ background-origin: content-box;
+ overflow: visible;
+ max-height: 30em;
+}
+
+code[class*="language"] {
+ max-height: inherit;
+ height: 100%;
+ padding: 0 1em;
+ display: block;
+ overflow: auto;
+}
+
+/* Margin bottom to accomodate shadow */
+:not(pre) > code[class*="language-"],
+pre[class*="language-"] {
+ background-color: #fdfdfd;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ margin-bottom: 1em;
+}
+
+/* Inline code */
+:not(pre) > code[class*="language-"] {
+ position: relative;
+ padding: .2em;
+ -webkit-border-radius: 0.3em;
+ -moz-border-radius: 0.3em;
+ -ms-border-radius: 0.3em;
+ -o-border-radius: 0.3em;
+ border-radius: 0.3em;
+ color: #c92c2c;
+ border: 1px solid rgba(0, 0, 0, 0.1);
+}
+
+pre[class*="language-"]:before,
+pre[class*="language-"]:after {
+ content: '';
+ z-index: -2;
+ display: block;
+ position: absolute;
+ bottom: 0.75em;
+ left: 0.18em;
+ width: 40%;
+ height: 20%;
+ -webkit-box-shadow: 0px 13px 8px #979797;
+ -moz-box-shadow: 0px 13px 8px #979797;
+ box-shadow: 0px 13px 8px #979797;
+ -webkit-transform: rotate(-2deg);
+ -moz-transform: rotate(-2deg);
+ -ms-transform: rotate(-2deg);
+ -o-transform: rotate(-2deg);
+ transform: rotate(-2deg);
+}
+
+:not(pre) > code[class*="language-"]:after,
+pre[class*="language-"]:after {
+ right: 0.75em;
+ left: auto;
+ -webkit-transform: rotate(2deg);
+ -moz-transform: rotate(2deg);
+ -ms-transform: rotate(2deg);
+ -o-transform: rotate(2deg);
+ transform: rotate(2deg);
+}
+
+.token.comment,
+.token.block-comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: #7D8B99;
+}
+
+.token.punctuation {
+ color: #5F6364;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.function-name,
+.token.constant,
+.token.symbol,
+.token.deleted {
+ color: #c92c2c;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.function,
+.token.builtin,
+.token.inserted {
+ color: #2f9c0a;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.token.variable {
+ color: #a67f59;
+ background: rgba(255, 255, 255, 0.5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword,
+.token.class-name {
+ color: #1990b8;
+}
+
+.token.regex,
+.token.important {
+ color: #e90;
+}
+
+.language-css .token.string,
+.style .token.string {
+ color: #a67f59;
+ background: rgba(255, 255, 255, 0.5);
+}
+
+.token.important {
+ font-weight: normal;
+}
+
+.token.bold {
+ font-weight: bold;
+}
+.token.italic {
+ font-style: italic;
+}
+
+.token.entity {
+ cursor: help;
+}
+
+.namespace {
+ opacity: .7;
+}
+
+@media screen and (max-width: 767px) {
+ pre[class*="language-"]:before,
+ pre[class*="language-"]:after {
+ bottom: 14px;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+ }
+
+}
+
+/* Plugin styles */
+.token.tab:not(:empty):before,
+.token.cr:before,
+.token.lf:before {
+ color: #e0d7d1;
+}
+
+/* Plugin styles: Line Numbers */
+pre[class*="language-"].line-numbers {
+ padding-left: 0;
+}
+
+pre[class*="language-"].line-numbers code {
+ padding-left: 3.8em;
+}
+
+pre[class*="language-"].line-numbers .line-numbers-rows {
+ left: 0;
+}
+
+/* Plugin styles: Line Highlight */
+pre[class*="language-"][data-line] {
+ padding-top: 0;
+ padding-bottom: 0;
+ padding-left: 0;
+}
+pre[data-line] code {
+ position: relative;
+ padding-left: 4em;
+}
+pre .line-highlight {
+ margin-top: 0;
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/prism/themes/prism-dark.css b/polymer_1.0.4/bower_components/prism/themes/prism-dark.css
new file mode 100644
index 0000000..a8047fc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/themes/prism-dark.css
@@ -0,0 +1,126 @@
+/**
+ * prism.js Dark theme for JavaScript, CSS and HTML
+ * Based on the slides of the talk “/Reg(exp){2}lained/”
+ * @author Lea Verou
+ */
+
+code[class*="language-"],
+pre[class*="language-"] {
+ color: white;
+ text-shadow: 0 -.1em .2em black;
+ font-family: Consolas, Monaco, 'Andale Mono', monospace;
+ direction: ltr;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ line-height: 1.5;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+
+@media print {
+ code[class*="language-"],
+ pre[class*="language-"] {
+ text-shadow: none;
+ }
+}
+
+pre[class*="language-"],
+:not(pre) > code[class*="language-"] {
+ background: hsl(30, 20%, 25%);
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+ padding: 1em;
+ margin: .5em 0;
+ overflow: auto;
+ border: .3em solid hsl(30, 20%, 40%);
+ border-radius: .5em;
+ box-shadow: 1px 1px .5em black inset;
+}
+
+/* Inline code */
+:not(pre) > code[class*="language-"] {
+ padding: .15em .2em .05em;
+ border-radius: .3em;
+ border: .13em solid hsl(30, 20%, 40%);
+ box-shadow: 1px 1px .3em -.1em black inset;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: hsl(30, 20%, 50%);
+}
+
+.token.punctuation {
+ opacity: .7;
+}
+
+.namespace {
+ opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol {
+ color: hsl(350, 40%, 70%);
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+ color: hsl(75, 70%, 60%);
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string,
+.token.variable {
+ color: hsl(40, 90%, 60%);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+ color: hsl(350, 40%, 70%);
+}
+
+.token.regex,
+.token.important {
+ color: #e90;
+}
+
+.token.important,
+.token.bold {
+ font-weight: bold;
+}
+.token.italic {
+ font-style: italic;
+}
+
+.token.entity {
+ cursor: help;
+}
+
+.token.deleted {
+ color: red;
+}
diff --git a/polymer_1.0.4/bower_components/prism/themes/prism-funky.css b/polymer_1.0.4/bower_components/prism/themes/prism-funky.css
new file mode 100644
index 0000000..f2614d1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/themes/prism-funky.css
@@ -0,0 +1,115 @@
+/**
+ * prism.js Funky theme
+ * Based on “Polyfilling the gaps” talk slides http://lea.verou.me/polyfilling-the-gaps/
+ * @author Lea Verou
+ */
+
+code[class*="language-"],
+pre[class*="language-"] {
+ font-family: Consolas, Monaco, 'Andale Mono', monospace;
+ direction: ltr;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ line-height: 1.5;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+ padding: .4em .8em;
+ margin: .5em 0;
+ overflow: auto;
+ background: url('data:image/svg+xml;charset=utf-8,<svg%20version%3D"1.1"%20xmlns%3D"http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg"%20width%3D"100"%20height%3D"100"%20fill%3D"rgba(0%2C0%2C0%2C.2)">%0D%0A<polygon%20points%3D"0%2C50%2050%2C0%200%2C0"%20%2F>%0D%0A<polygon%20points%3D"0%2C100%2050%2C100%20100%2C50%20100%2C0"%20%2F>%0D%0A<%2Fsvg>');
+ background-size: 1em 1em;
+}
+
+code[class*="language-"] {
+ background: black;
+ color: white;
+ box-shadow: -.3em 0 0 .3em black, .3em 0 0 .3em black;
+}
+
+/* Inline code */
+:not(pre) > code[class*="language-"] {
+ padding: .2em;
+ border-radius: .3em;
+ box-shadow: none;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: #aaa;
+}
+
+.token.punctuation {
+ color: #999;
+}
+
+.namespace {
+ opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol {
+ color: #0cf;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin {
+ color: yellow;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.toke.variable,
+.token.inserted {
+ color: yellowgreen;
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+ color: deeppink;
+}
+
+.token.regex,
+.token.important {
+ color: orange;
+}
+
+.token.important,
+.token.bold {
+ font-weight: bold;
+}
+.token.italic {
+ font-style: italic;
+}
+
+.token.entity {
+ cursor: help;
+}
+
+.token.deleted {
+ color: red;
+}
diff --git a/polymer_1.0.4/bower_components/prism/themes/prism-okaidia.css b/polymer_1.0.4/bower_components/prism/themes/prism-okaidia.css
new file mode 100644
index 0000000..3ff2e3c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/themes/prism-okaidia.css
@@ -0,0 +1,119 @@
+/**
+ * okaidia theme for JavaScript, CSS and HTML
+ * Loosely based on Monokai textmate theme by http://www.monokai.nl/
+ * @author ocodia
+ */
+
+code[class*="language-"],
+pre[class*="language-"] {
+ color: #f8f8f2;
+ text-shadow: 0 1px rgba(0, 0, 0, 0.3);
+ font-family: Consolas, Monaco, 'Andale Mono', monospace;
+ direction: ltr;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ line-height: 1.5;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+ padding: 1em;
+ margin: .5em 0;
+ overflow: auto;
+ border-radius: 0.3em;
+}
+
+:not(pre) > code[class*="language-"],
+pre[class*="language-"] {
+ background: #272822;
+}
+
+/* Inline code */
+:not(pre) > code[class*="language-"] {
+ padding: .1em;
+ border-radius: .3em;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: slategray;
+}
+
+.token.punctuation {
+ color: #f8f8f2;
+}
+
+.namespace {
+ opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.constant,
+.token.symbol,
+.token.deleted {
+ color: #f92672;
+}
+
+.token.boolean,
+.token.number {
+ color: #ae81ff;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+ color: #a6e22e;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string,
+.token.variable {
+ color: #f8f8f2;
+}
+
+.token.atrule,
+.token.attr-value,
+.token.function {
+ color: #e6db74;
+}
+
+.token.keyword {
+ color: #66d9ef;
+}
+
+.token.regex,
+.token.important {
+ color: #fd971f;
+}
+
+.token.important,
+.token.bold {
+ font-weight: bold;
+}
+.token.italic {
+ font-style: italic;
+}
+
+.token.entity {
+ cursor: help;
+}
diff --git a/polymer_1.0.4/bower_components/prism/themes/prism-tomorrow.css b/polymer_1.0.4/bower_components/prism/themes/prism-tomorrow.css
new file mode 100644
index 0000000..c998fb2
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/themes/prism-tomorrow.css
@@ -0,0 +1,119 @@
+/**
+ * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML
+ * Based on https://github.com/chriskempson/tomorrow-theme
+ * @author Rose Pritchard
+ */
+
+code[class*="language-"],
+pre[class*="language-"] {
+ color: #ccc;
+ font-family: Consolas, Monaco, 'Andale Mono', monospace;
+ direction: ltr;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ line-height: 1.5;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+ padding: 1em;
+ margin: .5em 0;
+ overflow: auto;
+}
+
+:not(pre) > code[class*="language-"],
+pre[class*="language-"] {
+ background: #2d2d2d;
+}
+
+/* Inline code */
+:not(pre) > code[class*="language-"] {
+ padding: .1em;
+ border-radius: .3em;
+}
+
+.token.comment,
+.token.block-comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: #999;
+}
+
+.token.punctuation {
+ color: #ccc;
+}
+
+.token.tag,
+.token.attr-name,
+.token.namespace,
+.token.deleted {
+ color: #e2777a;
+}
+
+.token.function-name {
+ color: #6196cc;
+}
+
+.token.boolean,
+.token.number,
+.token.function {
+ color: #f08d49;
+}
+
+.token.property,
+.token.class-name,
+.token.constant,
+.token.symbol {
+ color: #f8c555;
+}
+
+.token.selector,
+.token.important,
+.token.atrule,
+.token.keyword,
+.token.builtin {
+ color: #cc99cd;
+}
+
+.token.string,
+.token.char,
+.token.attr-value,
+.token.regex,
+.token.variable {
+ color: #7ec699;
+}
+
+.token.operator,
+.token.entity,
+.token.url {
+ color: #67cdcc;
+}
+
+.token.important,
+.token.bold {
+ font-weight: bold;
+}
+.token.italic {
+ font-style: italic;
+}
+
+.token.entity {
+ cursor: help;
+}
+
+.token.inserted {
+ color: green;
+}
diff --git a/polymer_1.0.4/bower_components/prism/themes/prism-twilight.css b/polymer_1.0.4/bower_components/prism/themes/prism-twilight.css
new file mode 100644
index 0000000..89dbe84
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/themes/prism-twilight.css
@@ -0,0 +1,199 @@
+/**
+ * prism.js Twilight theme
+ * Based (more or less) on the Twilight theme originally of Textmate fame.
+ * @author Remy Bach
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+ color: white;
+ direction: ltr;
+ font-family: Consolas, Monaco, 'Andale Mono', monospace;
+ text-align: left;
+ text-shadow: 0 -.1em .2em black;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ line-height: 1.5;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+
+pre[class*="language-"],
+:not(pre) > code[class*="language-"] {
+ background: hsl(0, 0%, 8%); /* #141414 */
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+ border-radius: .5em;
+ border: .3em solid hsl(0, 0%, 33%); /* #282A2B */
+ box-shadow: 1px 1px .5em black inset;
+ margin: .5em 0;
+ overflow: auto;
+ padding: 1em;
+}
+
+pre[class*="language-"]::selection {
+ /* Safari */
+ background: hsl(200, 4%, 16%); /* #282A2B */
+}
+
+pre[class*="language-"]::selection {
+ /* Firefox */
+ background: hsl(200, 4%, 16%); /* #282A2B */
+}
+
+/* Text Selection colour */
+pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
+ text-shadow: none;
+ background: hsla(0, 0%, 93%, 0.15); /* #EDEDED */
+}
+
+pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
+code[class*="language-"]::selection, code[class*="language-"] ::selection {
+ text-shadow: none;
+ background: hsla(0, 0%, 93%, 0.15); /* #EDEDED */
+}
+
+/* Inline code */
+:not(pre) > code[class*="language-"] {
+ border-radius: .3em;
+ border: .13em solid hsl(0, 0%, 33%); /* #545454 */
+ box-shadow: 1px 1px .3em -.1em black inset;
+ padding: .15em .2em .05em;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: hsl(0, 0%, 47%); /* #777777 */
+}
+
+.token.punctuation {
+ opacity: .7;
+}
+
+.namespace {
+ opacity: .7;
+}
+
+.token.tag,
+.token.boolean,
+.token.number,
+.token.deleted {
+ color: hsl(14, 58%, 55%); /* #CF6A4C */
+}
+
+.token.keyword,
+.token.property,
+.token.selector,
+.token.constant,
+.token.symbol,
+.token.builtin {
+ color: hsl(53, 89%, 79%); /* #F9EE98 */
+}
+
+.token.attr-name,
+.token.attr-value,
+.token.string,
+.token.char,
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string,
+.token.variable,
+.token.inserted {
+ color: hsl(76, 21%, 52%); /* #8F9D6A */
+}
+
+.token.atrule {
+ color: hsl(218, 22%, 55%); /* #7587A6 */
+}
+
+.token.regex,
+.token.important {
+ color: hsl(42, 75%, 65%); /* #E9C062 */
+}
+
+.token.important,
+.token.bold {
+ font-weight: bold;
+}
+.token.italic {
+ font-style: italic;
+}
+
+.token.entity {
+ cursor: help;
+}
+
+pre[data-line] {
+ padding: 1em 0 1em 3em;
+ position: relative;
+}
+
+/* Markup */
+.language-markup .token.tag,
+.language-markup .token.attr-name,
+.language-markup .token.punctuation {
+ color: hsl(33, 33%, 52%); /* #AC885B */
+}
+
+/* Make the tokens sit above the line highlight so the colours don't look faded. */
+.token {
+ position: relative;
+ z-index: 1;
+}
+
+.line-highlight {
+ background: -moz-linear-gradient(left, hsla(0, 0%, 33%, .1) 70%, hsla(0, 0%, 33%, 0)); /* #545454 */
+ background: -o-linear-gradient(left, hsla(0, 0%, 33%, .1) 70%, hsla(0, 0%, 33%, 0)); /* #545454 */
+ background: -webkit-linear-gradient(left, hsla(0, 0%, 33%, .1) 70%, hsla(0, 0%, 33%, 0)); /* #545454 */
+ background: hsla(0, 0%, 33%, 0.25); /* #545454 */
+ background: linear-gradient(left, hsla(0, 0%, 33%, .1) 70%, hsla(0, 0%, 33%, 0)); /* #545454 */
+ border-bottom: 1px dashed hsl(0, 0%, 33%); /* #545454 */
+ border-top: 1px dashed hsl(0, 0%, 33%); /* #545454 */
+ left: 0;
+ line-height: inherit;
+ margin-top: 0.75em; /* Same as .prism’s padding-top */
+ padding: inherit 0;
+ pointer-events: none;
+ position: absolute;
+ right: 0;
+ white-space: pre;
+ z-index: 0;
+}
+
+.line-highlight:before,
+.line-highlight[data-end]:after {
+ background-color: hsl(215, 15%, 59%); /* #8794A6 */
+ border-radius: 999px;
+ box-shadow: 0 1px white;
+ color: hsl(24, 20%, 95%); /* #F5F2F0 */
+ content: attr(data-start);
+ font: bold 65%/1.5 sans-serif;
+ left: .6em;
+ min-width: 1em;
+ padding: 0 .5em;
+ position: absolute;
+ text-align: center;
+ text-shadow: none;
+ top: .4em;
+ vertical-align: .3em;
+}
+
+.line-highlight[data-end]:after {
+ bottom: .4em;
+ content: attr(data-end);
+ top: auto;
+}
diff --git a/polymer_1.0.4/bower_components/prism/themes/prism.css b/polymer_1.0.4/bower_components/prism/themes/prism.css
new file mode 100644
index 0000000..a04c82c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/themes/prism.css
@@ -0,0 +1,135 @@
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+
+code[class*="language-"],
+pre[class*="language-"] {
+ color: black;
+ text-shadow: 0 1px white;
+ font-family: Consolas, Monaco, 'Andale Mono', monospace;
+ direction: ltr;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ line-height: 1.5;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
+ text-shadow: none;
+ background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
+code[class*="language-"]::selection, code[class*="language-"] ::selection {
+ text-shadow: none;
+ background: #b3d4fc;
+}
+
+@media print {
+ code[class*="language-"],
+ pre[class*="language-"] {
+ text-shadow: none;
+ }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+ padding: 1em;
+ margin: .5em 0;
+ overflow: auto;
+}
+
+:not(pre) > code[class*="language-"],
+pre[class*="language-"] {
+ background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre) > code[class*="language-"] {
+ padding: .1em;
+ border-radius: .3em;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: slategray;
+}
+
+.token.punctuation {
+ color: #999;
+}
+
+.namespace {
+ opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+ color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+ color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+ color: #a67f59;
+ background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+ color: #07a;
+}
+
+.token.function {
+ color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+ color: #e90;
+}
+
+.token.important,
+.token.bold {
+ font-weight: bold;
+}
+.token.italic {
+ font-style: italic;
+}
+
+.token.entity {
+ cursor: help;
+}
diff --git a/polymer_1.0.4/bower_components/prism/vendor/promise.js b/polymer_1.0.4/bower_components/prism/vendor/promise.js
new file mode 100644
index 0000000..9bcc799
--- /dev/null
+++ b/polymer_1.0.4/bower_components/prism/vendor/promise.js
@@ -0,0 +1,5 @@
+/**
+ * ES6-Promises
+ * https://github.com/jakearchibald/es6-promise
+ */
+!function(){var a,b,c,d;!function(){var e={},f={};a=function(a,b,c){e[a]={deps:b,callback:c}},d=c=b=function(a){function c(b){if("."!==b.charAt(0))return b;for(var c=b.split("/"),d=a.split("/").slice(0,-1),e=0,f=c.length;f>e;e++){var g=c[e];if(".."===g)d.pop();else{if("."===g)continue;d.push(g)}}return d.join("/")}if(d._eak_seen=e,f[a])return f[a];if(f[a]={},!e[a])throw new Error("Could not find module "+a);for(var g,h=e[a],i=h.deps,j=h.callback,k=[],l=0,m=i.length;m>l;l++)"exports"===i[l]?k.push(g={}):k.push(b(c(i[l])));var n=j.apply(this,k);return f[a]=g||n}}(),a("promise/all",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to all.");return new b(function(b,c){function d(a){return function(b){f(a,b)}}function f(a,c){h[a]=c,0===--i&&b(h)}var g,h=[],i=a.length;0===i&&b([]);for(var j=0;j<a.length;j++)g=a[j],g&&e(g.then)?g.then(d(j),c):f(j,g)})}var d=a.isArray,e=a.isFunction;b.all=c}),a("promise/asap",["exports"],function(a){"use strict";function b(){return function(){process.nextTick(e)}}function c(){var a=0,b=new i(e),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function d(){return function(){j.setTimeout(e,1)}}function e(){for(var a=0;a<k.length;a++){var b=k[a],c=b[0],d=b[1];c(d)}k=[]}function f(a,b){var c=k.push([a,b]);1===c&&g()}var g,h="undefined"!=typeof window?window:{},i=h.MutationObserver||h.WebKitMutationObserver,j="undefined"!=typeof global?global:void 0===this?window:this,k=[];g="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?b():i?c():d(),a.asap=f}),a("promise/config",["exports"],function(a){"use strict";function b(a,b){return 2!==arguments.length?c[a]:(c[a]=b,void 0)}var c={instrument:!1};a.config=c,a.configure=b}),a("promise/polyfill",["./promise","./utils","exports"],function(a,b,c){"use strict";function d(){var a;a="undefined"!=typeof global?global:"undefined"!=typeof window&&window.document?window:self;var b="Promise"in a&&"resolve"in a.Promise&&"reject"in a.Promise&&"all"in a.Promise&&"race"in a.Promise&&function(){var b;return new a.Promise(function(a){b=a}),f(b)}();b||(a.Promise=e)}var e=a.Promise,f=b.isFunction;c.polyfill=d}),a("promise/promise",["./config","./utils","./all","./race","./resolve","./reject","./asap","exports"],function(a,b,c,d,e,f,g,h){"use strict";function i(a){if(!v(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof i))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],j(a,this)}function j(a,b){function c(a){o(b,a)}function d(a){q(b,a)}try{a(c,d)}catch(e){d(e)}}function k(a,b,c,d){var e,f,g,h,i=v(c);if(i)try{e=c(d),g=!0}catch(j){h=!0,f=j}else e=d,g=!0;n(b,e)||(i&&g?o(b,e):h?q(b,f):a===D?o(b,e):a===E&&q(b,e))}function l(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+D]=c,e[f+E]=d}function m(a,b){for(var c,d,e=a._subscribers,f=a._detail,g=0;g<e.length;g+=3)c=e[g],d=e[g+b],k(b,c,d,f);a._subscribers=null}function n(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(u(b)&&(d=b.then,v(d)))return d.call(b,function(d){return c?!0:(c=!0,b!==d?o(a,d):p(a,d),void 0)},function(b){return c?!0:(c=!0,q(a,b),void 0)}),!0}catch(e){return c?!0:(q(a,e),!0)}return!1}function o(a,b){a===b?p(a,b):n(a,b)||p(a,b)}function p(a,b){a._state===B&&(a._state=C,a._detail=b,t.async(r,a))}function q(a,b){a._state===B&&(a._state=C,a._detail=b,t.async(s,a))}function r(a){m(a,a._state=D)}function s(a){m(a,a._state=E)}var t=a.config,u=(a.configure,b.objectOrFunction),v=b.isFunction,w=(b.now,c.all),x=d.race,y=e.resolve,z=f.reject,A=g.asap;t.async=A;var B=void 0,C=0,D=1,E=2;i.prototype={constructor:i,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(a,b){var c=this,d=new this.constructor(function(){});if(this._state){var e=arguments;t.async(function(){k(c._state,d,e[c._state-1],c._detail)})}else l(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}},i.all=w,i.race=x,i.resolve=y,i.reject=z,h.Promise=i}),a("promise/race",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to race.");return new b(function(b,c){for(var d,e=0;e<a.length;e++)d=a[e],d&&"function"==typeof d.then?d.then(b,c):b(d)})}var d=a.isArray;b.race=c}),a("promise/reject",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b,c){c(a)})}a.reject=b}),a("promise/resolve",["exports"],function(a){"use strict";function b(a){if(a&&"object"==typeof a&&a.constructor===this)return a;var b=this;return new b(function(b){b(a)})}a.resolve=b}),a("promise/utils",["exports"],function(a){"use strict";function b(a){return c(a)||"object"==typeof a&&null!==a}function c(a){return"function"==typeof a}function d(a){return"[object Array]"===Object.prototype.toString.call(a)}var e=Date.now||function(){return(new Date).getTime()};a.objectOrFunction=b,a.isFunction=c,a.isArray=d,a.now=e}),b("promise/polyfill").polyfill()}();
diff --git a/polymer_1.0.4/bower_components/promise-polyfill/.bower.json b/polymer_1.0.4/bower_components/promise-polyfill/.bower.json
new file mode 100644
index 0000000..ee0f467
--- /dev/null
+++ b/polymer_1.0.4/bower_components/promise-polyfill/.bower.json
@@ -0,0 +1,40 @@
+{
+ "name": "promise-polyfill",
+ "version": "1.0.0",
+ "homepage": "https://github.com/taylorhakes/promise-polyfill",
+ "authors": [
+ "Taylor Hakes"
+ ],
+ "description": "Lightweight promise polyfill for the browser and node. A+ Compliant.",
+ "main": "Promise.js",
+ "moduleType": [
+ "globals",
+ "node"
+ ],
+ "keywords": [
+ "promise",
+ "es6",
+ "polyfill",
+ "html5"
+ ],
+ "license": "MIT",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "polymer": "polymer/polymer#^1.0.0"
+ },
+ "_release": "1.0.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.0",
+ "commit": "2ef7dada161cae30e69ffff918485c57121d4b88"
+ },
+ "_source": "git://github.com/polymerlabs/promise-polyfill.git",
+ "_target": "^1.0.0",
+ "_originalSource": "polymerlabs/promise-polyfill"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/promise-polyfill/Gruntfile.js b/polymer_1.0.4/bower_components/promise-polyfill/Gruntfile.js
new file mode 100644
index 0000000..3138444
--- /dev/null
+++ b/polymer_1.0.4/bower_components/promise-polyfill/Gruntfile.js
@@ -0,0 +1,40 @@
+module.exports = function(grunt) {
+
+ grunt.initConfig({
+ pkg: grunt.file.readJSON('package.json'),
+
+ uglify: {
+ options: {
+ banner: '/*! <%= pkg.name %> <%= pkg.version %> */\n'
+ },
+ dist: {
+ files: {
+ 'Promise.min.uglify.js': ['Promise.js']
+ }
+ }
+ },
+
+ closurecompiler: {
+ options: {
+ compilation_level: 'ADVANCED_OPTIMIZATIONS',
+ },
+ dist: {
+ files: {
+ 'Promise.min.js': ['Promise.js']
+ }
+ }
+ },
+
+ bytesize: {
+ dist: {
+ src: ['Promise*.js']
+ }
+ }
+ });
+
+ grunt.loadNpmTasks('grunt-contrib-uglify');
+ grunt.loadNpmTasks('grunt-closurecompiler');
+ grunt.loadNpmTasks('grunt-bytesize');
+
+ grunt.registerTask('build', ['closurecompiler', 'bytesize']);
+};
diff --git a/polymer_1.0.4/bower_components/promise-polyfill/LICENSE b/polymer_1.0.4/bower_components/promise-polyfill/LICENSE
new file mode 100644
index 0000000..94b9dac
--- /dev/null
+++ b/polymer_1.0.4/bower_components/promise-polyfill/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2014 Taylor Hakes
+Copyright (c) 2014 Forbes Lindesay
+
+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.
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/promise-polyfill/Promise-Statics.js b/polymer_1.0.4/bower_components/promise-polyfill/Promise-Statics.js
new file mode 100644
index 0000000..7ce402e
--- /dev/null
+++ b/polymer_1.0.4/bower_components/promise-polyfill/Promise-Statics.js
@@ -0,0 +1,37 @@
+Promise.all = Promise.all || function () {
+ var args = Array.prototype.slice.call(arguments.length === 1 && Array.isArray(arguments[0]) ? arguments[0] : arguments);
+
+ return new Promise(function (resolve, reject) {
+ if (args.length === 0) return resolve([]);
+ var remaining = args.length;
+ function res(i, val) {
+ try {
+ if (val && (typeof val === 'object' || typeof val === 'function')) {
+ var then = val.then;
+ if (typeof then === 'function') {
+ then.call(val, function (val) { res(i, val) }, reject);
+ return;
+ }
+ }
+ args[i] = val;
+ if (--remaining === 0) {
+ resolve(args);
+ }
+ } catch (ex) {
+ reject(ex);
+ }
+ }
+ for (var i = 0; i < args.length; i++) {
+ res(i, args[i]);
+ }
+ });
+};
+
+Promise.race = Promise.race || function (values) {
+ return new Promise(function (resolve, reject) {
+ for(var i = 0, len = values.length; i < len; i++) {
+ values[i].then(resolve, reject);
+ }
+ });
+};
+
diff --git a/polymer_1.0.4/bower_components/promise-polyfill/Promise.js b/polymer_1.0.4/bower_components/promise-polyfill/Promise.js
new file mode 100644
index 0000000..dc6f58f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/promise-polyfill/Promise.js
@@ -0,0 +1,128 @@
+function MakePromise (asap) {
+ function Promise(fn) {
+ if (typeof this !== 'object' || typeof fn !== 'function') throw new TypeError();
+ this._state = null;
+ this._value = null;
+ this._deferreds = []
+
+ doResolve(fn, resolve.bind(this), reject.bind(this));
+ }
+
+ function handle(deferred) {
+ var me = this;
+ if (this._state === null) {
+ this._deferreds.push(deferred);
+ return
+ }
+ asap(function() {
+ var cb = me._state ? deferred.onFulfilled : deferred.onRejected
+ if (typeof cb !== 'function') {
+ (me._state ? deferred.resolve : deferred.reject)(me._value);
+ return;
+ }
+ var ret;
+ try {
+ ret = cb(me._value);
+ }
+ catch (e) {
+ deferred.reject(e);
+ return;
+ }
+ deferred.resolve(ret);
+ })
+ }
+
+ function resolve(newValue) {
+ try { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
+ if (newValue === this) throw new TypeError();
+ if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
+ var then = newValue.then;
+ if (typeof then === 'function') {
+ doResolve(then.bind(newValue), resolve.bind(this), reject.bind(this));
+ return;
+ }
+ }
+ this._state = true;
+ this._value = newValue;
+ finale.call(this);
+ } catch (e) { reject.call(this, e); }
+ }
+
+ function reject(newValue) {
+ this._state = false;
+ this._value = newValue;
+ finale.call(this);
+ }
+
+ function finale() {
+ for (var i = 0, len = this._deferreds.length; i < len; i++) {
+ handle.call(this, this._deferreds[i]);
+ }
+ this._deferreds = null;
+ }
+
+ /**
+ * Take a potentially misbehaving resolver function and make sure
+ * onFulfilled and onRejected are only called once.
+ *
+ * Makes no guarantees about asynchrony.
+ */
+ function doResolve(fn, onFulfilled, onRejected) {
+ var done = false;
+ try {
+ fn(function (value) {
+ if (done) return;
+ done = true;
+ onFulfilled(value);
+ }, function (reason) {
+ if (done) return;
+ done = true;
+ onRejected(reason);
+ })
+ } catch (ex) {
+ if (done) return;
+ done = true;
+ onRejected(ex);
+ }
+ }
+
+ Promise.prototype['catch'] = function (onRejected) {
+ return this.then(null, onRejected);
+ };
+
+ Promise.prototype.then = function(onFulfilled, onRejected) {
+ var me = this;
+ return new Promise(function(resolve, reject) {
+ handle.call(me, {
+ onFulfilled: onFulfilled,
+ onRejected: onRejected,
+ resolve: resolve,
+ reject: reject
+ });
+ })
+ };
+
+ Promise.resolve = function (value) {
+ if (value && typeof value === 'object' && value.constructor === Promise) {
+ return value;
+ }
+
+ return new Promise(function (resolve) {
+ resolve(value);
+ });
+ };
+
+ Promise.reject = function (value) {
+ return new Promise(function (resolve, reject) {
+ reject(value);
+ });
+ };
+
+
+ return Promise;
+}
+
+if (typeof module !== 'undefined') {
+ module.exports = MakePromise;
+}
+
diff --git a/polymer_1.0.4/bower_components/promise-polyfill/Promise.min.js b/polymer_1.0.4/bower_components/promise-polyfill/Promise.min.js
new file mode 100644
index 0000000..f37c6af
--- /dev/null
+++ b/polymer_1.0.4/bower_components/promise-polyfill/Promise.min.js
@@ -0,0 +1,3 @@
+function m(n){function b(a){if("object"!==typeof this||"function"!==typeof a)throw new TypeError;this.c=this.a=null;this.b=[];g(a,h.bind(this),d.bind(this))}function k(a){var c=this;null===this.a?this.b.push(a):n(function(){var f=c.a?a.d:a.e;if("function"!==typeof f)(c.a?a.resolve:a.reject)(c.c);else{var e;try{e=f(c.c)}catch(b){a.reject(b);return}a.resolve(e)}})}function h(a){try{if(a===this)throw new TypeError;if(a&&("object"===typeof a||"function"===typeof a)){var c=a.then;if("function"===typeof c){g(c.bind(a),
+h.bind(this),d.bind(this));return}}this.a=!0;this.c=a;l.call(this)}catch(b){d.call(this,b)}}function d(a){this.a=!1;this.c=a;l.call(this)}function l(){for(var a=0,c=this.b.length;a<c;a++)k.call(this,this.b[a]);this.b=null}function g(a,c,b){var e=!1;try{a(function(a){e||(e=!0,c(a))},function(a){e||(e=!0,b(a))})}catch(d){e||(e=!0,b(d))}}b.prototype["catch"]=function(a){return this.then(null,a)};b.prototype.then=function(a,c){var f=this;return new b(function(b,d){k.call(f,{d:a,e:c,resolve:b,reject:d})})};
+b.resolve=function(a){return a&&"object"===typeof a&&a.constructor===b?a:new b(function(b){b(a)})};b.reject=function(a){return new b(function(b,d){d(a)})};return b}"undefined"!==typeof module&&(module.f=m);
diff --git a/polymer_1.0.4/bower_components/promise-polyfill/README.md b/polymer_1.0.4/bower_components/promise-polyfill/README.md
new file mode 100644
index 0000000..de6806b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/promise-polyfill/README.md
@@ -0,0 +1,13 @@
+# Promise Polyfill
+
+Note: this is an unsolicited fork of [taylorhakes/promise-polyfill](https://github.com/taylorhakes/promise-polyfill)
+and should be considered experimental and unstable compared to upstream.
+
+## Testing
+```
+npm install
+npm test
+```
+
+## License
+MIT
diff --git a/polymer_1.0.4/bower_components/promise-polyfill/bower.json b/polymer_1.0.4/bower_components/promise-polyfill/bower.json
new file mode 100644
index 0000000..fad5964
--- /dev/null
+++ b/polymer_1.0.4/bower_components/promise-polyfill/bower.json
@@ -0,0 +1,31 @@
+{
+ "name": "promise-polyfill",
+ "version": "1.0.0",
+ "homepage": "https://github.com/taylorhakes/promise-polyfill",
+ "authors": [
+ "Taylor Hakes"
+ ],
+ "description": "Lightweight promise polyfill for the browser and node. A+ Compliant.",
+ "main": "Promise.js",
+ "moduleType": [
+ "globals",
+ "node"
+ ],
+ "keywords": [
+ "promise",
+ "es6",
+ "polyfill",
+ "html5"
+ ],
+ "license": "MIT",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "polymer": "polymer/polymer#^1.0.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/promise-polyfill/package.json b/polymer_1.0.4/bower_components/promise-polyfill/package.json
new file mode 100644
index 0000000..5360534
--- /dev/null
+++ b/polymer_1.0.4/bower_components/promise-polyfill/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "promise-polyfill",
+ "version": "2.0.0",
+ "description": "Lightweight promise polyfill. A+ compliant",
+ "main": "Promise.js",
+ "scripts": {
+ "test": "./node_modules/.bin/promises-aplus-tests tests/adapter.js; ./node_modules/.bin/promises-es6-tests tests/adapter.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://taylorhakes@github.com/taylorhakes/promise-polyfill.git"
+ },
+ "author": "Taylor Hakes",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/taylorhakes/promise-polyfill/issues"
+ },
+ "homepage": "https://github.com/taylorhakes/promise-polyfill",
+ "devDependencies": {
+ "grunt": "^0.4.5",
+ "grunt-bytesize": "^0.1.1",
+ "grunt-closurecompiler": "^0.9.9",
+ "grunt-contrib-uglify": "^0.4.0",
+ "mocha": "^2.2.1",
+ "promises-aplus-tests": "*",
+ "promises-es6-tests": "^0.5.0"
+ },
+ "keywords": [
+ "promise",
+ "promise-polyfill",
+ "ES6",
+ "promises-aplus"
+ ],
+ "dependencies": {}
+}
diff --git a/polymer_1.0.4/bower_components/promise-polyfill/promise-polyfill-lite.html b/polymer_1.0.4/bower_components/promise-polyfill/promise-polyfill-lite.html
new file mode 100644
index 0000000..87f5e75
--- /dev/null
+++ b/polymer_1.0.4/bower_components/promise-polyfill/promise-polyfill-lite.html
@@ -0,0 +1,7 @@
+<link rel="import" href="../polymer/polymer.html">
+<script src='./Promise.js'></script>
+<script>
+if (!window.Promise) {
+ window.Promise = MakePromise(Polymer.Base.async);
+}
+</script>
diff --git a/polymer_1.0.4/bower_components/promise-polyfill/promise-polyfill.html b/polymer_1.0.4/bower_components/promise-polyfill/promise-polyfill.html
new file mode 100644
index 0000000..94d2d2c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/promise-polyfill/promise-polyfill.html
@@ -0,0 +1,2 @@
+<link rel="import" href="./promise-polyfill-lite.html">
+<script src='./Promise-Statics.js'></script>
diff --git a/polymer_1.0.4/bower_components/sw-toolbox/.bower.json b/polymer_1.0.4/bower_components/sw-toolbox/.bower.json
new file mode 100644
index 0000000..3ba7ba6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/sw-toolbox/.bower.json
@@ -0,0 +1,25 @@
+{
+ "name": "sw-toolbox",
+ "main": "sw-toolbox.js",
+ "moduleType": [
+ "globals"
+ ],
+ "license": "Apache-2",
+ "ignore": [
+ "**/.*",
+ "lib",
+ "tests",
+ "gulpfile.js"
+ ],
+ "homepage": "https://github.com/GoogleChrome/sw-toolbox",
+ "version": "2.0.3",
+ "_release": "2.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v2.0.3",
+ "commit": "8763dcc9fbc9352d58f184050e2131c42f7b6d68"
+ },
+ "_source": "git://github.com/GoogleChrome/sw-toolbox.git",
+ "_target": "^2.0.2",
+ "_originalSource": "sw-toolbox"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/sw-toolbox/CONTRIBUTING.md b/polymer_1.0.4/bower_components/sw-toolbox/CONTRIBUTING.md
new file mode 100644
index 0000000..db67e3b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/sw-toolbox/CONTRIBUTING.md
@@ -0,0 +1,30 @@
+# How to become a contributor and submit your own code
+
+## Contributor License Agreements
+
+We'd love to accept your sample apps and patches! Before we can take them, we
+have to jump a couple of legal hurdles.
+
+Please fill out either the individual or corporate Contributor License Agreement
+(CLA).
+
+ * If you are an individual writing original source code and you're sure you
+ own the intellectual property, then you'll need to sign an [individual CLA]
+ (https://developers.google.com/open-source/cla/individual).
+ * If you work for a company that wants to allow you to contribute your work,
+ then you'll need to sign a [corporate CLA]
+ (https://developers.google.com/open-source/cla/corporate).
+
+Follow either of the two links above to access the appropriate CLA and
+instructions for how to sign and return it. Once we receive it, we'll be able to
+accept your pull requests.
+
+## Contributing A Patch
+
+1. Submit an issue describing your proposed change to the repo in question.
+1. The repo owner will respond to your issue promptly.
+1. If your proposed change is accepted, and you haven't already done so, sign a
+ Contributor License Agreement (see details above).
+1. Fork the desired repo, develop and test your code changes.
+1. Ensure that your code adheres to the existing style in the library.
+1. Submit a pull request.
diff --git a/polymer_1.0.4/bower_components/sw-toolbox/LICENSE b/polymer_1.0.4/bower_components/sw-toolbox/LICENSE
new file mode 100644
index 0000000..3338b3f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/sw-toolbox/LICENSE
@@ -0,0 +1,201 @@
+Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright ${copyright_attribution}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/polymer_1.0.4/bower_components/sw-toolbox/README.md b/polymer_1.0.4/bower_components/sw-toolbox/README.md
new file mode 100644
index 0000000..dd2754b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/sw-toolbox/README.md
@@ -0,0 +1,156 @@
+# Service Worker Toolbox
+
+> A collection of tools for [service workers](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/)
+
+## Service Worker helpers
+
+Service Worker Toolbox provides some simple helpers for use in creating your own service workers. If you're not sure what service workers are or what they are for, start with [the explainer doc](https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md).
+
+### Installing Service Worker Toolbox
+
+Service Worker Toolbox is available through Bower, npm or direct from github:
+
+`bower install --save sw-toolbox`
+
+`npm install --save sw-toolbox`
+
+`git clone https://github.com/GoogleChrome/sw-toolbox.git`
+
+### Registering your service worker
+
+From your registering page, register your service worker in the normal way. For example:
+
+```javascript
+navigator.serviceWorker.register('my-service-worker.js');
+```
+
+For even lower friction, if you don't intend to doing anything more fancy than just registering with a default scope, you can instead include the Service Worker Toolbox companion script in your HTML:
+
+```html
+<script src="/path/to/sw-toolbox/companion.js" data-service-worker="my-service-worker.js"></script>
+```
+
+As currently implemented in Chrome 40+, a service worker must exist at the root of the scope that you intend it to control, or higher. So if you want all of the pages under `/myapp/` to be controlled by the worker, the worker script itself must be served from either `/` or `/myapp/`. The default scope is the containing path of the service worker script.
+
+### Using Service Worker Toolbox in your worker script
+
+In your service worker you just need to use `importScripts` to load Service Worker Toolbox
+
+```javascript
+importScripts('bower_components/sw-toolbox/sw-toolbox.js'); // Update path to match your own setup
+```
+
+## Basic usage
+Within your service worker file
+```javascript
+// Set up routes from URL patterns to request handlers
+toolbox.router.get('/myapp/index.html', someHandler);
+
+// For some common cases Service Worker Toolbox provides a built-in handler
+toolbox.router.get('/', toolbox.networkFirst);
+
+// URL patterns are the same syntax as ExpressJS routes
+// (http://expressjs.com/guide/routing.html)
+toolbox.router.get(':foo/index.html', function(request, values) {
+ return new Response('Handled a request for ' + request.url +
+ ', where foo is "' + values.foo + '");
+});
+
+// For requests to other origins, specify the origin as an option
+toolbox.router.post('/(.*)', apiHandler, {origin: 'https://api.example.com'});
+
+// Provide a default handler
+toolbox.router.default = myDefaultRequestHandler;
+
+// You can provide a list of resources which will be cached at service worker install time
+toolbox.precache(['/index.html', '/site.css', '/images/logo.png']);
+```
+
+## Request handlers
+A request handler receives three arguments
+
+```javascript
+var myHandler = function(request, values, options) {
+ // ...
+}
+```
+
+- `request` - [Request](https://fetch.spec.whatwg.org/#request) object that triggered the `fetch` event
+- `values` - Object whose keys are the placeholder names in the URL pattern, with the values being the corresponding part of the request URL. For example, with a URL pattern of `'/images/:size/:name.jpg'` and an actual URL of `'/images/large/unicorns.jpg'`, `values` would be `{size: 'large', name: 'unicorns'}`
+- `options` - the options object that was used when [creating the route](#api)
+
+The return value should be a [Response](https://fetch.spec.whatwg.org/#response), or a [Promise](http://www.html5rocks.com/en/tutorials/es6/promises/) that resolves with a Response. If another value is returned, or if the returned Promise is rejected, the Request will fail which will appear to be a [NetworkError](https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-NetworkError) to the page that made the request.
+
+### Built-in handlers
+
+There are 5 built-in handlers to cover the most common network strategies. For more information about offline strategies see the [Offline Cookbook](http://jakearchibald.com/2014/offline-cookbook/).
+
+#### `toolbox.networkFirst`
+Try to handle the request by fetching from the network. If it succeeds, store the response in the cache. Otherwise, try to fulfill the request from the cache. This is the strategy to use for basic read-through caching. Also good for API requests where you always want the freshest data when it is available but would rather have stale data than no data.
+
+#### `toolbox.cacheFirst`
+If the request matches a cache entry, respond with that. Otherwise try to fetch the resource from the network. If the network request succeeds, update the cache. Good for resources that don't change, or for which you have some other update mechanism.
+
+#### `toolbox.fastest`
+Request the resource from both the cache and the network in parallel. Respond with whichever returns first. Usually this will be the cached version, if there is one. On the one hand this strategy will always make a network request, even if the resource is cached. On the other hand, if/when the network request completes the cache is updated, so that future cache reads will be more up-to-date.
+
+#### `toolbox.cacheOnly`
+Resolve the request from the cache, or fail. Good for when you need to guarantee that no network request will be made - to save battery on mobile, for example.
+
+#### `toolbox.networkOnly`
+Handle the request by trying to fetch the URL from the network. If the fetch fails, fail the request. Essentially the same as not creating a route for the URL at all.
+
+## API
+
+### Global Options
+Any method that accepts an `options` object will accept a boolean option of `debug`. When true this causes Service Worker Toolbox to output verbose log messages to the worker's console.
+
+Most methods that involve a cache (`toolbox.cache`, `toolbox.uncache`, `toolbox.fastest`, `toolbox.cacheFirst`, `toolbox.cacheOnly`, `toolbox.networkFirst`) accept an option called `cache`, which is the **name** of the [Cache](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache) that should be used. If not specifed Service Worker Toolbox will use a default cache.
+
+### `toolbox.router.get(urlPattern, handler, options)`
+### `toolbox.router.post(urlPattern, handler, options)`
+### `toolbox.router.put(urlPattern, handler, options)`
+### `toolbox.router.delete(urlPattern, handler, options)`
+### `toolbox.router.head(urlPattern, handler, options)`
+Create a route that causes requests for URLs matching `urlPattern` to be resolved by calling `handler`. Matches requests using the GET, POST, PUT, DELETE or HEAD HTTP methods respectively.
+
+- `urlPattern` - an Express style route. See the docs for the [path-to-regexp](https://github.com/pillarjs/path-to-regexp) module for the full syntax
+- `handler` - a request handler, as [described above](#request-handlers)
+- `options` - an object containing options for the route. This options object will be available to the request handler. The `origin` option is specific to the route methods, and is an exact string or a Regexp against which the origin of the Request must match for the route to be used.
+
+### `toolbox.router.any(urlPattern, handler, options)`
+Like `toolbox.router.get`, etc., but matches any HTTP method.
+
+### `toolbox.router.default`
+If you set this property to a function it will be used as the request handler for any request that does not match a route.
+
+### `toolbox.precache(arrayOfURLs)`
+Add each URL in arrayOfURLs to the list of resources that should be cached during the service worker install step. Note that this needs to be called before the install event is triggered, so you should do it on the first run of your script.
+
+### `toolbox.cache(url, options)`
+Causes the resource at `url` to be added to the cache. Returns a Promise. Supports the `debug` and `cache` [global options](#global-options).
+
+### `toolbox.uncache(url, options)`
+Causes the resource at `url` to be removed from the cache. Returns a Promise. Supports the `debug` and `cache` [global options](#global-options).
+
+## Support
+
+If you’ve found an error in this library, please file an issue: https://github.com/GoogleChrome/sw-toolbox/issues
+
+Patches are encouraged, and may be submitted by forking this project and submitting a pull request through GitHub.
+
+## License
+
+Copyright 2014 Google, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/polymer_1.0.4/bower_components/sw-toolbox/bower.json b/polymer_1.0.4/bower_components/sw-toolbox/bower.json
new file mode 100644
index 0000000..749bc55
--- /dev/null
+++ b/polymer_1.0.4/bower_components/sw-toolbox/bower.json
@@ -0,0 +1,14 @@
+{
+ "name": "sw-toolbox",
+ "main": "sw-toolbox.js",
+ "moduleType": [
+ "globals"
+ ],
+ "license": "Apache-2",
+ "ignore": [
+ "**/.*",
+ "lib",
+ "tests",
+ "gulpfile.js"
+ ]
+}
diff --git a/polymer_1.0.4/bower_components/sw-toolbox/companion.js b/polymer_1.0.4/bower_components/sw-toolbox/companion.js
new file mode 100644
index 0000000..a4dfb02
--- /dev/null
+++ b/polymer_1.0.4/bower_components/sw-toolbox/companion.js
@@ -0,0 +1,23 @@
+/*
+ Copyright 2014 Google Inc. All Rights Reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+(function() {
+ 'use strict';
+ var workerScript = document.currentScript.dataset.serviceWorker;
+
+ if (workerScript && 'serviceWorker' in navigator) {
+ navigator.serviceWorker.register(workerScript);
+ }
+})();
diff --git a/polymer_1.0.4/bower_components/sw-toolbox/package.json b/polymer_1.0.4/bower_components/sw-toolbox/package.json
new file mode 100644
index 0000000..ec471d1
--- /dev/null
+++ b/polymer_1.0.4/bower_components/sw-toolbox/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "sw-toolbox",
+ "version": "2.0.3",
+ "scripts": {
+ "test": "gulp test"
+ },
+ "repository": "https://github.com/GoogleChrome/sw-toolbox",
+ "devDependencies": {
+ "browserify": "^6.3.2",
+ "gulp": "^3.8.10",
+ "gulp-jshint": "^1.9.0",
+ "jshint-stylish": "^1.0.0",
+ "path-to-regexp": "^1.0.1",
+ "serviceworker-cache-polyfill": "coonsta/cache-polyfill",
+ "vinyl-source-stream": "^1.0.0"
+ },
+ "dependencies": {
+ "browserify-header": "^0.9.2",
+ "minifyify": "^6.4.0"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/sw-toolbox/sw-toolbox.js b/polymer_1.0.4/bower_components/sw-toolbox/sw-toolbox.js
new file mode 100644
index 0000000..9330276
--- /dev/null
+++ b/polymer_1.0.4/bower_components/sw-toolbox/sw-toolbox.js
@@ -0,0 +1,148 @@
+/*
+ Copyright 2014 Google Inc. All Rights Reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var o;"undefined"!=typeof window?o=window:"undefined"!=typeof global?o=global:"undefined"!=typeof self&&(o=self),o.toolbox=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+"use strict";function cache(e,t){return helpers.openCache(t).then(function(t){return t.add(e)})}function uncache(e,t){return helpers.openCache(t).then(function(t){return t["delete"](e)})}function precache(e){Array.isArray(e)||(e=[e]),options.preCacheItems=options.preCacheItems.concat(e)}require("serviceworker-cache-polyfill");var options=require("./options"),router=require("./router"),helpers=require("./helpers"),strategies=require("./strategies");helpers.debug("Service Worker Toolbox is loading"),self.addEventListener("install",function(e){var t=options.cacheName+"$$$inactive$$$";helpers.debug("install event fired"),helpers.debug("creating cache ["+t+"]"),helpers.debug("preCache list: "+(options.preCacheItems.join(", ")||"(none)")),e.waitUntil(helpers.openCache({cacheName:t}).then(function(e){return Promise.all(options.preCacheItems).then(e.addAll.bind(e))}))}),self.addEventListener("activate",function(e){helpers.debug("activate event fired");var t=options.cacheName+"$$$inactive$$$";e.waitUntil(helpers.renameCache(t,options.cacheName))}),self.addEventListener("fetch",function(e){var t=router.match(e.request);t?e.respondWith(t(e.request)):router["default"]&&e.respondWith(router["default"](e.request))}),module.exports={networkOnly:strategies.networkOnly,networkFirst:strategies.networkFirst,cacheOnly:strategies.cacheOnly,cacheFirst:strategies.cacheFirst,fastest:strategies.fastest,router:router,options:options,cache:cache,uncache:uncache,precache:precache};
+},{"./helpers":2,"./options":3,"./router":5,"./strategies":9,"serviceworker-cache-polyfill":14}],2:[function(require,module,exports){
+"use strict";function debug(e,n){n=n||{};var c=n.debug||globalOptions.debug;c&&console.log("[sw-toolbox] "+e)}function openCache(e){e=e||{};var n=e.cacheName||globalOptions.cacheName;return debug('Opening cache "'+n+'"',e),caches.open(n)}function fetchAndCache(e,n){n=n||{};var c=n.successResponses||globalOptions.successResponses;return fetch(e.clone()).then(function(t){return"GET"===e.method&&c.test(t.status)&&openCache(n).then(function(n){n.put(e,t)}),t.clone()})}function renameCache(e,n,c){return debug("Renaming cache: ["+e+"] to ["+n+"]",c),caches["delete"](n).then(function(){return Promise.all([caches.open(e),caches.open(n)]).then(function(n){var c=n[0],t=n[1];return c.keys().then(function(e){return Promise.all(e.map(function(e){return c.match(e).then(function(n){return t.put(e,n)})}))}).then(function(){return caches["delete"](e)})})})}var globalOptions=require("./options");module.exports={debug:debug,fetchAndCache:fetchAndCache,openCache:openCache,renameCache:renameCache};
+},{"./options":3}],3:[function(require,module,exports){
+"use strict";var scope;scope=self.registration?self.registration.scope:self.scope||new URL("./",self.location).href,module.exports={cacheName:"$$$toolbox-cache$$$"+scope+"$$$",debug:!1,preCacheItems:[],successResponses:/^0|([123]\d\d)|(40[14567])|410$/};
+},{}],4:[function(require,module,exports){
+"use strict";var url=new URL("./",self.location),basePath=url.pathname,pathRegexp=require("path-to-regexp"),Route=function(e,t,i,s){0!==t.indexOf("/")&&(t=basePath+t),this.method=e,this.keys=[],this.regexp=pathRegexp(t,this.keys),this.options=s,this.handler=i};Route.prototype.makeHandler=function(e){var t=this.regexp.exec(e),i={};return this.keys.forEach(function(e,s){i[e.name]=t[s+1]}),function(e){return this.handler(e,i,this.options)}.bind(this)},module.exports=Route;
+},{"path-to-regexp":12}],5:[function(require,module,exports){
+/*
+ Copyright 2014 Google Inc. All Rights Reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+'use strict';
+
+var Route = require('./route');
+
+function regexEscape(s) {
+ return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
+}
+
+var keyMatch = function(map, string) {
+ for (var item of map) {
+ var pattern = new RegExp(item[0]), value = item[1];
+ if (pattern.test(string)) {
+ return value;
+ }
+ }
+ return null;
+};
+
+var Router = function() {
+ this.routes = new Map();
+ this.default = null;
+};
+
+['get', 'post', 'put', 'delete', 'head', 'any'].forEach(function(method) {
+ Router.prototype[method] = function(path, handler, options) {
+ return this.add(method, path, handler, options);
+ };
+});
+
+Router.prototype.add = function(method, path, handler, options) {
+ options = options || {};
+ var origin = options.origin || self.location.origin;
+ if (origin instanceof RegExp) {
+ origin = origin.source;
+ } else {
+ origin = regexEscape(origin);
+ }
+ method = method.toLowerCase();
+
+ var route = new Route(method, path, handler, options);
+
+ if (!this.routes.has(origin)) {
+ this.routes.set(origin, new Map());
+ }
+
+ var methodMap = this.routes.get(origin);
+ if (!methodMap.has(method)) {
+ methodMap.set(method, new Map());
+ }
+
+ var routeMap = methodMap.get(method);
+ routeMap.set(route.regexp.source, route);
+};
+
+Router.prototype.matchMethod = function(method, url) {
+ url = new URL(url);
+ var origin = url.origin;
+ var path = url.pathname;
+ method = method.toLowerCase();
+
+ var methods = keyMatch(this.routes, origin);
+ if (!methods) {
+ return null;
+ }
+
+ var routes = methods.get(method);
+ if (!routes) {
+ return null;
+ }
+
+ var route = keyMatch(routes, path);
+
+ if (route) {
+ return route.makeHandler(path);
+ }
+
+ return null;
+};
+
+Router.prototype.match = function(request) {
+ return this.matchMethod(request.method, request.url) || this.matchMethod('any', request.url);
+};
+
+module.exports = new Router();
+
+},{"./route":4}],6:[function(require,module,exports){
+"use strict";function cacheFirst(e,r,t){return helpers.debug("Strategy: cache first ["+e.url+"]",t),helpers.openCache(t).then(function(r){return r.match(e).then(function(r){return r?r:helpers.fetchAndCache(e,t)})})}var helpers=require("../helpers");module.exports=cacheFirst;
+},{"../helpers":2}],7:[function(require,module,exports){
+"use strict";function cacheOnly(e,r,c){return helpers.debug("Strategy: cache only ["+e.url+"]",c),helpers.openCache(c).then(function(r){return r.match(e)})}var helpers=require("../helpers");module.exports=cacheOnly;
+},{"../helpers":2}],8:[function(require,module,exports){
+"use strict";function fastest(e,r,t){helpers.debug("Strategy: fastest ["+e.url+"]",t);var n=!1,c=[],s=function(e){return c.push(e.toString()),n?Promise.reject(new Error('Both cache and network failed: "'+c.join('", "')+'"')):void(n=!0)};return new Promise(function(r,n){helpers.fetchAndCache(e.clone(),t).then(r,s),cacheOnly(e,t).then(r,s)})}var helpers=require("../helpers"),cacheOnly=require("./cacheOnly");module.exports=fastest;
+},{"../helpers":2,"./cacheOnly":7}],9:[function(require,module,exports){
+module.exports={networkOnly:require("./networkOnly"),networkFirst:require("./networkFirst"),cacheOnly:require("./cacheOnly"),cacheFirst:require("./cacheFirst"),fastest:require("./fastest")};
+},{"./cacheFirst":6,"./cacheOnly":7,"./fastest":8,"./networkFirst":10,"./networkOnly":11}],10:[function(require,module,exports){
+"use strict";function networkFirst(e,r,s){s=s||{};var t=s.successResponses||globalOptions.successResponses;return helpers.debug("Strategy: network first ["+e.url+"]",s),helpers.openCache(s).then(function(r){return helpers.fetchAndCache(e,s).then(function(n){return t.test(n.status)?n:r.match(e).then(function(e){return helpers.debug("Response was an HTTP error",s),e?(helpers.debug("Resolving with cached response instead",s),e):(helpers.debug("No cached result, resolving with HTTP error response from network",s),n)})})["catch"](function(t){return helpers.debug("Network error, fallback to cache ["+e.url+"]",s),r.match(e)})})}var globalOptions=require("../options"),helpers=require("../helpers");module.exports=networkFirst;
+},{"../helpers":2,"../options":3}],11:[function(require,module,exports){
+"use strict";function networkOnly(e,r,t){return helpers.debug("Strategy: network only ["+e.url+"]",t),fetch(e)}var helpers=require("../helpers");module.exports=networkOnly;
+},{"../helpers":2}],12:[function(require,module,exports){
+function parse(e){for(var t,r=[],n=0,o=0,p="";null!=(t=PATH_REGEXP.exec(e));){var a=t[0],i=t[1],s=t.index;if(p+=e.slice(o,s),o=s+a.length,i)p+=i[1];else{p&&(r.push(p),p="");var u=t[2],c=t[3],l=t[4],f=t[5],g=t[6],x=t[7],h="+"===g||"*"===g,m="?"===g||"*"===g,y=u||"/",T=l||f||(x?".*":"[^"+y+"]+?");r.push({name:c||n++,prefix:u||"",delimiter:y,optional:m,repeat:h,pattern:escapeGroup(T)})}}return o<e.length&&(p+=e.substr(o)),p&&r.push(p),r}function compile(e){return tokensToFunction(parse(e))}function tokensToFunction(e){for(var t=new Array(e.length),r=0;r<e.length;r++)"object"==typeof e[r]&&(t[r]=new RegExp("^"+e[r].pattern+"$"));return function(r){var n="";r=r||{};for(var o=0;o<e.length;o++){var p=e[o];if("string"!=typeof p){var a=r[p.name];if(null==a){if(p.optional)continue;throw new TypeError('Expected "'+p.name+'" to be defined')}if(isarray(a)){if(!p.repeat)throw new TypeError('Expected "'+p.name+'" to not repeat');if(0===a.length){if(p.optional)continue;throw new TypeError('Expected "'+p.name+'" to not be empty')}for(var i=0;i<a.length;i++){if(!t[o].test(a[i]))throw new TypeError('Expected all "'+p.name+'" to match "'+p.pattern+'"');n+=(0===i?p.prefix:p.delimiter)+encodeURIComponent(a[i])}}else{if(!t[o].test(a))throw new TypeError('Expected "'+p.name+'" to match "'+p.pattern+'"');n+=p.prefix+encodeURIComponent(a)}}else n+=p}return n}}function escapeString(e){return e.replace(/([.+*?=^!:${}()[\]|\/])/g,"\\$1")}function escapeGroup(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function attachKeys(e,t){return e.keys=t,e}function flags(e){return e.sensitive?"":"i"}function regexpToRegexp(e,t){var r=e.source.match(/\((?!\?)/g);if(r)for(var n=0;n<r.length;n++)t.push({name:n,prefix:null,delimiter:null,optional:!1,repeat:!1,pattern:null});return attachKeys(e,t)}function arrayToRegexp(e,t,r){for(var n=[],o=0;o<e.length;o++)n.push(pathToRegexp(e[o],t,r).source);var p=new RegExp("(?:"+n.join("|")+")",flags(r));return attachKeys(p,t)}function stringToRegexp(e,t,r){for(var n=parse(e),o=tokensToRegExp(n,r),p=0;p<n.length;p++)"string"!=typeof n[p]&&t.push(n[p]);return attachKeys(o,t)}function tokensToRegExp(e,t){t=t||{};for(var r=t.strict,n=t.end!==!1,o="",p=e[e.length-1],a="string"==typeof p&&/\/$/.test(p),i=0;i<e.length;i++){var s=e[i];if("string"==typeof s)o+=escapeString(s);else{var u=escapeString(s.prefix),c=s.pattern;s.repeat&&(c+="(?:"+u+c+")*"),c=s.optional?u?"(?:"+u+"("+c+"))?":"("+c+")?":u+"("+c+")",o+=c}}return r||(o=(a?o.slice(0,-2):o)+"(?:\\/(?=$))?"),o+=n?"$":r&&a?"":"(?=\\/|$)",new RegExp("^"+o,flags(t))}function pathToRegexp(e,t,r){return t=t||[],isarray(t)?r||(r={}):(r=t,t=[]),e instanceof RegExp?regexpToRegexp(e,t,r):isarray(e)?arrayToRegexp(e,t,r):stringToRegexp(e,t,r)}var isarray=require("isarray");module.exports=pathToRegexp,module.exports.parse=parse,module.exports.compile=compile,module.exports.tokensToFunction=tokensToFunction,module.exports.tokensToRegExp=tokensToRegExp;var PATH_REGEXP=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^()])+)\\))?|\\(((?:\\\\.|[^()])+)\\))([+*?])?|(\\*))"].join("|"),"g");
+},{"isarray":13}],13:[function(require,module,exports){
+module.exports=Array.isArray||function(r){return"[object Array]"==Object.prototype.toString.call(r)};
+},{}],14:[function(require,module,exports){
+Cache.prototype.add||(Cache.prototype.add=function(t){return this.addAll([t])}),Cache.prototype.addAll||(Cache.prototype.addAll=function(t){function e(t){this.name="NetworkError",this.code=19,this.message=t}var r=this;return e.prototype=Object.create(Error.prototype),Promise.resolve().then(function(){if(arguments.length<1)throw new TypeError;return t=t.map(function(t){return t instanceof Request?t:String(t)}),Promise.all(t.map(function(t){"string"==typeof t&&(t=new Request(t));var r=new URL(t.url).protocol;if("http:"!==r&&"https:"!==r)throw new e("Invalid scheme");return fetch(t.clone())}))}).then(function(e){return Promise.all(e.map(function(e,n){return r.put(t[n],e)}))}).then(function(){return void 0})});
+},{}]},{},[1])(1)
+});
+
+
+//# sourceMappingURL=sw-toolbox.map.json
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/sw-toolbox/sw-toolbox.map.json b/polymer_1.0.4/bower_components/sw-toolbox/sw-toolbox.map.json
new file mode 100644
index 0000000..503061c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/sw-toolbox/sw-toolbox.map.json
@@ -0,0 +1 @@
+{"version":3,"sources":["node_modules/browserify/node_modules/browser-pack/_prelude.js","lib/router.js","lib/sw-toolbox.js","lib/helpers.js","lib/options.js","lib/strategies/index.js","lib/route.js","lib/strategies/networkOnly.js","lib/strategies/networkFirst.js","lib/strategies/cacheOnly.js","lib/strategies/cacheFirst.js","lib/strategies/fastest.js","node_modules/serviceworker-cache-polyfill/index.js","node_modules/path-to-regexp/index.js","node_modules/path-to-regexp/node_modules/isarray/index.js"],"names":["cache","url","options","helpers","openCache","then","add","uncache","precache","items","Array","isArray","preCacheItems","concat","require","router","strategies","debug","self","addEventListener","event","inactiveCache","cacheName","join","waitUntil","Promise","all","addAll","bind","renameCache","handler","match","request","respondWith","module","exports","networkOnly","networkFirst","cacheOnly","cacheFirst","fastest","message","flag","globalOptions","console","log","caches","open","fetchAndCache","successResponses","fetch","clone","response","method","test","status","put","source","destination","results","sourceCache","destCache","keys","requests","map","scope","registration","URL","location","href","basePath","pathname","pathRegexp","Route","path","indexOf","this","regexp","prototype","makeHandler","exec","values","forEach","key","index","name","cacheResponse","error","rejected","reasons","maybeReject","reason","push","toString","reject","Error","resolve","Cache","NetworkError","code","Object","create","arguments","length","TypeError","Request","String","scheme","protocol","responses","i","undefined","parse","str","res","tokens","PATH_REGEXP","m","escaped","offset","slice","prefix","capture","group","suffix","asterisk","repeat","optional","delimiter","pattern","escapeGroup","substr","compile","tokensToFunction","matches","RegExp","obj","value","isarray","j","encodeURIComponent","escapeString","replace","attachKeys","re","flags","sensitive","regexpToRegexp","groups","arrayToRegexp","parts","pathToRegexp","stringToRegexp","tokensToRegExp","strict","end","route","lastToken","endsWithSlash","token","arr","call"],"mappings":"AAAA;AEeA,YA8CA,SAASA,OAAMC,EAAKC,GAClB,MAAOC,SAAQC,UAAUF,GAASG,KAAK,SAASL,GAC9C,MAAOA,GAAMM,IAAIL,KAIrB,QAASM,SAAQN,EAAKC,GACpB,MAAOC,SAAQC,UAAUF,GAASG,KAAK,SAASL,GAC9C,MAAOA,GAAAA,UAAaC,KAIxB,QAASO,UAASC,GACXC,MAAMC,QAAQF,KACjBA,GAASA,IAEXP,QAAQU,cAAgBV,QAAQU,cAAcC,OAAOJ,GA5DvDK,QAAQ,+BACR,IAAIZ,SAAUY,QAAQ,aAClBC,OAASD,QAAQ,YACjBX,QAAUW,QAAQ,aAClBE,WAAaF,QAAQ,eAEzBX,SAAQc,MAAM,qCAIdC,KAAKC,iBAAiB,UAAW,SAASC,GACxC,GAAIC,GAAgBnB,QAAQoB,UAAY,gBACxCnB,SAAQc,MAAM,uBACdd,QAAQc,MAAM,mBAAqBI,EAAgB,KACnDlB,QAAQc,MAAM,mBAAqBf,QAAQU,cAAcW,KAAK,OAAS,WACvEH,EAAMI,UACJrB,QAAQC,WAAWkB,UAAWD,IAAgBhB,KAAK,SAASL,GAC1D,MAAOyB,SAAQC,IAAIxB,QAAQU,eAAeP,KAAKL,EAAM2B,OAAOC,KAAK5B,SAOvEkB,KAAKC,iBAAiB,WAAY,SAASC,GACzCjB,QAAQc,MAAM,uBACd,IAAII,GAAgBnB,QAAQoB,UAAY,gBACxCF,GAAMI,UAAUrB,QAAQ0B,YAAYR,EAAenB,QAAQoB,cAK7DJ,KAAKC,iBAAiB,QAAS,SAASC,GACtC,GAAIU,GAAUf,OAAOgB,MAAMX,EAAMY,QAE7BF,GACFV,EAAMa,YAAYH,EAAQV,EAAMY,UACvBjB,OAAAA,YACTK,EAAMa,YAAYlB,OAAAA,WAAeK,EAAMY,YAyB3CE,OAAOC,SACLC,YAAapB,WAAWoB,YACxBC,aAAcrB,WAAWqB,aACzBC,UAAWtB,WAAWsB,UACtBC,WAAYvB,WAAWuB,WACvBC,QAASxB,WAAWwB,QACpBzB,OAAQA,OACRb,QAASA,QACTF,MAAOA,MACPO,QAASA,QACTC,SAAUA;;AC3EZ,YAIA,SAASS,OAAMwB,EAASvC,GACtBA,EAAUA,KACV,IAAIwC,GAAOxC,EAAQe,OAAS0B,cAAc1B,KACtCyB,IACFE,QAAQC,IAAI,gBAAkBJ,GAIlC,QAASrC,WAAUF,GACjBA,EAAUA,KACV,IAAIoB,GAAYpB,EAAQoB,WAAaqB,cAAcrB,SAEnD,OADAL,OAAM,kBAAoBK,EAAY,IAAKpB,GACpC4C,OAAOC,KAAKzB,GAGrB,QAAS0B,eAAchB,EAAS9B,GAC9BA,EAAUA,KACV,IAAI+C,GAAmB/C,EAAQ+C,kBAAoBN,cAAcM,gBACjE,OAAOC,OAAMlB,EAAQmB,SAAS9C,KAAK,SAAS+C,GAS1C,MANuB,QAAnBpB,EAAQqB,QAAoBJ,EAAiBK,KAAKF,EAASG,SAC7DnD,UAAUF,GAASG,KAAK,SAASL,GAC/BA,EAAMwD,IAAIxB,EAASoB,KAIhBA,EAASD,UAIpB,QAAStB,aAAY4B,EAAQC,EAAaxD,GAExC,MADAe,OAAM,oBAAsBwC,EAAS,SAAWC,EAAc,IAAKxD,GAC5D4C,OAAAA,UAAcY,GAAarD,KAAK,WACrC,MAAOoB,SAAQC,KACboB,OAAOC,KAAKU,GACZX,OAAOC,KAAKW,KACXrD,KAAK,SAASsD,GACf,GAAIC,GAAcD,EAAQ,GACtBE,EAAYF,EAAQ,EAExB,OAAOC,GAAYE,OAAOzD,KAAK,SAAS0D,GACtC,MAAOtC,SAAQC,IAAIqC,EAASC,IAAI,SAAShC,GACvC,MAAO4B,GAAY7B,MAAMC,GAAS3B,KAAK,SAAS+C,GAC9C,MAAOS,GAAUL,IAAIxB,EAASoB,UAGjC/C,KAAK,WACN,MAAOyC,QAAAA,UAAcW,SAlD7B,GAAId,eAAgB7B,QAAQ,YAwD5BoB,QAAOC,SACLlB,MAAOA,MACP+B,cAAeA,cACf5C,UAAWA,UACXyB,YAAaA;;AC9Df,YAIA,IAAIoC,MAEFA,OADE/C,KAAKgD,aACChD,KAAKgD,aAAaD,MAElB/C,KAAK+C,OAAS,GAAIE,KAAI,KAAMjD,KAAKkD,UAAUC,KAGrDnC,OAAOC,SACNb,UAAW,sBAAwB2C,MAAQ,MAC3ChD,OAAO,EACPL,iBAIAqC,iBAAkB;;AElBnB,YAGA,IAAIhD,KAAM,GAAIkE,KAAI,KAAMjD,KAAKkD,UACzBE,SAAWrE,IAAIsE,SACfC,WAAa1D,QAAQ,kBAGrB2D,MAAQ,SAASpB,EAAQqB,EAAM5C,EAAS5B,GAMhB,IAAtBwE,EAAKC,QAAQ,OACfD,EAAOJ,SAAWI,GAGpBE,KAAKvB,OAASA,EACduB,KAAKd,QACLc,KAAKC,OAASL,WAAWE,EAAME,KAAKd,MACpCc,KAAK1E,QAAUA,EACf0E,KAAK9C,QAAUA,EAGjB2C,OAAMK,UAAUC,YAAc,SAAS9E,GACrC,GAAI8B,GAAQ6C,KAAKC,OAAOG,KAAK/E,GACzBgF,IAIJ,OAHAL,MAAKd,KAAKoB,QAAQ,SAASC,EAAKC,GAC9BH,EAAOE,EAAIE,MAAQtD,EAAMqD,EAAQ,KAE5B,SAASpD,GACd,MAAO4C,MAAK9C,QAAQE,EAASiD,EAAQL,KAAK1E,UAC1C0B,KAAKgD,OAGT1C,OAAOC,QAAUsC;;ALnDjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ASpFA,YAGA,SAASlC,YAAWP,EAASiD,EAAQ/E,GAEnC,MADAC,SAAQc,MAAM,0BAA4Be,EAAQ/B,IAAM,IAAKC,GACtDC,QAAQC,UAAUF,GAASG,KAAK,SAASL,GAC9C,MAAOA,GAAM+B,MAAMC,GAAS3B,KAAK,SAAU+C,GACzC,MAAIA,GACKA,EAGFjD,QAAQ6C,cAAchB,EAAS9B,OAV5C,GAAIC,SAAUW,QAAQ,aAetBoB,QAAOC,QAAUI;;ADhBjB,YAGA,SAASD,WAAUN,EAASiD,EAAQ/E,GAElC,MADAC,SAAQc,MAAM,yBAA2Be,EAAQ/B,IAAM,IAAKC,GACrDC,QAAQC,UAAUF,GAASG,KAAK,SAASL,GAC9C,MAAOA,GAAM+B,MAAMC,KALvB,GAAI7B,SAAUW,QAAQ,aAStBoB,QAAOC,QAAUG;;AEVjB,YAIA,SAASE,SAAQR,EAASiD,EAAQ/E,GAChCC,QAAQc,MAAM,sBAAwBe,EAAQ/B,IAAM,IAAKC,EACzD,IAAIsF,IAAW,EACXC,KAEAC,EAAc,SAASC,GAEzB,MADAF,GAAQG,KAAKD,EAAOE,YAChBL,EACK/D,QAAQqE,OAAO,GAAIC,OAAM,mCAAqCN,EAAQlE,KAAK,QAAU,WAE9FiE,GAAW,GAGb,OAAO,IAAI/D,SAAQ,SAASuE,EAASF,GACnC3F,QAAQ6C,cAAchB,EAAQmB,QAASjD,GAASG,KAAK2F,EAASN,GAC9DpD,UAAUN,EAAS9B,GAASG,KAAK2F,EAASN,KAlB9C,GAAIvF,SAAUW,QAAQ,cAClBwB,UAAYxB,QAAQ,cAqBxBoB,QAAOC,QAAUK;;ANvBjBN,OAAOC,SACLC,YAAatB,QAAQ,iBACrBuB,aAAcvB,QAAQ,kBACtBwB,UAAWxB,QAAQ,eACnByB,WAAYzB,QAAQ,gBACpB0B,QAAS1B,QAAQ;;AGLnB,YAIA,SAASuB,cAAaL,EAASiD,EAAQ/E,GACrCA,EAAUA,KACV,IAAI+C,GAAmB/C,EAAQ+C,kBAAoBN,cAAcM,gBAEjE,OADA9C,SAAQc,MAAM,4BAA8Be,EAAQ/B,IAAM,IAAKC,GACxDC,QAAQC,UAAUF,GAASG,KAAK,SAASL,GAC9C,MAAOG,SAAQ6C,cAAchB,EAAS9B,GAASG,KAAK,SAAS+C,GAC3D,MAAIH,GAAiBK,KAAKF,EAASG,QAC1BH,EAGFpD,EAAM+B,MAAMC,GAAS3B,KAAK,SAASiF,GAExC,MADAnF,SAAQc,MAAM,6BAA8Bf,GACxCoF,GACFnF,QAAQc,MAAM,yCAA0Cf,GACjDoF,IAIPnF,QAAQc,MAAM,oEAAqEf,GAC5EkD,OAdNjD,SAiBE,SAASoF,GAEhB,MADApF,SAAQc,MAAM,qCAAuCe,EAAQ/B,IAAM,IAAKC,GACjEF,EAAM+B,MAAMC,OA3BzB,GAAIW,eAAgB7B,QAAQ,cACxBX,QAAUW,QAAQ,aA+BtBoB,QAAOC,QAAUE;;ADjCjB,YAGA,SAASD,aAAYJ,EAASiD,EAAQ/E,GAEpC,MADAC,SAAQc,MAAM,2BAA6Be,EAAQ/B,IAAM,IAAKC,GACvDgD,MAAMlB,GAJf,GAAI7B,SAAUW,QAAQ,aAOtBoB,QAAOC,QAAUC;;AMYjB,QAAS4E,OAAOC,GAOd,IANA,GAIIC,GAJAC,KACAhC,EAAM,EACNC,EAAQ,EACRV,EAAO,GAG6B,OAAhCwC,EAAME,YAAYpC,KAAKiC,KAAe,CAC5C,GAAII,GAAIH,EAAI,GACRI,EAAUJ,EAAI,GACdK,EAASL,EAAI9B,KAKjB,IAJAV,GAAQuC,EAAIO,MAAMpC,EAAOmC,GACzBnC,EAAQmC,EAASF,EAAEd,OAGfe,EACF5C,GAAQ4C,EAAQ,OADlB,CAMI5C,IACFyC,EAAOvB,KAAKlB,GACZA,EAAO,GAGT,IAAI+C,GAASP,EAAI,GACb7B,EAAO6B,EAAI,GACXQ,EAAUR,EAAI,GACdS,EAAQT,EAAI,GACZU,EAASV,EAAI,GACbW,EAAWX,EAAI,GAEfY,EAAoB,MAAXF,GAA6B,MAAXA,EAC3BG,EAAsB,MAAXH,GAA6B,MAAXA,EAC7BI,EAAYP,GAAU,IACtBQ,EAAUP,GAAWC,IAAUE,EAAW,KAAO,KAAOG,EAAY,MAExEb,GAAOvB,MACLP,KAAMA,GAAQF,IACdsC,OAAQA,GAAU,GAClBO,UAAWA,EACXD,SAAUA,EACVD,OAAQA,EACRG,QAASC,YAAYD,MAczB,MATI7C,GAAQ6B,EAAIV,SACd7B,GAAQuC,EAAIkB,OAAO/C,IAIjBV,GACFyC,EAAOvB,KAAKlB,GAGPyC,EAST,QAASiB,SAASnB,GAChB,MAAOoB,kBAAiBrB,MAAMC,IAMhC,QAASoB,kBAAkBlB,GAKzB,IAAK,GAHDmB,GAAU,GAAI5H,OAAMyG,EAAOZ,QAGtBO,EAAI,EAAGA,EAAIK,EAAOZ,OAAQO,IACR,gBAAdK,GAAOL,KAChBwB,EAAQxB,GAAK,GAAIyB,QAAO,IAAMpB,EAAOL,GAAGmB,QAAU,KAItD,OAAO,UAAUO,GACf,GAAI9D,GAAO,EAEX8D,GAAMA,KAEN,KAAK,GAAI1B,GAAI,EAAGA,EAAIK,EAAOZ,OAAQO,IAAK,CACtC,GAAI3B,GAAMgC,EAAOL,EAEjB,IAAmB,gBAAR3B,GAAX,CAMA,GAAIsD,GAAQD,EAAIrD,EAAIE,KAEpB,IAAa,MAAToD,EAAe,CACjB,GAAItD,EAAI4C,SACN,QAEA,MAAM,IAAIvB,WAAU,aAAerB,EAAIE,KAAO,mBAIlD,GAAIqD,QAAQD,GAAZ,CACE,IAAKtD,EAAI2C,OACP,KAAM,IAAItB,WAAU,aAAerB,EAAIE,KAAO,kBAGhD,IAAqB,IAAjBoD,EAAMlC,OAAc,CACtB,GAAIpB,EAAI4C,SACN,QAEA,MAAM,IAAIvB,WAAU,aAAerB,EAAIE,KAAO,qBAIlD,IAAK,GAAIsD,GAAI,EAAGA,EAAIF,EAAMlC,OAAQoC,IAAK,CACrC,IAAKL,EAAQxB,GAAGxD,KAAKmF,EAAME,IACzB,KAAM,IAAInC,WAAU,iBAAmBrB,EAAIE,KAAO,eAAiBF,EAAI8C,QAAU,IAGnFvD,KAAe,IAANiE,EAAUxD,EAAIsC,OAAStC,EAAI6C,WAAaY,mBAAmBH,EAAME,SAlB9E,CAwBA,IAAKL,EAAQxB,GAAGxD,KAAKmF,GACnB,KAAM,IAAIjC,WAAU,aAAerB,EAAIE,KAAO,eAAiBF,EAAI8C,QAAU,IAG/EvD,IAAQS,EAAIsC,OAASmB,mBAAmBH,QA3CtC/D,IAAQS,EA8CZ,MAAOT,IAUX,QAASmE,cAAc5B,GACrB,MAAOA,GAAI6B,QAAQ,2BAA4B,QASjD,QAASZ,aAAaP,GACpB,MAAOA,GAAMmB,QAAQ,gBAAiB,QAUxC,QAASC,YAAYC,EAAIlF,GAEvB,MADAkF,GAAGlF,KAAOA,EACHkF,EAST,QAASC,OAAO/I,GACd,MAAOA,GAAQgJ,UAAY,GAAK,IAUlC,QAASC,gBAAgBzE,EAAMZ,GAE7B,GAAIsF,GAAS1E,EAAKjB,OAAO1B,MAAM,YAE/B,IAAIqH,EACF,IAAK,GAAItC,GAAI,EAAGA,EAAIsC,EAAO7C,OAAQO,IACjChD,EAAK8B,MACHP,KAAMyB,EACNW,OAAQ,KACRO,UAAW,KACXD,UAAU,EACVD,QAAQ,EACRG,QAAS,MAKf,OAAOc,YAAWrE,EAAMZ,GAW1B,QAASuF,eAAe3E,EAAMZ,EAAM5D,GAGlC,IAAK,GAFDoJ,MAEKxC,EAAI,EAAGA,EAAIpC,EAAK6B,OAAQO,IAC/BwC,EAAM1D,KAAK2D,aAAa7E,EAAKoC,GAAIhD,EAAM5D,GAASuD,OAGlD,IAAIoB,GAAS,GAAI0D,QAAO,MAAQe,EAAM/H,KAAK,KAAO,IAAK0H,MAAM/I,GAE7D,OAAO6I,YAAWlE,EAAQf,GAW5B,QAAS0F,gBAAgB9E,EAAMZ,EAAM5D,GAKnC,IAAK,GAJDiH,GAASH,MAAMtC,GACfsE,EAAKS,eAAetC,EAAQjH,GAGvB4G,EAAI,EAAGA,EAAIK,EAAOZ,OAAQO,IACR,gBAAdK,GAAOL,IAChBhD,EAAK8B,KAAKuB,EAAOL,GAIrB,OAAOiC,YAAWC,EAAIlF,GAWxB,QAAS2F,gBAAgBtC,EAAQjH,GAC/BA,EAAUA,KASV,KAAK,GAPDwJ,GAASxJ,EAAQwJ,OACjBC,EAAMzJ,EAAQyJ,OAAQ,EACtBC,EAAQ,GACRC,EAAY1C,EAAOA,EAAOZ,OAAS,GACnCuD,EAAqC,gBAAdD,IAA0B,MAAMvG,KAAKuG,GAGvD/C,EAAI,EAAGA,EAAIK,EAAOZ,OAAQO,IAAK,CACtC,GAAIiD,GAAQ5C,EAAOL,EAEnB,IAAqB,gBAAViD,GACTH,GAASf,aAAakB,OACjB,CACL,GAAItC,GAASoB,aAAakB,EAAMtC,QAC5BC,EAAUqC,EAAM9B,OAEhB8B,GAAMjC,SACRJ,GAAW,MAAQD,EAASC,EAAU,MAKpCA,EAFAqC,EAAMhC,SACJN,EACQ,MAAQA,EAAS,IAAMC,EAAU,MAEjC,IAAMA,EAAU,KAGlBD,EAAS,IAAMC,EAAU,IAGrCkC,GAASlC,GAoBb,MAZKgC,KACHE,GAASE,EAAgBF,EAAMpC,MAAM,EAAG,IAAMoC,GAAS,iBAIvDA,GADED,EACO,IAIAD,GAAUI,EAAgB,GAAK,YAGnC,GAAIvB,QAAO,IAAMqB,EAAOX,MAAM/I,IAevC,QAASqJ,cAAc7E,EAAMZ,EAAM5D,GAUjC,MATA4D,GAAOA,MAEF4E,QAAQ5E,GAGD5D,IACVA,OAHAA,EAAU4D,EACVA,MAKEY,YAAgB6D,QACXY,eAAezE,EAAMZ,EAAM5D,GAGhCwI,QAAQhE,GACH2E,cAAc3E,EAAMZ,EAAM5D,GAG5BsJ,eAAe9E,EAAMZ,EAAM5D,GAhYpC,GAAIwI,SAAU5H,QAAQ,UAKtBoB,QAAOC,QAAUoH,aACjBrH,OAAOC,QAAQ6E,MAAQA,MACvB9E,OAAOC,QAAQiG,QAAUA,QACzBlG,OAAOC,QAAQkG,iBAAmBA,iBAClCnG,OAAOC,QAAQsH,eAAiBA,cAOhC,IAAIrC,aAAc,GAAImB,SAGpB,UAOA,kGACAhH,KAAK,KAAM;;AC3BbW,OAAOC,QAAUzB,MAAMC,SAAW,SAAUqJ,GAC1C,MAA8C,kBAAvC5D,OAAOtB,UAAUe,SAASoE,KAAKD;;AFDnC/D,MAAMnB,UAAUxE,MACnB2F,MAAMnB,UAAUxE,IAAM,SAAa0B,GACjC,MAAO4C,MAAKjD,QAAQK,MAInBiE,MAAMnB,UAAUnD,SACnBsE,MAAMnB,UAAUnD,OAAS,SAAgBoC,GAIvC,QAASmC,GAAazD,GACpBmC,KAAKS,KAAO,eACZT,KAAKuB,KAAO,GACZvB,KAAKnC,QAAUA,EANjB,GAAIzC,GAAQ4E,IAUZ,OAFAsB,GAAapB,UAAYsB,OAAOC,OAAON,MAAMjB,WAEtCrD,QAAQuE,UAAU3F,KAAK,WAC5B,GAAIiG,UAAUC,OAAS,EAAG,KAAM,IAAIC,UAcpC,OATAzC,GAAWA,EAASC,IAAI,SAAShC,GAC/B,MAAIA,aAAmByE,SACdzE,EAGA0E,OAAO1E,KAIXP,QAAQC,IACbqC,EAASC,IAAI,SAAShC,GACG,gBAAZA,KACTA,EAAU,GAAIyE,SAAQzE,GAGxB,IAAI2E,GAAS,GAAIxC,KAAInC,EAAQ/B,KAAK2G,QAElC,IAAe,UAAXD,GAAiC,WAAXA,EACxB,KAAM,IAAIT,GAAa,iBAGzB,OAAOhD,OAAMlB,EAAQmB,cAGxB9C,KAAK,SAASwG,GAGf,MAAOpF,SAAQC,IACbmF,EAAU7C,IAAI,SAASZ,EAAU0D,GAC/B,MAAO9G,GAAMwD,IAAIO,EAAS+C,GAAI1D,QAGjC/C,KAAK,WACN,MAAO0G","file":"bundle.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})","/*\n Copyright 2014 Google Inc. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n'use strict';\n\nvar Route = require('./route');\n\nfunction regexEscape(s) {\n return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n}\n\nvar keyMatch = function(map, string) {\n for (var item of map) {\n var pattern = new RegExp(item[0]), value = item[1];\n if (pattern.test(string)) {\n return value;\n }\n }\n return null;\n};\n\nvar Router = function() {\n this.routes = new Map();\n this.default = null;\n};\n\n['get', 'post', 'put', 'delete', 'head', 'any'].forEach(function(method) {\n Router.prototype[method] = function(path, handler, options) {\n return this.add(method, path, handler, options);\n };\n});\n\nRouter.prototype.add = function(method, path, handler, options) {\n options = options || {};\n var origin = options.origin || self.location.origin;\n if (origin instanceof RegExp) {\n origin = origin.source;\n } else {\n origin = regexEscape(origin);\n }\n method = method.toLowerCase();\n\n var route = new Route(method, path, handler, options);\n\n if (!this.routes.has(origin)) {\n this.routes.set(origin, new Map());\n }\n\n var methodMap = this.routes.get(origin);\n if (!methodMap.has(method)) {\n methodMap.set(method, new Map());\n }\n\n var routeMap = methodMap.get(method);\n routeMap.set(route.regexp.source, route);\n};\n\nRouter.prototype.matchMethod = function(method, url) {\n url = new URL(url);\n var origin = url.origin;\n var path = url.pathname;\n method = method.toLowerCase();\n\n var methods = keyMatch(this.routes, origin);\n if (!methods) {\n return null;\n }\n\n var routes = methods.get(method);\n if (!routes) {\n return null;\n }\n\n var route = keyMatch(routes, path);\n\n if (route) {\n return route.makeHandler(path);\n }\n\n return null;\n};\n\nRouter.prototype.match = function(request) {\n return this.matchMethod(request.method, request.url) || this.matchMethod('any', request.url);\n};\n\nmodule.exports = new Router();\n","/*\n Copyright 2014 Google Inc. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n'use strict';\n\nrequire('serviceworker-cache-polyfill');\nvar options = require('./options');\nvar router = require('./router');\nvar helpers = require('./helpers');\nvar strategies = require('./strategies');\n\nhelpers.debug('Service Worker Toolbox is loading');\n\n// Install\n\nself.addEventListener('install', function(event) {\n var inactiveCache = options.cacheName + '$$$inactive$$$';\n helpers.debug('install event fired');\n helpers.debug('creating cache [' + inactiveCache + ']');\n helpers.debug('preCache list: ' + (options.preCacheItems.join(', ') || '(none)'));\n event.waitUntil(\n helpers.openCache({cacheName: inactiveCache}).then(function(cache) {\n return Promise.all(options.preCacheItems).then(cache.addAll.bind(cache));\n })\n );\n});\n\n// Activate\n\nself.addEventListener('activate', function(event) {\n helpers.debug('activate event fired');\n var inactiveCache = options.cacheName + '$$$inactive$$$';\n event.waitUntil(helpers.renameCache(inactiveCache, options.cacheName));\n});\n\n// Fetch\n\nself.addEventListener('fetch', function(event) {\n var handler = router.match(event.request);\n\n if (handler) {\n event.respondWith(handler(event.request));\n } else if (router.default) {\n event.respondWith(router.default(event.request));\n }\n});\n\n// Caching\n\nfunction cache(url, options) {\n return helpers.openCache(options).then(function(cache) {\n return cache.add(url);\n });\n}\n\nfunction uncache(url, options) {\n return helpers.openCache(options).then(function(cache) {\n return cache.delete(url);\n });\n}\n\nfunction precache(items) {\n if (!Array.isArray(items)) {\n items = [items];\n }\n options.preCacheItems = options.preCacheItems.concat(items);\n}\n\nmodule.exports = {\n networkOnly: strategies.networkOnly,\n networkFirst: strategies.networkFirst,\n cacheOnly: strategies.cacheOnly,\n cacheFirst: strategies.cacheFirst,\n fastest: strategies.fastest,\n router: router,\n options: options,\n cache: cache,\n uncache: uncache,\n precache: precache\n};\n","/*\n Copyright 2014 Google Inc. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n'use strict';\n\nvar globalOptions = require('./options');\n\nfunction debug(message, options) {\n options = options || {};\n var flag = options.debug || globalOptions.debug;\n if (flag) {\n console.log('[sw-toolbox] ' + message);\n }\n}\n\nfunction openCache(options) {\n options = options || {};\n var cacheName = options.cacheName || globalOptions.cacheName;\n debug('Opening cache \"' + cacheName + '\"', options);\n return caches.open(cacheName);\n}\n\nfunction fetchAndCache(request, options) {\n options = options || {};\n var successResponses = options.successResponses || globalOptions.successResponses;\n return fetch(request.clone()).then(function(response) {\n\n // Only cache GET requests with successful responses\n if (request.method === 'GET' && successResponses.test(response.status)) {\n openCache(options).then(function(cache) {\n cache.put(request, response);\n });\n }\n\n return response.clone();\n });\n}\n\nfunction renameCache(source, destination, options) {\n debug('Renaming cache: [' + source + '] to [' + destination + ']', options);\n return caches.delete(destination).then(function() {\n return Promise.all([\n caches.open(source),\n caches.open(destination)\n ]).then(function(results) {\n var sourceCache = results[0];\n var destCache = results[1];\n\n return sourceCache.keys().then(function(requests) {\n return Promise.all(requests.map(function(request) {\n return sourceCache.match(request).then(function(response) {\n return destCache.put(request, response);\n });\n }));\n }).then(function() {\n return caches.delete(source);\n });\n });\n });\n}\n\nmodule.exports = {\n debug: debug,\n fetchAndCache: fetchAndCache,\n openCache: openCache,\n renameCache: renameCache\n};\n","/*\n\tCopyright 2014 Google Inc. All Rights Reserved.\n\n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at\n\n\t http://www.apache.org/licenses/LICENSE-2.0\n\n\tUnless required by applicable law or agreed to in writing, software\n\tdistributed under the License is distributed on an \"AS IS\" BASIS,\n\tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\tSee the License for the specific language governing permissions and\n\tlimitations under the License.\n*/\n'use strict';\n\n// TODO: This is necessary to handle different implementations in the wild\n// The spec defines self.registration, but it was not implemented in Chrome 40.\nvar scope;\nif (self.registration) {\n scope = self.registration.scope;\n} else {\n scope = self.scope || new URL('./', self.location).href;\n}\n\nmodule.exports = {\n\tcacheName: '$$$toolbox-cache$$$' + scope + '$$$',\n\tdebug: false,\n\tpreCacheItems: [],\n\t// A regular expression to apply to HTTP response codes. Codes that match\n\t// will be considered successes, while others will not, and will not be\n\t// cached.\n\tsuccessResponses: /^0|([123]\\d\\d)|(40[14567])|410$/,\n};\n","/*\n\tCopyright 2014 Google Inc. All Rights Reserved.\n\n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at\n\n\t http://www.apache.org/licenses/LICENSE-2.0\n\n\tUnless required by applicable law or agreed to in writing, software\n\tdistributed under the License is distributed on an \"AS IS\" BASIS,\n\tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\tSee the License for the specific language governing permissions and\n\tlimitations under the License.\n*/\nmodule.exports = {\n networkOnly: require('./networkOnly'),\n networkFirst: require('./networkFirst'),\n cacheOnly: require('./cacheOnly'),\n cacheFirst: require('./cacheFirst'),\n fastest: require('./fastest')\t\n};","/*\n Copyright 2014 Google Inc. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n'use strict';\n\n//TODO: Use self.registration.scope instead of self.location\nvar url = new URL('./', self.location);\nvar basePath = url.pathname;\nvar pathRegexp = require('path-to-regexp');\n\n\nvar Route = function(method, path, handler, options) {\n // The URL() constructor can't parse express-style routes as they are not\n // valid urls. This means we have to manually manipulate relative urls into\n // absolute ones. This check is extremely naive but implementing a tweaked\n // version of the full algorithm seems like overkill\n // (https://url.spec.whatwg.org/#concept-basic-url-parser)\n if (path.indexOf('/') !== 0) {\n path = basePath + path;\n }\n\n this.method = method;\n this.keys = [];\n this.regexp = pathRegexp(path, this.keys);\n this.options = options;\n this.handler = handler;\n};\n\nRoute.prototype.makeHandler = function(url) {\n var match = this.regexp.exec(url);\n var values = {};\n this.keys.forEach(function(key, index) {\n values[key.name] = match[index + 1];\n });\n return function(request) {\n return this.handler(request, values, this.options);\n }.bind(this);\n};\n\nmodule.exports = Route;\n","/*\n\tCopyright 2014 Google Inc. All Rights Reserved.\n\n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at\n\n\t http://www.apache.org/licenses/LICENSE-2.0\n\n\tUnless required by applicable law or agreed to in writing, software\n\tdistributed under the License is distributed on an \"AS IS\" BASIS,\n\tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\tSee the License for the specific language governing permissions and\n\tlimitations under the License.\n*/\n'use strict';\nvar helpers = require('../helpers');\n\nfunction networkOnly(request, values, options) {\n helpers.debug('Strategy: network only [' + request.url + ']', options);\n return fetch(request);\n}\n\nmodule.exports = networkOnly;","/*\n Copyright 2014 Google Inc. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n'use strict';\nvar globalOptions = require('../options');\nvar helpers = require('../helpers');\n\nfunction networkFirst(request, values, options) {\n options = options || {};\n var successResponses = options.successResponses || globalOptions.successResponses;\n helpers.debug('Strategy: network first [' + request.url + ']', options);\n return helpers.openCache(options).then(function(cache) {\n return helpers.fetchAndCache(request, options).then(function(response) {\n if (successResponses.test(response.status)) {\n return response;\n }\n\n return cache.match(request).then(function(cacheResponse) {\n helpers.debug('Response was an HTTP error', options);\n if (cacheResponse) {\n helpers.debug('Resolving with cached response instead', options);\n return cacheResponse;\n } else {\n // If we didn't have anything in the cache, it's better to return the\n // error page than to return nothing\n helpers.debug('No cached result, resolving with HTTP error response from network', options);\n return response;\n }\n });\n }).catch(function(error) {\n helpers.debug('Network error, fallback to cache [' + request.url + ']', options);\n return cache.match(request);\n });\n });\n}\n\nmodule.exports = networkFirst;","/*\n\tCopyright 2014 Google Inc. All Rights Reserved.\n\n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at\n\n\t http://www.apache.org/licenses/LICENSE-2.0\n\n\tUnless required by applicable law or agreed to in writing, software\n\tdistributed under the License is distributed on an \"AS IS\" BASIS,\n\tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\tSee the License for the specific language governing permissions and\n\tlimitations under the License.\n*/\n'use strict';\nvar helpers = require('../helpers');\n\nfunction cacheOnly(request, values, options) {\n helpers.debug('Strategy: cache only [' + request.url + ']', options);\n return helpers.openCache(options).then(function(cache) {\n return cache.match(request);\n });\n}\n\nmodule.exports = cacheOnly;\n","/*\n\tCopyright 2014 Google Inc. All Rights Reserved.\n\n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at\n\n\t http://www.apache.org/licenses/LICENSE-2.0\n\n\tUnless required by applicable law or agreed to in writing, software\n\tdistributed under the License is distributed on an \"AS IS\" BASIS,\n\tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\tSee the License for the specific language governing permissions and\n\tlimitations under the License.\n*/\n'use strict';\nvar helpers = require('../helpers');\n\nfunction cacheFirst(request, values, options) {\n helpers.debug('Strategy: cache first [' + request.url + ']', options);\n return helpers.openCache(options).then(function(cache) {\n return cache.match(request).then(function (response) {\n if (response) {\n return response;\n }\n\n return helpers.fetchAndCache(request, options);\n });\n });\n}\n\nmodule.exports = cacheFirst;","/*\n Copyright 2014 Google Inc. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n'use strict';\nvar helpers = require('../helpers');\nvar cacheOnly = require('./cacheOnly');\n\nfunction fastest(request, values, options) {\n helpers.debug('Strategy: fastest [' + request.url + ']', options);\n var rejected = false;\n var reasons = [];\n\n var maybeReject = function(reason) {\n reasons.push(reason.toString());\n if (rejected) {\n return Promise.reject(new Error('Both cache and network failed: \"' + reasons.join('\", \"') + '\"'));\n }\n rejected = true;\n };\n\n return new Promise(function(resolve, reject) {\n helpers.fetchAndCache(request.clone(), options).then(resolve, maybeReject);\n cacheOnly(request, options).then(resolve, maybeReject);\n });\n}\n\nmodule.exports = fastest;","if (!Cache.prototype.add) {\n Cache.prototype.add = function add(request) {\n return this.addAll([request]);\n };\n}\n\nif (!Cache.prototype.addAll) {\n Cache.prototype.addAll = function addAll(requests) {\n var cache = this;\n\n // Since DOMExceptions are not constructable:\n function NetworkError(message) {\n this.name = 'NetworkError';\n this.code = 19;\n this.message = message;\n }\n NetworkError.prototype = Object.create(Error.prototype);\n\n return Promise.resolve().then(function() {\n if (arguments.length < 1) throw new TypeError();\n \n // Simulate sequence<(Request or USVString)> binding:\n var sequence = [];\n\n requests = requests.map(function(request) {\n if (request instanceof Request) {\n return request;\n }\n else {\n return String(request); // may throw TypeError\n }\n });\n\n return Promise.all(\n requests.map(function(request) {\n if (typeof request === 'string') {\n request = new Request(request);\n }\n\n var scheme = new URL(request.url).protocol;\n\n if (scheme !== 'http:' && scheme !== 'https:') {\n throw new NetworkError(\"Invalid scheme\");\n }\n\n return fetch(request.clone());\n })\n );\n }).then(function(responses) {\n // TODO: check that requests don't overwrite one another\n // (don't think this is possible to polyfill due to opaque responses)\n return Promise.all(\n responses.map(function(response, i) {\n return cache.put(requests[i], response);\n })\n );\n }).then(function() {\n return undefined;\n });\n };\n}\n","var isarray = require('isarray')\n\n/**\n * Expose `pathToRegexp`.\n */\nmodule.exports = pathToRegexp\nmodule.exports.parse = parse\nmodule.exports.compile = compile\nmodule.exports.tokensToFunction = tokensToFunction\nmodule.exports.tokensToRegExp = tokensToRegExp\n\n/**\n * The main path matching regexp utility.\n *\n * @type {RegExp}\n */\nvar PATH_REGEXP = new RegExp([\n // Match escaped characters that would otherwise appear in future matches.\n // This allows the user to escape special characters that won't transform.\n '(\\\\\\\\.)',\n // Match Express-style parameters and un-named parameters with a prefix\n // and optional suffixes. Matches appear as:\n //\n // \"/:test(\\\\d+)?\" => [\"/\", \"test\", \"\\d+\", undefined, \"?\", undefined]\n // \"/route(\\\\d+)\" => [undefined, undefined, undefined, \"\\d+\", undefined, undefined]\n // \"/*\" => [\"/\", undefined, undefined, undefined, undefined, \"*\"]\n '([\\\\/.])?(?:(?:\\\\:(\\\\w+)(?:\\\\(((?:\\\\\\\\.|[^()])+)\\\\))?|\\\\(((?:\\\\\\\\.|[^()])+)\\\\))([+*?])?|(\\\\*))'\n].join('|'), 'g')\n\n/**\n * Parse a string for the raw tokens.\n *\n * @param {String} str\n * @return {Array}\n */\nfunction parse (str) {\n var tokens = []\n var key = 0\n var index = 0\n var path = ''\n var res\n\n while ((res = PATH_REGEXP.exec(str)) != null) {\n var m = res[0]\n var escaped = res[1]\n var offset = res.index\n path += str.slice(index, offset)\n index = offset + m.length\n\n // Ignore already escaped sequences.\n if (escaped) {\n path += escaped[1]\n continue\n }\n\n // Push the current path onto the tokens.\n if (path) {\n tokens.push(path)\n path = ''\n }\n\n var prefix = res[2]\n var name = res[3]\n var capture = res[4]\n var group = res[5]\n var suffix = res[6]\n var asterisk = res[7]\n\n var repeat = suffix === '+' || suffix === '*'\n var optional = suffix === '?' || suffix === '*'\n var delimiter = prefix || '/'\n var pattern = capture || group || (asterisk ? '.*' : '[^' + delimiter + ']+?')\n\n tokens.push({\n name: name || key++,\n prefix: prefix || '',\n delimiter: delimiter,\n optional: optional,\n repeat: repeat,\n pattern: escapeGroup(pattern)\n })\n }\n\n // Match any characters still remaining.\n if (index < str.length) {\n path += str.substr(index)\n }\n\n // If the path exists, push it onto the end.\n if (path) {\n tokens.push(path)\n }\n\n return tokens\n}\n\n/**\n * Compile a string to a template function for the path.\n *\n * @param {String} str\n * @return {Function}\n */\nfunction compile (str) {\n return tokensToFunction(parse(str))\n}\n\n/**\n * Expose a method for transforming tokens into the path function.\n */\nfunction tokensToFunction (tokens) {\n // Compile all the tokens into regexps.\n var matches = new Array(tokens.length)\n\n // Compile all the patterns before compilation.\n for (var i = 0; i < tokens.length; i++) {\n if (typeof tokens[i] === 'object') {\n matches[i] = new RegExp('^' + tokens[i].pattern + '$')\n }\n }\n\n return function (obj) {\n var path = ''\n\n obj = obj || {}\n\n for (var i = 0; i < tokens.length; i++) {\n var key = tokens[i]\n\n if (typeof key === 'string') {\n path += key\n\n continue\n }\n\n var value = obj[key.name]\n\n if (value == null) {\n if (key.optional) {\n continue\n } else {\n throw new TypeError('Expected \"' + key.name + '\" to be defined')\n }\n }\n\n if (isarray(value)) {\n if (!key.repeat) {\n throw new TypeError('Expected \"' + key.name + '\" to not repeat')\n }\n\n if (value.length === 0) {\n if (key.optional) {\n continue\n } else {\n throw new TypeError('Expected \"' + key.name + '\" to not be empty')\n }\n }\n\n for (var j = 0; j < value.length; j++) {\n if (!matches[i].test(value[j])) {\n throw new TypeError('Expected all \"' + key.name + '\" to match \"' + key.pattern + '\"')\n }\n\n path += (j === 0 ? key.prefix : key.delimiter) + encodeURIComponent(value[j])\n }\n\n continue\n }\n\n if (!matches[i].test(value)) {\n throw new TypeError('Expected \"' + key.name + '\" to match \"' + key.pattern + '\"')\n }\n\n path += key.prefix + encodeURIComponent(value)\n }\n\n return path\n }\n}\n\n/**\n * Escape a regular expression string.\n *\n * @param {String} str\n * @return {String}\n */\nfunction escapeString (str) {\n return str.replace(/([.+*?=^!:${}()[\\]|\\/])/g, '\\\\$1')\n}\n\n/**\n * Escape the capturing group by escaping special characters and meaning.\n *\n * @param {String} group\n * @return {String}\n */\nfunction escapeGroup (group) {\n return group.replace(/([=!:$\\/()])/g, '\\\\$1')\n}\n\n/**\n * Attach the keys as a property of the regexp.\n *\n * @param {RegExp} re\n * @param {Array} keys\n * @return {RegExp}\n */\nfunction attachKeys (re, keys) {\n re.keys = keys\n return re\n}\n\n/**\n * Get the flags for a regexp from the options.\n *\n * @param {Object} options\n * @return {String}\n */\nfunction flags (options) {\n return options.sensitive ? '' : 'i'\n}\n\n/**\n * Pull out keys from a regexp.\n *\n * @param {RegExp} path\n * @param {Array} keys\n * @return {RegExp}\n */\nfunction regexpToRegexp (path, keys) {\n // Use a negative lookahead to match only capturing groups.\n var groups = path.source.match(/\\((?!\\?)/g)\n\n if (groups) {\n for (var i = 0; i < groups.length; i++) {\n keys.push({\n name: i,\n prefix: null,\n delimiter: null,\n optional: false,\n repeat: false,\n pattern: null\n })\n }\n }\n\n return attachKeys(path, keys)\n}\n\n/**\n * Transform an array into a regexp.\n *\n * @param {Array} path\n * @param {Array} keys\n * @param {Object} options\n * @return {RegExp}\n */\nfunction arrayToRegexp (path, keys, options) {\n var parts = []\n\n for (var i = 0; i < path.length; i++) {\n parts.push(pathToRegexp(path[i], keys, options).source)\n }\n\n var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))\n\n return attachKeys(regexp, keys)\n}\n\n/**\n * Create a path regexp from string input.\n *\n * @param {String} path\n * @param {Array} keys\n * @param {Object} options\n * @return {RegExp}\n */\nfunction stringToRegexp (path, keys, options) {\n var tokens = parse(path)\n var re = tokensToRegExp(tokens, options)\n\n // Attach keys back to the regexp.\n for (var i = 0; i < tokens.length; i++) {\n if (typeof tokens[i] !== 'string') {\n keys.push(tokens[i])\n }\n }\n\n return attachKeys(re, keys)\n}\n\n/**\n * Expose a function for taking tokens and returning a RegExp.\n *\n * @param {Array} tokens\n * @param {Array} keys\n * @param {Object} options\n * @return {RegExp}\n */\nfunction tokensToRegExp (tokens, options) {\n options = options || {}\n\n var strict = options.strict\n var end = options.end !== false\n var route = ''\n var lastToken = tokens[tokens.length - 1]\n var endsWithSlash = typeof lastToken === 'string' && /\\/$/.test(lastToken)\n\n // Iterate over the tokens and create our regexp string.\n for (var i = 0; i < tokens.length; i++) {\n var token = tokens[i]\n\n if (typeof token === 'string') {\n route += escapeString(token)\n } else {\n var prefix = escapeString(token.prefix)\n var capture = token.pattern\n\n if (token.repeat) {\n capture += '(?:' + prefix + capture + ')*'\n }\n\n if (token.optional) {\n if (prefix) {\n capture = '(?:' + prefix + '(' + capture + '))?'\n } else {\n capture = '(' + capture + ')?'\n }\n } else {\n capture = prefix + '(' + capture + ')'\n }\n\n route += capture\n }\n }\n\n // In non-strict mode we allow a slash at the end of match. If the path to\n // match already ends with a slash, we remove it for consistency. The slash\n // is valid at the end of a path match, not in the middle. This is important\n // in non-ending mode, where \"/test/\" shouldn't match \"/test//route\".\n if (!strict) {\n route = (endsWithSlash ? route.slice(0, -2) : route) + '(?:\\\\/(?=$))?'\n }\n\n if (end) {\n route += '$'\n } else {\n // In non-ending mode, we need the capturing groups to match as much as\n // possible by using a positive lookahead to the end or next path segment.\n route += strict && endsWithSlash ? '' : '(?=\\\\/|$)'\n }\n\n return new RegExp('^' + route, flags(options))\n}\n\n/**\n * Normalize the given path string, returning a regular expression.\n *\n * An empty array can be passed in for the keys, which will hold the\n * placeholder key descriptions. For example, using `/user/:id`, `keys` will\n * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.\n *\n * @param {(String|RegExp|Array)} path\n * @param {Array} [keys]\n * @param {Object} [options]\n * @return {RegExp}\n */\nfunction pathToRegexp (path, keys, options) {\n keys = keys || []\n\n if (!isarray(keys)) {\n options = keys\n keys = []\n } else if (!options) {\n options = {}\n }\n\n if (path instanceof RegExp) {\n return regexpToRegexp(path, keys, options)\n }\n\n if (isarray(path)) {\n return arrayToRegexp(path, keys, options)\n }\n\n return stringToRegexp(path, keys, options)\n}\n","module.exports = Array.isArray || function (arr) {\n return Object.prototype.toString.call(arr) == '[object Array]';\n};\n"]}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/web-animations-js/.bower.json b/polymer_1.0.4/bower_components/web-animations-js/.bower.json
new file mode 100644
index 0000000..4215dea
--- /dev/null
+++ b/polymer_1.0.4/bower_components/web-animations-js/.bower.json
@@ -0,0 +1,41 @@
+{
+ "name": "web-animations-js",
+ "description": "JavaScript implementation of the Web Animations API",
+ "homepage": "https://github.com/web-animations/web-animations-js",
+ "main": "web-animations.min.js",
+ "moduleType": [
+ "globals"
+ ],
+ "keywords": [
+ "animations",
+ "polyfill"
+ ],
+ "license": "Apache-2.0",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "templates",
+ "test",
+ "src",
+ "Gruntfile.js",
+ "package.json",
+ "target-config.js",
+ "target-loader.js",
+ "web-animations.dev.html",
+ "web-animations.dev.js",
+ "web-animations-next.dev.html",
+ "web-animations-next.dev.js",
+ "web-animations-next-lite.dev.html",
+ "web-animations-next-lite.dev.js"
+ ],
+ "version": "2.1.0",
+ "_release": "2.1.0",
+ "_resolution": {
+ "type": "version",
+ "tag": "2.1.0",
+ "commit": "7215de49976c233fb7abe2c19ee31a1009acc655"
+ },
+ "_source": "git://github.com/web-animations/web-animations-js.git",
+ "_target": "^2.0.0",
+ "_originalSource": "web-animations/web-animations-js"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/web-animations-js/COPYING b/polymer_1.0.4/bower_components/web-animations-js/COPYING
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/polymer_1.0.4/bower_components/web-animations-js/COPYING
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/polymer_1.0.4/bower_components/web-animations-js/History.md b/polymer_1.0.4/bower_components/web-animations-js/History.md
new file mode 100644
index 0000000..c612d23
--- /dev/null
+++ b/polymer_1.0.4/bower_components/web-animations-js/History.md
@@ -0,0 +1,118 @@
+### 2.1.0 - *June 15 2015*
+ * Fix bug affecting GroupEffects with infinite iteration children
+ * Add GroupEffect.firstChild and GroupEffect.lastChild
+ * Add initial values for most CSS properties
+ * Allow `timeline.play()` to be called with no arguments
+ * Add AnimationEffect.clone
+ * Add GroupEffect.append and GroupEffect.prepend
+ * Add AnimationEffect.remove
+ * Add Animation.ready and Animation.finished promises
+
+### 2.0.0 - *April 5 2015*
+
+ * Improve behavior of group Animation playback rate.
+ * Rename Animation to KeyframeEffect.
+ * Rename AnimationSequence to SequenceEffect.
+ * Rename AnimationGroup to GroupEffect.
+ * Rename AnimationPlayer to Animation.
+ * Remove KeyframeEffect.effect and add KeyframeEffect.getFrames.
+ * Rename Animation.source to Animation.effect.
+ * Rename Timeline.getAnimationPlayers to Timeline.getAnimations.
+ * Rename Element.getAnimationPlayers to Element.getAnimations.
+
+### 1.0.7 - *March 10 2015*
+
+ * Improve performance of constructing groups and sequences.
+ * Remove support for animating zoom.
+ * Add bower file.
+
+### 1.0.6 - *February 5 2015*
+
+ * Implement playbackRate setter for group players.
+ * Fix pausing a group player before its first tick.
+ * Fix cancelling a group player before its first tick.
+ * Fix excess CPU use on idle pages where custom effects and groups were used.
+ * Suppress AnimationTiming.playbackRate deprecation warning for cases where AnimationTiming.playbackRate == 1.
+
+### 1.0.5 - *January 6 2015*
+
+ * Fix loading the polyfill in an SVG document
+ * Fix a problem where groups didn't take effect in their first frame
+ * Don't rely on performance.now
+
+### 1.0.4 - *December 8 2014*
+
+ * Fix a critical bug where deprecation logic wasn't being loaded
+ when `web-animations-next` and `web-animations-next-lite` were
+ executed on top of a native `element.animate`.
+
+### 1.0.3 - *December 4 2014*
+
+ * Fix a critical bug on iOS 7 and Safari <= 6. Due to limitations,
+ inline style patching is not supported on these platforms.
+
+### 1.0.2 - *November 28 2014*
+
+ * Deprecated `AnimationTiming.playbackRate`.
+
+ For example, this is no longer supported:
+
+ var player = element.animate(
+ keyframes,
+ {duration: 1000, playbackRate: 2});
+
+ Use `AnimationPlayer.playbackRate` instead:
+
+ var player = element.animate(
+ keyframes,
+ {duration: 1000});
+ player.playbackRate = 2;
+
+ If you have any feedback on this change, please start a discussion
+ on the public-fx mailing list:
+ http://lists.w3.org/Archives/Public/public-fx/
+
+ Or file an issue against the specification on GitHub:
+ https://github.com/w3c/web-animations/issues/new
+
+### 1.0.1 - *November 26 2014*
+
+ * Players should be constructed in idle state
+ * `play()` and `reverse()` should not force a start times
+ * Add `requestAnimationFrame` ids and `cancelAnimationFrame`
+
+### 1.0.0 — *November 21 2014*
+
+ The web-animations-js hackers are pleased to announce the release of
+ a new codebase for the Web Animations Polyfill:
+ https://github.com/web-animations/web-animations-js
+
+ The previous polyfill has been moved to:
+ https://github.com/web-animations/web-animations-js-legacy
+
+ The new codebase is focused on code-size -- our smallest target is
+ now only 33kb or 11kb after gzip.
+
+ We've implemented native fallback. If the target browser provides
+ Web Animations features natively, the Polyfill will use them.
+
+ We now provide three different build targets:
+
+ `web-animations.min.js` - Tracks the Web Animations features that
+ are supported natively in browsers. Today that means Element.animate
+ and Playback Control in Chrome. If you’re not sure what features you
+ will need, start with this.
+
+ `web-animations-next.min.js` - All of web-animations.min.js plus
+ features that are still undergoing discussion or have yet to be
+ implemented natively.
+
+ `web-animations-next-lite.min.js` - A cut down version of
+ web-animations-next, removes several lesser used property handlers
+ and some of the larger and less used features such as matrix
+ interpolation/decomposition.
+
+ Not all features of the previous polyfill have been ported to the
+ new codebase; most notably mutation of Animations and Groups and
+ Additive Animations are not yet supported. These features are still
+ important and will be implemented in the coming weeks.
diff --git a/polymer_1.0.4/bower_components/web-animations-js/README.md b/polymer_1.0.4/bower_components/web-animations-js/README.md
new file mode 100644
index 0000000..fa3f972
--- /dev/null
+++ b/polymer_1.0.4/bower_components/web-animations-js/README.md
@@ -0,0 +1,161 @@
+
+Quick Start
+-----------
+
+To provide native Chrome Web Animation features (`Element.animate` and Playback
+Control) in other browsers, use `web-animations.min.js`. To explore all of the
+proposed Web Animations API, use `web-animations-next.min.js`.
+
+What is Web Animations?
+-----------------------
+
+Web Animations is a new JavaScript API for driving animated content on the web.
+By unifying the animation features of SVG and CSS, Web Animations unlocks
+features previously only usable declaratively, and exposes powerful,
+high-performance animation capabilities to developers.
+
+For more details see the
+[W3C specification](http://w3c.github.io/web-animations/).
+
+What is the polyfill?
+---------------------
+
+The polyfill is a JavaScript implementation of the Web Animations API. It works
+on modern versions of all major browsers. For more details about browser
+support see <https://www.polymer-project.org/resources/compatibility.html>.
+
+Getting Started
+---------------
+
+Here's a simple example of an animation that scales and changes the opacity of
+a `<div>` over 0.5 seconds. The animation alternates producing a pulsing
+effect.
+
+ <script src="web-animations.min.js"></script>
+ <div class="pulse" style="width:150px;">Hello world!</div>
+ <script>
+ var elem = document.querySelector('.pulse');
+ var animation = elem.animate([
+ {opacity: 0.5, transform: "scale(0.5)"},
+ {opacity: 1.0, transform: "scale(1)"}
+ ], {
+ direction: 'alternate',
+ duration: 500,
+ iterations: Infinity
+ });
+ </script>
+
+Web Animations supports off-main-thread animations, and also allows procedural
+generation of animations and fine-grained control of animation playback. See
+<http://web-animations.github.io> for ideas and inspiration!
+
+Native Fallback
+---------------
+
+When the polyfill runs on a browser that implements `Element.animate` and
+`Animation` Playback Control it will detect and use the underlying native
+features.
+
+Different Build Targets
+-----------------------
+
+### web-animations.min.js
+
+Tracks the Web Animations features that are supported natively in browsers.
+Today that means Element.animate and Playback Control in Chrome. If you’re not
+sure what features you will need, start with this.
+
+### web-animations-next.min.js
+
+Contains all of web-animations.min.js plus features that are still undergoing
+discussion or have yet to be implemented natively.
+
+### web-animations-next-lite.min.js
+
+A cut down version of web-animations-next, it removes several lesser used
+property handlers and some of the larger and less used features such as matrix
+interpolation/decomposition.
+
+### Build Target Comparison
+
+| | web-animations | web-animations-next | web-animations-next-lite |
+|------------------------|:--------------:|:-------------------:|:------------------------:|
+|Size (gzipped) | 12.5kb | 14kb | 10.5kb |
+|Element.animate | ✔ | ✔ | ✔ |
+|Timing input (easings, duration, fillMode, etc.) for animation effects| ✔ | ✔ | ✔ |
+|Playback control | ✔ | ✔ | ✔ |
+|Support for animating lengths, transforms and opacity| ✔ | ✔ | ✔ |
+|Support for animating other CSS properties| ✔ | ✔ | 🚫 |
+|Matrix fallback for transform animations | ✔ | ✔ | 🚫 |
+|KeyframeEffect constructor | 🚫 | ✔ | ✔ |
+|Simple GroupEffects & SequenceEffects | 🚫 | ✔ | ✔ |
+|Custom Effects | 🚫 | ✔ | ✔ |
+|Timing input (easings, duration, fillMode, etc.) for groups</div>| 🚫 | 🚫\* | 🚫 |
+|Additive animation | 🚫\* | 🚫\* | 🚫 |
+|Motion path | 🚫\* | 🚫\* | 🚫 |
+|Modifiable keyframe effect timing| 🚫 | 🚫\* | 🚫\* |
+|Modifiable group timing | 🚫 | 🚫\* | 🚫\* |
+|Usable inline style\*\* | ✔ | ✔ | 🚫 |
+
+\* support is planned for these features.
+\*\* see inline style caveat below.
+
+Caveats
+-------
+
+Some things won’t ever be faithful to the native implementation due to browser
+and CSS API limitations. These include:
+
+### Inline Style
+
+Inline style modification is the mechanism used by the polyfill to animate
+properties. Both web-animations and web-animations-next incorporate a module
+that emulates a vanilla inline style object, so that style modification from
+JavaScript can still work in the presence of animations. However, to keep the
+size of web-animations-next-lite as small as possible, the style emulation
+module is not included. When using this version of the polyfill, JavaScript
+inline style modification will be overwritten by animations.
+Due to browser constraints inline style modification is not supported on iOS 7
+or Safari 6 (or earlier versions).
+
+### Prefix handling
+
+The polyfill will automatically detect the correctly prefixed name to use when
+writing animated properties back to the platform. Where possible, the polyfill
+will only accept unprefixed versions of experimental features. For example:
+
+ var effect = new KeyframeEffect(elem, {"transform": "translate(100px, 100px)"}, 2000);
+
+will work in all browsers that implement a conforming version of transform, but
+
+ var effect = new KeyframeEffect(elem, {"-webkit-transform": "translate(100px, 100px)"}, 2000);
+
+will not work anywhere.
+
+API and Specification Feedback
+------------------------------
+
+File an issue on GitHub: <https://github.com/w3c/web-animations/issues/new>.
+Alternatively, send an email to <public-fx@w3.org> with subject line
+“[web-animations] … message topic …”
+([archives](http://lists.w3.org/Archives/Public/public-fx/)).
+
+Polyfill Issues
+---------------
+
+Report any issues with this implementation on GitHub:
+<https://github.com/web-animations/web-animations-next/issues/new>.
+
+Breaking changes
+----------------
+
+When we make a potentially breaking change to the polyfill's API
+surface (like a rename) we will, where possible, continue supporting the
+old version, deprecated, for three months, and ensure that there are
+console warnings to indicate that a change is pending. After three
+months, the old version of the API surface (e.g. the old version of a
+function name) will be removed. *If you see deprecation warnings you
+can't avoid it by not updating*.
+
+We also announce anything that isn't a bug fix on
+[web-animations-changes@googlegroups.com](https://groups.google.com/forum/#!forum/web-animations-changes).
diff --git a/polymer_1.0.4/bower_components/web-animations-js/bower.json b/polymer_1.0.4/bower_components/web-animations-js/bower.json
new file mode 100644
index 0000000..22f26b5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/web-animations-js/bower.json
@@ -0,0 +1,31 @@
+{
+ "name": "web-animations-js",
+ "description": "JavaScript implementation of the Web Animations API",
+ "homepage": "https://github.com/web-animations/web-animations-js",
+ "main": "web-animations.min.js",
+ "moduleType": [
+ "globals"
+ ],
+ "keywords": [
+ "animations",
+ "polyfill"
+ ],
+ "license": "Apache-2.0",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "templates",
+ "test",
+ "src",
+ "Gruntfile.js",
+ "package.json",
+ "target-config.js",
+ "target-loader.js",
+ "web-animations.dev.html",
+ "web-animations.dev.js",
+ "web-animations-next.dev.html",
+ "web-animations-next.dev.js",
+ "web-animations-next-lite.dev.html",
+ "web-animations-next-lite.dev.js"
+ ]
+}
diff --git a/polymer_1.0.4/bower_components/web-animations-js/web-animations-next-lite.min.js b/polymer_1.0.4/bower_components/web-animations-js/web-animations-next-lite.min.js
new file mode 100644
index 0000000..2ca5d37
--- /dev/null
+++ b/polymer_1.0.4/bower_components/web-animations-js/web-animations-next-lite.min.js
@@ -0,0 +1,17 @@
+// Copyright 2014 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+!function(a,b){b["true"]=a;var c={},d={},e={},f=null;!function(a){function b(a){if("number"==typeof a)return a;var b={};for(var c in a)b[c]=a[c];return b}function c(b,c){var d={delay:0,endDelay:0,fill:c?"both":"none",iterationStart:0,iterations:1,duration:c?"auto":0,playbackRate:1,direction:"normal",easing:"linear"};return"number"!=typeof b||isNaN(b)?void 0!==b&&Object.getOwnPropertyNames(b).forEach(function(c){if("auto"!=b[c]){if(("number"==typeof d[c]||"duration"==c)&&("number"!=typeof b[c]||isNaN(b[c])))return;if("fill"==c&&-1==q.indexOf(b[c]))return;if("direction"==c&&-1==r.indexOf(b[c]))return;if("playbackRate"==c&&1!==b[c]&&a.isDeprecated("AnimationEffectTiming.playbackRate","2014-11-28","Use Animation.playbackRate instead."))return;d[c]=b[c]}}):d.duration=b,d}function d(a,b){var d=c(a,b);return d.easing=g(d.easing),d}function e(a,b,c,d){return 0>a||a>1||0>c||c>1?z:function(e){function f(a,b,c){return 3*a*(1-c)*(1-c)*c+3*b*(1-c)*c*c+c*c*c}if(0==e||1==e)return e;for(var g=0,h=1;;){var i=(g+h)/2,j=f(a,c,i);if(Math.abs(e-j)<.001)return f(b,d,i);e>j?g=i:h=i}}}function f(a,b){return function(c){if(c>=1)return 1;var d=1/a;return c+=b*d,c-c%d}}function g(a){var b=x.exec(a);if(b)return e.apply(this,b.slice(1).map(Number));var c=y.exec(a);if(c)return f(Number(c[1]),{start:s,middle:t,end:u}[c[2]]);var d=v[a];return d?d:z}function h(a){return Math.abs(i(a)/a.playbackRate)}function i(a){return a.duration*a.iterations}function j(a,b,c){return null==b?A:b<c.delay?B:b>=c.delay+a?C:D}function k(a,b,c,d,e){switch(d){case B:return"backwards"==b||"both"==b?0:null;case D:return c-e;case C:return"forwards"==b||"both"==b?a:null;case A:return null}}function l(a,b,c,d){return(d.playbackRate<0?b-a:b)*d.playbackRate+c}function m(a,b,c,d,e){return 1/0===c||c===-1/0||c-d==b&&e.iterations&&(e.iterations+e.iterationStart)%1==0?a:c%a}function n(a,b,c,d){return 0===c?0:b==a?d.iterationStart+d.iterations-1:Math.floor(c/a)}function o(a,b,c,d){var e=a%2>=1,f="normal"==d.direction||d.direction==(e?"alternate-reverse":"alternate"),g=f?c:b-c,h=g/b;return b*d.easing(h)}function p(a,b,c){var d=j(a,b,c),e=k(a,c.fill,b,d,c.delay);if(null===e)return null;if(0===a)return d===B?0:1;var f=c.iterationStart*c.duration,g=l(a,e,f,c),h=m(c.duration,i(c),g,f,c),p=n(c.duration,h,g,c);return o(p,c.duration,h,c)/c.duration}var q="backwards|forwards|both|none".split("|"),r="reverse|alternate|alternate-reverse".split("|"),s=1,t=.5,u=0,v={ease:e(.25,.1,.25,1),"ease-in":e(.42,0,1,1),"ease-out":e(0,0,.58,1),"ease-in-out":e(.42,0,.58,1),"step-start":f(1,s),"step-middle":f(1,t),"step-end":f(1,u)},w="\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*",x=new RegExp("cubic-bezier\\("+w+","+w+","+w+","+w+"\\)"),y=/steps\(\s*(\d+)\s*,\s*(start|middle|end)\s*\)/,z=function(a){return a},A=0,B=1,C=2,D=3;a.cloneTimingInput=b,a.makeTiming=c,a.normalizeTimingInput=d,a.calculateActiveDuration=h,a.calculateTimeFraction=p,a.calculatePhase=j,a.toTimingFunction=g}(c,f),function(a){function b(a,b){return a in h?h[a][b]||b:b}function c(a,c,d){var g=e[a];if(g){f.style[a]=c;for(var h in g){var i=g[h],j=f.style[i];d[i]=b(i,j)}}else d[a]=b(a,c)}function d(b){function d(){var a=e.length;null==e[a-1].offset&&(e[a-1].offset=1),a>1&&null==e[0].offset&&(e[0].offset=0);for(var b=0,c=e[0].offset,d=1;a>d;d++){var f=e[d].offset;if(null!=f){for(var g=1;d-b>g;g++)e[b+g].offset=c+(f-c)*g/(d-b);b=d,c=f}}}if(!Array.isArray(b)&&null!==b)throw new TypeError("Keyframes must be null or an array of keyframes");if(null==b)return[];for(var e=b.map(function(b){var d={};for(var e in b){var f=b[e];if("offset"==e){if(null!=f&&(f=Number(f),!isFinite(f)))throw new TypeError("keyframe offsets must be numbers.")}else{if("composite"==e)throw{type:DOMException.NOT_SUPPORTED_ERR,name:"NotSupportedError",message:"add compositing is not supported"};f="easing"==e?a.toTimingFunction(f):""+f}c(e,f,d)}return void 0==d.offset&&(d.offset=null),void 0==d.easing&&(d.easing=a.toTimingFunction("linear")),d}),f=!0,g=-1/0,h=0;h<e.length;h++){var i=e[h].offset;if(null!=i){if(g>i)throw{code:DOMException.INVALID_MODIFICATION_ERR,name:"InvalidModificationError",message:"Keyframes are not loosely sorted by offset. Sort or specify offsets."};g=i}else f=!1}return e=e.filter(function(a){return a.offset>=0&&a.offset<=1}),f||d(),e}var e={background:["backgroundImage","backgroundPosition","backgroundSize","backgroundRepeat","backgroundAttachment","backgroundOrigin","backgroundClip","backgroundColor"],border:["borderTopColor","borderTopStyle","borderTopWidth","borderRightColor","borderRightStyle","borderRightWidth","borderBottomColor","borderBottomStyle","borderBottomWidth","borderLeftColor","borderLeftStyle","borderLeftWidth"],borderBottom:["borderBottomWidth","borderBottomStyle","borderBottomColor"],borderColor:["borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],borderLeft:["borderLeftWidth","borderLeftStyle","borderLeftColor"],borderRadius:["borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"],borderRight:["borderRightWidth","borderRightStyle","borderRightColor"],borderTop:["borderTopWidth","borderTopStyle","borderTopColor"],borderWidth:["borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth"],flex:["flexGrow","flexShrink","flexBasis"],font:["fontFamily","fontSize","fontStyle","fontVariant","fontWeight","lineHeight"],margin:["marginTop","marginRight","marginBottom","marginLeft"],outline:["outlineColor","outlineStyle","outlineWidth"],padding:["paddingTop","paddingRight","paddingBottom","paddingLeft"]},f=document.createElementNS("http://www.w3.org/1999/xhtml","div"),g={thin:"1px",medium:"3px",thick:"5px"},h={borderBottomWidth:g,borderLeftWidth:g,borderRightWidth:g,borderTopWidth:g,fontSize:{"xx-small":"60%","x-small":"75%",small:"89%",medium:"100%",large:"120%","x-large":"150%","xx-large":"200%"},fontWeight:{normal:"400",bold:"700"},outlineWidth:g,textShadow:{none:"0px 0px 0px transparent"},boxShadow:{none:"0px 0px 0px 0px transparent"}};a.normalizeKeyframes=d}(c,f),function(a){var b={};a.isDeprecated=function(a,c,d,e){var f=e?"are":"is",g=new Date,h=new Date(c);return h.setMonth(h.getMonth()+3),h>g?(a in b||console.warn("Web Animations: "+a+" "+f+" deprecated and will stop working on "+h.toDateString()+". "+d),b[a]=!0,!1):!0},a.deprecated=function(b,c,d,e){var f=e?"are":"is";if(a.isDeprecated(b,c,d,e))throw new Error(b+" "+f+" no longer supported. "+d)}}(c),function(){if(document.documentElement.animate){var a=document.documentElement.animate([],0),b=!0;if(a&&(b=!1,"play|currentTime|pause|reverse|playbackRate|cancel|finish|startTime|playState".split("|").forEach(function(c){void 0===a[c]&&(b=!0)})),!b)return}!function(a,b){function c(a){for(var b={},c=0;c<a.length;c++)for(var d in a[c])if("offset"!=d&&"easing"!=d&&"composite"!=d){var e={offset:a[c].offset,easing:a[c].easing,value:a[c][d]};b[d]=b[d]||[],b[d].push(e)}for(var f in b){var g=b[f];if(0!=g[0].offset||1!=g[g.length-1].offset)throw{type:DOMException.NOT_SUPPORTED_ERR,name:"NotSupportedError",message:"Partial keyframes are not supported"}}return b}function d(a){var c=[];for(var d in a)for(var e=a[d],f=0;f<e.length-1;f++){var g=e[f].offset,h=e[f+1].offset,i=e[f].value,j=e[f+1].value;g==h&&(1==h?i=j:j=i),c.push({startTime:g,endTime:h,easing:e[f].easing,property:d,interpolation:b.propertyInterpolation(d,i,j)})}return c.sort(function(a,b){return a.startTime-b.startTime}),c}b.convertEffectInput=function(e){var f=a.normalizeKeyframes(e),g=c(f),h=d(g);return function(a,c){if(null!=c)h.filter(function(a){return 0>=c&&0==a.startTime||c>=1&&1==a.endTime||c>=a.startTime&&c<=a.endTime}).forEach(function(d){var e=c-d.startTime,f=d.endTime-d.startTime,g=0==f?0:d.easing(e/f);b.apply(a,d.property,d.interpolation(g))});else for(var d in g)"offset"!=d&&"easing"!=d&&"composite"!=d&&b.clear(a,d)}}}(c,d,f),function(a){function b(a,b,c){e[c]=e[c]||[],e[c].push([a,b])}function c(a,c,d){for(var e=0;e<d.length;e++){var f=d[e];b(a,c,f),/-/.test(f)&&b(a,c,f.replace(/-(.)/g,function(a,b){return b.toUpperCase()}))}}function d(b,c,d){if("initial"==c||"initial"==d){var g=b.replace(/-(.)/g,function(a,b){return b.toUpperCase()});"initial"==c&&(c=f[g]),"initial"==d&&(d=f[g])}for(var h=c==d?[]:e[b],i=0;h&&i<h.length;i++){var j=h[i][0](c),k=h[i][0](d);if(void 0!==j&&void 0!==k){var l=h[i][1](j,k);if(l){var m=a.Interpolation.apply(null,l);return function(a){return 0==a?c:1==a?d:m(a)}}}}return a.Interpolation(!1,!0,function(a){return a?d:c})}var e={};a.addPropertiesHandler=c;var f={backgroundColor:"transparent",backgroundPosition:"0% 0%",borderBottomColor:"currentColor",borderBottomLeftRadius:"0px",borderBottomRightRadius:"0px",borderBottomWidth:"3px",borderLeftColor:"currentColor",borderLeftWidth:"3px",borderRightColor:"currentColor",borderRightWidth:"3px",borderSpacing:"2px",borderTopColor:"currentColor",borderTopLeftRadius:"0px",borderTopRightRadius:"0px",borderTopWidth:"3px",bottom:"auto",clip:"rect(0px, 0px, 0px, 0px)",color:"black",fontSize:"100%",fontWeight:"400",height:"auto",left:"auto",letterSpacing:"normal",lineHeight:"120%",marginBottom:"0px",marginLeft:"0px",marginRight:"0px",marginTop:"0px",maxHeight:"none",maxWidth:"none",minHeight:"0px",minWidth:"0px",opacity:"1.0",outlineColor:"invert",outlineOffset:"0px",outlineWidth:"3px",paddingBottom:"0px",paddingLeft:"0px",paddingRight:"0px",paddingTop:"0px",right:"auto",textIndent:"0px",textShadow:"0px 0px 0px transparent",top:"auto",transform:"",verticalAlign:"0px",visibility:"visible",width:"auto",wordSpacing:"normal",zIndex:"auto"};a.propertyInterpolation=d}(d,f),function(a,b){function c(b){var c=a.calculateActiveDuration(b),d=function(d){return a.calculateTimeFraction(c,d,b)};return d._totalDuration=b.delay+c+b.endDelay,d._isCurrent=function(d){var e=a.calculatePhase(c,d,b);return e===PhaseActive||e===PhaseBefore},d}b.KeyframeEffect=function(d,e,f){var g,h=c(a.normalizeTimingInput(f)),i=b.convertEffectInput(e),j=function(){i(d,g)};return j._update=function(a){return g=h(a),null!==g},j._clear=function(){i(d,null)},j._hasSameTarget=function(a){return d===a},j._isCurrent=h._isCurrent,j._totalDuration=h._totalDuration,j},b.NullEffect=function(a){var b=function(){a&&(a(),a=null)};return b._update=function(){return null},b._totalDuration=0,b._isCurrent=function(){return!1},b._hasSameTarget=function(){return!1},b}}(c,d,f),function(a){a.apply=function(b,c,d){b.style[a.propertyName(c)]=d},a.clear=function(b,c){b.style[a.propertyName(c)]=""}}(d,f),function(a){window.Element.prototype.animate=function(b,c){return a.timeline._play(a.KeyframeEffect(this,b,c))}}(d),function(a){function b(a,c,d){if("number"==typeof a&&"number"==typeof c)return a*(1-d)+c*d;if("boolean"==typeof a&&"boolean"==typeof c)return.5>d?a:c;if(a.length==c.length){for(var e=[],f=0;f<a.length;f++)e.push(b(a[f],c[f],d));return e}throw"Mismatched interpolation arguments "+a+":"+c}a.Interpolation=function(a,c,d){return function(e){return d(b(a,c,e))}}}(d,f),function(a,b){a.sequenceNumber=0;var c=function(a,b,c){this.target=a,this.currentTime=b,this.timelineTime=c,this.type="finish",this.bubbles=!1,this.cancelable=!1,this.currentTarget=a,this.defaultPrevented=!1,this.eventPhase=Event.AT_TARGET,this.timeStamp=Date.now()};b.Animation=function(b){this._sequenceNumber=a.sequenceNumber++,this._currentTime=0,this._startTime=null,this._paused=!1,this._playbackRate=1,this._inTimeline=!0,this._finishedFlag=!1,this.onfinish=null,this._finishHandlers=[],this._effect=b,this._inEffect=this._effect._update(0),this._idle=!0,this._currentTimePending=!1},b.Animation.prototype={_ensureAlive:function(){this._inEffect=this._effect._update(this.playbackRate<0&&0===this.currentTime?-1:this.currentTime),this._inTimeline||!this._inEffect&&this._finishedFlag||(this._inTimeline=!0,b.timeline._animations.push(this))},_tickCurrentTime:function(a,b){a!=this._currentTime&&(this._currentTime=a,this._isFinished&&!b&&(this._currentTime=this._playbackRate>0?this._totalDuration:0),this._ensureAlive())},get currentTime(){return this._idle||this._currentTimePending?null:this._currentTime},set currentTime(a){a=+a,isNaN(a)||(b.restart(),this._paused||null==this._startTime||(this._startTime=this._timeline.currentTime-a/this._playbackRate),this._currentTimePending=!1,this._currentTime!=a&&(this._tickCurrentTime(a,!0),b.invalidateEffects()))},get startTime(){return this._startTime},set startTime(a){a=+a,isNaN(a)||this._paused||this._idle||(this._startTime=a,this._tickCurrentTime((this._timeline.currentTime-this._startTime)*this.playbackRate),b.invalidateEffects())},get playbackRate(){return this._playbackRate},set playbackRate(a){if(a!=this._playbackRate){var b=this.currentTime;this._playbackRate=a,this._startTime=null,"paused"!=this.playState&&"idle"!=this.playState&&this.play(),null!=b&&(this.currentTime=b)}},get _isFinished(){return!this._idle&&(this._playbackRate>0&&this._currentTime>=this._totalDuration||this._playbackRate<0&&this._currentTime<=0)},get _totalDuration(){return this._effect._totalDuration},get playState(){return this._idle?"idle":null==this._startTime&&!this._paused&&0!=this.playbackRate||this._currentTimePending?"pending":this._paused?"paused":this._isFinished?"finished":"running"},play:function(){this._paused=!1,(this._isFinished||this._idle)&&(this._currentTime=this._playbackRate>0?0:this._totalDuration,this._startTime=null,b.invalidateEffects()),this._finishedFlag=!1,b.restart(),this._idle=!1,this._ensureAlive()},pause:function(){this._isFinished||this._paused||this._idle||(this._currentTimePending=!0),this._startTime=null,this._paused=!0},finish:function(){this._idle||(this.currentTime=this._playbackRate>0?this._totalDuration:0,this._startTime=this._totalDuration-this.currentTime,this._currentTimePending=!1)},cancel:function(){this._inEffect&&(this._inEffect=!1,this._idle=!0,this.currentTime=0,this._startTime=null,this._effect._update(null),b.invalidateEffects(),b.restart())},reverse:function(){this.playbackRate*=-1,this.play()},addEventListener:function(a,b){"function"==typeof b&&"finish"==a&&this._finishHandlers.push(b)},removeEventListener:function(a,b){if("finish"==a){var c=this._finishHandlers.indexOf(b);c>=0&&this._finishHandlers.splice(c,1)}},_fireEvents:function(a){var b=this._isFinished;if((b||this._idle)&&!this._finishedFlag){var d=new c(this,this._currentTime,a),e=this._finishHandlers.concat(this.onfinish?[this.onfinish]:[]);setTimeout(function(){e.forEach(function(a){a.call(d.target,d)})},0)}this._finishedFlag=b},_tick:function(a){return this._idle||this._paused||(null==this._startTime?this.startTime=a-this._currentTime/this.playbackRate:this._isFinished||this._tickCurrentTime((a-this._startTime)*this.playbackRate)),this._currentTimePending=!1,this._fireEvents(a),!this._idle&&(this._inEffect||!this._finishedFlag)}}}(c,d,f),function(a,b){function c(a){var b=i;i=[],a<s.currentTime&&(a=s.currentTime),g(a),b.forEach(function(b){b[1](a)}),o&&g(a),f(),l=void 0}function d(a,b){return a._sequenceNumber-b._sequenceNumber}function e(){this._animations=[],this.currentTime=window.performance&&performance.now?performance.now():0}function f(){p.forEach(function(a){a()}),p.length=0}function g(a){n=!1;var c=b.timeline;c.currentTime=a,c._animations.sort(d),m=!1;var e=c._animations;c._animations=[];var f=[],g=[];e=e.filter(function(b){return b._inTimeline=b._tick(a),b._inEffect?g.push(b._effect):f.push(b._effect),b._isFinished||b._paused||b._idle||(m=!0),b._inTimeline}),p.push.apply(p,f),p.push.apply(p,g),c._animations.push.apply(c._animations,e),o=!1,m&&requestAnimationFrame(function(){})}var h=window.requestAnimationFrame,i=[],j=0;window.requestAnimationFrame=function(a){var b=j++;return 0==i.length&&h(c),i.push([b,a]),b},window.cancelAnimationFrame=function(a){i.forEach(function(b){b[0]==a&&(b[1]=function(){})})},e.prototype={_play:function(c){c._timing=a.normalizeTimingInput(c.timing);var d=new b.Animation(c);return d._idle=!1,d._timeline=this,this._animations.push(d),b.restart(),b.invalidateEffects(),d}};var k,l=void 0,k=function(){return void 0==l&&(l=performance.now()),l},m=!1,n=!1;b.restart=function(){return m||(m=!0,requestAnimationFrame(function(){}),n=!0),n};var o=!1;b.invalidateEffects=function(){o=!0};var p=[],q=1e3/60,r=window.getComputedStyle;Object.defineProperty(window,"getComputedStyle",{configurable:!0,enumerable:!0,value:function(){if(o){var a=k();a-s.currentTime>0&&(s.currentTime+=q*(Math.floor((a-s.currentTime)/q)+1)),g(s.currentTime)}return f(),r.apply(this,arguments)}});var s=new e;b.timeline=s}(c,d,f),function(a){function b(a,b){var c=a.exec(b);return c?(c=a.ignoreCase?c[0].toLowerCase():c[0],[c,b.substr(c.length)]):void 0}function c(a,b){b=b.replace(/^\s*/,"");var c=a(b);return c?[c[0],c[1].replace(/^\s*/,"")]:void 0}function d(a,d,e){a=c.bind(null,a);for(var f=[];;){var g=a(e);if(!g)return[f,e];if(f.push(g[0]),e=g[1],g=b(d,e),!g||""==g[1])return[f,e];e=g[1]}}function e(a,b){for(var c=0,d=0;d<b.length&&(!/\s|,/.test(b[d])||0!=c);d++)if("("==b[d])c++;else if(")"==b[d]&&(c--,0==c&&d++,0>=c))break;var e=a(b.substr(0,d));return void 0==e?void 0:[e,b.substr(d)]}function f(a,b){for(var c=a,d=b;c&&d;)c>d?c%=d:d%=c;return c=a*b/(c+d)}function g(a){return function(b){var c=a(b);return c&&(c[0]=void 0),c}}function h(a,b){return function(c){var d=a(c);return d?d:[b,c]}}function i(b,c){for(var d=[],e=0;e<b.length;e++){var f=a.consumeTrimmed(b[e],c);if(!f||""==f[0])return;void 0!==f[0]&&d.push(f[0]),c=f[1]}return""==c?d:void 0}function j(a,b,c,d,e){for(var g=[],h=[],i=[],j=f(d.length,e.length),k=0;j>k;k++){var l=b(d[k%d.length],e[k%e.length]);if(!l)return;g.push(l[0]),h.push(l[1]),i.push(l[2])}return[g,h,function(b){var d=b.map(function(a,b){return i[b](a)}).join(c);return a?a(d):d}]}function k(a,b,c){for(var d=[],e=[],f=[],g=0,h=0;h<c.length;h++)if("function"==typeof c[h]){var i=c[h](a[g],b[g++]);d.push(i[0]),e.push(i[1]),f.push(i[2])}else!function(a){d.push(!1),e.push(!1),f.push(function(){return c[a]})}(h);return[d,e,function(a){for(var b="",c=0;c<a.length;c++)b+=f[c](a[c]);return b}]}a.consumeToken=b,a.consumeTrimmed=c,a.consumeRepeated=d,a.consumeParenthesised=e,a.ignore=g,a.optional=h,a.consumeList=i,a.mergeNestedRepeated=j.bind(null,null),a.mergeWrappedNestedRepeated=j,a.mergeList=k}(d),function(a){function b(b){function c(b){var c=a.consumeToken(/^inset/i,b);if(c)return d.inset=!0,c;var c=a.consumeLengthOrPercent(b);if(c)return d.lengths.push(c[0]),c;var c=a.consumeColor(b);return c?(d.color=c[0],c):void 0}var d={inset:!1,lengths:[],color:null},e=a.consumeRepeated(c,/^/,b);return e&&e[0].length?[d,e[1]]:void 0}function c(c){var d=a.consumeRepeated(b,/^,/,c);return d&&""==d[1]?d[0]:void 0}function d(b,c){for(;b.lengths.length<Math.max(b.lengths.length,c.lengths.length);)b.lengths.push({px:0});for(;c.lengths.length<Math.max(b.lengths.length,c.lengths.length);)c.lengths.push({px:0});if(b.inset==c.inset&&!!b.color==!!c.color){for(var d,e=[],f=[[],0],g=[[],0],h=0;h<b.lengths.length;h++){var i=a.mergeDimensions(b.lengths[h],c.lengths[h],2==h);f[0].push(i[0]),g[0].push(i[1]),e.push(i[2])}if(b.color&&c.color){var j=a.mergeColors(b.color,c.color);f[1]=j[0],g[1]=j[1],d=j[2]}return[f,g,function(a){for(var c=b.inset?"inset ":" ",f=0;f<e.length;f++)c+=e[f](a[0][f])+" ";return d&&(c+=d(a[1])),c}]}}function e(b,c,d,e){function f(a){return{inset:a,color:[0,0,0,0],lengths:[{px:0},{px:0},{px:0},{px:0}]}}for(var g=[],h=[],i=0;i<d.length||i<e.length;i++){var j=d[i]||f(e[i].inset),k=e[i]||f(d[i].inset);g.push(j),h.push(k)}return a.mergeNestedRepeated(b,c,g,h)}var f=e.bind(null,d,", ");a.addPropertiesHandler(c,f,["box-shadow","text-shadow"])}(d),function(a){function b(a){return a.toFixed(3).replace(".000","")}function c(a,b,c){return Math.min(b,Math.max(a,c))}function d(a){return/^\s*[-+]?(\d*\.)?\d+\s*$/.test(a)?Number(a):void 0}function e(a,c){return[a,c,b]}function f(a,b){return 0!=a?h(0,1/0)(a,b):void 0}function g(a,b){return[a,b,function(a){return Math.round(c(1,1/0,a))}]}function h(a,d){return function(e,f){return[e,f,function(e){return b(c(a,d,e))}]}}function i(a,b){return[a,b,Math.round]}a.clamp=c,a.addPropertiesHandler(d,h(0,1/0),["border-image-width","line-height"]),a.addPropertiesHandler(d,h(0,1),["opacity","shape-image-threshold"]),a.addPropertiesHandler(d,f,["flex-grow","flex-shrink"]),a.addPropertiesHandler(d,g,["orphans","widows"]),a.addPropertiesHandler(d,i,["z-index"]),a.parseNumber=d,a.mergeNumbers=e,a.numberToString=b}(d,f),function(a){function b(a,b){return"visible"==a||"visible"==b?[0,1,function(c){return 0>=c?a:c>=1?b:"visible"}]:void 0}a.addPropertiesHandler(String,b,["visibility"])}(d),function(a){function b(a){a=a.trim(),e.fillStyle="#000",e.fillStyle=a;var b=e.fillStyle;if(e.fillStyle="#fff",e.fillStyle=a,b==e.fillStyle){e.fillRect(0,0,1,1);var c=e.getImageData(0,0,1,1).data;e.clearRect(0,0,1,1);var d=c[3]/255;return[c[0]*d,c[1]*d,c[2]*d,d]}}function c(b,c){return[b,c,function(b){function c(a){return Math.max(0,Math.min(255,a))}if(b[3])for(var d=0;3>d;d++)b[d]=Math.round(c(b[d]/b[3]));return b[3]=a.numberToString(a.clamp(0,1,b[3])),"rgba("+b.join(",")+")"}]}var d=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");d.width=d.height=1;var e=d.getContext("2d");a.addPropertiesHandler(b,c,["background-color","border-bottom-color","border-left-color","border-right-color","border-top-color","color","outline-color","text-decoration-color"]),a.consumeColor=a.consumeParenthesised.bind(null,b),a.mergeColors=c}(d,f),function(a,b){function c(a,b){if(b=b.trim().toLowerCase(),"0"==b&&"px".search(a)>=0)return{px:0};if(/^[^(]*$|^calc/.test(b)){b=b.replace(/calc\(/g,"(");var c={};b=b.replace(a,function(a){return c[a]=null,"U"+a});for(var d="U("+a.source+")",e=b.replace(/[-+]?(\d*\.)?\d+/g,"N").replace(new RegExp("N"+d,"g"),"D").replace(/\s[+-]\s/g,"O").replace(/\s/g,""),f=[/N\*(D)/g,/(N|D)[*/]N/g,/(N|D)O\1/g,/\((N|D)\)/g],g=0;g<f.length;)f[g].test(e)?(e=e.replace(f[g],"$1"),g=0):g++;if("D"==e){for(var h in c){var i=eval(b.replace(new RegExp("U"+h,"g"),"").replace(new RegExp(d,"g"),"*0"));if(!isFinite(i))return;c[h]=i}return c}}}function d(a,b){return e(a,b,!0)}function e(b,c,d){var e,f=[];for(e in b)f.push(e);for(e in c)f.indexOf(e)<0&&f.push(e);return b=f.map(function(a){return b[a]||0}),c=f.map(function(a){return c[a]||0}),[b,c,function(b){var c=b.map(function(c,e){return 1==b.length&&d&&(c=Math.max(c,0)),a.numberToString(c)+f[e]}).join(" + ");return b.length>1?"calc("+c+")":c}]}var f="px|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc",g=c.bind(null,new RegExp(f,"g")),h=c.bind(null,new RegExp(f+"|%","g")),i=c.bind(null,/deg|rad|grad|turn/g);a.parseLength=g,a.parseLengthOrPercent=h,a.consumeLengthOrPercent=a.consumeParenthesised.bind(null,h),a.parseAngle=i,a.mergeDimensions=e;var j=a.consumeParenthesised.bind(null,g),k=a.consumeRepeated.bind(void 0,j,/^/),l=a.consumeRepeated.bind(void 0,k,/^,/);a.consumeSizePairList=l;var m=function(a){var b=l(a);return b&&""==b[1]?b[0]:void 0},n=a.mergeNestedRepeated.bind(void 0,d," "),o=a.mergeNestedRepeated.bind(void 0,n,",");a.mergeNonNegativeSizePair=n,a.addPropertiesHandler(m,o,["background-size"]),a.addPropertiesHandler(h,d,["border-bottom-width","border-image-width","border-left-width","border-right-width","border-top-width","flex-basis","font-size","height","line-height","max-height","max-width","outline-width","width"]),a.addPropertiesHandler(h,e,["border-bottom-left-radius","border-bottom-right-radius","border-top-left-radius","border-top-right-radius","bottom","left","letter-spacing","margin-bottom","margin-left","margin-right","margin-top","min-height","min-width","outline-offset","padding-bottom","padding-left","padding-right","padding-top","perspective","right","shape-margin","text-indent","top","vertical-align","word-spacing"])}(d,f),function(a){function b(b){return a.consumeLengthOrPercent(b)||a.consumeToken(/^auto/,b)}function c(c){var d=a.consumeList([a.ignore(a.consumeToken.bind(null,/^rect/)),a.ignore(a.consumeToken.bind(null,/^\(/)),a.consumeRepeated.bind(null,b,/^,/),a.ignore(a.consumeToken.bind(null,/^\)/))],c);return d&&4==d[0].length?d[0]:void 0}function d(b,c){return"auto"==b||"auto"==c?[!0,!1,function(d){var e=d?b:c;if("auto"==e)return"auto";var f=a.mergeDimensions(e,e);return f[2](f[0])}]:a.mergeDimensions(b,c)}function e(a){return"rect("+a+")"}var f=a.mergeWrappedNestedRepeated.bind(null,e,d,", ");a.parseBox=c,a.mergeBoxes=f,a.addPropertiesHandler(c,f,["clip"])}(d,f),function(a){function b(a){return function(b){var c=0;return a.map(function(a){return a===j?b[c++]:a})}}function c(a){return a}function d(b){if(b=b.toLowerCase().trim(),"none"==b)return[];for(var c,d=/\s*(\w+)\(([^)]*)\)/g,e=[],f=0;c=d.exec(b);){if(c.index!=f)return;f=c.index+c[0].length;var g=c[1],h=m[g];if(!h)return;var i=c[2].split(","),j=h[0];if(j.length<i.length)return;for(var n=[],o=0;o<j.length;o++){var p,q=i[o],r=j[o];if(p=q?{A:function(b){return"0"==b.trim()?l:a.parseAngle(b)},N:a.parseNumber,T:a.parseLengthOrPercent,L:a.parseLength}[r.toUpperCase()](q):{a:l,n:n[0],t:k}[r],void 0===p)return;n.push(p)}if(e.push({t:g,d:n}),d.lastIndex==b.length)return e}}function e(a){return a.toFixed(6).replace(".000000","")}function f(b,c){if(b.decompositionPair!==c){b.decompositionPair=c;var d=a.makeMatrixDecomposition(b)}if(c.decompositionPair!==b){c.decompositionPair=b;var f=a.makeMatrixDecomposition(c)}return null==d[0]||null==f[0]?[[!1],[!0],function(a){return a?c[0].d:b[0].d}]:(d[0].push(0),f[0].push(1),[d,f,function(b){var c=a.quat(d[0][3],f[0][3],b[5]),g=a.composeMatrix(b[0],b[1],b[2],c,b[4]),h=g.map(e).join(",");return h}])}function g(a){return a.replace(/[xy]/,"")}function h(a){return a.replace(/(x|y|z|3d)?$/,"3d")}function i(b,c){var d=a.makeMatrixDecomposition&&!0,e=!1;if(!b.length||!c.length){b.length||(e=!0,b=c,c=[]);for(var i=0;i<b.length;i++){var j=b[i].t,k=b[i].d,l="scale"==j.substr(0,5)?1:0;c.push({t:j,d:k.map(function(a){if("number"==typeof a)return l;var b={};for(var c in a)b[c]=l;return b})})}}var n=function(a,b){return"perspective"==a&&"perspective"==b||("matrix"==a||"matrix3d"==a)&&("matrix"==b||"matrix3d"==b)},o=[],p=[],q=[];if(b.length!=c.length){if(!d)return;var r=f(b,c);o=[r[0]],p=[r[1]],q=[["matrix",[r[2]]]]}else for(var i=0;i<b.length;i++){var j,s=b[i].t,t=c[i].t,u=b[i].d,v=c[i].d,w=m[s],x=m[t];if(n(s,t)){if(!d)return;var r=f([b[i]],[c[i]]);o.push(r[0]),p.push(r[1]),q.push(["matrix",[r[2]]])}else{if(s==t)j=s;else if(w[2]&&x[2]&&g(s)==g(t))j=g(s),u=w[2](u),v=x[2](v);else{if(!w[1]||!x[1]||h(s)!=h(t)){if(!d)return;var r=f(b,c);o=[r[0]],p=[r[1]],q=[["matrix",[r[2]]]];break}j=h(s),u=w[1](u),v=x[1](v)}for(var y=[],z=[],A=[],B=0;B<u.length;B++){var C="number"==typeof u[B]?a.mergeNumbers:a.mergeDimensions,r=C(u[B],v[B]);y[B]=r[0],z[B]=r[1],A.push(r[2])}o.push(y),p.push(z),q.push([j,A])}}if(e){var D=o;o=p,p=D}return[o,p,function(a){return a.map(function(a,b){var c=a.map(function(a,c){return q[b][1][c](a)}).join(",");return"matrix"==q[b][0]&&16==c.split(",").length&&(q[b][0]="matrix3d"),q[b][0]+"("+c+")"}).join(" ")}]}var j=null,k={px:0},l={deg:0},m={matrix:["NNNNNN",[j,j,0,0,j,j,0,0,0,0,1,0,j,j,0,1],c],matrix3d:["NNNNNNNNNNNNNNNN",c],rotate:["A"],rotatex:["A"],rotatey:["A"],rotatez:["A"],rotate3d:["NNNA"],perspective:["L"],scale:["Nn",b([j,j,1]),c],scalex:["N",b([j,1,1]),b([j,1])],scaley:["N",b([1,j,1]),b([1,j])],scalez:["N",b([1,1,j])],scale3d:["NNN",c],skew:["Aa",null,c],skewx:["A",null,b([j,l])],skewy:["A",null,b([l,j])],translate:["Tt",b([j,j,k]),c],translatex:["T",b([j,k,k]),b([j,k])],translatey:["T",b([k,j,k]),b([k,j])],translatez:["L",b([k,k,j])],translate3d:["TTL",c]};a.addPropertiesHandler(d,i,["transform"])}(d,f),function(a){function b(a,b){b.concat([a]).forEach(function(b){b in document.documentElement.style&&(c[a]=b)})}var c={};b("transform",["webkitTransform","msTransform"]),b("transformOrigin",["webkitTransformOrigin"]),b("perspective",["webkitPerspective"]),b("perspectiveOrigin",["webkitPerspectiveOrigin"]),a.propertyName=function(a){return c[a]||a}}(d,f)}(),!function(a,b){function c(a){var b=window.document.timeline;b.currentTime=a,b._discardAnimations(),0==b._animations.length?e=!1:requestAnimationFrame(c)}var d=window.requestAnimationFrame;window.requestAnimationFrame=function(a){return d(function(b){window.document.timeline._updateAnimationsPromises(),a(b),window.document.timeline._updateAnimationsPromises()})},b.AnimationTimeline=function(){this._animations=[],this.currentTime=void 0},b.AnimationTimeline.prototype={getAnimations:function(){return this._discardAnimations(),this._animations.slice()},getAnimationPlayers:function(){return a.deprecated("AnimationTimeline.getAnimationPlayers","2015-03-23","Use AnimationTimeline.getAnimations instead."),this.getAnimations()},_updateAnimationsPromises:function(){b.animationsWithPromises=b.animationsWithPromises.filter(function(a){return a._updatePromises()})},_discardAnimations:function(){this._updateAnimationsPromises(),this._animations=this._animations.filter(function(a){return"finished"!=a.playState&&"idle"!=a.playState})},_play:function(a){var c=new b.Animation(a);return this._animations.push(c),b.restartWebAnimationsNextTick(),c._updatePromises(),c._animation.play(),c._updatePromises(),c},play:function(a){return a&&a.remove(),this._play(a)}};var e=!1;b.restartWebAnimationsNextTick=function(){e||(e=!0,requestAnimationFrame(c))};var f=new b.AnimationTimeline;b.timeline=f;try{Object.defineProperty(window.document,"timeline",{configurable:!0,get:function(){return f}})}catch(g){}try{window.document.timeline=f}catch(g){}}(c,e,f),function(a,b){b.animationsWithPromises=[],b.Animation=function(b){this.effect=b,b&&(b._animation=this),this._sequenceNumber=a.sequenceNumber++,this._holdTime=0,this._paused=!1,this._isGroup=!1,this._animation=null,this._childAnimations=[],this._callback=null,this._oldPlayState="idle",this._rebuildUnderlyingAnimation(),this._animation.cancel(),this._updatePromises()},b.Animation.prototype={_updatePromises:function(){var a=this._oldPlayState,b=this.playState;return this._readyPromise&&b!==a&&("idle"==b?(this._rejectReadyPromise(),this._readyPromise=void 0):"pending"==a?this._resolveReadyPromise():"pending"==b&&(this._readyPromise=void 0)),this._finishedPromise&&b!==a&&("idle"==b?(this._rejectFinishedPromise(),this._finishedPromise=void 0):"finished"==b?this._resolveFinishedPromise():"finished"==a&&(this._finishedPromise=void 0)),this._oldPlayState=this.playState,this._readyPromise||this._finishedPromise},_rebuildUnderlyingAnimation:function(){this._updatePromises();var a,c,d,e,f=this._animation?!0:!1;f&&(a=this.playbackRate,c=this._paused,d=this.startTime,e=this.currentTime,this._animation.cancel(),this._animation._wrapper=null,this._animation=null),(!this.effect||this.effect instanceof window.KeyframeEffect)&&(this._animation=b.newUnderlyingAnimationForKeyframeEffect(this.effect),b.bindAnimationForKeyframeEffect(this)),(this.effect instanceof window.SequenceEffect||this.effect instanceof window.GroupEffect)&&(this._animation=b.newUnderlyingAnimationForGroup(this.effect),b.bindAnimationForGroup(this)),f&&(1!=a&&(this.playbackRate=a),null!==d?this.startTime=d:null!==e?this.currentTime=e:null!==this._holdTime&&(this.currentTime=this._holdTime),c&&this.pause()),this._updatePromises()},_updateChildren:function(){if(this.effect&&"idle"!=this.playState){var a=this.effect._timing.delay;this._childAnimations.forEach(function(c){this._arrangeChildren(c,a),this.effect instanceof window.SequenceEffect&&(a+=b.groupChildDuration(c.effect))}.bind(this))}},_setExternalAnimation:function(a){if(this.effect&&this._isGroup)for(var b=0;b<this.effect.children.length;b++)this.effect.children[b]._animation=a,this._childAnimations[b]._setExternalAnimation(a)},_constructChildAnimations:function(){if(this.effect&&this._isGroup){var a=this.effect._timing.delay;this._removeChildAnimations(),this.effect.children.forEach(function(c){var d=window.document.timeline._play(c);this._childAnimations.push(d),d.playbackRate=this.playbackRate,this._paused&&d.pause(),c._animation=this.effect._animation,this._arrangeChildren(d,a),this.effect instanceof window.SequenceEffect&&(a+=b.groupChildDuration(c))
+}.bind(this))}},_arrangeChildren:function(a,b){null===this.startTime?a.currentTime=this.currentTime-b/this.playbackRate:a.startTime!==this.startTime+b/this.playbackRate&&(a.startTime=this.startTime+b/this.playbackRate)},get playState(){return this._animation?this._animation.playState:"idle"},get finished(){return window.Promise?(this._finishedPromise||(-1==b.animationsWithPromises.indexOf(this)&&b.animationsWithPromises.push(this),this._finishedPromise=new Promise(function(a,b){this._resolveFinishedPromise=function(){a(this)},this._rejectFinishedPromise=function(){b({type:DOMException.ABORT_ERR,name:"AbortError"})}}.bind(this)),"finished"==this.playState&&this._resolveFinishedPromise()),this._finishedPromise):(console.warn("Animation Promises require JavaScript Promise constructor"),null)},get ready(){return window.Promise?(this._readyPromise||(-1==b.animationsWithPromises.indexOf(this)&&b.animationsWithPromises.push(this),this._readyPromise=new Promise(function(a,b){this._resolveReadyPromise=function(){a(this)},this._rejectReadyPromise=function(){b({type:DOMException.ABORT_ERR,name:"AbortError"})}}.bind(this)),"pending"!==this.playState&&this._resolveReadyPromise()),this._readyPromise):(console.warn("Animation Promises require JavaScript Promise constructor"),null)},get onfinish(){return this._onfinish},set onfinish(a){"function"==typeof a?(this._onfinish=a,this._animation.onfinish=function(b){b.target=this,a.call(this,b)}.bind(this)):(this._animation.onfinish=a,this.onfinish=this._animation.onfinish)},get currentTime(){this._updatePromises();var a=this._animation.currentTime;return this._updatePromises(),a},set currentTime(a){this._updatePromises(),this._animation.currentTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE,this._register(),this._forEachChild(function(b,c){b.currentTime=a-c}),this._updatePromises()},get startTime(){return this._animation.startTime},set startTime(a){this._updatePromises(),this._animation.startTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE,this._register(),this._forEachChild(function(b,c){b.startTime=a+c}),this._updatePromises()},get playbackRate(){return this._animation.playbackRate},set playbackRate(a){this._updatePromises();var b=this.currentTime;this._animation.playbackRate=a,this._forEachChild(function(b){b.playbackRate=a}),"paused"!=this.playState&&"idle"!=this.playState&&this.play(),null!==b&&(this.currentTime=b),this._updatePromises()},get source(){return a.deprecated("Animation.source","2015-03-23","Use Animation.effect instead."),this.effect},play:function(){this._updatePromises(),this._paused=!1,this._animation.play(),-1==document.timeline._animations.indexOf(this)&&document.timeline._animations.push(this),this._register(),b.awaitStartTime(this),this._forEachChild(function(a){var b=a.currentTime;a.play(),a.currentTime=b}),this._updatePromises()},pause:function(){this._updatePromises(),this.currentTime&&(this._holdTime=this.currentTime),this._animation.pause(),this._register(),this._forEachChild(function(a){a.pause()}),this._paused=!0,this._updatePromises()},finish:function(){this._updatePromises(),this._animation.finish(),this._register(),this._updatePromises()},cancel:function(){this._updatePromises(),this._animation.cancel(),this._register(),this._removeChildAnimations(),this._updatePromises()},reverse:function(){this._updatePromises();var a=this.currentTime;this._animation.reverse(),this._forEachChild(function(a){a.reverse()}),null!==a&&(this.currentTime=a),this._updatePromises()},addEventListener:function(a,b){var c=b;"function"==typeof b&&(c=function(a){a.target=this,b.call(this,a)}.bind(this),b._wrapper=c),this._animation.addEventListener(a,c)},removeEventListener:function(a,b){this._animation.removeEventListener(a,b&&b._wrapper||b)},_removeChildAnimations:function(){for(;this._childAnimations.length;)this._childAnimations.pop().cancel()},_forEachChild:function(b){var c=0;if(this.effect.children&&this._childAnimations.length<this.effect.children.length&&this._constructChildAnimations(),this._childAnimations.forEach(function(a){b.call(this,a,c),this.effect instanceof window.SequenceEffect&&(c+=a.effect.activeDuration)}.bind(this)),"pending"!=this.playState){var d=this.effect._timing,e=this.currentTime;null!==e&&(e=a.calculateTimeFraction(a.calculateActiveDuration(d),e,d)),(null==e||isNaN(e))&&this._removeChildAnimations()}}}}(c,e,f),function(a,b){function c(b){this._frames=a.normalizeKeyframes(b)}function d(){for(var a=!1;h.length;){var b=h.shift();b._updateChildren(),a=!0}return a}var e=function(a){if(a._animation=void 0,a instanceof window.SequenceEffect||a instanceof window.GroupEffect)for(var b=0;b<a.children.length;b++)e(a.children[b])};b.removeMulti=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c];d._parent?(-1==b.indexOf(d._parent)&&b.push(d._parent),d._parent.children.splice(d._parent.children.indexOf(d),1),d._parent=null,e(d)):d._animation&&d._animation.effect==d&&(d._animation.cancel(),d._animation.effect=new KeyframeEffect(null,[]),d._animation._callback&&(d._animation._callback._animation=null),d._animation._rebuildUnderlyingAnimation(),e(d))}for(c=0;c<b.length;c++)b[c]._rebuild()},b.KeyframeEffect=function(b,d,e){return this.target=b,this._timingInput=a.cloneTimingInput(e),this._timing=a.normalizeTimingInput(e),this.timing=a.makeTiming(e),this._normalizedKeyframes="function"==typeof d?d:new c(d),this._keyframes=d,this.activeDuration=a.calculateActiveDuration(this._timing),this},b.KeyframeEffect.prototype={getFrames:function(){return"function"==typeof this._normalizedKeyframes?this._normalizedKeyframes:this._normalizedKeyframes._frames},get effect(){return a.deprecated("KeyframeEffect.effect","2015-03-23","Use KeyframeEffect.getFrames() instead."),this._normalizedKeyframes},clone:function(){if("function"==typeof this.getFrames())throw new Error("Cloning custom effects is not supported.");var b=new KeyframeEffect(this.target,[],a.cloneTimingInput(this._timingInput));return b._normalizedKeyframes=this._normalizedKeyframes,b._keyframes=this._keyframes,b},remove:function(){b.removeMulti([this])}};var f=Element.prototype.animate;Element.prototype.animate=function(a,c){return b.timeline._play(new b.KeyframeEffect(this,a,c))};var g=document.createElementNS("http://www.w3.org/1999/xhtml","div");b.newUnderlyingAnimationForKeyframeEffect=function(a){if(a){var b=a.target||g,c=a._keyframes;"function"==typeof c&&(c=[]);var d=a._timingInput}else var b=g,c=[],d=0;return f.apply(b,[c,d])},b.bindAnimationForKeyframeEffect=function(a){a.effect&&"function"==typeof a.effect._normalizedKeyframes&&b.bindAnimationForCustomEffect(a)};var h=[];b.awaitStartTime=function(a){null===a.startTime&&a._isGroup&&(0==h.length&&requestAnimationFrame(d),h.push(a))};var i=window.getComputedStyle;Object.defineProperty(window,"getComputedStyle",{configurable:!0,enumerable:!0,value:function(){window.document.timeline._updateAnimationsPromises();var a=i.apply(this,arguments);return d()&&(a=i.apply(this,arguments)),window.document.timeline._updateAnimationsPromises(),a}}),window.KeyframeEffect=b.KeyframeEffect,window.Element.prototype.getAnimations=function(){return document.timeline.getAnimations().filter(function(a){return null!==a.effect&&a.effect.target==this}.bind(this))},window.Element.prototype.getAnimationPlayers=function(){return a.deprecated("Element.getAnimationPlayers","2015-03-23","Use Element.getAnimations instead."),this.getAnimations()},window.Animation=function(){a.deprecated("window.Animation","2015-03-23","Use window.KeyframeEffect instead."),window.KeyframeEffect.apply(this,arguments)},window.Animation.prototype=Object.create(window.KeyframeEffect.prototype),window.Animation.prototype.constructor=window.Animation}(c,e,f),function(a,b){function c(a){a._registered||(a._registered=!0,f.push(a),g||(g=!0,requestAnimationFrame(d)))}function d(){var a=f;f=[],a.sort(function(a,b){return a._sequenceNumber-b._sequenceNumber}),a=a.filter(function(a){a();var b=a._animation?a._animation.playState:"idle";return"running"!=b&&"pending"!=b&&(a._registered=!1),a._registered}),f.push.apply(f,a),f.length?(g=!0,requestAnimationFrame(d)):g=!1}var e=(document.createElementNS("http://www.w3.org/1999/xhtml","div"),0);b.bindAnimationForCustomEffect=function(b){var d=b.effect.target,f=b.effect._normalizedKeyframes,g=b.effect.timing,h=null;g=a.normalizeTimingInput(g);var i=function(){var c=i._animation?i._animation.currentTime:null;null!==c&&(c=a.calculateTimeFraction(a.calculateActiveDuration(g),c,g),isNaN(c)&&(c=null)),c!==h&&f(c,d,b.effect),h=c};i._animation=b,i._registered=!1,i._sequenceNumber=e++,b._callback=i,c(i)};var f=[],g=!1;b.Animation.prototype._register=function(){this._callback&&c(this._callback)}}(c,e,f),function(a,b){function c(a){return a._timing.delay+a.activeDuration+a._timing.endDelay}function d(b,c){this._parent=null,this.children=b||[],this._reparent(this.children),this._timingInput=a.cloneTimingInput(c),this._timing=a.normalizeTimingInput(c,!0),this.timing=a.makeTiming(c,!0),"auto"===this._timing.duration&&(this._timing.duration=this.activeDuration)}window.SequenceEffect=function(){d.apply(this,arguments)},window.GroupEffect=function(){d.apply(this,arguments)},d.prototype={_isAncestor:function(a){for(var b=this;null!==b;){if(b==a)return!0;b=b._parent}return!1},_rebuild:function(){for(var a=this;a;)"auto"===a.timing.duration&&(a._timing.duration=a.activeDuration),a=a._parent;this._animation&&this._animation._rebuildUnderlyingAnimation()},_reparent:function(a){b.removeMulti(a);for(var c=0;c<a.length;c++)a[c]._parent=this},_putChild:function(a,b){for(var c=b?"Cannot append an ancestor or self":"Cannot prepend an ancestor or self",d=0;d<a.length;d++)if(this._isAncestor(a[d]))throw{type:DOMException.HIERARCHY_REQUEST_ERR,name:"HierarchyRequestError",message:c};for(var d=0;d<a.length;d++)b?this.children.push(a[d]):this.children.unshift(a[d]);this._reparent(a),this._rebuild()},append:function(){this._putChild(arguments,!0)},prepend:function(){this._putChild(arguments,!1)},get firstChild(){return this.children.length?this.children[0]:null},get lastChild(){return this.children.length?this.children[this.children.length-1]:null},clone:function(){for(var b=a.cloneTimingInput(this._timingInput),c=[],d=0;d<this.children.length;d++)c.push(this.children[d].clone());return this instanceof GroupEffect?new GroupEffect(c,b):new SequenceEffect(c,b)},remove:function(){b.removeMulti([this])}},window.SequenceEffect.prototype=Object.create(d.prototype),Object.defineProperty(window.SequenceEffect.prototype,"activeDuration",{get:function(){var a=0;return this.children.forEach(function(b){a+=c(b)}),Math.max(a,0)}}),window.GroupEffect.prototype=Object.create(d.prototype),Object.defineProperty(window.GroupEffect.prototype,"activeDuration",{get:function(){var a=0;return this.children.forEach(function(b){a=Math.max(a,c(b))}),a}}),b.newUnderlyingAnimationForGroup=function(c){var d,e=null,f=function(b){var c=d._wrapper;return c&&"pending"!=c.playState&&c.effect?null==b?void c._removeChildAnimations():0==b&&c.playbackRate<0&&(e||(e=a.normalizeTimingInput(c.effect.timing)),b=a.calculateTimeFraction(a.calculateActiveDuration(e),-1,e),isNaN(b)||null==b)?(c._forEachChild(function(a){a.currentTime=-1}),void c._removeChildAnimations()):void 0:void 0};return d=b.timeline._play(new b.KeyframeEffect(null,f,c._timing))},b.bindAnimationForGroup=function(a){a._animation._wrapper=a,a._isGroup=!0,b.awaitStartTime(a),a._constructChildAnimations(),a._setExternalAnimation(a)},b.groupChildDuration=c,window.AnimationSequence=function(){a.deprecated("window.AnimationSequence","2015-03-23","Use window.SequenceEffect instead."),window.SequenceEffect.apply(this,arguments)},window.AnimationSequence.prototype=Object.create(window.SequenceEffect.prototype),window.AnimationSequence.prototype.constructor=window.AnimationSequence,window.AnimationGroup=function(){a.deprecated("window.AnimationGroup","2015-03-23","Use window.GroupEffect instead."),window.GroupEffect.apply(this,arguments)},window.AnimationGroup.prototype=Object.create(window.GroupEffect.prototype),window.AnimationGroup.prototype.constructor=window.AnimationGroup}(c,e,f)}({},function(){return this}());
+//# sourceMappingURL=web-animations-next-lite.min.js.map
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/web-animations-js/web-animations-next-lite.min.js.map b/polymer_1.0.4/bower_components/web-animations-js/web-animations-next-lite.min.js.map
new file mode 100644
index 0000000..61fcb9f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/web-animations-js/web-animations-next-lite.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"web-animations-next-lite.min.js","sources":["src/scope.js","src/timing-utilities.js","src/normalize-keyframes.js","src/deprecation.js","src/keyframe-interpolations.js","src/timeline.js","src/web-animations-next-animation.js","src/keyframe-effect-constructor.js","src/effect-callback.js","src/group-constructors.js"],"names":["webAnimationsShared","webAnimations1","webAnimationsNext","webAnimationsTesting","shared","cloneTimingInput","timingInput","clone","m","makeTiming","forGroup","timing","delay","endDelay","fill","iterationStart","iterations","duration","playbackRate","direction","easing","isNaN","undefined","Object","getOwnPropertyNames","forEach","property","fills","indexOf","directions","isDeprecated","normalizeTimingInput","toTimingFunction","cubic","a","b","c","d","linear","x","f","start","end","mid","xEst","Math","abs","step","count","pos","stepSize","cubicData","cubicBezierRe","exec","apply","this","slice","map","Number","stepData","stepRe","Start","middle","Middle","End","preset","presets","calculateActiveDuration","repeatedDuration","calculatePhase","activeDuration","localTime","PhaseNone","PhaseBefore","PhaseAfter","PhaseActive","calculateActiveTime","fillMode","phase","calculateScaledActiveTime","activeTime","startOffset","calculateIterationTime","iterationDuration","scaledActiveTime","Infinity","calculateCurrentIteration","iterationTime","floor","calculateTransformedTime","currentIteration","currentIterationIsOdd","currentDirectionIsForwards","directedTime","timeFraction","calculateTimeFraction","split","ease","ease-in","ease-out","ease-in-out","step-start","step-middle","step-end","numberString","RegExp","antiAlias","value","aliases","expandShorthandAndAntiAlias","result","longProperties","shorthandToLonghand","shorthandExpanderElem","style","i","longProperty","longhandValue","normalizeKeyframes","effectInput","spaceKeyframes","length","keyframes","offset","previousIndex","previousOffset","j","Array","isArray","TypeError","originalKeyframe","keyframe","member","memberValue","isFinite","type","DOMException","NOT_SUPPORTED_ERR","name","message","everyFrameHasOffset","code","INVALID_MODIFICATION_ERR","filter","background","border","borderBottom","borderColor","borderLeft","borderRadius","borderRight","borderTop","borderWidth","flex","font","margin","outline","padding","document","createElementNS","borderWidthAliases","thin","medium","thick","borderBottomWidth","borderLeftWidth","borderRightWidth","borderTopWidth","fontSize","xx-small","x-small","small","large","x-large","xx-large","fontWeight","normal","bold","outlineWidth","textShadow","none","boxShadow","silenced","feature","date","advice","plural","auxVerb","today","Date","expiry","setMonth","getMonth","console","warn","toDateString","deprecated","Error","testing","makePropertySpecificKeyframeGroups","propertySpecificKeyframeGroups","propertySpecificKeyframe","groupName","group","scope","webAnimationsNextTick","t","timeline","window","currentTime","_discardAnimations","_animations","ticking","requestAnimationFrame","originalRequestAnimationFrame","_updateAnimationsPromises","AnimationTimeline","prototype","getAnimations","getAnimationPlayers","animationsWithPromises","animation","_updatePromises","playState","_play","effect","Animation","push","restartWebAnimationsNextTick","_animation","play","remove","defineProperty","configurable","get","e","_sequenceNumber","sequenceNumber","_holdTime","_paused","_isGroup","_childAnimations","_callback","_oldPlayState","_rebuildUnderlyingAnimation","cancel","oldPlayState","newPlayState","_readyPromise","_rejectReadyPromise","_resolveReadyPromise","_finishedPromise","_rejectFinishedPromise","_resolveFinishedPromise","oldPlaybackRate","oldPaused","oldStartTime","oldCurrentTime","hadUnderlying","startTime","_wrapper","KeyframeEffect","newUnderlyingAnimationForKeyframeEffect","bindAnimationForKeyframeEffect","SequenceEffect","GroupEffect","newUnderlyingAnimationForGroup","bindAnimationForGroup","pause","_updateChildren","_timing","childAnimation","_arrangeChildren","groupChildDuration","bind","_setExternalAnimation","children","_constructChildAnimations","_removeChildAnimations","child",{"end":{"file":"src/animation.js","comments_before":[],"nlb":false,"endpos":2487,"pos":2476,"col":8,"line":72,"value":"currentTime","type":"name"},"start":{"file":"src/animation.js","comments_before":[],"nlb":false,"endpos":2487,"pos":2476,"col":8,"line":72,"value":"currentTime","type":"name"},"name":"currentTime"},"finished","Promise","resolve","reject","ABORT_ERR","ready","onfinish","_onfinish","v","target","call","sign","MAX_VALUE","_register","_forEachChild","source","awaitStartTime","time","finish","reverse","addEventListener","handler","wrapped","removeEventListener","pop","KeyframeList","_frames","updatePendingGroups","updated","pendingGroups","shift","disassociate","removeMulti","effects","oldParents","_parent","splice","_rebuild","_timingInput","_normalizedKeyframes","_keyframes","getFrames","originalElementAnimate","Element","animate","nullTarget","keyframeEffect","bindAnimationForCustomEffect","groupAnimation","originalGetComputedStyle","getComputedStyle","enumerable","arguments","create","constructor","register","callback","_registered","callbacks","tick","updating","sort","left","right","effectFunction","last","node","_reparent","_isAncestor","newChildren","_putChild","args","isAppend","HIERARCHY_REQUEST_ERR","unshift","append","prepend","firstChild","lastChild","clonedTiming","clonedChildren","total","max","underlyingAnimation","ticker","tf","AnimationSequence","AnimationGroup"],"mappings":";;;;;;;;;;;;;;CAcA,SAAIA,EAAAA,GACAC,EAAAA,QACAC,CAFJ,IAAIF,MACAC,KACAC,KAGEC,EAAuB,MCL7B,SAAUC,GAKR,QAASC,GAAiBC,GACxB,GAA0B,gBAAfA,GACT,MAAOA,EAET,IAAIC,KACJ,KAAK,GAAIC,KAAKF,GACZC,EAAMC,GAAKF,EAAYE,EAEzB,OAAOD,GAGT,QAASE,GAAWH,EAAaI,GAC/B,GAAIC,IACFC,MAAO,EACPC,SAAU,EACVC,KAAMJ,EAAW,OAAS,OAC1BK,eAAgB,EAChBC,WAAY,EACZC,SAAUP,EAAW,OAAS,EAC9BQ,aAAc,EACdC,UAAW,SACXC,OAAQ,SAyBV,OAvB0B,gBAAfd,IAA4Be,MAAMf,GAElBgB,SAAhBhB,GACTiB,OAAOC,oBAAoBlB,GAAamB,QAAQ,SAASC,GACvD,GAA6B,QAAzBpB,EAAYoB,GAAqB,CACnC,IAA+B,gBAApBf,GAAOe,IAAqC,YAAZA,KACL,gBAAzBpB,GAAYoB,IAAyBL,MAAMf,EAAYoB,KAChE,MAGJ,IAAiB,QAAZA,GAAgE,IAAxCC,EAAMC,QAAQtB,EAAYoB,IACrD,MAEF,IAAiB,aAAZA,GAA0E,IAA7CG,EAAWD,QAAQtB,EAAYoB,IAC/D,MAEF,IAAgB,gBAAZA,GAAwD,IAA1BpB,EAAYoB,IAAmBtB,EAAO0B,aAAa,qCAAsC,aAAc,uCACvI,MAEFnB,GAAOe,GAAYpB,EAAYoB,MAlBnCf,EAAOM,SAAWX,EAsBbK,EAGT,QAASoB,GAAqBzB,EAAaI,GACzC,GAAIC,GAASF,EAAWH,EAAaI,EAErC,OADAC,GAAOS,OAASY,EAAiBrB,EAAOS,QACjCT,EAGT,QAASsB,GAAMC,EAAGC,EAAGC,EAAGC,GACtB,MAAQ,GAAJH,GAASA,EAAI,GAAS,EAAJE,GAASA,EAAI,EAC1BE,EAEF,SAASC,GAOZ,QAASC,GAAEN,EAAGC,EAAG3B,GAAK,MAAO,GAAI0B,GAAK,EAAI1B,IAAM,EAAIA,GAAKA,EAAI,EAAI2B,GAAK,EAAI3B,GAAKA,EAAIA,EAAIA,EAAIA,EAAIA,EANjG,GAAS,GAAL+B,GAAe,GAALA,EACZ,MAAOA,EAGT,KADA,GAAIE,GAAQ,EAAGC,EAAM,IACX,CACR,GAAIC,IAAOF,EAAQC,GAAO,EAEtBE,EAAOJ,EAAEN,EAAGE,EAAGO,EACnB,IAAIE,KAAKC,IAAIP,EAAIK,GAAQ,KACvB,MAAOJ,GAAEL,EAAGE,EAAGM,EAENJ,GAAPK,EACFH,EAAQE,EAERD,EAAMC,IAUd,QAASI,GAAKC,EAAOC,GACnB,MAAO,UAASV,GACd,GAAIA,GAAK,EACP,MAAO,EAET,IAAIW,GAAW,EAAIF,CAEnB,OADAT,IAAKU,EAAMC,EACJX,EAAIA,EAAIW,GAmBnB,QAASlB,GAAiBZ,GACxB,GAAI+B,GAAYC,EAAcC,KAAKjC,EACnC,IAAI+B,EACF,MAAOlB,GAAMqB,MAAMC,KAAMJ,EAAUK,MAAM,GAAGC,IAAIC,QAElD,IAAIC,GAAWC,EAAOP,KAAKjC,EAC3B,IAAIuC,EACF,MAAOZ,GAAKW,OAAOC,EAAS,KAAMlB,MAASoB,EAAOC,OAAUC,EAAQrB,IAAOsB,GAAKL,EAAS,IAE3F,IAAIM,GAASC,EAAQ9C,EACrB,OAAI6C,GACKA,EAEF3B,EAGT,QAAS6B,GAAwBxD,GAC/B,MAAOkC,MAAKC,IAAIsB,EAAiBzD,GAAUA,EAAOO,cAGpD,QAASkD,GAAiBzD,GACxB,MAAOA,GAAOM,SAAWN,EAAOK,WAQlC,QAASqD,GAAeC,EAAgBC,EAAW5D,GACjD,MAAiB,OAAb4D,EACKC,EAELD,EAAY5D,EAAOC,MACd6D,EAELF,GAAa5D,EAAOC,MAAQ0D,EACvBI,EAEFC,EAGT,QAASC,GAAoBN,EAAgBO,EAAUN,EAAWO,EAAOlE,GACvE,OAAQkE,GACN,IAAKL,GACH,MAAgB,aAAZI,GAAuC,QAAZA,EACtB,EACF,IACT,KAAKF,GACH,MAAOJ,GAAY3D,CACrB,KAAK8D,GACH,MAAgB,YAAZG,GAAsC,QAAZA,EACrBP,EACF,IACT,KAAKE,GACH,MAAO,OAIb,QAASO,GAA0BT,EAAgBU,EAAYC,EAAatE,GAC1E,OAAQA,EAAOO,aAAe,EAAI8D,EAAaV,EAAiBU,GAAcrE,EAAOO,aAAe+D,EAGtG,QAASC,GAAuBC,EAAmBf,EAAkBgB,EAAkBH,EAAatE,GAClG,MAAyB0E,GAAAA,IAArBD,GAAiCA,IAAAA,GAAsBC,GAAaD,EAAmBH,GAAeb,GAAoBzD,EAAOK,aAAgBL,EAAOK,WAAaL,EAAOI,gBAAkB,GAAK,EAC9LoE,EAGFC,EAAmBD,EAG5B,QAASG,GAA0BH,EAAmBI,EAAeH,EAAkBzE,GACrF,MAAyB,KAArByE,EACK,EAELG,GAAiBJ,EACZxE,EAAOI,eAAiBJ,EAAOK,WAAa,EAE9C6B,KAAK2C,MAAMJ,EAAmBD,GAGvC,QAASM,GAAyBC,EAAkBP,EAAmBI,EAAe5E,GACpF,GAAIgF,GAAwBD,EAAmB,GAAK,EAChDE,EAAiD,UAApBjF,EAAOQ,WAAyBR,EAAOQ,YAAcwE,EAAwB,oBAAsB,aAChIE,EAAeD,EAA6BL,EAAgBJ,EAAoBI,EAChFO,EAAeD,EAAeV,CAClC,OAAOA,GAAoBxE,EAAOS,OAAO0E,GAG3C,QAASC,GAAsBzB,EAAgBC,EAAW5D,GACxD,GAAImE,GAAQT,EAAeC,EAAgBC,EAAW5D,GAClDqE,EAAaJ,EAAoBN,EAAgB3D,EAAOG,KAAMyD,EAAWO,EAAOnE,EAAOC,MAC3F,IAAmB,OAAfoE,EACF,MAAO,KACT,IAAuB,IAAnBV,EACF,MAAOQ,KAAUL,EAAc,EAAI,CACrC,IAAIQ,GAActE,EAAOI,eAAiBJ,EAAOM,SAC7CmE,EAAmBL,EAA0BT,EAAgBU,EAAYC,EAAatE,GACtF4E,EAAgBL,EAAuBvE,EAAOM,SAAUmD,EAAiBzD,GAASyE,EAAkBH,EAAatE,GACjH+E,EAAmBJ,EAA0B3E,EAAOM,SAAUsE,EAAeH,EAAkBzE,EACnG,OAAO8E,GAAyBC,EAAkB/E,EAAOM,SAAUsE,EAAe5E,GAAUA,EAAOM,SArNrG,GAAIU,GAAQ,+BAA+BqE,MAAM,KAC7CnE,EAAa,sCAAsCmE,MAAM,KAkFzDnC,EAAQ,EACRE,EAAS,GACTC,EAAM,EAaNE,GACF+B,KAAQhE,EAAM,IAAM,GAAK,IAAM,GAC/BiE,UAAWjE,EAAM,IAAM,EAAG,EAAG,GAC7BkE,WAAYlE,EAAM,EAAG,EAAG,IAAM,GAC9BmE,cAAenE,EAAM,IAAM,EAAG,IAAM,GACpCoE,aAActD,EAAK,EAAGc,GACtByC,cAAevD,EAAK,EAAGgB,GACvBwC,WAAYxD,EAAK,EAAGiB,IAGlBwC,EAAe,qCACfpD,EAAgB,GAAIqD,QAAO,kBAAoBD,EAAe,IAAMA,EAAe,IAAMA,EAAe,IAAMA,EAAe,OAC7H5C,EAAS,gDACTtB,EAAS,SAASC,GAAK,MAAOA,IA0B9BiC,EAAY,EACZC,EAAc,EACdC,EAAa,EACbC,EAAc,CA4ElBvE,GAAOC,iBAAmBA,EAC1BD,EAAOK,WAAaA,EACpBL,EAAO2B,qBAAuBA,EAC9B3B,EAAO+D,wBAA0BA,EACjC/D,EAAO2F,sBAAwBA,EAC/B3F,EAAOiE,eAAiBA,EACxBjE,EAAO4B,iBAAmBA,GAkBzBhC,EAAqBG,GClPxB,SAAUC,GAmIR,QAASsG,GAAUhF,EAAUiF,GAC3B,MAAIjF,KAAYkF,GACPA,EAAQlF,GAAUiF,IAAUA,EAE9BA,EAIT,QAASE,GAA4BnF,EAAUiF,EAAOG,GACpD,GAAIC,GAAiBC,EAAoBtF,EACzC,IAAIqF,EAAgB,CAClBE,EAAsBC,MAAMxF,GAAYiF,CACxC,KAAK,GAAIQ,KAAKJ,GAAgB,CAC5B,GAAIK,GAAeL,EAAeI,GAC9BE,EAAgBJ,EAAsBC,MAAME,EAChDN,GAAOM,GAAgBV,EAAUU,EAAcC,QAGjDP,GAAOpF,GAAYgF,EAAUhF,EAAUiF,GAI3C,QAASW,GAAmBC,GA4D1B,QAASC,KACP,GAAIC,GAASC,EAAUD,MACa,OAAhCC,EAAUD,EAAS,GAAGE,SACxBD,EAAUD,EAAS,GAAGE,OAAS,GAC7BF,EAAS,GAA4B,MAAvBC,EAAU,GAAGC,SAC7BD,EAAU,GAAGC,OAAS,EAIxB,KAAK,GAFDC,GAAgB,EAChBC,EAAiBH,EAAU,GAAGC,OACzBR,EAAI,EAAOM,EAAJN,EAAYA,IAAK,CAC/B,GAAIQ,GAASD,EAAUP,GAAGQ,MAC1B,IAAc,MAAVA,EAAgB,CAClB,IAAK,GAAIG,GAAI,EAAOX,EAAIS,EAARE,EAAuBA,IACrCJ,EAAUE,EAAgBE,GAAGH,OAASE,GAAkBF,EAASE,GAAkBC,GAAKX,EAAIS,EAC9FA,GAAgBT,EAChBU,EAAiBF,IA1EvB,IAAKI,MAAMC,QAAQT,IAAgC,OAAhBA,EACjC,KAAM,IAAIU,WAAU,kDAEtB,IAAmB,MAAfV,EACF,QAmCF,KAAK,GAjCDG,GAAYH,EAAY9D,IAAI,SAASyE,GACvC,GAAIC,KACJ,KAAK,GAAIC,KAAUF,GAAkB,CACnC,GAAIG,GAAcH,EAAiBE,EACnC,IAAc,UAAVA,GACF,GAAmB,MAAfC,IACFA,EAAc3E,OAAO2E,IAChBC,SAASD,IACZ,KAAM,IAAIJ,WAAU,yCAEnB,CAAA,GAAc,aAAVG,EACT,MACEG,KAAMC,aAAaC,kBACnBC,KAAM,oBACNC,QAAS,mCAGXN,GADmB,UAAVD,EACKhI,EAAO4B,iBAAiBqG,GAExB,GAAKA,EAErBxB,EAA4BuB,EAAQC,EAAaF,GAMnD,MAJuB7G,SAAnB6G,EAASR,SACXQ,EAASR,OAAS,MACGrG,QAAnB6G,EAAS/G,SACX+G,EAAS/G,OAAShB,EAAO4B,iBAAiB,WACrCmG,IAGLS,GAAAA,EAEAf,EAAAA,GAAkBxC,EACb8B,EAAI,EAAGA,EAAIO,EAAUD,OAAQN,IAAK,CACzC,GAAIQ,GAASD,EAAUP,GAAGQ,MAC1B,IAAc,MAAVA,EAAgB,CAClB,GAAaE,EAATF,EACF,MACEkB,KAAML,aAAaM,yBACnBJ,KAAM,2BACNC,QAAS,uEAGbd,GAAiBF,MAEjBiB,IAAAA,EA8BJ,MA1BAlB,GAAYA,EAAUqB,OAAO,SAASZ,GACpC,MAAOA,GAASR,QAAU,GAAKQ,EAASR,QAAU,IAsB/CiB,GACHpB,IAEKE,EA1OT,GAAIV,IACFgC,YACE,kBACA,qBACA,iBACA,mBACA,uBACA,mBACA,iBACA,mBAEFC,QACE,iBACA,iBACA,iBACA,mBACA,mBACA,mBACA,oBACA,oBACA,oBACA,kBACA,kBACA,mBAEFC,cACE,oBACA,oBACA,qBAEFC,aACE,iBACA,mBACA,oBACA,mBAEFC,YACE,kBACA,kBACA,mBAEFC,cACE,sBACA,uBACA,0BACA,0BAEFC,aACE,mBACA,mBACA,oBAEFC,WACE,iBACA,iBACA,kBAEFC,aACE,iBACA,mBACA,oBACA,mBAEFC,MACE,WACA,aACA,aAEFC,MACE,aACA,WACA,YACA,cACA,aACA,cAEFC,QACE,YACA,cACA,eACA,cAEFC,SACE,eACA,eACA,gBAEFC,SACE,aACA,eACA,gBACA,gBAIA5C,EAAwB6C,SAASC,gBAAgB,+BAAgC,OAEjFC,GACFC,KAAM,MACNC,OAAQ,MACRC,MAAO,OAGLvD,GACFwD,kBAAmBJ,EACnBK,gBAAiBL,EACjBM,iBAAkBN,EAClBO,eAAgBP,EAChBQ,UACEC,WAAY,MACZC,UAAW,MACXC,MAAS,MACTT,OAAU,OACVU,MAAS,OACTC,UAAW,OACXC,WAAY,QAEdC,YACEC,OAAQ,MACRC,KAAM,OAERC,aAAclB,EACdmB,YACEC,KAAM,2BAERC,WACED,KAAM,+BA+GVhL,GAAOkH,mBAAqBA,GAM3BtH,EAAqBG,GCpPxB,SAAUC,GAER,GAAIkL,KAEJlL,GAAO0B,aAAe,SAASyJ,EAASC,EAAMC,EAAQC,GACpD,GAAIC,GAAUD,EAAS,MAAQ,KAC3BE,EAAQ,GAAIC,MACZC,EAAS,GAAID,MAAKL,EAGtB,OAFAM,GAAOC,SAASD,EAAOE,WAAa,GAExBF,EAARF,GACIL,IAAWD,IACfW,QAAQC,KAAK,mBAAqBX,EAAU,IAAMI,EAAU,wCAA0CG,EAAOK,eAAiB,KAAOV,GAEvIH,EAASC,IAAAA,GAAW,IACb,GAMXnL,EAAOgM,WAAa,SAASb,EAASC,EAAMC,EAAQC,GAClD,GAAIC,GAAUD,EAAS,MAAQ,IAC/B,IAAItL,EAAO0B,aAAayJ,EAASC,EAAMC,EAAQC,GAC7C,KAAM,IAAIW,OAAMd,EAAU,IAAMI,EAAU,yBAA2BF,KAIxEzL,6mpBC5BH,qBAAyBsM,EA2BdC,GAAAA,eAAAA,EAGP,GAFIC,SAAAA,GAAAA,QAEgB9E,GAAAA,EAAUD,GAC5B,EAASW,QAAAA,IAAUV,QACjB,SAAc,GAAVU,IAAsBA,UAAgC,gBAAVA,QAC1CqE,EAAAA,GAAAA,KACF9E,GAAQD,KAAUP,GAAGQ,aACbD,kBACRf,gBAAiBQ,EAAGiB,mBAEtBoE,0BAAyCA,EAAAA,eAAAA,sBACzCA,EAAAA,qBAAAA,4BAA4CC,EAAAA,aAK7C,SAAIC,GAAaF,MAAAA,GAAAA,IAAAA,IAChBG,EAAQH,OC5ClB,SAAUpM,EAAQwM,GAkEhB,QAASC,GAAsBC,GAC7B,GAAIC,GAAWC,OAAOlD,SAASiD,QAC/BA,GAASE,YAAcH,EACvBC,EAASG,qBAC0B,GAA/BH,EAASI,YAAY1F,OACvB2F,GAAAA,EAEAC,sBAAsBR,GAxE1B,GAAIS,GAAgCN,OAAOK,qBAC3CL,QAAOK,sBAAwB,SAAS7K,GACtC,MAAO8K,GAA8B,SAAS/K,GAC5CyK,OAAOlD,SAASiD,SAASQ,4BACzB/K,EAAED,GACFyK,OAAOlD,SAASiD,SAASQ,+BAI7BX,EAAMY,kBAAoB,WACxBjK,KAAK4J,eACL5J,KAAK0J,YAAc3L,QAGrBsL,EAAMY,kBAAkBC,WACtBC,cAAe,WAEb,MADAnK,MAAK2J,qBACE3J,KAAK4J,YAAY3J,SAE1BmK,oBAAqB,WAEnB,MADAvN,GAAOgM,WAAW,wCAAyC,aAAc,gDAClE7I,KAAKmK,iBAEdH,0BAA2B,WACzBX,EAAMgB,uBAAyBhB,EAAMgB,uBAAuB7E,OAAO,SAAS8E,GAC1E,MAAOA,GAAUC,qBAGrBZ,mBAAoB,WAClB3J,KAAKgK,4BACLhK,KAAK4J,YAAc5J,KAAK4J,YAAYpE,OAAO,SAAS8E,GAClD,MAA8B,YAAvBA,EAAUE,WAAkD,QAAvBF,EAAUE,aAG1DC,MAAO,SAASC,GACd,GAAIJ,GAAY,GAAIjB,GAAMsB,UAAUD,EAWpC,OAVA1K,MAAK4J,YAAYgB,KAAKN,GACtBjB,EAAMwB,+BAMNP,EAAUC,kBACVD,EAAUQ,WAAWC,OACrBT,EAAUC,kBACHD,GAETS,KAAM,SAASL,GAIb,MAHIA,IACFA,EAAOM,SAEFhL,KAAKyK,MAAMC,IAItB,IAAIb,IAAAA,CAEJR,GAAMwB,6BAA+B,WAC9BhB,IACHA,GAAAA,EACAC,sBAAsBR,IAc1B,IAAIE,GAAW,GAAIH,GAAMY,iBACzBZ,GAAMG,SAAWA,CAEjB,KACExL,OAAOiN,eAAexB,OAAOlD,SAAU,YACrC2E,cAAAA,EACAC,IAAK,WAAa,MAAO3B,MAE3B,MAAO4B,IACT,IACE3B,OAAOlD,SAASiD,SAAWA,EAC3B,MAAO4B,MAER3O,EAAqBE,EAAmBC,GC1F3C,SAAUC,EAAQwM,GAChBA,EAAMgB,0BAENhB,EAAMsB,UAAY,SAASD,GACzB1K,KAAK0K,OAASA,EACVA,IACFA,EAAOI,WAAa9K,MAEtBA,KAAKqL,gBAAkBxO,EAAOyO,iBAC9BtL,KAAKuL,UAAY,EACjBvL,KAAKwL,SAAAA,EACLxL,KAAKyL,UAAAA,EACLzL,KAAK8K,WAAa,KAClB9K,KAAK0L,oBACL1L,KAAK2L,UAAY,KACjB3L,KAAK4L,cAAgB,OACrB5L,KAAK6L,8BAEL7L,KAAK8K,WAAWgB,SAChB9L,KAAKuK,mBAGPlB,EAAMsB,UAAUT,WACdK,gBAAiB,WACf,GAAIwB,GAAe/L,KAAK4L,cACpBI,EAAehM,KAAKwK,SAsBxB,OArBIxK,MAAKiM,eAAiBD,IAAiBD,IACrB,QAAhBC,GACFhM,KAAKkM,sBACLlM,KAAKiM,cAAgBlO,QACI,WAAhBgO,EACT/L,KAAKmM,uBACoB,WAAhBH,IACThM,KAAKiM,cAAgBlO,SAGrBiC,KAAKoM,kBAAoBJ,IAAiBD,IACxB,QAAhBC,GACFhM,KAAKqM,yBACLrM,KAAKoM,iBAAmBrO,QACC,YAAhBiO,EACThM,KAAKsM,0BACoB,YAAhBP,IACT/L,KAAKoM,iBAAmBrO,SAG5BiC,KAAK4L,cAAgB5L,KAAKwK,UAClBxK,KAAKiM,eAAiBjM,KAAKoM,kBAErCP,4BAA6B,WAC3B7L,KAAKuK,iBACL,IAAIgC,GACAC,EACAC,EACAC,EACAC,EAAgB3M,KAAK8K,YAAAA,GAAa,CAClC6B,KACFJ,EAAkBvM,KAAKrC,aACvB6O,EAAYxM,KAAKwL,QACjBiB,EAAezM,KAAK4M,UACpBF,EAAiB1M,KAAK0J,YACtB1J,KAAK8K,WAAWgB,SAChB9L,KAAK8K,WAAW+B,SAAW,KAC3B7M,KAAK8K,WAAa,QAGf9K,KAAK0K,QAAU1K,KAAK0K,iBAAkBjB,QAAOqD,kBAChD9M,KAAK8K,WAAazB,EAAM0D,wCAAwC/M,KAAK0K,QACrErB,EAAM2D,+BAA+BhN,QAEnCA,KAAK0K,iBAAkBjB,QAAOwD,gBAAkBjN,KAAK0K,iBAAkBjB,QAAOyD,eAChFlN,KAAK8K,WAAazB,EAAM8D,+BAA+BnN,KAAK0K,QAC5DrB,EAAM+D,sBAAsBpN,OAE1B2M,IACqB,GAAnBJ,IACFvM,KAAKrC,aAAe4O,GAED,OAAjBE,EACFzM,KAAK4M,UAAYH,EACW,OAAnBC,EACT1M,KAAK0J,YAAcgD,EACS,OAAnB1M,KAAKuL,YACdvL,KAAK0J,YAAc1J,KAAKuL,WAEtBiB,GACFxM,KAAKqN,SAGTrN,KAAKuK,mBAEP+C,gBAAiB,WACf,GAAKtN,KAAK0K,QAA4B,QAAlB1K,KAAKwK,UAAzB,CAGA,GAAIpG,GAASpE,KAAK0K,OAAO6C,QAAQlQ,KACjC2C,MAAK0L,iBAAiBxN,QAAQ,SAASsP,GACrCxN,KAAKyN,iBAAiBD,EAAgBpJ,GAClCpE,KAAK0K,iBAAkBjB,QAAOwD,iBAChC7I,GAAUiF,EAAMqE,mBAAmBF,EAAe9C,UACpDiD,KAAK3N,SAET4N,sBAAuB,SAAStD,GAC9B,GAAKtK,KAAK0K,QAAW1K,KAAKyL,SAE1B,IAAK,GAAI7H,GAAI,EAAGA,EAAI5D,KAAK0K,OAAOmD,SAAS3J,OAAQN,IAC/C5D,KAAK0K,OAAOmD,SAASjK,GAAGkH,WAAaR,EACrCtK,KAAK0L,iBAAiB9H,GAAGgK,sBAAsBtD,IAGnDwD,0BAA2B,WACzB,GAAK9N,KAAK0K,QAAW1K,KAAKyL,SAA1B,CAEA,GAAIrH,GAASpE,KAAK0K,OAAO6C,QAAQlQ,KACjC2C,MAAK+N,yBACL/N,KAAK0K,OAAOmD,SAAS3P,QAAQ,SAAS8P,GACpC,GAAIR,GAAiB/D,OAAOlD,SAASiD,SAASiB,MAAMuD,EACpDhO,MAAK0L,iBAAiBd,KAAK4C,GAC3BA,EAAe7P,aAAeqC,KAAKrC,aAC/BqC,KAAKwL,SACPgC,EAAeH,QACjBW,EAAMlD,WAAa9K,KAAK0K,OAAOI,WAE/B9K,KAAKyN,iBAAiBD,EAAgBpJ,GAElCpE,KAAK0K,iBAAkBjB,QAAOwD,iBAChC7I,GAAUiF,EAAMqE,mBAAmBM;EACrCL,KAAK3N,SAETyN,iBAAkB,SAASD,EAAgBpJ,GAClB,OAAnBpE,KAAK4M,UACPY,EAAe9D,YAAc1J,KAAK0J,YAActF,EAASpE,KAAKrC,aACrD6P,EAAeZ,YAAc5M,KAAK4M,UAAYxI,EAASpE,KAAKrC,eACrE6P,EAAeZ,UAAY5M,KAAK4M,UAAYxI,EAASpE,KAAKrC,eAG9DsQ,GAAIzD,aACF,MAAOxK,MAAK8K,WAAa9K,KAAK8K,WAAWN,UAAY,QAEvDyD,GAAIC,YACF,MAAKzE,QAAO0E,SAIPnO,KAAKoM,mBAC0C,IAA9C/C,EAAMgB,uBAAuBhM,QAAQ2B,OACvCqJ,EAAMgB,uBAAuBO,KAAK5K,MAEpCA,KAAKoM,iBAAmB,GAAI+B,SACxB,SAASC,EAASC,GAChBrO,KAAKsM,wBAA0B,WAC7B8B,EAAQpO,OAEVA,KAAKqM,uBAAyB,WAC5BgC,GAAQrJ,KAAMC,aAAaqJ,UAAWnJ,KAAM,iBAE9CwI,KAAK3N,OACW,YAAlBA,KAAKwK,WACPxK,KAAKsM,2BAGFtM,KAAKoM,mBApBV1D,QAAQC,KAAK,6DACN,OAqBXsF,GAAIM,SACF,MAAK9E,QAAO0E,SAIPnO,KAAKiM,gBAC0C,IAA9C5C,EAAMgB,uBAAuBhM,QAAQ2B,OACvCqJ,EAAMgB,uBAAuBO,KAAK5K,MAEpCA,KAAKiM,cAAgB,GAAIkC,SACrB,SAASC,EAASC,GAChBrO,KAAKmM,qBAAuB,WAC1BiC,EAAQpO,OAEVA,KAAKkM,oBAAsB,WACzBmC,GAAQrJ,KAAMC,aAAaqJ,UAAWnJ,KAAM,iBAE9CwI,KAAK3N,OACY,YAAnBA,KAAKwK,WACPxK,KAAKmM,wBAGFnM,KAAKiM,gBApBVvD,QAAQC,KAAK,6DACN,OAqBXsF,GAAIO,YACF,MAAOxO,MAAKyO,WAEdR,GAAIO,UAASE,GACK,kBAALA,IACT1O,KAAKyO,UAAYC,EACjB1O,KAAK8K,WAAW0D,SAAW,SAAUpD,GACnCA,EAAEuD,OAAS3O,KACX0O,EAAEE,KAAK5O,KAAMoL,IACZuC,KAAK3N,QAERA,KAAK8K,WAAW0D,SAAWE,EAC3B1O,KAAKwO,SAAWxO,KAAK8K,WAAW0D,WAGpCP,GAAIvE,eACF1J,KAAKuK,iBACL,IAAIb,GAAc1J,KAAK8K,WAAWpB,WAElC,OADA1J,MAAKuK,kBACEb,GAETuE,GAAIvE,aAAYgF,GACd1O,KAAKuK,kBACLvK,KAAK8K,WAAWpB,YAAc3E,SAAS2J,GAAKA,EAAIpP,KAAKuP,KAAKH,GAAKvO,OAAO2O,UACtE9O,KAAK+O,YACL/O,KAAKgP,cAAc,SAAShB,EAAO5J,GACjC4J,EAAMtE,YAAcgF,EAAItK,IAE1BpE,KAAKuK,mBAEP0D,GAAIrB,aACF,MAAO5M,MAAK8K,WAAW8B,WAEzBqB,GAAIrB,WAAU8B,GACZ1O,KAAKuK,kBACLvK,KAAK8K,WAAW8B,UAAY7H,SAAS2J,GAAKA,EAAIpP,KAAKuP,KAAKH,GAAKvO,OAAO2O,UACpE9O,KAAK+O,YACL/O,KAAKgP,cAAc,SAAShB,EAAO5J,GACjC4J,EAAMpB,UAAY8B,EAAItK,IAExBpE,KAAKuK,mBAEP0D,GAAItQ,gBACF,MAAOqC,MAAK8K,WAAWnN,cAEzBsQ,GAAItQ,cAAayF,GACfpD,KAAKuK,iBACL,IAAImC,GAAiB1M,KAAK0J,WAC1B1J,MAAK8K,WAAWnN,aAAeyF,EAC/BpD,KAAKgP,cAAc,SAASxB,GAC1BA,EAAe7P,aAAeyF,IAEV,UAAlBpD,KAAKwK,WAA2C,QAAlBxK,KAAKwK,WACrCxK,KAAK+K,OAEgB,OAAnB2B,IACF1M,KAAK0J,YAAcgD,GAErB1M,KAAKuK,mBAEP0D,GAAIgB,UAEF,MADApS,GAAOgM,WAAW,mBAAoB,aAAc,iCAC7C7I,KAAK0K,QAEdK,KAAM,WACJ/K,KAAKuK,kBACLvK,KAAKwL,SAAAA,EACLxL,KAAK8K,WAAWC,OACmC,IAA/CxE,SAASiD,SAASI,YAAYvL,QAAQ2B,OACxCuG,SAASiD,SAASI,YAAYgB,KAAK5K,MAErCA,KAAK+O,YACL1F,EAAM6F,eAAelP,MACrBA,KAAKgP,cAAc,SAAShB,GAC1B,GAAImB,GAAOnB,EAAMtE,WACjBsE,GAAMjD,OACNiD,EAAMtE,YAAcyF,IAEtBnP,KAAKuK,mBAEP8C,MAAO,WACLrN,KAAKuK,kBACDvK,KAAK0J,cACP1J,KAAKuL,UAAYvL,KAAK0J,aAExB1J,KAAK8K,WAAWuC,QAChBrN,KAAK+O,YACL/O,KAAKgP,cAAc,SAAShB,GAC1BA,EAAMX,UAERrN,KAAKwL,SAAAA,EACLxL,KAAKuK,mBAEP6E,OAAQ,WACNpP,KAAKuK,kBACLvK,KAAK8K,WAAWsE,SAChBpP,KAAK+O,YACL/O,KAAKuK,mBAEPuB,OAAQ,WACN9L,KAAKuK,kBACLvK,KAAK8K,WAAWgB,SAChB9L,KAAK+O,YACL/O,KAAK+N,yBACL/N,KAAKuK,mBAEP8E,QAAS,WACPrP,KAAKuK,iBACL,IAAImC,GAAiB1M,KAAK0J,WAC1B1J,MAAK8K,WAAWuE,UAChBrP,KAAKgP,cAAc,SAASxB,GAC1BA,EAAe6B,YAEM,OAAnB3C,IACF1M,KAAK0J,YAAcgD,GAErB1M,KAAKuK,mBAEP+E,iBAAkB,SAAStK,EAAMuK,GAC/B,GAAIC,GAAUD,CACQ,mBAAXA,KACTC,EAAU,SAAUpE,GAClBA,EAAEuD,OAAS3O,KACXuP,EAAQX,KAAK5O,KAAMoL,IAClBuC,KAAK3N,MACRuP,EAAQ1C,SAAW2C,GAErBxP,KAAK8K,WAAWwE,iBAAiBtK,EAAMwK,IAEzCC,oBAAqB,SAASzK,EAAMuK,GAClCvP,KAAK8K,WAAW2E,oBAAoBzK,EAAOuK,GAAWA,EAAQ1C,UAAa0C,IAE7ExB,uBAAwB,WACtB,KAAO/N,KAAK0L,iBAAiBxH,QAC3BlE,KAAK0L,iBAAiBgE,MAAM5D,UAEhCkD,cAAe,SAAS/P,GACtB,GAAImF,GAAS,CASb,IARIpE,KAAK0K,OAAOmD,UAAY7N,KAAK0L,iBAAiBxH,OAASlE,KAAK0K,OAAOmD,SAAS3J,QAC9ElE,KAAK8N,4BACP9N,KAAK0L,iBAAiBxN,QAAQ,SAAS8P,GACrC/O,EAAE2P,KAAK5O,KAAMgO,EAAO5J,GAChBpE,KAAK0K,iBAAkBjB,QAAOwD,iBAChC7I,GAAU4J,EAAMtD,OAAO3J,iBACzB4M,KAAK3N,OAEe,WAAlBA,KAAKwK,UAAT,CAEA,GAAIpN,GAAS4C,KAAK0K,OAAO6C,QACrBhE,EAAIvJ,KAAK0J,WACH,QAANH,IACFA,EAAI1M,EAAO2F,sBAAsB3F,EAAO+D,wBAAwBxD,GAASmM,EAAGnM,KACrE,MAALmM,GAAazL,MAAMyL,KACrBvJ,KAAK+N,6BAOVtR,EAAqBE,EAAmBC,GC3V1C,SAASC,EAAQwM,GAqChB,QAASsG,GAAa3L,GACpBhE,KAAK4P,QAAU/S,EAAOkH,mBAAmBC,GAgF3C,QAAS6L,KAEP,IADA,GAAIC,IAAAA,EACGC,EAAc7L,QAAQ,CAC3B,GAAIkF,GAAQ2G,EAAcC,OAC1B5G,GAAMkE,kBACNwC,GAAAA,EAEF,MAAOA,GA3HT,GAAIG,GAAe,SAASvF,GAE1B,GADAA,EAAOI,WAAa/M,OAChB2M,YAAkBjB,QAAOwD,gBAAkBvC,YAAkBjB,QAAOyD,YACtE,IAAK,GAAItJ,GAAI,EAAGA,EAAI8G,EAAOmD,SAAS3J,OAAQN,IAC1CqM,EAAavF,EAAOmD,SAASjK,IAKnCyF,GAAM6G,YAAc,SAASC,GAE3B,IAAK,GADDC,MACKxM,EAAI,EAAGA,EAAIuM,EAAQjM,OAAQN,IAAK,CACvC,GAAI8G,GAASyF,EAAQvM,EACjB8G,GAAO2F,SACiC,IAAtCD,EAAW/R,QAAQqM,EAAO2F,UAC5BD,EAAWxF,KAAKF,EAAO2F,SAEzB3F,EAAO2F,QAAQxC,SAASyC,OAAO5F,EAAO2F,QAAQxC,SAASxP,QAAQqM,GAAS,GACxEA,EAAO2F,QAAU,KACjBJ,EAAavF,IACJA,EAAOI,YAAeJ,EAAOI,WAAWJ,QAAUA,IAC3DA,EAAOI,WAAWgB,SAClBpB,EAAOI,WAAWJ,OAAS,GAAIoC,gBAAe,SAC1CpC,EAAOI,WAAWa,YACpBjB,EAAOI,WAAWa,UAAUb,WAAa,MAE3CJ,EAAOI,WAAWe,8BAClBoE,EAAavF,IAGjB,IAAK9G,EAAI,EAAGA,EAAIwM,EAAWlM,OAAQN,IACjCwM,EAAWxM,GAAG2M,YAQlBlH,EAAMyD,eAAiB,SAAS6B,EAAQ3K,EAAajH,GAanD,MAZAiD,MAAK2O,OAASA,EAEd3O,KAAKwQ,aAAe3T,EAAOC,iBAAiBC,GAC5CiD,KAAKuN,QAAU1Q,EAAO2B,qBAAqBzB,GAE3CiD,KAAK5C,OAASP,EAAOK,WAAWH,GAE9BiD,KAAKyQ,qBADmB,kBAAfzM,GACmBA,EAEA,GAAI2L,GAAa3L,GAC/ChE,KAAK0Q,WAAa1M,EAClBhE,KAAKe,eAAiBlE,EAAO+D,wBAAwBZ,KAAKuN,SACnDvN,MAGTqJ,EAAMyD,eAAe5C,WACnByG,UAAW,WACT,MAAwC,kBAA7B3Q,MAAKyQ,qBACPzQ,KAAKyQ,qBACPzQ,KAAKyQ,qBAAqBb,SAEnC3B,GAAIvD,UAEF,MADA7N,GAAOgM,WAAW,wBAAyB,aAAc,2CAClD7I,KAAKyQ,sBAEdzT,MAAO,WACL,GAA+B,kBAApBgD,MAAK2Q,YACd,KAAM,IAAI7H,OAAM,2CAElB,IAAI9L,GAAQ,GAAI8P,gBAAe9M,KAAK2O,UAAY9R,EAAOC,iBAAiBkD,KAAKwQ,cAG7E,OAFAxT,GAAMyT,qBAAuBzQ,KAAKyQ,qBAClCzT,EAAM0T,WAAa1Q,KAAK0Q,WACjB1T,GAETgO,OAAQ,WACN3B,EAAM6G,aAAalQ,QAIvB,IAAI4Q,GAAyBC,QAAQ3G,UAAU4G,OAC/CD,SAAQ3G,UAAU4G,QAAU,SAAS9M,EAAa5G,GAChD,MAAOiM,GAAMG,SAASiB,MAAM,GAAIpB,GAAMyD,eAAe9M,KAAMgE,EAAa5G,IAG1E,IAAI2T,GAAaxK,SAASC,gBAAgB,+BAAgC,MAC1E6C,GAAM0D,wCAA0C,SAASiE,GACvD,GAAIA,EAAgB,CAClB,GAAIrC,GAASqC,EAAerC,QAAUoC,EAClC5M,EAAY6M,EAAeN,UACP,mBAAbvM,KACTA,KAEF,IAAI/G,GAAS4T,EAAeR,iBAE5B,IAAI7B,GAASoC,EACT5M,KACA/G,EAAS,CAEf,OAAOwT,GAAuB7Q,MAAM4O,GAASxK,EAAW/G,KAG1DiM,EAAM2D,+BAAiC,SAAS1C,GAC1CA,EAAUI,QAA0D,kBAAzCJ,GAAUI,OAAO+F,sBAC9CpH,EAAM4H,6BAA6B3G,GAIvC,IAAIyF,KACJ1G,GAAM6F,eAAiB,SAASgC,GACG,OAA7BA,EAAetE,WAAuBsE,EAAezF,WAE7B,GAAxBsE,EAAc7L,QAChB4F,sBAAsB+F,GAExBE,EAAcnF,KAAKsG,IAWrB,IAAIC,GAA2B1H,OAAO2H,gBACtCpT,QAAOiN,eAAexB,OAAQ,oBAC5ByB,cAAAA,EACAmG,YAAAA,EACAjO,MAAO,WACLqG,OAAOlD,SAASiD,SAASQ,2BACzB,IAAIzG,GAAS4N,EAAyBpR,MAAMC,KAAMsR,UAIlD,OAHIzB,OACFtM,EAAS4N,EAAyBpR,MAAMC,KAAMsR,YAChD7H,OAAOlD,SAASiD,SAASQ,4BAClBzG,KAIXkG,OAAOqD,eAAiBzD,EAAMyD,eAC9BrD,OAAOoH,QAAQ3G,UAAUC,cAAgB,WACvC,MAAO5D,UAASiD,SAASW,gBAAgB3E,OAAO,SAAS8E,GACvD,MAA4B,QAArBA,EAAUI,QAAmBJ,EAAUI,OAAOiE,QAAU3O,MAC/D2N,KAAK3N,QAETyJ,OAAOoH,QAAQ3G,UAAUE,oBAAsB,WAE7C,MADAvN,GAAOgM,WAAW,8BAA+B,aAAc,sCACxD7I,KAAKmK,iBAYdV,OAAOkB,UAAY,WACjB9N,EAAOgM,WAAW,mBAAoB,aAAc,sCACpDY,OAAOqD,eAAe/M,MAAMC,KAAMsR,YAEpC7H,OAAOkB,UAAUT,UAAYlM,OAAOuT,OAAO9H,OAAOqD,eAAe5C,WACjET,OAAOkB,UAAUT,UAAUsH,YAAc/H,OAAOkB,WAEhDlO,EAAqBE,EAAmBC,GCzK1C,SAAUC,EAAQwM,GAkChB,QAASoI,GAASC,GACZA,EAASC,cAEbD,EAASC,aAAAA,EACTC,EAAUhH,KAAK8G,GACV7H,IACHA,GAAAA,EACAC,sBAAsB+H,KAI1B,QAASA,KACP,GAAIC,GAAWF,CACfA,MACAE,EAASC,KAAK,SAASC,EAAMC,GAC3B,MAAOD,GAAK3G,gBAAkB4G,EAAM5G,kBAEtCyG,EAAWA,EAAStM,OAAO,SAASkM,GAClCA,GACA,IAAIlH,GAAYkH,EAAS5G,WAAa4G,EAAS5G,WAAWN,UAAY,MAGtE,OAFiB,WAAbA,GAAuC,WAAbA,IAC5BkH,EAASC,aAAAA,GACJD,EAASC,cAElBC,EAAUhH,KAAK7K,MAAM6R,EAAWE,GAE5BF,EAAU1N,QACZ2F,GAAAA,EACAC,sBAAsB+H,IAEtBhI,GAAAA,EA9DJ,GAEIyB,IAFa/E,SAASC,gBAAgB,+BAAgC,OAErD,EACrB6C,GAAM4H,6BAA+B,SAAS3G,GAC5C,GAAIqE,GAASrE,EAAUI,OAAOiE,OAC1BuD,EAAiB5H,EAAUI,OAAO+F,qBAClCrT,EAASkN,EAAUI,OAAOtN,OAC1B+U,EAAO,IACX/U,GAASP,EAAO2B,qBAAqBpB,EACrC,IAAIsU,GAAW,WACb,GAAInI,GAAImI,EAAS5G,WAAa4G,EAAS5G,WAAWpB,YAAc,IACtD,QAANH,IACFA,EAAI1M,EAAO2F,sBAAsB3F,EAAO+D,wBAAwBxD,GAASmM,EAAGnM,GACxEU,MAAMyL,KACRA,EAAI,OAIJA,IAAM4I,GACRD,EAAe3I,EAAGoF,EAAQrE,EAAUI,QACtCyH,EAAO5I,EAGTmI,GAAS5G,WAAaR,EACtBoH,EAASC,aAAAA,EACTD,EAASrG,gBAAkBC,IAC3BhB,EAAUqB,UAAY+F,EACtBD,EAASC,GAGX,IAAIE,MACA/H,GAAAA,CAmCJR,GAAMsB,UAAUT,UAAU6E,UAAY,WAChC/O,KAAK2L,WACP8F,EAASzR,KAAK2L,aAGjBlP,EAAqBE,EAAmBC,GCxE3C,SAAUC,EAAQwM,GAEhB,QAASqE,GAAmB0E,GAC1B,MAAOA,GAAK7E,QAAQlQ,MAAQ+U,EAAKrR,eAAiBqR,EAAK7E,QAAQjQ,SAGjE,QAASkU,GAAY3D,EAAU9Q,GAC7BiD,KAAKqQ,QAAU,KACfrQ,KAAK6N,SAAWA,MAChB7N,KAAKqS,UAAUrS,KAAK6N,UACpB7N,KAAKwQ,aAAe3T,EAAOC,iBAAiBC,GAC5CiD,KAAKuN,QAAU1Q,EAAO2B,qBAAqBzB,GAAAA,GAC3CiD,KAAK5C,OAASP,EAAOK,WAAWH,GAAAA,GAEF,SAA1BiD,KAAKuN,QAAQ7P,WACfsC,KAAKuN,QAAQ7P,SAAWsC,KAAKe,gBAIjC0I,OAAOwD,eAAiB,WACtBuE,EAAYzR,MAAMC,KAAMsR,YAG1B7H,OAAOyD,YAAc,WACnBsE,EAAYzR,MAAMC,KAAMsR,YAG1BE,EAAYtH,WACVoI,YAAa,SAAS5H,GAEpB,IADA,GAAI/L,GAAIqB,KACK,OAANrB,GAAY,CACjB,GAAIA,GAAK+L,EACP,OAAA,CACF/L,GAAIA,EAAE0R,QAER,OAAA,GAEFE,SAAU,WAGR,IADA,GAAI6B,GAAOpS,KACJoS,GACwB,SAAzBA,EAAKhV,OAAOM,WACd0U,EAAK7E,QAAQ7P,SAAW0U,EAAKrR,gBAE/BqR,EAAOA,EAAK/B,OAEVrQ,MAAK8K,YACP9K,KAAK8K,WAAWe,+BAGpBwG,UAAW,SAASE,GAClBlJ,EAAM6G,YAAYqC,EAClB,KAAK,GAAI3O,GAAI,EAAGA,EAAI2O,EAAYrO,OAAQN,IACtC2O,EAAY3O,GAAGyM,QAAUrQ,MAG7BwS,UAAW,SAASC,EAAMC,GAExB,IAAK,GADDtN,GAAUsN,EAAW,oCAAsC,qCACtD9O,EAAI,EAAGA,EAAI6O,EAAKvO,OAAQN,IAC/B,GAAI5D,KAAKsS,YAAYG,EAAK7O,IACxB,MACEoB,KAAMC,aAAa0N,sBACnBxN,KAAM,wBACNC,QAASA,EAKf,KAAK,GAAIxB,GAAI,EAAGA,EAAI6O,EAAKvO,OAAQN,IAC/B8O,EAAW1S,KAAK6N,SAASjD,KAAK6H,EAAK7O,IAAM5D,KAAK6N,SAAS+E,QAAQH,EAAK7O,GAEtE5D,MAAKqS,UAAUI,GACfzS,KAAKuQ,YAEPsC,OAAQ,WACN7S,KAAKwS,UAAUlB,WAAAA,IAEjBwB,QAAS,WACP9S,KAAKwS,UAAUlB,WAAAA,IAEjBrD,GAAI8E,cACF,MAAO/S,MAAK6N,SAAS3J,OAASlE,KAAK6N,SAAS,GAAK,MAEnDI,GAAI+E,aACF,MAAOhT,MAAK6N,SAAS3J,OAASlE,KAAK6N,SAAS7N,KAAK6N,SAAS3J,OAAS,GAAK,MAE1ElH,MAAO,WAGL,IAAK,GAFDiW,GAAepW,EAAOC,iBAAiBkD,KAAKwQ,cAC5C0C,KACKtP,EAAI,EAAGA,EAAI5D,KAAK6N,SAAS3J,OAAQN,IACxCsP,EAAetI,KAAK5K,KAAK6N,SAASjK,GAAG5G,QAEvC,OAAQgD,gBAAgBkN,aACpB,GAAIA,aAAYgG,EAAgBD,GAChC,GAAIhG,gBAAeiG,EAAgBD,IAEzCjI,OAAQ,WACN3B,EAAM6G,aAAalQ,SAIvByJ,OAAOwD,eAAe/C,UAAYlM,OAAOuT,OAAOC,EAAYtH,WAC5DlM,OAAOiN,eACHxB,OAAOwD,eAAe/C,UACtB,kBAEEiB,IAAK,WACH,GAAIgI,GAAQ,CAIZ,OAHAnT,MAAK6N,SAAS3P,QAAQ,SAAS8P,GAC7BmF,GAASzF,EAAmBM,KAEvB1O,KAAK8T,IAAID,EAAO,MAI/B1J,OAAOyD,YAAYhD,UAAYlM,OAAOuT,OAAOC,EAAYtH,WACzDlM,OAAOiN,eACHxB,OAAOyD,YAAYhD,UACnB,kBAEEiB,IAAK,WACH,GAAIiI,GAAM,CAIV,OAHApT,MAAK6N,SAAS3P,QAAQ,SAAS8P,GAC7BoF,EAAM9T,KAAK8T,IAAIA,EAAK1F,EAAmBM,MAElCoF,KAIf/J,EAAM8D,+BAAiC,SAAS/D,GAC9C,GAAIiK,GACAjW,EAAS,KACTkW,EAAS,SAASC,GACpB,GAAIjJ,GAAY+I,EAAoBxG,QACpC,OAAKvC,IAGsB,WAAvBA,EAAUE,WAGTF,EAAUI,OAGL,MAAN6I,MACFjJ,GAAUyD,yBAQF,GAANwF,GAAWjJ,EAAU3M,aAAe,IACjCP,IACHA,EAASP,EAAO2B,qBAAqB8L,EAAUI,OAAOtN,SAExDmW,EAAK1W,EAAO2F,sBAAsB3F,EAAO+D,wBAAwBxD,GAAS,GAAIA,GAC1EU,MAAMyV,IAAa,MAANA,IACfjJ,EAAU0E,cAAc,SAAShB,GAC/BA,EAAMtE,YAAc,SAEtBY,GAAUyD,0BATd,OAlBA,OAkCF,OADAsF,GAAsBhK,EAAMG,SAASiB,MAAM,GAAIpB,GAAMyD,eAAe,KAAMwG,EAAQlK,EAAMmE,WAI1FlE,EAAM+D,sBAAwB,SAAS9C,GACrCA,EAAUQ,WAAW+B,SAAWvC,EAChCA,EAAUmB,UAAAA,EACVpC,EAAM6F,eAAe5E,GACrBA,EAAUwD,4BACVxD,EAAUsD,sBAAsBtD,IAGlCjB,EAAMqE,mBAAqBA,EAK3BjE,OAAO+J,kBAAoB,WACzB3W,EAAOgM,WAAW,2BAA4B,aAAc,sCAC5DY,OAAOwD,eAAelN,MAAMC,KAAMsR,YAEpC7H,OAAO+J,kBAAkBtJ,UAAYlM,OAAOuT,OAAO9H,OAAOwD,eAAe/C,WACzET,OAAO+J,kBAAkBtJ,UAAUsH,YAAc/H,OAAO+J,kBAExD/J,OAAOgK,eAAiB,WACtB5W,EAAOgM,WAAW,wBAAyB,aAAc,mCACzDY,OAAOyD,YAAYnN,MAAMC,KAAMsR,YAEjC7H,OAAOgK,eAAevJ,UAAYlM,OAAOuT,OAAO9H,OAAOyD,YAAYhD,WACnET,OAAOgK,eAAevJ,UAAUsH,YAAc/H,OAAOgK,gBAEpDhX,EAAqBE,EAAmBC,OTjMrCA,WAAAA,MAAuB"}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/web-animations-js/web-animations-next.min.js b/polymer_1.0.4/bower_components/web-animations-js/web-animations-next.min.js
new file mode 100644
index 0000000..b555389
--- /dev/null
+++ b/polymer_1.0.4/bower_components/web-animations-js/web-animations-next.min.js
@@ -0,0 +1,17 @@
+// Copyright 2014 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+!function(a,b){b["true"]=a;var c={},d={},e={},f=null;!function(a){function b(a){if("number"==typeof a)return a;var b={};for(var c in a)b[c]=a[c];return b}function c(b,c){var d={delay:0,endDelay:0,fill:c?"both":"none",iterationStart:0,iterations:1,duration:c?"auto":0,playbackRate:1,direction:"normal",easing:"linear"};return"number"!=typeof b||isNaN(b)?void 0!==b&&Object.getOwnPropertyNames(b).forEach(function(c){if("auto"!=b[c]){if(("number"==typeof d[c]||"duration"==c)&&("number"!=typeof b[c]||isNaN(b[c])))return;if("fill"==c&&-1==q.indexOf(b[c]))return;if("direction"==c&&-1==r.indexOf(b[c]))return;if("playbackRate"==c&&1!==b[c]&&a.isDeprecated("AnimationEffectTiming.playbackRate","2014-11-28","Use Animation.playbackRate instead."))return;d[c]=b[c]}}):d.duration=b,d}function d(a,b){var d=c(a,b);return d.easing=g(d.easing),d}function e(a,b,c,d){return 0>a||a>1||0>c||c>1?z:function(e){function f(a,b,c){return 3*a*(1-c)*(1-c)*c+3*b*(1-c)*c*c+c*c*c}if(0==e||1==e)return e;for(var g=0,h=1;;){var i=(g+h)/2,j=f(a,c,i);if(Math.abs(e-j)<.001)return f(b,d,i);e>j?g=i:h=i}}}function f(a,b){return function(c){if(c>=1)return 1;var d=1/a;return c+=b*d,c-c%d}}function g(a){var b=x.exec(a);if(b)return e.apply(this,b.slice(1).map(Number));var c=y.exec(a);if(c)return f(Number(c[1]),{start:s,middle:t,end:u}[c[2]]);var d=v[a];return d?d:z}function h(a){return Math.abs(i(a)/a.playbackRate)}function i(a){return a.duration*a.iterations}function j(a,b,c){return null==b?A:b<c.delay?B:b>=c.delay+a?C:D}function k(a,b,c,d,e){switch(d){case B:return"backwards"==b||"both"==b?0:null;case D:return c-e;case C:return"forwards"==b||"both"==b?a:null;case A:return null}}function l(a,b,c,d){return(d.playbackRate<0?b-a:b)*d.playbackRate+c}function m(a,b,c,d,e){return 1/0===c||c===-1/0||c-d==b&&e.iterations&&(e.iterations+e.iterationStart)%1==0?a:c%a}function n(a,b,c,d){return 0===c?0:b==a?d.iterationStart+d.iterations-1:Math.floor(c/a)}function o(a,b,c,d){var e=a%2>=1,f="normal"==d.direction||d.direction==(e?"alternate-reverse":"alternate"),g=f?c:b-c,h=g/b;return b*d.easing(h)}function p(a,b,c){var d=j(a,b,c),e=k(a,c.fill,b,d,c.delay);if(null===e)return null;if(0===a)return d===B?0:1;var f=c.iterationStart*c.duration,g=l(a,e,f,c),h=m(c.duration,i(c),g,f,c),p=n(c.duration,h,g,c);return o(p,c.duration,h,c)/c.duration}var q="backwards|forwards|both|none".split("|"),r="reverse|alternate|alternate-reverse".split("|"),s=1,t=.5,u=0,v={ease:e(.25,.1,.25,1),"ease-in":e(.42,0,1,1),"ease-out":e(0,0,.58,1),"ease-in-out":e(.42,0,.58,1),"step-start":f(1,s),"step-middle":f(1,t),"step-end":f(1,u)},w="\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*",x=new RegExp("cubic-bezier\\("+w+","+w+","+w+","+w+"\\)"),y=/steps\(\s*(\d+)\s*,\s*(start|middle|end)\s*\)/,z=function(a){return a},A=0,B=1,C=2,D=3;a.cloneTimingInput=b,a.makeTiming=c,a.normalizeTimingInput=d,a.calculateActiveDuration=h,a.calculateTimeFraction=p,a.calculatePhase=j,a.toTimingFunction=g}(c,f),function(a){function b(a,b){return a in h?h[a][b]||b:b}function c(a,c,d){var g=e[a];if(g){f.style[a]=c;for(var h in g){var i=g[h],j=f.style[i];d[i]=b(i,j)}}else d[a]=b(a,c)}function d(b){function d(){var a=e.length;null==e[a-1].offset&&(e[a-1].offset=1),a>1&&null==e[0].offset&&(e[0].offset=0);for(var b=0,c=e[0].offset,d=1;a>d;d++){var f=e[d].offset;if(null!=f){for(var g=1;d-b>g;g++)e[b+g].offset=c+(f-c)*g/(d-b);b=d,c=f}}}if(!Array.isArray(b)&&null!==b)throw new TypeError("Keyframes must be null or an array of keyframes");if(null==b)return[];for(var e=b.map(function(b){var d={};for(var e in b){var f=b[e];if("offset"==e){if(null!=f&&(f=Number(f),!isFinite(f)))throw new TypeError("keyframe offsets must be numbers.")}else{if("composite"==e)throw{type:DOMException.NOT_SUPPORTED_ERR,name:"NotSupportedError",message:"add compositing is not supported"};f="easing"==e?a.toTimingFunction(f):""+f}c(e,f,d)}return void 0==d.offset&&(d.offset=null),void 0==d.easing&&(d.easing=a.toTimingFunction("linear")),d}),f=!0,g=-1/0,h=0;h<e.length;h++){var i=e[h].offset;if(null!=i){if(g>i)throw{code:DOMException.INVALID_MODIFICATION_ERR,name:"InvalidModificationError",message:"Keyframes are not loosely sorted by offset. Sort or specify offsets."};g=i}else f=!1}return e=e.filter(function(a){return a.offset>=0&&a.offset<=1}),f||d(),e}var e={background:["backgroundImage","backgroundPosition","backgroundSize","backgroundRepeat","backgroundAttachment","backgroundOrigin","backgroundClip","backgroundColor"],border:["borderTopColor","borderTopStyle","borderTopWidth","borderRightColor","borderRightStyle","borderRightWidth","borderBottomColor","borderBottomStyle","borderBottomWidth","borderLeftColor","borderLeftStyle","borderLeftWidth"],borderBottom:["borderBottomWidth","borderBottomStyle","borderBottomColor"],borderColor:["borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],borderLeft:["borderLeftWidth","borderLeftStyle","borderLeftColor"],borderRadius:["borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"],borderRight:["borderRightWidth","borderRightStyle","borderRightColor"],borderTop:["borderTopWidth","borderTopStyle","borderTopColor"],borderWidth:["borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth"],flex:["flexGrow","flexShrink","flexBasis"],font:["fontFamily","fontSize","fontStyle","fontVariant","fontWeight","lineHeight"],margin:["marginTop","marginRight","marginBottom","marginLeft"],outline:["outlineColor","outlineStyle","outlineWidth"],padding:["paddingTop","paddingRight","paddingBottom","paddingLeft"]},f=document.createElementNS("http://www.w3.org/1999/xhtml","div"),g={thin:"1px",medium:"3px",thick:"5px"},h={borderBottomWidth:g,borderLeftWidth:g,borderRightWidth:g,borderTopWidth:g,fontSize:{"xx-small":"60%","x-small":"75%",small:"89%",medium:"100%",large:"120%","x-large":"150%","xx-large":"200%"},fontWeight:{normal:"400",bold:"700"},outlineWidth:g,textShadow:{none:"0px 0px 0px transparent"},boxShadow:{none:"0px 0px 0px 0px transparent"}};a.normalizeKeyframes=d}(c,f),function(a){var b={};a.isDeprecated=function(a,c,d,e){var f=e?"are":"is",g=new Date,h=new Date(c);return h.setMonth(h.getMonth()+3),h>g?(a in b||console.warn("Web Animations: "+a+" "+f+" deprecated and will stop working on "+h.toDateString()+". "+d),b[a]=!0,!1):!0},a.deprecated=function(b,c,d,e){var f=e?"are":"is";if(a.isDeprecated(b,c,d,e))throw new Error(b+" "+f+" no longer supported. "+d)}}(c),function(){if(document.documentElement.animate){var a=document.documentElement.animate([],0),b=!0;if(a&&(b=!1,"play|currentTime|pause|reverse|playbackRate|cancel|finish|startTime|playState".split("|").forEach(function(c){void 0===a[c]&&(b=!0)})),!b)return}!function(a,b){function c(a){for(var b={},c=0;c<a.length;c++)for(var d in a[c])if("offset"!=d&&"easing"!=d&&"composite"!=d){var e={offset:a[c].offset,easing:a[c].easing,value:a[c][d]};b[d]=b[d]||[],b[d].push(e)}for(var f in b){var g=b[f];if(0!=g[0].offset||1!=g[g.length-1].offset)throw{type:DOMException.NOT_SUPPORTED_ERR,name:"NotSupportedError",message:"Partial keyframes are not supported"}}return b}function d(a){var c=[];for(var d in a)for(var e=a[d],f=0;f<e.length-1;f++){var g=e[f].offset,h=e[f+1].offset,i=e[f].value,j=e[f+1].value;g==h&&(1==h?i=j:j=i),c.push({startTime:g,endTime:h,easing:e[f].easing,property:d,interpolation:b.propertyInterpolation(d,i,j)})}return c.sort(function(a,b){return a.startTime-b.startTime}),c}b.convertEffectInput=function(e){var f=a.normalizeKeyframes(e),g=c(f),h=d(g);return function(a,c){if(null!=c)h.filter(function(a){return 0>=c&&0==a.startTime||c>=1&&1==a.endTime||c>=a.startTime&&c<=a.endTime}).forEach(function(d){var e=c-d.startTime,f=d.endTime-d.startTime,g=0==f?0:d.easing(e/f);b.apply(a,d.property,d.interpolation(g))});else for(var d in g)"offset"!=d&&"easing"!=d&&"composite"!=d&&b.clear(a,d)}}}(c,d,f),function(a){function b(a,b,c){e[c]=e[c]||[],e[c].push([a,b])}function c(a,c,d){for(var e=0;e<d.length;e++){var f=d[e];b(a,c,f),/-/.test(f)&&b(a,c,f.replace(/-(.)/g,function(a,b){return b.toUpperCase()}))}}function d(b,c,d){if("initial"==c||"initial"==d){var g=b.replace(/-(.)/g,function(a,b){return b.toUpperCase()});"initial"==c&&(c=f[g]),"initial"==d&&(d=f[g])}for(var h=c==d?[]:e[b],i=0;h&&i<h.length;i++){var j=h[i][0](c),k=h[i][0](d);if(void 0!==j&&void 0!==k){var l=h[i][1](j,k);if(l){var m=a.Interpolation.apply(null,l);return function(a){return 0==a?c:1==a?d:m(a)}}}}return a.Interpolation(!1,!0,function(a){return a?d:c})}var e={};a.addPropertiesHandler=c;var f={backgroundColor:"transparent",backgroundPosition:"0% 0%",borderBottomColor:"currentColor",borderBottomLeftRadius:"0px",borderBottomRightRadius:"0px",borderBottomWidth:"3px",borderLeftColor:"currentColor",borderLeftWidth:"3px",borderRightColor:"currentColor",borderRightWidth:"3px",borderSpacing:"2px",borderTopColor:"currentColor",borderTopLeftRadius:"0px",borderTopRightRadius:"0px",borderTopWidth:"3px",bottom:"auto",clip:"rect(0px, 0px, 0px, 0px)",color:"black",fontSize:"100%",fontWeight:"400",height:"auto",left:"auto",letterSpacing:"normal",lineHeight:"120%",marginBottom:"0px",marginLeft:"0px",marginRight:"0px",marginTop:"0px",maxHeight:"none",maxWidth:"none",minHeight:"0px",minWidth:"0px",opacity:"1.0",outlineColor:"invert",outlineOffset:"0px",outlineWidth:"3px",paddingBottom:"0px",paddingLeft:"0px",paddingRight:"0px",paddingTop:"0px",right:"auto",textIndent:"0px",textShadow:"0px 0px 0px transparent",top:"auto",transform:"",verticalAlign:"0px",visibility:"visible",width:"auto",wordSpacing:"normal",zIndex:"auto"};a.propertyInterpolation=d}(d,f),function(a,b){function c(b){var c=a.calculateActiveDuration(b),d=function(d){return a.calculateTimeFraction(c,d,b)};return d._totalDuration=b.delay+c+b.endDelay,d._isCurrent=function(d){var e=a.calculatePhase(c,d,b);return e===PhaseActive||e===PhaseBefore},d}b.KeyframeEffect=function(d,e,f){var g,h=c(a.normalizeTimingInput(f)),i=b.convertEffectInput(e),j=function(){i(d,g)};return j._update=function(a){return g=h(a),null!==g},j._clear=function(){i(d,null)},j._hasSameTarget=function(a){return d===a},j._isCurrent=h._isCurrent,j._totalDuration=h._totalDuration,j},b.NullEffect=function(a){var b=function(){a&&(a(),a=null)};return b._update=function(){return null},b._totalDuration=0,b._isCurrent=function(){return!1},b._hasSameTarget=function(){return!1},b}}(c,d,f),function(a){function b(a,b,c){c.enumerable=!0,c.configurable=!0,Object.defineProperty(a,b,c)}function c(a){this._surrogateStyle=document.createElementNS("http://www.w3.org/1999/xhtml","div").style,this._style=a.style,this._length=0,this._isAnimatedProperty={};for(var b=0;b<this._style.length;b++){var c=this._style[b];this._surrogateStyle[c]=this._style[c]}this._updateIndices()}function d(a){if(!a._webAnimationsPatchedStyle){var d=new c(a);try{b(a,"style",{get:function(){return d}})}catch(e){a.style._set=function(b,c){a.style[b]=c},a.style._clear=function(b){a.style[b]=""}}a._webAnimationsPatchedStyle=a.style}}var e={cssText:1,length:1,parentRule:1},f={getPropertyCSSValue:1,getPropertyPriority:1,getPropertyValue:1,item:1,removeProperty:1,setProperty:1},g={removeProperty:1,setProperty:1};c.prototype={get cssText(){return this._surrogateStyle.cssText},set cssText(a){for(var b={},c=0;c<this._surrogateStyle.length;c++)b[this._surrogateStyle[c]]=!0;this._surrogateStyle.cssText=a,this._updateIndices();for(var c=0;c<this._surrogateStyle.length;c++)b[this._surrogateStyle[c]]=!0;for(var d in b)this._isAnimatedProperty[d]||this._style.setProperty(d,this._surrogateStyle.getPropertyValue(d))},get length(){return this._surrogateStyle.length},get parentRule(){return this._style.parentRule},_updateIndices:function(){for(;this._length<this._surrogateStyle.length;)Object.defineProperty(this,this._length,{configurable:!0,enumerable:!1,get:function(a){return function(){return this._surrogateStyle[a]}}(this._length)}),this._length++;for(;this._length>this._surrogateStyle.length;)this._length--,Object.defineProperty(this,this._length,{configurable:!0,enumerable:!1,value:void 0})},_set:function(a,b){this._style[a]=b,this._isAnimatedProperty[a]=!0},_clear:function(a){this._style[a]=this._surrogateStyle[a],delete this._isAnimatedProperty[a]}};for(var h in f)c.prototype[h]=function(a,b){return function(){var c=this._surrogateStyle[a].apply(this._surrogateStyle,arguments);return b&&(this._isAnimatedProperty[arguments[0]]||this._style[a].apply(this._style,arguments),this._updateIndices()),c}}(h,h in g);for(var i in document.documentElement.style)i in e||i in f||!function(a){b(c.prototype,a,{get:function(){return this._surrogateStyle[a]},set:function(b){this._surrogateStyle[a]=b,this._updateIndices(),this._isAnimatedProperty[a]||(this._style[a]=b)}})}(i);a.apply=function(b,c,e){d(b),b.style._set(a.propertyName(c),e)},a.clear=function(b,c){b._webAnimationsPatchedStyle&&b.style._clear(a.propertyName(c))}}(d,f),function(a){window.Element.prototype.animate=function(b,c){return a.timeline._play(a.KeyframeEffect(this,b,c))}}(d),function(a){function b(a,c,d){if("number"==typeof a&&"number"==typeof c)return a*(1-d)+c*d;if("boolean"==typeof a&&"boolean"==typeof c)return.5>d?a:c;if(a.length==c.length){for(var e=[],f=0;f<a.length;f++)e.push(b(a[f],c[f],d));return e}throw"Mismatched interpolation arguments "+a+":"+c}a.Interpolation=function(a,c,d){return function(e){return d(b(a,c,e))}}}(d,f),function(a){function b(a,b,c){return Math.max(Math.min(a,c),b)}function c(c,d,e){var f=a.dot(c,d);f=b(f,-1,1);var g=[];if(1===f)g=c;else for(var h=Math.acos(f),i=1*Math.sin(e*h)/Math.sqrt(1-f*f),j=0;4>j;j++)g.push(c[j]*(Math.cos(e*h)-f*i)+d[j]*i);return g}var d=function(){function a(a,b){for(var c=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],d=0;4>d;d++)for(var e=0;4>e;e++)for(var f=0;4>f;f++)c[d][e]+=b[d][f]*a[f][e];return c}function b(a){return 0==a[0][2]&&0==a[0][3]&&0==a[1][2]&&0==a[1][3]&&0==a[2][0]&&0==a[2][1]&&1==a[2][2]&&0==a[2][3]&&0==a[3][2]&&1==a[3][3]}function c(c,d,e,f,g){for(var h=[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]],i=0;4>i;i++)h[i][3]=g[i];for(var i=0;3>i;i++)for(var j=0;3>j;j++)h[3][i]+=c[j]*h[j][i];var k=f[0],l=f[1],m=f[2],n=f[3],o=[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]];o[0][0]=1-2*(l*l+m*m),o[0][1]=2*(k*l-m*n),o[0][2]=2*(k*m+l*n),o[1][0]=2*(k*l+m*n),o[1][1]=1-2*(k*k+m*m),o[1][2]=2*(l*m-k*n),o[2][0]=2*(k*m-l*n),o[2][1]=2*(l*m+k*n),o[2][2]=1-2*(k*k+l*l),h=a(h,o);var p=[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]];e[2]&&(p[2][1]=e[2],h=a(h,p)),e[1]&&(p[2][1]=0,p[2][0]=e[0],h=a(h,p)),e[0]&&(p[2][0]=0,p[1][0]=e[0],h=a(h,p));for(var i=0;3>i;i++)for(var j=0;3>j;j++)h[i][j]*=d[i];return b(h)?[h[0][0],h[0][1],h[1][0],h[1][1],h[3][0],h[3][1]]:h[0].concat(h[1],h[2],h[3])}return c}();a.composeMatrix=d,a.quat=c}(d,f),function(a,b){a.sequenceNumber=0;var c=function(a,b,c){this.target=a,this.currentTime=b,this.timelineTime=c,this.type="finish",this.bubbles=!1,this.cancelable=!1,this.currentTarget=a,this.defaultPrevented=!1,this.eventPhase=Event.AT_TARGET,this.timeStamp=Date.now()};b.Animation=function(b){this._sequenceNumber=a.sequenceNumber++,this._currentTime=0,this._startTime=null,this._paused=!1,this._playbackRate=1,this._inTimeline=!0,this._finishedFlag=!1,this.onfinish=null,this._finishHandlers=[],this._effect=b,this._inEffect=this._effect._update(0),this._idle=!0,this._currentTimePending=!1},b.Animation.prototype={_ensureAlive:function(){this._inEffect=this._effect._update(this.playbackRate<0&&0===this.currentTime?-1:this.currentTime),this._inTimeline||!this._inEffect&&this._finishedFlag||(this._inTimeline=!0,b.timeline._animations.push(this))},_tickCurrentTime:function(a,b){a!=this._currentTime&&(this._currentTime=a,this._isFinished&&!b&&(this._currentTime=this._playbackRate>0?this._totalDuration:0),this._ensureAlive())},get currentTime(){return this._idle||this._currentTimePending?null:this._currentTime},set currentTime(a){a=+a,isNaN(a)||(b.restart(),this._paused||null==this._startTime||(this._startTime=this._timeline.currentTime-a/this._playbackRate),this._currentTimePending=!1,this._currentTime!=a&&(this._tickCurrentTime(a,!0),b.invalidateEffects()))},get startTime(){return this._startTime},set startTime(a){a=+a,isNaN(a)||this._paused||this._idle||(this._startTime=a,this._tickCurrentTime((this._timeline.currentTime-this._startTime)*this.playbackRate),b.invalidateEffects())},get playbackRate(){return this._playbackRate},set playbackRate(a){if(a!=this._playbackRate){var b=this.currentTime;this._playbackRate=a,this._startTime=null,"paused"!=this.playState&&"idle"!=this.playState&&this.play(),null!=b&&(this.currentTime=b)}},get _isFinished(){return!this._idle&&(this._playbackRate>0&&this._currentTime>=this._totalDuration||this._playbackRate<0&&this._currentTime<=0)},get _totalDuration(){return this._effect._totalDuration},get playState(){return this._idle?"idle":null==this._startTime&&!this._paused&&0!=this.playbackRate||this._currentTimePending?"pending":this._paused?"paused":this._isFinished?"finished":"running"},play:function(){this._paused=!1,(this._isFinished||this._idle)&&(this._currentTime=this._playbackRate>0?0:this._totalDuration,this._startTime=null,b.invalidateEffects()),this._finishedFlag=!1,b.restart(),this._idle=!1,this._ensureAlive()},pause:function(){this._isFinished||this._paused||this._idle||(this._currentTimePending=!0),this._startTime=null,this._paused=!0},finish:function(){this._idle||(this.currentTime=this._playbackRate>0?this._totalDuration:0,this._startTime=this._totalDuration-this.currentTime,this._currentTimePending=!1)},cancel:function(){this._inEffect&&(this._inEffect=!1,this._idle=!0,this.currentTime=0,this._startTime=null,this._effect._update(null),b.invalidateEffects(),b.restart())},reverse:function(){this.playbackRate*=-1,this.play()},addEventListener:function(a,b){"function"==typeof b&&"finish"==a&&this._finishHandlers.push(b)},removeEventListener:function(a,b){if("finish"==a){var c=this._finishHandlers.indexOf(b);c>=0&&this._finishHandlers.splice(c,1)}},_fireEvents:function(a){var b=this._isFinished;if((b||this._idle)&&!this._finishedFlag){var d=new c(this,this._currentTime,a),e=this._finishHandlers.concat(this.onfinish?[this.onfinish]:[]);setTimeout(function(){e.forEach(function(a){a.call(d.target,d)})},0)}this._finishedFlag=b},_tick:function(a){return this._idle||this._paused||(null==this._startTime?this.startTime=a-this._currentTime/this.playbackRate:this._isFinished||this._tickCurrentTime((a-this._startTime)*this.playbackRate)),this._currentTimePending=!1,this._fireEvents(a),!this._idle&&(this._inEffect||!this._finishedFlag)}}}(c,d,f),function(a,b){function c(a){var b=i;i=[],a<s.currentTime&&(a=s.currentTime),g(a),b.forEach(function(b){b[1](a)}),o&&g(a),f(),l=void 0}function d(a,b){return a._sequenceNumber-b._sequenceNumber}function e(){this._animations=[],this.currentTime=window.performance&&performance.now?performance.now():0}function f(){p.forEach(function(a){a()}),p.length=0}function g(a){n=!1;var c=b.timeline;c.currentTime=a,c._animations.sort(d),m=!1;var e=c._animations;c._animations=[];var f=[],g=[];e=e.filter(function(b){return b._inTimeline=b._tick(a),b._inEffect?g.push(b._effect):f.push(b._effect),b._isFinished||b._paused||b._idle||(m=!0),b._inTimeline}),p.push.apply(p,f),p.push.apply(p,g),c._animations.push.apply(c._animations,e),o=!1,m&&requestAnimationFrame(function(){})}var h=window.requestAnimationFrame,i=[],j=0;window.requestAnimationFrame=function(a){var b=j++;return 0==i.length&&h(c),i.push([b,a]),b},window.cancelAnimationFrame=function(a){i.forEach(function(b){b[0]==a&&(b[1]=function(){})})},e.prototype={_play:function(c){c._timing=a.normalizeTimingInput(c.timing);var d=new b.Animation(c);return d._idle=!1,d._timeline=this,this._animations.push(d),b.restart(),b.invalidateEffects(),d}};var k,l=void 0,k=function(){return void 0==l&&(l=performance.now()),l},m=!1,n=!1;b.restart=function(){return m||(m=!0,requestAnimationFrame(function(){}),n=!0),n};var o=!1;b.invalidateEffects=function(){o=!0};var p=[],q=1e3/60,r=window.getComputedStyle;Object.defineProperty(window,"getComputedStyle",{configurable:!0,enumerable:!0,value:function(){if(o){var a=k();a-s.currentTime>0&&(s.currentTime+=q*(Math.floor((a-s.currentTime)/q)+1)),g(s.currentTime)}return f(),r.apply(this,arguments)}});var s=new e;b.timeline=s}(c,d,f),function(a){function b(a,b){for(var c=0,d=0;d<a.length;d++)c+=a[d]*b[d];return c}function c(a,b){return[a[0]*b[0]+a[4]*b[1]+a[8]*b[2]+a[12]*b[3],a[1]*b[0]+a[5]*b[1]+a[9]*b[2]+a[13]*b[3],a[2]*b[0]+a[6]*b[1]+a[10]*b[2]+a[14]*b[3],a[3]*b[0]+a[7]*b[1]+a[11]*b[2]+a[15]*b[3],a[0]*b[4]+a[4]*b[5]+a[8]*b[6]+a[12]*b[7],a[1]*b[4]+a[5]*b[5]+a[9]*b[6]+a[13]*b[7],a[2]*b[4]+a[6]*b[5]+a[10]*b[6]+a[14]*b[7],a[3]*b[4]+a[7]*b[5]+a[11]*b[6]+a[15]*b[7],a[0]*b[8]+a[4]*b[9]+a[8]*b[10]+a[12]*b[11],a[1]*b[8]+a[5]*b[9]+a[9]*b[10]+a[13]*b[11],a[2]*b[8]+a[6]*b[9]+a[10]*b[10]+a[14]*b[11],a[3]*b[8]+a[7]*b[9]+a[11]*b[10]+a[15]*b[11],a[0]*b[12]+a[4]*b[13]+a[8]*b[14]+a[12]*b[15],a[1]*b[12]+a[5]*b[13]+a[9]*b[14]+a[13]*b[15],a[2]*b[12]+a[6]*b[13]+a[10]*b[14]+a[14]*b[15],a[3]*b[12]+a[7]*b[13]+a[11]*b[14]+a[15]*b[15]]}function d(a){switch(a.t){case"rotatex":var b=a.d[0].rad||0,c=a.d[0].deg||0,d=c*Math.PI/180+b;return[1,0,0,0,0,Math.cos(d),Math.sin(d),0,0,-Math.sin(d),Math.cos(d),0,0,0,0,1];case"rotatey":var b=a.d[0].rad||0,c=a.d[0].deg||0,d=c*Math.PI/180+b;return[Math.cos(d),0,-Math.sin(d),0,0,1,0,0,Math.sin(d),0,Math.cos(d),0,0,0,0,1];case"rotate":case"rotatez":var b=a.d[0].rad||0,c=a.d[0].deg||0,d=c*Math.PI/180+b;return[Math.cos(d),Math.sin(d),0,0,-Math.sin(d),Math.cos(d),0,0,0,0,1,0,0,0,0,1];case"rotate3d":var e=a.d[0],f=a.d[1],g=a.d[2],b=a.d[3].rad||0,c=a.d[3].deg||0,d=c*Math.PI/180+b,h=e*e+f*f+g*g;if(0===h)e=1,f=0,g=0;else if(1!==h){var i=Math.sqrt(h);e/=i,f/=i,g/=i}var j=Math.sin(d/2),k=j*Math.cos(d/2),l=j*j;return[1-2*(f*f+g*g)*l,2*(e*f*l+g*k),2*(e*g*l-f*k),0,2*(e*f*l-g*k),1-2*(e*e+g*g)*l,2*(f*g*l+e*k),0,2*(e*g*l+f*k),2*(f*g*l-e*k),1-2*(e*e+f*f)*l,0,0,0,0,1];case"scale":return[a.d[0],0,0,0,0,a.d[1],0,0,0,0,1,0,0,0,0,1];case"scalex":return[a.d[0],0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];case"scaley":return[1,0,0,0,0,a.d[0],0,0,0,0,1,0,0,0,0,1];case"scalez":return[1,0,0,0,0,1,0,0,0,0,a.d[0],0,0,0,0,1];case"scale3d":return[a.d[0],0,0,0,0,a.d[1],0,0,0,0,a.d[2],0,0,0,0,1];case"skew":var m=a.d[0].deg||0,n=a.d[0].rad||0,o=a.d[1].deg||0,p=a.d[1].rad||0,q=m*Math.PI/180+n,r=o*Math.PI/180+p;return[1,Math.tan(r),0,0,Math.tan(q),1,0,0,0,0,1,0,0,0,0,1];case"skewx":var b=a.d[0].rad||0,c=a.d[0].deg||0,d=c*Math.PI/180+b;return[1,0,0,0,Math.tan(d),1,0,0,0,0,1,0,0,0,0,1];case"skewy":var b=a.d[0].rad||0,c=a.d[0].deg||0,d=c*Math.PI/180+b;return[1,Math.tan(d),0,0,0,1,0,0,0,0,1,0,0,0,0,1];case"translate":var e=a.d[0].px||0,f=a.d[1].px||0;return[1,0,0,0,0,1,0,0,0,0,1,0,e,f,0,1];case"translatex":var e=a.d[0].px||0;return[1,0,0,0,0,1,0,0,0,0,1,0,e,0,0,1];case"translatey":var f=a.d[0].px||0;return[1,0,0,0,0,1,0,0,0,0,1,0,0,f,0,1];case"translatez":var g=a.d[0].px||0;return[1,0,0,0,0,1,0,0,0,0,1,0,0,0,g,1];case"translate3d":var e=a.d[0].px||0,f=a.d[1].px||0,g=a.d[2].px||0;return[1,0,0,0,0,1,0,0,0,0,1,0,e,f,g,1];case"perspective":var s=a.d[0].px?-1/a.d[0].px:0;return[1,0,0,0,0,1,0,0,0,0,1,s,0,0,0,1];case"matrix":return[a.d[0],a.d[1],0,0,a.d[2],a.d[3],0,0,0,0,1,0,a.d[4],a.d[5],0,1];case"matrix3d":return a.d}}function e(a){return 0===a.length?[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]:a.map(d).reduce(c)}function f(a){return[g(e(a))]}var g=function(){function a(a){return a[0][0]*a[1][1]*a[2][2]+a[1][0]*a[2][1]*a[0][2]+a[2][0]*a[0][1]*a[1][2]-a[0][2]*a[1][1]*a[2][0]-a[1][2]*a[2][1]*a[0][0]-a[2][2]*a[0][1]*a[1][0]}function c(b){for(var c=1/a(b),d=b[0][0],e=b[0][1],f=b[0][2],g=b[1][0],h=b[1][1],i=b[1][2],j=b[2][0],k=b[2][1],l=b[2][2],m=[[(h*l-i*k)*c,(f*k-e*l)*c,(e*i-f*h)*c,0],[(i*j-g*l)*c,(d*l-f*j)*c,(f*g-d*i)*c,0],[(g*k-h*j)*c,(j*e-d*k)*c,(d*h-e*g)*c,0]],n=[],o=0;3>o;o++){for(var p=0,q=0;3>q;q++)p+=b[3][q]*m[q][o];n.push(p)}return n.push(1),m.push(n),m}function d(a){return[[a[0][0],a[1][0],a[2][0],a[3][0]],[a[0][1],a[1][1],a[2][1],a[3][1]],[a[0][2],a[1][2],a[2][2],a[3][2]],[a[0][3],a[1][3],a[2][3],a[3][3]]]}function e(a,b){for(var c=[],d=0;4>d;d++){for(var e=0,f=0;4>f;f++)e+=a[f]*b[f][d];c.push(e)}return c}function f(a){var b=g(a);return[a[0]/b,a[1]/b,a[2]/b]}function g(a){return Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2])}function h(a,b,c,d){return[c*a[0]+d*b[0],c*a[1]+d*b[1],c*a[2]+d*b[2]]}function i(a,b){return[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]]}function j(j){var k=[j.slice(0,4),j.slice(4,8),j.slice(8,12),j.slice(12,16)];if(1!==k[3][3])return null;for(var l=[],m=0;4>m;m++)l.push(k[m].slice());for(var m=0;3>m;m++)l[m][3]=0;if(0===a(l))return!1;var n,o=[];if(k[0][3]||k[1][3]||k[2][3]){o.push(k[0][3]),o.push(k[1][3]),o.push(k[2][3]),o.push(k[3][3]);var p=c(l),q=d(p);n=e(o,q)}else n=[0,0,0,1];var r=k[3].slice(0,3),s=[];s.push(k[0].slice(0,3));var t=[];t.push(g(s[0])),s[0]=f(s[0]);var u=[];s.push(k[1].slice(0,3)),u.push(b(s[0],s[1])),s[1]=h(s[1],s[0],1,-u[0]),t.push(g(s[1])),s[1]=f(s[1]),u[0]/=t[1],s.push(k[2].slice(0,3)),u.push(b(s[0],s[2])),s[2]=h(s[2],s[0],1,-u[1]),u.push(b(s[1],s[2])),s[2]=h(s[2],s[1],1,-u[2]),t.push(g(s[2])),s[2]=f(s[2]),u[1]/=t[2],u[2]/=t[2];var v=i(s[1],s[2]);if(b(s[0],v)<0)for(var m=0;3>m;m++)t[m]*=-1,s[m][0]*=-1,s[m][1]*=-1,s[m][2]*=-1;var w,x,y=s[0][0]+s[1][1]+s[2][2]+1;return y>1e-4?(w=.5/Math.sqrt(y),x=[(s[2][1]-s[1][2])*w,(s[0][2]-s[2][0])*w,(s[1][0]-s[0][1])*w,.25/w]):s[0][0]>s[1][1]&&s[0][0]>s[2][2]?(w=2*Math.sqrt(1+s[0][0]-s[1][1]-s[2][2]),x=[.25*w,(s[0][1]+s[1][0])/w,(s[0][2]+s[2][0])/w,(s[2][1]-s[1][2])/w]):s[1][1]>s[2][2]?(w=2*Math.sqrt(1+s[1][1]-s[0][0]-s[2][2]),x=[(s[0][1]+s[1][0])/w,.25*w,(s[1][2]+s[2][1])/w,(s[0][2]-s[2][0])/w]):(w=2*Math.sqrt(1+s[2][2]-s[0][0]-s[1][1]),x=[(s[0][2]+s[2][0])/w,(s[1][2]+s[2][1])/w,.25*w,(s[1][0]-s[0][1])/w]),[r,t,u,x,n]}return j}();a.dot=b,a.makeMatrixDecomposition=f}(d,f),function(a){function b(a,b){var c=a.exec(b);return c?(c=a.ignoreCase?c[0].toLowerCase():c[0],[c,b.substr(c.length)]):void 0}function c(a,b){b=b.replace(/^\s*/,"");var c=a(b);return c?[c[0],c[1].replace(/^\s*/,"")]:void 0}function d(a,d,e){a=c.bind(null,a);for(var f=[];;){var g=a(e);if(!g)return[f,e];if(f.push(g[0]),e=g[1],g=b(d,e),!g||""==g[1])return[f,e];e=g[1]}}function e(a,b){for(var c=0,d=0;d<b.length&&(!/\s|,/.test(b[d])||0!=c);d++)if("("==b[d])c++;else if(")"==b[d]&&(c--,0==c&&d++,0>=c))break;var e=a(b.substr(0,d));return void 0==e?void 0:[e,b.substr(d)]}function f(a,b){for(var c=a,d=b;c&&d;)c>d?c%=d:d%=c;return c=a*b/(c+d)}function g(a){return function(b){var c=a(b);return c&&(c[0]=void 0),c}}function h(a,b){return function(c){var d=a(c);return d?d:[b,c]}}function i(b,c){for(var d=[],e=0;e<b.length;e++){var f=a.consumeTrimmed(b[e],c);if(!f||""==f[0])return;void 0!==f[0]&&d.push(f[0]),c=f[1]}return""==c?d:void 0}function j(a,b,c,d,e){for(var g=[],h=[],i=[],j=f(d.length,e.length),k=0;j>k;k++){var l=b(d[k%d.length],e[k%e.length]);if(!l)return;g.push(l[0]),h.push(l[1]),i.push(l[2])}return[g,h,function(b){var d=b.map(function(a,b){return i[b](a)}).join(c);return a?a(d):d}]}function k(a,b,c){for(var d=[],e=[],f=[],g=0,h=0;h<c.length;h++)if("function"==typeof c[h]){var i=c[h](a[g],b[g++]);d.push(i[0]),e.push(i[1]),f.push(i[2])}else!function(a){d.push(!1),e.push(!1),f.push(function(){return c[a]})}(h);return[d,e,function(a){for(var b="",c=0;c<a.length;c++)b+=f[c](a[c]);return b}]}a.consumeToken=b,a.consumeTrimmed=c,a.consumeRepeated=d,a.consumeParenthesised=e,a.ignore=g,a.optional=h,a.consumeList=i,a.mergeNestedRepeated=j.bind(null,null),a.mergeWrappedNestedRepeated=j,a.mergeList=k}(d),function(a){function b(b){function c(b){var c=a.consumeToken(/^inset/i,b);if(c)return d.inset=!0,c;var c=a.consumeLengthOrPercent(b);if(c)return d.lengths.push(c[0]),c;var c=a.consumeColor(b);return c?(d.color=c[0],c):void 0}var d={inset:!1,lengths:[],color:null},e=a.consumeRepeated(c,/^/,b);return e&&e[0].length?[d,e[1]]:void 0}function c(c){var d=a.consumeRepeated(b,/^,/,c);return d&&""==d[1]?d[0]:void 0}function d(b,c){for(;b.lengths.length<Math.max(b.lengths.length,c.lengths.length);)b.lengths.push({px:0});for(;c.lengths.length<Math.max(b.lengths.length,c.lengths.length);)c.lengths.push({px:0});if(b.inset==c.inset&&!!b.color==!!c.color){for(var d,e=[],f=[[],0],g=[[],0],h=0;h<b.lengths.length;h++){var i=a.mergeDimensions(b.lengths[h],c.lengths[h],2==h);f[0].push(i[0]),g[0].push(i[1]),e.push(i[2])}if(b.color&&c.color){var j=a.mergeColors(b.color,c.color);f[1]=j[0],g[1]=j[1],d=j[2]}return[f,g,function(a){for(var c=b.inset?"inset ":" ",f=0;f<e.length;f++)c+=e[f](a[0][f])+" ";return d&&(c+=d(a[1])),c}]}}function e(b,c,d,e){function f(a){return{inset:a,color:[0,0,0,0],lengths:[{px:0},{px:0},{px:0},{px:0}]}}for(var g=[],h=[],i=0;i<d.length||i<e.length;i++){var j=d[i]||f(e[i].inset),k=e[i]||f(d[i].inset);g.push(j),h.push(k)}return a.mergeNestedRepeated(b,c,g,h)}var f=e.bind(null,d,", ");a.addPropertiesHandler(c,f,["box-shadow","text-shadow"])}(d),function(a){function b(a){return a.toFixed(3).replace(".000","")}function c(a,b,c){return Math.min(b,Math.max(a,c))}function d(a){return/^\s*[-+]?(\d*\.)?\d+\s*$/.test(a)?Number(a):void 0}function e(a,c){return[a,c,b]}function f(a,b){return 0!=a?h(0,1/0)(a,b):void 0}function g(a,b){return[a,b,function(a){return Math.round(c(1,1/0,a))}]}function h(a,d){return function(e,f){return[e,f,function(e){return b(c(a,d,e))}]}}function i(a,b){return[a,b,Math.round]}a.clamp=c,a.addPropertiesHandler(d,h(0,1/0),["border-image-width","line-height"]),a.addPropertiesHandler(d,h(0,1),["opacity","shape-image-threshold"]),a.addPropertiesHandler(d,f,["flex-grow","flex-shrink"]),a.addPropertiesHandler(d,g,["orphans","widows"]),a.addPropertiesHandler(d,i,["z-index"]),a.parseNumber=d,a.mergeNumbers=e,a.numberToString=b}(d,f),function(a){function b(a,b){return"visible"==a||"visible"==b?[0,1,function(c){return 0>=c?a:c>=1?b:"visible"}]:void 0}a.addPropertiesHandler(String,b,["visibility"])}(d),function(a){function b(a){a=a.trim(),e.fillStyle="#000",e.fillStyle=a;var b=e.fillStyle;if(e.fillStyle="#fff",e.fillStyle=a,b==e.fillStyle){e.fillRect(0,0,1,1);var c=e.getImageData(0,0,1,1).data;e.clearRect(0,0,1,1);var d=c[3]/255;return[c[0]*d,c[1]*d,c[2]*d,d]}}function c(b,c){return[b,c,function(b){function c(a){return Math.max(0,Math.min(255,a))}if(b[3])for(var d=0;3>d;d++)b[d]=Math.round(c(b[d]/b[3]));return b[3]=a.numberToString(a.clamp(0,1,b[3])),"rgba("+b.join(",")+")"}]}var d=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");d.width=d.height=1;var e=d.getContext("2d");a.addPropertiesHandler(b,c,["background-color","border-bottom-color","border-left-color","border-right-color","border-top-color","color","outline-color","text-decoration-color"]),a.consumeColor=a.consumeParenthesised.bind(null,b),a.mergeColors=c}(d,f),function(a,b){function c(a,b){if(b=b.trim().toLowerCase(),"0"==b&&"px".search(a)>=0)return{px:0};if(/^[^(]*$|^calc/.test(b)){b=b.replace(/calc\(/g,"(");var c={};b=b.replace(a,function(a){return c[a]=null,"U"+a});for(var d="U("+a.source+")",e=b.replace(/[-+]?(\d*\.)?\d+/g,"N").replace(new RegExp("N"+d,"g"),"D").replace(/\s[+-]\s/g,"O").replace(/\s/g,""),f=[/N\*(D)/g,/(N|D)[*/]N/g,/(N|D)O\1/g,/\((N|D)\)/g],g=0;g<f.length;)f[g].test(e)?(e=e.replace(f[g],"$1"),g=0):g++;if("D"==e){for(var h in c){var i=eval(b.replace(new RegExp("U"+h,"g"),"").replace(new RegExp(d,"g"),"*0"));if(!isFinite(i))return;c[h]=i}return c}}}function d(a,b){return e(a,b,!0)}function e(b,c,d){var e,f=[];for(e in b)f.push(e);for(e in c)f.indexOf(e)<0&&f.push(e);return b=f.map(function(a){return b[a]||0}),c=f.map(function(a){return c[a]||0}),[b,c,function(b){var c=b.map(function(c,e){return 1==b.length&&d&&(c=Math.max(c,0)),a.numberToString(c)+f[e]}).join(" + ");return b.length>1?"calc("+c+")":c}]}var f="px|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc",g=c.bind(null,new RegExp(f,"g")),h=c.bind(null,new RegExp(f+"|%","g")),i=c.bind(null,/deg|rad|grad|turn/g);a.parseLength=g,a.parseLengthOrPercent=h,a.consumeLengthOrPercent=a.consumeParenthesised.bind(null,h),a.parseAngle=i,a.mergeDimensions=e;
+var j=a.consumeParenthesised.bind(null,g),k=a.consumeRepeated.bind(void 0,j,/^/),l=a.consumeRepeated.bind(void 0,k,/^,/);a.consumeSizePairList=l;var m=function(a){var b=l(a);return b&&""==b[1]?b[0]:void 0},n=a.mergeNestedRepeated.bind(void 0,d," "),o=a.mergeNestedRepeated.bind(void 0,n,",");a.mergeNonNegativeSizePair=n,a.addPropertiesHandler(m,o,["background-size"]),a.addPropertiesHandler(h,d,["border-bottom-width","border-image-width","border-left-width","border-right-width","border-top-width","flex-basis","font-size","height","line-height","max-height","max-width","outline-width","width"]),a.addPropertiesHandler(h,e,["border-bottom-left-radius","border-bottom-right-radius","border-top-left-radius","border-top-right-radius","bottom","left","letter-spacing","margin-bottom","margin-left","margin-right","margin-top","min-height","min-width","outline-offset","padding-bottom","padding-left","padding-right","padding-top","perspective","right","shape-margin","text-indent","top","vertical-align","word-spacing"])}(d,f),function(a){function b(b){return a.consumeLengthOrPercent(b)||a.consumeToken(/^auto/,b)}function c(c){var d=a.consumeList([a.ignore(a.consumeToken.bind(null,/^rect/)),a.ignore(a.consumeToken.bind(null,/^\(/)),a.consumeRepeated.bind(null,b,/^,/),a.ignore(a.consumeToken.bind(null,/^\)/))],c);return d&&4==d[0].length?d[0]:void 0}function d(b,c){return"auto"==b||"auto"==c?[!0,!1,function(d){var e=d?b:c;if("auto"==e)return"auto";var f=a.mergeDimensions(e,e);return f[2](f[0])}]:a.mergeDimensions(b,c)}function e(a){return"rect("+a+")"}var f=a.mergeWrappedNestedRepeated.bind(null,e,d,", ");a.parseBox=c,a.mergeBoxes=f,a.addPropertiesHandler(c,f,["clip"])}(d,f),function(a){function b(a){return function(b){var c=0;return a.map(function(a){return a===j?b[c++]:a})}}function c(a){return a}function d(b){if(b=b.toLowerCase().trim(),"none"==b)return[];for(var c,d=/\s*(\w+)\(([^)]*)\)/g,e=[],f=0;c=d.exec(b);){if(c.index!=f)return;f=c.index+c[0].length;var g=c[1],h=m[g];if(!h)return;var i=c[2].split(","),j=h[0];if(j.length<i.length)return;for(var n=[],o=0;o<j.length;o++){var p,q=i[o],r=j[o];if(p=q?{A:function(b){return"0"==b.trim()?l:a.parseAngle(b)},N:a.parseNumber,T:a.parseLengthOrPercent,L:a.parseLength}[r.toUpperCase()](q):{a:l,n:n[0],t:k}[r],void 0===p)return;n.push(p)}if(e.push({t:g,d:n}),d.lastIndex==b.length)return e}}function e(a){return a.toFixed(6).replace(".000000","")}function f(b,c){if(b.decompositionPair!==c){b.decompositionPair=c;var d=a.makeMatrixDecomposition(b)}if(c.decompositionPair!==b){c.decompositionPair=b;var f=a.makeMatrixDecomposition(c)}return null==d[0]||null==f[0]?[[!1],[!0],function(a){return a?c[0].d:b[0].d}]:(d[0].push(0),f[0].push(1),[d,f,function(b){var c=a.quat(d[0][3],f[0][3],b[5]),g=a.composeMatrix(b[0],b[1],b[2],c,b[4]),h=g.map(e).join(",");return h}])}function g(a){return a.replace(/[xy]/,"")}function h(a){return a.replace(/(x|y|z|3d)?$/,"3d")}function i(b,c){var d=a.makeMatrixDecomposition&&!0,e=!1;if(!b.length||!c.length){b.length||(e=!0,b=c,c=[]);for(var i=0;i<b.length;i++){var j=b[i].t,k=b[i].d,l="scale"==j.substr(0,5)?1:0;c.push({t:j,d:k.map(function(a){if("number"==typeof a)return l;var b={};for(var c in a)b[c]=l;return b})})}}var n=function(a,b){return"perspective"==a&&"perspective"==b||("matrix"==a||"matrix3d"==a)&&("matrix"==b||"matrix3d"==b)},o=[],p=[],q=[];if(b.length!=c.length){if(!d)return;var r=f(b,c);o=[r[0]],p=[r[1]],q=[["matrix",[r[2]]]]}else for(var i=0;i<b.length;i++){var j,s=b[i].t,t=c[i].t,u=b[i].d,v=c[i].d,w=m[s],x=m[t];if(n(s,t)){if(!d)return;var r=f([b[i]],[c[i]]);o.push(r[0]),p.push(r[1]),q.push(["matrix",[r[2]]])}else{if(s==t)j=s;else if(w[2]&&x[2]&&g(s)==g(t))j=g(s),u=w[2](u),v=x[2](v);else{if(!w[1]||!x[1]||h(s)!=h(t)){if(!d)return;var r=f(b,c);o=[r[0]],p=[r[1]],q=[["matrix",[r[2]]]];break}j=h(s),u=w[1](u),v=x[1](v)}for(var y=[],z=[],A=[],B=0;B<u.length;B++){var C="number"==typeof u[B]?a.mergeNumbers:a.mergeDimensions,r=C(u[B],v[B]);y[B]=r[0],z[B]=r[1],A.push(r[2])}o.push(y),p.push(z),q.push([j,A])}}if(e){var D=o;o=p,p=D}return[o,p,function(a){return a.map(function(a,b){var c=a.map(function(a,c){return q[b][1][c](a)}).join(",");return"matrix"==q[b][0]&&16==c.split(",").length&&(q[b][0]="matrix3d"),q[b][0]+"("+c+")"}).join(" ")}]}var j=null,k={px:0},l={deg:0},m={matrix:["NNNNNN",[j,j,0,0,j,j,0,0,0,0,1,0,j,j,0,1],c],matrix3d:["NNNNNNNNNNNNNNNN",c],rotate:["A"],rotatex:["A"],rotatey:["A"],rotatez:["A"],rotate3d:["NNNA"],perspective:["L"],scale:["Nn",b([j,j,1]),c],scalex:["N",b([j,1,1]),b([j,1])],scaley:["N",b([1,j,1]),b([1,j])],scalez:["N",b([1,1,j])],scale3d:["NNN",c],skew:["Aa",null,c],skewx:["A",null,b([j,l])],skewy:["A",null,b([l,j])],translate:["Tt",b([j,j,k]),c],translatex:["T",b([j,k,k]),b([j,k])],translatey:["T",b([k,j,k]),b([k,j])],translatez:["L",b([k,k,j])],translate3d:["TTL",c]};a.addPropertiesHandler(d,i,["transform"])}(d,f),function(a){function b(a){var b=Number(a);return isNaN(b)||100>b||b>900||b%100!==0?void 0:b}function c(b){return b=100*Math.round(b/100),b=a.clamp(100,900,b),400===b?"normal":700===b?"bold":String(b)}function d(a,b){return[a,b,c]}a.addPropertiesHandler(b,d,["font-weight"])}(d),function(a){function b(a){var b={};for(var c in a)b[c]=-a[c];return b}function c(b){return a.consumeToken(/^(left|center|right|top|bottom)\b/i,b)||a.consumeLengthOrPercent(b)}function d(b,d){var e=a.consumeRepeated(c,/^/,d);if(e&&""==e[1]){var f=e[0];if(f[0]=f[0]||"center",f[1]=f[1]||"center",3==b&&(f[2]=f[2]||{px:0}),f.length==b){if(/top|bottom/.test(f[0])||/left|right/.test(f[1])){var h=f[0];f[0]=f[1],f[1]=h}if(/left|right|center|Object/.test(f[0])&&/top|bottom|center|Object/.test(f[1]))return f.map(function(a){return"object"==typeof a?a:g[a]})}}}function e(d){var e=a.consumeRepeated(c,/^/,d);if(e){for(var f=e[0],h=[{"%":50},{"%":50}],i=0,j=!1,k=0;k<f.length;k++){var l=f[k];"string"==typeof l?(j=/bottom|right/.test(l),i={left:0,right:0,center:i,top:1,bottom:1}[l],h[i]=g[l],"center"==l&&i++):(j&&(l=b(l),l["%"]=(l["%"]||0)+100),h[i]=l,i++,j=!1)}return[h,e[1]]}}function f(b){var c=a.consumeRepeated(e,/^,/,b);return c&&""==c[1]?c[0]:void 0}var g={left:{"%":0},center:{"%":50},right:{"%":100},top:{"%":0},bottom:{"%":100}},h=a.mergeNestedRepeated.bind(null,a.mergeDimensions," ");a.addPropertiesHandler(d.bind(null,3),h,["transform-origin"]),a.addPropertiesHandler(d.bind(null,2),h,["perspective-origin"]),a.consumePosition=e,a.mergeOffsetList=h;var i=a.mergeNestedRepeated.bind(null,h,", ");a.addPropertiesHandler(f,i,["background-position","object-position"])}(d),function(a){function b(b){var c=a.consumeToken(/^circle/,b);if(c&&c[0])return["circle"].concat(a.consumeList([a.ignore(a.consumeToken.bind(void 0,/^\(/)),d,a.ignore(a.consumeToken.bind(void 0,/^at/)),a.consumePosition,a.ignore(a.consumeToken.bind(void 0,/^\)/))],c[1]));var f=a.consumeToken(/^ellipse/,b);if(f&&f[0])return["ellipse"].concat(a.consumeList([a.ignore(a.consumeToken.bind(void 0,/^\(/)),e,a.ignore(a.consumeToken.bind(void 0,/^at/)),a.consumePosition,a.ignore(a.consumeToken.bind(void 0,/^\)/))],f[1]));var g=a.consumeToken(/^polygon/,b);return g&&g[0]?["polygon"].concat(a.consumeList([a.ignore(a.consumeToken.bind(void 0,/^\(/)),a.optional(a.consumeToken.bind(void 0,/^nonzero\s*,|^evenodd\s*,/),"nonzero,"),a.consumeSizePairList,a.ignore(a.consumeToken.bind(void 0,/^\)/))],g[1])):void 0}function c(b,c){return b[0]===c[0]?"circle"==b[0]?a.mergeList(b.slice(1),c.slice(1),["circle(",a.mergeDimensions," at ",a.mergeOffsetList,")"]):"ellipse"==b[0]?a.mergeList(b.slice(1),c.slice(1),["ellipse(",a.mergeNonNegativeSizePair," at ",a.mergeOffsetList,")"]):"polygon"==b[0]&&b[1]==c[1]?a.mergeList(b.slice(2),c.slice(2),["polygon(",b[1],g,")"]):void 0:void 0}var d=a.consumeParenthesised.bind(null,a.parseLengthOrPercent),e=a.consumeRepeated.bind(void 0,d,/^/),f=a.mergeNestedRepeated.bind(void 0,a.mergeDimensions," "),g=a.mergeNestedRepeated.bind(void 0,f,",");a.addPropertiesHandler(b,c,["shape-outside"])}(d),function(a){function b(a,b){b.concat([a]).forEach(function(b){b in document.documentElement.style&&(c[a]=b)})}var c={};b("transform",["webkitTransform","msTransform"]),b("transformOrigin",["webkitTransformOrigin"]),b("perspective",["webkitPerspective"]),b("perspectiveOrigin",["webkitPerspectiveOrigin"]),a.propertyName=function(a){return c[a]||a}}(d,f)}(),!function(a,b){function c(a){var b=window.document.timeline;b.currentTime=a,b._discardAnimations(),0==b._animations.length?e=!1:requestAnimationFrame(c)}var d=window.requestAnimationFrame;window.requestAnimationFrame=function(a){return d(function(b){window.document.timeline._updateAnimationsPromises(),a(b),window.document.timeline._updateAnimationsPromises()})},b.AnimationTimeline=function(){this._animations=[],this.currentTime=void 0},b.AnimationTimeline.prototype={getAnimations:function(){return this._discardAnimations(),this._animations.slice()},getAnimationPlayers:function(){return a.deprecated("AnimationTimeline.getAnimationPlayers","2015-03-23","Use AnimationTimeline.getAnimations instead."),this.getAnimations()},_updateAnimationsPromises:function(){b.animationsWithPromises=b.animationsWithPromises.filter(function(a){return a._updatePromises()})},_discardAnimations:function(){this._updateAnimationsPromises(),this._animations=this._animations.filter(function(a){return"finished"!=a.playState&&"idle"!=a.playState})},_play:function(a){var c=new b.Animation(a);return this._animations.push(c),b.restartWebAnimationsNextTick(),c._updatePromises(),c._animation.play(),c._updatePromises(),c},play:function(a){return a&&a.remove(),this._play(a)}};var e=!1;b.restartWebAnimationsNextTick=function(){e||(e=!0,requestAnimationFrame(c))};var f=new b.AnimationTimeline;b.timeline=f;try{Object.defineProperty(window.document,"timeline",{configurable:!0,get:function(){return f}})}catch(g){}try{window.document.timeline=f}catch(g){}}(c,e,f),function(a,b){b.animationsWithPromises=[],b.Animation=function(b){this.effect=b,b&&(b._animation=this),this._sequenceNumber=a.sequenceNumber++,this._holdTime=0,this._paused=!1,this._isGroup=!1,this._animation=null,this._childAnimations=[],this._callback=null,this._oldPlayState="idle",this._rebuildUnderlyingAnimation(),this._animation.cancel(),this._updatePromises()},b.Animation.prototype={_updatePromises:function(){var a=this._oldPlayState,b=this.playState;return this._readyPromise&&b!==a&&("idle"==b?(this._rejectReadyPromise(),this._readyPromise=void 0):"pending"==a?this._resolveReadyPromise():"pending"==b&&(this._readyPromise=void 0)),this._finishedPromise&&b!==a&&("idle"==b?(this._rejectFinishedPromise(),this._finishedPromise=void 0):"finished"==b?this._resolveFinishedPromise():"finished"==a&&(this._finishedPromise=void 0)),this._oldPlayState=this.playState,this._readyPromise||this._finishedPromise},_rebuildUnderlyingAnimation:function(){this._updatePromises();var a,c,d,e,f=this._animation?!0:!1;f&&(a=this.playbackRate,c=this._paused,d=this.startTime,e=this.currentTime,this._animation.cancel(),this._animation._wrapper=null,this._animation=null),(!this.effect||this.effect instanceof window.KeyframeEffect)&&(this._animation=b.newUnderlyingAnimationForKeyframeEffect(this.effect),b.bindAnimationForKeyframeEffect(this)),(this.effect instanceof window.SequenceEffect||this.effect instanceof window.GroupEffect)&&(this._animation=b.newUnderlyingAnimationForGroup(this.effect),b.bindAnimationForGroup(this)),f&&(1!=a&&(this.playbackRate=a),null!==d?this.startTime=d:null!==e?this.currentTime=e:null!==this._holdTime&&(this.currentTime=this._holdTime),c&&this.pause()),this._updatePromises()},_updateChildren:function(){if(this.effect&&"idle"!=this.playState){var a=this.effect._timing.delay;this._childAnimations.forEach(function(c){this._arrangeChildren(c,a),this.effect instanceof window.SequenceEffect&&(a+=b.groupChildDuration(c.effect))}.bind(this))}},_setExternalAnimation:function(a){if(this.effect&&this._isGroup)for(var b=0;b<this.effect.children.length;b++)this.effect.children[b]._animation=a,this._childAnimations[b]._setExternalAnimation(a)},_constructChildAnimations:function(){if(this.effect&&this._isGroup){var a=this.effect._timing.delay;this._removeChildAnimations(),this.effect.children.forEach(function(c){var d=window.document.timeline._play(c);this._childAnimations.push(d),d.playbackRate=this.playbackRate,this._paused&&d.pause(),c._animation=this.effect._animation,this._arrangeChildren(d,a),this.effect instanceof window.SequenceEffect&&(a+=b.groupChildDuration(c))}.bind(this))}},_arrangeChildren:function(a,b){null===this.startTime?a.currentTime=this.currentTime-b/this.playbackRate:a.startTime!==this.startTime+b/this.playbackRate&&(a.startTime=this.startTime+b/this.playbackRate)},get playState(){return this._animation?this._animation.playState:"idle"},get finished(){return window.Promise?(this._finishedPromise||(-1==b.animationsWithPromises.indexOf(this)&&b.animationsWithPromises.push(this),this._finishedPromise=new Promise(function(a,b){this._resolveFinishedPromise=function(){a(this)},this._rejectFinishedPromise=function(){b({type:DOMException.ABORT_ERR,name:"AbortError"})}}.bind(this)),"finished"==this.playState&&this._resolveFinishedPromise()),this._finishedPromise):(console.warn("Animation Promises require JavaScript Promise constructor"),null)},get ready(){return window.Promise?(this._readyPromise||(-1==b.animationsWithPromises.indexOf(this)&&b.animationsWithPromises.push(this),this._readyPromise=new Promise(function(a,b){this._resolveReadyPromise=function(){a(this)},this._rejectReadyPromise=function(){b({type:DOMException.ABORT_ERR,name:"AbortError"})}}.bind(this)),"pending"!==this.playState&&this._resolveReadyPromise()),this._readyPromise):(console.warn("Animation Promises require JavaScript Promise constructor"),null)},get onfinish(){return this._onfinish},set onfinish(a){"function"==typeof a?(this._onfinish=a,this._animation.onfinish=function(b){b.target=this,a.call(this,b)}.bind(this)):(this._animation.onfinish=a,this.onfinish=this._animation.onfinish)},get currentTime(){this._updatePromises();var a=this._animation.currentTime;return this._updatePromises(),a},set currentTime(a){this._updatePromises(),this._animation.currentTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE,this._register(),this._forEachChild(function(b,c){b.currentTime=a-c}),this._updatePromises()},get startTime(){return this._animation.startTime},set startTime(a){this._updatePromises(),this._animation.startTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE,this._register(),this._forEachChild(function(b,c){b.startTime=a+c}),this._updatePromises()},get playbackRate(){return this._animation.playbackRate},set playbackRate(a){this._updatePromises();var b=this.currentTime;this._animation.playbackRate=a,this._forEachChild(function(b){b.playbackRate=a}),"paused"!=this.playState&&"idle"!=this.playState&&this.play(),null!==b&&(this.currentTime=b),this._updatePromises()},get source(){return a.deprecated("Animation.source","2015-03-23","Use Animation.effect instead."),this.effect},play:function(){this._updatePromises(),this._paused=!1,this._animation.play(),-1==document.timeline._animations.indexOf(this)&&document.timeline._animations.push(this),this._register(),b.awaitStartTime(this),this._forEachChild(function(a){var b=a.currentTime;a.play(),a.currentTime=b}),this._updatePromises()},pause:function(){this._updatePromises(),this.currentTime&&(this._holdTime=this.currentTime),this._animation.pause(),this._register(),this._forEachChild(function(a){a.pause()}),this._paused=!0,this._updatePromises()},finish:function(){this._updatePromises(),this._animation.finish(),this._register(),this._updatePromises()},cancel:function(){this._updatePromises(),this._animation.cancel(),this._register(),this._removeChildAnimations(),this._updatePromises()},reverse:function(){this._updatePromises();var a=this.currentTime;this._animation.reverse(),this._forEachChild(function(a){a.reverse()}),null!==a&&(this.currentTime=a),this._updatePromises()},addEventListener:function(a,b){var c=b;"function"==typeof b&&(c=function(a){a.target=this,b.call(this,a)}.bind(this),b._wrapper=c),this._animation.addEventListener(a,c)},removeEventListener:function(a,b){this._animation.removeEventListener(a,b&&b._wrapper||b)},_removeChildAnimations:function(){for(;this._childAnimations.length;)this._childAnimations.pop().cancel()},_forEachChild:function(b){var c=0;if(this.effect.children&&this._childAnimations.length<this.effect.children.length&&this._constructChildAnimations(),this._childAnimations.forEach(function(a){b.call(this,a,c),this.effect instanceof window.SequenceEffect&&(c+=a.effect.activeDuration)}.bind(this)),"pending"!=this.playState){var d=this.effect._timing,e=this.currentTime;null!==e&&(e=a.calculateTimeFraction(a.calculateActiveDuration(d),e,d)),(null==e||isNaN(e))&&this._removeChildAnimations()}}}}(c,e,f),function(a,b){function c(b){this._frames=a.normalizeKeyframes(b)}function d(){for(var a=!1;h.length;){var b=h.shift();b._updateChildren(),a=!0}return a}var e=function(a){if(a._animation=void 0,a instanceof window.SequenceEffect||a instanceof window.GroupEffect)for(var b=0;b<a.children.length;b++)e(a.children[b])};b.removeMulti=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c];d._parent?(-1==b.indexOf(d._parent)&&b.push(d._parent),d._parent.children.splice(d._parent.children.indexOf(d),1),d._parent=null,e(d)):d._animation&&d._animation.effect==d&&(d._animation.cancel(),d._animation.effect=new KeyframeEffect(null,[]),d._animation._callback&&(d._animation._callback._animation=null),d._animation._rebuildUnderlyingAnimation(),e(d))}for(c=0;c<b.length;c++)b[c]._rebuild()},b.KeyframeEffect=function(b,d,e){return this.target=b,this._timingInput=a.cloneTimingInput(e),this._timing=a.normalizeTimingInput(e),this.timing=a.makeTiming(e),this._normalizedKeyframes="function"==typeof d?d:new c(d),this._keyframes=d,this.activeDuration=a.calculateActiveDuration(this._timing),this},b.KeyframeEffect.prototype={getFrames:function(){return"function"==typeof this._normalizedKeyframes?this._normalizedKeyframes:this._normalizedKeyframes._frames},get effect(){return a.deprecated("KeyframeEffect.effect","2015-03-23","Use KeyframeEffect.getFrames() instead."),this._normalizedKeyframes},clone:function(){if("function"==typeof this.getFrames())throw new Error("Cloning custom effects is not supported.");var b=new KeyframeEffect(this.target,[],a.cloneTimingInput(this._timingInput));return b._normalizedKeyframes=this._normalizedKeyframes,b._keyframes=this._keyframes,b},remove:function(){b.removeMulti([this])}};var f=Element.prototype.animate;Element.prototype.animate=function(a,c){return b.timeline._play(new b.KeyframeEffect(this,a,c))};var g=document.createElementNS("http://www.w3.org/1999/xhtml","div");b.newUnderlyingAnimationForKeyframeEffect=function(a){if(a){var b=a.target||g,c=a._keyframes;"function"==typeof c&&(c=[]);var d=a._timingInput}else var b=g,c=[],d=0;return f.apply(b,[c,d])},b.bindAnimationForKeyframeEffect=function(a){a.effect&&"function"==typeof a.effect._normalizedKeyframes&&b.bindAnimationForCustomEffect(a)};var h=[];b.awaitStartTime=function(a){null===a.startTime&&a._isGroup&&(0==h.length&&requestAnimationFrame(d),h.push(a))};var i=window.getComputedStyle;Object.defineProperty(window,"getComputedStyle",{configurable:!0,enumerable:!0,value:function(){window.document.timeline._updateAnimationsPromises();var a=i.apply(this,arguments);return d()&&(a=i.apply(this,arguments)),window.document.timeline._updateAnimationsPromises(),a}}),window.KeyframeEffect=b.KeyframeEffect,window.Element.prototype.getAnimations=function(){return document.timeline.getAnimations().filter(function(a){return null!==a.effect&&a.effect.target==this}.bind(this))},window.Element.prototype.getAnimationPlayers=function(){return a.deprecated("Element.getAnimationPlayers","2015-03-23","Use Element.getAnimations instead."),this.getAnimations()},window.Animation=function(){a.deprecated("window.Animation","2015-03-23","Use window.KeyframeEffect instead."),window.KeyframeEffect.apply(this,arguments)},window.Animation.prototype=Object.create(window.KeyframeEffect.prototype),window.Animation.prototype.constructor=window.Animation}(c,e,f),function(a,b){function c(a){a._registered||(a._registered=!0,f.push(a),g||(g=!0,requestAnimationFrame(d)))}function d(){var a=f;f=[],a.sort(function(a,b){return a._sequenceNumber-b._sequenceNumber}),a=a.filter(function(a){a();var b=a._animation?a._animation.playState:"idle";return"running"!=b&&"pending"!=b&&(a._registered=!1),a._registered}),f.push.apply(f,a),f.length?(g=!0,requestAnimationFrame(d)):g=!1}var e=(document.createElementNS("http://www.w3.org/1999/xhtml","div"),0);b.bindAnimationForCustomEffect=function(b){var d=b.effect.target,f=b.effect._normalizedKeyframes,g=b.effect.timing,h=null;g=a.normalizeTimingInput(g);var i=function(){var c=i._animation?i._animation.currentTime:null;null!==c&&(c=a.calculateTimeFraction(a.calculateActiveDuration(g),c,g),isNaN(c)&&(c=null)),c!==h&&f(c,d,b.effect),h=c};i._animation=b,i._registered=!1,i._sequenceNumber=e++,b._callback=i,c(i)};var f=[],g=!1;b.Animation.prototype._register=function(){this._callback&&c(this._callback)}}(c,e,f),function(a,b){function c(a){return a._timing.delay+a.activeDuration+a._timing.endDelay}function d(b,c){this._parent=null,this.children=b||[],this._reparent(this.children),this._timingInput=a.cloneTimingInput(c),this._timing=a.normalizeTimingInput(c,!0),this.timing=a.makeTiming(c,!0),"auto"===this._timing.duration&&(this._timing.duration=this.activeDuration)}window.SequenceEffect=function(){d.apply(this,arguments)},window.GroupEffect=function(){d.apply(this,arguments)},d.prototype={_isAncestor:function(a){for(var b=this;null!==b;){if(b==a)return!0;b=b._parent}return!1},_rebuild:function(){for(var a=this;a;)"auto"===a.timing.duration&&(a._timing.duration=a.activeDuration),a=a._parent;this._animation&&this._animation._rebuildUnderlyingAnimation()},_reparent:function(a){b.removeMulti(a);for(var c=0;c<a.length;c++)a[c]._parent=this},_putChild:function(a,b){for(var c=b?"Cannot append an ancestor or self":"Cannot prepend an ancestor or self",d=0;d<a.length;d++)if(this._isAncestor(a[d]))throw{type:DOMException.HIERARCHY_REQUEST_ERR,name:"HierarchyRequestError",message:c};for(var d=0;d<a.length;d++)b?this.children.push(a[d]):this.children.unshift(a[d]);this._reparent(a),this._rebuild()},append:function(){this._putChild(arguments,!0)},prepend:function(){this._putChild(arguments,!1)},get firstChild(){return this.children.length?this.children[0]:null},get lastChild(){return this.children.length?this.children[this.children.length-1]:null},clone:function(){for(var b=a.cloneTimingInput(this._timingInput),c=[],d=0;d<this.children.length;d++)c.push(this.children[d].clone());return this instanceof GroupEffect?new GroupEffect(c,b):new SequenceEffect(c,b)},remove:function(){b.removeMulti([this])}},window.SequenceEffect.prototype=Object.create(d.prototype),Object.defineProperty(window.SequenceEffect.prototype,"activeDuration",{get:function(){var a=0;return this.children.forEach(function(b){a+=c(b)}),Math.max(a,0)}}),window.GroupEffect.prototype=Object.create(d.prototype),Object.defineProperty(window.GroupEffect.prototype,"activeDuration",{get:function(){var a=0;return this.children.forEach(function(b){a=Math.max(a,c(b))}),a}}),b.newUnderlyingAnimationForGroup=function(c){var d,e=null,f=function(b){var c=d._wrapper;return c&&"pending"!=c.playState&&c.effect?null==b?void c._removeChildAnimations():0==b&&c.playbackRate<0&&(e||(e=a.normalizeTimingInput(c.effect.timing)),b=a.calculateTimeFraction(a.calculateActiveDuration(e),-1,e),isNaN(b)||null==b)?(c._forEachChild(function(a){a.currentTime=-1}),void c._removeChildAnimations()):void 0:void 0};return d=b.timeline._play(new b.KeyframeEffect(null,f,c._timing))},b.bindAnimationForGroup=function(a){a._animation._wrapper=a,a._isGroup=!0,b.awaitStartTime(a),a._constructChildAnimations(),a._setExternalAnimation(a)},b.groupChildDuration=c,window.AnimationSequence=function(){a.deprecated("window.AnimationSequence","2015-03-23","Use window.SequenceEffect instead."),window.SequenceEffect.apply(this,arguments)},window.AnimationSequence.prototype=Object.create(window.SequenceEffect.prototype),window.AnimationSequence.prototype.constructor=window.AnimationSequence,window.AnimationGroup=function(){a.deprecated("window.AnimationGroup","2015-03-23","Use window.GroupEffect instead."),window.GroupEffect.apply(this,arguments)},window.AnimationGroup.prototype=Object.create(window.GroupEffect.prototype),window.AnimationGroup.prototype.constructor=window.AnimationGroup}(c,e,f)}({},function(){return this}());
+//# sourceMappingURL=web-animations-next.min.js.map
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/web-animations-js/web-animations-next.min.js.map b/polymer_1.0.4/bower_components/web-animations-js/web-animations-next.min.js.map
new file mode 100644
index 0000000..bcb0efc
--- /dev/null
+++ b/polymer_1.0.4/bower_components/web-animations-js/web-animations-next.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"web-animations-next.min.js","sources":["src/scope.js","src/timing-utilities.js","src/normalize-keyframes.js","src/deprecation.js","src/keyframe-interpolations.js","src/property-interpolation.js","src/keyframe-effect.js","src/apply-preserving-inline-style.js","src/element-animatable.js","src/interpolation.js","src/matrix-interpolation.js","src/animation.js","src/tick.js","src/timeline.js","src/web-animations-next-animation.js","src/keyframe-effect-constructor.js","src/effect-callback.js","src/group-constructors.js"],"names":["webAnimationsShared","webAnimations1","webAnimationsNext","webAnimationsTesting","shared","cloneTimingInput","timingInput","clone","m","makeTiming","forGroup","timing","delay","endDelay","fill","iterationStart","iterations","duration","playbackRate","direction","easing","isNaN","undefined","Object","getOwnPropertyNames","forEach","property","fills","indexOf","directions","isDeprecated","normalizeTimingInput","toTimingFunction","cubic","a","b","c","d","linear","x","f","start","end","mid","xEst","Math","abs","step","count","pos","stepSize","cubicData","cubicBezierRe","exec","apply","this","slice","map","Number","stepData","stepRe","Start","middle","Middle","End","preset","presets","calculateActiveDuration","repeatedDuration","calculatePhase","activeDuration","localTime","PhaseNone","PhaseBefore","PhaseAfter","PhaseActive","calculateActiveTime","fillMode","phase","calculateScaledActiveTime","activeTime","startOffset","calculateIterationTime","iterationDuration","scaledActiveTime","Infinity","calculateCurrentIteration","iterationTime","floor","calculateTransformedTime","currentIteration","currentIterationIsOdd","currentDirectionIsForwards","directedTime","timeFraction","calculateTimeFraction","split","ease","ease-in","ease-out","ease-in-out","step-start","step-middle","step-end","numberString","RegExp","antiAlias","value","aliases","expandShorthandAndAntiAlias","result","longProperties","shorthandToLonghand","shorthandExpanderElem","style","i","longProperty","longhandValue","normalizeKeyframes","effectInput","spaceKeyframes","length","keyframes","offset","previousIndex","previousOffset","j","Array","isArray","TypeError","originalKeyframe","keyframe","member","memberValue","isFinite","type","DOMException","NOT_SUPPORTED_ERR","name","message","everyFrameHasOffset","code","INVALID_MODIFICATION_ERR","filter","background","border","borderBottom","borderColor","borderLeft","borderRadius","borderRight","borderTop","borderWidth","flex","font","margin","outline","padding","document","createElementNS","borderWidthAliases","thin","medium","thick","borderBottomWidth","borderLeftWidth","borderRightWidth","borderTopWidth","fontSize","xx-small","x-small","small","large","x-large","xx-large","fontWeight","normal","bold","outlineWidth","textShadow","none","boxShadow","silenced","feature","date","advice","plural","auxVerb","today","Date","expiry","setMonth","getMonth","console","warn","toDateString","deprecated","Error","scope","makePropertySpecificKeyframeGroups","propertySpecificKeyframeGroups","propertySpecificKeyframe","groupName","group","makeInterpolations","interpolations","startTime","startValue","endValue","endTime","push","propertyInterpolation","sort","leftInterpolation","rightInterpolation","convertEffectInput","target","fraction","interpolation","offsetFraction","localDuration","scaledLocalTime","clear","addPropertyHandler","parser","merger","propertyHandlers","addPropertiesHandler","properties","replace","toUpperCase","left","initialValues","ucProperty","right","handlers","parsedLeft","parsedRight","interpolationArgs","Interpolation","t","interp","bool","backgroundColor","backgroundPosition","borderBottomColor","borderBottomLeftRadius","borderBottomRightRadius","borderLeftColor","borderRightColor","borderSpacing","borderTopColor","borderTopLeftRadius","borderTopRightRadius","bottom","clip","color","height","letterSpacing","lineHeight","marginBottom","marginLeft","marginRight","marginTop","maxHeight","maxWidth","minHeight","minWidth","opacity","outlineColor","paddingBottom","paddingLeft","paddingRight","paddingTop","transform","verticalAlign","visibility","width","wordSpacing","zIndex","EffectTime","effectTime","_totalDuration","KeyframeEffect","keyframeEffect","_update","_clear","_hasSameTarget","otherTarget","_isCurrent","nullEffect","testing","configureProperty","descriptor","enumerable","configurable","defineProperty","AnimatedCSSStyleDeclaration","element","_surrogateStyle","_length","_isAnimatedProperty","_style","_updateIndices","ensureStyleIsPatched","_webAnimationsPatchedStyle","animatedStyle","get","styleAttributes","cssText","parentRule","styleMethods","getPropertyCSSValue","getPropertyPriority","getPropertyValue","removeProperty","styleMutatingMethods","setProperty","prototype",{"end":{"file":"src/apply-preserving-inline-style.js","comments_before":[],"nlb":false,"endpos":2110,"pos":2103,"col":8,"line":64,"value":"cssText","type":"name"},"start":{"file":"src/apply-preserving-inline-style.js","comments_before":[],"nlb":false,"endpos":2110,"pos":2103,"col":8,"line":64,"value":"cssText","type":"name"},"name":"cssText"},"isAffectedProperty","text","index","method","modifiesStyle","arguments","documentElement","_set","propertyName","window","Element","animate","timeline","_play","from","to","r","interpolate","convertToString","clamp","max","min","quat","product","fromQ","toQ","theta","sin","sqrt","cos","composeMatrix","multiply","k","is2D","translate","skew","perspective","matrix","y","z","rotMatrix","w","temp","scale","concat","sequenceNumber","AnimationEvent","currentTime","timelineTime","bubbles","cancelable","currentTarget","defaultPrevented","eventPhase","Event","AT_TARGET","timeStamp","now","Animation","effect","_sequenceNumber","_currentTime","_paused","_playbackRate","_inTimeline","_finishedFlag","onfinish","_finishHandlers","_effect","_inEffect","_idle","_currentTimePending","_ensureAlive","_animations","_tickCurrentTime","newTime","ignoreLimit","_isFinished","restart","_startTime","_timeline","invalidateEffects","oldCurrentTime","playState","play","pause","finish","cancel","addEventListener","handler","removeEventListener","splice","_fireEvents","baseTime","finished","event","setTimeout","call","processRafCallbacks","processing","rafCallbacks","tick","entry","needsRetick","applyPendingEffects","_now","compareAnimations","rightAnimation","leftAnimation","InternalTimeline","performance","hasRestartedThisFrame","ticking","updatingAnimations","newPendingClears","newPendingEffects","animation","_tick","webAnimationsNextTick","_discardAnimations","requestAnimationFrame","originalRequestAnimationFrame","_updateAnimationsPromises","AnimationTimeline","getAnimations","getAnimationPlayers","animationsWithPromises","_updatePromises","restartWebAnimationsNextTick","_animation","remove","e","_holdTime","_isGroup","_childAnimations","_callback","_oldPlayState","_rebuildUnderlyingAnimation","oldPlayState","newPlayState","_readyPromise","_rejectReadyPromise","_resolveReadyPromise","_finishedPromise","_rejectFinishedPromise","_resolveFinishedPromise","oldPlaybackRate","oldPaused","oldStartTime","hadUnderlying","_wrapper","newUnderlyingAnimationForKeyframeEffect","bindAnimationForKeyframeEffect","SequenceEffect","GroupEffect","newUnderlyingAnimationForGroup","bindAnimationForGroup","_updateChildren","_timing","childAnimation","_arrangeChildren","groupChildDuration","bind","_setExternalAnimation","children","_constructChildAnimations","_removeChildAnimations","child","Promise","resolve","reject","ABORT_ERR","ready","_onfinish","v","sign","MAX_VALUE","_register","_forEachChild","source","awaitStartTime","time","reverse","wrapped","pop","KeyframeList","_frames","updatePendingGroups","updated","pendingGroups","shift","disassociate","removeMulti","effects","oldParents","_parent","_rebuild","_timingInput","_normalizedKeyframes","_keyframes","getFrames","originalElementAnimate","nullTarget","bindAnimationForCustomEffect","groupAnimation","originalGetComputedStyle","getComputedStyle","create","constructor","register","callback","_registered","callbacks","updating","effectFunction","last","node","_reparent","_isAncestor","newChildren","_putChild","args","isAppend","HIERARCHY_REQUEST_ERR","unshift","append","prepend","firstChild","lastChild","clonedTiming","clonedChildren","total","underlyingAnimation","ticker","tf","AnimationSequence","AnimationGroup"],"mappings":";;;;;;;;;;;;;;CAcA,SAAIA,EAAAA,GACAC,EAAAA,QACAC,CAFJ,IAAIF,MACAC,KACAC,KAGEC,EAAuB,MCL7B,SAAUC,GAKR,QAASC,GAAiBC,GACxB,GAA0B,gBAAfA,GACT,MAAOA,EAET,IAAIC,KACJ,KAAK,GAAIC,KAAKF,GACZC,EAAMC,GAAKF,EAAYE,EAEzB,OAAOD,GAGT,QAASE,GAAWH,EAAaI,GAC/B,GAAIC,IACFC,MAAO,EACPC,SAAU,EACVC,KAAMJ,EAAW,OAAS,OAC1BK,eAAgB,EAChBC,WAAY,EACZC,SAAUP,EAAW,OAAS,EAC9BQ,aAAc,EACdC,UAAW,SACXC,OAAQ,SAyBV,OAvB0B,gBAAfd,IAA4Be,MAAMf,GAElBgB,SAAhBhB,GACTiB,OAAOC,oBAAoBlB,GAAamB,QAAQ,SAASC,GACvD,GAA6B,QAAzBpB,EAAYoB,GAAqB,CACnC,IAA+B,gBAApBf,GAAOe,IAAqC,YAAZA,KACL,gBAAzBpB,GAAYoB,IAAyBL,MAAMf,EAAYoB,KAChE,MAGJ,IAAiB,QAAZA,GAAgE,IAAxCC,EAAMC,QAAQtB,EAAYoB,IACrD,MAEF,IAAiB,aAAZA,GAA0E,IAA7CG,EAAWD,QAAQtB,EAAYoB,IAC/D,MAEF,IAAgB,gBAAZA,GAAwD,IAA1BpB,EAAYoB,IAAmBtB,EAAO0B,aAAa,qCAAsC,aAAc,uCACvI,MAEFnB,GAAOe,GAAYpB,EAAYoB,MAlBnCf,EAAOM,SAAWX,EAsBbK,EAGT,QAASoB,GAAqBzB,EAAaI,GACzC,GAAIC,GAASF,EAAWH,EAAaI,EAErC,OADAC,GAAOS,OAASY,EAAiBrB,EAAOS,QACjCT,EAGT,QAASsB,GAAMC,EAAGC,EAAGC,EAAGC,GACtB,MAAQ,GAAJH,GAASA,EAAI,GAAS,EAAJE,GAASA,EAAI,EAC1BE,EAEF,SAASC,GAOZ,QAASC,GAAEN,EAAGC,EAAG3B,GAAK,MAAO,GAAI0B,GAAK,EAAI1B,IAAM,EAAIA,GAAKA,EAAI,EAAI2B,GAAK,EAAI3B,GAAKA,EAAIA,EAAIA,EAAIA,EAAIA,EANjG,GAAS,GAAL+B,GAAe,GAALA,EACZ,MAAOA,EAGT,KADA,GAAIE,GAAQ,EAAGC,EAAM,IACX,CACR,GAAIC,IAAOF,EAAQC,GAAO,EAEtBE,EAAOJ,EAAEN,EAAGE,EAAGO,EACnB,IAAIE,KAAKC,IAAIP,EAAIK,GAAQ,KACvB,MAAOJ,GAAEL,EAAGE,EAAGM,EAENJ,GAAPK,EACFH,EAAQE,EAERD,EAAMC,IAUd,QAASI,GAAKC,EAAOC,GACnB,MAAO,UAASV,GACd,GAAIA,GAAK,EACP,MAAO,EAET,IAAIW,GAAW,EAAIF,CAEnB,OADAT,IAAKU,EAAMC,EACJX,EAAIA,EAAIW,GAmBnB,QAASlB,GAAiBZ,GACxB,GAAI+B,GAAYC,EAAcC,KAAKjC,EACnC,IAAI+B,EACF,MAAOlB,GAAMqB,MAAMC,KAAMJ,EAAUK,MAAM,GAAGC,IAAIC,QAElD,IAAIC,GAAWC,EAAOP,KAAKjC,EAC3B,IAAIuC,EACF,MAAOZ,GAAKW,OAAOC,EAAS,KAAMlB,MAASoB,EAAOC,OAAUC,EAAQrB,IAAOsB,GAAKL,EAAS,IAE3F,IAAIM,GAASC,EAAQ9C,EACrB,OAAI6C,GACKA,EAEF3B,EAGT,QAAS6B,GAAwBxD,GAC/B,MAAOkC,MAAKC,IAAIsB,EAAiBzD,GAAUA,EAAOO,cAGpD,QAASkD,GAAiBzD,GACxB,MAAOA,GAAOM,SAAWN,EAAOK,WAQlC,QAASqD,GAAeC,EAAgBC,EAAW5D,GACjD,MAAiB,OAAb4D,EACKC,EAELD,EAAY5D,EAAOC,MACd6D,EAELF,GAAa5D,EAAOC,MAAQ0D,EACvBI,EAEFC,EAGT,QAASC,GAAoBN,EAAgBO,EAAUN,EAAWO,EAAOlE,GACvE,OAAQkE,GACN,IAAKL,GACH,MAAgB,aAAZI,GAAuC,QAAZA,EACtB,EACF,IACT,KAAKF,GACH,MAAOJ,GAAY3D,CACrB,KAAK8D,GACH,MAAgB,YAAZG,GAAsC,QAAZA,EACrBP,EACF,IACT,KAAKE,GACH,MAAO,OAIb,QAASO,GAA0BT,EAAgBU,EAAYC,EAAatE,GAC1E,OAAQA,EAAOO,aAAe,EAAI8D,EAAaV,EAAiBU,GAAcrE,EAAOO,aAAe+D,EAGtG,QAASC,GAAuBC,EAAmBf,EAAkBgB,EAAkBH,EAAatE,GAClG,MAAyB0E,GAAAA,IAArBD,GAAiCA,IAAAA,GAAsBC,GAAaD,EAAmBH,GAAeb,GAAoBzD,EAAOK,aAAgBL,EAAOK,WAAaL,EAAOI,gBAAkB,GAAK,EAC9LoE,EAGFC,EAAmBD,EAG5B,QAASG,GAA0BH,EAAmBI,EAAeH,EAAkBzE,GACrF,MAAyB,KAArByE,EACK,EAELG,GAAiBJ,EACZxE,EAAOI,eAAiBJ,EAAOK,WAAa,EAE9C6B,KAAK2C,MAAMJ,EAAmBD,GAGvC,QAASM,GAAyBC,EAAkBP,EAAmBI,EAAe5E,GACpF,GAAIgF,GAAwBD,EAAmB,GAAK,EAChDE,EAAiD,UAApBjF,EAAOQ,WAAyBR,EAAOQ,YAAcwE,EAAwB,oBAAsB,aAChIE,EAAeD,EAA6BL,EAAgBJ,EAAoBI,EAChFO,EAAeD,EAAeV,CAClC,OAAOA,GAAoBxE,EAAOS,OAAO0E,GAG3C,QAASC,GAAsBzB,EAAgBC,EAAW5D,GACxD,GAAImE,GAAQT,EAAeC,EAAgBC,EAAW5D,GAClDqE,EAAaJ,EAAoBN,EAAgB3D,EAAOG,KAAMyD,EAAWO,EAAOnE,EAAOC,MAC3F,IAAmB,OAAfoE,EACF,MAAO,KACT,IAAuB,IAAnBV,EACF,MAAOQ,KAAUL,EAAc,EAAI,CACrC,IAAIQ,GAActE,EAAOI,eAAiBJ,EAAOM,SAC7CmE,EAAmBL,EAA0BT,EAAgBU,EAAYC,EAAatE,GACtF4E,EAAgBL,EAAuBvE,EAAOM,SAAUmD,EAAiBzD,GAASyE,EAAkBH,EAAatE,GACjH+E,EAAmBJ,EAA0B3E,EAAOM,SAAUsE,EAAeH,EAAkBzE,EACnG,OAAO8E,GAAyBC,EAAkB/E,EAAOM,SAAUsE,EAAe5E,GAAUA,EAAOM,SArNrG,GAAIU,GAAQ,+BAA+BqE,MAAM,KAC7CnE,EAAa,sCAAsCmE,MAAM,KAkFzDnC,EAAQ,EACRE,EAAS,GACTC,EAAM,EAaNE,GACF+B,KAAQhE,EAAM,IAAM,GAAK,IAAM,GAC/BiE,UAAWjE,EAAM,IAAM,EAAG,EAAG,GAC7BkE,WAAYlE,EAAM,EAAG,EAAG,IAAM,GAC9BmE,cAAenE,EAAM,IAAM,EAAG,IAAM,GACpCoE,aAActD,EAAK,EAAGc,GACtByC,cAAevD,EAAK,EAAGgB,GACvBwC,WAAYxD,EAAK,EAAGiB,IAGlBwC,EAAe,qCACfpD,EAAgB,GAAIqD,QAAO,kBAAoBD,EAAe,IAAMA,EAAe,IAAMA,EAAe,IAAMA,EAAe,OAC7H5C,EAAS,gDACTtB,EAAS,SAASC,GAAK,MAAOA,IA0B9BiC,EAAY,EACZC,EAAc,EACdC,EAAa,EACbC,EAAc,CA4ElBvE,GAAOC,iBAAmBA,EAC1BD,EAAOK,WAAaA,EACpBL,EAAO2B,qBAAuBA,EAC9B3B,EAAO+D,wBAA0BA,EACjC/D,EAAO2F,sBAAwBA,EAC/B3F,EAAOiE,eAAiBA,EACxBjE,EAAO4B,iBAAmBA,GAkBzBhC,EAAqBG,GClPxB,SAAUC,GAmIR,QAASsG,GAAUhF,EAAUiF,GAC3B,MAAIjF,KAAYkF,GACPA,EAAQlF,GAAUiF,IAAUA,EAE9BA,EAIT,QAASE,GAA4BnF,EAAUiF,EAAOG,GACpD,GAAIC,GAAiBC,EAAoBtF,EACzC,IAAIqF,EAAgB,CAClBE,EAAsBC,MAAMxF,GAAYiF,CACxC,KAAK,GAAIQ,KAAKJ,GAAgB,CAC5B,GAAIK,GAAeL,EAAeI,GAC9BE,EAAgBJ,EAAsBC,MAAME,EAChDN,GAAOM,GAAgBV,EAAUU,EAAcC,QAGjDP,GAAOpF,GAAYgF,EAAUhF,EAAUiF,GAI3C,QAASW,GAAmBC,GA4D1B,QAASC,KACP,GAAIC,GAASC,EAAUD,MACa,OAAhCC,EAAUD,EAAS,GAAGE,SACxBD,EAAUD,EAAS,GAAGE,OAAS,GAC7BF,EAAS,GAA4B,MAAvBC,EAAU,GAAGC,SAC7BD,EAAU,GAAGC,OAAS,EAIxB,KAAK,GAFDC,GAAgB,EAChBC,EAAiBH,EAAU,GAAGC,OACzBR,EAAI,EAAOM,EAAJN,EAAYA,IAAK,CAC/B,GAAIQ,GAASD,EAAUP,GAAGQ,MAC1B,IAAc,MAAVA,EAAgB,CAClB,IAAK,GAAIG,GAAI,EAAOX,EAAIS,EAARE,EAAuBA,IACrCJ,EAAUE,EAAgBE,GAAGH,OAASE,GAAkBF,EAASE,GAAkBC,GAAKX,EAAIS,EAC9FA,GAAgBT,EAChBU,EAAiBF,IA1EvB,IAAKI,MAAMC,QAAQT,IAAgC,OAAhBA,EACjC,KAAM,IAAIU,WAAU,kDAEtB,IAAmB,MAAfV,EACF,QAmCF,KAAK,GAjCDG,GAAYH,EAAY9D,IAAI,SAASyE,GACvC,GAAIC,KACJ,KAAK,GAAIC,KAAUF,GAAkB,CACnC,GAAIG,GAAcH,EAAiBE,EACnC,IAAc,UAAVA,GACF,GAAmB,MAAfC,IACFA,EAAc3E,OAAO2E,IAChBC,SAASD,IACZ,KAAM,IAAIJ,WAAU,yCAEnB,CAAA,GAAc,aAAVG,EACT,MACEG,KAAMC,aAAaC,kBACnBC,KAAM,oBACNC,QAAS,mCAGXN,GADmB,UAAVD,EACKhI,EAAO4B,iBAAiBqG,GAExB,GAAKA,EAErBxB,EAA4BuB,EAAQC,EAAaF,GAMnD,MAJuB7G,SAAnB6G,EAASR,SACXQ,EAASR,OAAS,MACGrG,QAAnB6G,EAAS/G,SACX+G,EAAS/G,OAAShB,EAAO4B,iBAAiB,WACrCmG,IAGLS,GAAAA,EAEAf,EAAAA,GAAkBxC,EACb8B,EAAI,EAAGA,EAAIO,EAAUD,OAAQN,IAAK,CACzC,GAAIQ,GAASD,EAAUP,GAAGQ,MAC1B,IAAc,MAAVA,EAAgB,CAClB,GAAaE,EAATF,EACF,MACEkB,KAAML,aAAaM,yBACnBJ,KAAM,2BACNC,QAAS,uEAGbd,GAAiBF,MAEjBiB,IAAAA,EA8BJ,MA1BAlB,GAAYA,EAAUqB,OAAO,SAASZ,GACpC,MAAOA,GAASR,QAAU,GAAKQ,EAASR,QAAU,IAsB/CiB,GACHpB,IAEKE,EA1OT,GAAIV,IACFgC,YACE,kBACA,qBACA,iBACA,mBACA,uBACA,mBACA,iBACA,mBAEFC,QACE,iBACA,iBACA,iBACA,mBACA,mBACA,mBACA,oBACA,oBACA,oBACA,kBACA,kBACA,mBAEFC,cACE,oBACA,oBACA,qBAEFC,aACE,iBACA,mBACA,oBACA,mBAEFC,YACE,kBACA,kBACA,mBAEFC,cACE,sBACA,uBACA,0BACA,0BAEFC,aACE,mBACA,mBACA,oBAEFC,WACE,iBACA,iBACA,kBAEFC,aACE,iBACA,mBACA,oBACA,mBAEFC,MACE,WACA,aACA,aAEFC,MACE,aACA,WACA,YACA,cACA,aACA,cAEFC,QACE,YACA,cACA,eACA,cAEFC,SACE,eACA,eACA,gBAEFC,SACE,aACA,eACA,gBACA,gBAIA5C,EAAwB6C,SAASC,gBAAgB,+BAAgC,OAEjFC,GACFC,KAAM,MACNC,OAAQ,MACRC,MAAO,OAGLvD,GACFwD,kBAAmBJ,EACnBK,gBAAiBL,EACjBM,iBAAkBN,EAClBO,eAAgBP,EAChBQ,UACEC,WAAY,MACZC,UAAW,MACXC,MAAS,MACTT,OAAU,OACVU,MAAS,OACTC,UAAW,OACXC,WAAY,QAEdC,YACEC,OAAQ,MACRC,KAAM,OAERC,aAAclB,EACdmB,YACEC,KAAM,2BAERC,WACED,KAAM,+BA+GVhL,GAAOkH,mBAAqBA,GAM3BtH,EAAqBG,GCpPxB,SAAUC,GAER,GAAIkL,KAEJlL,GAAO0B,aAAe,SAASyJ,EAASC,EAAMC,EAAQC,GACpD,GAAIC,GAAUD,EAAS,MAAQ,KAC3BE,EAAQ,GAAIC,MACZC,EAAS,GAAID,MAAKL,EAGtB,OAFAM,GAAOC,SAASD,EAAOE,WAAa,GAExBF,EAARF,GACIL,IAAWD,IACfW,QAAQC,KAAK,mBAAqBX,EAAU,IAAMI,EAAU,wCAA0CG,EAAOK,eAAiB,KAAOV,GAEvIH,EAASC,IAAAA,GAAW,IACb,GAMXnL,EAAOgM,WAAa,SAASb,EAASC,EAAMC,EAAQC,GAClD,GAAIC,GAAUD,EAAS,MAAQ,IAC/B,IAAItL,EAAO0B,aAAayJ,EAASC,EAAMC,EAAQC,GAC7C,KAAM,IAAIW,OAAMd,EAAU,IAAMI,EAAU,yBAA2BF,KAIxEzL,uurBC5BH,IAAA,GAAA,MAAkBsM,KA2BhB,EAAA,EAAA,EAASC,EAAAA,QAAAA,EAAAA,EAAAA,OAAAA,IAAAA,CAAAA,GAAmC7E,GAAAA,EAAAA,IAG1C,EAFI8E,EAAAA,GAAAA,OAAAA,EAAAA,EAAAA,IAEKrF,EAAWO,EAAUD,GAAQN,MACpC,GAASiB,KAAUV,GAAAA,EAAUP,KACb,GAAA,MAAViB,GAAAA,oBAAsD,EAAVA,EAC9C,EAAIqE,GAAAA,GAAAA,GACM/E,EACAA,KAAAA,KAAatG,EACdsG,KAAAA,GAAUP,qBAEnBqF,EAAAA,GAAyCA,aAAAA,iBAA+BpE,GACxEoE,SAAAA,GAAAA,QAA+BpE,GAAaqE,GAAAA,MAAAA,GAAAA,QAAAA,GAKlD,QAASC,OAAAA,IAAaF,QAAAA,GAAAA,EAAAA,EAAAA,GAAAA,MACpB,MAAIG,IAAAA,EAAQH,KAAAA,IAAAA,EAAAA,IAAAA,QAAAA,GACZ,GAAIG,MAAM,2BAA8BlF,KAAS,GAAGE,OAClD,GACQa,OAAAA,QAAaC,GACnBC,EAAM,GAAA,OAAA,EAAA,EACNC,GAAS,QAAA,GAAA,EAAA,GAIf,MAAO6D,IAAAA,EAAAA,EAIT,EAAA,EAAA,GAASI,EAAAA,GAAAA,OAAmBJ,QAAAA,GAAAA,EACtBK,GAAAA,OAAAA,EACJ,EAASH,SAAAA,GAAAA,MAAaF,MAAAA,MAAAA,EAAAA,EAAAA,EAAAA,EAAAA,MAEpB,QADIG,GAAQH,EAAAA,GAAAA,MAA+BE,UAClCvF,EAAWwF,GAAMlF,OAAS,EAAQ,EACrCqF,SAAYH,GAAAA,MAAShF,GACXgF,EAAMxF,EAAOQ,EAAAA,OACvBoF,QAAaJ,GAAMxF,EAAGR,GACtBqG,OAAWL,EAAU,EAAGhG,KACxBmG,OAAAA,EAAaG,MACA,EAAXA,EACFF,qBAEAC,EAAWD,EAGfF,EAAeK,EAAAA,IACbJ,qBACAG,gBACA7L,EAAQuL,qBACRjL,EAAUgL,EACKJ,EAAMa,IAAAA,UAAAA,0BAAiCJ,EAAYC,qBAIxEH,EAAeO,GAAK,YAASC,gBAAmBC,EAAAA,qBACvCD,EAAkBP,GAAYQ,UAAmBR,WAEnDD,EAAAA,qBApFHU,EAAqB,GAAShG,YAClC,EAAIG,YAAYtH,EAAOkH,EAAAA,aAAmBC,EACtCiF,EAAAA,eAAiCD,GAAAA,EAAAA,GACjCM,SAAiBD,GAAAA,QAAAA,GAAmBJ,EAAAA,GAAAA,MAAAA,WACxC,GAAO,WAASgB,GAAQC,EAAAA,EAAAA,SACN,GAAZA,MAAAA,IACFZ,EAAAA,EAAAA,GAAAA,EAAAA,EAAe9D,YAAgB2E,OAAAA,EAAAA,qBACrBD,OAAiBC,GAAAA,gBACjBD,GAAiBC,SAAAA,GACjBD,QAAYC,GAAAA,GAAcZ,EAAaW,EAAAA,OAAYC,EAAcT,UACxExL,OAAAA,EAAQ,UAASiM,CAClB,IAAIC,GAA4BD,EAAAA,SAAcZ,IAC1Cc,EAAAA,UAAgBF,OAAAA,EAAcT,UAAUS,EAAcZ,GACnB,EAAjBc,UAAyBF,CAAAA,EAAAA,SAActM,EAAOuM,EAAAA,EAAAA,EAAAA,IAAAA,GAAiBC,EACrFtB,aAAYkB,EAAAA,EAAAA,EAAQE,GAAAA,IAAAA,GAAchM,UAAUgM,EAAAA,EAAAA,EAAAA,EAAAA,IAAcA,GAAAA,EAAcG,GAAAA,GAAAA,QAAAA,EAGrE,GAAInM,EAAAA,EAAY8K,GAAAA,EAAAA,EAAAA,GAAAA,EACH,IAAZ9K,QAAoC,GAAZA,EAAAA,GAAoC,OAAA,EAAZA,EAAAA,SAC5CoM,GAAAA,QAAcpM,GAAAA,GAAAA,MA0E7B1B,MAAAA,IAAAA,EAAAA,KAAqBC,IAAAA,IAAAA,IAAAA,GAAgBE,EAAAA,GAAAA,IAAAA,GAAAA,GAAAA,EAAAA,EAAAA,EAAAA,IC/FxC,EAAA,GAAA,KAAUmM,MAIR,EAASyB,EAAAA,GAAAA,EAAAA,IAAAA,OAAmBC,GAAAA,GAAAA,EAAQC,eAClCC,EAAAA,MAAAA,EAAAA,EAAiBxM,EAAAA,KAAAA,QAAYwM,EAAAA,KAAAA,KAAiBxM,MAAAA,GAAAA,GAC9CwM,SAAAA,gBAA2BhB,+BAEpBiB,SAAAA,GAAAA,MAAqBH,EAAQC,OAAQG,CAAAA,IAAAA,GACvC,EAAWjH,WAAIiH,KAAW3G,GAAa,qBAC3B2G,EAEfL,GAAAA,mBAAmCrM,sBACtBA,oBAEXqM,qBAAmCrM,mBAAiB,QAAS,gBACpDU,0BA6Df,EAAS+K,aAAAA,EAAsBzL,qBAC7B,KAAY,KAAA,GAAsB,EAAA,YAChC,GAAiBA,EAAS2M,GAA6BjM,SAC9CA,EAAEkM,GAAAA,QAEC,GACVC,EAAOC,GAAcC,GAAAA,EACV,EAAA,OAATC,cACMF,KAAAA,GAAcC,KAAAA,OAG1B,IADIE,EAAAA,OAAmBD,GAAAA,EAAAA,IAAaR,gBAAAA,KAAiBxM,GACxC,CAAA,EAAGiN,EAAgBA,QAASlH,UAAQN,IAC3CyH,IAAAA,KAAaD,GAAeJ,EAC5BM,QAAAA,EAAcF,SAAeD,GACjC,MAAmBpN,GAAfsN,GAA4CtN,KAAhBuN,IAAAA,GAC9B,KAAIC,GAAAA,GAAoBH,KAAAA,EAAeC,OAAYC,IAAAA,EACnD,EAAIC,QAAAA,oBACWxC,KAAMyC,QAAAA,GAAczL,QAAM,IAAMwL,EAAAA,KAC7C,KAAO,QAASE,YACL,KAAUT,QACAG,MACZO,IAAAA,GAKf,UAAaF,cAAAA,YAA2B,cACtC,EAAOG,EAAAA,EAAAA,EAAeX,QAtGtBL,EAAAA,GAAAA,KAmBJ5B,IAAM6B,EAAAA,EAAuBA,QAAAA,EAEzBK,GAAAA,MAAAA,EAAAA,GAAAA,GACFW,IAAAA,KAAAA,EAAiB,CAAA,IAAA,GAAA,KACjBC,GAAoB,CAAA,GAAA,GACpBC,KAAAA,EAAAA,QAAmB,GAAA,QACnBC,IAAAA,EAAAA,KAAAA,IAAAA,QACAC,GAAAA,QAAAA,EAAyB,KACzBnF,MAAAA,KAAAA,SAAmB,GACnBoF,MAAAA,GAAiB,GACjBnF,EAAAA,MAAiB,KACjBoF,QAAkB,GAClBnF,EAAkB,GAElBoF,MAAAA,GACAC,EAAAA,GAAgB,GAAA,QAAA,GAChBC,EAAqB,EACrBC,GAAAA,GAAAA,GAAsB,IACtBtF,KAAAA,IAAgB,GAChBuF,EAAAA,KAAQ,EACRC,KAAM,IAAA,GAAA,EAAA,QACNC,GAAO,GAAA,EACPxF,KAAU,EAAA,OACVO,GAAY,EACZkF,IAAAA,SAAQ,GACF,MACNC,GAAAA,IAAAA,IAAe,EAAA,EACfC,IAAAA,SACAC,GAAAA,MAAc,GACdC,IAAAA,KAAY,EACZC,EAAAA,SAAa,GACbC,GAAAA,GACAC,EAAAA,IAAW,SACXC,EAAU,GAAA,MACVC,IAAAA,EAAW,QACXC,IACAC,EAAS,KACTC,IAAAA,EAAAA,IAAc,EAAA,eACC,GACf3F,EAAAA,KAAAA,KAAc,MACd4F,OAAAA,GAAe,OACfC,EAAAA,QAAa,EACbC,IAAAA,IAAc,GACdC,GAAY,iDAGA,EAAA,EACP,KACLC,KAAAA,GAAW,QACXC,EAAe,MACfC,EACAC,EACAC,KAAAA,KAAa,GAAA,QACbC,EAiCFjF,KAAMa,MAAAA,EAAAA,EAAwBA,KAAAA,KAAAA,qBAEbhN,GAAAA,YC7GnB,EAAUC,EAAQkM,qBAEPkF,EACP,EACIlN,uBAAwBH,EAAAA,qBAAwBxD,KAChD8Q,KAAAA,GACF,EAAOrR,WAAO2F,EAAAA,EAAAA,gBAAsBzB,CAA2B3D;GAOjE,GALA8Q,EAAWC,qBAAwB9Q,KAAQ0D,KAAAA,GAAiB3D,EAC5D8Q,EAAAA,gBAAwB,KAAA,OAASlN,EAC3BO,KAAQ1E,EAAsBkE,EAAAA,gBAAgBC,KAAW5D,OAC7D,EAAiBgE,KAAAA,GAAeG,oBAE3B2M,CAGHE,IAAAA,GAA0BnE,SAAQjG,GAAajH,GAAAA,GAAAA,EAC/CmR,EAAAA,OAAaD,IAAWpR,IAAAA,EAAO2B,GAAAA,EAAAA,GAAAA,QAAqBzB,EACnCgM,EAAMiB,oBAAmBhG,KAAAA,OAE1CqK,EAEF/E,KAAAA,EAeF,EAAA,oBAZegF,KAAU,OAAA,EACvB/L,IAAAA,GAAe2L,yBACS,EAE1BG,EAAeE,qBACbjF,EAAuB,GAEVkF,oBAA0BC,EAAAA,qBACrBA,EAEpBJ,GAAuCK,sBACvCL,qBAAgCH,oBAAWC,qBAI7CpF,mBAAmB,aACjB,YAAI4F,SAAa,cAEbpE,aACQ,YAGZoE,gBAAWL,UAAU,EACnB,qBAEFK,EACAA,GAAWD,4BAGXC,6BAA4B,yBAGrBA,0BAQajS,SAAAA,OAAgBE,iBCjExC,gBAAiBgS,cAsBf,eAASC,aAA0B1Q,aAAU2Q,YAC3CA,iBAAWC,iBACAC,eACXhR,gBAAOiR,cAAuB9Q,cAAU2Q,QAG1C,eAASI,cAAAA,MAA4BC,iBAO9BC,kBAAkB7I,EAASC,GAAgB,SAAA,GAAgC,QAAO7C,GAEvF3D,GAAKqP,MACLrP,GAAKsP,uBAGL,IAAa,EAAOtP,aAAYkE,QAAa,GACvC/F,QAAW6B,GAAY4D,GACtBwL,GAAAA,GAAAA,EAAgBjR,aAAY6B,EAAKuP,OAAOpR,EAE/C6B,aAAKwP,KAAAA,KA+FP,UAASC,EAAAA,OAAAA,EAAqBN,aACxBA,KAAAA,KAAQO,QAAAA,EAAAA,gBAGRC,KAAAA,KAAAA,EAAoBT,MAAAA,EAA4BC,OACpD,EACEN,aAAAA,KAAkBM,KAAS,SAAWS,EAAK,OAAa,IAAOD,GAAAA,EAAAA,GAAAA,OAC/D,EAGAR,GAAAA,OAAQxL,QAAa,GAAmBP,EAAAA,GACtC+L,MAAQxL,QAAMxF,GAAYiF,QAE5B+L,IAAQxL,GAAAA,EAAM4K,SAAS,GAAA,GAASpQ,GAAAA,EAC9BgR,EAAAA,CAAQxL,IAAMxF,QAAAA,EAKlBgR,MAAAA,MAAQO,IAAAA,GAAAA,EAAAA,gBAAqC/L,EA7J3CkM,EAAAA,OAAAA,GACFC,GAAS,EACT5L,MACA6L,EAAAA,gBAGEC,EACFC,GAAAA,QAAAA,GACAC,GAAAA,MAAAA,QACAC,EAAAA,IAAAA,GAAAA,GAEAC,EAAAA,2BAIEC,KAAAA,KAAAA,EAAAA,EACFD,KAAgB,GAChBE,SAAa,EA6BfpB,EAAAA,WAAAA,EAA4BqB,EAC1BC,qBACSxQ,EAAKoP,GAAgBU,UAE1BA,EAEF,GADIW,SACK7M,GAAgBwL,QAAAA,GAAgBlL,GACvCuM,MAAAA,UAAAA,GAAwBrB,GAAAA,GAAAA,CAAAA,OAAgBxL,GAE1C5D,IAAKoP,SAAAA,GAAAA,MAAgBU,KAAUY,EAAAA,EAC1BlB,KAAAA,KAAAA,QACA,GAAI5L,GAAI,MAAO5D,GAAKoP,QAAAA,GAAwBxL,GAC/C6M,GAAAA,EAAAA,EAAmBzQ,cAAKoP,OAAgBxL,QAErC,EAAIzF,QAAYsS,KAAAA,GAAAA,GAAAA,EACTnB,uBAAoBnR,KACvBoR,EAAOe,EAAYnS,EAAAA,EAAeiR,KAAAA,IAAgBe,CAAAA,GAAAA,EAAAA,OAAiBhS,EAI1E+F,MACF,GAAYkL,EAAAA,MAAgBlL,EAAAA,GAE9BsM,MAAIT,IAAAA,GACK/P,EAAKuP,GAAAA,EAAOQ,EAGL,EACP/P,KAAKqP,EAAeD,MAAAA,IAAAA,GAAgBlL,EAAAA,GACzClG,MAAOiR,KAAAA,EAAAA,EAA0BI,EAAAA,IAAAA,EAC/BL,OAAc,EACdD,OAAAA,MACK,KAAA,GAAA,MACI,EAAA,EAAA,EAAA,EAAa,OAAO/O,IAAKoP,CAAAA,GAAAA,GAAgBuB,EAAAA,EAC/C3Q,GAAAA,EAAKqP,EAEVrP,EAAKqP,IAAAA,EAEP,GAAOrP,EAAKqP,SAAUrP,GAAAA,MAAKoP,KAAAA,EAAAA,OAAgBlL,EACzClE,EAAKqP,WACLrR,IAAAA,EAAOiR,EAAAA,YAAejP,EAAMA,EAAKqP,qBACjB,EACdN,EAAAA,aACA3L,EAAOrF,eAIP,IAASI,EAAAA,EAAAA,EAAUiF,EAClBmM,GAAAA,EAAAA,GAAOpR,GAAAA,SACZ6B,EAAKsP,MAAAA,GAAoBnR,KAAAA,GAEnB,GAAA,EAASA,MAAAA,EAAAA,EACHA,EAAAA,IAAiBiR,EAAgBjR,WAAAA,EACtC6B,OAAKsP,MAAAA,IAAAA,QAAoBnR,GAK3ByS,GAAUZ,MAAAA,GAAAA,QACjBd,GAAAA,QAAAA,UAAAA,IAA4BqB,QAAAA,GAAoB,EAAUK,GAAQC,GAAAA,EAAAA,oBACzD,EACL,CAAItN,EAAAA,kBAAc6L,CAAgBwB,IAAAA,GAAQ7Q,EAAWqP,wBAAiB0B,GAMtE,GALID,EAAAA,oBACQvB,EAAAA,CAAAA,EAAAA,kBAA8B,CACtCtP,IAAKuP,GAAOqB,EAAQ7Q,wBAAmB+Q,GACpCtB,MAAAA,OAAAA,EAEAjM,IAERqN,MAAAA,EAAkBP,MAAAA,KAAAA,GAAAA,SAIvB,GAAA,MAASlS,GAAAA,EAAAA,GAAYoI,EAAAA,EAAAA,GAASwK,KAAAA,EAAgBpN,GAAAA,KACxCxF,GAAAA,EAAY0R,GAAAA,KAAAA,IAAAA,EAAmB1R,EAAY6R,SAAAA,GAG/C,GAAU7R,GAAAA,EACR0Q,KAAAA,EAAAA,GAAkBK,GAAAA,EAAAA,GAAAA,GAAAA,EAAAA,IAA4BqB,EAAAA,EAAWpS,cAClD,EAAA,GAAA,EACH,GAAA,EAAO6B,GAAKoP,EAAAA,EAAAA,IAAAA,EAET,EAAA,IAAA,GACEA,KAAAA,IAAgBjR,OAAAA,MAChBqR,QAAAA,GACKF,GAAAA,MAAAA,GAAoBnR,QAAAA,OAC5B6B,IAAKuP,QAAOpR,GAAYiF,GAAAA,MAG7BjF,GAyBL4K,QAAMhJ,eAAiBoP,MAAShR,QAAUiF,GACxCqM,EAAAA,GAAqBN,GAAAA,GACP6B,EAAKjI,0BAAmB5K,EAAWiF,GAGnD2F,CAAMwB,KAAQ,EAAA,SAAS4E,EAAShR,OAC1BgR,CAAAA,EAAAA,SAAQO,GAAAA,EAAAA,EAAAA,EACVP,KAAcZ,KAAAA,GAAOxF,GAAAA,EAAMkI,EAAAA,EAAAA,OAAa9S,IAAAA,CAAAA,GAAAA,GAO3CzB,EAAAA,GAAAA,EAAAA,EAAgBE,EAAAA,GAAAA,EAAAA,EChLnB,SAAUmM,EACRmI,OAAOC,EAAAA,GAAAA,EAAQZ,CAAAA,GAAAA,MAAUa,EAAAA,EAAU,EAAA,EAASpN,IAAAA,SAAajH,GAAAA,GAAAA,gBAC1CsU,GAAAA,MAASC,EAAYlD,IAAAA,KAAepO,KAAMgE,GAAAA,KAAajH,GAAAA,EAAAA,GAErEL,CCJH,OAAA,QAAiBkS,GAAAA,GAEM2C,SAAUtS,EAC7B,GAAoB,MAAA,eAA2B,GAAA,eAANuS,IACvC,UAAe,GAASA,YAEN,KAAA,UAARD,GAAoC,YAAA,IAANC,KACjCvS,KAOLsS,IAAKrN,IAAUsN,EAAGtN,QAEf,EADDuN,OACY7N,CAAAA,IAAI2N,EACXG,MAAAA,IAAAA,GAAiB9N,EAE1B,EAAO6N,EAEH,IAAA,EAAA,IAAA,GAAA,EAA+C,IAAMD,IAG7DzI,UAAMyC,EAAgB,UAAS+F,KAAUI,GAAAA,GAAAA,EAAAA,EAAAA,EAAAA,OACvC,IAAO,CAAA,GAAA,GACL,EAAOA,EAAAA,GAAAA,EAAAA,EAAgBD,EAAYH,GAAAA,EAAMC,EAAIvS,EAQhDvC,GAAAA,EAAAA,EAAgBE,EAAAA,GAAAA,EAAAA,EClCTmM,EAyFC6I,GAAcC,EACTA,EAAsBC,EAG3BC,IAAAA,EACHC,EAAUjJ,GAAUkJ,CAAAA,IAAOC,EACfF,MAAe,IAE/B,GAAID,GACAC,EACFD,KAAOE,EAAAA,IAKP,GAHIE,KAAQ7S,EAAU0S,IAAAA,EACd1S,KAAK8S,EAAQD,IAAa7S,EAAK+S,MAASL,UAAUA,EAEjDpO,UAAcA,CACrBmO,GAAAA,GAAUE,EAAY3S,EAAKgT,MAAiBN,IAAAA,EAIhD,IAAOD,EA5GLQ,IAAAA,EAAgB,IACTC,EAAAA,GAEF,EADDjP,EAAc,GAAc,EAAW,EAAuB,GACzDK,GAAcA,EACZW,EACEkO,GAAI,OACXlP,CAAAA,IAAUgB,EAAqBA,KAIrC,EAGF,IAASmO,EACP,IACM,EACFzV,GACW,CAAXA,IAAE,EAEFA,MAAK,IACM,GAAN,EACA,EACLA,EAAK,IACA,EACH,IAAG,GAGFsV,EAAAA,IAAcI,IAAAA,UAAkBC,EAAMb,KAAMc,OAAAA,EAGnD,EAFIC,GAAiB,EAAc,EAAsB,GAAM,GAE3C,EAClBA,EAAeD,GAAAA,GAGZ,IAAQ,GAAGjP,MACD,KACJ,KAAwBkP,EAAAA,EAAAA,EAAOvO,EAItCvF,OAAI+S,IAASgB,CAAAA,GAAIhB,GAASiB,gBAAsB,GAEhDC,GAAAA,EAAoB,aAAiB,EAAQ,gBAEjDA,EAAAA,EAAU,EAAiBF,GAAIA,EAC/BE,GAAAA,GAA2BF,GAAIC,EAC/BC,GAAAA,EAAuBjU,GAAQ+T,EAC/BE,GAAAA,EAA+BD,KAC/BC,EAAAA,IAAU,EAAiBjU,KAAYgU,GAC7B,EAAqBhU,KAC/BiU,GAAa,EAAcD,MAAQE,EACnCD,KAAmCC,GACnCD,EAAU,CAAG,GAAK,GAASjU,CAE3B8T,GAASN,EAAiBS,EAEtBE,EAAAA,OAAY,EAAiB,EAAiB,SAAW,GACzDP,MAAK,GACPO,IAAK,SAAa,EAClBL,GAAAA,GAASN,GAAiBW,EAGxBP,IAAAA,SACFO,EAAK,GAAG,MACRA,GAAQ,GAAKP,GAAK,GAClBE,KAASN,KAAAA,IAASM,OAAQK,UAGxBP,EAAK,GACPO,IAAK,IAAG,EACKP,MACbE,KAAAA,SAASN,EAASM,GAAQK,GAAAA,YAGnBvP,EAAOA,GAAOA,GACrB,IAAK,EACHkP,MAAAA,KAAUvO,OAAM6O,GAIpB,GAAA,KAAIV,GAAAA,GAAKI,GAAAA,GACCA,IAAAA,GAAO,GAAqBA,QAAU,UAAW,EAAG,EAAA,EAAIA,EAAAA,EAAAA,EAAO,EAAA,EAAG,EAAIA,EAAAA,EAAAA,EAAAA,EAAO,EAAG,EAAA,GAEnFA,GAAAA,UAAUO,mBAAyB,GAAIP,QAAO,KAEvD,SAAOP,KAAAA,SA0BTxJ,KAAMwJ,SAAAA,KAAgBA,UAAAA,QACtBxJ,aAECrM,KAAAA,OAAAA,KAAgBE,GAAAA,EAAAA,EAAAA,IAAAA,GAAAA,QCnHnB,IAAUC,GAAQkM,EAAAA,EAAAA,IAAO6F,GAEvB/R,EAAAA,KAAOyW,QAAAA,IAAAA,GAEP,EAAIC,EAAAA,IAAAA,GAAAA,EAAAA,KAAiB,QAAStJ,IAAAA,GAAQuJ,EAAAA,EAAAA,KAAaC,SAAAA,MACjDzT,GAAKiK,MAASA,KAAAA,KACdjK,GAAKwT,OAAAA,IAAcA,KAAAA,GACnBxT,EAAAA,KAAKyT,OAAeA,IAAAA,KAAAA,GAEpBzT,EAAKgF,KAAO,WACZhF,KAAK0T,GAAU,EACf1T,EAAAA,IAAK2T,GAAAA,YACAC,IAAAA,GAAAA,EAAAA,EAAgB3J,IACrBjK,GAAK6T,EAAAA,KAAAA,YACL7T,IAAK8T,GAAAA,EAAaC,EAAAA,IAAMC,GACxBhU,EAAAA,KAAKiU,YAAiBC,IAAAA,GAGxBnL,EAAMoL,EAAAA,KAAY,aAASC,MACzBpU,GAAKqU,GAAAA,qBAAyBf,EACzBgB,GACLtU,eAAkB,EACbuU,GACAC,SACAC,GAAAA,QACLzU,GAAK0U,GAAAA,GAAAA,GACL1U,OAAK2U,EAAW,OAChB3U,OAAK4U,IAAAA,IAAAA,GAAAA,EACL5U,KAAK6U,EAAAA,MAAUT,EAFC,OAGXU,EAAAA,QAAiBD,GAAAA,GAAQvG,MAC9BtO,GAAK+U,IAAQ,KACb/U,MAAKgV,EAAAA,KAAAA,EAAsB,EAG7BjM,MAAMoL,IAAAA,IAAU5D,GAAAA,MACd0E,EAAAA,SAAc,MAKVjV,EAAK8U,OAAAA,OAAiBD,GAAAA,QADpB7U,GAAKrC,EAAAA,GAAe,OAAKqC,EAAKwT,EAAAA,GACM,EAEAxT,qBAE9ByU,EAAAA,GAAgBzU,iBAAmBA,GAAK0U,SAC3CD,GAAAA,QACL1L,GAAemM,GAAYvL,GAAK3J,KAGpCmV,KAAAA,GAAAA,KAAAA,GAA2BC,EAAAA,IAASC,EAC9BD,EAAAA,OAAWpV,GAAKsU,QAAAA,GACbA,GAAec,MAChBpV,GAAKsV,aAAgBD,qCACEb,IAAAA,EAAgB,uBAA0B,GAChES,QAAAA,GAGLzB,EAAAA,GACF,GAAIxT,GAAK+U,EAAS/U,gBAAKgV,EAEhBhV,IAAAA,EAAKsU,IAAAA,GAEVd,IAAAA,EAAAA,GAAY4B,CAAAA,GAAAA,GACdA,EAAWA,EAAAA,IACPtX,EAAMsX,GAAAA,EAEVrM,IAAAA,SAAMwM,EACIhB,GAAAA,EAA8B,IAAA,SAAdiB,GAAAA,IACxBxV,EAAKwV,GAAAA,EAAaxV,KAAKyV,GAAAA,IAAAA,EAAUjC,QAAc4B,EAAUpV,CAAAA,GAAAA,aAAKwU,KAEhExU,EAAKgV,KAAAA,aAAsB,KACvBhV,EAAKsU,IAAAA,CAAAA,GAAgBc,GAAAA,EAEzBpV,EAAKmV,GAAAA,GAAAA,EAAiBC,GAAAA,EAAS,GAC/BrM,EAAAA,GAAM2M,2BAEJnM,KAAAA,EACF,KAAOvJ,2BAELuJ,KAAU6L,EAAAA,IACZA,MAAWA,GACPtX,IAAAA,SAAMsX,GAEDb,MAAAA,gBAETvU,GAAKwV,EAAaJ,EACbD,OAAAA,QAAuBM,GAAUjC,GAAcxT,GAAKwV,GAAAA,EAAcxV,gBACvE+I,EAAM2M,IAAAA,EAAAA,IAERlF,EAAI7S,CAAAA,IAAAA,GAAAA,GACKqC,EAAKwU,GAAAA,IAAAA,IAAAA,KAEV7W,IAAAA,KAAAA,EAAayF,EAAAA,GACXA,EAASpD,EAAAA,EAAKwU,EAAAA,EAAAA,OAGlB,IAAImB,CAAAA,GAAAA,GAAAA,EAAsBnC,EAAAA,iBACrBgB,IAAAA,EACLxU,eAAkB,KACI,GAAlBA,GAAK4V,KAAAA,EAAAA,MAA2C,EAAA,OAAlB5V,EAAK4V,IAAAA,EAAAA,OACrC5V,GAAK6V,GAEe,EAAlBF,GAAAA,EAAAA,GACGnC,UAAAA,GAAcmC,MAAAA,IAGnBL,EAAAA,EACWP,GAAU/U,EAAKwU,MAAAA,EAAgB,MAAKxU,GAAKsU,KAAAA,EAAAA,GAAgBtU,EAAKmO,IAAAA,GAClEqG,GAAAA,OAAAA,EAAqBxU,EAAKsU,KAAAA,QAAgB,GAEjDnG,GAAmB,GAAOnO,GAAK6U,EAAQ1G,gBAC3CqC,EACE,KAAA,EAASuE,OACA,IACe,IAAnB/U,EAAKwV,GAAAA,EAAuBxV,GAAAA,OAAKuU,GAAgC,IAAhB5W,MAAAA,IAAAA,GAAsBqC,QAAKgV,IAAAA,IAAAA,OACxE,IAAA,KAAA,KACLhV,IAAKuU,GAAAA,QACA,IACLvU,MAAKsV,EACA,EACF,oBAEH,KAAA,KACJtV,EAAKuU,gBACIe,IAAAA,GAAetV,qBACjBsU,EAAetU,KAAKwU,KAAAA,GAAAA,GAA6BrG,qBACjDqH,EAAa,qBACZE,EAER1V,KAAK0U,KAAAA,GAAAA,GACCa,uBAENvV,EAAKiV,gBAEPa,EACO9V,EAAKsV,gBAAqBf,CAAiBQ,IAC9C/U,GAAKgV,EAAAA,oBAEFQ,KAAa,KAClBxV,EAEF+V,KAAQ,GAAA,qBAGDvC,EAAmBgB,GAAoBxU,sBAC5CA,qBAAuBmO,GAAsBqF,SAAAA,GAC7CxT,QAAKgV,GAAAA,GAEPgB,GAAAA,GAAQ,EACDhW,aAAK8U,UAELA,EAAAA,IAAY,GACZC,EAAQ,GACb/U,OAAKwT,UACLxT,OAAKwV,EAAAA,aACAX,EAAAA,OAAQvG,EAAQ,aAGfoH,KAAAA,OAAAA,QAIN3M,EAEO,EAAA,OACP/I,EAAKrC,aACLqC,KAAK6V,OAAAA,QAEPI,EAAAA,gBAA2BjR,EAAMkR,OACT,EAAA,aAAXA,KAAAA,OAAiC,SAARlR,EAC7B4P,IAAAA,IAAAA,GAAgBjL,EAAKuM,aAE9BC,WAAAA,EAAqB,IAAA,GAAeD,EAClC,GAAY,OAAA,WAEZ,OAAIvF,EAAaiE,aAAAA,EAAgBvW,OAAQ6X,EACrCvF,aACF3Q,KAAK4U,OAAAA,QAAgBwB,EAEzBC,EAAa,OAASC,EAAAA,aAChBC,KAAWvW,OAAKsV,QACpB,EAAKiB,gBAAiBxB,EAAW/U,OAAK0U,EAAAA,aAChC8B,KAAQ,OAAIjD,SAAAA,EAAqBvT,IAAKsU,IAAAA,GAAcgC,EAAAA,aACzCtW,WAAK4U,EAAAA,OAAgBvB,IAAYsB,EAAY3U,IAAAA,WAAK2U,OACjE8B,EAAAA,aACErL,EAAAA,OAASlN,EAAQ,aAASgY,KACxBA,OAAQQ,QAAKF,EAAMvM,SAAQuM,EAE5B,aAEA9B,KAAAA,OAAgB6B,6BAEP9C,YACTzT,EAAK+U,oBAAeR,EACA,OAAdiB,EAAAA,aACFjM,KAAAA,OAAYkK,SAAezT,EAAKsU,KAAAA,OAAetU,QAAKrC,GAC5C2X,EAAAA,GACbtV,MAAKmV,GAAAA,KAAAA,EAAkB1B,GAAAA,UAAezT,EAAKwV,GAAAA,EAAAA,UAAmB7X,EAAAA,MAAAA,GAGlEqC,EAAKgV,MAAAA,IAAAA,UACLhV,EAAKqW,gBAAY5C,OAAAA,EACTzT,gBAAoB8U,MAAAA,WAAmBJ,EAAAA,GAAAA,EAAAA,UAQlDjY,EAAAA,MAAAA,GAAqBC,EAAAA,MAAAA,IAAgBE,WAAAA,EAAAA,yBCjNfgS,OAAAA,EAqBvB,gBAAS+H,MAAAA,WACHC,EAAAA,IAAAA,EAAaC,IAAAA,EACjBA,GAAAA,EAAAA,UACQxF,EAAAA,MAASmC,GAAAA,EAAAA,MACXnC,IAAAA,WAASmC,EACfsD,GAAAA,EACW5Y,MAAQ,OAAA,OAAS6Y,GAASA,GACjCC,EACGvL,qBACPwL,KACAC,KAAOnZ,EAGT,sBAASoZ,EAAiCC,EAAAA,gBACjCC,KAAAA,OAAchD,EAAkB+C,KAAe/C,EAGxD,EAAA,oBAASiD,KACPtX,OAAKkV,EAAAA,gBAEA1B,KAActC,EAAOqG,EAAeA,oBAAkBA,KAAYrD,OA8CzE,EAAS+C,IAAAA,GAAAA,qBACQ/Y,EAAQ,GAAce,mBACtBiF,GAqBR4S,SACPU,GAAAA,QAAAA,GAAwB,EACpBnG,GAAAA,EAAiBA,QACrBA,IAAAA,QAASmC,SACTnC,GAAS6D,IAAYrL,UAAKsN,gBAC1BM,QACA,EAAIC,GAAAA,KAAqBrG,GAAS6D,KAClC7D,GAAAA,aAAS6D,kBAELyC,gBACAC,EAAAA,mBACJF,0BAAqBA,EAAmBlS,eAAgBqS,sBACtDA,EAAUpD,qBAAwBqD,4BAKhCF,EAAAA,aAAkBjO,SAAKkO,GAAUhD,MAFjC8C,GAAAA,IAAsBE,IAAUhD,EAI7BgD,OCjIX,SAAUhb,EAAQkM,GAkEhB,QAASgP,GAAsBtM,GAC7B,GAAI4F,GAAWH,OAAO3K,SAAS8K,QAC/BA,GAASmC,YAAc/H,EACvB4F,EAAS2G,qBAC0B,GAA/B3G,EAAS6D,YAAYhR,OACvBuT,GAAAA,EAEAQ,sBAAsBF,GAxE1B,GAAIG,GAAgChH,OAAO+G,qBAC3C/G,QAAO+G,sBAAwB,SAAShZ,GACtC,MAAOiZ,GAA8B,SAASlZ,GAC5CkS,OAAO3K,SAAS8K,SAAS8G,4BACzBlZ,EAAED,GACFkS,OAAO3K,SAAS8K,SAAS8G,+BAI7BpP,EAAMqP,kBAAoB,WACxBpY,KAAKkV,eACLlV,KAAKwT,YAAczV,QAGrBgL,EAAMqP,kBAAkB7H,WACtB8H,cAAe,WAEb,MADArY,MAAKgY,qBACEhY,KAAKkV,YAAYjV,SAE1BqY,oBAAqB,WAEnB,MADAzb,GAAOgM,WAAW,wCAAyC,aAAc,gDAClE7I,KAAKqY,iBAEdF,0BAA2B,WACzBpP,EAAMwP,uBAAyBxP,EAAMwP,uBAAuB/S,OAAO,SAASqS,GAC1E,MAAOA,GAAUW,qBAGrBR,mBAAoB,WAClBhY,KAAKmY,4BACLnY,KAAKkV,YAAclV,KAAKkV,YAAY1P,OAAO,SAASqS,GAClD,MAA8B,YAAvBA,EAAUjC,WAAkD,QAAvBiC,EAAUjC,aAG1DtE,MAAO,SAAS8C,GACd,GAAIyD,GAAY,GAAI9O,GAAMoL,UAAUC,EAWpC,OAVApU,MAAKkV,YAAYvL,KAAKkO,GACtB9O,EAAM0P,+BAMNZ,EAAUW,kBACVX,EAAUa,WAAW7C,OACrBgC,EAAUW,kBACHX,GAEThC,KAAM,SAASzB,GAIb,MAHIA,IACFA,EAAOuE,SAEF3Y,KAAKsR,MAAM8C,IAItB,IAAIqD,IAAAA,CAEJ1O,GAAM0P,6BAA+B,WAC9BhB,IACHA,GAAAA,EACAQ,sBAAsBF,IAc1B,IAAI1G,GAAW,GAAItI,GAAMqP,iBACzBrP,GAAMsI,SAAWA,CAEjB,KACErT,OAAOiR,eAAeiC,OAAO3K,SAAU,YACrCyI,cAAAA,EACAY,IAAK,WAAa,MAAOyB,MAE3B,MAAOuH,IACT,IACE1H,OAAO3K,SAAS8K,SAAWA,EAC3B,MAAOuH,MAERnc,EAAqBE,EAAmBC,GC1F3C,SAAUC,EAAQkM,GAChBA,EAAMwP,0BAENxP,EAAMoL,UAAY,SAASC,GACzBpU,KAAKoU,OAASA,EACVA,IACFA,EAAOsE,WAAa1Y,MAEtBA,KAAKqU,gBAAkBxX,EAAOyW,iBAC9BtT,KAAK6Y,UAAY,EACjB7Y,KAAKuU,SAAAA,EACLvU,KAAK8Y,UAAAA,EACL9Y,KAAK0Y,WAAa,KAClB1Y,KAAK+Y,oBACL/Y,KAAKgZ,UAAY,KACjBhZ,KAAKiZ,cAAgB,OACrBjZ,KAAKkZ,8BAELlZ,KAAK0Y,WAAW1C,SAChBhW,KAAKwY,mBAGPzP,EAAMoL,UAAU5D,WACdiI,gBAAiB,WACf,GAAIW,GAAenZ,KAAKiZ,cACpBG,EAAepZ,KAAK4V,SAsBxB,OArBI5V,MAAKqZ,eAAiBD,IAAiBD,IACrB,QAAhBC,GACFpZ,KAAKsZ,sBACLtZ,KAAKqZ,cAAgBtb,QACI,WAAhBob,EACTnZ,KAAKuZ,uBACoB,WAAhBH,IACTpZ,KAAKqZ,cAAgBtb,SAGrBiC,KAAKwZ,kBAAoBJ,IAAiBD,IACxB,QAAhBC,GACFpZ,KAAKyZ,yBACLzZ,KAAKwZ,iBAAmBzb,QACC,YAAhBqb,EACTpZ,KAAK0Z,0BACoB,YAAhBP,IACTnZ,KAAKwZ,iBAAmBzb,SAG5BiC,KAAKiZ,cAAgBjZ,KAAK4V,UAClB5V,KAAKqZ,eAAiBrZ,KAAKwZ,kBAErCN,4BAA6B,WAC3BlZ,KAAKwY,iBACL,IAAImB,GACAC,EACAC,EACAlE,EACAmE,EAAgB9Z,KAAK0Y,YAAAA,GAAa,CAClCoB,KACFH,EAAkB3Z,KAAKrC,aACvBic,EAAY5Z,KAAKuU,QACjBsF,EAAe7Z,KAAKuJ,UACpBoM,EAAiB3V,KAAKwT,YACtBxT,KAAK0Y,WAAW1C,SAChBhW,KAAK0Y,WAAWqB,SAAW,KAC3B/Z,KAAK0Y,WAAa,QAGf1Y,KAAKoU,QAAUpU,KAAKoU,iBAAkBlD,QAAO9C,kBAChDpO,KAAK0Y,WAAa3P,EAAMiR,wCAAwCha,KAAKoU,QACrErL,EAAMkR,+BAA+Bja,QAEnCA,KAAKoU,iBAAkBlD,QAAOgJ,gBAAkBla,KAAKoU,iBAAkBlD,QAAOiJ,eAChFna,KAAK0Y,WAAa3P,EAAMqR,+BAA+Bpa,KAAKoU,QAC5DrL,EAAMsR,sBAAsBra,OAE1B8Z,IACqB,GAAnBH,IACF3Z,KAAKrC,aAAegc,GAED,OAAjBE,EACF7Z,KAAKuJ,UAAYsQ,EACW,OAAnBlE,EACT3V,KAAKwT,YAAcmC,EACS,OAAnB3V,KAAK6Y,YACd7Y,KAAKwT,YAAcxT,KAAK6Y,WAEtBe,GACF5Z,KAAK8V,SAGT9V,KAAKwY,mBAEP8B,gBAAiB,WACf,GAAKta,KAAKoU,QAA4B,QAAlBpU,KAAK4V,UAAzB,CAGA,GAAIxR,GAASpE,KAAKoU,OAAOmG,QAAQld,KACjC2C,MAAK+Y,iBAAiB7a,QAAQ,SAASsc,GACrCxa,KAAKya,iBAAiBD,EAAgBpW,GAClCpE,KAAKoU,iBAAkBlD,QAAOgJ,iBAChC9V,GAAU2E,EAAM2R,mBAAmBF,EAAepG,UACpDuG,KAAK3a,SAET4a,sBAAuB,SAAS/C,GAC9B,GAAK7X,KAAKoU,QAAWpU,KAAK8Y,SAE1B,IAAK,GAAIlV,GAAI,EAAGA,EAAI5D,KAAKoU,OAAOyG,SAAS3W,OAAQN,IAC/C5D,KAAKoU,OAAOyG,SAASjX,GAAG8U,WAAab,EACrC7X,KAAK+Y,iBAAiBnV,GAAGgX,sBAAsB/C,IAGnDiD,0BAA2B,WACzB,GAAK9a,KAAKoU,QAAWpU,KAAK8Y,SAA1B,CAEA,GAAI1U,GAASpE,KAAKoU,OAAOmG,QAAQld,KACjC2C,MAAK+a,yBACL/a,KAAKoU,OAAOyG,SAAS3c,QAAQ,SAAS8c,GACpC,GAAIR,GAAiBtJ,OAAO3K,SAAS8K,SAASC,MAAM0J,EACpDhb,MAAK+Y,iBAAiBpP,KAAK6Q,GAC3BA,EAAe7c,aAAeqC,KAAKrC,aAC/BqC,KAAKuU,SACPiG,EAAe1E,QACjBkF,EAAMtC,WAAa1Y,KAAKoU,OAAOsE,WAE/B1Y,KAAKya,iBAAiBD,EAAgBpW,GAElCpE,KAAKoU,iBAAkBlD,QAAOgJ,iBAChC9V,GAAU2E,EAAM2R,mBAAmBM,KACrCL,KAAK3a,SAETya,iBAAkB,SAASD,EAAgBpW,GAClB,OAAnBpE,KAAKuJ,UACPiR,EAAehH,YAAcxT,KAAKwT,YAAcpP,EAASpE,KAAKrC,aACrD6c,EAAejR,YAAcvJ,KAAKuJ,UAAYnF,EAASpE,KAAKrC,eACrE6c,EAAejR,UAAYvJ,KAAKuJ,UAAYnF,EAASpE,KAAKrC,eAG9D6S,GAAIoF,aACF,MAAO5V,MAAK0Y,WAAa1Y,KAAK0Y,WAAW9C,UAAY,QAEvDpF,GAAI+F,YACF,MAAKrF,QAAO+J,SAIPjb,KAAKwZ,mBAC0C,IAA9CzQ,EAAMwP,uBAAuBla,QAAQ2B,OACvC+I,EAAMwP,uBAAuB5O,KAAK3J,MAEpCA,KAAKwZ,iBAAmB,GAAIyB,SACxB,SAASC,EAASC,GAChBnb,KAAK0Z,wBAA0B,WAC7BwB,EAAQlb,OAEVA,KAAKyZ,uBAAyB,WAC5B0B,GAAQnW,KAAMC,aAAamW,UAAWjW,KAAM,iBAE9CwV,KAAK3a,OACW,YAAlBA,KAAK4V,WACP5V,KAAK0Z,2BAGF1Z,KAAKwZ,mBApBV9Q,QAAQC,KAAK,6DACN,OAqBX6H,GAAI6K,SACF,MAAKnK,QAAO+J,SAIPjb,KAAKqZ,gBAC0C,IAA9CtQ,EAAMwP,uBAAuBla,QAAQ2B,OACvC+I,EAAMwP,uBAAuB5O,KAAK3J,MAEpCA,KAAKqZ,cAAgB,GAAI4B,SACrB,SAASC,EAASC,GAChBnb,KAAKuZ,qBAAuB,WAC1B2B,EAAQlb,OAEVA,KAAKsZ,oBAAsB,WACzB6B,GAAQnW,KAAMC,aAAamW,UAAWjW,KAAM,iBAE9CwV,KAAK3a,OACY,YAAnBA,KAAK4V,WACP5V,KAAKuZ,wBAGFvZ,KAAKqZ,gBApBV3Q,QAAQC,KAAK,6DACN,OAqBX6H,GAAImE,YACF,MAAO3U,MAAKsb,WAEd9K,GAAImE,UAAS4G,GACK,kBAALA,IACTvb,KAAKsb,UAAYC,EACjBvb,KAAK0Y,WAAW/D,SAAW,SAAUiE,GACnCA,EAAE3O,OAASjK,KACXub,EAAE7E,KAAK1W,KAAM4Y,IACZ+B,KAAK3a,QAERA,KAAK0Y,WAAW/D,SAAW4G,EAC3Bvb,KAAK2U,SAAW3U,KAAK0Y,WAAW/D,WAGpCnE,GAAIgD,eACFxT,KAAKwY,iBACL,IAAIhF,GAAcxT,KAAK0Y,WAAWlF,WAElC,OADAxT,MAAKwY,kBACEhF,GAEThD,GAAIgD,aAAY+H,GACdvb,KAAKwY,kBACLxY,KAAK0Y,WAAWlF,YAAczO,SAASwW,GAAKA,EAAIjc,KAAKkc,KAAKD,GAAKpb,OAAOsb,UACtEzb,KAAK0b,YACL1b,KAAK2b,cAAc,SAASX,EAAO5W,GACjC4W,EAAMxH,YAAc+H,EAAInX,IAE1BpE,KAAKwY,mBAEPhI,GAAIjH,aACF,MAAOvJ,MAAK0Y,WAAWnP,WAEzBiH,GAAIjH,WAAUgS,GACZvb,KAAKwY,kBACLxY,KAAK0Y,WAAWnP,UAAYxE,SAASwW,GAAKA,EAAIjc,KAAKkc,KAAKD,GAAKpb,OAAOsb,UACpEzb,KAAK0b,YACL1b,KAAK2b,cAAc,SAASX,EAAO5W,GACjC4W,EAAMzR,UAAYgS,EAAInX,IAExBpE,KAAKwY,mBAEPhI,GAAI7S,gBACF,MAAOqC,MAAK0Y,WAAW/a,cAEzB6S,GAAI7S,cAAayF,GACfpD,KAAKwY,iBACL,IAAI7C,GAAiB3V,KAAKwT,WAC1BxT,MAAK0Y,WAAW/a,aAAeyF,EAC/BpD,KAAK2b,cAAc,SAASnB,GAC1BA,EAAe7c,aAAeyF,IAEV,UAAlBpD,KAAK4V,WAA2C,QAAlB5V,KAAK4V,WACrC5V,KAAK6V,OAEgB,OAAnBF,IACF3V,KAAKwT,YAAcmC,GAErB3V,KAAKwY,mBAEPhI,GAAIoL,UAEF,MADA/e,GAAOgM,WAAW,mBAAoB,aAAc,iCAC7C7I,KAAKoU,QAEdyB,KAAM,WACJ7V,KAAKwY,kBACLxY,KAAKuU,SAAAA,EACLvU,KAAK0Y,WAAW7C,OACmC,IAA/CtP,SAAS8K,SAAS6D,YAAY7W,QAAQ2B,OACxCuG,SAAS8K,SAAS6D,YAAYvL,KAAK3J,MAErCA,KAAK0b,YACL3S,EAAM8S,eAAe7b,MACrBA,KAAK2b,cAAc,SAASX,GAC1B,GAAIc,GAAOd,EAAMxH,WACjBwH,GAAMnF,OACNmF,EAAMxH,YAAcsI,IAEtB9b,KAAKwY,mBAEP1C,MAAO,WACL9V,KAAKwY,kBACDxY,KAAKwT,cACPxT,KAAK6Y,UAAY7Y,KAAKwT,aAExBxT,KAAK0Y,WAAW5C,QAChB9V,KAAK0b,YACL1b,KAAK2b,cAAc,SAASX,GAC1BA,EAAMlF,UAER9V,KAAKuU,SAAAA,EACLvU,KAAKwY,mBAEPzC,OAAQ,WACN/V,KAAKwY,kBACLxY,KAAK0Y,WAAW3C,SAChB/V,KAAK0b,YACL1b,KAAKwY,mBAEPxC,OAAQ,WACNhW,KAAKwY,kBACLxY,KAAK0Y,WAAW1C,SAChBhW,KAAK0b,YACL1b,KAAK+a,yBACL/a,KAAKwY,mBAEPuD,QAAS,WACP/b,KAAKwY,iBACL,IAAI7C,GAAiB3V,KAAKwT,WAC1BxT,MAAK0Y,WAAWqD,UAChB/b,KAAK2b,cAAc,SAASnB,GAC1BA,EAAeuB,YAEM,OAAnBpG,IACF3V,KAAKwT,YAAcmC,GAErB3V,KAAKwY,mBAEPvC,iBAAkB,SAASjR,EAAMkR,GAC/B,GAAI8F,GAAU9F,CACQ,mBAAXA,KACT8F,EAAU,SAAUpD,GAClBA,EAAE3O,OAASjK,KACXkW,EAAQQ,KAAK1W,KAAM4Y,IAClB+B,KAAK3a,MACRkW,EAAQ6D,SAAWiC,GAErBhc,KAAK0Y,WAAWzC,iBAAiBjR,EAAMgX,IAEzC7F,oBAAqB,SAASnR,EAAMkR,GAClClW,KAAK0Y,WAAWvC,oBAAoBnR,EAAOkR,GAAWA,EAAQ6D,UAAa7D,IAE7E6E,uBAAwB,WACtB,KAAO/a,KAAK+Y,iBAAiB7U,QAC3BlE,KAAK+Y,iBAAiBkD,MAAMjG,UAEhC2F,cAAe,SAAS1c,GACtB,GAAImF,GAAS,CASb,IARIpE,KAAKoU,OAAOyG,UAAY7a,KAAK+Y,iBAAiB7U,OAASlE,KAAKoU,OAAOyG,SAAS3W,QAC9ElE,KAAK8a,4BACP9a,KAAK+Y,iBAAiB7a,QAAQ,SAAS8c,GACrC/b,EAAEyX,KAAK1W,KAAMgb,EAAO5W,GAChBpE,KAAKoU,iBAAkBlD,QAAOgJ,iBAChC9V,GAAU4W,EAAM5G,OAAOrT,iBACzB4Z,KAAK3a,OAEe,WAAlBA,KAAK4V,UAAT,CAEA,GAAIxY,GAAS4C,KAAKoU,OAAOmG,QACrB9O,EAAIzL,KAAKwT,WACH,QAAN/H,IACFA,EAAI5O,EAAO2F,sBAAsB3F,EAAO+D,wBAAwBxD,GAASqO,EAAGrO,KACrE,MAALqO,GAAa3N,MAAM2N,KACrBzL,KAAK+a,6BAOVte,EAAqBE,EAAmBC,GC3V1C,SAASC,EAAQkM,GAqChB,QAASmT,GAAalY,GACpBhE,KAAKmc,QAAUtf,EAAOkH,mBAAmBC,GAgF3C,QAASoY,KAEP,IADA,GAAIC,IAAAA,EACGC,EAAcpY,QAAQ,CAC3B,GAAIkF,GAAQkT,EAAcC,OAC1BnT,GAAMkR,kBACN+B,GAAAA,EAEF,MAAOA,GA3HT,GAAIG,GAAe,SAASpI,GAE1B,GADAA,EAAOsE,WAAa3a,OAChBqW,YAAkBlD,QAAOgJ,gBAAkB9F,YAAkBlD,QAAOiJ,YACtE,IAAK,GAAIvW,GAAI,EAAGA,EAAIwQ,EAAOyG,SAAS3W,OAAQN,IAC1C4Y,EAAapI,EAAOyG,SAASjX,IAKnCmF,GAAM0T,YAAc,SAASC,GAE3B,IAAK,GADDC,MACK/Y,EAAI,EAAGA,EAAI8Y,EAAQxY,OAAQN,IAAK,CACvC,GAAIwQ,GAASsI,EAAQ9Y,EACjBwQ,GAAOwI,SACiC,IAAtCD,EAAWte,QAAQ+V,EAAOwI,UAC5BD,EAAWhT,KAAKyK,EAAOwI,SAEzBxI,EAAOwI,QAAQ/B,SAASzE,OAAOhC,EAAOwI,QAAQ/B,SAASxc,QAAQ+V,GAAS,GACxEA,EAAOwI,QAAU,KACjBJ,EAAapI,IACJA,EAAOsE,YAAetE,EAAOsE,WAAWtE,QAAUA,IAC3DA,EAAOsE,WAAW1C,SAClB5B,EAAOsE,WAAWtE,OAAS,GAAIhG,gBAAe,SAC1CgG,EAAOsE,WAAWM,YACpB5E,EAAOsE,WAAWM,UAAUN,WAAa,MAE3CtE,EAAOsE,WAAWQ,8BAClBsD,EAAapI,IAGjB,IAAKxQ,EAAI,EAAGA,EAAI+Y,EAAWzY,OAAQN,IACjC+Y,EAAW/Y,GAAGiZ,YAQlB9T,EAAMqF,eAAiB,SAASnE,EAAQjG,EAAajH,GAanD,MAZAiD,MAAKiK,OAASA,EAEdjK,KAAK8c,aAAejgB,EAAOC,iBAAiBC,GAC5CiD,KAAKua,QAAU1d,EAAO2B,qBAAqBzB,GAE3CiD,KAAK5C,OAASP,EAAOK,WAAWH,GAE9BiD,KAAK+c,qBADmB,kBAAf/Y,GACmBA,EAEA,GAAIkY,GAAalY,GAC/ChE,KAAKgd,WAAahZ,EAClBhE,KAAKe,eAAiBlE,EAAO+D,wBAAwBZ,KAAKua,SACnDva,MAGT+I,EAAMqF,eAAemC,WACnB0M,UAAW,WACT,MAAwC,kBAA7Bjd,MAAK+c,qBACP/c,KAAK+c,qBACP/c,KAAK+c,qBAAqBZ,SAEnC3L,GAAI4D,UAEF,MADAvX,GAAOgM,WAAW,wBAAyB,aAAc,2CAClD7I,KAAK+c,sBAEd/f,MAAO,WACL,GAA+B,kBAApBgD,MAAKid,YACd,KAAM,IAAInU,OAAM,2CAElB,IAAI9L,GAAQ,GAAIoR,gBAAepO,KAAKiK,UAAYpN,EAAOC,iBAAiBkD,KAAK8c,cAG7E,OAFA9f,GAAM+f,qBAAuB/c,KAAK+c,qBAClC/f,EAAMggB,WAAahd,KAAKgd,WACjBhgB,GAET2b,OAAQ,WACN5P,EAAM0T,aAAazc,QAIvB,IAAIkd,GAAyB/L,QAAQZ,UAAUa,OAC/CD,SAAQZ,UAAUa,QAAU,SAASpN,EAAa5G,GAChD,MAAO2L,GAAMsI,SAASC,MAAM,GAAIvI,GAAMqF,eAAepO,KAAMgE,EAAa5G,IAG1E,IAAI+f,GAAa5W,SAASC,gBAAgB,+BAAgC,MAC1EuC,GAAMiR,wCAA0C,SAAS3L,GACvD,GAAIA,EAAgB,CAClB,GAAIpE,GAASoE,EAAepE,QAAUkT,EAClChZ,EAAYkK,EAAe2O,UACP,mBAAb7Y,KACTA,KAEF,IAAI/G,GAASiR,EAAeyO,iBAE5B,IAAI7S,GAASkT,EACThZ,KACA/G,EAAS,CAEf,OAAO8f,GAAuBnd,MAAMkK,GAAS9F,EAAW/G,KAG1D2L,EAAMkR,+BAAiC,SAASpC,GAC1CA,EAAUzD,QAA0D,kBAAzCyD,GAAUzD,OAAO2I,sBAC9ChU,EAAMqU,6BAA6BvF,GAIvC,IAAIyE,KACJvT,GAAM8S,eAAiB,SAASwB,GACG,OAA7BA,EAAe9T,WAAuB8T,EAAevE,WAE7B,GAAxBwD,EAAcpY,QAChB+T,sBAAsBmE,GAExBE,EAAc3S,KAAK0T,IAWrB,IAAIC,GAA2BpM,OAAOqM,gBACtCvf,QAAOiR,eAAeiC,OAAQ,oBAC5BlC,cAAAA,EACAD,YAAAA,EACA3L,MAAO,WACL8N,OAAO3K,SAAS8K,SAAS8G,2BACzB,IAAI5U,GAAS+Z,EAAyBvd,MAAMC,KAAM8Q,UAIlD,OAHIsL,OACF7Y,EAAS+Z,EAAyBvd,MAAMC,KAAM8Q,YAChDI,OAAO3K,SAAS8K,SAAS8G,4BAClB5U,KAIX2N,OAAO9C,eAAiBrF,EAAMqF,eAC9B8C,OAAOC,QAAQZ,UAAU8H,cAAgB,WACvC,MAAO9R,UAAS8K,SAASgH,gBAAgB7S,OAAO,SAASqS,GACvD,MAA4B,QAArBA,EAAUzD,QAAmByD,EAAUzD,OAAOnK,QAAUjK,MAC/D2a,KAAK3a,QAETkR,OAAOC,QAAQZ,UAAU+H,oBAAsB,WAE7C,MADAzb,GAAOgM,WAAW,8BAA+B,aAAc,sCACxD7I,KAAKqY,iBAYdnH,OAAOiD,UAAY,WACjBtX,EAAOgM,WAAW,mBAAoB,aAAc,sCACpDqI,OAAO9C,eAAerO,MAAMC,KAAM8Q,YAEpCI,OAAOiD,UAAU5D,UAAYvS,OAAOwf,OAAOtM,OAAO9C,eAAemC,WACjEW,OAAOiD,UAAU5D,UAAUkN,YAAcvM,OAAOiD,WAEhD1X,EAAqBE,EAAmBC,GCzK1C,SAAUC,EAAQkM,GAkChB,QAAS2U,GAASC,GACZA,EAASC,cAEbD,EAASC,aAAAA,EACTC,EAAUlU,KAAKgU,GACVlG,IACHA,GAAAA,EACAQ,sBAAsBnB,KAI1B,QAASA,KACP,GAAIgH,GAAWD,CACfA,MACAC,EAASjU,KAAK,SAASmB,EAAMG,GAC3B,MAAOH,GAAKqJ,gBAAkBlJ,EAAMkJ,kBAEtCyJ,EAAWA,EAAStY,OAAO,SAASmY,GAClCA,GACA,IAAI/H,GAAY+H,EAASjF,WAAaiF,EAASjF,WAAW9C,UAAY,MAGtE,OAFiB,WAAbA,GAAuC,WAAbA,IAC5B+H,EAASC,aAAAA,GACJD,EAASC,cAElBC,EAAUlU,KAAK5J,MAAM8d,EAAWC,GAE5BD,EAAU3Z,QACZuT,GAAAA,EACAQ,sBAAsBnB,IAEtBW,GAAAA,EA9DJ,GAEInE,IAFa/M,SAASC,gBAAgB,+BAAgC,OAErD,EACrBuC,GAAMqU,6BAA+B,SAASvF,GAC5C,GAAI5N,GAAS4N,EAAUzD,OAAOnK,OAC1B8T,EAAiBlG,EAAUzD,OAAO2I,qBAClC3f,EAASya,EAAUzD,OAAOhX,OAC1B4gB,EAAO,IACX5gB,GAASP,EAAO2B,qBAAqBpB,EACrC,IAAIugB,GAAW,WACb,GAAIlS,GAAIkS,EAASjF,WAAaiF,EAASjF,WAAWlF,YAAc,IACtD,QAAN/H,IACFA,EAAI5O,EAAO2F,sBAAsB3F,EAAO+D,wBAAwBxD,GAASqO,EAAGrO,GACxEU,MAAM2N,KACRA,EAAI,OAIJA,IAAMuS,GACRD,EAAetS,EAAGxB,EAAQ4N,EAAUzD,QACtC4J,EAAOvS,EAGTkS,GAASjF,WAAab,EACtB8F,EAASC,aAAAA,EACTD,EAAStJ,gBAAkBf,IAC3BuE,EAAUmB,UAAY2E,EACtBD,EAASC,GAGX,IAAIE,MACApG,GAAAA,CAmCJ1O,GAAMoL,UAAU5D,UAAUmL,UAAY,WAChC1b,KAAKgZ,WACP0E,EAAS1d,KAAKgZ,aAGjBvc,EAAqBE,EAAmBC,GCxE3C,SAAUC,EAAQkM,GAEhB,QAAS2R,GAAmBuD,GAC1B,MAAOA,GAAK1D,QAAQld,MAAQ4gB,EAAKld,eAAiBkd,EAAK1D,QAAQjd,SAGjE,QAASmgB,GAAY5C,EAAU9d,GAC7BiD,KAAK4c,QAAU,KACf5c,KAAK6a,SAAWA,MAChB7a,KAAKke,UAAUle,KAAK6a,UACpB7a,KAAK8c,aAAejgB,EAAOC,iBAAiBC,GAC5CiD,KAAKua,QAAU1d,EAAO2B,qBAAqBzB,GAAAA,GAC3CiD,KAAK5C,OAASP,EAAOK,WAAWH,GAAAA,GAEF,SAA1BiD,KAAKua,QAAQ7c,WACfsC,KAAKua,QAAQ7c,SAAWsC,KAAKe,gBAIjCmQ,OAAOgJ,eAAiB,WACtBuD,EAAY1d,MAAMC,KAAM8Q,YAG1BI,OAAOiJ,YAAc,WACnBsD,EAAY1d,MAAMC,KAAM8Q,YAG1B2M,EAAYlN,WACV4N,YAAa,SAAS/J,GAEpB,IADA,GAAIzV,GAAIqB,KACK,OAANrB,GAAY,CACjB,GAAIA,GAAKyV,EACP,OAAA,CACFzV,GAAIA,EAAEie,QAER,OAAA,GAEFC,SAAU,WAGR,IADA,GAAIoB,GAAOje,KACJie,GACwB,SAAzBA,EAAK7gB,OAAOM,WACdugB,EAAK1D,QAAQ7c,SAAWugB,EAAKld,gBAE/Bkd,EAAOA,EAAKrB,OAEV5c,MAAK0Y,YACP1Y,KAAK0Y,WAAWQ,+BAGpBgF,UAAW,SAASE,GAClBrV,EAAM0T,YAAY2B,EAClB,KAAK,GAAIxa,GAAI,EAAGA,EAAIwa,EAAYla,OAAQN,IACtCwa,EAAYxa,GAAGgZ,QAAU5c,MAG7Bqe,UAAW,SAASC,EAAMC,GAExB,IAAK,GADDnZ,GAAUmZ,EAAW,oCAAsC,qCACtD3a,EAAI,EAAGA,EAAI0a,EAAKpa,OAAQN,IAC/B,GAAI5D,KAAKme,YAAYG,EAAK1a,IACxB,MACEoB,KAAMC,aAAauZ,sBACnBrZ,KAAM,wBACNC,QAASA,EAKf,KAAK,GAAIxB,GAAI,EAAGA,EAAI0a,EAAKpa,OAAQN,IAC/B2a,EAAWve,KAAK6a,SAASlR,KAAK2U,EAAK1a,IAAM5D,KAAK6a,SAAS4D,QAAQH,EAAK1a,GAEtE5D,MAAKke,UAAUI,GACfte,KAAK6c,YAEP6B,OAAQ,WACN1e,KAAKqe,UAAUvN,WAAAA,IAEjB6N,QAAS,WACP3e,KAAKqe,UAAUvN,WAAAA,IAEjBN,GAAIoO,cACF,MAAO5e,MAAK6a,SAAS3W,OAASlE,KAAK6a,SAAS,GAAK,MAEnDrK,GAAIqO,aACF,MAAO7e,MAAK6a,SAAS3W,OAASlE,KAAK6a,SAAS7a,KAAK6a,SAAS3W,OAAS,GAAK,MAE1ElH,MAAO,WAGL,IAAK,GAFD8hB,GAAejiB,EAAOC,iBAAiBkD,KAAK8c,cAC5CiC,KACKnb,EAAI,EAAGA,EAAI5D,KAAK6a,SAAS3W,OAAQN,IACxCmb,EAAepV,KAAK3J,KAAK6a,SAASjX,GAAG5G,QAEvC,OAAQgD,gBAAgBma,aACpB,GAAIA,aAAY4E,EAAgBD,GAChC,GAAI5E,gBAAe6E,EAAgBD,IAEzCnG,OAAQ,WACN5P,EAAM0T,aAAazc,SAIvBkR,OAAOgJ,eAAe3J,UAAYvS,OAAOwf,OAAOC,EAAYlN,WAC5DvS,OAAOiR,eACHiC,OAAOgJ,eAAe3J,UACtB,kBAEEX,IAAK,WACH,GAAIoP,GAAQ,CAIZ,OAHAhf,MAAK6a,SAAS3c,QAAQ,SAAS8c,GAC7BgE,GAAStE,EAAmBM,KAEvB1b,KAAKuS,IAAImN,EAAO,MAI/B9N,OAAOiJ,YAAY5J,UAAYvS,OAAOwf,OAAOC,EAAYlN,WACzDvS,OAAOiR,eACHiC,OAAOiJ,YAAY5J,UACnB,kBAEEX,IAAK,WACH,GAAIiC,GAAM,CAIV,OAHA7R,MAAK6a,SAAS3c,QAAQ,SAAS8c,GAC7BnJ,EAAMvS,KAAKuS,IAAIA,EAAK6I,EAAmBM,MAElCnJ,KAIf9I,EAAMqR,+BAAiC,SAAShR,GAC9C,GAAI6V,GACA7hB,EAAS,KACT8hB,EAAS,SAASC,GACpB,GAAItH,GAAYoH,EAAoBlF,QACpC,OAAKlC,IAGsB,WAAvBA,EAAUjC,WAGTiC,EAAUzD,OAGL,MAAN+K,MACFtH,GAAUkD,yBAQF,GAANoE,GAAWtH,EAAUla,aAAe,IACjCP,IACHA,EAASP,EAAO2B,qBAAqBqZ,EAAUzD,OAAOhX,SAExD+hB,EAAKtiB,EAAO2F,sBAAsB3F,EAAO+D,wBAAwBxD,GAAS,GAAIA,GAC1EU,MAAMqhB,IAAa,MAANA,IACftH,EAAU8D,cAAc,SAASX,GAC/BA,EAAMxH,YAAc,SAEtBqE,GAAUkD,0BATd,OAlBA,OAkCF,OADAkE,GAAsBlW,EAAMsI,SAASC,MAAM,GAAIvI,GAAMqF,eAAe,KAAM8Q,EAAQ9V,EAAMmR,WAI1FxR,EAAMsR,sBAAwB,SAASxC,GACrCA,EAAUa,WAAWqB,SAAWlC,EAChCA,EAAUiB,UAAAA,EACV/P,EAAM8S,eAAehE,GACrBA,EAAUiD,4BACVjD,EAAU+C,sBAAsB/C,IAGlC9O,EAAM2R,mBAAqBA,EAK3BxJ,OAAOkO,kBAAoB,WACzBviB,EAAOgM,WAAW,2BAA4B,aAAc,sCAC5DqI,OAAOgJ,eAAena,MAAMC,KAAM8Q,YAEpCI,OAAOkO,kBAAkB7O,UAAYvS,OAAOwf,OAAOtM,OAAOgJ,eAAe3J,WACzEW,OAAOkO,kBAAkB7O,UAAUkN,YAAcvM,OAAOkO,kBAExDlO,OAAOmO,eAAiB,WACtBxiB,EAAOgM,WAAW,wBAAyB,aAAc,mCACzDqI,OAAOiJ,YAAYpa,MAAMC,KAAM8Q,YAEjCI,OAAOmO,eAAe9O,UAAYvS,OAAOwf,OAAOtM,OAAOiJ,YAAY5J,WACnEW,OAAOmO,eAAe9O,UAAUkN,YAAcvM,OAAOmO,gBAEpD5iB,EAAqBE,EAAmBC,OjBjMrCA,WAAAA,MAAuB"}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/web-animations-js/web-animations.html b/polymer_1.0.4/bower_components/web-animations-js/web-animations.html
new file mode 100644
index 0000000..b5de36c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/web-animations-js/web-animations.html
@@ -0,0 +1,50 @@
+<!--
+ Copyright 2014 Google Inc. All rights reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- WARNING: This file is DEPRECATED, for development purposes use
+ web-animations*.dev.html instead or depend on
+ web-animations*.min.js in the web-animations-js
+ repository -->
+
+<script src="src/dev.js"></script>
+<script src="src/scope.js"></script>
+<script src="src/deprecation.js"></script>
+<script src="src/timing-utilities.js"></script>
+<script src="src/normalize-keyframes.js"></script>
+<script src="src/animation-node.js"></script>
+<script src="src/effect.js"></script>
+<script src="src/property-interpolation.js"></script>
+<script src="src/animation.js"></script>
+<script src="src/apply.js"></script>
+<script src="src/element-animatable.js"></script>
+<script src="src/interpolation.js"></script>
+<script src="src/player.js"></script>
+<script src="src/tick.js"></script>
+<script src="src/handler-utils.js"></script>
+<script src="src/shadow-handler.js"></script>
+<script src="src/number-handler.js"></script>
+<script src="src/visibility-handler.js"></script>
+<script src="src/color-handler.js"></script>
+<script src="src/dimension-handler.js"></script>
+<script src="src/box-handler.js"></script>
+<script src="src/transform-handler.js"></script>
+<script src="src/property-names.js"></script>
+<script src="src/timeline.js"></script>
+<script src="src/maxifill-player.js"></script>
+<script src="src/animation-constructor.js"></script>
+<script src="src/effect-callback.js"></script>
+<script src="src/group-constructors.js"></script>
+
diff --git a/polymer_1.0.4/bower_components/web-animations-js/web-animations.min.js b/polymer_1.0.4/bower_components/web-animations-js/web-animations.min.js
new file mode 100644
index 0000000..62c3ae5
--- /dev/null
+++ b/polymer_1.0.4/bower_components/web-animations-js/web-animations.min.js
@@ -0,0 +1,17 @@
+// Copyright 2014 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+!function(a,b){b["true"]=a,function(){if(document.documentElement.animate){var a=document.documentElement.animate([],0),b=!0;if(a&&(b=!1,"play|currentTime|pause|reverse|playbackRate|cancel|finish|startTime|playState".split("|").forEach(function(c){void 0===a[c]&&(b=!0)})),!b)return}var c={},d={},e={},f=null;!function(a){function b(a){if("number"==typeof a)return a;var b={};for(var c in a)b[c]=a[c];return b}function c(b,c){var d={delay:0,endDelay:0,fill:c?"both":"none",iterationStart:0,iterations:1,duration:c?"auto":0,playbackRate:1,direction:"normal",easing:"linear"};return"number"!=typeof b||isNaN(b)?void 0!==b&&Object.getOwnPropertyNames(b).forEach(function(c){if("auto"!=b[c]){if(("number"==typeof d[c]||"duration"==c)&&("number"!=typeof b[c]||isNaN(b[c])))return;if("fill"==c&&-1==q.indexOf(b[c]))return;if("direction"==c&&-1==r.indexOf(b[c]))return;if("playbackRate"==c&&1!==b[c]&&a.isDeprecated("AnimationEffectTiming.playbackRate","2014-11-28","Use Animation.playbackRate instead."))return;d[c]=b[c]}}):d.duration=b,d}function d(a,b){var d=c(a,b);return d.easing=g(d.easing),d}function e(a,b,c,d){return 0>a||a>1||0>c||c>1?z:function(e){function f(a,b,c){return 3*a*(1-c)*(1-c)*c+3*b*(1-c)*c*c+c*c*c}if(0==e||1==e)return e;for(var g=0,h=1;;){var i=(g+h)/2,j=f(a,c,i);if(Math.abs(e-j)<.001)return f(b,d,i);e>j?g=i:h=i}}}function f(a,b){return function(c){if(c>=1)return 1;var d=1/a;return c+=b*d,c-c%d}}function g(a){var b=x.exec(a);if(b)return e.apply(this,b.slice(1).map(Number));var c=y.exec(a);if(c)return f(Number(c[1]),{start:s,middle:t,end:u}[c[2]]);var d=v[a];return d?d:z}function h(a){return Math.abs(i(a)/a.playbackRate)}function i(a){return a.duration*a.iterations}function j(a,b,c){return null==b?A:b<c.delay?B:b>=c.delay+a?C:D}function k(a,b,c,d,e){switch(d){case B:return"backwards"==b||"both"==b?0:null;case D:return c-e;case C:return"forwards"==b||"both"==b?a:null;case A:return null}}function l(a,b,c,d){return(d.playbackRate<0?b-a:b)*d.playbackRate+c}function m(a,b,c,d,e){return 1/0===c||c===-1/0||c-d==b&&e.iterations&&(e.iterations+e.iterationStart)%1==0?a:c%a}function n(a,b,c,d){return 0===c?0:b==a?d.iterationStart+d.iterations-1:Math.floor(c/a)}function o(a,b,c,d){var e=a%2>=1,f="normal"==d.direction||d.direction==(e?"alternate-reverse":"alternate"),g=f?c:b-c,h=g/b;return b*d.easing(h)}function p(a,b,c){var d=j(a,b,c),e=k(a,c.fill,b,d,c.delay);if(null===e)return null;if(0===a)return d===B?0:1;var f=c.iterationStart*c.duration,g=l(a,e,f,c),h=m(c.duration,i(c),g,f,c),p=n(c.duration,h,g,c);return o(p,c.duration,h,c)/c.duration}var q="backwards|forwards|both|none".split("|"),r="reverse|alternate|alternate-reverse".split("|"),s=1,t=.5,u=0,v={ease:e(.25,.1,.25,1),"ease-in":e(.42,0,1,1),"ease-out":e(0,0,.58,1),"ease-in-out":e(.42,0,.58,1),"step-start":f(1,s),"step-middle":f(1,t),"step-end":f(1,u)},w="\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*",x=new RegExp("cubic-bezier\\("+w+","+w+","+w+","+w+"\\)"),y=/steps\(\s*(\d+)\s*,\s*(start|middle|end)\s*\)/,z=function(a){return a},A=0,B=1,C=2,D=3;a.cloneTimingInput=b,a.makeTiming=c,a.normalizeTimingInput=d,a.calculateActiveDuration=h,a.calculateTimeFraction=p,a.calculatePhase=j,a.toTimingFunction=g}(c,f),function(a){function b(a,b){return a in h?h[a][b]||b:b}function c(a,c,d){var g=e[a];if(g){f.style[a]=c;for(var h in g){var i=g[h],j=f.style[i];d[i]=b(i,j)}}else d[a]=b(a,c)}function d(b){function d(){var a=e.length;null==e[a-1].offset&&(e[a-1].offset=1),a>1&&null==e[0].offset&&(e[0].offset=0);for(var b=0,c=e[0].offset,d=1;a>d;d++){var f=e[d].offset;if(null!=f){for(var g=1;d-b>g;g++)e[b+g].offset=c+(f-c)*g/(d-b);b=d,c=f}}}if(!Array.isArray(b)&&null!==b)throw new TypeError("Keyframes must be null or an array of keyframes");if(null==b)return[];for(var e=b.map(function(b){var d={};for(var e in b){var f=b[e];if("offset"==e){if(null!=f&&(f=Number(f),!isFinite(f)))throw new TypeError("keyframe offsets must be numbers.")}else{if("composite"==e)throw{type:DOMException.NOT_SUPPORTED_ERR,name:"NotSupportedError",message:"add compositing is not supported"};f="easing"==e?a.toTimingFunction(f):""+f}c(e,f,d)}return void 0==d.offset&&(d.offset=null),void 0==d.easing&&(d.easing=a.toTimingFunction("linear")),d}),f=!0,g=-1/0,h=0;h<e.length;h++){var i=e[h].offset;if(null!=i){if(g>i)throw{code:DOMException.INVALID_MODIFICATION_ERR,name:"InvalidModificationError",message:"Keyframes are not loosely sorted by offset. Sort or specify offsets."};g=i}else f=!1}return e=e.filter(function(a){return a.offset>=0&&a.offset<=1}),f||d(),e}var e={background:["backgroundImage","backgroundPosition","backgroundSize","backgroundRepeat","backgroundAttachment","backgroundOrigin","backgroundClip","backgroundColor"],border:["borderTopColor","borderTopStyle","borderTopWidth","borderRightColor","borderRightStyle","borderRightWidth","borderBottomColor","borderBottomStyle","borderBottomWidth","borderLeftColor","borderLeftStyle","borderLeftWidth"],borderBottom:["borderBottomWidth","borderBottomStyle","borderBottomColor"],borderColor:["borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],borderLeft:["borderLeftWidth","borderLeftStyle","borderLeftColor"],borderRadius:["borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"],borderRight:["borderRightWidth","borderRightStyle","borderRightColor"],borderTop:["borderTopWidth","borderTopStyle","borderTopColor"],borderWidth:["borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth"],flex:["flexGrow","flexShrink","flexBasis"],font:["fontFamily","fontSize","fontStyle","fontVariant","fontWeight","lineHeight"],margin:["marginTop","marginRight","marginBottom","marginLeft"],outline:["outlineColor","outlineStyle","outlineWidth"],padding:["paddingTop","paddingRight","paddingBottom","paddingLeft"]},f=document.createElementNS("http://www.w3.org/1999/xhtml","div"),g={thin:"1px",medium:"3px",thick:"5px"},h={borderBottomWidth:g,borderLeftWidth:g,borderRightWidth:g,borderTopWidth:g,fontSize:{"xx-small":"60%","x-small":"75%",small:"89%",medium:"100%",large:"120%","x-large":"150%","xx-large":"200%"},fontWeight:{normal:"400",bold:"700"},outlineWidth:g,textShadow:{none:"0px 0px 0px transparent"},boxShadow:{none:"0px 0px 0px 0px transparent"}};a.normalizeKeyframes=d}(c,f),function(a){var b={};a.isDeprecated=function(a,c,d,e){var f=e?"are":"is",g=new Date,h=new Date(c);return h.setMonth(h.getMonth()+3),h>g?(a in b||console.warn("Web Animations: "+a+" "+f+" deprecated and will stop working on "+h.toDateString()+". "+d),b[a]=!0,!1):!0},a.deprecated=function(b,c,d,e){var f=e?"are":"is";if(a.isDeprecated(b,c,d,e))throw new Error(b+" "+f+" no longer supported. "+d)}}(c),function(a,b){function c(a){for(var b={},c=0;c<a.length;c++)for(var d in a[c])if("offset"!=d&&"easing"!=d&&"composite"!=d){var e={offset:a[c].offset,easing:a[c].easing,value:a[c][d]};b[d]=b[d]||[],b[d].push(e)}for(var f in b){var g=b[f];if(0!=g[0].offset||1!=g[g.length-1].offset)throw{type:DOMException.NOT_SUPPORTED_ERR,name:"NotSupportedError",message:"Partial keyframes are not supported"}}return b}function d(a){var c=[];for(var d in a)for(var e=a[d],f=0;f<e.length-1;f++){var g=e[f].offset,h=e[f+1].offset,i=e[f].value,j=e[f+1].value;g==h&&(1==h?i=j:j=i),c.push({startTime:g,endTime:h,easing:e[f].easing,property:d,interpolation:b.propertyInterpolation(d,i,j)})}return c.sort(function(a,b){return a.startTime-b.startTime}),c}b.convertEffectInput=function(e){var f=a.normalizeKeyframes(e),g=c(f),h=d(g);return function(a,c){if(null!=c)h.filter(function(a){return 0>=c&&0==a.startTime||c>=1&&1==a.endTime||c>=a.startTime&&c<=a.endTime}).forEach(function(d){var e=c-d.startTime,f=d.endTime-d.startTime,g=0==f?0:d.easing(e/f);b.apply(a,d.property,d.interpolation(g))});else for(var d in g)"offset"!=d&&"easing"!=d&&"composite"!=d&&b.clear(a,d)}}}(c,d,f),function(a){function b(a,b,c){e[c]=e[c]||[],e[c].push([a,b])}function c(a,c,d){for(var e=0;e<d.length;e++){var f=d[e];b(a,c,f),/-/.test(f)&&b(a,c,f.replace(/-(.)/g,function(a,b){return b.toUpperCase()}))}}function d(b,c,d){if("initial"==c||"initial"==d){var g=b.replace(/-(.)/g,function(a,b){return b.toUpperCase()});"initial"==c&&(c=f[g]),"initial"==d&&(d=f[g])}for(var h=c==d?[]:e[b],i=0;h&&i<h.length;i++){var j=h[i][0](c),k=h[i][0](d);if(void 0!==j&&void 0!==k){var l=h[i][1](j,k);if(l){var m=a.Interpolation.apply(null,l);return function(a){return 0==a?c:1==a?d:m(a)}}}}return a.Interpolation(!1,!0,function(a){return a?d:c})}var e={};a.addPropertiesHandler=c;var f={backgroundColor:"transparent",backgroundPosition:"0% 0%",borderBottomColor:"currentColor",borderBottomLeftRadius:"0px",borderBottomRightRadius:"0px",borderBottomWidth:"3px",borderLeftColor:"currentColor",borderLeftWidth:"3px",borderRightColor:"currentColor",borderRightWidth:"3px",borderSpacing:"2px",borderTopColor:"currentColor",borderTopLeftRadius:"0px",borderTopRightRadius:"0px",borderTopWidth:"3px",bottom:"auto",clip:"rect(0px, 0px, 0px, 0px)",color:"black",fontSize:"100%",fontWeight:"400",height:"auto",left:"auto",letterSpacing:"normal",lineHeight:"120%",marginBottom:"0px",marginLeft:"0px",marginRight:"0px",marginTop:"0px",maxHeight:"none",maxWidth:"none",minHeight:"0px",minWidth:"0px",opacity:"1.0",outlineColor:"invert",outlineOffset:"0px",outlineWidth:"3px",paddingBottom:"0px",paddingLeft:"0px",paddingRight:"0px",paddingTop:"0px",right:"auto",textIndent:"0px",textShadow:"0px 0px 0px transparent",top:"auto",transform:"",verticalAlign:"0px",visibility:"visible",width:"auto",wordSpacing:"normal",zIndex:"auto"};a.propertyInterpolation=d}(d,f),function(a,b){function c(b){var c=a.calculateActiveDuration(b),d=function(d){return a.calculateTimeFraction(c,d,b)};return d._totalDuration=b.delay+c+b.endDelay,d._isCurrent=function(d){var e=a.calculatePhase(c,d,b);return e===PhaseActive||e===PhaseBefore},d}b.KeyframeEffect=function(d,e,f){var g,h=c(a.normalizeTimingInput(f)),i=b.convertEffectInput(e),j=function(){i(d,g)};return j._update=function(a){return g=h(a),null!==g},j._clear=function(){i(d,null)},j._hasSameTarget=function(a){return d===a},j._isCurrent=h._isCurrent,j._totalDuration=h._totalDuration,j},b.NullEffect=function(a){var b=function(){a&&(a(),a=null)};return b._update=function(){return null},b._totalDuration=0,b._isCurrent=function(){return!1},b._hasSameTarget=function(){return!1},b}}(c,d,f),function(a){function b(a,b,c){c.enumerable=!0,c.configurable=!0,Object.defineProperty(a,b,c)}function c(a){this._surrogateStyle=document.createElementNS("http://www.w3.org/1999/xhtml","div").style,this._style=a.style,this._length=0,this._isAnimatedProperty={};for(var b=0;b<this._style.length;b++){var c=this._style[b];this._surrogateStyle[c]=this._style[c]}this._updateIndices()}function d(a){if(!a._webAnimationsPatchedStyle){var d=new c(a);try{b(a,"style",{get:function(){return d}})}catch(e){a.style._set=function(b,c){a.style[b]=c},a.style._clear=function(b){a.style[b]=""}}a._webAnimationsPatchedStyle=a.style}}var e={cssText:1,length:1,parentRule:1},f={getPropertyCSSValue:1,getPropertyPriority:1,getPropertyValue:1,item:1,removeProperty:1,setProperty:1},g={removeProperty:1,setProperty:1};c.prototype={get cssText(){return this._surrogateStyle.cssText},set cssText(a){for(var b={},c=0;c<this._surrogateStyle.length;c++)b[this._surrogateStyle[c]]=!0;this._surrogateStyle.cssText=a,this._updateIndices();for(var c=0;c<this._surrogateStyle.length;c++)b[this._surrogateStyle[c]]=!0;for(var d in b)this._isAnimatedProperty[d]||this._style.setProperty(d,this._surrogateStyle.getPropertyValue(d))},get length(){return this._surrogateStyle.length},get parentRule(){return this._style.parentRule},_updateIndices:function(){for(;this._length<this._surrogateStyle.length;)Object.defineProperty(this,this._length,{configurable:!0,enumerable:!1,get:function(a){return function(){return this._surrogateStyle[a]}}(this._length)}),this._length++;for(;this._length>this._surrogateStyle.length;)this._length--,Object.defineProperty(this,this._length,{configurable:!0,enumerable:!1,value:void 0})},_set:function(a,b){this._style[a]=b,this._isAnimatedProperty[a]=!0},_clear:function(a){this._style[a]=this._surrogateStyle[a],delete this._isAnimatedProperty[a]}};for(var h in f)c.prototype[h]=function(a,b){return function(){var c=this._surrogateStyle[a].apply(this._surrogateStyle,arguments);return b&&(this._isAnimatedProperty[arguments[0]]||this._style[a].apply(this._style,arguments),this._updateIndices()),c}}(h,h in g);for(var i in document.documentElement.style)i in e||i in f||!function(a){b(c.prototype,a,{get:function(){return this._surrogateStyle[a]},set:function(b){this._surrogateStyle[a]=b,this._updateIndices(),this._isAnimatedProperty[a]||(this._style[a]=b)}})}(i);a.apply=function(b,c,e){d(b),b.style._set(a.propertyName(c),e)},a.clear=function(b,c){b._webAnimationsPatchedStyle&&b.style._clear(a.propertyName(c))}}(d,f),function(a){window.Element.prototype.animate=function(b,c){return a.timeline._play(a.KeyframeEffect(this,b,c))}}(d),function(a){function b(a,c,d){if("number"==typeof a&&"number"==typeof c)return a*(1-d)+c*d;if("boolean"==typeof a&&"boolean"==typeof c)return.5>d?a:c;if(a.length==c.length){for(var e=[],f=0;f<a.length;f++)e.push(b(a[f],c[f],d));return e}throw"Mismatched interpolation arguments "+a+":"+c}a.Interpolation=function(a,c,d){return function(e){return d(b(a,c,e))}}}(d,f),function(a){function b(a,b,c){return Math.max(Math.min(a,c),b)}function c(c,d,e){var f=a.dot(c,d);f=b(f,-1,1);var g=[];if(1===f)g=c;else for(var h=Math.acos(f),i=1*Math.sin(e*h)/Math.sqrt(1-f*f),j=0;4>j;j++)g.push(c[j]*(Math.cos(e*h)-f*i)+d[j]*i);return g}var d=function(){function a(a,b){for(var c=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],d=0;4>d;d++)for(var e=0;4>e;e++)for(var f=0;4>f;f++)c[d][e]+=b[d][f]*a[f][e];return c}function b(a){return 0==a[0][2]&&0==a[0][3]&&0==a[1][2]&&0==a[1][3]&&0==a[2][0]&&0==a[2][1]&&1==a[2][2]&&0==a[2][3]&&0==a[3][2]&&1==a[3][3]}function c(c,d,e,f,g){for(var h=[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]],i=0;4>i;i++)h[i][3]=g[i];for(var i=0;3>i;i++)for(var j=0;3>j;j++)h[3][i]+=c[j]*h[j][i];var k=f[0],l=f[1],m=f[2],n=f[3],o=[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]];o[0][0]=1-2*(l*l+m*m),o[0][1]=2*(k*l-m*n),o[0][2]=2*(k*m+l*n),o[1][0]=2*(k*l+m*n),o[1][1]=1-2*(k*k+m*m),o[1][2]=2*(l*m-k*n),o[2][0]=2*(k*m-l*n),o[2][1]=2*(l*m+k*n),o[2][2]=1-2*(k*k+l*l),h=a(h,o);var p=[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]];e[2]&&(p[2][1]=e[2],h=a(h,p)),e[1]&&(p[2][1]=0,p[2][0]=e[0],h=a(h,p)),e[0]&&(p[2][0]=0,p[1][0]=e[0],h=a(h,p));for(var i=0;3>i;i++)for(var j=0;3>j;j++)h[i][j]*=d[i];return b(h)?[h[0][0],h[0][1],h[1][0],h[1][1],h[3][0],h[3][1]]:h[0].concat(h[1],h[2],h[3])}return c}();a.composeMatrix=d,a.quat=c}(d,f),function(a,b){a.sequenceNumber=0;var c=function(a,b,c){this.target=a,this.currentTime=b,this.timelineTime=c,this.type="finish",this.bubbles=!1,this.cancelable=!1,this.currentTarget=a,this.defaultPrevented=!1,this.eventPhase=Event.AT_TARGET,this.timeStamp=Date.now()};b.Animation=function(b){this._sequenceNumber=a.sequenceNumber++,this._currentTime=0,this._startTime=null,this._paused=!1,this._playbackRate=1,this._inTimeline=!0,this._finishedFlag=!1,this.onfinish=null,this._finishHandlers=[],this._effect=b,this._inEffect=this._effect._update(0),this._idle=!0,this._currentTimePending=!1},b.Animation.prototype={_ensureAlive:function(){this._inEffect=this._effect._update(this.playbackRate<0&&0===this.currentTime?-1:this.currentTime),this._inTimeline||!this._inEffect&&this._finishedFlag||(this._inTimeline=!0,b.timeline._animations.push(this))},_tickCurrentTime:function(a,b){a!=this._currentTime&&(this._currentTime=a,this._isFinished&&!b&&(this._currentTime=this._playbackRate>0?this._totalDuration:0),this._ensureAlive())},get currentTime(){return this._idle||this._currentTimePending?null:this._currentTime},set currentTime(a){a=+a,isNaN(a)||(b.restart(),this._paused||null==this._startTime||(this._startTime=this._timeline.currentTime-a/this._playbackRate),this._currentTimePending=!1,this._currentTime!=a&&(this._tickCurrentTime(a,!0),b.invalidateEffects()))},get startTime(){return this._startTime},set startTime(a){a=+a,isNaN(a)||this._paused||this._idle||(this._startTime=a,this._tickCurrentTime((this._timeline.currentTime-this._startTime)*this.playbackRate),b.invalidateEffects())},get playbackRate(){return this._playbackRate},set playbackRate(a){if(a!=this._playbackRate){var b=this.currentTime;this._playbackRate=a,this._startTime=null,"paused"!=this.playState&&"idle"!=this.playState&&this.play(),null!=b&&(this.currentTime=b)}},get _isFinished(){return!this._idle&&(this._playbackRate>0&&this._currentTime>=this._totalDuration||this._playbackRate<0&&this._currentTime<=0)},get _totalDuration(){return this._effect._totalDuration},get playState(){return this._idle?"idle":null==this._startTime&&!this._paused&&0!=this.playbackRate||this._currentTimePending?"pending":this._paused?"paused":this._isFinished?"finished":"running"},play:function(){this._paused=!1,(this._isFinished||this._idle)&&(this._currentTime=this._playbackRate>0?0:this._totalDuration,this._startTime=null,b.invalidateEffects()),this._finishedFlag=!1,b.restart(),this._idle=!1,this._ensureAlive()},pause:function(){this._isFinished||this._paused||this._idle||(this._currentTimePending=!0),this._startTime=null,this._paused=!0},finish:function(){this._idle||(this.currentTime=this._playbackRate>0?this._totalDuration:0,this._startTime=this._totalDuration-this.currentTime,this._currentTimePending=!1)},cancel:function(){this._inEffect&&(this._inEffect=!1,this._idle=!0,this.currentTime=0,this._startTime=null,this._effect._update(null),b.invalidateEffects(),b.restart())},reverse:function(){this.playbackRate*=-1,this.play()},addEventListener:function(a,b){"function"==typeof b&&"finish"==a&&this._finishHandlers.push(b)},removeEventListener:function(a,b){if("finish"==a){var c=this._finishHandlers.indexOf(b);c>=0&&this._finishHandlers.splice(c,1)}},_fireEvents:function(a){var b=this._isFinished;if((b||this._idle)&&!this._finishedFlag){var d=new c(this,this._currentTime,a),e=this._finishHandlers.concat(this.onfinish?[this.onfinish]:[]);setTimeout(function(){e.forEach(function(a){a.call(d.target,d)})},0)}this._finishedFlag=b},_tick:function(a){return this._idle||this._paused||(null==this._startTime?this.startTime=a-this._currentTime/this.playbackRate:this._isFinished||this._tickCurrentTime((a-this._startTime)*this.playbackRate)),this._currentTimePending=!1,this._fireEvents(a),!this._idle&&(this._inEffect||!this._finishedFlag)}}}(c,d,f),function(a,b){function c(a){var b=i;i=[],a<s.currentTime&&(a=s.currentTime),g(a),b.forEach(function(b){b[1](a)}),o&&g(a),f(),l=void 0}function d(a,b){return a._sequenceNumber-b._sequenceNumber}function e(){this._animations=[],this.currentTime=window.performance&&performance.now?performance.now():0}function f(){p.forEach(function(a){a()}),p.length=0}function g(a){n=!1;var c=b.timeline;c.currentTime=a,c._animations.sort(d),m=!1;var e=c._animations;c._animations=[];var f=[],g=[];e=e.filter(function(b){return b._inTimeline=b._tick(a),b._inEffect?g.push(b._effect):f.push(b._effect),b._isFinished||b._paused||b._idle||(m=!0),b._inTimeline}),p.push.apply(p,f),p.push.apply(p,g),c._animations.push.apply(c._animations,e),o=!1,m&&requestAnimationFrame(function(){})}var h=window.requestAnimationFrame,i=[],j=0;window.requestAnimationFrame=function(a){var b=j++;return 0==i.length&&h(c),i.push([b,a]),b},window.cancelAnimationFrame=function(a){i.forEach(function(b){b[0]==a&&(b[1]=function(){})})},e.prototype={_play:function(c){c._timing=a.normalizeTimingInput(c.timing);var d=new b.Animation(c);return d._idle=!1,d._timeline=this,this._animations.push(d),b.restart(),b.invalidateEffects(),d}};var k,l=void 0,k=function(){return void 0==l&&(l=performance.now()),l},m=!1,n=!1;b.restart=function(){return m||(m=!0,requestAnimationFrame(function(){}),n=!0),n};var o=!1;b.invalidateEffects=function(){o=!0};var p=[],q=1e3/60,r=window.getComputedStyle;Object.defineProperty(window,"getComputedStyle",{configurable:!0,enumerable:!0,value:function(){if(o){var a=k();a-s.currentTime>0&&(s.currentTime+=q*(Math.floor((a-s.currentTime)/q)+1)),g(s.currentTime)}return f(),r.apply(this,arguments)}});var s=new e;b.timeline=s}(c,d,f),function(a){function b(a,b){for(var c=0,d=0;d<a.length;d++)c+=a[d]*b[d];return c}function c(a,b){return[a[0]*b[0]+a[4]*b[1]+a[8]*b[2]+a[12]*b[3],a[1]*b[0]+a[5]*b[1]+a[9]*b[2]+a[13]*b[3],a[2]*b[0]+a[6]*b[1]+a[10]*b[2]+a[14]*b[3],a[3]*b[0]+a[7]*b[1]+a[11]*b[2]+a[15]*b[3],a[0]*b[4]+a[4]*b[5]+a[8]*b[6]+a[12]*b[7],a[1]*b[4]+a[5]*b[5]+a[9]*b[6]+a[13]*b[7],a[2]*b[4]+a[6]*b[5]+a[10]*b[6]+a[14]*b[7],a[3]*b[4]+a[7]*b[5]+a[11]*b[6]+a[15]*b[7],a[0]*b[8]+a[4]*b[9]+a[8]*b[10]+a[12]*b[11],a[1]*b[8]+a[5]*b[9]+a[9]*b[10]+a[13]*b[11],a[2]*b[8]+a[6]*b[9]+a[10]*b[10]+a[14]*b[11],a[3]*b[8]+a[7]*b[9]+a[11]*b[10]+a[15]*b[11],a[0]*b[12]+a[4]*b[13]+a[8]*b[14]+a[12]*b[15],a[1]*b[12]+a[5]*b[13]+a[9]*b[14]+a[13]*b[15],a[2]*b[12]+a[6]*b[13]+a[10]*b[14]+a[14]*b[15],a[3]*b[12]+a[7]*b[13]+a[11]*b[14]+a[15]*b[15]]}function d(a){switch(a.t){case"rotatex":var b=a.d[0].rad||0,c=a.d[0].deg||0,d=c*Math.PI/180+b;return[1,0,0,0,0,Math.cos(d),Math.sin(d),0,0,-Math.sin(d),Math.cos(d),0,0,0,0,1];case"rotatey":var b=a.d[0].rad||0,c=a.d[0].deg||0,d=c*Math.PI/180+b;return[Math.cos(d),0,-Math.sin(d),0,0,1,0,0,Math.sin(d),0,Math.cos(d),0,0,0,0,1];case"rotate":case"rotatez":var b=a.d[0].rad||0,c=a.d[0].deg||0,d=c*Math.PI/180+b;return[Math.cos(d),Math.sin(d),0,0,-Math.sin(d),Math.cos(d),0,0,0,0,1,0,0,0,0,1];case"rotate3d":var e=a.d[0],f=a.d[1],g=a.d[2],b=a.d[3].rad||0,c=a.d[3].deg||0,d=c*Math.PI/180+b,h=e*e+f*f+g*g;if(0===h)e=1,f=0,g=0;else if(1!==h){var i=Math.sqrt(h);e/=i,f/=i,g/=i}var j=Math.sin(d/2),k=j*Math.cos(d/2),l=j*j;return[1-2*(f*f+g*g)*l,2*(e*f*l+g*k),2*(e*g*l-f*k),0,2*(e*f*l-g*k),1-2*(e*e+g*g)*l,2*(f*g*l+e*k),0,2*(e*g*l+f*k),2*(f*g*l-e*k),1-2*(e*e+f*f)*l,0,0,0,0,1];case"scale":return[a.d[0],0,0,0,0,a.d[1],0,0,0,0,1,0,0,0,0,1];case"scalex":return[a.d[0],0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];case"scaley":return[1,0,0,0,0,a.d[0],0,0,0,0,1,0,0,0,0,1];case"scalez":return[1,0,0,0,0,1,0,0,0,0,a.d[0],0,0,0,0,1];case"scale3d":return[a.d[0],0,0,0,0,a.d[1],0,0,0,0,a.d[2],0,0,0,0,1];case"skew":var m=a.d[0].deg||0,n=a.d[0].rad||0,o=a.d[1].deg||0,p=a.d[1].rad||0,q=m*Math.PI/180+n,r=o*Math.PI/180+p;return[1,Math.tan(r),0,0,Math.tan(q),1,0,0,0,0,1,0,0,0,0,1];case"skewx":var b=a.d[0].rad||0,c=a.d[0].deg||0,d=c*Math.PI/180+b;return[1,0,0,0,Math.tan(d),1,0,0,0,0,1,0,0,0,0,1];case"skewy":var b=a.d[0].rad||0,c=a.d[0].deg||0,d=c*Math.PI/180+b;return[1,Math.tan(d),0,0,0,1,0,0,0,0,1,0,0,0,0,1];case"translate":var e=a.d[0].px||0,f=a.d[1].px||0;return[1,0,0,0,0,1,0,0,0,0,1,0,e,f,0,1];case"translatex":var e=a.d[0].px||0;return[1,0,0,0,0,1,0,0,0,0,1,0,e,0,0,1];case"translatey":var f=a.d[0].px||0;return[1,0,0,0,0,1,0,0,0,0,1,0,0,f,0,1];case"translatez":var g=a.d[0].px||0;return[1,0,0,0,0,1,0,0,0,0,1,0,0,0,g,1];case"translate3d":var e=a.d[0].px||0,f=a.d[1].px||0,g=a.d[2].px||0;return[1,0,0,0,0,1,0,0,0,0,1,0,e,f,g,1];case"perspective":var s=a.d[0].px?-1/a.d[0].px:0;return[1,0,0,0,0,1,0,0,0,0,1,s,0,0,0,1];case"matrix":return[a.d[0],a.d[1],0,0,a.d[2],a.d[3],0,0,0,0,1,0,a.d[4],a.d[5],0,1];case"matrix3d":return a.d}}function e(a){return 0===a.length?[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]:a.map(d).reduce(c)}function f(a){return[g(e(a))]}var g=function(){function a(a){return a[0][0]*a[1][1]*a[2][2]+a[1][0]*a[2][1]*a[0][2]+a[2][0]*a[0][1]*a[1][2]-a[0][2]*a[1][1]*a[2][0]-a[1][2]*a[2][1]*a[0][0]-a[2][2]*a[0][1]*a[1][0]}function c(b){for(var c=1/a(b),d=b[0][0],e=b[0][1],f=b[0][2],g=b[1][0],h=b[1][1],i=b[1][2],j=b[2][0],k=b[2][1],l=b[2][2],m=[[(h*l-i*k)*c,(f*k-e*l)*c,(e*i-f*h)*c,0],[(i*j-g*l)*c,(d*l-f*j)*c,(f*g-d*i)*c,0],[(g*k-h*j)*c,(j*e-d*k)*c,(d*h-e*g)*c,0]],n=[],o=0;3>o;o++){for(var p=0,q=0;3>q;q++)p+=b[3][q]*m[q][o];n.push(p)}return n.push(1),m.push(n),m}function d(a){return[[a[0][0],a[1][0],a[2][0],a[3][0]],[a[0][1],a[1][1],a[2][1],a[3][1]],[a[0][2],a[1][2],a[2][2],a[3][2]],[a[0][3],a[1][3],a[2][3],a[3][3]]]}function e(a,b){for(var c=[],d=0;4>d;d++){for(var e=0,f=0;4>f;f++)e+=a[f]*b[f][d];c.push(e)}return c}function f(a){var b=g(a);return[a[0]/b,a[1]/b,a[2]/b]}function g(a){return Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2])}function h(a,b,c,d){return[c*a[0]+d*b[0],c*a[1]+d*b[1],c*a[2]+d*b[2]]}function i(a,b){return[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]]}function j(j){var k=[j.slice(0,4),j.slice(4,8),j.slice(8,12),j.slice(12,16)];if(1!==k[3][3])return null;for(var l=[],m=0;4>m;m++)l.push(k[m].slice());for(var m=0;3>m;m++)l[m][3]=0;if(0===a(l))return!1;var n,o=[];if(k[0][3]||k[1][3]||k[2][3]){o.push(k[0][3]),o.push(k[1][3]),o.push(k[2][3]),o.push(k[3][3]);var p=c(l),q=d(p);n=e(o,q)}else n=[0,0,0,1];var r=k[3].slice(0,3),s=[];s.push(k[0].slice(0,3));var t=[];t.push(g(s[0])),s[0]=f(s[0]);var u=[];s.push(k[1].slice(0,3)),u.push(b(s[0],s[1])),s[1]=h(s[1],s[0],1,-u[0]),t.push(g(s[1])),s[1]=f(s[1]),u[0]/=t[1],s.push(k[2].slice(0,3)),u.push(b(s[0],s[2])),s[2]=h(s[2],s[0],1,-u[1]),u.push(b(s[1],s[2])),s[2]=h(s[2],s[1],1,-u[2]),t.push(g(s[2])),s[2]=f(s[2]),u[1]/=t[2],u[2]/=t[2];var v=i(s[1],s[2]);if(b(s[0],v)<0)for(var m=0;3>m;m++)t[m]*=-1,s[m][0]*=-1,s[m][1]*=-1,s[m][2]*=-1;var w,x,y=s[0][0]+s[1][1]+s[2][2]+1;return y>1e-4?(w=.5/Math.sqrt(y),x=[(s[2][1]-s[1][2])*w,(s[0][2]-s[2][0])*w,(s[1][0]-s[0][1])*w,.25/w]):s[0][0]>s[1][1]&&s[0][0]>s[2][2]?(w=2*Math.sqrt(1+s[0][0]-s[1][1]-s[2][2]),x=[.25*w,(s[0][1]+s[1][0])/w,(s[0][2]+s[2][0])/w,(s[2][1]-s[1][2])/w]):s[1][1]>s[2][2]?(w=2*Math.sqrt(1+s[1][1]-s[0][0]-s[2][2]),x=[(s[0][1]+s[1][0])/w,.25*w,(s[1][2]+s[2][1])/w,(s[0][2]-s[2][0])/w]):(w=2*Math.sqrt(1+s[2][2]-s[0][0]-s[1][1]),x=[(s[0][2]+s[2][0])/w,(s[1][2]+s[2][1])/w,.25*w,(s[1][0]-s[0][1])/w]),[r,t,u,x,n]}return j}();a.dot=b,a.makeMatrixDecomposition=f}(d,f),function(a){function b(a,b){var c=a.exec(b);return c?(c=a.ignoreCase?c[0].toLowerCase():c[0],[c,b.substr(c.length)]):void 0}function c(a,b){b=b.replace(/^\s*/,"");var c=a(b);return c?[c[0],c[1].replace(/^\s*/,"")]:void 0}function d(a,d,e){a=c.bind(null,a);for(var f=[];;){var g=a(e);if(!g)return[f,e];if(f.push(g[0]),e=g[1],g=b(d,e),!g||""==g[1])return[f,e];e=g[1]}}function e(a,b){for(var c=0,d=0;d<b.length&&(!/\s|,/.test(b[d])||0!=c);d++)if("("==b[d])c++;else if(")"==b[d]&&(c--,0==c&&d++,0>=c))break;var e=a(b.substr(0,d));return void 0==e?void 0:[e,b.substr(d)]}function f(a,b){for(var c=a,d=b;c&&d;)c>d?c%=d:d%=c;return c=a*b/(c+d)}function g(a){return function(b){var c=a(b);return c&&(c[0]=void 0),c}}function h(a,b){return function(c){var d=a(c);return d?d:[b,c]}}function i(b,c){for(var d=[],e=0;e<b.length;e++){var f=a.consumeTrimmed(b[e],c);if(!f||""==f[0])return;void 0!==f[0]&&d.push(f[0]),c=f[1]}return""==c?d:void 0}function j(a,b,c,d,e){for(var g=[],h=[],i=[],j=f(d.length,e.length),k=0;j>k;k++){var l=b(d[k%d.length],e[k%e.length]);if(!l)return;g.push(l[0]),h.push(l[1]),i.push(l[2])}return[g,h,function(b){var d=b.map(function(a,b){return i[b](a)}).join(c);return a?a(d):d}]}function k(a,b,c){for(var d=[],e=[],f=[],g=0,h=0;h<c.length;h++)if("function"==typeof c[h]){var i=c[h](a[g],b[g++]);d.push(i[0]),e.push(i[1]),f.push(i[2])}else!function(a){d.push(!1),e.push(!1),f.push(function(){return c[a]})}(h);return[d,e,function(a){for(var b="",c=0;c<a.length;c++)b+=f[c](a[c]);return b}]}a.consumeToken=b,a.consumeTrimmed=c,a.consumeRepeated=d,a.consumeParenthesised=e,a.ignore=g,a.optional=h,a.consumeList=i,a.mergeNestedRepeated=j.bind(null,null),a.mergeWrappedNestedRepeated=j,a.mergeList=k}(d),function(a){function b(b){function c(b){var c=a.consumeToken(/^inset/i,b);if(c)return d.inset=!0,c;var c=a.consumeLengthOrPercent(b);if(c)return d.lengths.push(c[0]),c;var c=a.consumeColor(b);return c?(d.color=c[0],c):void 0}var d={inset:!1,lengths:[],color:null},e=a.consumeRepeated(c,/^/,b);return e&&e[0].length?[d,e[1]]:void 0}function c(c){var d=a.consumeRepeated(b,/^,/,c);return d&&""==d[1]?d[0]:void 0}function d(b,c){for(;b.lengths.length<Math.max(b.lengths.length,c.lengths.length);)b.lengths.push({px:0});for(;c.lengths.length<Math.max(b.lengths.length,c.lengths.length);)c.lengths.push({px:0});if(b.inset==c.inset&&!!b.color==!!c.color){for(var d,e=[],f=[[],0],g=[[],0],h=0;h<b.lengths.length;h++){var i=a.mergeDimensions(b.lengths[h],c.lengths[h],2==h);f[0].push(i[0]),g[0].push(i[1]),e.push(i[2])}if(b.color&&c.color){var j=a.mergeColors(b.color,c.color);f[1]=j[0],g[1]=j[1],d=j[2]}return[f,g,function(a){for(var c=b.inset?"inset ":" ",f=0;f<e.length;f++)c+=e[f](a[0][f])+" ";return d&&(c+=d(a[1])),c}]}}function e(b,c,d,e){function f(a){return{inset:a,color:[0,0,0,0],lengths:[{px:0},{px:0},{px:0},{px:0}]}}for(var g=[],h=[],i=0;i<d.length||i<e.length;i++){var j=d[i]||f(e[i].inset),k=e[i]||f(d[i].inset);g.push(j),h.push(k)}return a.mergeNestedRepeated(b,c,g,h)}var f=e.bind(null,d,", ");a.addPropertiesHandler(c,f,["box-shadow","text-shadow"])}(d),function(a){function b(a){return a.toFixed(3).replace(".000","")}function c(a,b,c){return Math.min(b,Math.max(a,c))}function d(a){return/^\s*[-+]?(\d*\.)?\d+\s*$/.test(a)?Number(a):void 0}function e(a,c){return[a,c,b]}function f(a,b){return 0!=a?h(0,1/0)(a,b):void 0}function g(a,b){return[a,b,function(a){return Math.round(c(1,1/0,a))}]}function h(a,d){return function(e,f){return[e,f,function(e){return b(c(a,d,e))}]}}function i(a,b){return[a,b,Math.round]}a.clamp=c,a.addPropertiesHandler(d,h(0,1/0),["border-image-width","line-height"]),a.addPropertiesHandler(d,h(0,1),["opacity","shape-image-threshold"]),a.addPropertiesHandler(d,f,["flex-grow","flex-shrink"]),a.addPropertiesHandler(d,g,["orphans","widows"]),a.addPropertiesHandler(d,i,["z-index"]),a.parseNumber=d,a.mergeNumbers=e,a.numberToString=b}(d,f),function(a){function b(a,b){return"visible"==a||"visible"==b?[0,1,function(c){return 0>=c?a:c>=1?b:"visible"}]:void 0}a.addPropertiesHandler(String,b,["visibility"])}(d),function(a){function b(a){a=a.trim(),e.fillStyle="#000",e.fillStyle=a;var b=e.fillStyle;if(e.fillStyle="#fff",e.fillStyle=a,b==e.fillStyle){e.fillRect(0,0,1,1);var c=e.getImageData(0,0,1,1).data;e.clearRect(0,0,1,1);var d=c[3]/255;return[c[0]*d,c[1]*d,c[2]*d,d]}}function c(b,c){return[b,c,function(b){function c(a){return Math.max(0,Math.min(255,a))}if(b[3])for(var d=0;3>d;d++)b[d]=Math.round(c(b[d]/b[3]));return b[3]=a.numberToString(a.clamp(0,1,b[3])),"rgba("+b.join(",")+")"}]}var d=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");d.width=d.height=1;var e=d.getContext("2d");a.addPropertiesHandler(b,c,["background-color","border-bottom-color","border-left-color","border-right-color","border-top-color","color","outline-color","text-decoration-color"]),a.consumeColor=a.consumeParenthesised.bind(null,b),a.mergeColors=c}(d,f),function(a,b){function c(a,b){if(b=b.trim().toLowerCase(),"0"==b&&"px".search(a)>=0)return{px:0};if(/^[^(]*$|^calc/.test(b)){b=b.replace(/calc\(/g,"(");var c={};b=b.replace(a,function(a){return c[a]=null,"U"+a});for(var d="U("+a.source+")",e=b.replace(/[-+]?(\d*\.)?\d+/g,"N").replace(new RegExp("N"+d,"g"),"D").replace(/\s[+-]\s/g,"O").replace(/\s/g,""),f=[/N\*(D)/g,/(N|D)[*/]N/g,/(N|D)O\1/g,/\((N|D)\)/g],g=0;g<f.length;)f[g].test(e)?(e=e.replace(f[g],"$1"),g=0):g++;if("D"==e){for(var h in c){var i=eval(b.replace(new RegExp("U"+h,"g"),"").replace(new RegExp(d,"g"),"*0"));if(!isFinite(i))return;c[h]=i}return c}}}function d(a,b){return e(a,b,!0)}function e(b,c,d){var e,f=[];for(e in b)f.push(e);for(e in c)f.indexOf(e)<0&&f.push(e);return b=f.map(function(a){return b[a]||0}),c=f.map(function(a){return c[a]||0}),[b,c,function(b){var c=b.map(function(c,e){return 1==b.length&&d&&(c=Math.max(c,0)),a.numberToString(c)+f[e]}).join(" + ");return b.length>1?"calc("+c+")":c}]}var f="px|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc",g=c.bind(null,new RegExp(f,"g")),h=c.bind(null,new RegExp(f+"|%","g")),i=c.bind(null,/deg|rad|grad|turn/g);a.parseLength=g,a.parseLengthOrPercent=h,a.consumeLengthOrPercent=a.consumeParenthesised.bind(null,h),a.parseAngle=i,a.mergeDimensions=e;
+var j=a.consumeParenthesised.bind(null,g),k=a.consumeRepeated.bind(void 0,j,/^/),l=a.consumeRepeated.bind(void 0,k,/^,/);a.consumeSizePairList=l;var m=function(a){var b=l(a);return b&&""==b[1]?b[0]:void 0},n=a.mergeNestedRepeated.bind(void 0,d," "),o=a.mergeNestedRepeated.bind(void 0,n,",");a.mergeNonNegativeSizePair=n,a.addPropertiesHandler(m,o,["background-size"]),a.addPropertiesHandler(h,d,["border-bottom-width","border-image-width","border-left-width","border-right-width","border-top-width","flex-basis","font-size","height","line-height","max-height","max-width","outline-width","width"]),a.addPropertiesHandler(h,e,["border-bottom-left-radius","border-bottom-right-radius","border-top-left-radius","border-top-right-radius","bottom","left","letter-spacing","margin-bottom","margin-left","margin-right","margin-top","min-height","min-width","outline-offset","padding-bottom","padding-left","padding-right","padding-top","perspective","right","shape-margin","text-indent","top","vertical-align","word-spacing"])}(d,f),function(a){function b(b){return a.consumeLengthOrPercent(b)||a.consumeToken(/^auto/,b)}function c(c){var d=a.consumeList([a.ignore(a.consumeToken.bind(null,/^rect/)),a.ignore(a.consumeToken.bind(null,/^\(/)),a.consumeRepeated.bind(null,b,/^,/),a.ignore(a.consumeToken.bind(null,/^\)/))],c);return d&&4==d[0].length?d[0]:void 0}function d(b,c){return"auto"==b||"auto"==c?[!0,!1,function(d){var e=d?b:c;if("auto"==e)return"auto";var f=a.mergeDimensions(e,e);return f[2](f[0])}]:a.mergeDimensions(b,c)}function e(a){return"rect("+a+")"}var f=a.mergeWrappedNestedRepeated.bind(null,e,d,", ");a.parseBox=c,a.mergeBoxes=f,a.addPropertiesHandler(c,f,["clip"])}(d,f),function(a){function b(a){return function(b){var c=0;return a.map(function(a){return a===j?b[c++]:a})}}function c(a){return a}function d(b){if(b=b.toLowerCase().trim(),"none"==b)return[];for(var c,d=/\s*(\w+)\(([^)]*)\)/g,e=[],f=0;c=d.exec(b);){if(c.index!=f)return;f=c.index+c[0].length;var g=c[1],h=m[g];if(!h)return;var i=c[2].split(","),j=h[0];if(j.length<i.length)return;for(var n=[],o=0;o<j.length;o++){var p,q=i[o],r=j[o];if(p=q?{A:function(b){return"0"==b.trim()?l:a.parseAngle(b)},N:a.parseNumber,T:a.parseLengthOrPercent,L:a.parseLength}[r.toUpperCase()](q):{a:l,n:n[0],t:k}[r],void 0===p)return;n.push(p)}if(e.push({t:g,d:n}),d.lastIndex==b.length)return e}}function e(a){return a.toFixed(6).replace(".000000","")}function f(b,c){if(b.decompositionPair!==c){b.decompositionPair=c;var d=a.makeMatrixDecomposition(b)}if(c.decompositionPair!==b){c.decompositionPair=b;var f=a.makeMatrixDecomposition(c)}return null==d[0]||null==f[0]?[[!1],[!0],function(a){return a?c[0].d:b[0].d}]:(d[0].push(0),f[0].push(1),[d,f,function(b){var c=a.quat(d[0][3],f[0][3],b[5]),g=a.composeMatrix(b[0],b[1],b[2],c,b[4]),h=g.map(e).join(",");return h}])}function g(a){return a.replace(/[xy]/,"")}function h(a){return a.replace(/(x|y|z|3d)?$/,"3d")}function i(b,c){var d=a.makeMatrixDecomposition&&!0,e=!1;if(!b.length||!c.length){b.length||(e=!0,b=c,c=[]);for(var i=0;i<b.length;i++){var j=b[i].t,k=b[i].d,l="scale"==j.substr(0,5)?1:0;c.push({t:j,d:k.map(function(a){if("number"==typeof a)return l;var b={};for(var c in a)b[c]=l;return b})})}}var n=function(a,b){return"perspective"==a&&"perspective"==b||("matrix"==a||"matrix3d"==a)&&("matrix"==b||"matrix3d"==b)},o=[],p=[],q=[];if(b.length!=c.length){if(!d)return;var r=f(b,c);o=[r[0]],p=[r[1]],q=[["matrix",[r[2]]]]}else for(var i=0;i<b.length;i++){var j,s=b[i].t,t=c[i].t,u=b[i].d,v=c[i].d,w=m[s],x=m[t];if(n(s,t)){if(!d)return;var r=f([b[i]],[c[i]]);o.push(r[0]),p.push(r[1]),q.push(["matrix",[r[2]]])}else{if(s==t)j=s;else if(w[2]&&x[2]&&g(s)==g(t))j=g(s),u=w[2](u),v=x[2](v);else{if(!w[1]||!x[1]||h(s)!=h(t)){if(!d)return;var r=f(b,c);o=[r[0]],p=[r[1]],q=[["matrix",[r[2]]]];break}j=h(s),u=w[1](u),v=x[1](v)}for(var y=[],z=[],A=[],B=0;B<u.length;B++){var C="number"==typeof u[B]?a.mergeNumbers:a.mergeDimensions,r=C(u[B],v[B]);y[B]=r[0],z[B]=r[1],A.push(r[2])}o.push(y),p.push(z),q.push([j,A])}}if(e){var D=o;o=p,p=D}return[o,p,function(a){return a.map(function(a,b){var c=a.map(function(a,c){return q[b][1][c](a)}).join(",");return"matrix"==q[b][0]&&16==c.split(",").length&&(q[b][0]="matrix3d"),q[b][0]+"("+c+")"}).join(" ")}]}var j=null,k={px:0},l={deg:0},m={matrix:["NNNNNN",[j,j,0,0,j,j,0,0,0,0,1,0,j,j,0,1],c],matrix3d:["NNNNNNNNNNNNNNNN",c],rotate:["A"],rotatex:["A"],rotatey:["A"],rotatez:["A"],rotate3d:["NNNA"],perspective:["L"],scale:["Nn",b([j,j,1]),c],scalex:["N",b([j,1,1]),b([j,1])],scaley:["N",b([1,j,1]),b([1,j])],scalez:["N",b([1,1,j])],scale3d:["NNN",c],skew:["Aa",null,c],skewx:["A",null,b([j,l])],skewy:["A",null,b([l,j])],translate:["Tt",b([j,j,k]),c],translatex:["T",b([j,k,k]),b([j,k])],translatey:["T",b([k,j,k]),b([k,j])],translatez:["L",b([k,k,j])],translate3d:["TTL",c]};a.addPropertiesHandler(d,i,["transform"])}(d,f),function(a){function b(a){var b=Number(a);return isNaN(b)||100>b||b>900||b%100!==0?void 0:b}function c(b){return b=100*Math.round(b/100),b=a.clamp(100,900,b),400===b?"normal":700===b?"bold":String(b)}function d(a,b){return[a,b,c]}a.addPropertiesHandler(b,d,["font-weight"])}(d),function(a){function b(a){var b={};for(var c in a)b[c]=-a[c];return b}function c(b){return a.consumeToken(/^(left|center|right|top|bottom)\b/i,b)||a.consumeLengthOrPercent(b)}function d(b,d){var e=a.consumeRepeated(c,/^/,d);if(e&&""==e[1]){var f=e[0];if(f[0]=f[0]||"center",f[1]=f[1]||"center",3==b&&(f[2]=f[2]||{px:0}),f.length==b){if(/top|bottom/.test(f[0])||/left|right/.test(f[1])){var h=f[0];f[0]=f[1],f[1]=h}if(/left|right|center|Object/.test(f[0])&&/top|bottom|center|Object/.test(f[1]))return f.map(function(a){return"object"==typeof a?a:g[a]})}}}function e(d){var e=a.consumeRepeated(c,/^/,d);if(e){for(var f=e[0],h=[{"%":50},{"%":50}],i=0,j=!1,k=0;k<f.length;k++){var l=f[k];"string"==typeof l?(j=/bottom|right/.test(l),i={left:0,right:0,center:i,top:1,bottom:1}[l],h[i]=g[l],"center"==l&&i++):(j&&(l=b(l),l["%"]=(l["%"]||0)+100),h[i]=l,i++,j=!1)}return[h,e[1]]}}function f(b){var c=a.consumeRepeated(e,/^,/,b);return c&&""==c[1]?c[0]:void 0}var g={left:{"%":0},center:{"%":50},right:{"%":100},top:{"%":0},bottom:{"%":100}},h=a.mergeNestedRepeated.bind(null,a.mergeDimensions," ");a.addPropertiesHandler(d.bind(null,3),h,["transform-origin"]),a.addPropertiesHandler(d.bind(null,2),h,["perspective-origin"]),a.consumePosition=e,a.mergeOffsetList=h;var i=a.mergeNestedRepeated.bind(null,h,", ");a.addPropertiesHandler(f,i,["background-position","object-position"])}(d),function(a){function b(b){var c=a.consumeToken(/^circle/,b);if(c&&c[0])return["circle"].concat(a.consumeList([a.ignore(a.consumeToken.bind(void 0,/^\(/)),d,a.ignore(a.consumeToken.bind(void 0,/^at/)),a.consumePosition,a.ignore(a.consumeToken.bind(void 0,/^\)/))],c[1]));var f=a.consumeToken(/^ellipse/,b);if(f&&f[0])return["ellipse"].concat(a.consumeList([a.ignore(a.consumeToken.bind(void 0,/^\(/)),e,a.ignore(a.consumeToken.bind(void 0,/^at/)),a.consumePosition,a.ignore(a.consumeToken.bind(void 0,/^\)/))],f[1]));var g=a.consumeToken(/^polygon/,b);return g&&g[0]?["polygon"].concat(a.consumeList([a.ignore(a.consumeToken.bind(void 0,/^\(/)),a.optional(a.consumeToken.bind(void 0,/^nonzero\s*,|^evenodd\s*,/),"nonzero,"),a.consumeSizePairList,a.ignore(a.consumeToken.bind(void 0,/^\)/))],g[1])):void 0}function c(b,c){return b[0]===c[0]?"circle"==b[0]?a.mergeList(b.slice(1),c.slice(1),["circle(",a.mergeDimensions," at ",a.mergeOffsetList,")"]):"ellipse"==b[0]?a.mergeList(b.slice(1),c.slice(1),["ellipse(",a.mergeNonNegativeSizePair," at ",a.mergeOffsetList,")"]):"polygon"==b[0]&&b[1]==c[1]?a.mergeList(b.slice(2),c.slice(2),["polygon(",b[1],g,")"]):void 0:void 0}var d=a.consumeParenthesised.bind(null,a.parseLengthOrPercent),e=a.consumeRepeated.bind(void 0,d,/^/),f=a.mergeNestedRepeated.bind(void 0,a.mergeDimensions," "),g=a.mergeNestedRepeated.bind(void 0,f,",");a.addPropertiesHandler(b,c,["shape-outside"])}(d),function(a){function b(a,b){b.concat([a]).forEach(function(b){b in document.documentElement.style&&(c[a]=b)})}var c={};b("transform",["webkitTransform","msTransform"]),b("transformOrigin",["webkitTransformOrigin"]),b("perspective",["webkitPerspective"]),b("perspectiveOrigin",["webkitPerspectiveOrigin"]),a.propertyName=function(a){return c[a]||a}}(d,f)}()}({},function(){return this}());
+//# sourceMappingURL=web-animations.min.js.map
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/web-animations-js/web-animations.min.js.gz b/polymer_1.0.4/bower_components/web-animations-js/web-animations.min.js.gz
new file mode 100644
index 0000000..775fe8d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/web-animations-js/web-animations.min.js.gz
Binary files differ
diff --git a/polymer_1.0.4/bower_components/web-animations-js/web-animations.min.js.map b/polymer_1.0.4/bower_components/web-animations-js/web-animations.min.js.map
new file mode 100644
index 0000000..e2f28b6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/web-animations-js/web-animations.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"web-animations.min.js","sources":["src/scope.js","src/timing-utilities.js","src/normalize-keyframes.js","src/deprecation.js","src/keyframe-interpolations.js","src/property-interpolation.js","src/keyframe-effect.js","src/apply-preserving-inline-style.js","src/element-animatable.js","src/interpolation.js","src/matrix-interpolation.js","src/animation.js","src/tick.js"],"names":["webAnimationsShared","webAnimations1","webAnimationsNext","WEB_ANIMATIONS_TESTING","webAnimationsTesting","shared","testing","cloneTimingInput","timingInput","clone","m","makeTiming","forGroup","timing","delay","endDelay","fill","iterationStart","iterations","duration","playbackRate","direction","easing","isNaN","undefined","Object","getOwnPropertyNames","forEach","property","fills","indexOf","directions","isDeprecated","normalizeTimingInput","toTimingFunction","cubic","a","b","d","c","linear","x","f","start","mid","end","xEst","Math","abs","step","count","pos","stepSize","cubicData","cubicBezierRe","exec","apply","this","slice","map","Number","stepData","stepRe","Start","middle","Middle","End","preset","presets","calculateActiveDuration","repeatedDuration","activeDuration","localTime","PhaseNone","PhaseBefore","PhaseAfter","PhaseActive","calculateActiveTime","fillMode","phase","calculateScaledActiveTime","activeTime","startOffset","calculateIterationTime","iterationDuration","scaledActiveTime","Infinity","calculateCurrentIteration","iterationTime","floor","calculateTransformedTime","currentIteration","currentIterationIsOdd","currentDirectionIsForwards","directedTime","timeFraction","calculateTimeFraction","calculatePhase","split","ease-in","ease-out","ease-in-out","step-start","step-middle","step-end","numberString","RegExp","antiAlias","aliases","value","expandShorthandAndAntiAlias","result","longProperties","shorthandToLonghand","shorthandExpanderElem","style","i","longProperty","longhandValue","normalizeKeyframes","effectInput","spaceKeyframes","length","keyframes","offset","previousIndex","previousOffset","j","Array","isArray","TypeError","originalKeyframe","keyframe","member","memberValue","isFinite","type","DOMException","NOT_SUPPORTED_ERR","name","message","everyFrameHasOffset","code","INVALID_MODIFICATION_ERR","filter","background","border","borderBottom","borderColor","borderRight","borderTop","borderWidth","flex","font","margin","outline","padding","document","createElementNS","borderWidthAliases","thin","medium","thick","borderBottomWidth","borderLeftWidth","borderRightWidth","borderTopWidth","fontSize","xx-small","x-small","small","large","x-large","xx-large","normal","textShadow","none","boxShadow","silenced","feature","date","advice","plural","auxVerb","today","Date","expiry","getMonth","console","deprecated","scope","makePropertySpecificKeyframeGroups","propertySpecificKeyframeGroups","propertySpecificKeyframe","group","groupName","makeInterpolations","interpolations","startTime","endTime","startValue","endValue","interpolation","propertyInterpolation","rightInterpolation","leftInterpolation","convertEffectInput","target","fraction","offsetFraction","scaledLocalTime","localDuration","clear","addPropertyHandler","parser","merger","propertyHandlers","push","addPropertiesHandler","properties","toUpperCase","right","left","ucProperty","replace","initialValues","handlers","parsedLeft","parsedRight","interpolationArgs","interp","Interpolation","t","bool","backgroundColor","backgroundPosition","borderBottomColor","borderBottomLeftRadius","borderBottomRightRadius","borderRightColor","borderSpacing","borderTopColor","borderTopLeftRadius","borderTopRightRadius","clip","color","fontWeight","height","letterSpacing","lineHeight","marginBottom","marginLeft","marginRight","marginTop","maxHeight","maxWidth","minHeight","minWidth","opacity","outlineColor","outlineOffset","outlineWidth","paddingBottom","paddingLeft","paddingRight","paddingTop","textIndent","verticalAlign","visibility","width","wordSpacing","EffectTime","effectTime","_totalDuration","_isCurrent","KeyframeEffect","keyframeEffect","_hasSameTarget","nullEffect","_update","configureProperty","descriptor","enumerable","configurable","defineProperty","object","AnimatedCSSStyleDeclaration","element","_surrogateStyle","_length","_style","_updateIndices","ensureStyleIsPatched","_webAnimationsPatchedStyle","animatedStyle","_set","_clear","styleAttributes","cssText","parentRule","styleMethods","getPropertyCSSValue","getPropertyPriority","getPropertyValue","item","removeProperty","setProperty","styleMutatingMethods","prototype",{"end":{"file":"src/apply-preserving-inline-style.js","comments_before":[],"nlb":false,"endpos":2110,"pos":2103,"col":8,"line":64,"value":"cssText","type":"name"},"start":{"file":"src/apply-preserving-inline-style.js","comments_before":[],"nlb":false,"endpos":2110,"pos":2103,"col":8,"line":64,"value":"cssText","type":"name"},"name":"cssText"},"text","isAffectedProperty","_isAnimatedProperty","index","method","modifiesStyle","arguments","documentElement","set","propertyName","window","Element","animate","timeline","_play","interpolate","from","to","convertToString","clamp","min","max","toQ","fromQ","product","quat","theta","acos","sin","composeMatrix","multiply","k","is2D","translate","scale","skew","perspective","matrix","w","rotMatrix","z","y","temp","concat","sequenceNumber","AnimationEvent","currentTime","timelineTime","bubbles","cancelable","currentTarget","defaultPrevented","eventPhase","Event","AT_TARGET","timeStamp","now","Animation","_sequenceNumber","_currentTime","_startTime","_paused","_playbackRate","_inTimeline","_finishedFlag","onfinish","_finishHandlers","_effect","effect","_inEffect","_idle","_currentTimePending","_ensureAlive","_animations","_tickCurrentTime","newTime","ignoreLimit","_isFinished","restart","_timeline","invalidateEffects","oldCurrentTime","playState","play","pause","cancel","addEventListener","handler","removeEventListener","splice","_fireEvents","baseTime","finished","setTimeout","event","processRafCallbacks","processing","rafCallbacks","tick","entry","needsRetick","applyPendingEffects","compareAnimations","leftAnimation","rightAnimation","InternalTimeline","performance","pendingEffects","hasRestartedThisFrame","updatingAnimations","newPendingClears","newPendingEffects","animation"],"mappings":";;;;;;;;;;;;;;w7pBAcA,QAAIA,KAAAA,IAAAA,GAAAA,KACAC,IAAAA,GAAAA,EAAAA,GAAAA,KACAC,IAAAA,GAAAA,KAEJ,IAAKC,GACCC,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAuB,KAAA,WCLnBC,GAAAA,GAAQC,EAAAA,EAAAA,GAKhB,EAAA,EAASC,EAAAA,GAAAA,EAAAA,EAAAA,EAAAA,GAAAA,EAAiBC,EAAAA,EAAAA,GACxB,KAA0B,EAAA,EAAA,EAAA,EAAfA,GAAAA,KAAAA,EAAAA,EACT,EAAOA,KAAAA,GAAAA,IAET,EAAIC,EACC,EAAA,EAAIC,EAAAA,EAAKF,EAAAA,CAAAA,IAAAA,IAAAA,EACNE,EAAKF,EAAAA,EAAAA,EAAAA,EAAAA,MAEb,IAAA,IAAOC,EAGT,CAAA,GAASE,GAAAA,KAAWH,KAAAA,EAAaI,IAAAA,EAC3BC,GAAAA,EACFC,GAAO,EACPC,GAAU,GACVC,KAAMJ,IAAAA,EAAW,GAAA,EAAS,EAAA,KAC1BK,IAAAA,EAAAA,GAAAA,EACAC,EAAAA,CAAAA,QAAY,EACZC,GAAAA,EAAAA,EAAAA,EAAUP,GAAAA,EAAAA,GAAW,EAAA,EAAA,EAAS,EAC9BQ,GAAAA,GAAAA,EAAAA,EAAAA,EAAc,EACdC,GAAAA,EAAAA,GAAW,EAAA,EAAA,EAAA,EACXC,GAAAA,EAAAA,GAAQ,EAAA,EAAA,EAAA,GAyBV,EAAA,GAvB0B,EAAA,EAAA,EAAA,EAAA,GAAA,EAAfd,GAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GAA4Be,GAAAA,EAAMf,EAAAA,EAAAA,EAAAA,GAAAA,EAElBgB,GAAAA,EAAAA,EAAAA,EAAhBhB,GAAAA,EAAAA,EAAAA,EAAAA,EACTiB,EAAAA,EAAAA,KAAOC,QAAAA,OAAAA,EAAoBlB,EAAAA,GAAAA,EAAAA,EAAAA,EAAamB,EAAAA,EAAAA,EAAQ,GAAA,EAAA,EAAA,EAASC,EAAAA,EAAAA,EAAAA,EAAAA,EACvD,EAA6B,EAAA,KAAA,SAAzBpB,OAAYoB,EAAAA,EAAqB,GACnC,EAA+B,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAApBf,EAAAA,EAAAA,EAAAA,EAAOe,EAAAA,EAAAA,KAAAA,SAAqC,OAAZA,EAAAA,EAAAA,EAAAA,EAAAA,EACL,EAAA,EAAA,GAAA,EAAA,EAAA,EAAzBpB,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAYoB,KAAAA,SAAyBL,OAAMf,EAAAA,EAAAA,EAAAA,EAAYoB,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAChE,EAGJ,EAAA,GAAiB,EAAA,EAAA,EAAA,EAAZA,EAAAA,KAAAA,UAAwBC,OAAMC,EAAQtB,EAAAA,GAAAA,EAAAA,EAAAA,EAAYoB,EAAAA,EAAAA,EAAAA,GACrD,EAAA,EAEF,EAAA,EAAiB,EAAA,EAAA,GAAA,EAAA,EAAZA,EAAAA,EAAAA,EAAAA,KAA0E,OAA7CG,GAAAA,GAAWD,EAAQtB,EAAAA,GAAAA,KAAAA,EAAYoB,EAAAA,EAC/D,EAAA,GAEF,KAAgB,EAAA,EAAA,EAAA,EAAZA,GAAAA,KAAAA,EAAwD,EAA1BpB,EAAAA,EAAAA,GAAYoB,KAAAA,EAAAA,EAAmBvB,EAAO2B,KAAAA,GAAAA,IAAa,EAAA,EAAA,EAAA,KAAA,GAAA,IAAA,CAAsC,QAAA,EAAA,KAAc,IAAA,GAAA,EAAA,EAAA,KAAA,IAAA,GAAA,EAAA,EACvI,EAAA,EAAA,EAEFnB,EAAAA,EAAAA,EAAAA,EAAOe,EAAAA,EAAAA,KAAAA,QAAYpB,GAAAA,GAAYoB,EAAAA,EAAAA,GAlBnCf,KAAAA,EAAOM,EAAAA,EAAWX,EAAAA,GAAAA,KAsBbK,EAAAA,EAGT,EAAA,KAASoB,GAAAA,IAAAA,CAAAA,QAAqBzB,EAAAA,EAAAA,EAAAA,EAAAA,KAAaI,IAAAA,GACzC,EAAIC,EAAAA,EAAAA,EAAAA,EAASF,EAAAA,EAAAA,EAAAA,EAAAA,EAAWH,EAAAA,KAAAA,QAAaI,GAAAA,GAErC,EADAC,EAAAA,GAAAA,KAAOS,EAAAA,EAASY,EAAAA,EAAAA,GAAAA,KAAiBrB,EAAAA,EAAOS,EAAAA,KACjCT,GAGT,IAAA,CAASsB,QAAMC,EAAGC,KAAMC,IACtB,GAAIF,EAASA,EAAI,EAAA,EAAS,EAAJG,EAASA,EAAI,EAC1BC,EAAAA,EAAAA,EAAAA,EAEF,EAAA,EAAA,KAASC,YAOHC,GAAKL,GAAG3B,EAAK,EAAA,GAAO,IAAS,EAAIA,EAAAA,EAAUA,EAAKA,GAAI,IAAS,CAAIA,QAAaA,EAAIA,EAAIA,EANjG,EAAA,EAAS,EAAL+B,EAAAA,EAAe,EAALA,EACZ,EAAA,EAAA,EAAOA,EAGT,EAAA,EADA,KAAIE,aAAiB,GAEnB,GAAA,EAAIC,EAAOD,GAAAA,IAAQE,CAAAA,QAEfC,EAAOJ,EAAEN,EAAGG,EAAGK,EAAAA,EACnB,EAAA,EAAIG,EAAAA,EAAAA,EAAKC,EAAAA,EAAIP,EAAIK,EAAAA,EAAQ,KAAA,aACXR,GAAGM,GAENH,EAAPK,EACFH,GAAAA,IAAQC,CAAAA,QAEFA,EAAAA,EAUd,EAAA,EAAA,EAAA,EAASK,EAAAA,EAAAA,EAAKC,EAAAA,EAAAA,EAAOC,EAAAA,EAAAA,EACnB,EAAA,KAAO,aACL,GAAS,GACP,EAAA,EAAO,GAET,IAAIC,CAAAA,QAAW,EAAIF,EAAAA,EAEnB,EAAA,EAAA,EAAA,EADAT,EAAAA,EAAKU,EAAAA,EAAMC,EAAAA,EAAAA,EAAAA,EACJX,EAAIA,KAAIW,cAmBnB,GAASlB,GAAAA,EAAAA,EAAAA,GAAAA,IAAiBZ,EAAAA,EAAAA,EACxB,EAAI+B,GAAAA,IAAAA,EAAAA,EAAYC,EAAAA,EAAAA,GAAAA,IAAcC,CAAAA,QAAKjC,EACnC,EAAA,EAAI+B,EAAAA,EAAAA,EAAAA,EAAAA,EACF,EAAA,EAAA,EAAOlB,EAAAA,EAAAA,EAAAA,EAAMqB,EAAAA,KAAMC,cAAgBC,GAAAA,GAAM,EAAGC,EAAIC,GAAAA,GAAAA,GAElD,EAAIC,EAAAA,GAAAA,GAAWC,CAAAA,QAAOP,EAAKjC,EAAAA,EAAAA,EAAAA,EAC3B,EAAA,EAAIuC,EAAAA,EAAAA,EAAAA,EACF,EAAA,EAAA,EAAOZ,EAAAA,EAAAA,KAAKW,SAAOC,OAAS,EAAMlB,EAAAA,GAASoB,EAAOC,EAAAA,GAAAA,EAAUC,EAAAA,EAAQpB,EAAAA,GAAOqB,EAAKL,EAAAA,GAAAA,EAAS,EAAA,EAE3F,EAAA,EAAIM,EAAAA,EAAAA,EAASC,GAAAA,EAAQ9C,EAAAA,GAAAA,EACrB,EAAA,KAAI6C,WACKA,MAEF3B,GAGT,GAAA,QAAS6B,GAAAA,GACP,MAAOtB,KAAKC,EAAIsB,QAAiBzD,EAAAA,EAAUA,EAAAA,EAAAA,EAAAA,EAAOO,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAGpD,EAAA,EAAA,GAASkD,EAAAA,IAAiBzD,GACjBA,OAAOM,GAAkBD,QAQlC,GAAwBqD,GAAgBC,OAAW3D,EAChC,EACR4D,KAEO5D,GAAAA,GACP6D,WAELF,QAAa3D,GAAe0D,GAAAA,MAAAA,GACvBI,GAAAA,GAAAA,EAAAA,GAEFC,GAAAA,EAAAA,GAAAA,GAGT,EAAA,GAAA,GAASC,EAAAA,GAAAA,GAAAA,EAAAA,GAAAA,GAAAA,EAAAA,GAAoBN,GAAAA,EAAAA,GAAAA,GAAAA,EAAAA,GAAgBO,GAAAA,EAAAA,GAAUN,GAAAA,EAAAA,GAAAA,GAAWO,EAAAA,GAAOjE,GAAAA,EAAAA,GACvE,GAAA,EAAA,GAAQiE,GAAAA,EACN,GAAA,GAAKL,EAAAA,GAAAA,GAAAA,EAAAA,GACH,GAAA,EAAgB,GAAA,GAAA,QAAZI,GAAuC,GAAA,IAAZA,GAAAA,GACtB,EACF,EACJF,GAAAA,EAAAA,EAAAA,GACH,GAAA,EAAA,EAAOJ,GAAAA,GAAAA,EAAAA,EAAY1D,GAAAA,GACrB,EAAA,EAAK6D,GAAAA,GAAAA,EAAAA,EAAAA,GACH,GAAA,EAAgB,EAAA,GAAA,GAAA,EAAA,EAAZG,GAAAA,GAAAA,EAAAA,EAAsC,GAAA,GAAA,EAAZA,EAAAA,GAAAA,GAAAA,KACrBP,EAAAA,EAAAA,EAAAA,GACF,GACT,EAAKE,EAAAA,EAAAA,GAAAA,GACH,EAAA,EAAO,EAAA,GAAA,EAIb,KAASO,EAAAA,EAAAA,EAAAA,GAAAA,GAAAA,EAAAA,EAAAA,EAAAA,GAAAA,GAA0BT,EAAAA,EAAAA,EAAAA,GAAAA,EAAgBU,KAAAA,EAAAA,EAAYC,EAAAA,GAAAA,GAAAA,EAAarE,EAAAA,EAAAA,GAC1E,GAAA,EAAQA,EAAAA,EAAAA,GAAOO,EAAAA,IAAAA,KAAmB6D,EAAAA,EAAAA,EAAaV,EAAAA,IAAAA,CAAAA,IAAAA,GAAiBU,GAAAA,EAAAA,EAAAA,EAAAA,EAAcpE,EAAAA,IAAOO,GAAAA,EAAAA,GAAAA,GAAe8D,EAAAA,GAAAA,EAAAA,GAGtG,KAASC,GAAAA,MAAAA,GAAuBC,KAAAA,GAAAA,EAAAA,KAAmBd,GAAAA,EAAAA,QAAkBe,GAAkBH,GAAAA,QAAarE,EAAAA,GAClG,GAAA,EAAyByE,GAAAA,GAArBD,EAAAA,GAAAA,GAAAA,EAAAA,GAAAA,KAAiCA,EAAAA,GAAAA,GAAAA,EAAAA,GAAAA,GAAAA,EAAAA,GAAsBC,GAAAA,EAAaD,GAAAA,KAAAA,EAAAA,GAAAA,GAAmBH,EAAAA,GAAAA,GAAAA,EAAAA,GAAeZ,GAAAA,EAAAA,GAAAA,KAAAA,EAAAA,GAAoBzD,GAAAA,EAAAA,GAAOK,GAAAA,EAAAA,GAAAA,GAAAA,EAAgBL,GAAAA,KAAOK,QAAaL,GAAOI,EAAAA,GAAAA,IAAkB,GAAK,MAC9LmE,EAAAA,EAAAA,EAAAA,EAAAA,IAGFC,CAAAA,IAAAA,GAAAA,GAAAA,EAAmBD,EAAAA,EAAAA,EAAAA,EAAAA,IAAAA,GAG5B,EAAA,GAAA,EAAA,GAASG,EAAAA,GAAAA,KAAAA,GAAAA,MAA0BH,GAAAA,QAAmBI,GAAAA,GAAAA,GAAeH,GAAAA,EAAAA,EAAkBxE,QAAAA,EACrF,GAAA,EAAyB,EAAA,GAArBwE,EAAAA,EAAAA,GAAAA,GAAAA,QAGAG,GAAAA,GAAiBJ,MAAAA,MAAAA,KACZvE,EAAAA,GAAAA,EAAOI,GAAAA,EAAAA,GAAAA,EAAAA,GAAAA,EAAiBJ,GAAAA,EAAAA,IAAOK,QAAa,GAEzCuE,EAAAA,EAAMJ,EAAAA,GAAAA,OAAmBD,EAAAA,EAAAA,GAAAA,EAAAA,EAAAA,GAGvC,EAAA,EAASM,GAAAA,EAAAA,EAAAA,GAAAA,EAAAA,EAAAA,GAAAA,EAAyBC,EAAAA,IAAAA,QAAkBP,GAAAA,EAAAA,GAAAA,OAAmBI,EAAAA,GAAAA,EAAAA,GAAe3E,EAAAA,GAAAA,EACpF,GAAI+E,EAAAA,GAAAA,EAAAA,GAAAA,EAAAA,GAAAA,EAAAA,GAAwBD,EAAAA,GAAAA,EAAAA,GAAAA,EAAmB,GAAK,EAChDE,IAAAA,QAAAA,GAAiD,GAApBhF,GAAAA,IAAOQ,EAAAA,MAAyBR,EAAOQ,GAAAA,EAAAA,MAAcuE,EAAAA,GAAAA,EAAAA,MAAwB,EAAA,IAAA,EAAA,MAAA,GAAsB,IAAA,IAAA,IAChIE,EAAAA,GAAAA,GAAAA,MAAeD,KAAAA,KAAAA,GAAAA,MAA6BL,EAAgBJ,EAAAA,EAAAA,EAAAA,IAAAA,EAAoBI,KAChFO,EAAAA,GAAAA,QAAeD,KAAAA,GAAAA,GAAeV,EAAAA,EAAAA,EAAAA,IAAAA,EAC3BA,GAAAA,GAAAA,CAAAA,IAAAA,IAAoBvE,EAAOS,GAGpC,OAAS0E,CAAAA,IAAAA,GAAAA,IAAsBzB,IAAAA,EAAAA,GAAgBC,IAAAA,EAAAA,GAAW3D,IAAAA,EACxD,GAAIkE,GAAAA,CAAAA,EAAQkB,KAAAA,EAAAA,GAAAA,IAAe1B,EAAAA,KAAAA,EAAgBC,GAAAA,IAAAA,EAAW3D,KAAAA,EAClDoE,GAAAA,IAAAA,EAAaJ,KAAAA,EAAAA,GAAAA,GAAAA,IAAoBN,GAA6BC,EAAAA,GAAyB1D,EAG3F,EAAIyD,EACeG,GACnB,EAAkB7D,EAAAA,OACdwE,IAAmBL,EAAAA,EAAAA,EAAAA,EAAAA,IAAAA,GAA0BT,EAAAA,GAAAA,MAAAA,EAAgBU,GAAAA,IAAAA,GAAYC,KAAAA,EAAarE,GAAAA,MACtF2E,EAAAA,GAAAA,IAAAA,KAAgBL,GAAAA,KAAAA,EAAuBtE,EAAAA,KAAOM,EAAAA,GAAUmD,EAAAA,EAAAA,GAAiBzD,IAAAA,KAASwE,GAAAA,KAAAA,EAAkBH,GAAAA,MAAAA,EAAarE,IAAAA,EACjH8E,KAAAA,EAAAA,EAAAA,GAAmBJ,EAAAA,KAAAA,EAAAA,GAAAA,EAAAA,EAA0B1E,GAAAA,EAAOM,GAAAA,GAAUqE,EAAAA,IAAAA,EAAeH,KAAAA,EAAAA,EAAkBxE,KAAAA,EACnG,GAAA,EAAO6E,EAAAA,IAAAA,EAAAA,IAAAA,EAAyBC,GAAAA,EAAAA,KAAkB9E,EAAAA,GAAOM,MAAAA,EAAAA,IAAUqE,EAAAA,KAAAA,EAAe3E,EAAAA,GAAUA,EAAAA,KAAOM,EAAAA,GArNrG,EAAY,EAAA,GAAA,EAAA,GAAA,GAAA,EAAA,IAAA,EAA+B+E,KAAAA,EAAM,EAC7CnE,GAAAA,EAAAA,KAAa,EAAA,GAAA,EAAA,EAAA,GAAA,EAAA,GAAA,GAAA,EAAsCmE,IAAM,EAkFzDnC,KAAQ,EACRE,EAAS,KACH,EAaNG,GAAAA,EACMjC,EAAAA,IAAM,EAAW,IAAM,EAC/BgE,GAAAA,EAAWhE,IAAM,EAAS,EAAG,IAC7BiE,GAAAA,EAAYjE,EAAM,GAAM,EAAM,GAC9BkE,IAAAA,EAAAA,EAAAA,GAAelE,GAAM,EAAM,IAAG,GAAM,GACpCmE,EAAAA,EAAAA,EAAAA,IAAAA,EAAcrD,IAAQc,GAAAA,EACtBwC,GAAAA,IAAAA,GAAAA,EAAetD,GAAAA,IAAQgB,GAAAA,EACvBuC,GAAAA,IAAAA,EAAAA,IAAYvD,GAAK,EAGfwD,EAAAA,EAAAA,GAAAA,GAAe,EAAA,GAAA,GAAA,EAAA,GAAA,GAAA,CAAA,OAAA,GAAA,MACfnD,EAAAA,GAAAA,KAAAA,KAAoBoD,GAAAA,IAAO,EAAA,GAAA,GAAoBD,EAAAA,GAAAA,IAAAA,GAAe,EAAMA,GAAAA,GAAAA,EAAAA,GAAe,IAAMA,GAAAA,EAAAA,GAAAA,GAAe,EAAMA,GAAAA,IAAAA,EAAAA,IAAe,IAAA,EAC7H3C,GAAAA,GAAS,EAAA,GAAA,IAAA,EAAA,GAAA,GAAA,EAAA,GAAA,IAAA,EAAA,EAAA,KAAA,KAAA,EACTtB,EAAAA,GAAS,GAAA,EAAA,GAASC,GAAK,EAAOA,GAAAA,IA0B9BgC,GACAC,IAAAA,GAAAA,EACAC,GAAAA,GAAAA,EAAAA,GACAC,IAAAA,GAAAA,EAAAA,GA4EJvE,GAAAA,EAAOE,GAAAA,IAAAA,GAAAA,EAAAA,GAAmBA,GAAAA,EAAAA,GAAAA,IAAAA,IAC1BF,EAAAA,GAAOM,GAAAA,EAAAA,GAAaA,IAAAA,EAAAA,EAAAA,KACpBN,KAAO4B,EAAAA,EAAAA,GAAAA,GAAAA,EAAAA,GAAAA,GAAuBA,EAAAA,GAAAA,IAAAA,IAC9B5B,EAAOgE,GAAAA,GAAAA,EAAAA,GAAAA,IAAAA,EAAAA,IAA0BA,GAAAA,EAAAA,GAAAA,GAAAA,EAAAA,GAAAA,IACjChE,GAAAA,EAAO2F,GAAAA,GAAAA,EAAAA,GAAAA,IAAAA,KAAwBA,EAAAA,EAAAA,KAAAA,KAAAA,EAAAA,EAAAA,GAC/B3F,GAAAA,EAAO4F,GAAAA,GAAAA,EAAAA,GAAAA,IAAiBA,IACxB5F,EAAAA,GAAO6B,GAAAA,EAAAA,GAAAA,IAAAA,GAAmBA,EAAAA,GAAAA,GAAAA,EAAAA,GAkBzBlC,IAAAA,EAAAA,IAAAA,GAAAA,EAAAA,GAAqBI,GAAAA,EAAAA,GAAAA,IAAAA,KAAAA,EClPxB,EAAUC,EAAQC,EAmIhB,GAASqG,MAAU/E,KACbA,GAAAA,IAAYgF,EAAAA,EACPA,wBAAkBC,GAMpBC,EAAAA,GAAsCD,SAAOE,GAChDC,QAAAA,GAAiBC,EAAAA,GAAoBrF,GAAAA,GACrCoF,EAAAA,KAAAA,EACFE,OAAAA,IAAAA,EAAsBC,EAAMvF,WAAYiF,EACnC,GAAIO,cAAKJ,EACZ,IAAIK,EAAAA,EAAeL,OAAAA,EAAeI,UAC9BE,OAAgBJ,QAAAA,GAAsBC,EAAME,GAChDN,EAAAA,EAAOM,QAAgBV,OAAAA,GAAUU,IAAAA,GAAAA,EAAcC,EAAAA,OAGjDP,IAAOnF,EAAY+E,GAAAA,EAAU/E,GAAAA,QAAUiF,OAI3C,KAAA,OAASU,QAAAA,GAAmBC,EA4D1B,EAASC,GAAAA,EACHC,EAAmBA,KACa,KAAA,EAAhCC,KAAUD,GAAS,QAAGE,CAAAA,GACxBD,GAAUD,EAAS,EAAY,KAC7BA,EAAS,OAA4B,EAAvBC,EAAU,IAAGC,EAAAA,KAC7BD,EAAU,IAAGC,EAAS,EAInB,GAFDC,EAAAA,EACAC,EAAAA,IAAiBH,GAAaC,IACzBR,EAAWM,GAAAA,OAAa,EAC3BE,EAASD,GAAAA,EAAaC,IAC1B,QAAc,GACQR,EAAIS,GAAAA,IAAeE,GACrCJ,GAAAA,EAAUE,EAAAA,EAAAA,EAAAA,EAAgBE,UAAYD,OAAAA,KAAAA,EAAkBF,KAASE,GAAAA,GAAAA,IAAkBC,GAAKX,KAAIS,EAAAA,GAC9FA,QAAgBT,IAChBU,KAAAA,EAAAA,KAAiBF,IA1ElBI,GAAAA,GAAMC,IAAQT,GAAAA,GAAgC,KAAA,IAAhBA,GAAAA,EAC3B,EAAIU,OAAAA,EAAU,GAAA,OAAA,SAAA,EAAA,QAAA,EAAA,EAAA,OAEH,IAAfV,QAAAA,GACF,EAAA,GAAA,IAmCF,GAAK,GAjCDG,EAAAA,EAAAA,EAAAA,GAAAA,GAAYH,EAAAA,EAAAA,GAAAA,EAAAA,GAAY7D,CAAAA,OAAI,GAAA,EAASwE,GAAAA,EAAAA,GAAAA,QACvC,GAAIC,GAAAA,MACC,UAAIC,GAAUF,GAAAA,GAAAA,EACjB,EAAIG,OAAcH,KAAAA,EAAAA,GAAiBE,QACnC,GAAc,QAAVA,GACiB,EAAfC,GACFA,MAAAA,UAAqBA,GAAAA,GAAAA,GAChBC,EAASD,EAAAA,OACZ,GAAUJ,GAAAA,EAAU,IAAA,QAAA,GAAA,EAEnB,GAAc,IAAA,GAAVG,MACT,EACEG,EAAAA,EAAAA,EAAMC,OAAAA,IAAaC,CAAAA,GAAAA,GAAAA,EACnBC,eAAM,EAAA,GACNC,EAAAA,KAAS,GAAA,IAAA,EAAA,GAAA,MAAA,UAGXN,EADmB,IAAA,EAAVD,KAAAA,EACKhI,IAAO6B,EAAAA,EAAAA,GAAiBoG,MAAAA,IAAAA,EAEnBA,EAAAA,OAErBxB,QAAAA,GAAoCwB,EAAAA,EAMtC,EAJuB9G,EAAnB4G,GAAAA,IAASR,GAAAA,MACFA,KACPQ,KACFA,EAAAA,EAAS9G,EAASjB,OAAO6B,EAAAA,QAAAA,EAAiB,EAAA,EAAA,EACrCkG,IAAAA,CAAAA,GAAAA,GAGLS,EAAAA,EAAsB,EAEtBf,EAAAA,QAAAA,EAAkBxC,EACb8B,EAAWO,QAAUD,KAAAA,EAAQN,MAChCQ,GAASD,KAAUP,EAAGQ,IAC1B,EAAoB,KACLE,EAAAA,IAAAA,EACX,KACEgB,EAAML,IAAAA,OAAaM,EAAAA,EACb,SAAA,GAAA,GAAA,GACNH,EAAS,IAAA,SAAA,EAAA,GAAA,MAAA,GAAA,GAAA,KAAA,KAGbd,EAAAA,OAAiBF,GAAAA,EAEjBiB,GAAAA,IAAAA,QAIJlB,GAAAA,EAAYA,EAAUqB,GAAAA,IAAO,GAAA,MAASZ,KAC7BA,KAASR,EAAAA,EAAU,EAAA,EAAKQ,EAAAA,EAAAA,OAASR,IAAU,GAsB/CiB,kBAAAA,GACHpB,GAAAA,CAAAA,GAAAA,GAEKE,EAAAA,GA1OT,EAAIV,GAAAA,EAAAA,KAAAA,GACFgC,KAAAA,EACE,IAAA,EAAA,KAAA,EACA,IAAA,EAAA,KACA,EAAA,SACA,SAAA,GAAA,EACA,MAAA,GAAA,EAAA,MACA,GAAA,EAAA,KACA,WAAA,MACA,GAAA,MAAA,EAEFC,QAAAA,EACE,EAAA,SACA,GAAA,IACA,GAAA,GAAA,GAAA,EAAA,EACA,EAAA,EAAA,OAAA,IACA,GAAA,EACA,GAAA,EAAA,GAAA,OACA,KAAA,EACA,aAAA,EACA,EAAA,eACA,EACA,EAAA,gBACA,EAEFC,EAAAA,qBACE,EACA,EACA,OAAA,EAAA,EAEFC,SACE,EAAA,EAAA,YACA,EACA,EAAA,oBACA,EAGA,KAAA,KAAA,MACA,EAAA,2BACA,EAGA,EAAA,UACA,GAAA,GACA,SAAA,GACA,QAAA,GAAA,GAEFC,QACE,GAAA,GACA,GAAA,GAAA,EACA,aAAA,UAEFC,EACE,IAAA,EAAA,MACA,GAAA,OAAA,EAAA,CACA,IAAA,GAAA,EAEFC,uBACE,EACA,IAAA,EAAA,MACA,GAAA,QAAA,KACA,EAAA,IAAA,CAEFC,IACE,GAAA,EACA,aACA,EAAA,OAEFC,IACE,EACA,MAAA,EACA,GAAA,GACA,OAAA,GAAA,IACA,OACA,EAAA,WAEFC,MAAAA,MACE,EAAA,EACA,gBACA,EACA,IAAA,EAEFC,OACE,IAAA,EACA,GAAA,QAAA,EACA,EAAA,IAAA,OAEFC,QACE,GACA,GACA,GAAA,GAAA,EACA,gBAIA1C,EAAAA,KAAAA,EAAwB2C,OAASC,IAAAA,IAAgB,EAAA,GAAA,EAAA,GAAA,OAAA,QAAgC,GAEjFC,EAAAA,GACFC,KAAM,EACNC,QAAQ,OACRC,KAAO,IAGLtD,EAAAA,QACFuD,OAAAA,EAAAA,QAAmBJ,SAAAA,EACnBK,QAAAA,MAAiBL,GAAAA,GAAAA,MAAAA,EAAAA,QACjBM,OAAAA,KAAkBN,IAAAA,EAAAA,QAClBO,OAAAA,EAAAA,QAAgBP,SAAAA,EAChBQ,QACEC,MAAAA,GAAAA,GAAY,IAAA,EACZC,OAAW,EACXC,SAAS,EACTT,SAAU,EACVU,MAAS,CAAA,IACTC,GAAAA,GACAC,KAGAC,MACM,GAAA,MAEMf,GAAAA,EAAAA,EAAAA,EAAAA,EAAAA,QACdgB,OACEC,IAAAA,CAAM,GAAA,GAAA,EAERC,gBACQ,EAAA,QAAA,GAAA,EAAA,QAAA,GA+GV5K,GAAAA,EAAOkH,GAAAA,GAAAA,KAAqBA,EAAAA,IAM3BvH,EAAAA,GAAqBI,KAAAA,ECpPxB,IAAA,EAEM8K,KAAAA,EAEGlJ,IAAAA,GAAe,EAAA,OAASmJ,EAASC,MAAMC,CAAAA,GAAQC,GAChDC,EAAAA,YAAmB,EAAQ,MAC3BC,EAAYC,MACZC,GAAaD,GAAKL,EACtBM,GAAAA,EAAgBA,GAAAA,EAAOC,GAAa,EAG5BR,EAAWD,GAAAA,OACfU,EAAa,EAAqBT,SAAU,GAAMI,IAAU,GAAA,GAAA,EAAA,MAAA,SAAA,IAAA,EAAA,EAA0CG,EAAAA,EAAwB,OAAOL,IAAAA,GAEvIH,EAGO,GAIX7K,EAAOwL,GAAAA,IAAAA,GAAa,OAAA,KAAgCP,GAClD,EAAuB,EAAQ,KAC/B,KAAWtJ,QAAAA,GAAoCsJ,EACvC,EAAUH,EAAAA,GAAgBI,QAAU,GAAA,GAAA,OAA2BF,MAIxErL,EAAAA,OAAAA,EAAAA,EAAAA,EC5BH,GAAA,UAAUK,GAAQyL,IAAAA,GAAOxL,IAAAA,GAAAA,IA2BvB,GAAA,KAASyL,IAAAA,GAAAA,MAAAA,KAAmCpE,EAAAA,EAAAA,EAAAA,EAG1C,QAFIqE,EAAAA,EAAAA,OAAAA,IAAAA,CAAAA,GAAAA,GAAAA,EAAAA,IAEK5E,EAAWO,EAAUD,GAAQN,OAC/B,EAAA,EAAIiB,IAAAA,EAAoBjB,EACb,GAAA,MAAViB,GAAgC,KAAA,GAAVA,EAAgC,KAAA,GAAA,MAAVA,GAC9C,oBAAI4D,EACFrE,EAAQD,EAAaC,GACbD,GAAAA,GACRd,EAAoBwB,KAEtB2D,KAAAA,EAAAA,KAAAA,GAA+B3D,qBAAU2D,EAAAA,GACzCA,aAAAA,iBAA+B3D,GAAa4D,SAAAA,GAAAA,QAK7C,GAAiBD,GAAAA,MAAAA,GAAAA,QAAAA,GAAAA,QAAAA,OAChBE,IAAAA,QAAQF,GAAAA,EAAAA,EAAAA,GAAAA,MAA+BG,MAAAA,IAC3C,EAAuB,KAAnBD,IAAM,EAAGtE,IAAAA,QAAesE,GAAYxE,GAAYE,MAClD,2BACqBc,KAAAA,GAAAA,OACb,GAAA,OAAA,QACNE,GAAS,EAAA,GAAA,OAAA,EAAA,EAIf,GAAOoD,QAAAA,GAAAA,EAIT,GAASI,MAAAA,IAAAA,EAAAA,EAAmBJ,EAAAA,EAAAA,GAAAA,EAAAA,GACtBK,OAAAA,QAAAA,GACKF,EAAaH,GAAAA,OAAAA,EAAAA,EAAAA,SAEf,GADDE,MAAQF,MAAAA,MAAAA,EAAAA,EAAAA,EAAAA,EAAAA,MAA+BG,QAAAA,GACjBzE,EAAYN,GACpC,MAAIkF,UAAYJ,EAAM9E,GAAGQ,OACrB2E,EAAUL,EAAU,SACpBM,GAAAA,MAAAA,GAAsB3F,EACtB4F,EAAWP,EAAAA,OAAarF,QACxByF,GAAAA,EAAaC,GACA,OAAXA,EACFC,EAAAA,KAAaC,OAAAA,EAEbA,MAAWD,EAAAA,EAGfH,qBACEC,EAAWA,EACFC,EACTjL,EAAAA,IAAAA,qBACAM,gBACA8K,EAAAA,qBAAqBC,EAAAA,EAAiCH,EAAAA,IAAYC,UAOxE,0BAHoB,EAAA,qBAA4BG,EAAAA,GAC9C,YAAOC,gBAAkBP,EAAYM,qBAAmBN,EAEnDD,GApFHS,UAAAA,WAAqB,EAAStF,qBAC9BG,EAAmBJ,GAAAA,YAAmBC,EAAAA,YACtCwE,EAAAA,EAAAA,aAAiCD,EAAAA,EAAAA,eAAmCpE,GACpE0E,EAAiBD,GAAmBJ,SAAAA,GACxC,QAAO,GAAA,EAASe,GAAQC,MACtB,WAAIA,GAAAA,WACFX,GAAerD,EAAAA,EAAAA,SAAO,GAAS0D,MAAAA,IAAAA,EAAAA,EAC7B,GAAoB,EAAA,EAAZM,YAAiBN,OAAAA,EAAcJ,qBACW,OAAzBI,GAAAA,gBACjBM,GAAYN,SAAcJ,GAAaU,QAAYN,GAAcH,GACxE5K,EAAQ,EAAS+K,OAAAA,EAClB,UAAIO,OAAAA,EAAiBD,UAAWN,CAAcJ,IAAAA,GAC1BI,EAAcH,SAAUG,IAAAA,EAAcJ,UACtDY,OAAAA,EAAAA,UAAkBC,EAAAA,GAA8CF,EAAAA,UAAiBE,CAAAA,EACrFrB,SAAMtI,EAAMuJ,EAAAA,EAAAA,EAAQL,IAAAA,GAAc9K,EAAU8K,aAAAA,EAAcA,EAAAA,EAAAA,GAAAA,IAAAA,GAAcQ,UAAAA,EAAAA,EAAAA,EAAAA,EAG1E,IAAK,GAAItL,EAAYoK,GAAAA,GAAAA,QAAAA,EAAAA,GAAAA,EACH,EAAZpK,GAAAA,EAAoC,EAAZA,GAAAA,EAAoC,IAAZA,QAAAA,GAC5CwL,EAAML,GAAQnL,OAAAA,EA0E7B5B,EAAAA,SAAAA,GAAqBC,QAAAA,GAAgBG,GAAAA,MAAAA,MAAAA,IAAAA,EC/FxC,KAAA,IAAU0L,IAAAA,IAIR,GAAA,EAAA,GAASuB,IAAAA,GAAAA,GAAAA,EAAAA,EAAAA,EAAAA,IAAmBC,EAAAA,GAAAA,KAAQC,MAAQ3L,EAAAA,EAC1C4L,GAAAA,EAAAA,IAAAA,OAAiB5L,GAAAA,GAAAA,EAAY4L,eAAiB5L,EAAAA,MAAAA,EAC9C4L,EAAAA,EAAAA,KAAAA,QAAiB5L,EAAAA,KAAAA,KAAU6L,MAAMH,GAAAA,GAAQC,SAE3C,gBAASG,+BAAqCC,SACnCvG,GAAWuG,MAAAA,EAAWjG,OAAQN,CAAK,IACtCxF,GAAAA,EAAW+L,WAEfN,KAAAA,GAAAA,qBAAmCzL,EAC/B,GAASA,mBAEXyL,sBAAmCzL,oBAAiB,qBAC3CW,mBAAEqL,QA6DjB,gBAASjB,0BAAsCkB,EAC7C,aAAIC,EAA8B,qBAC5BC,KAAAA,KAAAA,GAAsBC,EAAQ,YAAS,GACzC,EAASJ,GAEPE,SACKG,EAAAA,GAAcF,QAAAA,GACnBF,EACFA,GAAQI,GAAAA,EAAcF,EAAAA,OAGrB,cADUD,KAAQD,GAAAA,KAAaL,OAAAA,IAAiB5L,EAAAA,OACrCsM,GAAAA,EAAAA,IAAY9G,gBAAaM,KAAa,GAChDyG,CAAAA,EAAaD,EAAAA,QAAeJ,UAC5BM,IAAAA,IAAcF,KAAeL,GACjC,EAAmBrM,QAAf2M,EAA4C3M,SAAhB4M,GAAAA,MAC1BC,GAAAA,GAAoBH,KAAAA,IAAY,GAAGC,KAAAA,GAAYC,GAC/CC,KAAAA,EACF,OAAIC,IAASxC,EAAMyC,EAAAA,QAAc/K,oBAAY6K,KAC7C,QAAO,GAAA,QACL,IAAA,EACIG,KAAeX,KACZS,QAAOE,YAKf1C,KAAMyC,QAAAA,MAAc,IAAa,GAASE,UACxCA,cAAeX,YAtGtBN,cAAAA,EAmBJ1B,EAAAA,EAAAA,EAAM4B,QAAAA,EAAuBA,GAAAA,KAAAA,IAEzBO,EAAAA,EACFS,QAAAA,EAAiB,GAAA,MACjBC,EAAAA,GAAAA,GAAAA,IAAAA,KAAoB,EACpBC,CAAAA,IAAAA,GAAAA,KAAmB,GACnBC,CAAAA,GAAAA,GAAAA,KAAAA,EAAwB,QACxBC,GAAAA,QAAAA,IAAAA,EAAyB,KACzB3E,IAAAA,QAAAA,GAAAA,QAAmB,EACF,KAAA,MAAA,KACjBC,SAAAA,GAAiB,MACjB2E,GAAAA,GAAkB,EAAA,MAClB1E,KAAkB,QAElB2E,GACAC,EAAgB,GAAA,MAChBC,GAAAA,EAAqB,GACrBC,GAAAA,QAAAA,GACA7E,EAAAA,EAAgB,GACR,GAAA,GACR8E,IAAM,KAAA,IAAA,GAAA,EACNC,KAAO,EAAA,KACP9E,IAAU,GACV+E,EAAAA,QAAY,GACZC,GAAQ,EAAA,KACRzB,EAAM,OACN0B,GAAAA,EAAe,IAAA,SACfC,GAAY,MACZC,GAAAA,IAAc,IAAA,EACdC,EAAAA,IAAY,SACZC,GAAa,MACbC,GAAAA,IAAW,KACXC,EAAAA,EAAW,SACXC,GAAU,GACVC,GAAAA,EACAC,IAAAA,SAAU,EACVC,GAAAA,MACAC,IAAAA,EAAAA,QAAc,IACdC,EAAe,KACfC,IAAAA,EAAAA,IAAc,EACdC,eAAe,GACfC,EAAAA,KAAa,KACbC,MAAAA,OAAc,GACdC,OAAY,EAAA,QACZ5C,EAAO,IACP6C,IAAY,GAAA,GACZ3F,iDAEW,EACX4F,EACAC,KAAAA,KAAY,GAAA,QACZC,EACAC,MAAAA,EACQ,EAiCJnE,KAAAA,KAAAA,GAAAA,QAAwBA,EAAAA,KAAAA,MAE7B1M,EAAAA,EAAgBG,KAAAA,KC7GnB,qBAAyBE,GAAAA,YAEdyQ,EAAWlQ,EAClB,qBACqBR,EAAOgE,EAAAA,uBACX,EAASG,qBACjBnE,KAAO2F,KAAAA,GAAsBzB,EAAAA,WAAgBC,EAOtD,EALAwM,gBAAWC,CAAiBpQ;GAAOC,GAAQyD,EAAiB1D,qBAC5DmQ,KAAWE,KAAAA,GAAa,EAClBnM,EAAAA,gBAAekB,KAAAA,OAAe1B,EAAgBC,KAAAA,EAC3CO,EAAUH,gBAAeG,KAAUL,OAAAA,EAK9CoH,KAAMqF,GAAAA,oBAA0BpE,CAAqBvM,IAAAA,GAG/CuF,SAFAiL,GAAaD,GAAAA,GAAW1Q,EAAO4B,EAAqBzB,OAAAA,IACpD6L,IAAAA,EAAAA,GAAiBP,EAAMgB,GAAAA,QAAAA,EAEvBsE,EAAAA,oBAEF/E,KAAAA,OAAeU,EAGjBqE,KAAAA,EAAkC5M,EAAAA,oBAChCuB,KAAeiL,OAAAA,EACRjL,IAAAA,GAETqL,yBAAwB,EACPrE,EAAQ,qBAEVsE,EAAiB,GACvBtE,oBAETqE,EAAAA,qBAA4BJ,EAC5BI,GAAgCJ,sBAAWC,qBAI7CnF,oBAAmB,qBACbwF,mBACElE,aAEFA,YAaJ,SAVAkE,cAAWC,aAAU,YACZ,gBAEEN,UAAAA,EACXK,qBAAwB,EAGxBA,GAAWD,4BACF,6BAUVrR,yBAAqCI,0BCjE9B0L,SAAOxL,OAsBf,iBAASkR,gBAA0B5P,cAAU6P,eAC3CA,aAAWC,aACXD,YAAWE,iBACJC,iBAAeC,eAAkBJ,gBAGjCK,cAAAA,cAA4BC,QAAAA,eAO9BC,cAAkBnI,MAASC,iBAAgB,kBAAA,EAAuC3C,GACzE4K,SAAQ5K,GACjB8K,QACLxO,GAGA,GAAS2D,MAAW3D,GAAKyO,uBACnBtQ,IAAW6B,EAAKyO,aACfF,QAAAA,GAAgBpQ,QAAAA,GAAiBsQ,GAAOtQ,GAAAA,GAE1CuQ,EAAAA,aA+FP,EAASC,OAAAA,EAAAA,aAAqBL,KAC5B,KAAIA,UAAQM,EAAAA,OAAAA,EAAAA,aAGRC,KAAAA,KAAAA,QAAoBR,EAAAA,gBAAAA,KAA4BC,KAAAA,EAEhCA,MAAS,EAAA,OAAgB,EAAA,aAAoBO,KAAAA,KAAAA,SAC/D,EAGAP,OAAQ5K,IAAMoL,GAAO,EAAS3Q,GAAAA,OAAUiF,EACtCkL,GAAAA,OAAQ5K,QAAMvF,GAEhBmQ,EAAQ5K,GAAMqL,MAAS,QAAS5Q,GAAAA,QAC9BmQ,IAAQ5K,GAAMvF,EAAAA,SAAY,GAK9BmQ,GAAAA,GAAQM,EAAAA,EAAAA,CAAAA,IAAAA,QAA6BN,EAAQ5K,MAAAA,MA7J3CsL,IAAAA,GAAAA,EACFC,gBACQ,EACRC,EAGEC,OAAAA,GACFC,GAAAA,EAAAA,MAAAA,EACAC,gBAAAA,EAAqB,GACrBC,QAAAA,GACAC,GACAC,MAAAA,QAAgB,EAChBC,IAAAA,GAAa,GAGXC,EAAAA,2BAEFD,KAAAA,KA6BFpB,EAAAA,EAAAA,KAAAA,GAA4BsB,SAC1BC,EAAIX,EACF,WAAYV,EAAAA,EAAgBU,qBAElBY,EAEL,GADDC,UAAAA,EACqBvB,GAAwB5K,SAC/CmM,GAAmB9P,QAAKuO,GAAAA,GAAgB5K,MAE1C3D,UAAKuO,GAAgBU,GAAAA,GAAAA,CAAUY,OAC/B7P,GAAK0O,IAAAA,SACL,GAAK,MAAW/K,KAAI3D,EAAAA,EAAKuO,KAAAA,KAAgBtK,QACvC6L,GAAAA,GAAAA,MAAAA,GAAAA,QAAwBvB,GAAAA,GAE1B,GAAA,EAASpQ,EAAAA,cAAY2R,OAAAA,QACTC,EAAAA,QAAAA,KAAoB5R,GAAAA,GAC5B6B,EAAYyP,uBAA2BlB,KAAAA,EAAgBe,EAAAA,EAAiBnR,EAI1E8F,KAAAA,IACKjE,CAAAA,GAAAA,EAAKuO,OAAAA,EAEdqB,MAAIV,GACF,EAAOlP,MAAKyO,EAAOS,GAAAA,MAGrBR,IAAAA,GAAgB,EAAA,GACd,EAAYF,EAAeD,EACzBvQ,KAAAA,EAAOmQ,MAAenO,IAAMA,GAAKwO,EAAAA,GAC/BN,MAAAA,KAAAA,EACAD,EACK,EAAA,IAAA,EACH,OAAO,EAAA,OAAa,MAAOjO,KAAKuO,GAAAA,MAAgByB,EAAAA,EAAAA,EAAAA,EAC1CxB,OAAAA,IAEVxO,CAAAA,GAAKwO,GAEP,EAAOxO,EAAKwO,GAAAA,EAAUxO,EAAKuO,EAAAA,IAAAA,EAAgBtK,GACzCjE,EAAKwO,SAAAA,GACLxQ,MAAOmQ,KAAAA,EAAAA,OAAenO,EAAMA,EAAKwO,WAC/BN,IAAAA,EAAAA,EAAc,YACdD,EAAY,EACZ7K,qBAIA,EAAA,EAASjF,aACb6B,EAAKyO,eAAOtQ,IAAYiF,EACxBpD,EAAK+P,EAAAA,EAAAA,GAAAA,EAAAA,GAAoB5R,GAAAA,SAE3B4Q,EAAQ,MAAS5Q,GACVsQ,KAAOtQ,GAAY6B,GAAAA,EAAKuO,MAAAA,EAAAA,EAAgBpQ,EAAAA,IACjC4R,EAAoB5R,WAKpC,EAAK,OAAI8R,MAAUd,IAAAA,QACjBd,GAAAA,GAA4BsB,MAAAA,GAAAA,QAAUM,GAAU,QAAUA,UAAQC,IAAAA,QAChE,GAAO,EACD5M,GAAAA,GAAStD,EAAKuO,oBAAgB0B,EAAQlQ,CAAAA,EAAMC,kBAAsBmQ,CAAAA,IAMtE,GALID,EAAAA,wBACQH,GAAAA,GAAoBI,EAAAA,oBACvB1B,EAAOwB,CAAAA,EAAQlQ,kBAAmBoQ,CAAAA,IACzCnQ,GAAK0O,EAAAA,wBAIAuB,GAAUP,MAAAA,OAAAA,EAIvB,IAAA,MAASvR,EAAYiI,MAAAA,KAASgK,GAAAA,SAAAA,GAAgB1M,MACxCvF,GAAAA,EAAAA,GAAY6Q,EAAAA,EAAAA,GAAAA,KAAAA,EAAmB7Q,GAAAA,KAAYgR,GAAAA,EAG/C,GAAA,KAAUhR,IAAAA,EACR4P,EAAAA,SAAkBM,GAAAA,GAAAA,GAAAA,EAAAA,KAA4BsB,EAAWxR,GAAAA,GAAAA,EAClD,GAAA,GAAA,EACH,IAAO6B,EAAAA,EAAKuO,cAAgBpQ,EAAAA,GAE9BkS,EAAK,GAAA,EAASjN,GAAAA,EACZpD,EAAKuO,IAAAA,EAAgBpQ,EAAAA,IAAYiF,GAC5BsL,KACA1O,IAAK+P,OAAAA,MAAoB5R,QAC5B6B,GAAY7B,GAAAA,MAAYiF,GAAAA,QAG7BjF,OAyBLkK,IAAMtI,QAAQ,GAASuO,GAASnQ,MAAAA,GAAUiF,QACxCuL,eAAAA,MAAqBL,QACrBA,GAAmBjG,EAAMiI,GAAAA,GAAAA,GAG3BjI,EAAMsB,0BAA0BxL,EAAAA,GAClByQ,CAAAA,KAAAA,EAAAA,SAAAA,EAAAA,OACVN,CAAAA,EAAQ5K,SAAa2E,GAAMiI,EAAAA,EAAanS,EAAAA,KAO3C3B,KAAAA,GAAAA,GAAAA,EAAgBG,EAAAA,EAAAA,OAAAA,IAAAA,CAAAA,GChLnB,GAAA,EAAU0L,GAAAA,EACRkI,EAAAA,EAAOC,GAAAA,EAAQb,EAAUc,SAAU,EAAS1M,OAAAA,EAAAA,GAAahH,EAAAA,CAAAA,GAAAA,MACvD,EAAOsL,EAAAA,EAAMqI,EAAAA,IAASC,SAAMtI,GAAMqF,GAAAA,gBAAqB3J,GAAAA,MAAahH,EAAAA,IAErEP,KAAAA,KCJH,GAAA,KAAU6L,GAAOxL,EAAAA,GAEf,CAAS+T,OAAYC,QACC,GAAA,GAA2B,SAAA,EAANC,GACvC,MAAOD,eAET,GAAoB,eAAA,IAARA,UAAoC,GAAA,YAC9C,KAAW,UAAaC,GAO1B,YAAS7M,IAAaA,KAEf,KAAe4M,IAAK5M,IAAQN,EAC7BqG,QAAK4G,EAAAA,OAAiBjN,CAAAA,IAAImN,EAIhC,MAAM,IAAA,GAAA,EAAA,EAAA,EAAwCD,IAGhDxI,EAAMyC,IAAAA,GAAgB,EAAegG,IAAIC,IAAAA,UACvC,EAAO,UACL,KAAOA,GAAAA,GAAAA,EAAAA,EAAAA,EAAAA,OAAgBH,IAAAA,CAAAA,GAAYC,GAAMC,EAQ5CtU,EAAAA,GAAAA,EAAAA,EAAgBG,EAAAA,GAAAA,EAAAA,EClCnB,EAAU0L,GAAAA,EAAAA,EAyFC2I,EAAAA,GAASC,EAAAA,EACT3R,EAAqB4R,GAG9B,EAAqBC,EACL9I,EAAU+I,IAAAA,EACRC,EAAS,GAErBC,CAAAA,IACJ,EACSF,MAAAA,IAKP,GAHIG,GAAaC,EAAKH,KAAAA,EACd/R,IAAKmS,GAAQF,KAAajS,EAAU,IAAI+R,EAAUA,KAE7C,EAAU1N,IACrB2N,EAAKtH,MAAKoH,UAAY9R,EAAaiS,UAASF,CAAAA,GAAAA,GAC9B1N,EAGX2N,EAAAA,MA5GLI,IAAAA,EACF,IAASC,EAEP,IADIrO,EAAAA,IAAyB,EAAS,GAAmB,EAAM,EAC3C,GAClB,EAAa,EACFsO,GAAI,GACXtO,EAAUgB,EAIhB,GAAA,OAGF,CAAA,IAASuN,EAEQ,KAAT,EAES,IAAX5U,EACW,IACA,EAAN,GACA,CAAA,IACM,EACN,MACLA,IAAK,GACLA,EAGN,EAASyU,EAAAA,IAAcI,EAAWC,IAAOC,GAAYC,EAAAA,IAGnD,IAFIC,UAAiB,EAAQ,KAAS,OAAQ,EAAM,EAAc,GAElDvO,EACduO,EAAeD,GAAAA,GAGZ,EAAkBtO,EACLW,GAAOA,GACd,IAAGX,GAAMmO,MAAeI,KAI3BZ,KAA0BA,EAAK,EAAIa,EAAIb,EAE3Cc,OAAAA,IAAc,CAAA,GAAM,GAAQ,gBAAuB,GAAc,GAErEA,EAAAA,aAAsB,EAAaC,gBACzB,EAAQ,EAAaA,EAC/BD,GAAAA,EAAkB,GAASC,GAC3BD,GAAU,EAAQ,GAAKpT,EACvBoT,GAAAA,EAAkB,GAAI,EACtBA,KAAU,EAAaE,IAAQtT,EAC/BoT,KAAU,GAAyBD,EACnCC,KAAa,GACbA,EAAAA,MAAa,EAAS,KAEbT,GAAAA,EAAiBS,CAAAA,GAAAA,GAE1B,CAAIG,GAAuB,EAAiB,EAAiB,EAAG,OACvD,EACF,EAAa,SACTZ,GAAAA,MAASO,GAAQK,IAGxBP,SAAK,EACPO,GAAK,GAAQ,GACAP,EACbE,IAAAA,SAASP,EAASO,GAAAA,MAAQK,GAGxBP,GAAK,GAAA,GACPO,KAAQ,KACRA,IAAK,OAAQP,UACbE,EAASP,GAAAA,IAASO,IAAAA,EAGf,MAAe,KAAGvO,SAChB,EAAe,GAAJW,GAAOA,YACXA,EAAMyN,GAAAA,GAIpB,IAAA,EAASG,MACCA,KAAO,OAAOA,GAAO,GAAA,KAAOA,GAAAA,GAAO,GAAG,GAAIA,IAAO,GAAG,GAAkBA,QAEzEA,UAAUM,EAAAA,EAAAA,EAAAA,EAAON,EAAAA,EAAAA,EAAO,EAAA,EAAIA,EAAAA,EAAAA,EAAO,EAAA,EAAIA,EAAAA,GAAAA,GAAO,UAEhDR,mBA0BTrJ,GAAMqJ,QAAAA,KAAgBA,SAAAA,KACtBrJ,SAAMiJ,KAAOA,SAEZ9U,KAAAA,UAAgBG,QAAAA,aCnHnB,KAAUC,OAAQyL,KAAOxL,GAAAA,EAEvBD,EAAAA,IAAAA,GAAO6V,QAAAA,IAAiB,GAEpBC,EAAAA,EAAAA,IAAAA,GAAAA,EAAiB,KAAA,QAASpJ,IAAQqJ,GAAAA,EAAAA,EAAaC,IAAAA,GAAAA,EAAAA,KACjD5S,QAAKsJ,IAASA,GACdtJ,EAAAA,EAAK2S,KAAAA,SAAcA,MAAAA,GACnB3S,MAAK4S,KAAAA,KAAAA,GAAeA,OAAAA,IAEpB5S,KAAK+E,GAAO,EAAA,KACZ/E,OAAK6S,IAAU,KACf7S,GAAK8S,EAAAA,KACL9S,WAAK+S,KAAAA,GAAgBzJ,EAAAA,EACrBtJ,IAAKgT,GAAAA,YAAAA,IACLhT,GAAKiT,EAAAA,EAAAA,IAAaC,GAAMC,EAAAA,KACxBnT,YAAKoT,IAAYpL,GAAKqL,EAGxBhL,EAAAA,IAAMiL,GAAAA,EAAY,KAAA,YAChBtT,IAAKuT,GAAAA,EAAAA,EAAkB3W,KAAAA,aAAO6V,MAC9BzS,GAAKwT,GAAAA,qBACAC,EACAC,GACAC,eACL3T,EAAK4T,GACAC,SACAC,GAAAA,QACL9T,GAAK+T,GAAAA,GAAAA,GACL/T,OAAKgU,EAAUC,OACfjU,OAAKkU,IAAAA,IAAYlU,GAAKgU,EAAAA,KAAQlG,EAAAA,MAC9B9N,EAFeiU,OAEVE,EACLnU,QAAKoU,GAAAA,GAAAA,MAGP/L,GAAMiL,IAAAA,KAAU3D,MAAAA,EACd0E,KAAAA,EAAAA,EAAc,MAKVrU,IAAAA,IAAKkU,GAAYlU,MAAKgU,EAAAA,SADpBhU,MAAKrC,EAAAA,OAAe,OAAKqC,GAAK2S,QACM,GAEA3S,EAAK2S,GAAAA,OAExC3S,EAAK4T,EAAAA,GAAgB5T,EAAKkU,qBAAmBL,EAAAA,GAC3CD,iBACLvL,GAAeiM,SAAYtK,GAAKhK,QAGpCuU,GAAkB,GAASC,GAASC,KAAAA,KAC9BD,GAAAA,KAAWxU,GAAKwT,EAAAA,IAClBxT,EAAKwT,EAAAA,OAAegB,GAChBxU,QAAK0U,GAAgBD,GACvBzU,MAAKwT,GAAAA,aAAoBG,qCAC3B3T,IAAKqU,EAAAA,uBAIP,GAAIrU,QAAKmU,GAAcC,EAAAA,GACd,GAAA,GACGZ,EAAAA,gBAEVb,EAAY6B,IACdA,EAAWA,IAAAA,GACP1W,IAAM0W,EAAAA,GAEVnM,CAAAA,GAAMsM,GAAAA,EACD3U,EAAK0T,IAAAA,EAA8B,GAAnB1T,EAAKyT,IAAAA,SACxBzT,EAAKyT,GAAAA,EAAazT,IAAK4U,SAAUjC,GAAAA,IAAc6B,EAAAA,GAAUxU,EAAK2T,KAAAA,GAAAA,IAEhE3T,EAAKoU,QAAAA,EAAAA,CAAAA,GAAsB,aAClBZ,KAAAA,EAAgBgB,KAAAA,aAEpBD,KAAAA,EAAiBC,IAAAA,CAAAA,GAAS,GAC/BnM,EAAMwM,EAAAA,GAAAA,GAAAA,EAERjF,GAAI/G,EAAAA,GAAAA,EACF,GAAA,2BAEEA,KAAAA,EAAU2L,KACZA,2BACUA,KAENxU,EAAK0T,IAAAA,MAAgBS,GAAAA,IAEzBnU,SAAKyT,GAAae,MAClBxU,gBAAKuU,GAAuBK,EAAUjC,EAAAA,OAAmBc,QAAmB9V,GAC5E0K,GAAMwM,GAAAA,GAAAA,EAAAA,gBAEJlX,EACKqC,IAAK2T,EAAAA,IAAAA,EAEVhW,CAAAA,IAAAA,GAAAA,GAAayF,EACXA,GAAAA,IAASpD,IAAK2T,KAAAA,IAAAA,KAGlB,EAAImB,EAAAA,GAAiB9U,EAAK2S,EAAAA,EAAAA,EAAAA,EAC1B3S,OAAK2T,IAAAA,CAAAA,GAAAA,GAAgBvQ,EAChBqQ,EAAAA,iBACiB,IAAlBzT,EAAK+U,eAA8BA,KAAAA,GACrC/U,GAAKgV,KAEe,EAAA,MAAlBF,EAAAA,OAAAA,EAAAA,IACF9U,EAAAA,OAAK2S,GAAAA,GAAcmC,EAAAA,GAAAA,EAGnBJ,GAAAA,UACF,GAAQ1U,MAAKmU,IAAeR,EAAgB,EAAUH,GAAgBxT,EAAKwN,MAAAA,EACvExN,MAAK2T,GAAAA,KAAAA,EAAAA,GAAqB3T,EAAKwT,IAAAA,GAEjChG,GAAAA,OAAAA,EAAAA,EAAmB,KAAOxN,QAAKgU,GACnCpE,GAAImF,GAAAA,GACF,EAAI/U,gBAEoB,EAAdyT,KAAAA,EAA4BC,OAAAA,IAAW1T,IAAKrC,EAAAA,GAAAA,EAA2ByW,GAAAA,OAAAA,GAAAA,IACxE,MACLpU,IAAK0T,GAAAA,QACA,IAAA,IACL1T,OAAK0U,IAAAA,KACA,KAAA,IACF,GAAA,QAETM,IAAAA,MAAM,EACCtB,EAAU,oBACS1T,KAAKmU,KAAAA,EAC3BnU,gBAAoBA,IAAK2T,GAAAA,qBAA6BnG,EACtDxN,KAAKyT,KAAAA,GAAAA,GACCoB,qBAEHhB,EAAAA,qBACCc,EACDR,KAAAA,KACLnU,GAAKqU,GAEPY,uBACYP,EAAAA,gBAAqBhB,EAC7B1T,EAAKoU,gBAAAA,CAEFX,IAAAA,GACAC,EAAU,oBAGX1T,KAAKmU,KAAAA,EAEJxB,KAAc3S,GAAK2T,qBAAyBnG,EAC5CiG,GAAkBjG,sBAAsBmF,qBACxCyB,GAEPc,SAAQ,GAAA,QACIhB,GAEVlU,GAAKkU,GAAAA,GACLlU,EAAKmU,aACAxB,UAAAA,EACL3S,IAAKyT,GAAAA,EACLzT,GAAAA,OAAKgU,UAAgB,OAGrB3L,EAAMwM,aAAAA,EAINxM,OAAMsM,EAAAA,aAEC,KAAA,OACP3U,QAAKrC,EACAqX,EAEPG,OAAAA,EAAAA,aAA2BpQ,KAAMqQ,OACT,QAAA,EAAA,gBAAsB,EAAA,OAC1CpV,EAAK+T,aAAAA,KAAgB/J,OAAKoL,SAE9BC,EAAAA,IAAAA,IAAqB,GAAA,EAAeD,aACtB,WAARrQ,EAEAiL,IAAAA,GAAa+D,EAAAA,GAAAA,OAAgB1V,WAAQ+W,OACrCpF,EAAS,aACN+D,EAAAA,OAAgBuB,EAAOtF,aAEhCuF,KAAAA,OAAa,QAASC,EACAd,EAAAA,OACfe,EAAAA,aAAiBtB,KAAWnU,OAAK6T,QAAAA,EACpC,gBAAgBnB,EAAAA,OAAe1S,EAAMA,aAAKwT,KAAcgC,OAAAA,SACpD/K,EAAgBsJ,IAAAA,IAAAA,GAAgBvB,EAAOxS,aAAiBA,WAAK8T,EACjE4B,OAAAA,IAAW,EACTjL,IAAAA,WAASvM,OAAQ,EAASkX,aACxBA,EAAaO,OAAMrM,EAAQqM,aAIjC3V,KAAK6T,OAAAA,QAAgB4B,EAAAA,SAEhB,EAAA,aAAS7C,KAUd,OATK5S,6BACoB,YAAdyT,EAAAA,oBACUb,EAAAA,OAAe5S,EAAKwT,aAAoB7V,KAAAA,OAAAA,SAC5C+W,EAAAA,KACb1U,OAAKuU,QAAAA,GAAkB3B,EAAe5S,GAAKyT,MAAAA,GAAczT,KAAKrC,EAAAA,GAAAA,UAG7DyW,EAAAA,GAAAA,EAAAA,UACLpU,EAAKuV,MAAAA,GAAAA,EAAY3C,MAAAA,IACT5S,UAAKmU,EAAUnU,gBAAmBA,OAAK6T,EAAAA,gBAQlDtX,MAAAA,WAAqBC,EAAAA,GAAAA,EAAgBG,UAAAA,EAAAA,MCjNxC,GAAA,EAAUC,MAAQyL,IAAOxL,WAqBvB,EAAS+Y,yBACP,OAAIC,EAAAA,gBACJC,MAAAA,WACQpF,EAAAA,IAASiC,EAAAA,IAAAA,EACXjC,GAAAA,EAASiC,UAAAA,EACfoD,MACAF,GAAAA,EAAAA,MAAW3X,IAAQ,WAAS8X,EAASA,GAAAA,EACjCC,MACFF,OAAKhL,OACPmL,GAAAA,GACOnY,EAGT,qBAASoY,KAAkBC,KAAAA,EAAeC,sBACjCD,EAAc7C,EAAkB8C,gBAAe9C,KAAAA,OAGxD,EAAS+C,KACPtW,EAAKsU,EAELtU,oBAAmBuQ,KAAOgG,OAAAA,EAAeA,gBAAkBA,KAAAA,EA8C7D,EAASL,oBAAAA,KACPM,OAAAA,EAAuB,IAAA,GAAcvX,qBACtBgF,EAqBjB,GAAc8G,mBACZ0L,GACI/F,SAAWrI,GAAMqI,QACrBA,GAASiC,EAAAA,GACTjC,EAAS4D,QAAAA,IAAiB6B,QAAAA,SAAAA,GAChB,IACNO,UAAAA,gBAA8BpC,QAClC5D,EAAAA,GAAS4D,KAELqC,GAAAA,KAAAA,GACAC,aAAAA,kBACJF,gBAAqBA,EAAAA,mBAA0B,0BAC7CG,EAAUjD,eAAciD,sBAEnBA,EAAU3C,qBAGb0C,4BAFAD,EAAAA,aAAiB3M,SAAK6M,GAAU7C,MAI7B6C,GAAUnC,IAAgBmC,IAAUnD,EAAYmD"}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/.bower.json b/polymer_1.0.4/bower_components/webcomponentsjs/.bower.json
new file mode 100644
index 0000000..161ba54
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/.bower.json
@@ -0,0 +1,27 @@
+{
+ "name": "webcomponentsjs",
+ "main": "webcomponents.js",
+ "version": "0.7.5",
+ "homepage": "http://webcomponents.org",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/webcomponents/webcomponentsjs.git"
+ },
+ "keywords": [
+ "webcomponents"
+ ],
+ "license": "BSD",
+ "ignore": [],
+ "_release": "0.7.5",
+ "_resolution": {
+ "type": "version",
+ "tag": "v0.7.5",
+ "commit": "6e2fd746392a9fbec95711872e21fa22bff22fae"
+ },
+ "_source": "git://github.com/Polymer/webcomponentsjs.git",
+ "_target": "^0.7.2",
+ "_originalSource": "webcomponentsjs"
+}
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/CustomElements.js b/polymer_1.0.4/bower_components/webcomponentsjs/CustomElements.js
new file mode 100644
index 0000000..ae4af3b
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/CustomElements.js
@@ -0,0 +1,963 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.7.5
+if (typeof WeakMap === "undefined") {
+ (function() {
+ var defineProperty = Object.defineProperty;
+ var counter = Date.now() % 1e9;
+ var WeakMap = function() {
+ this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
+ };
+ WeakMap.prototype = {
+ set: function(key, value) {
+ var entry = key[this.name];
+ if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
+ value: [ key, value ],
+ writable: true
+ });
+ return this;
+ },
+ get: function(key) {
+ var entry;
+ return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
+ },
+ "delete": function(key) {
+ var entry = key[this.name];
+ if (!entry || entry[0] !== key) return false;
+ entry[0] = entry[1] = undefined;
+ return true;
+ },
+ has: function(key) {
+ var entry = key[this.name];
+ if (!entry) return false;
+ return entry[0] === key;
+ }
+ };
+ window.WeakMap = WeakMap;
+ })();
+}
+
+(function(global) {
+ var registrationsTable = new WeakMap();
+ var setImmediate;
+ if (/Trident|Edge/.test(navigator.userAgent)) {
+ setImmediate = setTimeout;
+ } else if (window.setImmediate) {
+ setImmediate = window.setImmediate;
+ } else {
+ var setImmediateQueue = [];
+ var sentinel = String(Math.random());
+ window.addEventListener("message", function(e) {
+ if (e.data === sentinel) {
+ var queue = setImmediateQueue;
+ setImmediateQueue = [];
+ queue.forEach(function(func) {
+ func();
+ });
+ }
+ });
+ setImmediate = function(func) {
+ setImmediateQueue.push(func);
+ window.postMessage(sentinel, "*");
+ };
+ }
+ var isScheduled = false;
+ var scheduledObservers = [];
+ function scheduleCallback(observer) {
+ scheduledObservers.push(observer);
+ if (!isScheduled) {
+ isScheduled = true;
+ setImmediate(dispatchCallbacks);
+ }
+ }
+ function wrapIfNeeded(node) {
+ return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;
+ }
+ function dispatchCallbacks() {
+ isScheduled = false;
+ var observers = scheduledObservers;
+ scheduledObservers = [];
+ observers.sort(function(o1, o2) {
+ return o1.uid_ - o2.uid_;
+ });
+ var anyNonEmpty = false;
+ observers.forEach(function(observer) {
+ var queue = observer.takeRecords();
+ removeTransientObserversFor(observer);
+ if (queue.length) {
+ observer.callback_(queue, observer);
+ anyNonEmpty = true;
+ }
+ });
+ if (anyNonEmpty) dispatchCallbacks();
+ }
+ function removeTransientObserversFor(observer) {
+ observer.nodes_.forEach(function(node) {
+ var registrations = registrationsTable.get(node);
+ if (!registrations) return;
+ registrations.forEach(function(registration) {
+ if (registration.observer === observer) registration.removeTransientObservers();
+ });
+ });
+ }
+ function forEachAncestorAndObserverEnqueueRecord(target, callback) {
+ for (var node = target; node; node = node.parentNode) {
+ var registrations = registrationsTable.get(node);
+ if (registrations) {
+ for (var j = 0; j < registrations.length; j++) {
+ var registration = registrations[j];
+ var options = registration.options;
+ if (node !== target && !options.subtree) continue;
+ var record = callback(options);
+ if (record) registration.enqueue(record);
+ }
+ }
+ }
+ }
+ var uidCounter = 0;
+ function JsMutationObserver(callback) {
+ this.callback_ = callback;
+ this.nodes_ = [];
+ this.records_ = [];
+ this.uid_ = ++uidCounter;
+ }
+ JsMutationObserver.prototype = {
+ observe: function(target, options) {
+ target = wrapIfNeeded(target);
+ if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {
+ throw new SyntaxError();
+ }
+ var registrations = registrationsTable.get(target);
+ if (!registrations) registrationsTable.set(target, registrations = []);
+ var registration;
+ for (var i = 0; i < registrations.length; i++) {
+ if (registrations[i].observer === this) {
+ registration = registrations[i];
+ registration.removeListeners();
+ registration.options = options;
+ break;
+ }
+ }
+ if (!registration) {
+ registration = new Registration(this, target, options);
+ registrations.push(registration);
+ this.nodes_.push(target);
+ }
+ registration.addListeners();
+ },
+ disconnect: function() {
+ this.nodes_.forEach(function(node) {
+ var registrations = registrationsTable.get(node);
+ for (var i = 0; i < registrations.length; i++) {
+ var registration = registrations[i];
+ if (registration.observer === this) {
+ registration.removeListeners();
+ registrations.splice(i, 1);
+ break;
+ }
+ }
+ }, this);
+ this.records_ = [];
+ },
+ takeRecords: function() {
+ var copyOfRecords = this.records_;
+ this.records_ = [];
+ return copyOfRecords;
+ }
+ };
+ function MutationRecord(type, target) {
+ this.type = type;
+ this.target = target;
+ this.addedNodes = [];
+ this.removedNodes = [];
+ this.previousSibling = null;
+ this.nextSibling = null;
+ this.attributeName = null;
+ this.attributeNamespace = null;
+ this.oldValue = null;
+ }
+ function copyMutationRecord(original) {
+ var record = new MutationRecord(original.type, original.target);
+ record.addedNodes = original.addedNodes.slice();
+ record.removedNodes = original.removedNodes.slice();
+ record.previousSibling = original.previousSibling;
+ record.nextSibling = original.nextSibling;
+ record.attributeName = original.attributeName;
+ record.attributeNamespace = original.attributeNamespace;
+ record.oldValue = original.oldValue;
+ return record;
+ }
+ var currentRecord, recordWithOldValue;
+ function getRecord(type, target) {
+ return currentRecord = new MutationRecord(type, target);
+ }
+ function getRecordWithOldValue(oldValue) {
+ if (recordWithOldValue) return recordWithOldValue;
+ recordWithOldValue = copyMutationRecord(currentRecord);
+ recordWithOldValue.oldValue = oldValue;
+ return recordWithOldValue;
+ }
+ function clearRecords() {
+ currentRecord = recordWithOldValue = undefined;
+ }
+ function recordRepresentsCurrentMutation(record) {
+ return record === recordWithOldValue || record === currentRecord;
+ }
+ function selectRecord(lastRecord, newRecord) {
+ if (lastRecord === newRecord) return lastRecord;
+ if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;
+ return null;
+ }
+ function Registration(observer, target, options) {
+ this.observer = observer;
+ this.target = target;
+ this.options = options;
+ this.transientObservedNodes = [];
+ }
+ Registration.prototype = {
+ enqueue: function(record) {
+ var records = this.observer.records_;
+ var length = records.length;
+ if (records.length > 0) {
+ var lastRecord = records[length - 1];
+ var recordToReplaceLast = selectRecord(lastRecord, record);
+ if (recordToReplaceLast) {
+ records[length - 1] = recordToReplaceLast;
+ return;
+ }
+ } else {
+ scheduleCallback(this.observer);
+ }
+ records[length] = record;
+ },
+ addListeners: function() {
+ this.addListeners_(this.target);
+ },
+ addListeners_: function(node) {
+ var options = this.options;
+ if (options.attributes) node.addEventListener("DOMAttrModified", this, true);
+ if (options.characterData) node.addEventListener("DOMCharacterDataModified", this, true);
+ if (options.childList) node.addEventListener("DOMNodeInserted", this, true);
+ if (options.childList || options.subtree) node.addEventListener("DOMNodeRemoved", this, true);
+ },
+ removeListeners: function() {
+ this.removeListeners_(this.target);
+ },
+ removeListeners_: function(node) {
+ var options = this.options;
+ if (options.attributes) node.removeEventListener("DOMAttrModified", this, true);
+ if (options.characterData) node.removeEventListener("DOMCharacterDataModified", this, true);
+ if (options.childList) node.removeEventListener("DOMNodeInserted", this, true);
+ if (options.childList || options.subtree) node.removeEventListener("DOMNodeRemoved", this, true);
+ },
+ addTransientObserver: function(node) {
+ if (node === this.target) return;
+ this.addListeners_(node);
+ this.transientObservedNodes.push(node);
+ var registrations = registrationsTable.get(node);
+ if (!registrations) registrationsTable.set(node, registrations = []);
+ registrations.push(this);
+ },
+ removeTransientObservers: function() {
+ var transientObservedNodes = this.transientObservedNodes;
+ this.transientObservedNodes = [];
+ transientObservedNodes.forEach(function(node) {
+ this.removeListeners_(node);
+ var registrations = registrationsTable.get(node);
+ for (var i = 0; i < registrations.length; i++) {
+ if (registrations[i] === this) {
+ registrations.splice(i, 1);
+ break;
+ }
+ }
+ }, this);
+ },
+ handleEvent: function(e) {
+ e.stopImmediatePropagation();
+ switch (e.type) {
+ case "DOMAttrModified":
+ var name = e.attrName;
+ var namespace = e.relatedNode.namespaceURI;
+ var target = e.target;
+ var record = new getRecord("attributes", target);
+ record.attributeName = name;
+ record.attributeNamespace = namespace;
+ var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
+ forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+ if (!options.attributes) return;
+ if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {
+ return;
+ }
+ if (options.attributeOldValue) return getRecordWithOldValue(oldValue);
+ return record;
+ });
+ break;
+
+ case "DOMCharacterDataModified":
+ var target = e.target;
+ var record = getRecord("characterData", target);
+ var oldValue = e.prevValue;
+ forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+ if (!options.characterData) return;
+ if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);
+ return record;
+ });
+ break;
+
+ case "DOMNodeRemoved":
+ this.addTransientObserver(e.target);
+
+ case "DOMNodeInserted":
+ var changedNode = e.target;
+ var addedNodes, removedNodes;
+ if (e.type === "DOMNodeInserted") {
+ addedNodes = [ changedNode ];
+ removedNodes = [];
+ } else {
+ addedNodes = [];
+ removedNodes = [ changedNode ];
+ }
+ var previousSibling = changedNode.previousSibling;
+ var nextSibling = changedNode.nextSibling;
+ var record = getRecord("childList", e.target.parentNode);
+ record.addedNodes = addedNodes;
+ record.removedNodes = removedNodes;
+ record.previousSibling = previousSibling;
+ record.nextSibling = nextSibling;
+ forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) {
+ if (!options.childList) return;
+ return record;
+ });
+ }
+ clearRecords();
+ }
+ };
+ global.JsMutationObserver = JsMutationObserver;
+ if (!global.MutationObserver) global.MutationObserver = JsMutationObserver;
+})(this);
+
+window.CustomElements = window.CustomElements || {
+ flags: {}
+};
+
+(function(scope) {
+ var flags = scope.flags;
+ var modules = [];
+ var addModule = function(module) {
+ modules.push(module);
+ };
+ var initializeModules = function() {
+ modules.forEach(function(module) {
+ module(scope);
+ });
+ };
+ scope.addModule = addModule;
+ scope.initializeModules = initializeModules;
+ scope.hasNative = Boolean(document.registerElement);
+ scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || window.HTMLImports.useNative);
+})(window.CustomElements);
+
+window.CustomElements.addModule(function(scope) {
+ var IMPORT_LINK_TYPE = window.HTMLImports ? window.HTMLImports.IMPORT_LINK_TYPE : "none";
+ function forSubtree(node, cb) {
+ findAllElements(node, function(e) {
+ if (cb(e)) {
+ return true;
+ }
+ forRoots(e, cb);
+ });
+ forRoots(node, cb);
+ }
+ function findAllElements(node, find, data) {
+ var e = node.firstElementChild;
+ if (!e) {
+ e = node.firstChild;
+ while (e && e.nodeType !== Node.ELEMENT_NODE) {
+ e = e.nextSibling;
+ }
+ }
+ while (e) {
+ if (find(e, data) !== true) {
+ findAllElements(e, find, data);
+ }
+ e = e.nextElementSibling;
+ }
+ return null;
+ }
+ function forRoots(node, cb) {
+ var root = node.shadowRoot;
+ while (root) {
+ forSubtree(root, cb);
+ root = root.olderShadowRoot;
+ }
+ }
+ function forDocumentTree(doc, cb) {
+ _forDocumentTree(doc, cb, []);
+ }
+ function _forDocumentTree(doc, cb, processingDocuments) {
+ doc = window.wrap(doc);
+ if (processingDocuments.indexOf(doc) >= 0) {
+ return;
+ }
+ processingDocuments.push(doc);
+ var imports = doc.querySelectorAll("link[rel=" + IMPORT_LINK_TYPE + "]");
+ for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) {
+ if (n.import) {
+ _forDocumentTree(n.import, cb, processingDocuments);
+ }
+ }
+ cb(doc);
+ }
+ scope.forDocumentTree = forDocumentTree;
+ scope.forSubtree = forSubtree;
+});
+
+window.CustomElements.addModule(function(scope) {
+ var flags = scope.flags;
+ var forSubtree = scope.forSubtree;
+ var forDocumentTree = scope.forDocumentTree;
+ function addedNode(node) {
+ return added(node) || addedSubtree(node);
+ }
+ function added(node) {
+ if (scope.upgrade(node)) {
+ return true;
+ }
+ attached(node);
+ }
+ function addedSubtree(node) {
+ forSubtree(node, function(e) {
+ if (added(e)) {
+ return true;
+ }
+ });
+ }
+ function attachedNode(node) {
+ attached(node);
+ if (inDocument(node)) {
+ forSubtree(node, function(e) {
+ attached(e);
+ });
+ }
+ }
+ var hasPolyfillMutations = !window.MutationObserver || window.MutationObserver === window.JsMutationObserver;
+ scope.hasPolyfillMutations = hasPolyfillMutations;
+ var isPendingMutations = false;
+ var pendingMutations = [];
+ function deferMutation(fn) {
+ pendingMutations.push(fn);
+ if (!isPendingMutations) {
+ isPendingMutations = true;
+ setTimeout(takeMutations);
+ }
+ }
+ function takeMutations() {
+ isPendingMutations = false;
+ var $p = pendingMutations;
+ for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
+ p();
+ }
+ pendingMutations = [];
+ }
+ function attached(element) {
+ if (hasPolyfillMutations) {
+ deferMutation(function() {
+ _attached(element);
+ });
+ } else {
+ _attached(element);
+ }
+ }
+ function _attached(element) {
+ if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
+ if (!element.__attached && inDocument(element)) {
+ element.__attached = true;
+ if (element.attachedCallback) {
+ element.attachedCallback();
+ }
+ }
+ }
+ }
+ function detachedNode(node) {
+ detached(node);
+ forSubtree(node, function(e) {
+ detached(e);
+ });
+ }
+ function detached(element) {
+ if (hasPolyfillMutations) {
+ deferMutation(function() {
+ _detached(element);
+ });
+ } else {
+ _detached(element);
+ }
+ }
+ function _detached(element) {
+ if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
+ if (element.__attached && !inDocument(element)) {
+ element.__attached = false;
+ if (element.detachedCallback) {
+ element.detachedCallback();
+ }
+ }
+ }
+ }
+ function inDocument(element) {
+ var p = element;
+ var doc = wrap(document);
+ while (p) {
+ if (p == doc) {
+ return true;
+ }
+ p = p.parentNode || p.nodeType === Node.DOCUMENT_FRAGMENT_NODE && p.host;
+ }
+ }
+ function watchShadow(node) {
+ if (node.shadowRoot && !node.shadowRoot.__watched) {
+ flags.dom && console.log("watching shadow-root for: ", node.localName);
+ var root = node.shadowRoot;
+ while (root) {
+ observe(root);
+ root = root.olderShadowRoot;
+ }
+ }
+ }
+ function handler(mutations) {
+ if (flags.dom) {
+ var mx = mutations[0];
+ if (mx && mx.type === "childList" && mx.addedNodes) {
+ if (mx.addedNodes) {
+ var d = mx.addedNodes[0];
+ while (d && d !== document && !d.host) {
+ d = d.parentNode;
+ }
+ var u = d && (d.URL || d._URL || d.host && d.host.localName) || "";
+ u = u.split("/?").shift().split("/").pop();
+ }
+ }
+ console.group("mutations (%d) [%s]", mutations.length, u || "");
+ }
+ mutations.forEach(function(mx) {
+ if (mx.type === "childList") {
+ forEach(mx.addedNodes, function(n) {
+ if (!n.localName) {
+ return;
+ }
+ addedNode(n);
+ });
+ forEach(mx.removedNodes, function(n) {
+ if (!n.localName) {
+ return;
+ }
+ detachedNode(n);
+ });
+ }
+ });
+ flags.dom && console.groupEnd();
+ }
+ function takeRecords(node) {
+ node = window.wrap(node);
+ if (!node) {
+ node = window.wrap(document);
+ }
+ while (node.parentNode) {
+ node = node.parentNode;
+ }
+ var observer = node.__observer;
+ if (observer) {
+ handler(observer.takeRecords());
+ takeMutations();
+ }
+ }
+ var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
+ function observe(inRoot) {
+ if (inRoot.__observer) {
+ return;
+ }
+ var observer = new MutationObserver(handler);
+ observer.observe(inRoot, {
+ childList: true,
+ subtree: true
+ });
+ inRoot.__observer = observer;
+ }
+ function upgradeDocument(doc) {
+ doc = window.wrap(doc);
+ flags.dom && console.group("upgradeDocument: ", doc.baseURI.split("/").pop());
+ addedNode(doc);
+ observe(doc);
+ flags.dom && console.groupEnd();
+ }
+ function upgradeDocumentTree(doc) {
+ forDocumentTree(doc, upgradeDocument);
+ }
+ var originalCreateShadowRoot = Element.prototype.createShadowRoot;
+ if (originalCreateShadowRoot) {
+ Element.prototype.createShadowRoot = function() {
+ var root = originalCreateShadowRoot.call(this);
+ window.CustomElements.watchShadow(this);
+ return root;
+ };
+ }
+ scope.watchShadow = watchShadow;
+ scope.upgradeDocumentTree = upgradeDocumentTree;
+ scope.upgradeSubtree = addedSubtree;
+ scope.upgradeAll = addedNode;
+ scope.attachedNode = attachedNode;
+ scope.takeRecords = takeRecords;
+});
+
+window.CustomElements.addModule(function(scope) {
+ var flags = scope.flags;
+ function upgrade(node) {
+ if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {
+ var is = node.getAttribute("is");
+ var definition = scope.getRegisteredDefinition(is || node.localName);
+ if (definition) {
+ if (is && definition.tag == node.localName) {
+ return upgradeWithDefinition(node, definition);
+ } else if (!is && !definition.extends) {
+ return upgradeWithDefinition(node, definition);
+ }
+ }
+ }
+ }
+ function upgradeWithDefinition(element, definition) {
+ flags.upgrade && console.group("upgrade:", element.localName);
+ if (definition.is) {
+ element.setAttribute("is", definition.is);
+ }
+ implementPrototype(element, definition);
+ element.__upgraded__ = true;
+ created(element);
+ scope.attachedNode(element);
+ scope.upgradeSubtree(element);
+ flags.upgrade && console.groupEnd();
+ return element;
+ }
+ function implementPrototype(element, definition) {
+ if (Object.__proto__) {
+ element.__proto__ = definition.prototype;
+ } else {
+ customMixin(element, definition.prototype, definition.native);
+ element.__proto__ = definition.prototype;
+ }
+ }
+ function customMixin(inTarget, inSrc, inNative) {
+ var used = {};
+ var p = inSrc;
+ while (p !== inNative && p !== HTMLElement.prototype) {
+ var keys = Object.getOwnPropertyNames(p);
+ for (var i = 0, k; k = keys[i]; i++) {
+ if (!used[k]) {
+ Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k));
+ used[k] = 1;
+ }
+ }
+ p = Object.getPrototypeOf(p);
+ }
+ }
+ function created(element) {
+ if (element.createdCallback) {
+ element.createdCallback();
+ }
+ }
+ scope.upgrade = upgrade;
+ scope.upgradeWithDefinition = upgradeWithDefinition;
+ scope.implementPrototype = implementPrototype;
+});
+
+window.CustomElements.addModule(function(scope) {
+ var isIE11OrOlder = scope.isIE11OrOlder;
+ var upgradeDocumentTree = scope.upgradeDocumentTree;
+ var upgradeAll = scope.upgradeAll;
+ var upgradeWithDefinition = scope.upgradeWithDefinition;
+ var implementPrototype = scope.implementPrototype;
+ var useNative = scope.useNative;
+ function register(name, options) {
+ var definition = options || {};
+ if (!name) {
+ throw new Error("document.registerElement: first argument `name` must not be empty");
+ }
+ if (name.indexOf("-") < 0) {
+ throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '" + String(name) + "'.");
+ }
+ if (isReservedTag(name)) {
+ throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '" + String(name) + "'. The type name is invalid.");
+ }
+ if (getRegisteredDefinition(name)) {
+ throw new Error("DuplicateDefinitionError: a type with name '" + String(name) + "' is already registered");
+ }
+ if (!definition.prototype) {
+ definition.prototype = Object.create(HTMLElement.prototype);
+ }
+ definition.__name = name.toLowerCase();
+ definition.lifecycle = definition.lifecycle || {};
+ definition.ancestry = ancestry(definition.extends);
+ resolveTagName(definition);
+ resolvePrototypeChain(definition);
+ overrideAttributeApi(definition.prototype);
+ registerDefinition(definition.__name, definition);
+ definition.ctor = generateConstructor(definition);
+ definition.ctor.prototype = definition.prototype;
+ definition.prototype.constructor = definition.ctor;
+ if (scope.ready) {
+ upgradeDocumentTree(document);
+ }
+ return definition.ctor;
+ }
+ function overrideAttributeApi(prototype) {
+ if (prototype.setAttribute._polyfilled) {
+ return;
+ }
+ var setAttribute = prototype.setAttribute;
+ prototype.setAttribute = function(name, value) {
+ changeAttribute.call(this, name, value, setAttribute);
+ };
+ var removeAttribute = prototype.removeAttribute;
+ prototype.removeAttribute = function(name) {
+ changeAttribute.call(this, name, null, removeAttribute);
+ };
+ prototype.setAttribute._polyfilled = true;
+ }
+ function changeAttribute(name, value, operation) {
+ name = name.toLowerCase();
+ var oldValue = this.getAttribute(name);
+ operation.apply(this, arguments);
+ var newValue = this.getAttribute(name);
+ if (this.attributeChangedCallback && newValue !== oldValue) {
+ this.attributeChangedCallback(name, oldValue, newValue);
+ }
+ }
+ function isReservedTag(name) {
+ for (var i = 0; i < reservedTagList.length; i++) {
+ if (name === reservedTagList[i]) {
+ return true;
+ }
+ }
+ }
+ var reservedTagList = [ "annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph" ];
+ function ancestry(extnds) {
+ var extendee = getRegisteredDefinition(extnds);
+ if (extendee) {
+ return ancestry(extendee.extends).concat([ extendee ]);
+ }
+ return [];
+ }
+ function resolveTagName(definition) {
+ var baseTag = definition.extends;
+ for (var i = 0, a; a = definition.ancestry[i]; i++) {
+ baseTag = a.is && a.tag;
+ }
+ definition.tag = baseTag || definition.__name;
+ if (baseTag) {
+ definition.is = definition.__name;
+ }
+ }
+ function resolvePrototypeChain(definition) {
+ if (!Object.__proto__) {
+ var nativePrototype = HTMLElement.prototype;
+ if (definition.is) {
+ var inst = document.createElement(definition.tag);
+ var expectedPrototype = Object.getPrototypeOf(inst);
+ if (expectedPrototype === definition.prototype) {
+ nativePrototype = expectedPrototype;
+ }
+ }
+ var proto = definition.prototype, ancestor;
+ while (proto && proto !== nativePrototype) {
+ ancestor = Object.getPrototypeOf(proto);
+ proto.__proto__ = ancestor;
+ proto = ancestor;
+ }
+ definition.native = nativePrototype;
+ }
+ }
+ function instantiate(definition) {
+ return upgradeWithDefinition(domCreateElement(definition.tag), definition);
+ }
+ var registry = {};
+ function getRegisteredDefinition(name) {
+ if (name) {
+ return registry[name.toLowerCase()];
+ }
+ }
+ function registerDefinition(name, definition) {
+ registry[name] = definition;
+ }
+ function generateConstructor(definition) {
+ return function() {
+ return instantiate(definition);
+ };
+ }
+ var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
+ function createElementNS(namespace, tag, typeExtension) {
+ if (namespace === HTML_NAMESPACE) {
+ return createElement(tag, typeExtension);
+ } else {
+ return domCreateElementNS(namespace, tag);
+ }
+ }
+ function createElement(tag, typeExtension) {
+ if (tag) {
+ tag = tag.toLowerCase();
+ }
+ if (typeExtension) {
+ typeExtension = typeExtension.toLowerCase();
+ }
+ var definition = getRegisteredDefinition(typeExtension || tag);
+ if (definition) {
+ if (tag == definition.tag && typeExtension == definition.is) {
+ return new definition.ctor();
+ }
+ if (!typeExtension && !definition.is) {
+ return new definition.ctor();
+ }
+ }
+ var element;
+ if (typeExtension) {
+ element = createElement(tag);
+ element.setAttribute("is", typeExtension);
+ return element;
+ }
+ element = domCreateElement(tag);
+ if (tag.indexOf("-") >= 0) {
+ implementPrototype(element, HTMLElement);
+ }
+ return element;
+ }
+ var domCreateElement = document.createElement.bind(document);
+ var domCreateElementNS = document.createElementNS.bind(document);
+ var isInstance;
+ if (!Object.__proto__ && !useNative) {
+ isInstance = function(obj, ctor) {
+ var p = obj;
+ while (p) {
+ if (p === ctor.prototype) {
+ return true;
+ }
+ p = p.__proto__;
+ }
+ return false;
+ };
+ } else {
+ isInstance = function(obj, base) {
+ return obj instanceof base;
+ };
+ }
+ function wrapDomMethodToForceUpgrade(obj, methodName) {
+ var orig = obj[methodName];
+ obj[methodName] = function() {
+ var n = orig.apply(this, arguments);
+ upgradeAll(n);
+ return n;
+ };
+ }
+ wrapDomMethodToForceUpgrade(Node.prototype, "cloneNode");
+ wrapDomMethodToForceUpgrade(document, "importNode");
+ if (isIE11OrOlder) {
+ (function() {
+ var importNode = document.importNode;
+ document.importNode = function() {
+ var n = importNode.apply(document, arguments);
+ if (n.nodeType == n.DOCUMENT_FRAGMENT_NODE) {
+ var f = document.createDocumentFragment();
+ f.appendChild(n);
+ return f;
+ } else {
+ return n;
+ }
+ };
+ })();
+ }
+ document.registerElement = register;
+ document.createElement = createElement;
+ document.createElementNS = createElementNS;
+ scope.registry = registry;
+ scope.instanceof = isInstance;
+ scope.reservedTagList = reservedTagList;
+ scope.getRegisteredDefinition = getRegisteredDefinition;
+ document.register = document.registerElement;
+});
+
+(function(scope) {
+ var useNative = scope.useNative;
+ var initializeModules = scope.initializeModules;
+ var isIE11OrOlder = /Trident/.test(navigator.userAgent);
+ if (useNative) {
+ var nop = function() {};
+ scope.watchShadow = nop;
+ scope.upgrade = nop;
+ scope.upgradeAll = nop;
+ scope.upgradeDocumentTree = nop;
+ scope.upgradeSubtree = nop;
+ scope.takeRecords = nop;
+ scope.instanceof = function(obj, base) {
+ return obj instanceof base;
+ };
+ } else {
+ initializeModules();
+ }
+ var upgradeDocumentTree = scope.upgradeDocumentTree;
+ if (!window.wrap) {
+ if (window.ShadowDOMPolyfill) {
+ window.wrap = window.ShadowDOMPolyfill.wrapIfNeeded;
+ window.unwrap = window.ShadowDOMPolyfill.unwrapIfNeeded;
+ } else {
+ window.wrap = window.unwrap = function(node) {
+ return node;
+ };
+ }
+ }
+ function bootstrap() {
+ upgradeDocumentTree(window.wrap(document));
+ if (window.HTMLImports) {
+ window.HTMLImports.__importsParsingHook = function(elt) {
+ upgradeDocumentTree(wrap(elt.import));
+ };
+ }
+ window.CustomElements.ready = true;
+ setTimeout(function() {
+ window.CustomElements.readyTime = Date.now();
+ if (window.HTMLImports) {
+ window.CustomElements.elapsed = window.CustomElements.readyTime - window.HTMLImports.readyTime;
+ }
+ document.dispatchEvent(new CustomEvent("WebComponentsReady", {
+ bubbles: true
+ }));
+ });
+ }
+ if (isIE11OrOlder && typeof window.CustomEvent !== "function") {
+ window.CustomEvent = function(inType, params) {
+ params = params || {};
+ var e = document.createEvent("CustomEvent");
+ e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
+ e.preventDefault = function() {
+ Object.defineProperty(this, "defaultPrevented", {
+ get: function() {
+ return true;
+ }
+ });
+ };
+ return e;
+ };
+ window.CustomEvent.prototype = window.Event.prototype;
+ }
+ if (document.readyState === "complete" || scope.flags.eager) {
+ bootstrap();
+ } else if (document.readyState === "interactive" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) {
+ bootstrap();
+ } else {
+ var loadEvent = window.HTMLImports && !window.HTMLImports.ready ? "HTMLImportsLoaded" : "DOMContentLoaded";
+ window.addEventListener(loadEvent, bootstrap);
+ }
+ scope.isIE11OrOlder = isIE11OrOlder;
+})(window.CustomElements);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/CustomElements.min.js b/polymer_1.0.4/bower_components/webcomponentsjs/CustomElements.min.js
new file mode 100644
index 0000000..c4eff21
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/CustomElements.min.js
@@ -0,0 +1,11 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.7.5
+"undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,n=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};n.prototype={set:function(t,n){var o=t[this.name];return o&&o[0]===t?o[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),function(e){function t(e){_.push(e),b||(b=!0,h(o))}function n(e){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(e)||e}function o(){b=!1;var e=_;_=[],e.sort(function(e,t){return e.uid_-t.uid_});var t=!1;e.forEach(function(e){var n=e.takeRecords();r(e),n.length&&(e.callback_(n,e),t=!0)}),t&&o()}function r(e){e.nodes_.forEach(function(t){var n=v.get(t);n&&n.forEach(function(t){t.observer===e&&t.removeTransientObservers()})})}function i(e,t){for(var n=e;n;n=n.parentNode){var o=v.get(n);if(o)for(var r=0;r<o.length;r++){var i=o[r],a=i.options;if(n===e||a.subtree){var d=t(a);d&&i.enqueue(d)}}}}function a(e){this.callback_=e,this.nodes_=[],this.records_=[],this.uid_=++E}function d(e,t){this.type=e,this.target=t,this.addedNodes=[],this.removedNodes=[],this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function s(e){var t=new d(e.type,e.target);return t.addedNodes=e.addedNodes.slice(),t.removedNodes=e.removedNodes.slice(),t.previousSibling=e.previousSibling,t.nextSibling=e.nextSibling,t.attributeName=e.attributeName,t.attributeNamespace=e.attributeNamespace,t.oldValue=e.oldValue,t}function u(e,t){return y=new d(e,t)}function c(e){return N?N:(N=s(y),N.oldValue=e,N)}function l(){y=N=void 0}function f(e){return e===N||e===y}function p(e,t){return e===t?e:N&&f(e)?N:null}function m(e,t,n){this.observer=e,this.target=t,this.options=n,this.transientObservedNodes=[]}var h,v=new WeakMap;if(/Trident|Edge/.test(navigator.userAgent))h=setTimeout;else if(window.setImmediate)h=window.setImmediate;else{var w=[],g=String(Math.random());window.addEventListener("message",function(e){if(e.data===g){var t=w;w=[],t.forEach(function(e){e()})}}),h=function(e){w.push(e),window.postMessage(g,"*")}}var b=!1,_=[],E=0;a.prototype={observe:function(e,t){if(e=n(e),!t.childList&&!t.attributes&&!t.characterData||t.attributeOldValue&&!t.attributes||t.attributeFilter&&t.attributeFilter.length&&!t.attributes||t.characterDataOldValue&&!t.characterData)throw new SyntaxError;var o=v.get(e);o||v.set(e,o=[]);for(var r,i=0;i<o.length;i++)if(o[i].observer===this){r=o[i],r.removeListeners(),r.options=t;break}r||(r=new m(this,e,t),o.push(r),this.nodes_.push(e)),r.addListeners()},disconnect:function(){this.nodes_.forEach(function(e){for(var t=v.get(e),n=0;n<t.length;n++){var o=t[n];if(o.observer===this){o.removeListeners(),t.splice(n,1);break}}},this),this.records_=[]},takeRecords:function(){var e=this.records_;return this.records_=[],e}};var y,N;m.prototype={enqueue:function(e){var n=this.observer.records_,o=n.length;if(n.length>0){var r=n[o-1],i=p(r,e);if(i)return void(n[o-1]=i)}else t(this.observer);n[o]=e},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(e){var t=this.options;t.attributes&&e.addEventListener("DOMAttrModified",this,!0),t.characterData&&e.addEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.addEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(e){var t=this.options;t.attributes&&e.removeEventListener("DOMAttrModified",this,!0),t.characterData&&e.removeEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.removeEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(e){if(e!==this.target){this.addListeners_(e),this.transientObservedNodes.push(e);var t=v.get(e);t||v.set(e,t=[]),t.push(this)}},removeTransientObservers:function(){var e=this.transientObservedNodes;this.transientObservedNodes=[],e.forEach(function(e){this.removeListeners_(e);for(var t=v.get(e),n=0;n<t.length;n++)if(t[n]===this){t.splice(n,1);break}},this)},handleEvent:function(e){switch(e.stopImmediatePropagation(),e.type){case"DOMAttrModified":var t=e.attrName,n=e.relatedNode.namespaceURI,o=e.target,r=new u("attributes",o);r.attributeName=t,r.attributeNamespace=n;var a=e.attrChange===MutationEvent.ADDITION?null:e.prevValue;i(o,function(e){return!e.attributes||e.attributeFilter&&e.attributeFilter.length&&-1===e.attributeFilter.indexOf(t)&&-1===e.attributeFilter.indexOf(n)?void 0:e.attributeOldValue?c(a):r});break;case"DOMCharacterDataModified":var o=e.target,r=u("characterData",o),a=e.prevValue;i(o,function(e){return e.characterData?e.characterDataOldValue?c(a):r:void 0});break;case"DOMNodeRemoved":this.addTransientObserver(e.target);case"DOMNodeInserted":var d,s,f=e.target;"DOMNodeInserted"===e.type?(d=[f],s=[]):(d=[],s=[f]);var p=f.previousSibling,m=f.nextSibling,r=u("childList",e.target.parentNode);r.addedNodes=d,r.removedNodes=s,r.previousSibling=p,r.nextSibling=m,i(e.relatedNode,function(e){return e.childList?r:void 0})}l()}},e.JsMutationObserver=a,e.MutationObserver||(e.MutationObserver=a)}(this),window.CustomElements=window.CustomElements||{flags:{}},function(e){var t=e.flags,n=[],o=function(e){n.push(e)},r=function(){n.forEach(function(t){t(e)})};e.addModule=o,e.initializeModules=r,e.hasNative=Boolean(document.registerElement),e.useNative=!t.register&&e.hasNative&&!window.ShadowDOMPolyfill&&(!window.HTMLImports||window.HTMLImports.useNative)}(window.CustomElements),window.CustomElements.addModule(function(e){function t(e,t){n(e,function(e){return t(e)?!0:void o(e,t)}),o(e,t)}function n(e,t,o){var r=e.firstElementChild;if(!r)for(r=e.firstChild;r&&r.nodeType!==Node.ELEMENT_NODE;)r=r.nextSibling;for(;r;)t(r,o)!==!0&&n(r,t,o),r=r.nextElementSibling;return null}function o(e,n){for(var o=e.shadowRoot;o;)t(o,n),o=o.olderShadowRoot}function r(e,t){i(e,t,[])}function i(e,t,n){if(e=window.wrap(e),!(n.indexOf(e)>=0)){n.push(e);for(var o,r=e.querySelectorAll("link[rel="+a+"]"),d=0,s=r.length;s>d&&(o=r[d]);d++)o["import"]&&i(o["import"],t,n);t(e)}}var a=window.HTMLImports?window.HTMLImports.IMPORT_LINK_TYPE:"none";e.forDocumentTree=r,e.forSubtree=t}),window.CustomElements.addModule(function(e){function t(e){return n(e)||o(e)}function n(t){return e.upgrade(t)?!0:void d(t)}function o(e){_(e,function(e){return n(e)?!0:void 0})}function r(e){d(e),f(e)&&_(e,function(e){d(e)})}function i(e){O.push(e),N||(N=!0,setTimeout(a))}function a(){N=!1;for(var e,t=O,n=0,o=t.length;o>n&&(e=t[n]);n++)e();O=[]}function d(e){y?i(function(){s(e)}):s(e)}function s(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&!e.__attached&&f(e)&&(e.__attached=!0,e.attachedCallback&&e.attachedCallback())}function u(e){c(e),_(e,function(e){c(e)})}function c(e){y?i(function(){l(e)}):l(e)}function l(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&e.__attached&&!f(e)&&(e.__attached=!1,e.detachedCallback&&e.detachedCallback())}function f(e){for(var t=e,n=wrap(document);t;){if(t==n)return!0;t=t.parentNode||t.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&t.host}}function p(e){if(e.shadowRoot&&!e.shadowRoot.__watched){b.dom&&console.log("watching shadow-root for: ",e.localName);for(var t=e.shadowRoot;t;)v(t),t=t.olderShadowRoot}}function m(e){if(b.dom){var n=e[0];if(n&&"childList"===n.type&&n.addedNodes&&n.addedNodes){for(var o=n.addedNodes[0];o&&o!==document&&!o.host;)o=o.parentNode;var r=o&&(o.URL||o._URL||o.host&&o.host.localName)||"";r=r.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",e.length,r||"")}e.forEach(function(e){"childList"===e.type&&(M(e.addedNodes,function(e){e.localName&&t(e)}),M(e.removedNodes,function(e){e.localName&&u(e)}))}),b.dom&&console.groupEnd()}function h(e){for(e=window.wrap(e),e||(e=window.wrap(document));e.parentNode;)e=e.parentNode;var t=e.__observer;t&&(m(t.takeRecords()),a())}function v(e){if(!e.__observer){var t=new MutationObserver(m);t.observe(e,{childList:!0,subtree:!0}),e.__observer=t}}function w(e){e=window.wrap(e),b.dom&&console.group("upgradeDocument: ",e.baseURI.split("/").pop()),t(e),v(e),b.dom&&console.groupEnd()}function g(e){E(e,w)}var b=e.flags,_=e.forSubtree,E=e.forDocumentTree,y=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;e.hasPolyfillMutations=y;var N=!1,O=[],M=Array.prototype.forEach.call.bind(Array.prototype.forEach),L=Element.prototype.createShadowRoot;L&&(Element.prototype.createShadowRoot=function(){var e=L.call(this);return window.CustomElements.watchShadow(this),e}),e.watchShadow=p,e.upgradeDocumentTree=g,e.upgradeSubtree=o,e.upgradeAll=t,e.attachedNode=r,e.takeRecords=h}),window.CustomElements.addModule(function(e){function t(t){if(!t.__upgraded__&&t.nodeType===Node.ELEMENT_NODE){var o=t.getAttribute("is"),r=e.getRegisteredDefinition(o||t.localName);if(r){if(o&&r.tag==t.localName)return n(t,r);if(!o&&!r["extends"])return n(t,r)}}}function n(t,n){return a.upgrade&&console.group("upgrade:",t.localName),n.is&&t.setAttribute("is",n.is),o(t,n),t.__upgraded__=!0,i(t),e.attachedNode(t),e.upgradeSubtree(t),a.upgrade&&console.groupEnd(),t}function o(e,t){Object.__proto__?e.__proto__=t.prototype:(r(e,t.prototype,t["native"]),e.__proto__=t.prototype)}function r(e,t,n){for(var o={},r=t;r!==n&&r!==HTMLElement.prototype;){for(var i,a=Object.getOwnPropertyNames(r),d=0;i=a[d];d++)o[i]||(Object.defineProperty(e,i,Object.getOwnPropertyDescriptor(r,i)),o[i]=1);r=Object.getPrototypeOf(r)}}function i(e){e.createdCallback&&e.createdCallback()}var a=e.flags;e.upgrade=t,e.upgradeWithDefinition=n,e.implementPrototype=o}),window.CustomElements.addModule(function(e){function t(t,o){var s=o||{};if(!t)throw new Error("document.registerElement: first argument `name` must not be empty");if(t.indexOf("-")<0)throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(t)+"'.");if(r(t))throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '"+String(t)+"'. The type name is invalid.");if(u(t))throw new Error("DuplicateDefinitionError: a type with name '"+String(t)+"' is already registered");return s.prototype||(s.prototype=Object.create(HTMLElement.prototype)),s.__name=t.toLowerCase(),s.lifecycle=s.lifecycle||{},s.ancestry=i(s["extends"]),a(s),d(s),n(s.prototype),c(s.__name,s),s.ctor=l(s),s.ctor.prototype=s.prototype,s.prototype.constructor=s.ctor,e.ready&&w(document),s.ctor}function n(e){if(!e.setAttribute._polyfilled){var t=e.setAttribute;e.setAttribute=function(e,n){o.call(this,e,n,t)};var n=e.removeAttribute;e.removeAttribute=function(e){o.call(this,e,null,n)},e.setAttribute._polyfilled=!0}}function o(e,t,n){e=e.toLowerCase();var o=this.getAttribute(e);n.apply(this,arguments);var r=this.getAttribute(e);this.attributeChangedCallback&&r!==o&&this.attributeChangedCallback(e,o,r)}function r(e){for(var t=0;t<y.length;t++)if(e===y[t])return!0}function i(e){var t=u(e);return t?i(t["extends"]).concat([t]):[]}function a(e){for(var t,n=e["extends"],o=0;t=e.ancestry[o];o++)n=t.is&&t.tag;e.tag=n||e.__name,n&&(e.is=e.__name)}function d(e){if(!Object.__proto__){var t=HTMLElement.prototype;if(e.is){var n=document.createElement(e.tag),o=Object.getPrototypeOf(n);o===e.prototype&&(t=o)}for(var r,i=e.prototype;i&&i!==t;)r=Object.getPrototypeOf(i),i.__proto__=r,i=r;e["native"]=t}}function s(e){return b(M(e.tag),e)}function u(e){return e?N[e.toLowerCase()]:void 0}function c(e,t){N[e]=t}function l(e){return function(){return s(e)}}function f(e,t,n){return e===O?p(t,n):L(e,t)}function p(e,t){e&&(e=e.toLowerCase()),t&&(t=t.toLowerCase());var n=u(t||e);if(n){if(e==n.tag&&t==n.is)return new n.ctor;if(!t&&!n.is)return new n.ctor}var o;return t?(o=p(e),o.setAttribute("is",t),o):(o=M(e),e.indexOf("-")>=0&&_(o,HTMLElement),o)}function m(e,t){var n=e[t];e[t]=function(){var e=n.apply(this,arguments);return g(e),e}}var h,v=e.isIE11OrOlder,w=e.upgradeDocumentTree,g=e.upgradeAll,b=e.upgradeWithDefinition,_=e.implementPrototype,E=e.useNative,y=["annotation-xml","color-profile","font-face","font-face-src","font-face-uri","font-face-format","font-face-name","missing-glyph"],N={},O="http://www.w3.org/1999/xhtml",M=document.createElement.bind(document),L=document.createElementNS.bind(document);h=Object.__proto__||E?function(e,t){return e instanceof t}:function(e,t){for(var n=e;n;){if(n===t.prototype)return!0;n=n.__proto__}return!1},m(Node.prototype,"cloneNode"),m(document,"importNode"),v&&!function(){var e=document.importNode;document.importNode=function(){var t=e.apply(document,arguments);if(t.nodeType==t.DOCUMENT_FRAGMENT_NODE){var n=document.createDocumentFragment();return n.appendChild(t),n}return t}}(),document.registerElement=t,document.createElement=p,document.createElementNS=f,e.registry=N,e["instanceof"]=h,e.reservedTagList=y,e.getRegisteredDefinition=u,document.register=document.registerElement}),function(e){function t(){a(window.wrap(document)),window.HTMLImports&&(window.HTMLImports.__importsParsingHook=function(e){a(wrap(e["import"]))}),window.CustomElements.ready=!0,setTimeout(function(){window.CustomElements.readyTime=Date.now(),window.HTMLImports&&(window.CustomElements.elapsed=window.CustomElements.readyTime-window.HTMLImports.readyTime),document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})}var n=e.useNative,o=e.initializeModules,r=/Trident/.test(navigator.userAgent);if(n){var i=function(){};e.watchShadow=i,e.upgrade=i,e.upgradeAll=i,e.upgradeDocumentTree=i,e.upgradeSubtree=i,e.takeRecords=i,e["instanceof"]=function(e,t){return e instanceof t}}else o();var a=e.upgradeDocumentTree;if(window.wrap||(window.ShadowDOMPolyfill?(window.wrap=window.ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=window.ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}),r&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n.preventDefault=function(){Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}})},n},window.CustomEvent.prototype=window.Event.prototype),"complete"===document.readyState||e.flags.eager)t();else if("interactive"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var d=window.HTMLImports&&!window.HTMLImports.ready?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(d,t)}else t();e.isIE11OrOlder=r}(window.CustomElements);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/HTMLImports.js b/polymer_1.0.4/bower_components/webcomponentsjs/HTMLImports.js
new file mode 100644
index 0000000..e9f03ec
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/HTMLImports.js
@@ -0,0 +1,1085 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.7.5
+if (typeof WeakMap === "undefined") {
+ (function() {
+ var defineProperty = Object.defineProperty;
+ var counter = Date.now() % 1e9;
+ var WeakMap = function() {
+ this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
+ };
+ WeakMap.prototype = {
+ set: function(key, value) {
+ var entry = key[this.name];
+ if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
+ value: [ key, value ],
+ writable: true
+ });
+ return this;
+ },
+ get: function(key) {
+ var entry;
+ return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
+ },
+ "delete": function(key) {
+ var entry = key[this.name];
+ if (!entry || entry[0] !== key) return false;
+ entry[0] = entry[1] = undefined;
+ return true;
+ },
+ has: function(key) {
+ var entry = key[this.name];
+ if (!entry) return false;
+ return entry[0] === key;
+ }
+ };
+ window.WeakMap = WeakMap;
+ })();
+}
+
+(function(global) {
+ var registrationsTable = new WeakMap();
+ var setImmediate;
+ if (/Trident|Edge/.test(navigator.userAgent)) {
+ setImmediate = setTimeout;
+ } else if (window.setImmediate) {
+ setImmediate = window.setImmediate;
+ } else {
+ var setImmediateQueue = [];
+ var sentinel = String(Math.random());
+ window.addEventListener("message", function(e) {
+ if (e.data === sentinel) {
+ var queue = setImmediateQueue;
+ setImmediateQueue = [];
+ queue.forEach(function(func) {
+ func();
+ });
+ }
+ });
+ setImmediate = function(func) {
+ setImmediateQueue.push(func);
+ window.postMessage(sentinel, "*");
+ };
+ }
+ var isScheduled = false;
+ var scheduledObservers = [];
+ function scheduleCallback(observer) {
+ scheduledObservers.push(observer);
+ if (!isScheduled) {
+ isScheduled = true;
+ setImmediate(dispatchCallbacks);
+ }
+ }
+ function wrapIfNeeded(node) {
+ return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;
+ }
+ function dispatchCallbacks() {
+ isScheduled = false;
+ var observers = scheduledObservers;
+ scheduledObservers = [];
+ observers.sort(function(o1, o2) {
+ return o1.uid_ - o2.uid_;
+ });
+ var anyNonEmpty = false;
+ observers.forEach(function(observer) {
+ var queue = observer.takeRecords();
+ removeTransientObserversFor(observer);
+ if (queue.length) {
+ observer.callback_(queue, observer);
+ anyNonEmpty = true;
+ }
+ });
+ if (anyNonEmpty) dispatchCallbacks();
+ }
+ function removeTransientObserversFor(observer) {
+ observer.nodes_.forEach(function(node) {
+ var registrations = registrationsTable.get(node);
+ if (!registrations) return;
+ registrations.forEach(function(registration) {
+ if (registration.observer === observer) registration.removeTransientObservers();
+ });
+ });
+ }
+ function forEachAncestorAndObserverEnqueueRecord(target, callback) {
+ for (var node = target; node; node = node.parentNode) {
+ var registrations = registrationsTable.get(node);
+ if (registrations) {
+ for (var j = 0; j < registrations.length; j++) {
+ var registration = registrations[j];
+ var options = registration.options;
+ if (node !== target && !options.subtree) continue;
+ var record = callback(options);
+ if (record) registration.enqueue(record);
+ }
+ }
+ }
+ }
+ var uidCounter = 0;
+ function JsMutationObserver(callback) {
+ this.callback_ = callback;
+ this.nodes_ = [];
+ this.records_ = [];
+ this.uid_ = ++uidCounter;
+ }
+ JsMutationObserver.prototype = {
+ observe: function(target, options) {
+ target = wrapIfNeeded(target);
+ if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {
+ throw new SyntaxError();
+ }
+ var registrations = registrationsTable.get(target);
+ if (!registrations) registrationsTable.set(target, registrations = []);
+ var registration;
+ for (var i = 0; i < registrations.length; i++) {
+ if (registrations[i].observer === this) {
+ registration = registrations[i];
+ registration.removeListeners();
+ registration.options = options;
+ break;
+ }
+ }
+ if (!registration) {
+ registration = new Registration(this, target, options);
+ registrations.push(registration);
+ this.nodes_.push(target);
+ }
+ registration.addListeners();
+ },
+ disconnect: function() {
+ this.nodes_.forEach(function(node) {
+ var registrations = registrationsTable.get(node);
+ for (var i = 0; i < registrations.length; i++) {
+ var registration = registrations[i];
+ if (registration.observer === this) {
+ registration.removeListeners();
+ registrations.splice(i, 1);
+ break;
+ }
+ }
+ }, this);
+ this.records_ = [];
+ },
+ takeRecords: function() {
+ var copyOfRecords = this.records_;
+ this.records_ = [];
+ return copyOfRecords;
+ }
+ };
+ function MutationRecord(type, target) {
+ this.type = type;
+ this.target = target;
+ this.addedNodes = [];
+ this.removedNodes = [];
+ this.previousSibling = null;
+ this.nextSibling = null;
+ this.attributeName = null;
+ this.attributeNamespace = null;
+ this.oldValue = null;
+ }
+ function copyMutationRecord(original) {
+ var record = new MutationRecord(original.type, original.target);
+ record.addedNodes = original.addedNodes.slice();
+ record.removedNodes = original.removedNodes.slice();
+ record.previousSibling = original.previousSibling;
+ record.nextSibling = original.nextSibling;
+ record.attributeName = original.attributeName;
+ record.attributeNamespace = original.attributeNamespace;
+ record.oldValue = original.oldValue;
+ return record;
+ }
+ var currentRecord, recordWithOldValue;
+ function getRecord(type, target) {
+ return currentRecord = new MutationRecord(type, target);
+ }
+ function getRecordWithOldValue(oldValue) {
+ if (recordWithOldValue) return recordWithOldValue;
+ recordWithOldValue = copyMutationRecord(currentRecord);
+ recordWithOldValue.oldValue = oldValue;
+ return recordWithOldValue;
+ }
+ function clearRecords() {
+ currentRecord = recordWithOldValue = undefined;
+ }
+ function recordRepresentsCurrentMutation(record) {
+ return record === recordWithOldValue || record === currentRecord;
+ }
+ function selectRecord(lastRecord, newRecord) {
+ if (lastRecord === newRecord) return lastRecord;
+ if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;
+ return null;
+ }
+ function Registration(observer, target, options) {
+ this.observer = observer;
+ this.target = target;
+ this.options = options;
+ this.transientObservedNodes = [];
+ }
+ Registration.prototype = {
+ enqueue: function(record) {
+ var records = this.observer.records_;
+ var length = records.length;
+ if (records.length > 0) {
+ var lastRecord = records[length - 1];
+ var recordToReplaceLast = selectRecord(lastRecord, record);
+ if (recordToReplaceLast) {
+ records[length - 1] = recordToReplaceLast;
+ return;
+ }
+ } else {
+ scheduleCallback(this.observer);
+ }
+ records[length] = record;
+ },
+ addListeners: function() {
+ this.addListeners_(this.target);
+ },
+ addListeners_: function(node) {
+ var options = this.options;
+ if (options.attributes) node.addEventListener("DOMAttrModified", this, true);
+ if (options.characterData) node.addEventListener("DOMCharacterDataModified", this, true);
+ if (options.childList) node.addEventListener("DOMNodeInserted", this, true);
+ if (options.childList || options.subtree) node.addEventListener("DOMNodeRemoved", this, true);
+ },
+ removeListeners: function() {
+ this.removeListeners_(this.target);
+ },
+ removeListeners_: function(node) {
+ var options = this.options;
+ if (options.attributes) node.removeEventListener("DOMAttrModified", this, true);
+ if (options.characterData) node.removeEventListener("DOMCharacterDataModified", this, true);
+ if (options.childList) node.removeEventListener("DOMNodeInserted", this, true);
+ if (options.childList || options.subtree) node.removeEventListener("DOMNodeRemoved", this, true);
+ },
+ addTransientObserver: function(node) {
+ if (node === this.target) return;
+ this.addListeners_(node);
+ this.transientObservedNodes.push(node);
+ var registrations = registrationsTable.get(node);
+ if (!registrations) registrationsTable.set(node, registrations = []);
+ registrations.push(this);
+ },
+ removeTransientObservers: function() {
+ var transientObservedNodes = this.transientObservedNodes;
+ this.transientObservedNodes = [];
+ transientObservedNodes.forEach(function(node) {
+ this.removeListeners_(node);
+ var registrations = registrationsTable.get(node);
+ for (var i = 0; i < registrations.length; i++) {
+ if (registrations[i] === this) {
+ registrations.splice(i, 1);
+ break;
+ }
+ }
+ }, this);
+ },
+ handleEvent: function(e) {
+ e.stopImmediatePropagation();
+ switch (e.type) {
+ case "DOMAttrModified":
+ var name = e.attrName;
+ var namespace = e.relatedNode.namespaceURI;
+ var target = e.target;
+ var record = new getRecord("attributes", target);
+ record.attributeName = name;
+ record.attributeNamespace = namespace;
+ var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
+ forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+ if (!options.attributes) return;
+ if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {
+ return;
+ }
+ if (options.attributeOldValue) return getRecordWithOldValue(oldValue);
+ return record;
+ });
+ break;
+
+ case "DOMCharacterDataModified":
+ var target = e.target;
+ var record = getRecord("characterData", target);
+ var oldValue = e.prevValue;
+ forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+ if (!options.characterData) return;
+ if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);
+ return record;
+ });
+ break;
+
+ case "DOMNodeRemoved":
+ this.addTransientObserver(e.target);
+
+ case "DOMNodeInserted":
+ var changedNode = e.target;
+ var addedNodes, removedNodes;
+ if (e.type === "DOMNodeInserted") {
+ addedNodes = [ changedNode ];
+ removedNodes = [];
+ } else {
+ addedNodes = [];
+ removedNodes = [ changedNode ];
+ }
+ var previousSibling = changedNode.previousSibling;
+ var nextSibling = changedNode.nextSibling;
+ var record = getRecord("childList", e.target.parentNode);
+ record.addedNodes = addedNodes;
+ record.removedNodes = removedNodes;
+ record.previousSibling = previousSibling;
+ record.nextSibling = nextSibling;
+ forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) {
+ if (!options.childList) return;
+ return record;
+ });
+ }
+ clearRecords();
+ }
+ };
+ global.JsMutationObserver = JsMutationObserver;
+ if (!global.MutationObserver) global.MutationObserver = JsMutationObserver;
+})(this);
+
+window.HTMLImports = window.HTMLImports || {
+ flags: {}
+};
+
+(function(scope) {
+ var IMPORT_LINK_TYPE = "import";
+ var useNative = Boolean(IMPORT_LINK_TYPE in document.createElement("link"));
+ var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);
+ var wrap = function(node) {
+ return hasShadowDOMPolyfill ? window.ShadowDOMPolyfill.wrapIfNeeded(node) : node;
+ };
+ var rootDocument = wrap(document);
+ var currentScriptDescriptor = {
+ get: function() {
+ var script = window.HTMLImports.currentScript || document.currentScript || (document.readyState !== "complete" ? document.scripts[document.scripts.length - 1] : null);
+ return wrap(script);
+ },
+ configurable: true
+ };
+ Object.defineProperty(document, "_currentScript", currentScriptDescriptor);
+ Object.defineProperty(rootDocument, "_currentScript", currentScriptDescriptor);
+ var isIE = /Trident/.test(navigator.userAgent);
+ function whenReady(callback, doc) {
+ doc = doc || rootDocument;
+ whenDocumentReady(function() {
+ watchImportsLoad(callback, doc);
+ }, doc);
+ }
+ var requiredReadyState = isIE ? "complete" : "interactive";
+ var READY_EVENT = "readystatechange";
+ function isDocumentReady(doc) {
+ return doc.readyState === "complete" || doc.readyState === requiredReadyState;
+ }
+ function whenDocumentReady(callback, doc) {
+ if (!isDocumentReady(doc)) {
+ var checkReady = function() {
+ if (doc.readyState === "complete" || doc.readyState === requiredReadyState) {
+ doc.removeEventListener(READY_EVENT, checkReady);
+ whenDocumentReady(callback, doc);
+ }
+ };
+ doc.addEventListener(READY_EVENT, checkReady);
+ } else if (callback) {
+ callback();
+ }
+ }
+ function markTargetLoaded(event) {
+ event.target.__loaded = true;
+ }
+ function watchImportsLoad(callback, doc) {
+ var imports = doc.querySelectorAll("link[rel=import]");
+ var parsedCount = 0, importCount = imports.length, newImports = [], errorImports = [];
+ function checkDone() {
+ if (parsedCount == importCount && callback) {
+ callback({
+ allImports: imports,
+ loadedImports: newImports,
+ errorImports: errorImports
+ });
+ }
+ }
+ function loadedImport(e) {
+ markTargetLoaded(e);
+ newImports.push(this);
+ parsedCount++;
+ checkDone();
+ }
+ function errorLoadingImport(e) {
+ errorImports.push(this);
+ parsedCount++;
+ checkDone();
+ }
+ if (importCount) {
+ for (var i = 0, imp; i < importCount && (imp = imports[i]); i++) {
+ if (isImportLoaded(imp)) {
+ parsedCount++;
+ checkDone();
+ } else {
+ imp.addEventListener("load", loadedImport);
+ imp.addEventListener("error", errorLoadingImport);
+ }
+ }
+ } else {
+ checkDone();
+ }
+ }
+ function isImportLoaded(link) {
+ return useNative ? link.__loaded || link.import && link.import.readyState !== "loading" : link.__importParsed;
+ }
+ if (useNative) {
+ new MutationObserver(function(mxns) {
+ for (var i = 0, l = mxns.length, m; i < l && (m = mxns[i]); i++) {
+ if (m.addedNodes) {
+ handleImports(m.addedNodes);
+ }
+ }
+ }).observe(document.head, {
+ childList: true
+ });
+ function handleImports(nodes) {
+ for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+ if (isImport(n)) {
+ handleImport(n);
+ }
+ }
+ }
+ function isImport(element) {
+ return element.localName === "link" && element.rel === "import";
+ }
+ function handleImport(element) {
+ var loaded = element.import;
+ if (loaded) {
+ markTargetLoaded({
+ target: element
+ });
+ } else {
+ element.addEventListener("load", markTargetLoaded);
+ element.addEventListener("error", markTargetLoaded);
+ }
+ }
+ (function() {
+ if (document.readyState === "loading") {
+ var imports = document.querySelectorAll("link[rel=import]");
+ for (var i = 0, l = imports.length, imp; i < l && (imp = imports[i]); i++) {
+ handleImport(imp);
+ }
+ }
+ })();
+ }
+ whenReady(function(detail) {
+ window.HTMLImports.ready = true;
+ window.HTMLImports.readyTime = new Date().getTime();
+ var evt = rootDocument.createEvent("CustomEvent");
+ evt.initCustomEvent("HTMLImportsLoaded", true, true, detail);
+ rootDocument.dispatchEvent(evt);
+ });
+ scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
+ scope.useNative = useNative;
+ scope.rootDocument = rootDocument;
+ scope.whenReady = whenReady;
+ scope.isIE = isIE;
+})(window.HTMLImports);
+
+(function(scope) {
+ var modules = [];
+ var addModule = function(module) {
+ modules.push(module);
+ };
+ var initializeModules = function() {
+ modules.forEach(function(module) {
+ module(scope);
+ });
+ };
+ scope.addModule = addModule;
+ scope.initializeModules = initializeModules;
+})(window.HTMLImports);
+
+window.HTMLImports.addModule(function(scope) {
+ var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
+ var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
+ var path = {
+ resolveUrlsInStyle: function(style, linkUrl) {
+ var doc = style.ownerDocument;
+ var resolver = doc.createElement("a");
+ style.textContent = this.resolveUrlsInCssText(style.textContent, linkUrl, resolver);
+ return style;
+ },
+ resolveUrlsInCssText: function(cssText, linkUrl, urlObj) {
+ var r = this.replaceUrls(cssText, urlObj, linkUrl, CSS_URL_REGEXP);
+ r = this.replaceUrls(r, urlObj, linkUrl, CSS_IMPORT_REGEXP);
+ return r;
+ },
+ replaceUrls: function(text, urlObj, linkUrl, regexp) {
+ return text.replace(regexp, function(m, pre, url, post) {
+ var urlPath = url.replace(/["']/g, "");
+ if (linkUrl) {
+ urlPath = new URL(urlPath, linkUrl).href;
+ }
+ urlObj.href = urlPath;
+ urlPath = urlObj.href;
+ return pre + "'" + urlPath + "'" + post;
+ });
+ }
+ };
+ scope.path = path;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var xhr = {
+ async: true,
+ ok: function(request) {
+ return request.status >= 200 && request.status < 300 || request.status === 304 || request.status === 0;
+ },
+ load: function(url, next, nextContext) {
+ var request = new XMLHttpRequest();
+ if (scope.flags.debug || scope.flags.bust) {
+ url += "?" + Math.random();
+ }
+ request.open("GET", url, xhr.async);
+ request.addEventListener("readystatechange", function(e) {
+ if (request.readyState === 4) {
+ var locationHeader = request.getResponseHeader("Location");
+ var redirectedUrl = null;
+ if (locationHeader) {
+ var redirectedUrl = locationHeader.substr(0, 1) === "/" ? location.origin + locationHeader : locationHeader;
+ }
+ next.call(nextContext, !xhr.ok(request) && request, request.response || request.responseText, redirectedUrl);
+ }
+ });
+ request.send();
+ return request;
+ },
+ loadDocument: function(url, next, nextContext) {
+ this.load(url, next, nextContext).responseType = "document";
+ }
+ };
+ scope.xhr = xhr;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var xhr = scope.xhr;
+ var flags = scope.flags;
+ var Loader = function(onLoad, onComplete) {
+ this.cache = {};
+ this.onload = onLoad;
+ this.oncomplete = onComplete;
+ this.inflight = 0;
+ this.pending = {};
+ };
+ Loader.prototype = {
+ addNodes: function(nodes) {
+ this.inflight += nodes.length;
+ for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+ this.require(n);
+ }
+ this.checkDone();
+ },
+ addNode: function(node) {
+ this.inflight++;
+ this.require(node);
+ this.checkDone();
+ },
+ require: function(elt) {
+ var url = elt.src || elt.href;
+ elt.__nodeUrl = url;
+ if (!this.dedupe(url, elt)) {
+ this.fetch(url, elt);
+ }
+ },
+ dedupe: function(url, elt) {
+ if (this.pending[url]) {
+ this.pending[url].push(elt);
+ return true;
+ }
+ var resource;
+ if (this.cache[url]) {
+ this.onload(url, elt, this.cache[url]);
+ this.tail();
+ return true;
+ }
+ this.pending[url] = [ elt ];
+ return false;
+ },
+ fetch: function(url, elt) {
+ flags.load && console.log("fetch", url, elt);
+ if (!url) {
+ setTimeout(function() {
+ this.receive(url, elt, {
+ error: "href must be specified"
+ }, null);
+ }.bind(this), 0);
+ } else if (url.match(/^data:/)) {
+ var pieces = url.split(",");
+ var header = pieces[0];
+ var body = pieces[1];
+ if (header.indexOf(";base64") > -1) {
+ body = atob(body);
+ } else {
+ body = decodeURIComponent(body);
+ }
+ setTimeout(function() {
+ this.receive(url, elt, null, body);
+ }.bind(this), 0);
+ } else {
+ var receiveXhr = function(err, resource, redirectedUrl) {
+ this.receive(url, elt, err, resource, redirectedUrl);
+ }.bind(this);
+ xhr.load(url, receiveXhr);
+ }
+ },
+ receive: function(url, elt, err, resource, redirectedUrl) {
+ this.cache[url] = resource;
+ var $p = this.pending[url];
+ for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
+ this.onload(url, p, resource, err, redirectedUrl);
+ this.tail();
+ }
+ this.pending[url] = null;
+ },
+ tail: function() {
+ --this.inflight;
+ this.checkDone();
+ },
+ checkDone: function() {
+ if (!this.inflight) {
+ this.oncomplete();
+ }
+ }
+ };
+ scope.Loader = Loader;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var Observer = function(addCallback) {
+ this.addCallback = addCallback;
+ this.mo = new MutationObserver(this.handler.bind(this));
+ };
+ Observer.prototype = {
+ handler: function(mutations) {
+ for (var i = 0, l = mutations.length, m; i < l && (m = mutations[i]); i++) {
+ if (m.type === "childList" && m.addedNodes.length) {
+ this.addedNodes(m.addedNodes);
+ }
+ }
+ },
+ addedNodes: function(nodes) {
+ if (this.addCallback) {
+ this.addCallback(nodes);
+ }
+ for (var i = 0, l = nodes.length, n, loading; i < l && (n = nodes[i]); i++) {
+ if (n.children && n.children.length) {
+ this.addedNodes(n.children);
+ }
+ }
+ },
+ observe: function(root) {
+ this.mo.observe(root, {
+ childList: true,
+ subtree: true
+ });
+ }
+ };
+ scope.Observer = Observer;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var path = scope.path;
+ var rootDocument = scope.rootDocument;
+ var flags = scope.flags;
+ var isIE = scope.isIE;
+ var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
+ var IMPORT_SELECTOR = "link[rel=" + IMPORT_LINK_TYPE + "]";
+ var importParser = {
+ documentSelectors: IMPORT_SELECTOR,
+ importsSelectors: [ IMPORT_SELECTOR, "link[rel=stylesheet]", "style", "script:not([type])", 'script[type="application/javascript"]', 'script[type="text/javascript"]' ].join(","),
+ map: {
+ link: "parseLink",
+ script: "parseScript",
+ style: "parseStyle"
+ },
+ dynamicElements: [],
+ parseNext: function() {
+ var next = this.nextToParse();
+ if (next) {
+ this.parse(next);
+ }
+ },
+ parse: function(elt) {
+ if (this.isParsed(elt)) {
+ flags.parse && console.log("[%s] is already parsed", elt.localName);
+ return;
+ }
+ var fn = this[this.map[elt.localName]];
+ if (fn) {
+ this.markParsing(elt);
+ fn.call(this, elt);
+ }
+ },
+ parseDynamic: function(elt, quiet) {
+ this.dynamicElements.push(elt);
+ if (!quiet) {
+ this.parseNext();
+ }
+ },
+ markParsing: function(elt) {
+ flags.parse && console.log("parsing", elt);
+ this.parsingElement = elt;
+ },
+ markParsingComplete: function(elt) {
+ elt.__importParsed = true;
+ this.markDynamicParsingComplete(elt);
+ if (elt.__importElement) {
+ elt.__importElement.__importParsed = true;
+ this.markDynamicParsingComplete(elt.__importElement);
+ }
+ this.parsingElement = null;
+ flags.parse && console.log("completed", elt);
+ },
+ markDynamicParsingComplete: function(elt) {
+ var i = this.dynamicElements.indexOf(elt);
+ if (i >= 0) {
+ this.dynamicElements.splice(i, 1);
+ }
+ },
+ parseImport: function(elt) {
+ if (window.HTMLImports.__importsParsingHook) {
+ window.HTMLImports.__importsParsingHook(elt);
+ }
+ if (elt.import) {
+ elt.import.__importParsed = true;
+ }
+ this.markParsingComplete(elt);
+ if (elt.__resource && !elt.__error) {
+ elt.dispatchEvent(new CustomEvent("load", {
+ bubbles: false
+ }));
+ } else {
+ elt.dispatchEvent(new CustomEvent("error", {
+ bubbles: false
+ }));
+ }
+ if (elt.__pending) {
+ var fn;
+ while (elt.__pending.length) {
+ fn = elt.__pending.shift();
+ if (fn) {
+ fn({
+ target: elt
+ });
+ }
+ }
+ }
+ this.parseNext();
+ },
+ parseLink: function(linkElt) {
+ if (nodeIsImport(linkElt)) {
+ this.parseImport(linkElt);
+ } else {
+ linkElt.href = linkElt.href;
+ this.parseGeneric(linkElt);
+ }
+ },
+ parseStyle: function(elt) {
+ var src = elt;
+ elt = cloneStyle(elt);
+ src.__appliedElement = elt;
+ elt.__importElement = src;
+ this.parseGeneric(elt);
+ },
+ parseGeneric: function(elt) {
+ this.trackElement(elt);
+ this.addElementToDocument(elt);
+ },
+ rootImportForElement: function(elt) {
+ var n = elt;
+ while (n.ownerDocument.__importLink) {
+ n = n.ownerDocument.__importLink;
+ }
+ return n;
+ },
+ addElementToDocument: function(elt) {
+ var port = this.rootImportForElement(elt.__importElement || elt);
+ port.parentNode.insertBefore(elt, port);
+ },
+ trackElement: function(elt, callback) {
+ var self = this;
+ var done = function(e) {
+ if (callback) {
+ callback(e);
+ }
+ self.markParsingComplete(elt);
+ self.parseNext();
+ };
+ elt.addEventListener("load", done);
+ elt.addEventListener("error", done);
+ if (isIE && elt.localName === "style") {
+ var fakeLoad = false;
+ if (elt.textContent.indexOf("@import") == -1) {
+ fakeLoad = true;
+ } else if (elt.sheet) {
+ fakeLoad = true;
+ var csr = elt.sheet.cssRules;
+ var len = csr ? csr.length : 0;
+ for (var i = 0, r; i < len && (r = csr[i]); i++) {
+ if (r.type === CSSRule.IMPORT_RULE) {
+ fakeLoad = fakeLoad && Boolean(r.styleSheet);
+ }
+ }
+ }
+ if (fakeLoad) {
+ setTimeout(function() {
+ elt.dispatchEvent(new CustomEvent("load", {
+ bubbles: false
+ }));
+ });
+ }
+ }
+ },
+ parseScript: function(scriptElt) {
+ var script = document.createElement("script");
+ script.__importElement = scriptElt;
+ script.src = scriptElt.src ? scriptElt.src : generateScriptDataUrl(scriptElt);
+ scope.currentScript = scriptElt;
+ this.trackElement(script, function(e) {
+ script.parentNode.removeChild(script);
+ scope.currentScript = null;
+ });
+ this.addElementToDocument(script);
+ },
+ nextToParse: function() {
+ this._mayParse = [];
+ return !this.parsingElement && (this.nextToParseInDoc(rootDocument) || this.nextToParseDynamic());
+ },
+ nextToParseInDoc: function(doc, link) {
+ if (doc && this._mayParse.indexOf(doc) < 0) {
+ this._mayParse.push(doc);
+ var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));
+ for (var i = 0, l = nodes.length, p = 0, n; i < l && (n = nodes[i]); i++) {
+ if (!this.isParsed(n)) {
+ if (this.hasResource(n)) {
+ return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n;
+ } else {
+ return;
+ }
+ }
+ }
+ }
+ return link;
+ },
+ nextToParseDynamic: function() {
+ return this.dynamicElements[0];
+ },
+ parseSelectorsForNode: function(node) {
+ var doc = node.ownerDocument || node;
+ return doc === rootDocument ? this.documentSelectors : this.importsSelectors;
+ },
+ isParsed: function(node) {
+ return node.__importParsed;
+ },
+ needsDynamicParsing: function(elt) {
+ return this.dynamicElements.indexOf(elt) >= 0;
+ },
+ hasResource: function(node) {
+ if (nodeIsImport(node) && node.import === undefined) {
+ return false;
+ }
+ return true;
+ }
+ };
+ function nodeIsImport(elt) {
+ return elt.localName === "link" && elt.rel === IMPORT_LINK_TYPE;
+ }
+ function generateScriptDataUrl(script) {
+ var scriptContent = generateScriptContent(script);
+ return "data:text/javascript;charset=utf-8," + encodeURIComponent(scriptContent);
+ }
+ function generateScriptContent(script) {
+ return script.textContent + generateSourceMapHint(script);
+ }
+ function generateSourceMapHint(script) {
+ var owner = script.ownerDocument;
+ owner.__importedScripts = owner.__importedScripts || 0;
+ var moniker = script.ownerDocument.baseURI;
+ var num = owner.__importedScripts ? "-" + owner.__importedScripts : "";
+ owner.__importedScripts++;
+ return "\n//# sourceURL=" + moniker + num + ".js\n";
+ }
+ function cloneStyle(style) {
+ var clone = style.ownerDocument.createElement("style");
+ clone.textContent = style.textContent;
+ path.resolveUrlsInStyle(clone);
+ return clone;
+ }
+ scope.parser = importParser;
+ scope.IMPORT_SELECTOR = IMPORT_SELECTOR;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var flags = scope.flags;
+ var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
+ var IMPORT_SELECTOR = scope.IMPORT_SELECTOR;
+ var rootDocument = scope.rootDocument;
+ var Loader = scope.Loader;
+ var Observer = scope.Observer;
+ var parser = scope.parser;
+ var importer = {
+ documents: {},
+ documentPreloadSelectors: IMPORT_SELECTOR,
+ importsPreloadSelectors: [ IMPORT_SELECTOR ].join(","),
+ loadNode: function(node) {
+ importLoader.addNode(node);
+ },
+ loadSubtree: function(parent) {
+ var nodes = this.marshalNodes(parent);
+ importLoader.addNodes(nodes);
+ },
+ marshalNodes: function(parent) {
+ return parent.querySelectorAll(this.loadSelectorsForNode(parent));
+ },
+ loadSelectorsForNode: function(node) {
+ var doc = node.ownerDocument || node;
+ return doc === rootDocument ? this.documentPreloadSelectors : this.importsPreloadSelectors;
+ },
+ loaded: function(url, elt, resource, err, redirectedUrl) {
+ flags.load && console.log("loaded", url, elt);
+ elt.__resource = resource;
+ elt.__error = err;
+ if (isImportLink(elt)) {
+ var doc = this.documents[url];
+ if (doc === undefined) {
+ doc = err ? null : makeDocument(resource, redirectedUrl || url);
+ if (doc) {
+ doc.__importLink = elt;
+ this.bootDocument(doc);
+ }
+ this.documents[url] = doc;
+ }
+ elt.import = doc;
+ }
+ parser.parseNext();
+ },
+ bootDocument: function(doc) {
+ this.loadSubtree(doc);
+ this.observer.observe(doc);
+ parser.parseNext();
+ },
+ loadedAll: function() {
+ parser.parseNext();
+ }
+ };
+ var importLoader = new Loader(importer.loaded.bind(importer), importer.loadedAll.bind(importer));
+ importer.observer = new Observer();
+ function isImportLink(elt) {
+ return isLinkRel(elt, IMPORT_LINK_TYPE);
+ }
+ function isLinkRel(elt, rel) {
+ return elt.localName === "link" && elt.getAttribute("rel") === rel;
+ }
+ function hasBaseURIAccessor(doc) {
+ return !!Object.getOwnPropertyDescriptor(doc, "baseURI");
+ }
+ function makeDocument(resource, url) {
+ var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);
+ doc._URL = url;
+ var base = doc.createElement("base");
+ base.setAttribute("href", url);
+ if (!doc.baseURI && !hasBaseURIAccessor(doc)) {
+ Object.defineProperty(doc, "baseURI", {
+ value: url
+ });
+ }
+ var meta = doc.createElement("meta");
+ meta.setAttribute("charset", "utf-8");
+ doc.head.appendChild(meta);
+ doc.head.appendChild(base);
+ doc.body.innerHTML = resource;
+ if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
+ HTMLTemplateElement.bootstrap(doc);
+ }
+ return doc;
+ }
+ if (!document.baseURI) {
+ var baseURIDescriptor = {
+ get: function() {
+ var base = document.querySelector("base");
+ return base ? base.href : window.location.href;
+ },
+ configurable: true
+ };
+ Object.defineProperty(document, "baseURI", baseURIDescriptor);
+ Object.defineProperty(rootDocument, "baseURI", baseURIDescriptor);
+ }
+ scope.importer = importer;
+ scope.importLoader = importLoader;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var parser = scope.parser;
+ var importer = scope.importer;
+ var dynamic = {
+ added: function(nodes) {
+ var owner, parsed, loading;
+ for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+ if (!owner) {
+ owner = n.ownerDocument;
+ parsed = parser.isParsed(owner);
+ }
+ loading = this.shouldLoadNode(n);
+ if (loading) {
+ importer.loadNode(n);
+ }
+ if (this.shouldParseNode(n) && parsed) {
+ parser.parseDynamic(n, loading);
+ }
+ }
+ },
+ shouldLoadNode: function(node) {
+ return node.nodeType === 1 && matches.call(node, importer.loadSelectorsForNode(node));
+ },
+ shouldParseNode: function(node) {
+ return node.nodeType === 1 && matches.call(node, parser.parseSelectorsForNode(node));
+ }
+ };
+ importer.observer.addCallback = dynamic.added.bind(dynamic);
+ var matches = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector;
+});
+
+(function(scope) {
+ var initializeModules = scope.initializeModules;
+ var isIE = scope.isIE;
+ if (scope.useNative) {
+ return;
+ }
+ if (isIE && typeof window.CustomEvent !== "function") {
+ window.CustomEvent = function(inType, params) {
+ params = params || {};
+ var e = document.createEvent("CustomEvent");
+ e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
+ e.preventDefault = function() {
+ Object.defineProperty(this, "defaultPrevented", {
+ get: function() {
+ return true;
+ }
+ });
+ };
+ return e;
+ };
+ window.CustomEvent.prototype = window.Event.prototype;
+ }
+ initializeModules();
+ var rootDocument = scope.rootDocument;
+ function bootstrap() {
+ window.HTMLImports.importer.bootDocument(rootDocument);
+ }
+ if (document.readyState === "complete" || document.readyState === "interactive" && !window.attachEvent) {
+ bootstrap();
+ } else {
+ document.addEventListener("DOMContentLoaded", bootstrap);
+ }
+})(window.HTMLImports);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/HTMLImports.min.js b/polymer_1.0.4/bower_components/webcomponentsjs/HTMLImports.min.js
new file mode 100644
index 0000000..c13580a
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/HTMLImports.min.js
@@ -0,0 +1,11 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.7.5
+"undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,n=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};n.prototype={set:function(t,n){var r=t[this.name];return r&&r[0]===t?r[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),function(e){function t(e){_.push(e),w||(w=!0,f(r))}function n(e){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(e)||e}function r(){w=!1;var e=_;_=[],e.sort(function(e,t){return e.uid_-t.uid_});var t=!1;e.forEach(function(e){var n=e.takeRecords();o(e),n.length&&(e.callback_(n,e),t=!0)}),t&&r()}function o(e){e.nodes_.forEach(function(t){var n=v.get(t);n&&n.forEach(function(t){t.observer===e&&t.removeTransientObservers()})})}function i(e,t){for(var n=e;n;n=n.parentNode){var r=v.get(n);if(r)for(var o=0;o<r.length;o++){var i=r[o],a=i.options;if(n===e||a.subtree){var s=t(a);s&&i.enqueue(s)}}}}function a(e){this.callback_=e,this.nodes_=[],this.records_=[],this.uid_=++E}function s(e,t){this.type=e,this.target=t,this.addedNodes=[],this.removedNodes=[],this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function d(e){var t=new s(e.type,e.target);return t.addedNodes=e.addedNodes.slice(),t.removedNodes=e.removedNodes.slice(),t.previousSibling=e.previousSibling,t.nextSibling=e.nextSibling,t.attributeName=e.attributeName,t.attributeNamespace=e.attributeNamespace,t.oldValue=e.oldValue,t}function c(e,t){return L=new s(e,t)}function u(e){return y?y:(y=d(L),y.oldValue=e,y)}function l(){L=y=void 0}function h(e){return e===y||e===L}function m(e,t){return e===t?e:y&&h(e)?y:null}function p(e,t,n){this.observer=e,this.target=t,this.options=n,this.transientObservedNodes=[]}var f,v=new WeakMap;if(/Trident|Edge/.test(navigator.userAgent))f=setTimeout;else if(window.setImmediate)f=window.setImmediate;else{var b=[],g=String(Math.random());window.addEventListener("message",function(e){if(e.data===g){var t=b;b=[],t.forEach(function(e){e()})}}),f=function(e){b.push(e),window.postMessage(g,"*")}}var w=!1,_=[],E=0;a.prototype={observe:function(e,t){if(e=n(e),!t.childList&&!t.attributes&&!t.characterData||t.attributeOldValue&&!t.attributes||t.attributeFilter&&t.attributeFilter.length&&!t.attributes||t.characterDataOldValue&&!t.characterData)throw new SyntaxError;var r=v.get(e);r||v.set(e,r=[]);for(var o,i=0;i<r.length;i++)if(r[i].observer===this){o=r[i],o.removeListeners(),o.options=t;break}o||(o=new p(this,e,t),r.push(o),this.nodes_.push(e)),o.addListeners()},disconnect:function(){this.nodes_.forEach(function(e){for(var t=v.get(e),n=0;n<t.length;n++){var r=t[n];if(r.observer===this){r.removeListeners(),t.splice(n,1);break}}},this),this.records_=[]},takeRecords:function(){var e=this.records_;return this.records_=[],e}};var L,y;p.prototype={enqueue:function(e){var n=this.observer.records_,r=n.length;if(n.length>0){var o=n[r-1],i=m(o,e);if(i)return void(n[r-1]=i)}else t(this.observer);n[r]=e},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(e){var t=this.options;t.attributes&&e.addEventListener("DOMAttrModified",this,!0),t.characterData&&e.addEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.addEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(e){var t=this.options;t.attributes&&e.removeEventListener("DOMAttrModified",this,!0),t.characterData&&e.removeEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.removeEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(e){if(e!==this.target){this.addListeners_(e),this.transientObservedNodes.push(e);var t=v.get(e);t||v.set(e,t=[]),t.push(this)}},removeTransientObservers:function(){var e=this.transientObservedNodes;this.transientObservedNodes=[],e.forEach(function(e){this.removeListeners_(e);for(var t=v.get(e),n=0;n<t.length;n++)if(t[n]===this){t.splice(n,1);break}},this)},handleEvent:function(e){switch(e.stopImmediatePropagation(),e.type){case"DOMAttrModified":var t=e.attrName,n=e.relatedNode.namespaceURI,r=e.target,o=new c("attributes",r);o.attributeName=t,o.attributeNamespace=n;var a=e.attrChange===MutationEvent.ADDITION?null:e.prevValue;i(r,function(e){return!e.attributes||e.attributeFilter&&e.attributeFilter.length&&-1===e.attributeFilter.indexOf(t)&&-1===e.attributeFilter.indexOf(n)?void 0:e.attributeOldValue?u(a):o});break;case"DOMCharacterDataModified":var r=e.target,o=c("characterData",r),a=e.prevValue;i(r,function(e){return e.characterData?e.characterDataOldValue?u(a):o:void 0});break;case"DOMNodeRemoved":this.addTransientObserver(e.target);case"DOMNodeInserted":var s,d,h=e.target;"DOMNodeInserted"===e.type?(s=[h],d=[]):(s=[],d=[h]);var m=h.previousSibling,p=h.nextSibling,o=c("childList",e.target.parentNode);o.addedNodes=s,o.removedNodes=d,o.previousSibling=m,o.nextSibling=p,i(e.relatedNode,function(e){return e.childList?o:void 0})}l()}},e.JsMutationObserver=a,e.MutationObserver||(e.MutationObserver=a)}(this),window.HTMLImports=window.HTMLImports||{flags:{}},function(e){function t(e,t){t=t||p,r(function(){i(e,t)},t)}function n(e){return"complete"===e.readyState||e.readyState===b}function r(e,t){if(n(t))e&&e();else{var o=function(){("complete"===t.readyState||t.readyState===b)&&(t.removeEventListener(g,o),r(e,t))};t.addEventListener(g,o)}}function o(e){e.target.__loaded=!0}function i(e,t){function n(){d==c&&e&&e({allImports:s,loadedImports:u,errorImports:l})}function r(e){o(e),u.push(this),d++,n()}function i(e){l.push(this),d++,n()}var s=t.querySelectorAll("link[rel=import]"),d=0,c=s.length,u=[],l=[];if(c)for(var h,m=0;c>m&&(h=s[m]);m++)a(h)?(d++,n()):(h.addEventListener("load",r),h.addEventListener("error",i));else n()}function a(e){return l?e.__loaded||e["import"]&&"loading"!==e["import"].readyState:e.__importParsed}function s(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)d(t)&&c(t)}function d(e){return"link"===e.localName&&"import"===e.rel}function c(e){var t=e["import"];t?o({target:e}):(e.addEventListener("load",o),e.addEventListener("error",o))}var u="import",l=Boolean(u in document.createElement("link")),h=Boolean(window.ShadowDOMPolyfill),m=function(e){return h?window.ShadowDOMPolyfill.wrapIfNeeded(e):e},p=m(document),f={get:function(){var e=window.HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return m(e)},configurable:!0};Object.defineProperty(document,"_currentScript",f),Object.defineProperty(p,"_currentScript",f);var v=/Trident/.test(navigator.userAgent),b=v?"complete":"interactive",g="readystatechange";l&&(new MutationObserver(function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.addedNodes&&s(t.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var e,t=document.querySelectorAll("link[rel=import]"),n=0,r=t.length;r>n&&(e=t[n]);n++)c(e)}()),t(function(e){window.HTMLImports.ready=!0,window.HTMLImports.readyTime=(new Date).getTime();var t=p.createEvent("CustomEvent");t.initCustomEvent("HTMLImportsLoaded",!0,!0,e),p.dispatchEvent(t)}),e.IMPORT_LINK_TYPE=u,e.useNative=l,e.rootDocument=p,e.whenReady=t,e.isIE=v}(window.HTMLImports),function(e){var t=[],n=function(e){t.push(e)},r=function(){t.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=r}(window.HTMLImports),window.HTMLImports.addModule(function(e){var t=/(url\()([^)]*)(\))/g,n=/(@import[\s]+(?!url\())([^;]*)(;)/g,r={resolveUrlsInStyle:function(e,t){var n=e.ownerDocument,r=n.createElement("a");return e.textContent=this.resolveUrlsInCssText(e.textContent,t,r),e},resolveUrlsInCssText:function(e,r,o){var i=this.replaceUrls(e,o,r,t);return i=this.replaceUrls(i,o,r,n)},replaceUrls:function(e,t,n,r){return e.replace(r,function(e,r,o,i){var a=o.replace(/["']/g,"");return n&&(a=new URL(a,n).href),t.href=a,a=t.href,r+"'"+a+"'"+i})}};e.path=r}),window.HTMLImports.addModule(function(e){var t={async:!0,ok:function(e){return e.status>=200&&e.status<300||304===e.status||0===e.status},load:function(n,r,o){var i=new XMLHttpRequest;return(e.flags.debug||e.flags.bust)&&(n+="?"+Math.random()),i.open("GET",n,t.async),i.addEventListener("readystatechange",function(e){if(4===i.readyState){var n=i.getResponseHeader("Location"),a=null;if(n)var a="/"===n.substr(0,1)?location.origin+n:n;r.call(o,!t.ok(i)&&i,i.response||i.responseText,a)}}),i.send(),i},loadDocument:function(e,t,n){this.load(e,t,n).responseType="document"}};e.xhr=t}),window.HTMLImports.addModule(function(e){var t=e.xhr,n=e.flags,r=function(e,t){this.cache={},this.onload=e,this.oncomplete=t,this.inflight=0,this.pending={}};r.prototype={addNodes:function(e){this.inflight+=e.length;for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)this.require(t);this.checkDone()},addNode:function(e){this.inflight++,this.require(e),this.checkDone()},require:function(e){var t=e.src||e.href;e.__nodeUrl=t,this.dedupe(t,e)||this.fetch(t,e)},dedupe:function(e,t){if(this.pending[e])return this.pending[e].push(t),!0;return this.cache[e]?(this.onload(e,t,this.cache[e]),this.tail(),!0):(this.pending[e]=[t],!1)},fetch:function(e,r){if(n.load&&console.log("fetch",e,r),e)if(e.match(/^data:/)){var o=e.split(","),i=o[0],a=o[1];a=i.indexOf(";base64")>-1?atob(a):decodeURIComponent(a),setTimeout(function(){this.receive(e,r,null,a)}.bind(this),0)}else{var s=function(t,n,o){this.receive(e,r,t,n,o)}.bind(this);t.load(e,s)}else setTimeout(function(){this.receive(e,r,{error:"href must be specified"},null)}.bind(this),0)},receive:function(e,t,n,r,o){this.cache[e]=r;for(var i,a=this.pending[e],s=0,d=a.length;d>s&&(i=a[s]);s++)this.onload(e,i,r,n,o),this.tail();this.pending[e]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},e.Loader=r}),window.HTMLImports.addModule(function(e){var t=function(e){this.addCallback=e,this.mo=new MutationObserver(this.handler.bind(this))};t.prototype={handler:function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)"childList"===t.type&&t.addedNodes.length&&this.addedNodes(t.addedNodes)},addedNodes:function(e){this.addCallback&&this.addCallback(e);for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.children&&t.children.length&&this.addedNodes(t.children)},observe:function(e){this.mo.observe(e,{childList:!0,subtree:!0})}},e.Observer=t}),window.HTMLImports.addModule(function(e){function t(e){return"link"===e.localName&&e.rel===u}function n(e){var t=r(e);return"data:text/javascript;charset=utf-8,"+encodeURIComponent(t)}function r(e){return e.textContent+o(e)}function o(e){var t=e.ownerDocument;t.__importedScripts=t.__importedScripts||0;var n=e.ownerDocument.baseURI,r=t.__importedScripts?"-"+t.__importedScripts:"";return t.__importedScripts++,"\n//# sourceURL="+n+r+".js\n"}function i(e){var t=e.ownerDocument.createElement("style");return t.textContent=e.textContent,a.resolveUrlsInStyle(t),t}var a=e.path,s=e.rootDocument,d=e.flags,c=e.isIE,u=e.IMPORT_LINK_TYPE,l="link[rel="+u+"]",h={documentSelectors:l,importsSelectors:[l,"link[rel=stylesheet]","style","script:not([type])",'script[type="application/javascript"]','script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},dynamicElements:[],parseNext:function(){var e=this.nextToParse();e&&this.parse(e)},parse:function(e){if(this.isParsed(e))return void(d.parse&&console.log("[%s] is already parsed",e.localName));var t=this[this.map[e.localName]];t&&(this.markParsing(e),t.call(this,e))},parseDynamic:function(e,t){this.dynamicElements.push(e),t||this.parseNext()},markParsing:function(e){d.parse&&console.log("parsing",e),this.parsingElement=e},markParsingComplete:function(e){e.__importParsed=!0,this.markDynamicParsingComplete(e),e.__importElement&&(e.__importElement.__importParsed=!0,this.markDynamicParsingComplete(e.__importElement)),this.parsingElement=null,d.parse&&console.log("completed",e)},markDynamicParsingComplete:function(e){var t=this.dynamicElements.indexOf(e);t>=0&&this.dynamicElements.splice(t,1)},parseImport:function(e){if(window.HTMLImports.__importsParsingHook&&window.HTMLImports.__importsParsingHook(e),e["import"]&&(e["import"].__importParsed=!0),this.markParsingComplete(e),e.dispatchEvent(e.__resource&&!e.__error?new CustomEvent("load",{bubbles:!1}):new CustomEvent("error",{bubbles:!1})),e.__pending)for(var t;e.__pending.length;)t=e.__pending.shift(),t&&t({target:e});this.parseNext()},parseLink:function(e){t(e)?this.parseImport(e):(e.href=e.href,this.parseGeneric(e))},parseStyle:function(e){var t=e;e=i(e),t.__appliedElement=e,e.__importElement=t,this.parseGeneric(e)},parseGeneric:function(e){this.trackElement(e),this.addElementToDocument(e)},rootImportForElement:function(e){for(var t=e;t.ownerDocument.__importLink;)t=t.ownerDocument.__importLink;return t},addElementToDocument:function(e){var t=this.rootImportForElement(e.__importElement||e);t.parentNode.insertBefore(e,t)},trackElement:function(e,t){var n=this,r=function(r){t&&t(r),n.markParsingComplete(e),n.parseNext()};if(e.addEventListener("load",r),e.addEventListener("error",r),c&&"style"===e.localName){var o=!1;if(-1==e.textContent.indexOf("@import"))o=!0;else if(e.sheet){o=!0;for(var i,a=e.sheet.cssRules,s=a?a.length:0,d=0;s>d&&(i=a[d]);d++)i.type===CSSRule.IMPORT_RULE&&(o=o&&Boolean(i.styleSheet))}o&&setTimeout(function(){e.dispatchEvent(new CustomEvent("load",{bubbles:!1}))})}},parseScript:function(t){var r=document.createElement("script");r.__importElement=t,r.src=t.src?t.src:n(t),e.currentScript=t,this.trackElement(r,function(t){r.parentNode.removeChild(r),e.currentScript=null}),this.addElementToDocument(r)},nextToParse:function(){return this._mayParse=[],!this.parsingElement&&(this.nextToParseInDoc(s)||this.nextToParseDynamic())},nextToParseInDoc:function(e,n){if(e&&this._mayParse.indexOf(e)<0){this._mayParse.push(e);for(var r,o=e.querySelectorAll(this.parseSelectorsForNode(e)),i=0,a=o.length;a>i&&(r=o[i]);i++)if(!this.isParsed(r))return this.hasResource(r)?t(r)?this.nextToParseInDoc(r["import"],r):r:void 0}return n},nextToParseDynamic:function(){return this.dynamicElements[0]},parseSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===s?this.documentSelectors:this.importsSelectors},isParsed:function(e){return e.__importParsed},needsDynamicParsing:function(e){return this.dynamicElements.indexOf(e)>=0},hasResource:function(e){return t(e)&&void 0===e["import"]?!1:!0}};e.parser=h,e.IMPORT_SELECTOR=l}),window.HTMLImports.addModule(function(e){function t(e){return n(e,a)}function n(e,t){return"link"===e.localName&&e.getAttribute("rel")===t}function r(e){return!!Object.getOwnPropertyDescriptor(e,"baseURI")}function o(e,t){var n=document.implementation.createHTMLDocument(a);n._URL=t;var o=n.createElement("base");o.setAttribute("href",t),n.baseURI||r(n)||Object.defineProperty(n,"baseURI",{value:t});var i=n.createElement("meta");return i.setAttribute("charset","utf-8"),n.head.appendChild(i),n.head.appendChild(o),n.body.innerHTML=e,window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(n),n}var i=e.flags,a=e.IMPORT_LINK_TYPE,s=e.IMPORT_SELECTOR,d=e.rootDocument,c=e.Loader,u=e.Observer,l=e.parser,h={documents:{},documentPreloadSelectors:s,importsPreloadSelectors:[s].join(","),loadNode:function(e){m.addNode(e)},loadSubtree:function(e){var t=this.marshalNodes(e);m.addNodes(t)},marshalNodes:function(e){return e.querySelectorAll(this.loadSelectorsForNode(e))},loadSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===d?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(e,n,r,a,s){if(i.load&&console.log("loaded",e,n),n.__resource=r,n.__error=a,t(n)){var d=this.documents[e];void 0===d&&(d=a?null:o(r,s||e),d&&(d.__importLink=n,this.bootDocument(d)),this.documents[e]=d),n["import"]=d}l.parseNext()},bootDocument:function(e){this.loadSubtree(e),this.observer.observe(e),l.parseNext()},loadedAll:function(){l.parseNext()}},m=new c(h.loaded.bind(h),h.loadedAll.bind(h));if(h.observer=new u,!document.baseURI){var p={get:function(){var e=document.querySelector("base");return e?e.href:window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",p),Object.defineProperty(d,"baseURI",p)}e.importer=h,e.importLoader=m}),window.HTMLImports.addModule(function(e){var t=e.parser,n=e.importer,r={added:function(e){for(var r,o,i,a,s=0,d=e.length;d>s&&(a=e[s]);s++)r||(r=a.ownerDocument,o=t.isParsed(r)),i=this.shouldLoadNode(a),i&&n.loadNode(a),this.shouldParseNode(a)&&o&&t.parseDynamic(a,i)},shouldLoadNode:function(e){return 1===e.nodeType&&o.call(e,n.loadSelectorsForNode(e))},shouldParseNode:function(e){return 1===e.nodeType&&o.call(e,t.parseSelectorsForNode(e))}};n.observer.addCallback=r.added.bind(r);var o=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector}),function(e){function t(){window.HTMLImports.importer.bootDocument(o)}var n=e.initializeModules,r=e.isIE;if(!e.useNative){r&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n.preventDefault=function(){Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}})},n},window.CustomEvent.prototype=window.Event.prototype),n();var o=e.rootDocument;"complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?t():document.addEventListener("DOMContentLoaded",t)}}(window.HTMLImports);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/MutationObserver.js b/polymer_1.0.4/bower_components/webcomponentsjs/MutationObserver.js
new file mode 100644
index 0000000..b8fb3cf
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/MutationObserver.js
@@ -0,0 +1,344 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.7.5
+if (typeof WeakMap === "undefined") {
+ (function() {
+ var defineProperty = Object.defineProperty;
+ var counter = Date.now() % 1e9;
+ var WeakMap = function() {
+ this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
+ };
+ WeakMap.prototype = {
+ set: function(key, value) {
+ var entry = key[this.name];
+ if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
+ value: [ key, value ],
+ writable: true
+ });
+ return this;
+ },
+ get: function(key) {
+ var entry;
+ return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
+ },
+ "delete": function(key) {
+ var entry = key[this.name];
+ if (!entry || entry[0] !== key) return false;
+ entry[0] = entry[1] = undefined;
+ return true;
+ },
+ has: function(key) {
+ var entry = key[this.name];
+ if (!entry) return false;
+ return entry[0] === key;
+ }
+ };
+ window.WeakMap = WeakMap;
+ })();
+}
+
+(function(global) {
+ var registrationsTable = new WeakMap();
+ var setImmediate;
+ if (/Trident|Edge/.test(navigator.userAgent)) {
+ setImmediate = setTimeout;
+ } else if (window.setImmediate) {
+ setImmediate = window.setImmediate;
+ } else {
+ var setImmediateQueue = [];
+ var sentinel = String(Math.random());
+ window.addEventListener("message", function(e) {
+ if (e.data === sentinel) {
+ var queue = setImmediateQueue;
+ setImmediateQueue = [];
+ queue.forEach(function(func) {
+ func();
+ });
+ }
+ });
+ setImmediate = function(func) {
+ setImmediateQueue.push(func);
+ window.postMessage(sentinel, "*");
+ };
+ }
+ var isScheduled = false;
+ var scheduledObservers = [];
+ function scheduleCallback(observer) {
+ scheduledObservers.push(observer);
+ if (!isScheduled) {
+ isScheduled = true;
+ setImmediate(dispatchCallbacks);
+ }
+ }
+ function wrapIfNeeded(node) {
+ return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;
+ }
+ function dispatchCallbacks() {
+ isScheduled = false;
+ var observers = scheduledObservers;
+ scheduledObservers = [];
+ observers.sort(function(o1, o2) {
+ return o1.uid_ - o2.uid_;
+ });
+ var anyNonEmpty = false;
+ observers.forEach(function(observer) {
+ var queue = observer.takeRecords();
+ removeTransientObserversFor(observer);
+ if (queue.length) {
+ observer.callback_(queue, observer);
+ anyNonEmpty = true;
+ }
+ });
+ if (anyNonEmpty) dispatchCallbacks();
+ }
+ function removeTransientObserversFor(observer) {
+ observer.nodes_.forEach(function(node) {
+ var registrations = registrationsTable.get(node);
+ if (!registrations) return;
+ registrations.forEach(function(registration) {
+ if (registration.observer === observer) registration.removeTransientObservers();
+ });
+ });
+ }
+ function forEachAncestorAndObserverEnqueueRecord(target, callback) {
+ for (var node = target; node; node = node.parentNode) {
+ var registrations = registrationsTable.get(node);
+ if (registrations) {
+ for (var j = 0; j < registrations.length; j++) {
+ var registration = registrations[j];
+ var options = registration.options;
+ if (node !== target && !options.subtree) continue;
+ var record = callback(options);
+ if (record) registration.enqueue(record);
+ }
+ }
+ }
+ }
+ var uidCounter = 0;
+ function JsMutationObserver(callback) {
+ this.callback_ = callback;
+ this.nodes_ = [];
+ this.records_ = [];
+ this.uid_ = ++uidCounter;
+ }
+ JsMutationObserver.prototype = {
+ observe: function(target, options) {
+ target = wrapIfNeeded(target);
+ if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {
+ throw new SyntaxError();
+ }
+ var registrations = registrationsTable.get(target);
+ if (!registrations) registrationsTable.set(target, registrations = []);
+ var registration;
+ for (var i = 0; i < registrations.length; i++) {
+ if (registrations[i].observer === this) {
+ registration = registrations[i];
+ registration.removeListeners();
+ registration.options = options;
+ break;
+ }
+ }
+ if (!registration) {
+ registration = new Registration(this, target, options);
+ registrations.push(registration);
+ this.nodes_.push(target);
+ }
+ registration.addListeners();
+ },
+ disconnect: function() {
+ this.nodes_.forEach(function(node) {
+ var registrations = registrationsTable.get(node);
+ for (var i = 0; i < registrations.length; i++) {
+ var registration = registrations[i];
+ if (registration.observer === this) {
+ registration.removeListeners();
+ registrations.splice(i, 1);
+ break;
+ }
+ }
+ }, this);
+ this.records_ = [];
+ },
+ takeRecords: function() {
+ var copyOfRecords = this.records_;
+ this.records_ = [];
+ return copyOfRecords;
+ }
+ };
+ function MutationRecord(type, target) {
+ this.type = type;
+ this.target = target;
+ this.addedNodes = [];
+ this.removedNodes = [];
+ this.previousSibling = null;
+ this.nextSibling = null;
+ this.attributeName = null;
+ this.attributeNamespace = null;
+ this.oldValue = null;
+ }
+ function copyMutationRecord(original) {
+ var record = new MutationRecord(original.type, original.target);
+ record.addedNodes = original.addedNodes.slice();
+ record.removedNodes = original.removedNodes.slice();
+ record.previousSibling = original.previousSibling;
+ record.nextSibling = original.nextSibling;
+ record.attributeName = original.attributeName;
+ record.attributeNamespace = original.attributeNamespace;
+ record.oldValue = original.oldValue;
+ return record;
+ }
+ var currentRecord, recordWithOldValue;
+ function getRecord(type, target) {
+ return currentRecord = new MutationRecord(type, target);
+ }
+ function getRecordWithOldValue(oldValue) {
+ if (recordWithOldValue) return recordWithOldValue;
+ recordWithOldValue = copyMutationRecord(currentRecord);
+ recordWithOldValue.oldValue = oldValue;
+ return recordWithOldValue;
+ }
+ function clearRecords() {
+ currentRecord = recordWithOldValue = undefined;
+ }
+ function recordRepresentsCurrentMutation(record) {
+ return record === recordWithOldValue || record === currentRecord;
+ }
+ function selectRecord(lastRecord, newRecord) {
+ if (lastRecord === newRecord) return lastRecord;
+ if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;
+ return null;
+ }
+ function Registration(observer, target, options) {
+ this.observer = observer;
+ this.target = target;
+ this.options = options;
+ this.transientObservedNodes = [];
+ }
+ Registration.prototype = {
+ enqueue: function(record) {
+ var records = this.observer.records_;
+ var length = records.length;
+ if (records.length > 0) {
+ var lastRecord = records[length - 1];
+ var recordToReplaceLast = selectRecord(lastRecord, record);
+ if (recordToReplaceLast) {
+ records[length - 1] = recordToReplaceLast;
+ return;
+ }
+ } else {
+ scheduleCallback(this.observer);
+ }
+ records[length] = record;
+ },
+ addListeners: function() {
+ this.addListeners_(this.target);
+ },
+ addListeners_: function(node) {
+ var options = this.options;
+ if (options.attributes) node.addEventListener("DOMAttrModified", this, true);
+ if (options.characterData) node.addEventListener("DOMCharacterDataModified", this, true);
+ if (options.childList) node.addEventListener("DOMNodeInserted", this, true);
+ if (options.childList || options.subtree) node.addEventListener("DOMNodeRemoved", this, true);
+ },
+ removeListeners: function() {
+ this.removeListeners_(this.target);
+ },
+ removeListeners_: function(node) {
+ var options = this.options;
+ if (options.attributes) node.removeEventListener("DOMAttrModified", this, true);
+ if (options.characterData) node.removeEventListener("DOMCharacterDataModified", this, true);
+ if (options.childList) node.removeEventListener("DOMNodeInserted", this, true);
+ if (options.childList || options.subtree) node.removeEventListener("DOMNodeRemoved", this, true);
+ },
+ addTransientObserver: function(node) {
+ if (node === this.target) return;
+ this.addListeners_(node);
+ this.transientObservedNodes.push(node);
+ var registrations = registrationsTable.get(node);
+ if (!registrations) registrationsTable.set(node, registrations = []);
+ registrations.push(this);
+ },
+ removeTransientObservers: function() {
+ var transientObservedNodes = this.transientObservedNodes;
+ this.transientObservedNodes = [];
+ transientObservedNodes.forEach(function(node) {
+ this.removeListeners_(node);
+ var registrations = registrationsTable.get(node);
+ for (var i = 0; i < registrations.length; i++) {
+ if (registrations[i] === this) {
+ registrations.splice(i, 1);
+ break;
+ }
+ }
+ }, this);
+ },
+ handleEvent: function(e) {
+ e.stopImmediatePropagation();
+ switch (e.type) {
+ case "DOMAttrModified":
+ var name = e.attrName;
+ var namespace = e.relatedNode.namespaceURI;
+ var target = e.target;
+ var record = new getRecord("attributes", target);
+ record.attributeName = name;
+ record.attributeNamespace = namespace;
+ var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
+ forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+ if (!options.attributes) return;
+ if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {
+ return;
+ }
+ if (options.attributeOldValue) return getRecordWithOldValue(oldValue);
+ return record;
+ });
+ break;
+
+ case "DOMCharacterDataModified":
+ var target = e.target;
+ var record = getRecord("characterData", target);
+ var oldValue = e.prevValue;
+ forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+ if (!options.characterData) return;
+ if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);
+ return record;
+ });
+ break;
+
+ case "DOMNodeRemoved":
+ this.addTransientObserver(e.target);
+
+ case "DOMNodeInserted":
+ var changedNode = e.target;
+ var addedNodes, removedNodes;
+ if (e.type === "DOMNodeInserted") {
+ addedNodes = [ changedNode ];
+ removedNodes = [];
+ } else {
+ addedNodes = [];
+ removedNodes = [ changedNode ];
+ }
+ var previousSibling = changedNode.previousSibling;
+ var nextSibling = changedNode.nextSibling;
+ var record = getRecord("childList", e.target.parentNode);
+ record.addedNodes = addedNodes;
+ record.removedNodes = removedNodes;
+ record.previousSibling = previousSibling;
+ record.nextSibling = nextSibling;
+ forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) {
+ if (!options.childList) return;
+ return record;
+ });
+ }
+ clearRecords();
+ }
+ };
+ global.JsMutationObserver = JsMutationObserver;
+ if (!global.MutationObserver) global.MutationObserver = JsMutationObserver;
+})(this);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/MutationObserver.min.js b/polymer_1.0.4/bower_components/webcomponentsjs/MutationObserver.min.js
new file mode 100644
index 0000000..45b4cbf
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/MutationObserver.min.js
@@ -0,0 +1,11 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.7.5
+"undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,r=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};r.prototype={set:function(t,r){var i=t[this.name];return i&&i[0]===t?i[1]=r:e(t,this.name,{value:[t,r],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=r}(),function(e){function t(e){O.push(e),N||(N=!0,b(i))}function r(e){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(e)||e}function i(){N=!1;var e=O;O=[],e.sort(function(e,t){return e.uid_-t.uid_});var t=!1;e.forEach(function(e){var r=e.takeRecords();n(e),r.length&&(e.callback_(r,e),t=!0)}),t&&i()}function n(e){e.nodes_.forEach(function(t){var r=p.get(t);r&&r.forEach(function(t){t.observer===e&&t.removeTransientObservers()})})}function a(e,t){for(var r=e;r;r=r.parentNode){var i=p.get(r);if(i)for(var n=0;n<i.length;n++){var a=i[n],s=a.options;if(r===e||s.subtree){var o=t(s);o&&a.enqueue(o)}}}}function s(e){this.callback_=e,this.nodes_=[],this.records_=[],this.uid_=++M}function o(e,t){this.type=e,this.target=t,this.addedNodes=[],this.removedNodes=[],this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function d(e){var t=new o(e.type,e.target);return t.addedNodes=e.addedNodes.slice(),t.removedNodes=e.removedNodes.slice(),t.previousSibling=e.previousSibling,t.nextSibling=e.nextSibling,t.attributeName=e.attributeName,t.attributeNamespace=e.attributeNamespace,t.oldValue=e.oldValue,t}function u(e,t){return D=new o(e,t)}function h(e){return w?w:(w=d(D),w.oldValue=e,w)}function c(){D=w=void 0}function v(e){return e===w||e===D}function l(e,t){return e===t?e:w&&v(e)?w:null}function f(e,t,r){this.observer=e,this.target=t,this.options=r,this.transientObservedNodes=[]}var b,p=new WeakMap;if(/Trident|Edge/.test(navigator.userAgent))b=setTimeout;else if(window.setImmediate)b=window.setImmediate;else{var g=[],m=String(Math.random());window.addEventListener("message",function(e){if(e.data===m){var t=g;g=[],t.forEach(function(e){e()})}}),b=function(e){g.push(e),window.postMessage(m,"*")}}var N=!1,O=[],M=0;s.prototype={observe:function(e,t){if(e=r(e),!t.childList&&!t.attributes&&!t.characterData||t.attributeOldValue&&!t.attributes||t.attributeFilter&&t.attributeFilter.length&&!t.attributes||t.characterDataOldValue&&!t.characterData)throw new SyntaxError;var i=p.get(e);i||p.set(e,i=[]);for(var n,a=0;a<i.length;a++)if(i[a].observer===this){n=i[a],n.removeListeners(),n.options=t;break}n||(n=new f(this,e,t),i.push(n),this.nodes_.push(e)),n.addListeners()},disconnect:function(){this.nodes_.forEach(function(e){for(var t=p.get(e),r=0;r<t.length;r++){var i=t[r];if(i.observer===this){i.removeListeners(),t.splice(r,1);break}}},this),this.records_=[]},takeRecords:function(){var e=this.records_;return this.records_=[],e}};var D,w;f.prototype={enqueue:function(e){var r=this.observer.records_,i=r.length;if(r.length>0){var n=r[i-1],a=l(n,e);if(a)return void(r[i-1]=a)}else t(this.observer);r[i]=e},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(e){var t=this.options;t.attributes&&e.addEventListener("DOMAttrModified",this,!0),t.characterData&&e.addEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.addEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(e){var t=this.options;t.attributes&&e.removeEventListener("DOMAttrModified",this,!0),t.characterData&&e.removeEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.removeEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(e){if(e!==this.target){this.addListeners_(e),this.transientObservedNodes.push(e);var t=p.get(e);t||p.set(e,t=[]),t.push(this)}},removeTransientObservers:function(){var e=this.transientObservedNodes;this.transientObservedNodes=[],e.forEach(function(e){this.removeListeners_(e);for(var t=p.get(e),r=0;r<t.length;r++)if(t[r]===this){t.splice(r,1);break}},this)},handleEvent:function(e){switch(e.stopImmediatePropagation(),e.type){case"DOMAttrModified":var t=e.attrName,r=e.relatedNode.namespaceURI,i=e.target,n=new u("attributes",i);n.attributeName=t,n.attributeNamespace=r;var s=e.attrChange===MutationEvent.ADDITION?null:e.prevValue;a(i,function(e){return!e.attributes||e.attributeFilter&&e.attributeFilter.length&&-1===e.attributeFilter.indexOf(t)&&-1===e.attributeFilter.indexOf(r)?void 0:e.attributeOldValue?h(s):n});break;case"DOMCharacterDataModified":var i=e.target,n=u("characterData",i),s=e.prevValue;a(i,function(e){return e.characterData?e.characterDataOldValue?h(s):n:void 0});break;case"DOMNodeRemoved":this.addTransientObserver(e.target);case"DOMNodeInserted":var o,d,v=e.target;"DOMNodeInserted"===e.type?(o=[v],d=[]):(o=[],d=[v]);var l=v.previousSibling,f=v.nextSibling,n=u("childList",e.target.parentNode);n.addedNodes=o,n.removedNodes=d,n.previousSibling=l,n.nextSibling=f,a(e.relatedNode,function(e){return e.childList?n:void 0})}c()}},e.JsMutationObserver=s,e.MutationObserver||(e.MutationObserver=s)}(this);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/README.md b/polymer_1.0.4/bower_components/webcomponentsjs/README.md
new file mode 100644
index 0000000..9cf692f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/README.md
@@ -0,0 +1,125 @@
+webcomponents.js
+================
+
+[](https://gitter.im/webcomponents/webcomponentsjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+A suite of polyfills supporting the [Web Components](http://webcomponents.org) specs:
+
+**Custom Elements**: allows authors to define their own custom tags ([spec](https://w3c.github.io/webcomponents/spec/custom/)).
+
+**HTML Imports**: a way to include and reuse HTML documents via other HTML documents ([spec](https://w3c.github.io/webcomponents/spec/imports/)).
+
+**Shadow DOM**: provides encapsulation by hiding DOM subtrees under shadow roots ([spec](https://w3c.github.io/webcomponents/spec/shadow/)).
+
+This also folds in polyfills for `MutationObserver` and `WeakMap`.
+
+
+## Releases
+
+Pre-built (concatenated & minified) versions of the polyfills are maintained in the [tagged versions](https://github.com/webcomponents/webcomponentsjs/releases) of this repo. There are two variants:
+
+`webcomponents.js` includes all of the polyfills.
+
+`webcomponents-lite.js` includes all polyfills except for shadow DOM.
+
+
+## Browser Support
+
+Our polyfills are intended to work in the latest versions of evergreen browsers. See below
+for our complete browser support matrix:
+
+| Polyfill | IE10 | IE11+ | Chrome* | Firefox* | Safari 7+* | Chrome Android* | Mobile Safari* |
+| ---------- |:----:|:-----:|:-------:|:--------:|:----------:|:---------------:|:--------------:|
+| Custom Elements | ~ | ✓ | ✓ | ✓ | ✓ | ✓| ✓ |
+| HTML Imports | ~ | ✓ | ✓ | ✓ | ✓| ✓| ✓ |
+| Shadow DOM | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Templates | ✓ | ✓ | ✓ | ✓| ✓ | ✓ | ✓ |
+
+
+*Indicates the current version of the browser
+
+~Indicates support may be flaky. If using Custom Elements or HTML Imports with Shadow DOM,
+you will get the non-flaky Mutation Observer polyfill that Shadow DOM includes.
+
+The polyfills may work in older browsers, however require additional polyfills (such as classList)
+to be used. We cannot guarantee support for browsers outside of our compatibility matrix.
+
+
+### Manually Building
+
+If you wish to build the polyfills yourself, you'll need `node` and `gulp` on your system:
+
+ * install [node.js](http://nodejs.org/) using the instructions on their website
+ * use `npm` to install [gulp.js](http://gulpjs.com/): `npm install -g gulp`
+
+Now you are ready to build the polyfills with:
+
+ # install dependencies
+ npm install
+ # build
+ gulp build
+
+The builds will be placed into the `dist/` directory.
+
+## Contribute
+
+See the [contributing guide](CONTRIBUTING.md)
+
+## License
+
+Everything in this repository is BSD style license unless otherwise specified.
+
+Copyright (c) 2015 The Polymer Authors. All rights reserved.
+
+## Helper utilities
+
+### `WebComponentsReady`
+
+Under native HTML Imports, `<script>` tags in the main document block the loading of such imports. This is to ensure the imports have loaded and any registered elements in them have been upgraded.
+
+The webcomponents.js and webcomponents-lite.js polyfills parse element definitions and handle their upgrade asynchronously. If prematurely fetching the element from the DOM before it has an opportunity to upgrade, you'll be working with an `HTMLUnknownElement`.
+
+For these situations (or when you need an approximate replacement for the Polymer 0.5 `polymer-ready` behavior), you can use the `WebComponentsReady` event as a signal before interacting with the element. The criteria for this event to fire is all Custom Elements with definitions registered by the time HTML Imports available at load time have loaded have upgraded.
+
+```js
+window.addEventListener('WebComponentsReady', function(e) {
+ // imports are loaded and elements have been registered
+ console.log('Components are ready');
+});
+```
+
+## Known Issues
+
+ * [Custom element's constructor property is unreliable](#constructor)
+ * [Contenteditable elements do not trigger MutationObserver](#contentedit)
+ * [ShadowCSS: :host-context(...):host(...) doesn't work](#hostcontext)
+ * [execCommand isn't supported under Shadow DOM](#execcommand)
+
+### Custom element's constructor property is unreliable <a id="constructor"></a>
+See [#215](https://github.com/webcomponents/webcomponentsjs/issues/215) for background.
+
+In Safari and IE, instances of Custom Elements have a `constructor` property of `HTMLUnknownElementConstructor` and `HTMLUnknownElement`, respectively. It's unsafe to rely on this property for checking element types.
+
+It's worth noting that `customElement.__proto__.__proto__.constructor` is `HTMLElementPrototype` and that the prototype chain isn't modified by the polyfills(onto `ElementPrototype`, etc.)
+
+### Contenteditable elements do not trigger MutationObserver <a id="contentedit"></a>
+Using the MutationObserver polyfill, it isn't possible to monitor mutations of an element marked `contenteditable`.
+See [the mailing list](https://groups.google.com/forum/#!msg/polymer-dev/LHdtRVXXVsA/v1sGoiTYWUkJ)
+
+### ShadowCSS: :host-context(...):host(...) doesn't work <a id="hostcontext"></a>
+See [#16](https://github.com/webcomponents/webcomponentsjs/issues/16) for background.
+
+Under the shadow DOM polyfill, rules like:
+```
+:host-context(.foo):host(.bar) {...}
+```
+don't work, despite working under native Shadow DOM. The solution is to use `polyfill-next-selector` like:
+
+```
+polyfill-next-selector { content: '.foo :host.bar, :host.foo.bar'; }
+```
+
+### execCommand and contenteditable isn't supported under Shadow DOM <a id="execcommand"></a>
+See [#212](https://github.com/webcomponents/webcomponentsjs/issues/212)
+
+`execCommand`, and `contenteditable` aren't supported under the ShadowDOM polyfill, with commands that insert or remove nodes being especially prone to failure.
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/ShadowDOM.js b/polymer_1.0.4/bower_components/webcomponentsjs/ShadowDOM.js
new file mode 100644
index 0000000..dc67ad9
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/ShadowDOM.js
@@ -0,0 +1,4414 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.7.5
+if (typeof WeakMap === "undefined") {
+ (function() {
+ var defineProperty = Object.defineProperty;
+ var counter = Date.now() % 1e9;
+ var WeakMap = function() {
+ this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
+ };
+ WeakMap.prototype = {
+ set: function(key, value) {
+ var entry = key[this.name];
+ if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
+ value: [ key, value ],
+ writable: true
+ });
+ return this;
+ },
+ get: function(key) {
+ var entry;
+ return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
+ },
+ "delete": function(key) {
+ var entry = key[this.name];
+ if (!entry || entry[0] !== key) return false;
+ entry[0] = entry[1] = undefined;
+ return true;
+ },
+ has: function(key) {
+ var entry = key[this.name];
+ if (!entry) return false;
+ return entry[0] === key;
+ }
+ };
+ window.WeakMap = WeakMap;
+ })();
+}
+
+window.ShadowDOMPolyfill = {};
+
+(function(scope) {
+ "use strict";
+ var constructorTable = new WeakMap();
+ var nativePrototypeTable = new WeakMap();
+ var wrappers = Object.create(null);
+ function detectEval() {
+ if (typeof chrome !== "undefined" && chrome.app && chrome.app.runtime) {
+ return false;
+ }
+ if (navigator.getDeviceStorage) {
+ return false;
+ }
+ try {
+ var f = new Function("return true;");
+ return f();
+ } catch (ex) {
+ return false;
+ }
+ }
+ var hasEval = detectEval();
+ function assert(b) {
+ if (!b) throw new Error("Assertion failed");
+ }
+ var defineProperty = Object.defineProperty;
+ var getOwnPropertyNames = Object.getOwnPropertyNames;
+ var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
+ function mixin(to, from) {
+ var names = getOwnPropertyNames(from);
+ for (var i = 0; i < names.length; i++) {
+ var name = names[i];
+ defineProperty(to, name, getOwnPropertyDescriptor(from, name));
+ }
+ return to;
+ }
+ function mixinStatics(to, from) {
+ var names = getOwnPropertyNames(from);
+ for (var i = 0; i < names.length; i++) {
+ var name = names[i];
+ switch (name) {
+ case "arguments":
+ case "caller":
+ case "length":
+ case "name":
+ case "prototype":
+ case "toString":
+ continue;
+ }
+ defineProperty(to, name, getOwnPropertyDescriptor(from, name));
+ }
+ return to;
+ }
+ function oneOf(object, propertyNames) {
+ for (var i = 0; i < propertyNames.length; i++) {
+ if (propertyNames[i] in object) return propertyNames[i];
+ }
+ }
+ var nonEnumerableDataDescriptor = {
+ value: undefined,
+ configurable: true,
+ enumerable: false,
+ writable: true
+ };
+ function defineNonEnumerableDataProperty(object, name, value) {
+ nonEnumerableDataDescriptor.value = value;
+ defineProperty(object, name, nonEnumerableDataDescriptor);
+ }
+ getOwnPropertyNames(window);
+ function getWrapperConstructor(node, opt_instance) {
+ var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);
+ if (isFirefox) {
+ try {
+ getOwnPropertyNames(nativePrototype);
+ } catch (error) {
+ nativePrototype = nativePrototype.__proto__;
+ }
+ }
+ var wrapperConstructor = constructorTable.get(nativePrototype);
+ if (wrapperConstructor) return wrapperConstructor;
+ var parentWrapperConstructor = getWrapperConstructor(nativePrototype);
+ var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor);
+ registerInternal(nativePrototype, GeneratedWrapper, opt_instance);
+ return GeneratedWrapper;
+ }
+ function addForwardingProperties(nativePrototype, wrapperPrototype) {
+ installProperty(nativePrototype, wrapperPrototype, true);
+ }
+ function registerInstanceProperties(wrapperPrototype, instanceObject) {
+ installProperty(instanceObject, wrapperPrototype, false);
+ }
+ var isFirefox = /Firefox/.test(navigator.userAgent);
+ var dummyDescriptor = {
+ get: function() {},
+ set: function(v) {},
+ configurable: true,
+ enumerable: true
+ };
+ function isEventHandlerName(name) {
+ return /^on[a-z]+$/.test(name);
+ }
+ function isIdentifierName(name) {
+ return /^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name);
+ }
+ function getGetter(name) {
+ return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name) : function() {
+ return this.__impl4cf1e782hg__[name];
+ };
+ }
+ function getSetter(name) {
+ return hasEval && isIdentifierName(name) ? new Function("v", "this.__impl4cf1e782hg__." + name + " = v") : function(v) {
+ this.__impl4cf1e782hg__[name] = v;
+ };
+ }
+ function getMethod(name) {
+ return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name + ".apply(this.__impl4cf1e782hg__, arguments)") : function() {
+ return this.__impl4cf1e782hg__[name].apply(this.__impl4cf1e782hg__, arguments);
+ };
+ }
+ function getDescriptor(source, name) {
+ try {
+ return Object.getOwnPropertyDescriptor(source, name);
+ } catch (ex) {
+ return dummyDescriptor;
+ }
+ }
+ var isBrokenSafari = function() {
+ var descr = Object.getOwnPropertyDescriptor(Node.prototype, "nodeType");
+ return descr && !descr.get && !descr.set;
+ }();
+ function installProperty(source, target, allowMethod, opt_blacklist) {
+ var names = getOwnPropertyNames(source);
+ for (var i = 0; i < names.length; i++) {
+ var name = names[i];
+ if (name === "polymerBlackList_") continue;
+ if (name in target) continue;
+ if (source.polymerBlackList_ && source.polymerBlackList_[name]) continue;
+ if (isFirefox) {
+ source.__lookupGetter__(name);
+ }
+ var descriptor = getDescriptor(source, name);
+ var getter, setter;
+ if (typeof descriptor.value === "function") {
+ if (allowMethod) {
+ target[name] = getMethod(name);
+ }
+ continue;
+ }
+ var isEvent = isEventHandlerName(name);
+ if (isEvent) getter = scope.getEventHandlerGetter(name); else getter = getGetter(name);
+ if (descriptor.writable || descriptor.set || isBrokenSafari) {
+ if (isEvent) setter = scope.getEventHandlerSetter(name); else setter = getSetter(name);
+ }
+ var configurable = isBrokenSafari || descriptor.configurable;
+ defineProperty(target, name, {
+ get: getter,
+ set: setter,
+ configurable: configurable,
+ enumerable: descriptor.enumerable
+ });
+ }
+ }
+ function register(nativeConstructor, wrapperConstructor, opt_instance) {
+ if (nativeConstructor == null) {
+ return;
+ }
+ var nativePrototype = nativeConstructor.prototype;
+ registerInternal(nativePrototype, wrapperConstructor, opt_instance);
+ mixinStatics(wrapperConstructor, nativeConstructor);
+ }
+ function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {
+ var wrapperPrototype = wrapperConstructor.prototype;
+ assert(constructorTable.get(nativePrototype) === undefined);
+ constructorTable.set(nativePrototype, wrapperConstructor);
+ nativePrototypeTable.set(wrapperPrototype, nativePrototype);
+ addForwardingProperties(nativePrototype, wrapperPrototype);
+ if (opt_instance) registerInstanceProperties(wrapperPrototype, opt_instance);
+ defineNonEnumerableDataProperty(wrapperPrototype, "constructor", wrapperConstructor);
+ wrapperConstructor.prototype = wrapperPrototype;
+ }
+ function isWrapperFor(wrapperConstructor, nativeConstructor) {
+ return constructorTable.get(nativeConstructor.prototype) === wrapperConstructor;
+ }
+ function registerObject(object) {
+ var nativePrototype = Object.getPrototypeOf(object);
+ var superWrapperConstructor = getWrapperConstructor(nativePrototype);
+ var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);
+ registerInternal(nativePrototype, GeneratedWrapper, object);
+ return GeneratedWrapper;
+ }
+ function createWrapperConstructor(superWrapperConstructor) {
+ function GeneratedWrapper(node) {
+ superWrapperConstructor.call(this, node);
+ }
+ var p = Object.create(superWrapperConstructor.prototype);
+ p.constructor = GeneratedWrapper;
+ GeneratedWrapper.prototype = p;
+ return GeneratedWrapper;
+ }
+ function isWrapper(object) {
+ return object && object.__impl4cf1e782hg__;
+ }
+ function isNative(object) {
+ return !isWrapper(object);
+ }
+ function wrap(impl) {
+ if (impl === null) return null;
+ assert(isNative(impl));
+ var wrapper = impl.__wrapper8e3dd93a60__;
+ if (wrapper != null) {
+ return wrapper;
+ }
+ return impl.__wrapper8e3dd93a60__ = new (getWrapperConstructor(impl, impl))(impl);
+ }
+ function unwrap(wrapper) {
+ if (wrapper === null) return null;
+ assert(isWrapper(wrapper));
+ return wrapper.__impl4cf1e782hg__;
+ }
+ function unsafeUnwrap(wrapper) {
+ return wrapper.__impl4cf1e782hg__;
+ }
+ function setWrapper(impl, wrapper) {
+ wrapper.__impl4cf1e782hg__ = impl;
+ impl.__wrapper8e3dd93a60__ = wrapper;
+ }
+ function unwrapIfNeeded(object) {
+ return object && isWrapper(object) ? unwrap(object) : object;
+ }
+ function wrapIfNeeded(object) {
+ return object && !isWrapper(object) ? wrap(object) : object;
+ }
+ function rewrap(node, wrapper) {
+ if (wrapper === null) return;
+ assert(isNative(node));
+ assert(wrapper === undefined || isWrapper(wrapper));
+ node.__wrapper8e3dd93a60__ = wrapper;
+ }
+ var getterDescriptor = {
+ get: undefined,
+ configurable: true,
+ enumerable: true
+ };
+ function defineGetter(constructor, name, getter) {
+ getterDescriptor.get = getter;
+ defineProperty(constructor.prototype, name, getterDescriptor);
+ }
+ function defineWrapGetter(constructor, name) {
+ defineGetter(constructor, name, function() {
+ return wrap(this.__impl4cf1e782hg__[name]);
+ });
+ }
+ function forwardMethodsToWrapper(constructors, names) {
+ constructors.forEach(function(constructor) {
+ names.forEach(function(name) {
+ constructor.prototype[name] = function() {
+ var w = wrapIfNeeded(this);
+ return w[name].apply(w, arguments);
+ };
+ });
+ });
+ }
+ scope.assert = assert;
+ scope.constructorTable = constructorTable;
+ scope.defineGetter = defineGetter;
+ scope.defineWrapGetter = defineWrapGetter;
+ scope.forwardMethodsToWrapper = forwardMethodsToWrapper;
+ scope.isIdentifierName = isIdentifierName;
+ scope.isWrapper = isWrapper;
+ scope.isWrapperFor = isWrapperFor;
+ scope.mixin = mixin;
+ scope.nativePrototypeTable = nativePrototypeTable;
+ scope.oneOf = oneOf;
+ scope.registerObject = registerObject;
+ scope.registerWrapper = register;
+ scope.rewrap = rewrap;
+ scope.setWrapper = setWrapper;
+ scope.unsafeUnwrap = unsafeUnwrap;
+ scope.unwrap = unwrap;
+ scope.unwrapIfNeeded = unwrapIfNeeded;
+ scope.wrap = wrap;
+ scope.wrapIfNeeded = wrapIfNeeded;
+ scope.wrappers = wrappers;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ function newSplice(index, removed, addedCount) {
+ return {
+ index: index,
+ removed: removed,
+ addedCount: addedCount
+ };
+ }
+ var EDIT_LEAVE = 0;
+ var EDIT_UPDATE = 1;
+ var EDIT_ADD = 2;
+ var EDIT_DELETE = 3;
+ function ArraySplice() {}
+ ArraySplice.prototype = {
+ calcEditDistances: function(current, currentStart, currentEnd, old, oldStart, oldEnd) {
+ var rowCount = oldEnd - oldStart + 1;
+ var columnCount = currentEnd - currentStart + 1;
+ var distances = new Array(rowCount);
+ for (var i = 0; i < rowCount; i++) {
+ distances[i] = new Array(columnCount);
+ distances[i][0] = i;
+ }
+ for (var j = 0; j < columnCount; j++) distances[0][j] = j;
+ for (var i = 1; i < rowCount; i++) {
+ for (var j = 1; j < columnCount; j++) {
+ if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1])) distances[i][j] = distances[i - 1][j - 1]; else {
+ var north = distances[i - 1][j] + 1;
+ var west = distances[i][j - 1] + 1;
+ distances[i][j] = north < west ? north : west;
+ }
+ }
+ }
+ return distances;
+ },
+ spliceOperationsFromEditDistances: function(distances) {
+ var i = distances.length - 1;
+ var j = distances[0].length - 1;
+ var current = distances[i][j];
+ var edits = [];
+ while (i > 0 || j > 0) {
+ if (i == 0) {
+ edits.push(EDIT_ADD);
+ j--;
+ continue;
+ }
+ if (j == 0) {
+ edits.push(EDIT_DELETE);
+ i--;
+ continue;
+ }
+ var northWest = distances[i - 1][j - 1];
+ var west = distances[i - 1][j];
+ var north = distances[i][j - 1];
+ var min;
+ if (west < north) min = west < northWest ? west : northWest; else min = north < northWest ? north : northWest;
+ if (min == northWest) {
+ if (northWest == current) {
+ edits.push(EDIT_LEAVE);
+ } else {
+ edits.push(EDIT_UPDATE);
+ current = northWest;
+ }
+ i--;
+ j--;
+ } else if (min == west) {
+ edits.push(EDIT_DELETE);
+ i--;
+ current = west;
+ } else {
+ edits.push(EDIT_ADD);
+ j--;
+ current = north;
+ }
+ }
+ edits.reverse();
+ return edits;
+ },
+ calcSplices: function(current, currentStart, currentEnd, old, oldStart, oldEnd) {
+ var prefixCount = 0;
+ var suffixCount = 0;
+ var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);
+ if (currentStart == 0 && oldStart == 0) prefixCount = this.sharedPrefix(current, old, minLength);
+ if (currentEnd == current.length && oldEnd == old.length) suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);
+ currentStart += prefixCount;
+ oldStart += prefixCount;
+ currentEnd -= suffixCount;
+ oldEnd -= suffixCount;
+ if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0) return [];
+ if (currentStart == currentEnd) {
+ var splice = newSplice(currentStart, [], 0);
+ while (oldStart < oldEnd) splice.removed.push(old[oldStart++]);
+ return [ splice ];
+ } else if (oldStart == oldEnd) return [ newSplice(currentStart, [], currentEnd - currentStart) ];
+ var ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));
+ var splice = undefined;
+ var splices = [];
+ var index = currentStart;
+ var oldIndex = oldStart;
+ for (var i = 0; i < ops.length; i++) {
+ switch (ops[i]) {
+ case EDIT_LEAVE:
+ if (splice) {
+ splices.push(splice);
+ splice = undefined;
+ }
+ index++;
+ oldIndex++;
+ break;
+
+ case EDIT_UPDATE:
+ if (!splice) splice = newSplice(index, [], 0);
+ splice.addedCount++;
+ index++;
+ splice.removed.push(old[oldIndex]);
+ oldIndex++;
+ break;
+
+ case EDIT_ADD:
+ if (!splice) splice = newSplice(index, [], 0);
+ splice.addedCount++;
+ index++;
+ break;
+
+ case EDIT_DELETE:
+ if (!splice) splice = newSplice(index, [], 0);
+ splice.removed.push(old[oldIndex]);
+ oldIndex++;
+ break;
+ }
+ }
+ if (splice) {
+ splices.push(splice);
+ }
+ return splices;
+ },
+ sharedPrefix: function(current, old, searchLength) {
+ for (var i = 0; i < searchLength; i++) if (!this.equals(current[i], old[i])) return i;
+ return searchLength;
+ },
+ sharedSuffix: function(current, old, searchLength) {
+ var index1 = current.length;
+ var index2 = old.length;
+ var count = 0;
+ while (count < searchLength && this.equals(current[--index1], old[--index2])) count++;
+ return count;
+ },
+ calculateSplices: function(current, previous) {
+ return this.calcSplices(current, 0, current.length, previous, 0, previous.length);
+ },
+ equals: function(currentValue, previousValue) {
+ return currentValue === previousValue;
+ }
+ };
+ scope.ArraySplice = ArraySplice;
+})(window.ShadowDOMPolyfill);
+
+(function(context) {
+ "use strict";
+ var OriginalMutationObserver = window.MutationObserver;
+ var callbacks = [];
+ var pending = false;
+ var timerFunc;
+ function handle() {
+ pending = false;
+ var copies = callbacks.slice(0);
+ callbacks = [];
+ for (var i = 0; i < copies.length; i++) {
+ (0, copies[i])();
+ }
+ }
+ if (OriginalMutationObserver) {
+ var counter = 1;
+ var observer = new OriginalMutationObserver(handle);
+ var textNode = document.createTextNode(counter);
+ observer.observe(textNode, {
+ characterData: true
+ });
+ timerFunc = function() {
+ counter = (counter + 1) % 2;
+ textNode.data = counter;
+ };
+ } else {
+ timerFunc = window.setTimeout;
+ }
+ function setEndOfMicrotask(func) {
+ callbacks.push(func);
+ if (pending) return;
+ pending = true;
+ timerFunc(handle, 0);
+ }
+ context.setEndOfMicrotask = setEndOfMicrotask;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var setEndOfMicrotask = scope.setEndOfMicrotask;
+ var wrapIfNeeded = scope.wrapIfNeeded;
+ var wrappers = scope.wrappers;
+ var registrationsTable = new WeakMap();
+ var globalMutationObservers = [];
+ var isScheduled = false;
+ function scheduleCallback(observer) {
+ if (observer.scheduled_) return;
+ observer.scheduled_ = true;
+ globalMutationObservers.push(observer);
+ if (isScheduled) return;
+ setEndOfMicrotask(notifyObservers);
+ isScheduled = true;
+ }
+ function notifyObservers() {
+ isScheduled = false;
+ while (globalMutationObservers.length) {
+ var notifyList = globalMutationObservers;
+ globalMutationObservers = [];
+ notifyList.sort(function(x, y) {
+ return x.uid_ - y.uid_;
+ });
+ for (var i = 0; i < notifyList.length; i++) {
+ var mo = notifyList[i];
+ mo.scheduled_ = false;
+ var queue = mo.takeRecords();
+ removeTransientObserversFor(mo);
+ if (queue.length) {
+ mo.callback_(queue, mo);
+ }
+ }
+ }
+ }
+ function MutationRecord(type, target) {
+ this.type = type;
+ this.target = target;
+ this.addedNodes = new wrappers.NodeList();
+ this.removedNodes = new wrappers.NodeList();
+ this.previousSibling = null;
+ this.nextSibling = null;
+ this.attributeName = null;
+ this.attributeNamespace = null;
+ this.oldValue = null;
+ }
+ function registerTransientObservers(ancestor, node) {
+ for (;ancestor; ancestor = ancestor.parentNode) {
+ var registrations = registrationsTable.get(ancestor);
+ if (!registrations) continue;
+ for (var i = 0; i < registrations.length; i++) {
+ var registration = registrations[i];
+ if (registration.options.subtree) registration.addTransientObserver(node);
+ }
+ }
+ }
+ function removeTransientObserversFor(observer) {
+ for (var i = 0; i < observer.nodes_.length; i++) {
+ var node = observer.nodes_[i];
+ var registrations = registrationsTable.get(node);
+ if (!registrations) return;
+ for (var j = 0; j < registrations.length; j++) {
+ var registration = registrations[j];
+ if (registration.observer === observer) registration.removeTransientObservers();
+ }
+ }
+ }
+ function enqueueMutation(target, type, data) {
+ var interestedObservers = Object.create(null);
+ var associatedStrings = Object.create(null);
+ for (var node = target; node; node = node.parentNode) {
+ var registrations = registrationsTable.get(node);
+ if (!registrations) continue;
+ for (var j = 0; j < registrations.length; j++) {
+ var registration = registrations[j];
+ var options = registration.options;
+ if (node !== target && !options.subtree) continue;
+ if (type === "attributes" && !options.attributes) continue;
+ if (type === "attributes" && options.attributeFilter && (data.namespace !== null || options.attributeFilter.indexOf(data.name) === -1)) {
+ continue;
+ }
+ if (type === "characterData" && !options.characterData) continue;
+ if (type === "childList" && !options.childList) continue;
+ var observer = registration.observer;
+ interestedObservers[observer.uid_] = observer;
+ if (type === "attributes" && options.attributeOldValue || type === "characterData" && options.characterDataOldValue) {
+ associatedStrings[observer.uid_] = data.oldValue;
+ }
+ }
+ }
+ for (var uid in interestedObservers) {
+ var observer = interestedObservers[uid];
+ var record = new MutationRecord(type, target);
+ if ("name" in data && "namespace" in data) {
+ record.attributeName = data.name;
+ record.attributeNamespace = data.namespace;
+ }
+ if (data.addedNodes) record.addedNodes = data.addedNodes;
+ if (data.removedNodes) record.removedNodes = data.removedNodes;
+ if (data.previousSibling) record.previousSibling = data.previousSibling;
+ if (data.nextSibling) record.nextSibling = data.nextSibling;
+ if (associatedStrings[uid] !== undefined) record.oldValue = associatedStrings[uid];
+ scheduleCallback(observer);
+ observer.records_.push(record);
+ }
+ }
+ var slice = Array.prototype.slice;
+ function MutationObserverOptions(options) {
+ this.childList = !!options.childList;
+ this.subtree = !!options.subtree;
+ if (!("attributes" in options) && ("attributeOldValue" in options || "attributeFilter" in options)) {
+ this.attributes = true;
+ } else {
+ this.attributes = !!options.attributes;
+ }
+ if ("characterDataOldValue" in options && !("characterData" in options)) this.characterData = true; else this.characterData = !!options.characterData;
+ if (!this.attributes && (options.attributeOldValue || "attributeFilter" in options) || !this.characterData && options.characterDataOldValue) {
+ throw new TypeError();
+ }
+ this.characterData = !!options.characterData;
+ this.attributeOldValue = !!options.attributeOldValue;
+ this.characterDataOldValue = !!options.characterDataOldValue;
+ if ("attributeFilter" in options) {
+ if (options.attributeFilter == null || typeof options.attributeFilter !== "object") {
+ throw new TypeError();
+ }
+ this.attributeFilter = slice.call(options.attributeFilter);
+ } else {
+ this.attributeFilter = null;
+ }
+ }
+ var uidCounter = 0;
+ function MutationObserver(callback) {
+ this.callback_ = callback;
+ this.nodes_ = [];
+ this.records_ = [];
+ this.uid_ = ++uidCounter;
+ this.scheduled_ = false;
+ }
+ MutationObserver.prototype = {
+ constructor: MutationObserver,
+ observe: function(target, options) {
+ target = wrapIfNeeded(target);
+ var newOptions = new MutationObserverOptions(options);
+ var registration;
+ var registrations = registrationsTable.get(target);
+ if (!registrations) registrationsTable.set(target, registrations = []);
+ for (var i = 0; i < registrations.length; i++) {
+ if (registrations[i].observer === this) {
+ registration = registrations[i];
+ registration.removeTransientObservers();
+ registration.options = newOptions;
+ }
+ }
+ if (!registration) {
+ registration = new Registration(this, target, newOptions);
+ registrations.push(registration);
+ this.nodes_.push(target);
+ }
+ },
+ disconnect: function() {
+ this.nodes_.forEach(function(node) {
+ var registrations = registrationsTable.get(node);
+ for (var i = 0; i < registrations.length; i++) {
+ var registration = registrations[i];
+ if (registration.observer === this) {
+ registrations.splice(i, 1);
+ break;
+ }
+ }
+ }, this);
+ this.records_ = [];
+ },
+ takeRecords: function() {
+ var copyOfRecords = this.records_;
+ this.records_ = [];
+ return copyOfRecords;
+ }
+ };
+ function Registration(observer, target, options) {
+ this.observer = observer;
+ this.target = target;
+ this.options = options;
+ this.transientObservedNodes = [];
+ }
+ Registration.prototype = {
+ addTransientObserver: function(node) {
+ if (node === this.target) return;
+ scheduleCallback(this.observer);
+ this.transientObservedNodes.push(node);
+ var registrations = registrationsTable.get(node);
+ if (!registrations) registrationsTable.set(node, registrations = []);
+ registrations.push(this);
+ },
+ removeTransientObservers: function() {
+ var transientObservedNodes = this.transientObservedNodes;
+ this.transientObservedNodes = [];
+ for (var i = 0; i < transientObservedNodes.length; i++) {
+ var node = transientObservedNodes[i];
+ var registrations = registrationsTable.get(node);
+ for (var j = 0; j < registrations.length; j++) {
+ if (registrations[j] === this) {
+ registrations.splice(j, 1);
+ break;
+ }
+ }
+ }
+ }
+ };
+ scope.enqueueMutation = enqueueMutation;
+ scope.registerTransientObservers = registerTransientObservers;
+ scope.wrappers.MutationObserver = MutationObserver;
+ scope.wrappers.MutationRecord = MutationRecord;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ function TreeScope(root, parent) {
+ this.root = root;
+ this.parent = parent;
+ }
+ TreeScope.prototype = {
+ get renderer() {
+ if (this.root instanceof scope.wrappers.ShadowRoot) {
+ return scope.getRendererForHost(this.root.host);
+ }
+ return null;
+ },
+ contains: function(treeScope) {
+ for (;treeScope; treeScope = treeScope.parent) {
+ if (treeScope === this) return true;
+ }
+ return false;
+ }
+ };
+ function setTreeScope(node, treeScope) {
+ if (node.treeScope_ !== treeScope) {
+ node.treeScope_ = treeScope;
+ for (var sr = node.shadowRoot; sr; sr = sr.olderShadowRoot) {
+ sr.treeScope_.parent = treeScope;
+ }
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ setTreeScope(child, treeScope);
+ }
+ }
+ }
+ function getTreeScope(node) {
+ if (node instanceof scope.wrappers.Window) {
+ debugger;
+ }
+ if (node.treeScope_) return node.treeScope_;
+ var parent = node.parentNode;
+ var treeScope;
+ if (parent) treeScope = getTreeScope(parent); else treeScope = new TreeScope(node, null);
+ return node.treeScope_ = treeScope;
+ }
+ scope.TreeScope = TreeScope;
+ scope.getTreeScope = getTreeScope;
+ scope.setTreeScope = setTreeScope;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
+ var getTreeScope = scope.getTreeScope;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var wrappers = scope.wrappers;
+ var wrappedFuns = new WeakMap();
+ var listenersTable = new WeakMap();
+ var handledEventsTable = new WeakMap();
+ var currentlyDispatchingEvents = new WeakMap();
+ var targetTable = new WeakMap();
+ var currentTargetTable = new WeakMap();
+ var relatedTargetTable = new WeakMap();
+ var eventPhaseTable = new WeakMap();
+ var stopPropagationTable = new WeakMap();
+ var stopImmediatePropagationTable = new WeakMap();
+ var eventHandlersTable = new WeakMap();
+ var eventPathTable = new WeakMap();
+ function isShadowRoot(node) {
+ return node instanceof wrappers.ShadowRoot;
+ }
+ function rootOfNode(node) {
+ return getTreeScope(node).root;
+ }
+ function getEventPath(node, event) {
+ var path = [];
+ var current = node;
+ path.push(current);
+ while (current) {
+ var destinationInsertionPoints = getDestinationInsertionPoints(current);
+ if (destinationInsertionPoints && destinationInsertionPoints.length > 0) {
+ for (var i = 0; i < destinationInsertionPoints.length; i++) {
+ var insertionPoint = destinationInsertionPoints[i];
+ if (isShadowInsertionPoint(insertionPoint)) {
+ var shadowRoot = rootOfNode(insertionPoint);
+ var olderShadowRoot = shadowRoot.olderShadowRoot;
+ if (olderShadowRoot) path.push(olderShadowRoot);
+ }
+ path.push(insertionPoint);
+ }
+ current = destinationInsertionPoints[destinationInsertionPoints.length - 1];
+ } else {
+ if (isShadowRoot(current)) {
+ if (inSameTree(node, current) && eventMustBeStopped(event)) {
+ break;
+ }
+ current = current.host;
+ path.push(current);
+ } else {
+ current = current.parentNode;
+ if (current) path.push(current);
+ }
+ }
+ }
+ return path;
+ }
+ function eventMustBeStopped(event) {
+ if (!event) return false;
+ switch (event.type) {
+ case "abort":
+ case "error":
+ case "select":
+ case "change":
+ case "load":
+ case "reset":
+ case "resize":
+ case "scroll":
+ case "selectstart":
+ return true;
+ }
+ return false;
+ }
+ function isShadowInsertionPoint(node) {
+ return node instanceof HTMLShadowElement;
+ }
+ function getDestinationInsertionPoints(node) {
+ return scope.getDestinationInsertionPoints(node);
+ }
+ function eventRetargetting(path, currentTarget) {
+ if (path.length === 0) return currentTarget;
+ if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
+ var currentTargetTree = getTreeScope(currentTarget);
+ var originalTarget = path[0];
+ var originalTargetTree = getTreeScope(originalTarget);
+ var relativeTargetTree = lowestCommonInclusiveAncestor(currentTargetTree, originalTargetTree);
+ for (var i = 0; i < path.length; i++) {
+ var node = path[i];
+ if (getTreeScope(node) === relativeTargetTree) return node;
+ }
+ return path[path.length - 1];
+ }
+ function getTreeScopeAncestors(treeScope) {
+ var ancestors = [];
+ for (;treeScope; treeScope = treeScope.parent) {
+ ancestors.push(treeScope);
+ }
+ return ancestors;
+ }
+ function lowestCommonInclusiveAncestor(tsA, tsB) {
+ var ancestorsA = getTreeScopeAncestors(tsA);
+ var ancestorsB = getTreeScopeAncestors(tsB);
+ var result = null;
+ while (ancestorsA.length > 0 && ancestorsB.length > 0) {
+ var a = ancestorsA.pop();
+ var b = ancestorsB.pop();
+ if (a === b) result = a; else break;
+ }
+ return result;
+ }
+ function getTreeScopeRoot(ts) {
+ if (!ts.parent) return ts;
+ return getTreeScopeRoot(ts.parent);
+ }
+ function relatedTargetResolution(event, currentTarget, relatedTarget) {
+ if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
+ var currentTargetTree = getTreeScope(currentTarget);
+ var relatedTargetTree = getTreeScope(relatedTarget);
+ var relatedTargetEventPath = getEventPath(relatedTarget, event);
+ var lowestCommonAncestorTree;
+ var lowestCommonAncestorTree = lowestCommonInclusiveAncestor(currentTargetTree, relatedTargetTree);
+ if (!lowestCommonAncestorTree) lowestCommonAncestorTree = relatedTargetTree.root;
+ for (var commonAncestorTree = lowestCommonAncestorTree; commonAncestorTree; commonAncestorTree = commonAncestorTree.parent) {
+ var adjustedRelatedTarget;
+ for (var i = 0; i < relatedTargetEventPath.length; i++) {
+ var node = relatedTargetEventPath[i];
+ if (getTreeScope(node) === commonAncestorTree) return node;
+ }
+ }
+ return null;
+ }
+ function inSameTree(a, b) {
+ return getTreeScope(a) === getTreeScope(b);
+ }
+ var NONE = 0;
+ var CAPTURING_PHASE = 1;
+ var AT_TARGET = 2;
+ var BUBBLING_PHASE = 3;
+ var pendingError;
+ function dispatchOriginalEvent(originalEvent) {
+ if (handledEventsTable.get(originalEvent)) return;
+ handledEventsTable.set(originalEvent, true);
+ dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));
+ if (pendingError) {
+ var err = pendingError;
+ pendingError = null;
+ throw err;
+ }
+ }
+ function isLoadLikeEvent(event) {
+ switch (event.type) {
+ case "load":
+ case "beforeunload":
+ case "unload":
+ return true;
+ }
+ return false;
+ }
+ function dispatchEvent(event, originalWrapperTarget) {
+ if (currentlyDispatchingEvents.get(event)) throw new Error("InvalidStateError");
+ currentlyDispatchingEvents.set(event, true);
+ scope.renderAllPending();
+ var eventPath;
+ var overrideTarget;
+ var win;
+ if (isLoadLikeEvent(event) && !event.bubbles) {
+ var doc = originalWrapperTarget;
+ if (doc instanceof wrappers.Document && (win = doc.defaultView)) {
+ overrideTarget = doc;
+ eventPath = [];
+ }
+ }
+ if (!eventPath) {
+ if (originalWrapperTarget instanceof wrappers.Window) {
+ win = originalWrapperTarget;
+ eventPath = [];
+ } else {
+ eventPath = getEventPath(originalWrapperTarget, event);
+ if (!isLoadLikeEvent(event)) {
+ var doc = eventPath[eventPath.length - 1];
+ if (doc instanceof wrappers.Document) win = doc.defaultView;
+ }
+ }
+ }
+ eventPathTable.set(event, eventPath);
+ if (dispatchCapturing(event, eventPath, win, overrideTarget)) {
+ if (dispatchAtTarget(event, eventPath, win, overrideTarget)) {
+ dispatchBubbling(event, eventPath, win, overrideTarget);
+ }
+ }
+ eventPhaseTable.set(event, NONE);
+ currentTargetTable.delete(event, null);
+ currentlyDispatchingEvents.delete(event);
+ return event.defaultPrevented;
+ }
+ function dispatchCapturing(event, eventPath, win, overrideTarget) {
+ var phase = CAPTURING_PHASE;
+ if (win) {
+ if (!invoke(win, event, phase, eventPath, overrideTarget)) return false;
+ }
+ for (var i = eventPath.length - 1; i > 0; i--) {
+ if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return false;
+ }
+ return true;
+ }
+ function dispatchAtTarget(event, eventPath, win, overrideTarget) {
+ var phase = AT_TARGET;
+ var currentTarget = eventPath[0] || win;
+ return invoke(currentTarget, event, phase, eventPath, overrideTarget);
+ }
+ function dispatchBubbling(event, eventPath, win, overrideTarget) {
+ var phase = BUBBLING_PHASE;
+ for (var i = 1; i < eventPath.length; i++) {
+ if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return;
+ }
+ if (win && eventPath.length > 0) {
+ invoke(win, event, phase, eventPath, overrideTarget);
+ }
+ }
+ function invoke(currentTarget, event, phase, eventPath, overrideTarget) {
+ var listeners = listenersTable.get(currentTarget);
+ if (!listeners) return true;
+ var target = overrideTarget || eventRetargetting(eventPath, currentTarget);
+ if (target === currentTarget) {
+ if (phase === CAPTURING_PHASE) return true;
+ if (phase === BUBBLING_PHASE) phase = AT_TARGET;
+ } else if (phase === BUBBLING_PHASE && !event.bubbles) {
+ return true;
+ }
+ if ("relatedTarget" in event) {
+ var originalEvent = unwrap(event);
+ var unwrappedRelatedTarget = originalEvent.relatedTarget;
+ if (unwrappedRelatedTarget) {
+ if (unwrappedRelatedTarget instanceof Object && unwrappedRelatedTarget.addEventListener) {
+ var relatedTarget = wrap(unwrappedRelatedTarget);
+ var adjusted = relatedTargetResolution(event, currentTarget, relatedTarget);
+ if (adjusted === target) return true;
+ } else {
+ adjusted = null;
+ }
+ relatedTargetTable.set(event, adjusted);
+ }
+ }
+ eventPhaseTable.set(event, phase);
+ var type = event.type;
+ var anyRemoved = false;
+ targetTable.set(event, target);
+ currentTargetTable.set(event, currentTarget);
+ listeners.depth++;
+ for (var i = 0, len = listeners.length; i < len; i++) {
+ var listener = listeners[i];
+ if (listener.removed) {
+ anyRemoved = true;
+ continue;
+ }
+ if (listener.type !== type || !listener.capture && phase === CAPTURING_PHASE || listener.capture && phase === BUBBLING_PHASE) {
+ continue;
+ }
+ try {
+ if (typeof listener.handler === "function") listener.handler.call(currentTarget, event); else listener.handler.handleEvent(event);
+ if (stopImmediatePropagationTable.get(event)) return false;
+ } catch (ex) {
+ if (!pendingError) pendingError = ex;
+ }
+ }
+ listeners.depth--;
+ if (anyRemoved && listeners.depth === 0) {
+ var copy = listeners.slice();
+ listeners.length = 0;
+ for (var i = 0; i < copy.length; i++) {
+ if (!copy[i].removed) listeners.push(copy[i]);
+ }
+ }
+ return !stopPropagationTable.get(event);
+ }
+ function Listener(type, handler, capture) {
+ this.type = type;
+ this.handler = handler;
+ this.capture = Boolean(capture);
+ }
+ Listener.prototype = {
+ equals: function(that) {
+ return this.handler === that.handler && this.type === that.type && this.capture === that.capture;
+ },
+ get removed() {
+ return this.handler === null;
+ },
+ remove: function() {
+ this.handler = null;
+ }
+ };
+ var OriginalEvent = window.Event;
+ OriginalEvent.prototype.polymerBlackList_ = {
+ returnValue: true,
+ keyLocation: true
+ };
+ function Event(type, options) {
+ if (type instanceof OriginalEvent) {
+ var impl = type;
+ if (!OriginalBeforeUnloadEvent && impl.type === "beforeunload" && !(this instanceof BeforeUnloadEvent)) {
+ return new BeforeUnloadEvent(impl);
+ }
+ setWrapper(impl, this);
+ } else {
+ return wrap(constructEvent(OriginalEvent, "Event", type, options));
+ }
+ }
+ Event.prototype = {
+ get target() {
+ return targetTable.get(this);
+ },
+ get currentTarget() {
+ return currentTargetTable.get(this);
+ },
+ get eventPhase() {
+ return eventPhaseTable.get(this);
+ },
+ get path() {
+ var eventPath = eventPathTable.get(this);
+ if (!eventPath) return [];
+ return eventPath.slice();
+ },
+ stopPropagation: function() {
+ stopPropagationTable.set(this, true);
+ },
+ stopImmediatePropagation: function() {
+ stopPropagationTable.set(this, true);
+ stopImmediatePropagationTable.set(this, true);
+ }
+ };
+ registerWrapper(OriginalEvent, Event, document.createEvent("Event"));
+ function unwrapOptions(options) {
+ if (!options || !options.relatedTarget) return options;
+ return Object.create(options, {
+ relatedTarget: {
+ value: unwrap(options.relatedTarget)
+ }
+ });
+ }
+ function registerGenericEvent(name, SuperEvent, prototype) {
+ var OriginalEvent = window[name];
+ var GenericEvent = function(type, options) {
+ if (type instanceof OriginalEvent) setWrapper(type, this); else return wrap(constructEvent(OriginalEvent, name, type, options));
+ };
+ GenericEvent.prototype = Object.create(SuperEvent.prototype);
+ if (prototype) mixin(GenericEvent.prototype, prototype);
+ if (OriginalEvent) {
+ try {
+ registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent("temp"));
+ } catch (ex) {
+ registerWrapper(OriginalEvent, GenericEvent, document.createEvent(name));
+ }
+ }
+ return GenericEvent;
+ }
+ var UIEvent = registerGenericEvent("UIEvent", Event);
+ var CustomEvent = registerGenericEvent("CustomEvent", Event);
+ var relatedTargetProto = {
+ get relatedTarget() {
+ var relatedTarget = relatedTargetTable.get(this);
+ if (relatedTarget !== undefined) return relatedTarget;
+ return wrap(unwrap(this).relatedTarget);
+ }
+ };
+ function getInitFunction(name, relatedTargetIndex) {
+ return function() {
+ arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]);
+ var impl = unwrap(this);
+ impl[name].apply(impl, arguments);
+ };
+ }
+ var mouseEventProto = mixin({
+ initMouseEvent: getInitFunction("initMouseEvent", 14)
+ }, relatedTargetProto);
+ var focusEventProto = mixin({
+ initFocusEvent: getInitFunction("initFocusEvent", 5)
+ }, relatedTargetProto);
+ var MouseEvent = registerGenericEvent("MouseEvent", UIEvent, mouseEventProto);
+ var FocusEvent = registerGenericEvent("FocusEvent", UIEvent, focusEventProto);
+ var defaultInitDicts = Object.create(null);
+ var supportsEventConstructors = function() {
+ try {
+ new window.FocusEvent("focus");
+ } catch (ex) {
+ return false;
+ }
+ return true;
+ }();
+ function constructEvent(OriginalEvent, name, type, options) {
+ if (supportsEventConstructors) return new OriginalEvent(type, unwrapOptions(options));
+ var event = unwrap(document.createEvent(name));
+ var defaultDict = defaultInitDicts[name];
+ var args = [ type ];
+ Object.keys(defaultDict).forEach(function(key) {
+ var v = options != null && key in options ? options[key] : defaultDict[key];
+ if (key === "relatedTarget") v = unwrap(v);
+ args.push(v);
+ });
+ event["init" + name].apply(event, args);
+ return event;
+ }
+ if (!supportsEventConstructors) {
+ var configureEventConstructor = function(name, initDict, superName) {
+ if (superName) {
+ var superDict = defaultInitDicts[superName];
+ initDict = mixin(mixin({}, superDict), initDict);
+ }
+ defaultInitDicts[name] = initDict;
+ };
+ configureEventConstructor("Event", {
+ bubbles: false,
+ cancelable: false
+ });
+ configureEventConstructor("CustomEvent", {
+ detail: null
+ }, "Event");
+ configureEventConstructor("UIEvent", {
+ view: null,
+ detail: 0
+ }, "Event");
+ configureEventConstructor("MouseEvent", {
+ screenX: 0,
+ screenY: 0,
+ clientX: 0,
+ clientY: 0,
+ ctrlKey: false,
+ altKey: false,
+ shiftKey: false,
+ metaKey: false,
+ button: 0,
+ relatedTarget: null
+ }, "UIEvent");
+ configureEventConstructor("FocusEvent", {
+ relatedTarget: null
+ }, "UIEvent");
+ }
+ var OriginalBeforeUnloadEvent = window.BeforeUnloadEvent;
+ function BeforeUnloadEvent(impl) {
+ Event.call(this, impl);
+ }
+ BeforeUnloadEvent.prototype = Object.create(Event.prototype);
+ mixin(BeforeUnloadEvent.prototype, {
+ get returnValue() {
+ return unsafeUnwrap(this).returnValue;
+ },
+ set returnValue(v) {
+ unsafeUnwrap(this).returnValue = v;
+ }
+ });
+ if (OriginalBeforeUnloadEvent) registerWrapper(OriginalBeforeUnloadEvent, BeforeUnloadEvent);
+ function isValidListener(fun) {
+ if (typeof fun === "function") return true;
+ return fun && fun.handleEvent;
+ }
+ function isMutationEvent(type) {
+ switch (type) {
+ case "DOMAttrModified":
+ case "DOMAttributeNameChanged":
+ case "DOMCharacterDataModified":
+ case "DOMElementNameChanged":
+ case "DOMNodeInserted":
+ case "DOMNodeInsertedIntoDocument":
+ case "DOMNodeRemoved":
+ case "DOMNodeRemovedFromDocument":
+ case "DOMSubtreeModified":
+ return true;
+ }
+ return false;
+ }
+ var OriginalEventTarget = window.EventTarget;
+ function EventTarget(impl) {
+ setWrapper(impl, this);
+ }
+ var methodNames = [ "addEventListener", "removeEventListener", "dispatchEvent" ];
+ [ Node, Window ].forEach(function(constructor) {
+ var p = constructor.prototype;
+ methodNames.forEach(function(name) {
+ Object.defineProperty(p, name + "_", {
+ value: p[name]
+ });
+ });
+ });
+ function getTargetToListenAt(wrapper) {
+ if (wrapper instanceof wrappers.ShadowRoot) wrapper = wrapper.host;
+ return unwrap(wrapper);
+ }
+ EventTarget.prototype = {
+ addEventListener: function(type, fun, capture) {
+ if (!isValidListener(fun) || isMutationEvent(type)) return;
+ var listener = new Listener(type, fun, capture);
+ var listeners = listenersTable.get(this);
+ if (!listeners) {
+ listeners = [];
+ listeners.depth = 0;
+ listenersTable.set(this, listeners);
+ } else {
+ for (var i = 0; i < listeners.length; i++) {
+ if (listener.equals(listeners[i])) return;
+ }
+ }
+ listeners.push(listener);
+ var target = getTargetToListenAt(this);
+ target.addEventListener_(type, dispatchOriginalEvent, true);
+ },
+ removeEventListener: function(type, fun, capture) {
+ capture = Boolean(capture);
+ var listeners = listenersTable.get(this);
+ if (!listeners) return;
+ var count = 0, found = false;
+ for (var i = 0; i < listeners.length; i++) {
+ if (listeners[i].type === type && listeners[i].capture === capture) {
+ count++;
+ if (listeners[i].handler === fun) {
+ found = true;
+ listeners[i].remove();
+ }
+ }
+ }
+ if (found && count === 1) {
+ var target = getTargetToListenAt(this);
+ target.removeEventListener_(type, dispatchOriginalEvent, true);
+ }
+ },
+ dispatchEvent: function(event) {
+ var nativeEvent = unwrap(event);
+ var eventType = nativeEvent.type;
+ handledEventsTable.set(nativeEvent, false);
+ scope.renderAllPending();
+ var tempListener;
+ if (!hasListenerInAncestors(this, eventType)) {
+ tempListener = function() {};
+ this.addEventListener(eventType, tempListener, true);
+ }
+ try {
+ return unwrap(this).dispatchEvent_(nativeEvent);
+ } finally {
+ if (tempListener) this.removeEventListener(eventType, tempListener, true);
+ }
+ }
+ };
+ function hasListener(node, type) {
+ var listeners = listenersTable.get(node);
+ if (listeners) {
+ for (var i = 0; i < listeners.length; i++) {
+ if (!listeners[i].removed && listeners[i].type === type) return true;
+ }
+ }
+ return false;
+ }
+ function hasListenerInAncestors(target, type) {
+ for (var node = unwrap(target); node; node = node.parentNode) {
+ if (hasListener(wrap(node), type)) return true;
+ }
+ return false;
+ }
+ if (OriginalEventTarget) registerWrapper(OriginalEventTarget, EventTarget);
+ function wrapEventTargetMethods(constructors) {
+ forwardMethodsToWrapper(constructors, methodNames);
+ }
+ var originalElementFromPoint = document.elementFromPoint;
+ function elementFromPoint(self, document, x, y) {
+ scope.renderAllPending();
+ var element = wrap(originalElementFromPoint.call(unsafeUnwrap(document), x, y));
+ if (!element) return null;
+ var path = getEventPath(element, null);
+ var idx = path.lastIndexOf(self);
+ if (idx == -1) return null; else path = path.slice(0, idx);
+ return eventRetargetting(path, self);
+ }
+ function getEventHandlerGetter(name) {
+ return function() {
+ var inlineEventHandlers = eventHandlersTable.get(this);
+ return inlineEventHandlers && inlineEventHandlers[name] && inlineEventHandlers[name].value || null;
+ };
+ }
+ function getEventHandlerSetter(name) {
+ var eventType = name.slice(2);
+ return function(value) {
+ var inlineEventHandlers = eventHandlersTable.get(this);
+ if (!inlineEventHandlers) {
+ inlineEventHandlers = Object.create(null);
+ eventHandlersTable.set(this, inlineEventHandlers);
+ }
+ var old = inlineEventHandlers[name];
+ if (old) this.removeEventListener(eventType, old.wrapped, false);
+ if (typeof value === "function") {
+ var wrapped = function(e) {
+ var rv = value.call(this, e);
+ if (rv === false) e.preventDefault(); else if (name === "onbeforeunload" && typeof rv === "string") e.returnValue = rv;
+ };
+ this.addEventListener(eventType, wrapped, false);
+ inlineEventHandlers[name] = {
+ value: value,
+ wrapped: wrapped
+ };
+ }
+ };
+ }
+ scope.elementFromPoint = elementFromPoint;
+ scope.getEventHandlerGetter = getEventHandlerGetter;
+ scope.getEventHandlerSetter = getEventHandlerSetter;
+ scope.wrapEventTargetMethods = wrapEventTargetMethods;
+ scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;
+ scope.wrappers.CustomEvent = CustomEvent;
+ scope.wrappers.Event = Event;
+ scope.wrappers.EventTarget = EventTarget;
+ scope.wrappers.FocusEvent = FocusEvent;
+ scope.wrappers.MouseEvent = MouseEvent;
+ scope.wrappers.UIEvent = UIEvent;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var UIEvent = scope.wrappers.UIEvent;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var wrap = scope.wrap;
+ var OriginalTouchEvent = window.TouchEvent;
+ if (!OriginalTouchEvent) return;
+ var nativeEvent;
+ try {
+ nativeEvent = document.createEvent("TouchEvent");
+ } catch (ex) {
+ return;
+ }
+ var nonEnumDescriptor = {
+ enumerable: false
+ };
+ function nonEnum(obj, prop) {
+ Object.defineProperty(obj, prop, nonEnumDescriptor);
+ }
+ function Touch(impl) {
+ setWrapper(impl, this);
+ }
+ Touch.prototype = {
+ get target() {
+ return wrap(unsafeUnwrap(this).target);
+ }
+ };
+ var descr = {
+ configurable: true,
+ enumerable: true,
+ get: null
+ };
+ [ "clientX", "clientY", "screenX", "screenY", "pageX", "pageY", "identifier", "webkitRadiusX", "webkitRadiusY", "webkitRotationAngle", "webkitForce" ].forEach(function(name) {
+ descr.get = function() {
+ return unsafeUnwrap(this)[name];
+ };
+ Object.defineProperty(Touch.prototype, name, descr);
+ });
+ function TouchList() {
+ this.length = 0;
+ nonEnum(this, "length");
+ }
+ TouchList.prototype = {
+ item: function(index) {
+ return this[index];
+ }
+ };
+ function wrapTouchList(nativeTouchList) {
+ var list = new TouchList();
+ for (var i = 0; i < nativeTouchList.length; i++) {
+ list[i] = new Touch(nativeTouchList[i]);
+ }
+ list.length = i;
+ return list;
+ }
+ function TouchEvent(impl) {
+ UIEvent.call(this, impl);
+ }
+ TouchEvent.prototype = Object.create(UIEvent.prototype);
+ mixin(TouchEvent.prototype, {
+ get touches() {
+ return wrapTouchList(unsafeUnwrap(this).touches);
+ },
+ get targetTouches() {
+ return wrapTouchList(unsafeUnwrap(this).targetTouches);
+ },
+ get changedTouches() {
+ return wrapTouchList(unsafeUnwrap(this).changedTouches);
+ },
+ initTouchEvent: function() {
+ throw new Error("Not implemented");
+ }
+ });
+ registerWrapper(OriginalTouchEvent, TouchEvent, nativeEvent);
+ scope.wrappers.Touch = Touch;
+ scope.wrappers.TouchEvent = TouchEvent;
+ scope.wrappers.TouchList = TouchList;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var wrap = scope.wrap;
+ var nonEnumDescriptor = {
+ enumerable: false
+ };
+ function nonEnum(obj, prop) {
+ Object.defineProperty(obj, prop, nonEnumDescriptor);
+ }
+ function NodeList() {
+ this.length = 0;
+ nonEnum(this, "length");
+ }
+ NodeList.prototype = {
+ item: function(index) {
+ return this[index];
+ }
+ };
+ nonEnum(NodeList.prototype, "item");
+ function wrapNodeList(list) {
+ if (list == null) return list;
+ var wrapperList = new NodeList();
+ for (var i = 0, length = list.length; i < length; i++) {
+ wrapperList[i] = wrap(list[i]);
+ }
+ wrapperList.length = length;
+ return wrapperList;
+ }
+ function addWrapNodeListMethod(wrapperConstructor, name) {
+ wrapperConstructor.prototype[name] = function() {
+ return wrapNodeList(unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));
+ };
+ }
+ scope.wrappers.NodeList = NodeList;
+ scope.addWrapNodeListMethod = addWrapNodeListMethod;
+ scope.wrapNodeList = wrapNodeList;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ scope.wrapHTMLCollection = scope.wrapNodeList;
+ scope.wrappers.HTMLCollection = scope.wrappers.NodeList;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var EventTarget = scope.wrappers.EventTarget;
+ var NodeList = scope.wrappers.NodeList;
+ var TreeScope = scope.TreeScope;
+ var assert = scope.assert;
+ var defineWrapGetter = scope.defineWrapGetter;
+ var enqueueMutation = scope.enqueueMutation;
+ var getTreeScope = scope.getTreeScope;
+ var isWrapper = scope.isWrapper;
+ var mixin = scope.mixin;
+ var registerTransientObservers = scope.registerTransientObservers;
+ var registerWrapper = scope.registerWrapper;
+ var setTreeScope = scope.setTreeScope;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var wrap = scope.wrap;
+ var wrapIfNeeded = scope.wrapIfNeeded;
+ var wrappers = scope.wrappers;
+ function assertIsNodeWrapper(node) {
+ assert(node instanceof Node);
+ }
+ function createOneElementNodeList(node) {
+ var nodes = new NodeList();
+ nodes[0] = node;
+ nodes.length = 1;
+ return nodes;
+ }
+ var surpressMutations = false;
+ function enqueueRemovalForInsertedNodes(node, parent, nodes) {
+ enqueueMutation(parent, "childList", {
+ removedNodes: nodes,
+ previousSibling: node.previousSibling,
+ nextSibling: node.nextSibling
+ });
+ }
+ function enqueueRemovalForInsertedDocumentFragment(df, nodes) {
+ enqueueMutation(df, "childList", {
+ removedNodes: nodes
+ });
+ }
+ function collectNodes(node, parentNode, previousNode, nextNode) {
+ if (node instanceof DocumentFragment) {
+ var nodes = collectNodesForDocumentFragment(node);
+ surpressMutations = true;
+ for (var i = nodes.length - 1; i >= 0; i--) {
+ node.removeChild(nodes[i]);
+ nodes[i].parentNode_ = parentNode;
+ }
+ surpressMutations = false;
+ for (var i = 0; i < nodes.length; i++) {
+ nodes[i].previousSibling_ = nodes[i - 1] || previousNode;
+ nodes[i].nextSibling_ = nodes[i + 1] || nextNode;
+ }
+ if (previousNode) previousNode.nextSibling_ = nodes[0];
+ if (nextNode) nextNode.previousSibling_ = nodes[nodes.length - 1];
+ return nodes;
+ }
+ var nodes = createOneElementNodeList(node);
+ var oldParent = node.parentNode;
+ if (oldParent) {
+ oldParent.removeChild(node);
+ }
+ node.parentNode_ = parentNode;
+ node.previousSibling_ = previousNode;
+ node.nextSibling_ = nextNode;
+ if (previousNode) previousNode.nextSibling_ = node;
+ if (nextNode) nextNode.previousSibling_ = node;
+ return nodes;
+ }
+ function collectNodesNative(node) {
+ if (node instanceof DocumentFragment) return collectNodesForDocumentFragment(node);
+ var nodes = createOneElementNodeList(node);
+ var oldParent = node.parentNode;
+ if (oldParent) enqueueRemovalForInsertedNodes(node, oldParent, nodes);
+ return nodes;
+ }
+ function collectNodesForDocumentFragment(node) {
+ var nodes = new NodeList();
+ var i = 0;
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ nodes[i++] = child;
+ }
+ nodes.length = i;
+ enqueueRemovalForInsertedDocumentFragment(node, nodes);
+ return nodes;
+ }
+ function snapshotNodeList(nodeList) {
+ return nodeList;
+ }
+ function nodeWasAdded(node, treeScope) {
+ setTreeScope(node, treeScope);
+ node.nodeIsInserted_();
+ }
+ function nodesWereAdded(nodes, parent) {
+ var treeScope = getTreeScope(parent);
+ for (var i = 0; i < nodes.length; i++) {
+ nodeWasAdded(nodes[i], treeScope);
+ }
+ }
+ function nodeWasRemoved(node) {
+ setTreeScope(node, new TreeScope(node, null));
+ }
+ function nodesWereRemoved(nodes) {
+ for (var i = 0; i < nodes.length; i++) {
+ nodeWasRemoved(nodes[i]);
+ }
+ }
+ function ensureSameOwnerDocument(parent, child) {
+ var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ? parent : parent.ownerDocument;
+ if (ownerDoc !== child.ownerDocument) ownerDoc.adoptNode(child);
+ }
+ function adoptNodesIfNeeded(owner, nodes) {
+ if (!nodes.length) return;
+ var ownerDoc = owner.ownerDocument;
+ if (ownerDoc === nodes[0].ownerDocument) return;
+ for (var i = 0; i < nodes.length; i++) {
+ scope.adoptNodeNoRemove(nodes[i], ownerDoc);
+ }
+ }
+ function unwrapNodesForInsertion(owner, nodes) {
+ adoptNodesIfNeeded(owner, nodes);
+ var length = nodes.length;
+ if (length === 1) return unwrap(nodes[0]);
+ var df = unwrap(owner.ownerDocument.createDocumentFragment());
+ for (var i = 0; i < length; i++) {
+ df.appendChild(unwrap(nodes[i]));
+ }
+ return df;
+ }
+ function clearChildNodes(wrapper) {
+ if (wrapper.firstChild_ !== undefined) {
+ var child = wrapper.firstChild_;
+ while (child) {
+ var tmp = child;
+ child = child.nextSibling_;
+ tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;
+ }
+ }
+ wrapper.firstChild_ = wrapper.lastChild_ = undefined;
+ }
+ function removeAllChildNodes(wrapper) {
+ if (wrapper.invalidateShadowRenderer()) {
+ var childWrapper = wrapper.firstChild;
+ while (childWrapper) {
+ assert(childWrapper.parentNode === wrapper);
+ var nextSibling = childWrapper.nextSibling;
+ var childNode = unwrap(childWrapper);
+ var parentNode = childNode.parentNode;
+ if (parentNode) originalRemoveChild.call(parentNode, childNode);
+ childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = null;
+ childWrapper = nextSibling;
+ }
+ wrapper.firstChild_ = wrapper.lastChild_ = null;
+ } else {
+ var node = unwrap(wrapper);
+ var child = node.firstChild;
+ var nextSibling;
+ while (child) {
+ nextSibling = child.nextSibling;
+ originalRemoveChild.call(node, child);
+ child = nextSibling;
+ }
+ }
+ }
+ function invalidateParent(node) {
+ var p = node.parentNode;
+ return p && p.invalidateShadowRenderer();
+ }
+ function cleanupNodes(nodes) {
+ for (var i = 0, n; i < nodes.length; i++) {
+ n = nodes[i];
+ n.parentNode.removeChild(n);
+ }
+ }
+ var originalImportNode = document.importNode;
+ var originalCloneNode = window.Node.prototype.cloneNode;
+ function cloneNode(node, deep, opt_doc) {
+ var clone;
+ if (opt_doc) clone = wrap(originalImportNode.call(opt_doc, unsafeUnwrap(node), false)); else clone = wrap(originalCloneNode.call(unsafeUnwrap(node), false));
+ if (deep) {
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ clone.appendChild(cloneNode(child, true, opt_doc));
+ }
+ if (node instanceof wrappers.HTMLTemplateElement) {
+ var cloneContent = clone.content;
+ for (var child = node.content.firstChild; child; child = child.nextSibling) {
+ cloneContent.appendChild(cloneNode(child, true, opt_doc));
+ }
+ }
+ }
+ return clone;
+ }
+ function contains(self, child) {
+ if (!child || getTreeScope(self) !== getTreeScope(child)) return false;
+ for (var node = child; node; node = node.parentNode) {
+ if (node === self) return true;
+ }
+ return false;
+ }
+ var OriginalNode = window.Node;
+ function Node(original) {
+ assert(original instanceof OriginalNode);
+ EventTarget.call(this, original);
+ this.parentNode_ = undefined;
+ this.firstChild_ = undefined;
+ this.lastChild_ = undefined;
+ this.nextSibling_ = undefined;
+ this.previousSibling_ = undefined;
+ this.treeScope_ = undefined;
+ }
+ var OriginalDocumentFragment = window.DocumentFragment;
+ var originalAppendChild = OriginalNode.prototype.appendChild;
+ var originalCompareDocumentPosition = OriginalNode.prototype.compareDocumentPosition;
+ var originalIsEqualNode = OriginalNode.prototype.isEqualNode;
+ var originalInsertBefore = OriginalNode.prototype.insertBefore;
+ var originalRemoveChild = OriginalNode.prototype.removeChild;
+ var originalReplaceChild = OriginalNode.prototype.replaceChild;
+ var isIe = /Trident|Edge/.test(navigator.userAgent);
+ var removeChildOriginalHelper = isIe ? function(parent, child) {
+ try {
+ originalRemoveChild.call(parent, child);
+ } catch (ex) {
+ if (!(parent instanceof OriginalDocumentFragment)) throw ex;
+ }
+ } : function(parent, child) {
+ originalRemoveChild.call(parent, child);
+ };
+ Node.prototype = Object.create(EventTarget.prototype);
+ mixin(Node.prototype, {
+ appendChild: function(childWrapper) {
+ return this.insertBefore(childWrapper, null);
+ },
+ insertBefore: function(childWrapper, refWrapper) {
+ assertIsNodeWrapper(childWrapper);
+ var refNode;
+ if (refWrapper) {
+ if (isWrapper(refWrapper)) {
+ refNode = unwrap(refWrapper);
+ } else {
+ refNode = refWrapper;
+ refWrapper = wrap(refNode);
+ }
+ } else {
+ refWrapper = null;
+ refNode = null;
+ }
+ refWrapper && assert(refWrapper.parentNode === this);
+ var nodes;
+ var previousNode = refWrapper ? refWrapper.previousSibling : this.lastChild;
+ var useNative = !this.invalidateShadowRenderer() && !invalidateParent(childWrapper);
+ if (useNative) nodes = collectNodesNative(childWrapper); else nodes = collectNodes(childWrapper, this, previousNode, refWrapper);
+ if (useNative) {
+ ensureSameOwnerDocument(this, childWrapper);
+ clearChildNodes(this);
+ originalInsertBefore.call(unsafeUnwrap(this), unwrap(childWrapper), refNode);
+ } else {
+ if (!previousNode) this.firstChild_ = nodes[0];
+ if (!refWrapper) {
+ this.lastChild_ = nodes[nodes.length - 1];
+ if (this.firstChild_ === undefined) this.firstChild_ = this.firstChild;
+ }
+ var parentNode = refNode ? refNode.parentNode : unsafeUnwrap(this);
+ if (parentNode) {
+ originalInsertBefore.call(parentNode, unwrapNodesForInsertion(this, nodes), refNode);
+ } else {
+ adoptNodesIfNeeded(this, nodes);
+ }
+ }
+ enqueueMutation(this, "childList", {
+ addedNodes: nodes,
+ nextSibling: refWrapper,
+ previousSibling: previousNode
+ });
+ nodesWereAdded(nodes, this);
+ return childWrapper;
+ },
+ removeChild: function(childWrapper) {
+ assertIsNodeWrapper(childWrapper);
+ if (childWrapper.parentNode !== this) {
+ var found = false;
+ var childNodes = this.childNodes;
+ for (var ieChild = this.firstChild; ieChild; ieChild = ieChild.nextSibling) {
+ if (ieChild === childWrapper) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ throw new Error("NotFoundError");
+ }
+ }
+ var childNode = unwrap(childWrapper);
+ var childWrapperNextSibling = childWrapper.nextSibling;
+ var childWrapperPreviousSibling = childWrapper.previousSibling;
+ if (this.invalidateShadowRenderer()) {
+ var thisFirstChild = this.firstChild;
+ var thisLastChild = this.lastChild;
+ var parentNode = childNode.parentNode;
+ if (parentNode) removeChildOriginalHelper(parentNode, childNode);
+ if (thisFirstChild === childWrapper) this.firstChild_ = childWrapperNextSibling;
+ if (thisLastChild === childWrapper) this.lastChild_ = childWrapperPreviousSibling;
+ if (childWrapperPreviousSibling) childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;
+ if (childWrapperNextSibling) {
+ childWrapperNextSibling.previousSibling_ = childWrapperPreviousSibling;
+ }
+ childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = undefined;
+ } else {
+ clearChildNodes(this);
+ removeChildOriginalHelper(unsafeUnwrap(this), childNode);
+ }
+ if (!surpressMutations) {
+ enqueueMutation(this, "childList", {
+ removedNodes: createOneElementNodeList(childWrapper),
+ nextSibling: childWrapperNextSibling,
+ previousSibling: childWrapperPreviousSibling
+ });
+ }
+ registerTransientObservers(this, childWrapper);
+ return childWrapper;
+ },
+ replaceChild: function(newChildWrapper, oldChildWrapper) {
+ assertIsNodeWrapper(newChildWrapper);
+ var oldChildNode;
+ if (isWrapper(oldChildWrapper)) {
+ oldChildNode = unwrap(oldChildWrapper);
+ } else {
+ oldChildNode = oldChildWrapper;
+ oldChildWrapper = wrap(oldChildNode);
+ }
+ if (oldChildWrapper.parentNode !== this) {
+ throw new Error("NotFoundError");
+ }
+ var nextNode = oldChildWrapper.nextSibling;
+ var previousNode = oldChildWrapper.previousSibling;
+ var nodes;
+ var useNative = !this.invalidateShadowRenderer() && !invalidateParent(newChildWrapper);
+ if (useNative) {
+ nodes = collectNodesNative(newChildWrapper);
+ } else {
+ if (nextNode === newChildWrapper) nextNode = newChildWrapper.nextSibling;
+ nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);
+ }
+ if (!useNative) {
+ if (this.firstChild === oldChildWrapper) this.firstChild_ = nodes[0];
+ if (this.lastChild === oldChildWrapper) this.lastChild_ = nodes[nodes.length - 1];
+ oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ = oldChildWrapper.parentNode_ = undefined;
+ if (oldChildNode.parentNode) {
+ originalReplaceChild.call(oldChildNode.parentNode, unwrapNodesForInsertion(this, nodes), oldChildNode);
+ }
+ } else {
+ ensureSameOwnerDocument(this, newChildWrapper);
+ clearChildNodes(this);
+ originalReplaceChild.call(unsafeUnwrap(this), unwrap(newChildWrapper), oldChildNode);
+ }
+ enqueueMutation(this, "childList", {
+ addedNodes: nodes,
+ removedNodes: createOneElementNodeList(oldChildWrapper),
+ nextSibling: nextNode,
+ previousSibling: previousNode
+ });
+ nodeWasRemoved(oldChildWrapper);
+ nodesWereAdded(nodes, this);
+ return oldChildWrapper;
+ },
+ nodeIsInserted_: function() {
+ for (var child = this.firstChild; child; child = child.nextSibling) {
+ child.nodeIsInserted_();
+ }
+ },
+ hasChildNodes: function() {
+ return this.firstChild !== null;
+ },
+ get parentNode() {
+ return this.parentNode_ !== undefined ? this.parentNode_ : wrap(unsafeUnwrap(this).parentNode);
+ },
+ get firstChild() {
+ return this.firstChild_ !== undefined ? this.firstChild_ : wrap(unsafeUnwrap(this).firstChild);
+ },
+ get lastChild() {
+ return this.lastChild_ !== undefined ? this.lastChild_ : wrap(unsafeUnwrap(this).lastChild);
+ },
+ get nextSibling() {
+ return this.nextSibling_ !== undefined ? this.nextSibling_ : wrap(unsafeUnwrap(this).nextSibling);
+ },
+ get previousSibling() {
+ return this.previousSibling_ !== undefined ? this.previousSibling_ : wrap(unsafeUnwrap(this).previousSibling);
+ },
+ get parentElement() {
+ var p = this.parentNode;
+ while (p && p.nodeType !== Node.ELEMENT_NODE) {
+ p = p.parentNode;
+ }
+ return p;
+ },
+ get textContent() {
+ var s = "";
+ for (var child = this.firstChild; child; child = child.nextSibling) {
+ if (child.nodeType != Node.COMMENT_NODE) {
+ s += child.textContent;
+ }
+ }
+ return s;
+ },
+ set textContent(textContent) {
+ if (textContent == null) textContent = "";
+ var removedNodes = snapshotNodeList(this.childNodes);
+ if (this.invalidateShadowRenderer()) {
+ removeAllChildNodes(this);
+ if (textContent !== "") {
+ var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textContent);
+ this.appendChild(textNode);
+ }
+ } else {
+ clearChildNodes(this);
+ unsafeUnwrap(this).textContent = textContent;
+ }
+ var addedNodes = snapshotNodeList(this.childNodes);
+ enqueueMutation(this, "childList", {
+ addedNodes: addedNodes,
+ removedNodes: removedNodes
+ });
+ nodesWereRemoved(removedNodes);
+ nodesWereAdded(addedNodes, this);
+ },
+ get childNodes() {
+ var wrapperList = new NodeList();
+ var i = 0;
+ for (var child = this.firstChild; child; child = child.nextSibling) {
+ wrapperList[i++] = child;
+ }
+ wrapperList.length = i;
+ return wrapperList;
+ },
+ cloneNode: function(deep) {
+ return cloneNode(this, deep);
+ },
+ contains: function(child) {
+ return contains(this, wrapIfNeeded(child));
+ },
+ compareDocumentPosition: function(otherNode) {
+ return originalCompareDocumentPosition.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));
+ },
+ isEqualNode: function(otherNode) {
+ return originalIsEqualNode.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));
+ },
+ normalize: function() {
+ var nodes = snapshotNodeList(this.childNodes);
+ var remNodes = [];
+ var s = "";
+ var modNode;
+ for (var i = 0, n; i < nodes.length; i++) {
+ n = nodes[i];
+ if (n.nodeType === Node.TEXT_NODE) {
+ if (!modNode && !n.data.length) this.removeChild(n); else if (!modNode) modNode = n; else {
+ s += n.data;
+ remNodes.push(n);
+ }
+ } else {
+ if (modNode && remNodes.length) {
+ modNode.data += s;
+ cleanupNodes(remNodes);
+ }
+ remNodes = [];
+ s = "";
+ modNode = null;
+ if (n.childNodes.length) n.normalize();
+ }
+ }
+ if (modNode && remNodes.length) {
+ modNode.data += s;
+ cleanupNodes(remNodes);
+ }
+ }
+ });
+ defineWrapGetter(Node, "ownerDocument");
+ registerWrapper(OriginalNode, Node, document.createDocumentFragment());
+ delete Node.prototype.querySelector;
+ delete Node.prototype.querySelectorAll;
+ Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);
+ scope.cloneNode = cloneNode;
+ scope.nodeWasAdded = nodeWasAdded;
+ scope.nodeWasRemoved = nodeWasRemoved;
+ scope.nodesWereAdded = nodesWereAdded;
+ scope.nodesWereRemoved = nodesWereRemoved;
+ scope.originalInsertBefore = originalInsertBefore;
+ scope.originalRemoveChild = originalRemoveChild;
+ scope.snapshotNodeList = snapshotNodeList;
+ scope.wrappers.Node = Node;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLCollection = scope.wrappers.HTMLCollection;
+ var NodeList = scope.wrappers.NodeList;
+ var getTreeScope = scope.getTreeScope;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var wrap = scope.wrap;
+ var originalDocumentQuerySelector = document.querySelector;
+ var originalElementQuerySelector = document.documentElement.querySelector;
+ var originalDocumentQuerySelectorAll = document.querySelectorAll;
+ var originalElementQuerySelectorAll = document.documentElement.querySelectorAll;
+ var originalDocumentGetElementsByTagName = document.getElementsByTagName;
+ var originalElementGetElementsByTagName = document.documentElement.getElementsByTagName;
+ var originalDocumentGetElementsByTagNameNS = document.getElementsByTagNameNS;
+ var originalElementGetElementsByTagNameNS = document.documentElement.getElementsByTagNameNS;
+ var OriginalElement = window.Element;
+ var OriginalDocument = window.HTMLDocument || window.Document;
+ function filterNodeList(list, index, result, deep) {
+ var wrappedItem = null;
+ var root = null;
+ for (var i = 0, length = list.length; i < length; i++) {
+ wrappedItem = wrap(list[i]);
+ if (!deep && (root = getTreeScope(wrappedItem).root)) {
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ continue;
+ }
+ }
+ result[index++] = wrappedItem;
+ }
+ return index;
+ }
+ function shimSelector(selector) {
+ return String(selector).replace(/\/deep\/|::shadow|>>>/g, " ");
+ }
+ function shimMatchesSelector(selector) {
+ return String(selector).replace(/:host\(([^\s]+)\)/g, "$1").replace(/([^\s]):host/g, "$1").replace(":host", "*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content|>>>/g, " ");
+ }
+ function findOne(node, selector) {
+ var m, el = node.firstElementChild;
+ while (el) {
+ if (el.matches(selector)) return el;
+ m = findOne(el, selector);
+ if (m) return m;
+ el = el.nextElementSibling;
+ }
+ return null;
+ }
+ function matchesSelector(el, selector) {
+ return el.matches(selector);
+ }
+ var XHTML_NS = "http://www.w3.org/1999/xhtml";
+ function matchesTagName(el, localName, localNameLowerCase) {
+ var ln = el.localName;
+ return ln === localName || ln === localNameLowerCase && el.namespaceURI === XHTML_NS;
+ }
+ function matchesEveryThing() {
+ return true;
+ }
+ function matchesLocalNameOnly(el, ns, localName) {
+ return el.localName === localName;
+ }
+ function matchesNameSpace(el, ns) {
+ return el.namespaceURI === ns;
+ }
+ function matchesLocalNameNS(el, ns, localName) {
+ return el.namespaceURI === ns && el.localName === localName;
+ }
+ function findElements(node, index, result, p, arg0, arg1) {
+ var el = node.firstElementChild;
+ while (el) {
+ if (p(el, arg0, arg1)) result[index++] = el;
+ index = findElements(el, index, result, p, arg0, arg1);
+ el = el.nextElementSibling;
+ }
+ return index;
+ }
+ function querySelectorAllFiltered(p, index, result, selector, deep) {
+ var target = unsafeUnwrap(this);
+ var list;
+ var root = getTreeScope(this).root;
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ return findElements(this, index, result, p, selector, null);
+ } else if (target instanceof OriginalElement) {
+ list = originalElementQuerySelectorAll.call(target, selector);
+ } else if (target instanceof OriginalDocument) {
+ list = originalDocumentQuerySelectorAll.call(target, selector);
+ } else {
+ return findElements(this, index, result, p, selector, null);
+ }
+ return filterNodeList(list, index, result, deep);
+ }
+ var SelectorsInterface = {
+ querySelector: function(selector) {
+ var shimmed = shimSelector(selector);
+ var deep = shimmed !== selector;
+ selector = shimmed;
+ var target = unsafeUnwrap(this);
+ var wrappedItem;
+ var root = getTreeScope(this).root;
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ return findOne(this, selector);
+ } else if (target instanceof OriginalElement) {
+ wrappedItem = wrap(originalElementQuerySelector.call(target, selector));
+ } else if (target instanceof OriginalDocument) {
+ wrappedItem = wrap(originalDocumentQuerySelector.call(target, selector));
+ } else {
+ return findOne(this, selector);
+ }
+ if (!wrappedItem) {
+ return wrappedItem;
+ } else if (!deep && (root = getTreeScope(wrappedItem).root)) {
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ return findOne(this, selector);
+ }
+ }
+ return wrappedItem;
+ },
+ querySelectorAll: function(selector) {
+ var shimmed = shimSelector(selector);
+ var deep = shimmed !== selector;
+ selector = shimmed;
+ var result = new NodeList();
+ result.length = querySelectorAllFiltered.call(this, matchesSelector, 0, result, selector, deep);
+ return result;
+ }
+ };
+ var MatchesInterface = {
+ matches: function(selector) {
+ selector = shimMatchesSelector(selector);
+ return scope.originalMatches.call(unsafeUnwrap(this), selector);
+ }
+ };
+ function getElementsByTagNameFiltered(p, index, result, localName, lowercase) {
+ var target = unsafeUnwrap(this);
+ var list;
+ var root = getTreeScope(this).root;
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ return findElements(this, index, result, p, localName, lowercase);
+ } else if (target instanceof OriginalElement) {
+ list = originalElementGetElementsByTagName.call(target, localName, lowercase);
+ } else if (target instanceof OriginalDocument) {
+ list = originalDocumentGetElementsByTagName.call(target, localName, lowercase);
+ } else {
+ return findElements(this, index, result, p, localName, lowercase);
+ }
+ return filterNodeList(list, index, result, false);
+ }
+ function getElementsByTagNameNSFiltered(p, index, result, ns, localName) {
+ var target = unsafeUnwrap(this);
+ var list;
+ var root = getTreeScope(this).root;
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ return findElements(this, index, result, p, ns, localName);
+ } else if (target instanceof OriginalElement) {
+ list = originalElementGetElementsByTagNameNS.call(target, ns, localName);
+ } else if (target instanceof OriginalDocument) {
+ list = originalDocumentGetElementsByTagNameNS.call(target, ns, localName);
+ } else {
+ return findElements(this, index, result, p, ns, localName);
+ }
+ return filterNodeList(list, index, result, false);
+ }
+ var GetElementsByInterface = {
+ getElementsByTagName: function(localName) {
+ var result = new HTMLCollection();
+ var match = localName === "*" ? matchesEveryThing : matchesTagName;
+ result.length = getElementsByTagNameFiltered.call(this, match, 0, result, localName, localName.toLowerCase());
+ return result;
+ },
+ getElementsByClassName: function(className) {
+ return this.querySelectorAll("." + className);
+ },
+ getElementsByTagNameNS: function(ns, localName) {
+ var result = new HTMLCollection();
+ var match = null;
+ if (ns === "*") {
+ match = localName === "*" ? matchesEveryThing : matchesLocalNameOnly;
+ } else {
+ match = localName === "*" ? matchesNameSpace : matchesLocalNameNS;
+ }
+ result.length = getElementsByTagNameNSFiltered.call(this, match, 0, result, ns || null, localName);
+ return result;
+ }
+ };
+ scope.GetElementsByInterface = GetElementsByInterface;
+ scope.SelectorsInterface = SelectorsInterface;
+ scope.MatchesInterface = MatchesInterface;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var NodeList = scope.wrappers.NodeList;
+ function forwardElement(node) {
+ while (node && node.nodeType !== Node.ELEMENT_NODE) {
+ node = node.nextSibling;
+ }
+ return node;
+ }
+ function backwardsElement(node) {
+ while (node && node.nodeType !== Node.ELEMENT_NODE) {
+ node = node.previousSibling;
+ }
+ return node;
+ }
+ var ParentNodeInterface = {
+ get firstElementChild() {
+ return forwardElement(this.firstChild);
+ },
+ get lastElementChild() {
+ return backwardsElement(this.lastChild);
+ },
+ get childElementCount() {
+ var count = 0;
+ for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
+ count++;
+ }
+ return count;
+ },
+ get children() {
+ var wrapperList = new NodeList();
+ var i = 0;
+ for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
+ wrapperList[i++] = child;
+ }
+ wrapperList.length = i;
+ return wrapperList;
+ },
+ remove: function() {
+ var p = this.parentNode;
+ if (p) p.removeChild(this);
+ }
+ };
+ var ChildNodeInterface = {
+ get nextElementSibling() {
+ return forwardElement(this.nextSibling);
+ },
+ get previousElementSibling() {
+ return backwardsElement(this.previousSibling);
+ }
+ };
+ var NonElementParentNodeInterface = {
+ getElementById: function(id) {
+ if (/[ \t\n\r\f]/.test(id)) return null;
+ return this.querySelector('[id="' + id + '"]');
+ }
+ };
+ scope.ChildNodeInterface = ChildNodeInterface;
+ scope.NonElementParentNodeInterface = NonElementParentNodeInterface;
+ scope.ParentNodeInterface = ParentNodeInterface;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var ChildNodeInterface = scope.ChildNodeInterface;
+ var Node = scope.wrappers.Node;
+ var enqueueMutation = scope.enqueueMutation;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var OriginalCharacterData = window.CharacterData;
+ function CharacterData(node) {
+ Node.call(this, node);
+ }
+ CharacterData.prototype = Object.create(Node.prototype);
+ mixin(CharacterData.prototype, {
+ get nodeValue() {
+ return this.data;
+ },
+ set nodeValue(data) {
+ this.data = data;
+ },
+ get textContent() {
+ return this.data;
+ },
+ set textContent(value) {
+ this.data = value;
+ },
+ get data() {
+ return unsafeUnwrap(this).data;
+ },
+ set data(value) {
+ var oldValue = unsafeUnwrap(this).data;
+ enqueueMutation(this, "characterData", {
+ oldValue: oldValue
+ });
+ unsafeUnwrap(this).data = value;
+ }
+ });
+ mixin(CharacterData.prototype, ChildNodeInterface);
+ registerWrapper(OriginalCharacterData, CharacterData, document.createTextNode(""));
+ scope.wrappers.CharacterData = CharacterData;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var CharacterData = scope.wrappers.CharacterData;
+ var enqueueMutation = scope.enqueueMutation;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ function toUInt32(x) {
+ return x >>> 0;
+ }
+ var OriginalText = window.Text;
+ function Text(node) {
+ CharacterData.call(this, node);
+ }
+ Text.prototype = Object.create(CharacterData.prototype);
+ mixin(Text.prototype, {
+ splitText: function(offset) {
+ offset = toUInt32(offset);
+ var s = this.data;
+ if (offset > s.length) throw new Error("IndexSizeError");
+ var head = s.slice(0, offset);
+ var tail = s.slice(offset);
+ this.data = head;
+ var newTextNode = this.ownerDocument.createTextNode(tail);
+ if (this.parentNode) this.parentNode.insertBefore(newTextNode, this.nextSibling);
+ return newTextNode;
+ }
+ });
+ registerWrapper(OriginalText, Text, document.createTextNode(""));
+ scope.wrappers.Text = Text;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ if (!window.DOMTokenList) {
+ console.warn("Missing DOMTokenList prototype, please include a " + "compatible classList polyfill such as http://goo.gl/uTcepH.");
+ return;
+ }
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var enqueueMutation = scope.enqueueMutation;
+ function getClass(el) {
+ return unsafeUnwrap(el).getAttribute("class");
+ }
+ function enqueueClassAttributeChange(el, oldValue) {
+ enqueueMutation(el, "attributes", {
+ name: "class",
+ namespace: null,
+ oldValue: oldValue
+ });
+ }
+ function invalidateClass(el) {
+ scope.invalidateRendererBasedOnAttribute(el, "class");
+ }
+ function changeClass(tokenList, method, args) {
+ var ownerElement = tokenList.ownerElement_;
+ if (ownerElement == null) {
+ return method.apply(tokenList, args);
+ }
+ var oldValue = getClass(ownerElement);
+ var retv = method.apply(tokenList, args);
+ if (getClass(ownerElement) !== oldValue) {
+ enqueueClassAttributeChange(ownerElement, oldValue);
+ invalidateClass(ownerElement);
+ }
+ return retv;
+ }
+ var oldAdd = DOMTokenList.prototype.add;
+ DOMTokenList.prototype.add = function() {
+ changeClass(this, oldAdd, arguments);
+ };
+ var oldRemove = DOMTokenList.prototype.remove;
+ DOMTokenList.prototype.remove = function() {
+ changeClass(this, oldRemove, arguments);
+ };
+ var oldToggle = DOMTokenList.prototype.toggle;
+ DOMTokenList.prototype.toggle = function() {
+ return changeClass(this, oldToggle, arguments);
+ };
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var ChildNodeInterface = scope.ChildNodeInterface;
+ var GetElementsByInterface = scope.GetElementsByInterface;
+ var Node = scope.wrappers.Node;
+ var ParentNodeInterface = scope.ParentNodeInterface;
+ var SelectorsInterface = scope.SelectorsInterface;
+ var MatchesInterface = scope.MatchesInterface;
+ var addWrapNodeListMethod = scope.addWrapNodeListMethod;
+ var enqueueMutation = scope.enqueueMutation;
+ var mixin = scope.mixin;
+ var oneOf = scope.oneOf;
+ var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var wrappers = scope.wrappers;
+ var OriginalElement = window.Element;
+ var matchesNames = [ "matches", "mozMatchesSelector", "msMatchesSelector", "webkitMatchesSelector" ].filter(function(name) {
+ return OriginalElement.prototype[name];
+ });
+ var matchesName = matchesNames[0];
+ var originalMatches = OriginalElement.prototype[matchesName];
+ function invalidateRendererBasedOnAttribute(element, name) {
+ var p = element.parentNode;
+ if (!p || !p.shadowRoot) return;
+ var renderer = scope.getRendererForHost(p);
+ if (renderer.dependsOnAttribute(name)) renderer.invalidate();
+ }
+ function enqueAttributeChange(element, name, oldValue) {
+ enqueueMutation(element, "attributes", {
+ name: name,
+ namespace: null,
+ oldValue: oldValue
+ });
+ }
+ var classListTable = new WeakMap();
+ function Element(node) {
+ Node.call(this, node);
+ }
+ Element.prototype = Object.create(Node.prototype);
+ mixin(Element.prototype, {
+ createShadowRoot: function() {
+ var newShadowRoot = new wrappers.ShadowRoot(this);
+ unsafeUnwrap(this).polymerShadowRoot_ = newShadowRoot;
+ var renderer = scope.getRendererForHost(this);
+ renderer.invalidate();
+ return newShadowRoot;
+ },
+ get shadowRoot() {
+ return unsafeUnwrap(this).polymerShadowRoot_ || null;
+ },
+ setAttribute: function(name, value) {
+ var oldValue = unsafeUnwrap(this).getAttribute(name);
+ unsafeUnwrap(this).setAttribute(name, value);
+ enqueAttributeChange(this, name, oldValue);
+ invalidateRendererBasedOnAttribute(this, name);
+ },
+ removeAttribute: function(name) {
+ var oldValue = unsafeUnwrap(this).getAttribute(name);
+ unsafeUnwrap(this).removeAttribute(name);
+ enqueAttributeChange(this, name, oldValue);
+ invalidateRendererBasedOnAttribute(this, name);
+ },
+ get classList() {
+ var list = classListTable.get(this);
+ if (!list) {
+ list = unsafeUnwrap(this).classList;
+ if (!list) return;
+ list.ownerElement_ = this;
+ classListTable.set(this, list);
+ }
+ return list;
+ },
+ get className() {
+ return unsafeUnwrap(this).className;
+ },
+ set className(v) {
+ this.setAttribute("class", v);
+ },
+ get id() {
+ return unsafeUnwrap(this).id;
+ },
+ set id(v) {
+ this.setAttribute("id", v);
+ }
+ });
+ matchesNames.forEach(function(name) {
+ if (name !== "matches") {
+ Element.prototype[name] = function(selector) {
+ return this.matches(selector);
+ };
+ }
+ });
+ if (OriginalElement.prototype.webkitCreateShadowRoot) {
+ Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;
+ }
+ mixin(Element.prototype, ChildNodeInterface);
+ mixin(Element.prototype, GetElementsByInterface);
+ mixin(Element.prototype, ParentNodeInterface);
+ mixin(Element.prototype, SelectorsInterface);
+ mixin(Element.prototype, MatchesInterface);
+ registerWrapper(OriginalElement, Element, document.createElementNS(null, "x"));
+ scope.invalidateRendererBasedOnAttribute = invalidateRendererBasedOnAttribute;
+ scope.matchesNames = matchesNames;
+ scope.originalMatches = originalMatches;
+ scope.wrappers.Element = Element;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var Element = scope.wrappers.Element;
+ var defineGetter = scope.defineGetter;
+ var enqueueMutation = scope.enqueueMutation;
+ var mixin = scope.mixin;
+ var nodesWereAdded = scope.nodesWereAdded;
+ var nodesWereRemoved = scope.nodesWereRemoved;
+ var registerWrapper = scope.registerWrapper;
+ var snapshotNodeList = scope.snapshotNodeList;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var wrappers = scope.wrappers;
+ var escapeAttrRegExp = /[&\u00A0"]/g;
+ var escapeDataRegExp = /[&\u00A0<>]/g;
+ function escapeReplace(c) {
+ switch (c) {
+ case "&":
+ return "&";
+
+ case "<":
+ return "<";
+
+ case ">":
+ return ">";
+
+ case '"':
+ return """;
+
+ case " ":
+ return " ";
+ }
+ }
+ function escapeAttr(s) {
+ return s.replace(escapeAttrRegExp, escapeReplace);
+ }
+ function escapeData(s) {
+ return s.replace(escapeDataRegExp, escapeReplace);
+ }
+ function makeSet(arr) {
+ var set = {};
+ for (var i = 0; i < arr.length; i++) {
+ set[arr[i]] = true;
+ }
+ return set;
+ }
+ var voidElements = makeSet([ "area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr" ]);
+ var plaintextParents = makeSet([ "style", "script", "xmp", "iframe", "noembed", "noframes", "plaintext", "noscript" ]);
+ var XHTML_NS = "http://www.w3.org/1999/xhtml";
+ function needsSelfClosingSlash(node) {
+ if (node.namespaceURI !== XHTML_NS) return true;
+ var doctype = node.ownerDocument.doctype;
+ return doctype && doctype.publicId && doctype.systemId;
+ }
+ function getOuterHTML(node, parentNode) {
+ switch (node.nodeType) {
+ case Node.ELEMENT_NODE:
+ var tagName = node.tagName.toLowerCase();
+ var s = "<" + tagName;
+ var attrs = node.attributes;
+ for (var i = 0, attr; attr = attrs[i]; i++) {
+ s += " " + attr.name + '="' + escapeAttr(attr.value) + '"';
+ }
+ if (voidElements[tagName]) {
+ if (needsSelfClosingSlash(node)) s += "/";
+ return s + ">";
+ }
+ return s + ">" + getInnerHTML(node) + "</" + tagName + ">";
+
+ case Node.TEXT_NODE:
+ var data = node.data;
+ if (parentNode && plaintextParents[parentNode.localName]) return data;
+ return escapeData(data);
+
+ case Node.COMMENT_NODE:
+ return "<!--" + node.data + "-->";
+
+ default:
+ console.error(node);
+ throw new Error("not implemented");
+ }
+ }
+ function getInnerHTML(node) {
+ if (node instanceof wrappers.HTMLTemplateElement) node = node.content;
+ var s = "";
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ s += getOuterHTML(child, node);
+ }
+ return s;
+ }
+ function setInnerHTML(node, value, opt_tagName) {
+ var tagName = opt_tagName || "div";
+ node.textContent = "";
+ var tempElement = unwrap(node.ownerDocument.createElement(tagName));
+ tempElement.innerHTML = value;
+ var firstChild;
+ while (firstChild = tempElement.firstChild) {
+ node.appendChild(wrap(firstChild));
+ }
+ }
+ var oldIe = /MSIE/.test(navigator.userAgent);
+ var OriginalHTMLElement = window.HTMLElement;
+ var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
+ function HTMLElement(node) {
+ Element.call(this, node);
+ }
+ HTMLElement.prototype = Object.create(Element.prototype);
+ mixin(HTMLElement.prototype, {
+ get innerHTML() {
+ return getInnerHTML(this);
+ },
+ set innerHTML(value) {
+ if (oldIe && plaintextParents[this.localName]) {
+ this.textContent = value;
+ return;
+ }
+ var removedNodes = snapshotNodeList(this.childNodes);
+ if (this.invalidateShadowRenderer()) {
+ if (this instanceof wrappers.HTMLTemplateElement) setInnerHTML(this.content, value); else setInnerHTML(this, value, this.tagName);
+ } else if (!OriginalHTMLTemplateElement && this instanceof wrappers.HTMLTemplateElement) {
+ setInnerHTML(this.content, value);
+ } else {
+ unsafeUnwrap(this).innerHTML = value;
+ }
+ var addedNodes = snapshotNodeList(this.childNodes);
+ enqueueMutation(this, "childList", {
+ addedNodes: addedNodes,
+ removedNodes: removedNodes
+ });
+ nodesWereRemoved(removedNodes);
+ nodesWereAdded(addedNodes, this);
+ },
+ get outerHTML() {
+ return getOuterHTML(this, this.parentNode);
+ },
+ set outerHTML(value) {
+ var p = this.parentNode;
+ if (p) {
+ p.invalidateShadowRenderer();
+ var df = frag(p, value);
+ p.replaceChild(df, this);
+ }
+ },
+ insertAdjacentHTML: function(position, text) {
+ var contextElement, refNode;
+ switch (String(position).toLowerCase()) {
+ case "beforebegin":
+ contextElement = this.parentNode;
+ refNode = this;
+ break;
+
+ case "afterend":
+ contextElement = this.parentNode;
+ refNode = this.nextSibling;
+ break;
+
+ case "afterbegin":
+ contextElement = this;
+ refNode = this.firstChild;
+ break;
+
+ case "beforeend":
+ contextElement = this;
+ refNode = null;
+ break;
+
+ default:
+ return;
+ }
+ var df = frag(contextElement, text);
+ contextElement.insertBefore(df, refNode);
+ },
+ get hidden() {
+ return this.hasAttribute("hidden");
+ },
+ set hidden(v) {
+ if (v) {
+ this.setAttribute("hidden", "");
+ } else {
+ this.removeAttribute("hidden");
+ }
+ }
+ });
+ function frag(contextElement, html) {
+ var p = unwrap(contextElement.cloneNode(false));
+ p.innerHTML = html;
+ var df = unwrap(document.createDocumentFragment());
+ var c;
+ while (c = p.firstChild) {
+ df.appendChild(c);
+ }
+ return wrap(df);
+ }
+ function getter(name) {
+ return function() {
+ scope.renderAllPending();
+ return unsafeUnwrap(this)[name];
+ };
+ }
+ function getterRequiresRendering(name) {
+ defineGetter(HTMLElement, name, getter(name));
+ }
+ [ "clientHeight", "clientLeft", "clientTop", "clientWidth", "offsetHeight", "offsetLeft", "offsetTop", "offsetWidth", "scrollHeight", "scrollWidth" ].forEach(getterRequiresRendering);
+ function getterAndSetterRequiresRendering(name) {
+ Object.defineProperty(HTMLElement.prototype, name, {
+ get: getter(name),
+ set: function(v) {
+ scope.renderAllPending();
+ unsafeUnwrap(this)[name] = v;
+ },
+ configurable: true,
+ enumerable: true
+ });
+ }
+ [ "scrollLeft", "scrollTop" ].forEach(getterAndSetterRequiresRendering);
+ function methodRequiresRendering(name) {
+ Object.defineProperty(HTMLElement.prototype, name, {
+ value: function() {
+ scope.renderAllPending();
+ return unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments);
+ },
+ configurable: true,
+ enumerable: true
+ });
+ }
+ [ "getBoundingClientRect", "getClientRects", "scrollIntoView" ].forEach(methodRequiresRendering);
+ registerWrapper(OriginalHTMLElement, HTMLElement, document.createElement("b"));
+ scope.wrappers.HTMLElement = HTMLElement;
+ scope.getInnerHTML = getInnerHTML;
+ scope.setInnerHTML = setInnerHTML;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var wrap = scope.wrap;
+ var OriginalHTMLCanvasElement = window.HTMLCanvasElement;
+ function HTMLCanvasElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLCanvasElement.prototype, {
+ getContext: function() {
+ var context = unsafeUnwrap(this).getContext.apply(unsafeUnwrap(this), arguments);
+ return context && wrap(context);
+ }
+ });
+ registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement, document.createElement("canvas"));
+ scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var OriginalHTMLContentElement = window.HTMLContentElement;
+ function HTMLContentElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLContentElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLContentElement.prototype, {
+ constructor: HTMLContentElement,
+ get select() {
+ return this.getAttribute("select");
+ },
+ set select(value) {
+ this.setAttribute("select", value);
+ },
+ setAttribute: function(n, v) {
+ HTMLElement.prototype.setAttribute.call(this, n, v);
+ if (String(n).toLowerCase() === "select") this.invalidateShadowRenderer(true);
+ }
+ });
+ if (OriginalHTMLContentElement) registerWrapper(OriginalHTMLContentElement, HTMLContentElement);
+ scope.wrappers.HTMLContentElement = HTMLContentElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var wrapHTMLCollection = scope.wrapHTMLCollection;
+ var unwrap = scope.unwrap;
+ var OriginalHTMLFormElement = window.HTMLFormElement;
+ function HTMLFormElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLFormElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLFormElement.prototype, {
+ get elements() {
+ return wrapHTMLCollection(unwrap(this).elements);
+ }
+ });
+ registerWrapper(OriginalHTMLFormElement, HTMLFormElement, document.createElement("form"));
+ scope.wrappers.HTMLFormElement = HTMLFormElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var registerWrapper = scope.registerWrapper;
+ var unwrap = scope.unwrap;
+ var rewrap = scope.rewrap;
+ var OriginalHTMLImageElement = window.HTMLImageElement;
+ function HTMLImageElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLImageElement.prototype = Object.create(HTMLElement.prototype);
+ registerWrapper(OriginalHTMLImageElement, HTMLImageElement, document.createElement("img"));
+ function Image(width, height) {
+ if (!(this instanceof Image)) {
+ throw new TypeError("DOM object constructor cannot be called as a function.");
+ }
+ var node = unwrap(document.createElement("img"));
+ HTMLElement.call(this, node);
+ rewrap(node, this);
+ if (width !== undefined) node.width = width;
+ if (height !== undefined) node.height = height;
+ }
+ Image.prototype = HTMLImageElement.prototype;
+ scope.wrappers.HTMLImageElement = HTMLImageElement;
+ scope.wrappers.Image = Image;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var NodeList = scope.wrappers.NodeList;
+ var registerWrapper = scope.registerWrapper;
+ var OriginalHTMLShadowElement = window.HTMLShadowElement;
+ function HTMLShadowElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);
+ HTMLShadowElement.prototype.constructor = HTMLShadowElement;
+ if (OriginalHTMLShadowElement) registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);
+ scope.wrappers.HTMLShadowElement = HTMLShadowElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var contentTable = new WeakMap();
+ var templateContentsOwnerTable = new WeakMap();
+ function getTemplateContentsOwner(doc) {
+ if (!doc.defaultView) return doc;
+ var d = templateContentsOwnerTable.get(doc);
+ if (!d) {
+ d = doc.implementation.createHTMLDocument("");
+ while (d.lastChild) {
+ d.removeChild(d.lastChild);
+ }
+ templateContentsOwnerTable.set(doc, d);
+ }
+ return d;
+ }
+ function extractContent(templateElement) {
+ var doc = getTemplateContentsOwner(templateElement.ownerDocument);
+ var df = unwrap(doc.createDocumentFragment());
+ var child;
+ while (child = templateElement.firstChild) {
+ df.appendChild(child);
+ }
+ return df;
+ }
+ var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
+ function HTMLTemplateElement(node) {
+ HTMLElement.call(this, node);
+ if (!OriginalHTMLTemplateElement) {
+ var content = extractContent(node);
+ contentTable.set(this, wrap(content));
+ }
+ }
+ HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLTemplateElement.prototype, {
+ constructor: HTMLTemplateElement,
+ get content() {
+ if (OriginalHTMLTemplateElement) return wrap(unsafeUnwrap(this).content);
+ return contentTable.get(this);
+ }
+ });
+ if (OriginalHTMLTemplateElement) registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);
+ scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var registerWrapper = scope.registerWrapper;
+ var OriginalHTMLMediaElement = window.HTMLMediaElement;
+ if (!OriginalHTMLMediaElement) return;
+ function HTMLMediaElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);
+ registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement, document.createElement("audio"));
+ scope.wrappers.HTMLMediaElement = HTMLMediaElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLMediaElement = scope.wrappers.HTMLMediaElement;
+ var registerWrapper = scope.registerWrapper;
+ var unwrap = scope.unwrap;
+ var rewrap = scope.rewrap;
+ var OriginalHTMLAudioElement = window.HTMLAudioElement;
+ if (!OriginalHTMLAudioElement) return;
+ function HTMLAudioElement(node) {
+ HTMLMediaElement.call(this, node);
+ }
+ HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);
+ registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement, document.createElement("audio"));
+ function Audio(src) {
+ if (!(this instanceof Audio)) {
+ throw new TypeError("DOM object constructor cannot be called as a function.");
+ }
+ var node = unwrap(document.createElement("audio"));
+ HTMLMediaElement.call(this, node);
+ rewrap(node, this);
+ node.setAttribute("preload", "auto");
+ if (src !== undefined) node.setAttribute("src", src);
+ }
+ Audio.prototype = HTMLAudioElement.prototype;
+ scope.wrappers.HTMLAudioElement = HTMLAudioElement;
+ scope.wrappers.Audio = Audio;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var rewrap = scope.rewrap;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var OriginalHTMLOptionElement = window.HTMLOptionElement;
+ function trimText(s) {
+ return s.replace(/\s+/g, " ").trim();
+ }
+ function HTMLOptionElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLOptionElement.prototype, {
+ get text() {
+ return trimText(this.textContent);
+ },
+ set text(value) {
+ this.textContent = trimText(String(value));
+ },
+ get form() {
+ return wrap(unwrap(this).form);
+ }
+ });
+ registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement, document.createElement("option"));
+ function Option(text, value, defaultSelected, selected) {
+ if (!(this instanceof Option)) {
+ throw new TypeError("DOM object constructor cannot be called as a function.");
+ }
+ var node = unwrap(document.createElement("option"));
+ HTMLElement.call(this, node);
+ rewrap(node, this);
+ if (text !== undefined) node.text = text;
+ if (value !== undefined) node.setAttribute("value", value);
+ if (defaultSelected === true) node.setAttribute("selected", "");
+ node.selected = selected === true;
+ }
+ Option.prototype = HTMLOptionElement.prototype;
+ scope.wrappers.HTMLOptionElement = HTMLOptionElement;
+ scope.wrappers.Option = Option;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var OriginalHTMLSelectElement = window.HTMLSelectElement;
+ function HTMLSelectElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLSelectElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLSelectElement.prototype, {
+ add: function(element, before) {
+ if (typeof before === "object") before = unwrap(before);
+ unwrap(this).add(unwrap(element), before);
+ },
+ remove: function(indexOrNode) {
+ if (indexOrNode === undefined) {
+ HTMLElement.prototype.remove.call(this);
+ return;
+ }
+ if (typeof indexOrNode === "object") indexOrNode = unwrap(indexOrNode);
+ unwrap(this).remove(indexOrNode);
+ },
+ get form() {
+ return wrap(unwrap(this).form);
+ }
+ });
+ registerWrapper(OriginalHTMLSelectElement, HTMLSelectElement, document.createElement("select"));
+ scope.wrappers.HTMLSelectElement = HTMLSelectElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var wrapHTMLCollection = scope.wrapHTMLCollection;
+ var OriginalHTMLTableElement = window.HTMLTableElement;
+ function HTMLTableElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLTableElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLTableElement.prototype, {
+ get caption() {
+ return wrap(unwrap(this).caption);
+ },
+ createCaption: function() {
+ return wrap(unwrap(this).createCaption());
+ },
+ get tHead() {
+ return wrap(unwrap(this).tHead);
+ },
+ createTHead: function() {
+ return wrap(unwrap(this).createTHead());
+ },
+ createTFoot: function() {
+ return wrap(unwrap(this).createTFoot());
+ },
+ get tFoot() {
+ return wrap(unwrap(this).tFoot);
+ },
+ get tBodies() {
+ return wrapHTMLCollection(unwrap(this).tBodies);
+ },
+ createTBody: function() {
+ return wrap(unwrap(this).createTBody());
+ },
+ get rows() {
+ return wrapHTMLCollection(unwrap(this).rows);
+ },
+ insertRow: function(index) {
+ return wrap(unwrap(this).insertRow(index));
+ }
+ });
+ registerWrapper(OriginalHTMLTableElement, HTMLTableElement, document.createElement("table"));
+ scope.wrappers.HTMLTableElement = HTMLTableElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var wrapHTMLCollection = scope.wrapHTMLCollection;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var OriginalHTMLTableSectionElement = window.HTMLTableSectionElement;
+ function HTMLTableSectionElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLTableSectionElement.prototype, {
+ constructor: HTMLTableSectionElement,
+ get rows() {
+ return wrapHTMLCollection(unwrap(this).rows);
+ },
+ insertRow: function(index) {
+ return wrap(unwrap(this).insertRow(index));
+ }
+ });
+ registerWrapper(OriginalHTMLTableSectionElement, HTMLTableSectionElement, document.createElement("thead"));
+ scope.wrappers.HTMLTableSectionElement = HTMLTableSectionElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var wrapHTMLCollection = scope.wrapHTMLCollection;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var OriginalHTMLTableRowElement = window.HTMLTableRowElement;
+ function HTMLTableRowElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLTableRowElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLTableRowElement.prototype, {
+ get cells() {
+ return wrapHTMLCollection(unwrap(this).cells);
+ },
+ insertCell: function(index) {
+ return wrap(unwrap(this).insertCell(index));
+ }
+ });
+ registerWrapper(OriginalHTMLTableRowElement, HTMLTableRowElement, document.createElement("tr"));
+ scope.wrappers.HTMLTableRowElement = HTMLTableRowElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLContentElement = scope.wrappers.HTMLContentElement;
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
+ var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var OriginalHTMLUnknownElement = window.HTMLUnknownElement;
+ function HTMLUnknownElement(node) {
+ switch (node.localName) {
+ case "content":
+ return new HTMLContentElement(node);
+
+ case "shadow":
+ return new HTMLShadowElement(node);
+
+ case "template":
+ return new HTMLTemplateElement(node);
+ }
+ HTMLElement.call(this, node);
+ }
+ HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);
+ registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);
+ scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var Element = scope.wrappers.Element;
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var registerObject = scope.registerObject;
+ var defineWrapGetter = scope.defineWrapGetter;
+ var SVG_NS = "http://www.w3.org/2000/svg";
+ var svgTitleElement = document.createElementNS(SVG_NS, "title");
+ var SVGTitleElement = registerObject(svgTitleElement);
+ var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;
+ if (!("classList" in svgTitleElement)) {
+ var descr = Object.getOwnPropertyDescriptor(Element.prototype, "classList");
+ Object.defineProperty(HTMLElement.prototype, "classList", descr);
+ delete Element.prototype.classList;
+ }
+ defineWrapGetter(SVGElement, "ownerSVGElement");
+ scope.wrappers.SVGElement = SVGElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var OriginalSVGUseElement = window.SVGUseElement;
+ var SVG_NS = "http://www.w3.org/2000/svg";
+ var gWrapper = wrap(document.createElementNS(SVG_NS, "g"));
+ var useElement = document.createElementNS(SVG_NS, "use");
+ var SVGGElement = gWrapper.constructor;
+ var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);
+ var parentInterface = parentInterfacePrototype.constructor;
+ function SVGUseElement(impl) {
+ parentInterface.call(this, impl);
+ }
+ SVGUseElement.prototype = Object.create(parentInterfacePrototype);
+ if ("instanceRoot" in useElement) {
+ mixin(SVGUseElement.prototype, {
+ get instanceRoot() {
+ return wrap(unwrap(this).instanceRoot);
+ },
+ get animatedInstanceRoot() {
+ return wrap(unwrap(this).animatedInstanceRoot);
+ }
+ });
+ }
+ registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);
+ scope.wrappers.SVGUseElement = SVGUseElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var EventTarget = scope.wrappers.EventTarget;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var wrap = scope.wrap;
+ var OriginalSVGElementInstance = window.SVGElementInstance;
+ if (!OriginalSVGElementInstance) return;
+ function SVGElementInstance(impl) {
+ EventTarget.call(this, impl);
+ }
+ SVGElementInstance.prototype = Object.create(EventTarget.prototype);
+ mixin(SVGElementInstance.prototype, {
+ get correspondingElement() {
+ return wrap(unsafeUnwrap(this).correspondingElement);
+ },
+ get correspondingUseElement() {
+ return wrap(unsafeUnwrap(this).correspondingUseElement);
+ },
+ get parentNode() {
+ return wrap(unsafeUnwrap(this).parentNode);
+ },
+ get childNodes() {
+ throw new Error("Not implemented");
+ },
+ get firstChild() {
+ return wrap(unsafeUnwrap(this).firstChild);
+ },
+ get lastChild() {
+ return wrap(unsafeUnwrap(this).lastChild);
+ },
+ get previousSibling() {
+ return wrap(unsafeUnwrap(this).previousSibling);
+ },
+ get nextSibling() {
+ return wrap(unsafeUnwrap(this).nextSibling);
+ }
+ });
+ registerWrapper(OriginalSVGElementInstance, SVGElementInstance);
+ scope.wrappers.SVGElementInstance = SVGElementInstance;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var wrap = scope.wrap;
+ var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
+ function CanvasRenderingContext2D(impl) {
+ setWrapper(impl, this);
+ }
+ mixin(CanvasRenderingContext2D.prototype, {
+ get canvas() {
+ return wrap(unsafeUnwrap(this).canvas);
+ },
+ drawImage: function() {
+ arguments[0] = unwrapIfNeeded(arguments[0]);
+ unsafeUnwrap(this).drawImage.apply(unsafeUnwrap(this), arguments);
+ },
+ createPattern: function() {
+ arguments[0] = unwrap(arguments[0]);
+ return unsafeUnwrap(this).createPattern.apply(unsafeUnwrap(this), arguments);
+ }
+ });
+ registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D, document.createElement("canvas").getContext("2d"));
+ scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var wrap = scope.wrap;
+ var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
+ if (!OriginalWebGLRenderingContext) return;
+ function WebGLRenderingContext(impl) {
+ setWrapper(impl, this);
+ }
+ mixin(WebGLRenderingContext.prototype, {
+ get canvas() {
+ return wrap(unsafeUnwrap(this).canvas);
+ },
+ texImage2D: function() {
+ arguments[5] = unwrapIfNeeded(arguments[5]);
+ unsafeUnwrap(this).texImage2D.apply(unsafeUnwrap(this), arguments);
+ },
+ texSubImage2D: function() {
+ arguments[6] = unwrapIfNeeded(arguments[6]);
+ unsafeUnwrap(this).texSubImage2D.apply(unsafeUnwrap(this), arguments);
+ }
+ });
+ var instanceProperties = /WebKit/.test(navigator.userAgent) ? {
+ drawingBufferHeight: null,
+ drawingBufferWidth: null
+ } : {};
+ registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext, instanceProperties);
+ scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var GetElementsByInterface = scope.GetElementsByInterface;
+ var NonElementParentNodeInterface = scope.NonElementParentNodeInterface;
+ var ParentNodeInterface = scope.ParentNodeInterface;
+ var SelectorsInterface = scope.SelectorsInterface;
+ var mixin = scope.mixin;
+ var registerObject = scope.registerObject;
+ var DocumentFragment = registerObject(document.createDocumentFragment());
+ mixin(DocumentFragment.prototype, ParentNodeInterface);
+ mixin(DocumentFragment.prototype, SelectorsInterface);
+ mixin(DocumentFragment.prototype, GetElementsByInterface);
+ mixin(DocumentFragment.prototype, NonElementParentNodeInterface);
+ var Comment = registerObject(document.createComment(""));
+ scope.wrappers.Comment = Comment;
+ scope.wrappers.DocumentFragment = DocumentFragment;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var DocumentFragment = scope.wrappers.DocumentFragment;
+ var TreeScope = scope.TreeScope;
+ var elementFromPoint = scope.elementFromPoint;
+ var getInnerHTML = scope.getInnerHTML;
+ var getTreeScope = scope.getTreeScope;
+ var mixin = scope.mixin;
+ var rewrap = scope.rewrap;
+ var setInnerHTML = scope.setInnerHTML;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var shadowHostTable = new WeakMap();
+ var nextOlderShadowTreeTable = new WeakMap();
+ function ShadowRoot(hostWrapper) {
+ var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment());
+ DocumentFragment.call(this, node);
+ rewrap(node, this);
+ var oldShadowRoot = hostWrapper.shadowRoot;
+ nextOlderShadowTreeTable.set(this, oldShadowRoot);
+ this.treeScope_ = new TreeScope(this, getTreeScope(oldShadowRoot || hostWrapper));
+ shadowHostTable.set(this, hostWrapper);
+ }
+ ShadowRoot.prototype = Object.create(DocumentFragment.prototype);
+ mixin(ShadowRoot.prototype, {
+ constructor: ShadowRoot,
+ get innerHTML() {
+ return getInnerHTML(this);
+ },
+ set innerHTML(value) {
+ setInnerHTML(this, value);
+ this.invalidateShadowRenderer();
+ },
+ get olderShadowRoot() {
+ return nextOlderShadowTreeTable.get(this) || null;
+ },
+ get host() {
+ return shadowHostTable.get(this) || null;
+ },
+ invalidateShadowRenderer: function() {
+ return shadowHostTable.get(this).invalidateShadowRenderer();
+ },
+ elementFromPoint: function(x, y) {
+ return elementFromPoint(this, this.ownerDocument, x, y);
+ }
+ });
+ scope.wrappers.ShadowRoot = ShadowRoot;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var wrap = scope.wrap;
+ var getTreeScope = scope.getTreeScope;
+ var OriginalRange = window.Range;
+ var ShadowRoot = scope.wrappers.ShadowRoot;
+ function getHost(node) {
+ var root = getTreeScope(node).root;
+ if (root instanceof ShadowRoot) {
+ return root.host;
+ }
+ return null;
+ }
+ function hostNodeToShadowNode(refNode, offset) {
+ if (refNode.shadowRoot) {
+ offset = Math.min(refNode.childNodes.length - 1, offset);
+ var child = refNode.childNodes[offset];
+ if (child) {
+ var insertionPoint = scope.getDestinationInsertionPoints(child);
+ if (insertionPoint.length > 0) {
+ var parentNode = insertionPoint[0].parentNode;
+ if (parentNode.nodeType == Node.ELEMENT_NODE) {
+ refNode = parentNode;
+ }
+ }
+ }
+ }
+ return refNode;
+ }
+ function shadowNodeToHostNode(node) {
+ node = wrap(node);
+ return getHost(node) || node;
+ }
+ function Range(impl) {
+ setWrapper(impl, this);
+ }
+ Range.prototype = {
+ get startContainer() {
+ return shadowNodeToHostNode(unsafeUnwrap(this).startContainer);
+ },
+ get endContainer() {
+ return shadowNodeToHostNode(unsafeUnwrap(this).endContainer);
+ },
+ get commonAncestorContainer() {
+ return shadowNodeToHostNode(unsafeUnwrap(this).commonAncestorContainer);
+ },
+ setStart: function(refNode, offset) {
+ refNode = hostNodeToShadowNode(refNode, offset);
+ unsafeUnwrap(this).setStart(unwrapIfNeeded(refNode), offset);
+ },
+ setEnd: function(refNode, offset) {
+ refNode = hostNodeToShadowNode(refNode, offset);
+ unsafeUnwrap(this).setEnd(unwrapIfNeeded(refNode), offset);
+ },
+ setStartBefore: function(refNode) {
+ unsafeUnwrap(this).setStartBefore(unwrapIfNeeded(refNode));
+ },
+ setStartAfter: function(refNode) {
+ unsafeUnwrap(this).setStartAfter(unwrapIfNeeded(refNode));
+ },
+ setEndBefore: function(refNode) {
+ unsafeUnwrap(this).setEndBefore(unwrapIfNeeded(refNode));
+ },
+ setEndAfter: function(refNode) {
+ unsafeUnwrap(this).setEndAfter(unwrapIfNeeded(refNode));
+ },
+ selectNode: function(refNode) {
+ unsafeUnwrap(this).selectNode(unwrapIfNeeded(refNode));
+ },
+ selectNodeContents: function(refNode) {
+ unsafeUnwrap(this).selectNodeContents(unwrapIfNeeded(refNode));
+ },
+ compareBoundaryPoints: function(how, sourceRange) {
+ return unsafeUnwrap(this).compareBoundaryPoints(how, unwrap(sourceRange));
+ },
+ extractContents: function() {
+ return wrap(unsafeUnwrap(this).extractContents());
+ },
+ cloneContents: function() {
+ return wrap(unsafeUnwrap(this).cloneContents());
+ },
+ insertNode: function(node) {
+ unsafeUnwrap(this).insertNode(unwrapIfNeeded(node));
+ },
+ surroundContents: function(newParent) {
+ unsafeUnwrap(this).surroundContents(unwrapIfNeeded(newParent));
+ },
+ cloneRange: function() {
+ return wrap(unsafeUnwrap(this).cloneRange());
+ },
+ isPointInRange: function(node, offset) {
+ return unsafeUnwrap(this).isPointInRange(unwrapIfNeeded(node), offset);
+ },
+ comparePoint: function(node, offset) {
+ return unsafeUnwrap(this).comparePoint(unwrapIfNeeded(node), offset);
+ },
+ intersectsNode: function(node) {
+ return unsafeUnwrap(this).intersectsNode(unwrapIfNeeded(node));
+ },
+ toString: function() {
+ return unsafeUnwrap(this).toString();
+ }
+ };
+ if (OriginalRange.prototype.createContextualFragment) {
+ Range.prototype.createContextualFragment = function(html) {
+ return wrap(unsafeUnwrap(this).createContextualFragment(html));
+ };
+ }
+ registerWrapper(window.Range, Range, document.createRange());
+ scope.wrappers.Range = Range;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var Element = scope.wrappers.Element;
+ var HTMLContentElement = scope.wrappers.HTMLContentElement;
+ var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
+ var Node = scope.wrappers.Node;
+ var ShadowRoot = scope.wrappers.ShadowRoot;
+ var assert = scope.assert;
+ var getTreeScope = scope.getTreeScope;
+ var mixin = scope.mixin;
+ var oneOf = scope.oneOf;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var ArraySplice = scope.ArraySplice;
+ function updateWrapperUpAndSideways(wrapper) {
+ wrapper.previousSibling_ = wrapper.previousSibling;
+ wrapper.nextSibling_ = wrapper.nextSibling;
+ wrapper.parentNode_ = wrapper.parentNode;
+ }
+ function updateWrapperDown(wrapper) {
+ wrapper.firstChild_ = wrapper.firstChild;
+ wrapper.lastChild_ = wrapper.lastChild;
+ }
+ function updateAllChildNodes(parentNodeWrapper) {
+ assert(parentNodeWrapper instanceof Node);
+ for (var childWrapper = parentNodeWrapper.firstChild; childWrapper; childWrapper = childWrapper.nextSibling) {
+ updateWrapperUpAndSideways(childWrapper);
+ }
+ updateWrapperDown(parentNodeWrapper);
+ }
+ function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {
+ var parentNode = unwrap(parentNodeWrapper);
+ var newChild = unwrap(newChildWrapper);
+ var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;
+ remove(newChildWrapper);
+ updateWrapperUpAndSideways(newChildWrapper);
+ if (!refChildWrapper) {
+ parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;
+ if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild) parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;
+ var lastChildWrapper = wrap(parentNode.lastChild);
+ if (lastChildWrapper) lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;
+ } else {
+ if (parentNodeWrapper.firstChild === refChildWrapper) parentNodeWrapper.firstChild_ = refChildWrapper;
+ refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;
+ }
+ scope.originalInsertBefore.call(parentNode, newChild, refChild);
+ }
+ function remove(nodeWrapper) {
+ var node = unwrap(nodeWrapper);
+ var parentNode = node.parentNode;
+ if (!parentNode) return;
+ var parentNodeWrapper = wrap(parentNode);
+ updateWrapperUpAndSideways(nodeWrapper);
+ if (nodeWrapper.previousSibling) nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;
+ if (nodeWrapper.nextSibling) nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;
+ if (parentNodeWrapper.lastChild === nodeWrapper) parentNodeWrapper.lastChild_ = nodeWrapper;
+ if (parentNodeWrapper.firstChild === nodeWrapper) parentNodeWrapper.firstChild_ = nodeWrapper;
+ scope.originalRemoveChild.call(parentNode, node);
+ }
+ var distributedNodesTable = new WeakMap();
+ var destinationInsertionPointsTable = new WeakMap();
+ var rendererForHostTable = new WeakMap();
+ function resetDistributedNodes(insertionPoint) {
+ distributedNodesTable.set(insertionPoint, []);
+ }
+ function getDistributedNodes(insertionPoint) {
+ var rv = distributedNodesTable.get(insertionPoint);
+ if (!rv) distributedNodesTable.set(insertionPoint, rv = []);
+ return rv;
+ }
+ function getChildNodesSnapshot(node) {
+ var result = [], i = 0;
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ result[i++] = child;
+ }
+ return result;
+ }
+ var request = oneOf(window, [ "requestAnimationFrame", "mozRequestAnimationFrame", "webkitRequestAnimationFrame", "setTimeout" ]);
+ var pendingDirtyRenderers = [];
+ var renderTimer;
+ function renderAllPending() {
+ for (var i = 0; i < pendingDirtyRenderers.length; i++) {
+ var renderer = pendingDirtyRenderers[i];
+ var parentRenderer = renderer.parentRenderer;
+ if (parentRenderer && parentRenderer.dirty) continue;
+ renderer.render();
+ }
+ pendingDirtyRenderers = [];
+ }
+ function handleRequestAnimationFrame() {
+ renderTimer = null;
+ renderAllPending();
+ }
+ function getRendererForHost(host) {
+ var renderer = rendererForHostTable.get(host);
+ if (!renderer) {
+ renderer = new ShadowRenderer(host);
+ rendererForHostTable.set(host, renderer);
+ }
+ return renderer;
+ }
+ function getShadowRootAncestor(node) {
+ var root = getTreeScope(node).root;
+ if (root instanceof ShadowRoot) return root;
+ return null;
+ }
+ function getRendererForShadowRoot(shadowRoot) {
+ return getRendererForHost(shadowRoot.host);
+ }
+ var spliceDiff = new ArraySplice();
+ spliceDiff.equals = function(renderNode, rawNode) {
+ return unwrap(renderNode.node) === rawNode;
+ };
+ function RenderNode(node) {
+ this.skip = false;
+ this.node = node;
+ this.childNodes = [];
+ }
+ RenderNode.prototype = {
+ append: function(node) {
+ var rv = new RenderNode(node);
+ this.childNodes.push(rv);
+ return rv;
+ },
+ sync: function(opt_added) {
+ if (this.skip) return;
+ var nodeWrapper = this.node;
+ var newChildren = this.childNodes;
+ var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));
+ var added = opt_added || new WeakMap();
+ var splices = spliceDiff.calculateSplices(newChildren, oldChildren);
+ var newIndex = 0, oldIndex = 0;
+ var lastIndex = 0;
+ for (var i = 0; i < splices.length; i++) {
+ var splice = splices[i];
+ for (;lastIndex < splice.index; lastIndex++) {
+ oldIndex++;
+ newChildren[newIndex++].sync(added);
+ }
+ var removedCount = splice.removed.length;
+ for (var j = 0; j < removedCount; j++) {
+ var wrapper = wrap(oldChildren[oldIndex++]);
+ if (!added.get(wrapper)) remove(wrapper);
+ }
+ var addedCount = splice.addedCount;
+ var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);
+ for (var j = 0; j < addedCount; j++) {
+ var newChildRenderNode = newChildren[newIndex++];
+ var newChildWrapper = newChildRenderNode.node;
+ insertBefore(nodeWrapper, newChildWrapper, refNode);
+ added.set(newChildWrapper, true);
+ newChildRenderNode.sync(added);
+ }
+ lastIndex += addedCount;
+ }
+ for (var i = lastIndex; i < newChildren.length; i++) {
+ newChildren[i].sync(added);
+ }
+ }
+ };
+ function ShadowRenderer(host) {
+ this.host = host;
+ this.dirty = false;
+ this.invalidateAttributes();
+ this.associateNode(host);
+ }
+ ShadowRenderer.prototype = {
+ render: function(opt_renderNode) {
+ if (!this.dirty) return;
+ this.invalidateAttributes();
+ var host = this.host;
+ this.distribution(host);
+ var renderNode = opt_renderNode || new RenderNode(host);
+ this.buildRenderTree(renderNode, host);
+ var topMostRenderer = !opt_renderNode;
+ if (topMostRenderer) renderNode.sync();
+ this.dirty = false;
+ },
+ get parentRenderer() {
+ return getTreeScope(this.host).renderer;
+ },
+ invalidate: function() {
+ if (!this.dirty) {
+ this.dirty = true;
+ var parentRenderer = this.parentRenderer;
+ if (parentRenderer) parentRenderer.invalidate();
+ pendingDirtyRenderers.push(this);
+ if (renderTimer) return;
+ renderTimer = window[request](handleRequestAnimationFrame, 0);
+ }
+ },
+ distribution: function(root) {
+ this.resetAllSubtrees(root);
+ this.distributionResolution(root);
+ },
+ resetAll: function(node) {
+ if (isInsertionPoint(node)) resetDistributedNodes(node); else resetDestinationInsertionPoints(node);
+ this.resetAllSubtrees(node);
+ },
+ resetAllSubtrees: function(node) {
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ this.resetAll(child);
+ }
+ if (node.shadowRoot) this.resetAll(node.shadowRoot);
+ if (node.olderShadowRoot) this.resetAll(node.olderShadowRoot);
+ },
+ distributionResolution: function(node) {
+ if (isShadowHost(node)) {
+ var shadowHost = node;
+ var pool = poolPopulation(shadowHost);
+ var shadowTrees = getShadowTrees(shadowHost);
+ for (var i = 0; i < shadowTrees.length; i++) {
+ this.poolDistribution(shadowTrees[i], pool);
+ }
+ for (var i = shadowTrees.length - 1; i >= 0; i--) {
+ var shadowTree = shadowTrees[i];
+ var shadow = getShadowInsertionPoint(shadowTree);
+ if (shadow) {
+ var olderShadowRoot = shadowTree.olderShadowRoot;
+ if (olderShadowRoot) {
+ pool = poolPopulation(olderShadowRoot);
+ }
+ for (var j = 0; j < pool.length; j++) {
+ destributeNodeInto(pool[j], shadow);
+ }
+ }
+ this.distributionResolution(shadowTree);
+ }
+ }
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ this.distributionResolution(child);
+ }
+ },
+ poolDistribution: function(node, pool) {
+ if (node instanceof HTMLShadowElement) return;
+ if (node instanceof HTMLContentElement) {
+ var content = node;
+ this.updateDependentAttributes(content.getAttribute("select"));
+ var anyDistributed = false;
+ for (var i = 0; i < pool.length; i++) {
+ var node = pool[i];
+ if (!node) continue;
+ if (matches(node, content)) {
+ destributeNodeInto(node, content);
+ pool[i] = undefined;
+ anyDistributed = true;
+ }
+ }
+ if (!anyDistributed) {
+ for (var child = content.firstChild; child; child = child.nextSibling) {
+ destributeNodeInto(child, content);
+ }
+ }
+ return;
+ }
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ this.poolDistribution(child, pool);
+ }
+ },
+ buildRenderTree: function(renderNode, node) {
+ var children = this.compose(node);
+ for (var i = 0; i < children.length; i++) {
+ var child = children[i];
+ var childRenderNode = renderNode.append(child);
+ this.buildRenderTree(childRenderNode, child);
+ }
+ if (isShadowHost(node)) {
+ var renderer = getRendererForHost(node);
+ renderer.dirty = false;
+ }
+ },
+ compose: function(node) {
+ var children = [];
+ var p = node.shadowRoot || node;
+ for (var child = p.firstChild; child; child = child.nextSibling) {
+ if (isInsertionPoint(child)) {
+ this.associateNode(p);
+ var distributedNodes = getDistributedNodes(child);
+ for (var j = 0; j < distributedNodes.length; j++) {
+ var distributedNode = distributedNodes[j];
+ if (isFinalDestination(child, distributedNode)) children.push(distributedNode);
+ }
+ } else {
+ children.push(child);
+ }
+ }
+ return children;
+ },
+ invalidateAttributes: function() {
+ this.attributes = Object.create(null);
+ },
+ updateDependentAttributes: function(selector) {
+ if (!selector) return;
+ var attributes = this.attributes;
+ if (/\.\w+/.test(selector)) attributes["class"] = true;
+ if (/#\w+/.test(selector)) attributes["id"] = true;
+ selector.replace(/\[\s*([^\s=\|~\]]+)/g, function(_, name) {
+ attributes[name] = true;
+ });
+ },
+ dependsOnAttribute: function(name) {
+ return this.attributes[name];
+ },
+ associateNode: function(node) {
+ unsafeUnwrap(node).polymerShadowRenderer_ = this;
+ }
+ };
+ function poolPopulation(node) {
+ var pool = [];
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ if (isInsertionPoint(child)) {
+ pool.push.apply(pool, getDistributedNodes(child));
+ } else {
+ pool.push(child);
+ }
+ }
+ return pool;
+ }
+ function getShadowInsertionPoint(node) {
+ if (node instanceof HTMLShadowElement) return node;
+ if (node instanceof HTMLContentElement) return null;
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ var res = getShadowInsertionPoint(child);
+ if (res) return res;
+ }
+ return null;
+ }
+ function destributeNodeInto(child, insertionPoint) {
+ getDistributedNodes(insertionPoint).push(child);
+ var points = destinationInsertionPointsTable.get(child);
+ if (!points) destinationInsertionPointsTable.set(child, [ insertionPoint ]); else points.push(insertionPoint);
+ }
+ function getDestinationInsertionPoints(node) {
+ return destinationInsertionPointsTable.get(node);
+ }
+ function resetDestinationInsertionPoints(node) {
+ destinationInsertionPointsTable.set(node, undefined);
+ }
+ var selectorStartCharRe = /^(:not\()?[*.#[a-zA-Z_|]/;
+ function matches(node, contentElement) {
+ var select = contentElement.getAttribute("select");
+ if (!select) return true;
+ select = select.trim();
+ if (!select) return true;
+ if (!(node instanceof Element)) return false;
+ if (!selectorStartCharRe.test(select)) return false;
+ try {
+ return node.matches(select);
+ } catch (ex) {
+ return false;
+ }
+ }
+ function isFinalDestination(insertionPoint, node) {
+ var points = getDestinationInsertionPoints(node);
+ return points && points[points.length - 1] === insertionPoint;
+ }
+ function isInsertionPoint(node) {
+ return node instanceof HTMLContentElement || node instanceof HTMLShadowElement;
+ }
+ function isShadowHost(shadowHost) {
+ return shadowHost.shadowRoot;
+ }
+ function getShadowTrees(host) {
+ var trees = [];
+ for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {
+ trees.push(tree);
+ }
+ return trees;
+ }
+ function render(host) {
+ new ShadowRenderer(host).render();
+ }
+ Node.prototype.invalidateShadowRenderer = function(force) {
+ var renderer = unsafeUnwrap(this).polymerShadowRenderer_;
+ if (renderer) {
+ renderer.invalidate();
+ return true;
+ }
+ return false;
+ };
+ HTMLContentElement.prototype.getDistributedNodes = HTMLShadowElement.prototype.getDistributedNodes = function() {
+ renderAllPending();
+ return getDistributedNodes(this);
+ };
+ Element.prototype.getDestinationInsertionPoints = function() {
+ renderAllPending();
+ return getDestinationInsertionPoints(this) || [];
+ };
+ HTMLContentElement.prototype.nodeIsInserted_ = HTMLShadowElement.prototype.nodeIsInserted_ = function() {
+ this.invalidateShadowRenderer();
+ var shadowRoot = getShadowRootAncestor(this);
+ var renderer;
+ if (shadowRoot) renderer = getRendererForShadowRoot(shadowRoot);
+ unsafeUnwrap(this).polymerShadowRenderer_ = renderer;
+ if (renderer) renderer.invalidate();
+ };
+ scope.getRendererForHost = getRendererForHost;
+ scope.getShadowTrees = getShadowTrees;
+ scope.renderAllPending = renderAllPending;
+ scope.getDestinationInsertionPoints = getDestinationInsertionPoints;
+ scope.visual = {
+ insertBefore: insertBefore,
+ remove: remove
+ };
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var assert = scope.assert;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var elementsWithFormProperty = [ "HTMLButtonElement", "HTMLFieldSetElement", "HTMLInputElement", "HTMLKeygenElement", "HTMLLabelElement", "HTMLLegendElement", "HTMLObjectElement", "HTMLOutputElement", "HTMLTextAreaElement" ];
+ function createWrapperConstructor(name) {
+ if (!window[name]) return;
+ assert(!scope.wrappers[name]);
+ var GeneratedWrapper = function(node) {
+ HTMLElement.call(this, node);
+ };
+ GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);
+ mixin(GeneratedWrapper.prototype, {
+ get form() {
+ return wrap(unwrap(this).form);
+ }
+ });
+ registerWrapper(window[name], GeneratedWrapper, document.createElement(name.slice(4, -7)));
+ scope.wrappers[name] = GeneratedWrapper;
+ }
+ elementsWithFormProperty.forEach(createWrapperConstructor);
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var wrap = scope.wrap;
+ var OriginalSelection = window.Selection;
+ function Selection(impl) {
+ setWrapper(impl, this);
+ }
+ Selection.prototype = {
+ get anchorNode() {
+ return wrap(unsafeUnwrap(this).anchorNode);
+ },
+ get focusNode() {
+ return wrap(unsafeUnwrap(this).focusNode);
+ },
+ addRange: function(range) {
+ unsafeUnwrap(this).addRange(unwrapIfNeeded(range));
+ },
+ collapse: function(node, index) {
+ unsafeUnwrap(this).collapse(unwrapIfNeeded(node), index);
+ },
+ containsNode: function(node, allowPartial) {
+ return unsafeUnwrap(this).containsNode(unwrapIfNeeded(node), allowPartial);
+ },
+ getRangeAt: function(index) {
+ return wrap(unsafeUnwrap(this).getRangeAt(index));
+ },
+ removeRange: function(range) {
+ unsafeUnwrap(this).removeRange(unwrap(range));
+ },
+ selectAllChildren: function(node) {
+ unsafeUnwrap(this).selectAllChildren(unwrapIfNeeded(node));
+ },
+ toString: function() {
+ return unsafeUnwrap(this).toString();
+ }
+ };
+ if (OriginalSelection.prototype.extend) {
+ Selection.prototype.extend = function(node, offset) {
+ unsafeUnwrap(this).extend(unwrapIfNeeded(node), offset);
+ };
+ }
+ registerWrapper(window.Selection, Selection, window.getSelection());
+ scope.wrappers.Selection = Selection;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var wrap = scope.wrap;
+ var OriginalTreeWalker = window.TreeWalker;
+ function TreeWalker(impl) {
+ setWrapper(impl, this);
+ }
+ TreeWalker.prototype = {
+ get root() {
+ return wrap(unsafeUnwrap(this).root);
+ },
+ get currentNode() {
+ return wrap(unsafeUnwrap(this).currentNode);
+ },
+ set currentNode(node) {
+ unsafeUnwrap(this).currentNode = unwrapIfNeeded(node);
+ },
+ get filter() {
+ return unsafeUnwrap(this).filter;
+ },
+ parentNode: function() {
+ return wrap(unsafeUnwrap(this).parentNode());
+ },
+ firstChild: function() {
+ return wrap(unsafeUnwrap(this).firstChild());
+ },
+ lastChild: function() {
+ return wrap(unsafeUnwrap(this).lastChild());
+ },
+ previousSibling: function() {
+ return wrap(unsafeUnwrap(this).previousSibling());
+ },
+ previousNode: function() {
+ return wrap(unsafeUnwrap(this).previousNode());
+ },
+ nextNode: function() {
+ return wrap(unsafeUnwrap(this).nextNode());
+ }
+ };
+ registerWrapper(OriginalTreeWalker, TreeWalker);
+ scope.wrappers.TreeWalker = TreeWalker;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var GetElementsByInterface = scope.GetElementsByInterface;
+ var Node = scope.wrappers.Node;
+ var ParentNodeInterface = scope.ParentNodeInterface;
+ var NonElementParentNodeInterface = scope.NonElementParentNodeInterface;
+ var Selection = scope.wrappers.Selection;
+ var SelectorsInterface = scope.SelectorsInterface;
+ var ShadowRoot = scope.wrappers.ShadowRoot;
+ var TreeScope = scope.TreeScope;
+ var cloneNode = scope.cloneNode;
+ var defineWrapGetter = scope.defineWrapGetter;
+ var elementFromPoint = scope.elementFromPoint;
+ var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
+ var matchesNames = scope.matchesNames;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var renderAllPending = scope.renderAllPending;
+ var rewrap = scope.rewrap;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var wrapEventTargetMethods = scope.wrapEventTargetMethods;
+ var wrapNodeList = scope.wrapNodeList;
+ var implementationTable = new WeakMap();
+ function Document(node) {
+ Node.call(this, node);
+ this.treeScope_ = new TreeScope(this, null);
+ }
+ Document.prototype = Object.create(Node.prototype);
+ defineWrapGetter(Document, "documentElement");
+ defineWrapGetter(Document, "body");
+ defineWrapGetter(Document, "head");
+ function wrapMethod(name) {
+ var original = document[name];
+ Document.prototype[name] = function() {
+ return wrap(original.apply(unsafeUnwrap(this), arguments));
+ };
+ }
+ [ "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode" ].forEach(wrapMethod);
+ var originalAdoptNode = document.adoptNode;
+ function adoptNodeNoRemove(node, doc) {
+ originalAdoptNode.call(unsafeUnwrap(doc), unwrap(node));
+ adoptSubtree(node, doc);
+ }
+ function adoptSubtree(node, doc) {
+ if (node.shadowRoot) doc.adoptNode(node.shadowRoot);
+ if (node instanceof ShadowRoot) adoptOlderShadowRoots(node, doc);
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ adoptSubtree(child, doc);
+ }
+ }
+ function adoptOlderShadowRoots(shadowRoot, doc) {
+ var oldShadowRoot = shadowRoot.olderShadowRoot;
+ if (oldShadowRoot) doc.adoptNode(oldShadowRoot);
+ }
+ var originalGetSelection = document.getSelection;
+ mixin(Document.prototype, {
+ adoptNode: function(node) {
+ if (node.parentNode) node.parentNode.removeChild(node);
+ adoptNodeNoRemove(node, this);
+ return node;
+ },
+ elementFromPoint: function(x, y) {
+ return elementFromPoint(this, this, x, y);
+ },
+ importNode: function(node, deep) {
+ return cloneNode(node, deep, unsafeUnwrap(this));
+ },
+ getSelection: function() {
+ renderAllPending();
+ return new Selection(originalGetSelection.call(unwrap(this)));
+ },
+ getElementsByName: function(name) {
+ return SelectorsInterface.querySelectorAll.call(this, "[name=" + JSON.stringify(String(name)) + "]");
+ }
+ });
+ var originalCreateTreeWalker = document.createTreeWalker;
+ var TreeWalkerWrapper = scope.wrappers.TreeWalker;
+ Document.prototype.createTreeWalker = function(root, whatToShow, filter, expandEntityReferences) {
+ var newFilter = null;
+ if (filter) {
+ if (filter.acceptNode && typeof filter.acceptNode === "function") {
+ newFilter = {
+ acceptNode: function(node) {
+ return filter.acceptNode(wrap(node));
+ }
+ };
+ } else if (typeof filter === "function") {
+ newFilter = function(node) {
+ return filter(wrap(node));
+ };
+ }
+ }
+ return new TreeWalkerWrapper(originalCreateTreeWalker.call(unwrap(this), unwrap(root), whatToShow, newFilter, expandEntityReferences));
+ };
+ if (document.registerElement) {
+ var originalRegisterElement = document.registerElement;
+ Document.prototype.registerElement = function(tagName, object) {
+ var prototype, extendsOption;
+ if (object !== undefined) {
+ prototype = object.prototype;
+ extendsOption = object.extends;
+ }
+ if (!prototype) prototype = Object.create(HTMLElement.prototype);
+ if (scope.nativePrototypeTable.get(prototype)) {
+ throw new Error("NotSupportedError");
+ }
+ var proto = Object.getPrototypeOf(prototype);
+ var nativePrototype;
+ var prototypes = [];
+ while (proto) {
+ nativePrototype = scope.nativePrototypeTable.get(proto);
+ if (nativePrototype) break;
+ prototypes.push(proto);
+ proto = Object.getPrototypeOf(proto);
+ }
+ if (!nativePrototype) {
+ throw new Error("NotSupportedError");
+ }
+ var newPrototype = Object.create(nativePrototype);
+ for (var i = prototypes.length - 1; i >= 0; i--) {
+ newPrototype = Object.create(newPrototype);
+ }
+ [ "createdCallback", "attachedCallback", "detachedCallback", "attributeChangedCallback" ].forEach(function(name) {
+ var f = prototype[name];
+ if (!f) return;
+ newPrototype[name] = function() {
+ if (!(wrap(this) instanceof CustomElementConstructor)) {
+ rewrap(this);
+ }
+ f.apply(wrap(this), arguments);
+ };
+ });
+ var p = {
+ prototype: newPrototype
+ };
+ if (extendsOption) p.extends = extendsOption;
+ function CustomElementConstructor(node) {
+ if (!node) {
+ if (extendsOption) {
+ return document.createElement(extendsOption, tagName);
+ } else {
+ return document.createElement(tagName);
+ }
+ }
+ setWrapper(node, this);
+ }
+ CustomElementConstructor.prototype = prototype;
+ CustomElementConstructor.prototype.constructor = CustomElementConstructor;
+ scope.constructorTable.set(newPrototype, CustomElementConstructor);
+ scope.nativePrototypeTable.set(prototype, newPrototype);
+ var nativeConstructor = originalRegisterElement.call(unwrap(this), tagName, p);
+ return CustomElementConstructor;
+ };
+ forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "registerElement" ]);
+ }
+ forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement, window.HTMLHtmlElement ], [ "appendChild", "compareDocumentPosition", "contains", "getElementsByClassName", "getElementsByTagName", "getElementsByTagNameNS", "insertBefore", "querySelector", "querySelectorAll", "removeChild", "replaceChild" ]);
+ forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLHeadElement, window.HTMLHtmlElement ], matchesNames);
+ forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "adoptNode", "importNode", "contains", "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "createTreeWalker", "elementFromPoint", "getElementById", "getElementsByName", "getSelection" ]);
+ mixin(Document.prototype, GetElementsByInterface);
+ mixin(Document.prototype, ParentNodeInterface);
+ mixin(Document.prototype, SelectorsInterface);
+ mixin(Document.prototype, NonElementParentNodeInterface);
+ mixin(Document.prototype, {
+ get implementation() {
+ var implementation = implementationTable.get(this);
+ if (implementation) return implementation;
+ implementation = new DOMImplementation(unwrap(this).implementation);
+ implementationTable.set(this, implementation);
+ return implementation;
+ },
+ get defaultView() {
+ return wrap(unwrap(this).defaultView);
+ }
+ });
+ registerWrapper(window.Document, Document, document.implementation.createHTMLDocument(""));
+ if (window.HTMLDocument) registerWrapper(window.HTMLDocument, Document);
+ wrapEventTargetMethods([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement ]);
+ function DOMImplementation(impl) {
+ setWrapper(impl, this);
+ }
+ var originalCreateDocument = document.implementation.createDocument;
+ DOMImplementation.prototype.createDocument = function() {
+ arguments[2] = unwrap(arguments[2]);
+ return wrap(originalCreateDocument.apply(unsafeUnwrap(this), arguments));
+ };
+ function wrapImplMethod(constructor, name) {
+ var original = document.implementation[name];
+ constructor.prototype[name] = function() {
+ return wrap(original.apply(unsafeUnwrap(this), arguments));
+ };
+ }
+ function forwardImplMethod(constructor, name) {
+ var original = document.implementation[name];
+ constructor.prototype[name] = function() {
+ return original.apply(unsafeUnwrap(this), arguments);
+ };
+ }
+ wrapImplMethod(DOMImplementation, "createDocumentType");
+ wrapImplMethod(DOMImplementation, "createHTMLDocument");
+ forwardImplMethod(DOMImplementation, "hasFeature");
+ registerWrapper(window.DOMImplementation, DOMImplementation);
+ forwardMethodsToWrapper([ window.DOMImplementation ], [ "createDocument", "createDocumentType", "createHTMLDocument", "hasFeature" ]);
+ scope.adoptNodeNoRemove = adoptNodeNoRemove;
+ scope.wrappers.DOMImplementation = DOMImplementation;
+ scope.wrappers.Document = Document;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var EventTarget = scope.wrappers.EventTarget;
+ var Selection = scope.wrappers.Selection;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var renderAllPending = scope.renderAllPending;
+ var unwrap = scope.unwrap;
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var wrap = scope.wrap;
+ var OriginalWindow = window.Window;
+ var originalGetComputedStyle = window.getComputedStyle;
+ var originalGetDefaultComputedStyle = window.getDefaultComputedStyle;
+ var originalGetSelection = window.getSelection;
+ function Window(impl) {
+ EventTarget.call(this, impl);
+ }
+ Window.prototype = Object.create(EventTarget.prototype);
+ OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {
+ return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);
+ };
+ if (originalGetDefaultComputedStyle) {
+ OriginalWindow.prototype.getDefaultComputedStyle = function(el, pseudo) {
+ return wrap(this || window).getDefaultComputedStyle(unwrapIfNeeded(el), pseudo);
+ };
+ }
+ OriginalWindow.prototype.getSelection = function() {
+ return wrap(this || window).getSelection();
+ };
+ delete window.getComputedStyle;
+ delete window.getDefaultComputedStyle;
+ delete window.getSelection;
+ [ "addEventListener", "removeEventListener", "dispatchEvent" ].forEach(function(name) {
+ OriginalWindow.prototype[name] = function() {
+ var w = wrap(this || window);
+ return w[name].apply(w, arguments);
+ };
+ delete window[name];
+ });
+ mixin(Window.prototype, {
+ getComputedStyle: function(el, pseudo) {
+ renderAllPending();
+ return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
+ },
+ getSelection: function() {
+ renderAllPending();
+ return new Selection(originalGetSelection.call(unwrap(this)));
+ },
+ get document() {
+ return wrap(unwrap(this).document);
+ }
+ });
+ if (originalGetDefaultComputedStyle) {
+ Window.prototype.getDefaultComputedStyle = function(el, pseudo) {
+ renderAllPending();
+ return originalGetDefaultComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
+ };
+ }
+ registerWrapper(OriginalWindow, Window, window);
+ scope.wrappers.Window = Window;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var unwrap = scope.unwrap;
+ var OriginalDataTransfer = window.DataTransfer || window.Clipboard;
+ var OriginalDataTransferSetDragImage = OriginalDataTransfer.prototype.setDragImage;
+ if (OriginalDataTransferSetDragImage) {
+ OriginalDataTransfer.prototype.setDragImage = function(image, x, y) {
+ OriginalDataTransferSetDragImage.call(this, unwrap(image), x, y);
+ };
+ }
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unwrap = scope.unwrap;
+ var OriginalFormData = window.FormData;
+ if (!OriginalFormData) return;
+ function FormData(formElement) {
+ var impl;
+ if (formElement instanceof OriginalFormData) {
+ impl = formElement;
+ } else {
+ impl = new OriginalFormData(formElement && unwrap(formElement));
+ }
+ setWrapper(impl, this);
+ }
+ registerWrapper(OriginalFormData, FormData, new OriginalFormData());
+ scope.wrappers.FormData = FormData;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var originalSend = XMLHttpRequest.prototype.send;
+ XMLHttpRequest.prototype.send = function(obj) {
+ return originalSend.call(this, unwrapIfNeeded(obj));
+ };
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+ "use strict";
+ var isWrapperFor = scope.isWrapperFor;
+ var elements = {
+ a: "HTMLAnchorElement",
+ area: "HTMLAreaElement",
+ audio: "HTMLAudioElement",
+ base: "HTMLBaseElement",
+ body: "HTMLBodyElement",
+ br: "HTMLBRElement",
+ button: "HTMLButtonElement",
+ canvas: "HTMLCanvasElement",
+ caption: "HTMLTableCaptionElement",
+ col: "HTMLTableColElement",
+ content: "HTMLContentElement",
+ data: "HTMLDataElement",
+ datalist: "HTMLDataListElement",
+ del: "HTMLModElement",
+ dir: "HTMLDirectoryElement",
+ div: "HTMLDivElement",
+ dl: "HTMLDListElement",
+ embed: "HTMLEmbedElement",
+ fieldset: "HTMLFieldSetElement",
+ font: "HTMLFontElement",
+ form: "HTMLFormElement",
+ frame: "HTMLFrameElement",
+ frameset: "HTMLFrameSetElement",
+ h1: "HTMLHeadingElement",
+ head: "HTMLHeadElement",
+ hr: "HTMLHRElement",
+ html: "HTMLHtmlElement",
+ iframe: "HTMLIFrameElement",
+ img: "HTMLImageElement",
+ input: "HTMLInputElement",
+ keygen: "HTMLKeygenElement",
+ label: "HTMLLabelElement",
+ legend: "HTMLLegendElement",
+ li: "HTMLLIElement",
+ link: "HTMLLinkElement",
+ map: "HTMLMapElement",
+ marquee: "HTMLMarqueeElement",
+ menu: "HTMLMenuElement",
+ menuitem: "HTMLMenuItemElement",
+ meta: "HTMLMetaElement",
+ meter: "HTMLMeterElement",
+ object: "HTMLObjectElement",
+ ol: "HTMLOListElement",
+ optgroup: "HTMLOptGroupElement",
+ option: "HTMLOptionElement",
+ output: "HTMLOutputElement",
+ p: "HTMLParagraphElement",
+ param: "HTMLParamElement",
+ pre: "HTMLPreElement",
+ progress: "HTMLProgressElement",
+ q: "HTMLQuoteElement",
+ script: "HTMLScriptElement",
+ select: "HTMLSelectElement",
+ shadow: "HTMLShadowElement",
+ source: "HTMLSourceElement",
+ span: "HTMLSpanElement",
+ style: "HTMLStyleElement",
+ table: "HTMLTableElement",
+ tbody: "HTMLTableSectionElement",
+ template: "HTMLTemplateElement",
+ textarea: "HTMLTextAreaElement",
+ thead: "HTMLTableSectionElement",
+ time: "HTMLTimeElement",
+ title: "HTMLTitleElement",
+ tr: "HTMLTableRowElement",
+ track: "HTMLTrackElement",
+ ul: "HTMLUListElement",
+ video: "HTMLVideoElement"
+ };
+ function overrideConstructor(tagName) {
+ var nativeConstructorName = elements[tagName];
+ var nativeConstructor = window[nativeConstructorName];
+ if (!nativeConstructor) return;
+ var element = document.createElement(tagName);
+ var wrapperConstructor = element.constructor;
+ window[nativeConstructorName] = wrapperConstructor;
+ }
+ Object.keys(elements).forEach(overrideConstructor);
+ Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {
+ window[name] = scope.wrappers[name];
+ });
+})(window.ShadowDOMPolyfill);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/ShadowDOM.min.js b/polymer_1.0.4/bower_components/webcomponentsjs/ShadowDOM.min.js
new file mode 100644
index 0000000..1380d54
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/ShadowDOM.min.js
@@ -0,0 +1,15 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.7.5
+"undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,n=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};n.prototype={set:function(t,n){var r=t[this.name];return r&&r[0]===t?r[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),window.ShadowDOMPolyfill={},function(e){"use strict";function t(){if("undefined"!=typeof chrome&&chrome.app&&chrome.app.runtime)return!1;if(navigator.getDeviceStorage)return!1;try{var e=new Function("return true;");return e()}catch(t){return!1}}function n(e){if(!e)throw new Error("Assertion failed")}function r(e,t){for(var n=k(t),r=0;r<n.length;r++){var o=n[r];A(e,o,F(t,o))}return e}function o(e,t){for(var n=k(t),r=0;r<n.length;r++){var o=n[r];switch(o){case"arguments":case"caller":case"length":case"name":case"prototype":case"toString":continue}A(e,o,F(t,o))}return e}function i(e,t){for(var n=0;n<t.length;n++)if(t[n]in e)return t[n]}function a(e,t,n){B.value=n,A(e,t,B)}function s(e,t){var n=e.__proto__||Object.getPrototypeOf(e);if(U)try{k(n)}catch(r){n=n.__proto__}var o=R.get(n);if(o)return o;var i=s(n),a=E(i);return v(n,a,t),a}function c(e,t){m(e,t,!0)}function u(e,t){m(t,e,!1)}function l(e){return/^on[a-z]+$/.test(e)}function p(e){return/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(e)}function d(e){return I&&p(e)?new Function("return this.__impl4cf1e782hg__."+e):function(){return this.__impl4cf1e782hg__[e]}}function f(e){return I&&p(e)?new Function("v","this.__impl4cf1e782hg__."+e+" = v"):function(t){this.__impl4cf1e782hg__[e]=t}}function h(e){return I&&p(e)?new Function("return this.__impl4cf1e782hg__."+e+".apply(this.__impl4cf1e782hg__, arguments)"):function(){return this.__impl4cf1e782hg__[e].apply(this.__impl4cf1e782hg__,arguments)}}function w(e,t){try{return Object.getOwnPropertyDescriptor(e,t)}catch(n){return q}}function m(t,n,r,o){for(var i=k(t),a=0;a<i.length;a++){var s=i[a];if("polymerBlackList_"!==s&&!(s in n||t.polymerBlackList_&&t.polymerBlackList_[s])){U&&t.__lookupGetter__(s);var c,u,p=w(t,s);if("function"!=typeof p.value){var m=l(s);c=m?e.getEventHandlerGetter(s):d(s),(p.writable||p.set||V)&&(u=m?e.getEventHandlerSetter(s):f(s));var g=V||p.configurable;A(n,s,{get:c,set:u,configurable:g,enumerable:p.enumerable})}else r&&(n[s]=h(s))}}}function g(e,t,n){if(null!=e){var r=e.prototype;v(r,t,n),o(t,e)}}function v(e,t,r){var o=t.prototype;n(void 0===R.get(e)),R.set(e,t),P.set(o,e),c(e,o),r&&u(o,r),a(o,"constructor",t),t.prototype=o}function b(e,t){return R.get(t.prototype)===e}function y(e){var t=Object.getPrototypeOf(e),n=s(t),r=E(n);return v(t,r,e),r}function E(e){function t(t){e.call(this,t)}var n=Object.create(e.prototype);return n.constructor=t,t.prototype=n,t}function S(e){return e&&e.__impl4cf1e782hg__}function M(e){return!S(e)}function T(e){if(null===e)return null;n(M(e));var t=e.__wrapper8e3dd93a60__;return null!=t?t:e.__wrapper8e3dd93a60__=new(s(e,e))(e)}function O(e){return null===e?null:(n(S(e)),e.__impl4cf1e782hg__)}function N(e){return e.__impl4cf1e782hg__}function j(e,t){t.__impl4cf1e782hg__=e,e.__wrapper8e3dd93a60__=t}function L(e){return e&&S(e)?O(e):e}function _(e){return e&&!S(e)?T(e):e}function C(e,t){null!==t&&(n(M(e)),n(void 0===t||S(t)),e.__wrapper8e3dd93a60__=t)}function D(e,t,n){G.get=n,A(e.prototype,t,G)}function H(e,t){D(e,t,function(){return T(this.__impl4cf1e782hg__[t])})}function x(e,t){e.forEach(function(e){t.forEach(function(t){e.prototype[t]=function(){var e=_(this);return e[t].apply(e,arguments)}})})}var R=new WeakMap,P=new WeakMap,W=Object.create(null),I=t(),A=Object.defineProperty,k=Object.getOwnPropertyNames,F=Object.getOwnPropertyDescriptor,B={value:void 0,configurable:!0,enumerable:!1,writable:!0};k(window);var U=/Firefox/.test(navigator.userAgent),q={get:function(){},set:function(e){},configurable:!0,enumerable:!0},V=function(){var e=Object.getOwnPropertyDescriptor(Node.prototype,"nodeType");return e&&!e.get&&!e.set}(),G={get:void 0,configurable:!0,enumerable:!0};e.assert=n,e.constructorTable=R,e.defineGetter=D,e.defineWrapGetter=H,e.forwardMethodsToWrapper=x,e.isIdentifierName=p,e.isWrapper=S,e.isWrapperFor=b,e.mixin=r,e.nativePrototypeTable=P,e.oneOf=i,e.registerObject=y,e.registerWrapper=g,e.rewrap=C,e.setWrapper=j,e.unsafeUnwrap=N,e.unwrap=O,e.unwrapIfNeeded=L,e.wrap=T,e.wrapIfNeeded=_,e.wrappers=W}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e,t,n){return{index:e,removed:t,addedCount:n}}function n(){}var r=0,o=1,i=2,a=3;n.prototype={calcEditDistances:function(e,t,n,r,o,i){for(var a=i-o+1,s=n-t+1,c=new Array(a),u=0;a>u;u++)c[u]=new Array(s),c[u][0]=u;for(var l=0;s>l;l++)c[0][l]=l;for(var u=1;a>u;u++)for(var l=1;s>l;l++)if(this.equals(e[t+l-1],r[o+u-1]))c[u][l]=c[u-1][l-1];else{var p=c[u-1][l]+1,d=c[u][l-1]+1;c[u][l]=d>p?p:d}return c},spliceOperationsFromEditDistances:function(e){for(var t=e.length-1,n=e[0].length-1,s=e[t][n],c=[];t>0||n>0;)if(0!=t)if(0!=n){var u,l=e[t-1][n-1],p=e[t-1][n],d=e[t][n-1];u=d>p?l>p?p:l:l>d?d:l,u==l?(l==s?c.push(r):(c.push(o),s=l),t--,n--):u==p?(c.push(a),t--,s=p):(c.push(i),n--,s=d)}else c.push(a),t--;else c.push(i),n--;return c.reverse(),c},calcSplices:function(e,n,s,c,u,l){var p=0,d=0,f=Math.min(s-n,l-u);if(0==n&&0==u&&(p=this.sharedPrefix(e,c,f)),s==e.length&&l==c.length&&(d=this.sharedSuffix(e,c,f-p)),n+=p,u+=p,s-=d,l-=d,s-n==0&&l-u==0)return[];if(n==s){for(var h=t(n,[],0);l>u;)h.removed.push(c[u++]);return[h]}if(u==l)return[t(n,[],s-n)];for(var w=this.spliceOperationsFromEditDistances(this.calcEditDistances(e,n,s,c,u,l)),h=void 0,m=[],g=n,v=u,b=0;b<w.length;b++)switch(w[b]){case r:h&&(m.push(h),h=void 0),g++,v++;break;case o:h||(h=t(g,[],0)),h.addedCount++,g++,h.removed.push(c[v]),v++;break;case i:h||(h=t(g,[],0)),h.addedCount++,g++;break;case a:h||(h=t(g,[],0)),h.removed.push(c[v]),v++}return h&&m.push(h),m},sharedPrefix:function(e,t,n){for(var r=0;n>r;r++)if(!this.equals(e[r],t[r]))return r;return n},sharedSuffix:function(e,t,n){for(var r=e.length,o=t.length,i=0;n>i&&this.equals(e[--r],t[--o]);)i++;return i},calculateSplices:function(e,t){return this.calcSplices(e,0,e.length,t,0,t.length)},equals:function(e,t){return e===t}},e.ArraySplice=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(){a=!1;var e=i.slice(0);i=[];for(var t=0;t<e.length;t++)e[t]()}function n(e){i.push(e),a||(a=!0,r(t,0))}var r,o=window.MutationObserver,i=[],a=!1;if(o){var s=1,c=new o(t),u=document.createTextNode(s);c.observe(u,{characterData:!0}),r=function(){s=(s+1)%2,u.data=s}}else r=window.setTimeout;e.setEndOfMicrotask=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){e.scheduled_||(e.scheduled_=!0,h.push(e),w||(l(n),w=!0))}function n(){for(w=!1;h.length;){var e=h;h=[],e.sort(function(e,t){return e.uid_-t.uid_});for(var t=0;t<e.length;t++){var n=e[t];n.scheduled_=!1;var r=n.takeRecords();i(n),r.length&&n.callback_(r,n)}}}function r(e,t){this.type=e,this.target=t,this.addedNodes=new d.NodeList,this.removedNodes=new d.NodeList,this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function o(e,t){for(;e;e=e.parentNode){var n=f.get(e);if(n)for(var r=0;r<n.length;r++){var o=n[r];o.options.subtree&&o.addTransientObserver(t)}}}function i(e){for(var t=0;t<e.nodes_.length;t++){var n=e.nodes_[t],r=f.get(n);if(!r)return;for(var o=0;o<r.length;o++){var i=r[o];i.observer===e&&i.removeTransientObservers()}}}function a(e,n,o){for(var i=Object.create(null),a=Object.create(null),s=e;s;s=s.parentNode){var c=f.get(s);if(c)for(var u=0;u<c.length;u++){var l=c[u],p=l.options;if((s===e||p.subtree)&&!("attributes"===n&&!p.attributes||"attributes"===n&&p.attributeFilter&&(null!==o.namespace||-1===p.attributeFilter.indexOf(o.name))||"characterData"===n&&!p.characterData||"childList"===n&&!p.childList)){var d=l.observer;i[d.uid_]=d,("attributes"===n&&p.attributeOldValue||"characterData"===n&&p.characterDataOldValue)&&(a[d.uid_]=o.oldValue)}}}for(var h in i){var d=i[h],w=new r(n,e);"name"in o&&"namespace"in o&&(w.attributeName=o.name,w.attributeNamespace=o.namespace),o.addedNodes&&(w.addedNodes=o.addedNodes),o.removedNodes&&(w.removedNodes=o.removedNodes),o.previousSibling&&(w.previousSibling=o.previousSibling),o.nextSibling&&(w.nextSibling=o.nextSibling),void 0!==a[h]&&(w.oldValue=a[h]),t(d),d.records_.push(w)}}function s(e){if(this.childList=!!e.childList,this.subtree=!!e.subtree,this.attributes="attributes"in e||!("attributeOldValue"in e||"attributeFilter"in e)?!!e.attributes:!0,this.characterData="characterDataOldValue"in e&&!("characterData"in e)?!0:!!e.characterData,!this.attributes&&(e.attributeOldValue||"attributeFilter"in e)||!this.characterData&&e.characterDataOldValue)throw new TypeError;if(this.characterData=!!e.characterData,this.attributeOldValue=!!e.attributeOldValue,this.characterDataOldValue=!!e.characterDataOldValue,"attributeFilter"in e){if(null==e.attributeFilter||"object"!=typeof e.attributeFilter)throw new TypeError;this.attributeFilter=m.call(e.attributeFilter)}else this.attributeFilter=null}function c(e){this.callback_=e,this.nodes_=[],this.records_=[],this.uid_=++g,this.scheduled_=!1}function u(e,t,n){this.observer=e,this.target=t,this.options=n,this.transientObservedNodes=[]}var l=e.setEndOfMicrotask,p=e.wrapIfNeeded,d=e.wrappers,f=new WeakMap,h=[],w=!1,m=Array.prototype.slice,g=0;c.prototype={constructor:c,observe:function(e,t){e=p(e);var n,r=new s(t),o=f.get(e);o||f.set(e,o=[]);for(var i=0;i<o.length;i++)o[i].observer===this&&(n=o[i],n.removeTransientObservers(),n.options=r);n||(n=new u(this,e,r),o.push(n),this.nodes_.push(e))},disconnect:function(){this.nodes_.forEach(function(e){for(var t=f.get(e),n=0;n<t.length;n++){var r=t[n];if(r.observer===this){t.splice(n,1);break}}},this),this.records_=[]},takeRecords:function(){var e=this.records_;return this.records_=[],e}},u.prototype={addTransientObserver:function(e){if(e!==this.target){t(this.observer),this.transientObservedNodes.push(e);var n=f.get(e);n||f.set(e,n=[]),n.push(this)}},removeTransientObservers:function(){var e=this.transientObservedNodes;this.transientObservedNodes=[];for(var t=0;t<e.length;t++)for(var n=e[t],r=f.get(n),o=0;o<r.length;o++)if(r[o]===this){r.splice(o,1);break}}},e.enqueueMutation=a,e.registerTransientObservers=o,e.wrappers.MutationObserver=c,e.wrappers.MutationRecord=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e,t){this.root=e,this.parent=t}function n(e,t){if(e.treeScope_!==t){e.treeScope_=t;for(var r=e.shadowRoot;r;r=r.olderShadowRoot)r.treeScope_.parent=t;for(var o=e.firstChild;o;o=o.nextSibling)n(o,t)}}function r(n){if(n instanceof e.wrappers.Window,n.treeScope_)return n.treeScope_;var o,i=n.parentNode;return o=i?r(i):new t(n,null),n.treeScope_=o}t.prototype={get renderer(){return this.root instanceof e.wrappers.ShadowRoot?e.getRendererForHost(this.root.host):null},contains:function(e){for(;e;e=e.parent)if(e===this)return!0;return!1}},e.TreeScope=t,e.getTreeScope=r,e.setTreeScope=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return e instanceof G.ShadowRoot}function n(e){return A(e).root}function r(e,r){var s=[],c=e;for(s.push(c);c;){var u=a(c);if(u&&u.length>0){for(var l=0;l<u.length;l++){var d=u[l];if(i(d)){var f=n(d),h=f.olderShadowRoot;h&&s.push(h)}s.push(d)}c=u[u.length-1]}else if(t(c)){if(p(e,c)&&o(r))break;c=c.host,s.push(c)}else c=c.parentNode,c&&s.push(c)}return s}function o(e){if(!e)return!1;switch(e.type){case"abort":case"error":case"select":case"change":case"load":case"reset":case"resize":case"scroll":case"selectstart":return!0}return!1}function i(e){return e instanceof HTMLShadowElement}function a(t){return e.getDestinationInsertionPoints(t)}function s(e,t){if(0===e.length)return t;t instanceof G.Window&&(t=t.document);for(var n=A(t),r=e[0],o=A(r),i=u(n,o),a=0;a<e.length;a++){var s=e[a];if(A(s)===i)return s}return e[e.length-1]}function c(e){for(var t=[];e;e=e.parent)t.push(e);return t}function u(e,t){for(var n=c(e),r=c(t),o=null;n.length>0&&r.length>0;){var i=n.pop(),a=r.pop();if(i!==a)break;o=i}return o}function l(e,t,n){t instanceof G.Window&&(t=t.document);var o,i=A(t),a=A(n),s=r(n,e),o=u(i,a);o||(o=a.root);for(var c=o;c;c=c.parent)for(var l=0;l<s.length;l++){var p=s[l];if(A(p)===c)return p}return null}function p(e,t){return A(e)===A(t)}function d(e){if(!X.get(e)&&(X.set(e,!0),h(V(e),V(e.target)),W)){var t=W;throw W=null,t}}function f(e){switch(e.type){case"load":case"beforeunload":case"unload":return!0}return!1}function h(t,n){if(K.get(t))throw new Error("InvalidStateError");K.set(t,!0),e.renderAllPending();var o,i,a;if(f(t)&&!t.bubbles){var s=n;s instanceof G.Document&&(a=s.defaultView)&&(i=s,o=[])}if(!o)if(n instanceof G.Window)a=n,o=[];else if(o=r(n,t),!f(t)){var s=o[o.length-1];s instanceof G.Document&&(a=s.defaultView)}return ne.set(t,o),w(t,o,a,i)&&m(t,o,a,i)&&g(t,o,a,i),J.set(t,re),$["delete"](t,null),K["delete"](t),t.defaultPrevented}function w(e,t,n,r){var o=oe;if(n&&!v(n,e,o,t,r))return!1;for(var i=t.length-1;i>0;i--)if(!v(t[i],e,o,t,r))return!1;return!0}function m(e,t,n,r){var o=ie,i=t[0]||n;return v(i,e,o,t,r)}function g(e,t,n,r){for(var o=ae,i=1;i<t.length;i++)if(!v(t[i],e,o,t,r))return;n&&t.length>0&&v(n,e,o,t,r)}function v(e,t,n,r,o){var i=z.get(e);if(!i)return!0;var a=o||s(r,e);if(a===e){if(n===oe)return!0;n===ae&&(n=ie)}else if(n===ae&&!t.bubbles)return!0;if("relatedTarget"in t){var c=q(t),u=c.relatedTarget;if(u){if(u instanceof Object&&u.addEventListener){var p=V(u),d=l(t,e,p);if(d===a)return!0}else d=null;Z.set(t,d)}}J.set(t,n);var f=t.type,h=!1;Y.set(t,a),$.set(t,e),i.depth++;for(var w=0,m=i.length;m>w;w++){var g=i[w];if(g.removed)h=!0;else if(!(g.type!==f||!g.capture&&n===oe||g.capture&&n===ae))try{if("function"==typeof g.handler?g.handler.call(e,t):g.handler.handleEvent(t),ee.get(t))return!1}catch(v){W||(W=v)}}if(i.depth--,h&&0===i.depth){var b=i.slice();i.length=0;for(var w=0;w<b.length;w++)b[w].removed||i.push(b[w])}return!Q.get(t)}function b(e,t,n){this.type=e,this.handler=t,this.capture=Boolean(n)}function y(e,t){if(!(e instanceof se))return V(T(se,"Event",e,t));var n=e;return ve||"beforeunload"!==n.type||this instanceof O?void B(n,this):new O(n)}function E(e){return e&&e.relatedTarget?Object.create(e,{relatedTarget:{value:q(e.relatedTarget)}}):e}function S(e,t,n){var r=window[e],o=function(t,n){return t instanceof r?void B(t,this):V(T(r,e,t,n))};if(o.prototype=Object.create(t.prototype),n&&k(o.prototype,n),r)try{F(r,o,new r("temp"))}catch(i){F(r,o,document.createEvent(e))}return o}function M(e,t){return function(){arguments[t]=q(arguments[t]);var n=q(this);n[e].apply(n,arguments)}}function T(e,t,n,r){if(me)return new e(n,E(r));var o=q(document.createEvent(t)),i=we[t],a=[n];return Object.keys(i).forEach(function(e){var t=null!=r&&e in r?r[e]:i[e];"relatedTarget"===e&&(t=q(t)),a.push(t)}),o["init"+t].apply(o,a),o}function O(e){y.call(this,e)}function N(e){return"function"==typeof e?!0:e&&e.handleEvent}function j(e){switch(e){case"DOMAttrModified":case"DOMAttributeNameChanged":case"DOMCharacterDataModified":case"DOMElementNameChanged":case"DOMNodeInserted":case"DOMNodeInsertedIntoDocument":case"DOMNodeRemoved":case"DOMNodeRemovedFromDocument":case"DOMSubtreeModified":return!0}return!1}function L(e){B(e,this)}function _(e){return e instanceof G.ShadowRoot&&(e=e.host),q(e)}function C(e,t){var n=z.get(e);if(n)for(var r=0;r<n.length;r++)if(!n[r].removed&&n[r].type===t)return!0;return!1}function D(e,t){for(var n=q(e);n;n=n.parentNode)if(C(V(n),t))return!0;return!1}function H(e){I(e,ye)}function x(t,n,o,i){e.renderAllPending();var a=V(Ee.call(U(n),o,i));if(!a)return null;var c=r(a,null),u=c.lastIndexOf(t);return-1==u?null:(c=c.slice(0,u),s(c,t))}function R(e){return function(){var t=te.get(this);return t&&t[e]&&t[e].value||null}}function P(e){var t=e.slice(2);return function(n){var r=te.get(this);r||(r=Object.create(null),te.set(this,r));var o=r[e];if(o&&this.removeEventListener(t,o.wrapped,!1),"function"==typeof n){var i=function(t){var r=n.call(this,t);r===!1?t.preventDefault():"onbeforeunload"===e&&"string"==typeof r&&(t.returnValue=r)};this.addEventListener(t,i,!1),r[e]={value:n,wrapped:i}}}}var W,I=e.forwardMethodsToWrapper,A=e.getTreeScope,k=e.mixin,F=e.registerWrapper,B=e.setWrapper,U=e.unsafeUnwrap,q=e.unwrap,V=e.wrap,G=e.wrappers,z=(new WeakMap,new WeakMap),X=new WeakMap,K=new WeakMap,Y=new WeakMap,$=new WeakMap,Z=new WeakMap,J=new WeakMap,Q=new WeakMap,ee=new WeakMap,te=new WeakMap,ne=new WeakMap,re=0,oe=1,ie=2,ae=3;b.prototype={equals:function(e){return this.handler===e.handler&&this.type===e.type&&this.capture===e.capture},get removed(){return null===this.handler},remove:function(){this.handler=null}};var se=window.Event;se.prototype.polymerBlackList_={returnValue:!0,keyLocation:!0},y.prototype={get target(){return Y.get(this)},get currentTarget(){return $.get(this)},get eventPhase(){return J.get(this)},get path(){var e=ne.get(this);return e?e.slice():[]},stopPropagation:function(){Q.set(this,!0)},stopImmediatePropagation:function(){Q.set(this,!0),ee.set(this,!0)}},F(se,y,document.createEvent("Event"));var ce=S("UIEvent",y),ue=S("CustomEvent",y),le={get relatedTarget(){var e=Z.get(this);return void 0!==e?e:V(q(this).relatedTarget)}},pe=k({initMouseEvent:M("initMouseEvent",14)},le),de=k({initFocusEvent:M("initFocusEvent",5)},le),fe=S("MouseEvent",ce,pe),he=S("FocusEvent",ce,de),we=Object.create(null),me=function(){try{new window.FocusEvent("focus")}catch(e){return!1}return!0}();if(!me){var ge=function(e,t,n){if(n){var r=we[n];t=k(k({},r),t)}we[e]=t};ge("Event",{bubbles:!1,cancelable:!1}),ge("CustomEvent",{detail:null},"Event"),ge("UIEvent",{view:null,detail:0},"Event"),ge("MouseEvent",{screenX:0,screenY:0,clientX:0,clientY:0,ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1,button:0,relatedTarget:null},"UIEvent"),ge("FocusEvent",{relatedTarget:null},"UIEvent")}var ve=window.BeforeUnloadEvent;O.prototype=Object.create(y.prototype),k(O.prototype,{get returnValue(){return U(this).returnValue},set returnValue(e){U(this).returnValue=e}}),ve&&F(ve,O);var be=window.EventTarget,ye=["addEventListener","removeEventListener","dispatchEvent"];[Node,Window].forEach(function(e){var t=e.prototype;ye.forEach(function(e){Object.defineProperty(t,e+"_",{value:t[e]})})}),L.prototype={addEventListener:function(e,t,n){if(N(t)&&!j(e)){var r=new b(e,t,n),o=z.get(this);if(o){for(var i=0;i<o.length;i++)if(r.equals(o[i]))return}else o=[],o.depth=0,z.set(this,o);o.push(r);var a=_(this);a.addEventListener_(e,d,!0)}},removeEventListener:function(e,t,n){n=Boolean(n);var r=z.get(this);if(r){for(var o=0,i=!1,a=0;a<r.length;a++)r[a].type===e&&r[a].capture===n&&(o++,r[a].handler===t&&(i=!0,r[a].remove()));if(i&&1===o){var s=_(this);s.removeEventListener_(e,d,!0)}}},dispatchEvent:function(t){var n=q(t),r=n.type;X.set(n,!1),e.renderAllPending();var o;D(this,r)||(o=function(){},this.addEventListener(r,o,!0));try{return q(this).dispatchEvent_(n)}finally{o&&this.removeEventListener(r,o,!0)}}},be&&F(be,L);var Ee=document.elementFromPoint;e.elementFromPoint=x,e.getEventHandlerGetter=R,e.getEventHandlerSetter=P,e.wrapEventTargetMethods=H,e.wrappers.BeforeUnloadEvent=O,e.wrappers.CustomEvent=ue,e.wrappers.Event=y,e.wrappers.EventTarget=L,e.wrappers.FocusEvent=he,e.wrappers.MouseEvent=fe,e.wrappers.UIEvent=ce}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e,t){Object.defineProperty(e,t,w)}function n(e){u(e,this)}function r(){this.length=0,t(this,"length")}function o(e){for(var t=new r,o=0;o<e.length;o++)t[o]=new n(e[o]);return t.length=o,t}function i(e){a.call(this,e)}var a=e.wrappers.UIEvent,s=e.mixin,c=e.registerWrapper,u=e.setWrapper,l=e.unsafeUnwrap,p=e.wrap,d=window.TouchEvent;if(d){var f;try{f=document.createEvent("TouchEvent")}catch(h){return}var w={enumerable:!1};n.prototype={get target(){return p(l(this).target)}};var m={configurable:!0,enumerable:!0,get:null};["clientX","clientY","screenX","screenY","pageX","pageY","identifier","webkitRadiusX","webkitRadiusY","webkitRotationAngle","webkitForce"].forEach(function(e){m.get=function(){return l(this)[e]},Object.defineProperty(n.prototype,e,m)}),r.prototype={item:function(e){return this[e]}},i.prototype=Object.create(a.prototype),s(i.prototype,{get touches(){return o(l(this).touches)},get targetTouches(){return o(l(this).targetTouches)},get changedTouches(){return o(l(this).changedTouches)},initTouchEvent:function(){throw new Error("Not implemented")}}),c(d,i,f),e.wrappers.Touch=n,e.wrappers.TouchEvent=i,e.wrappers.TouchList=r}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e,t){Object.defineProperty(e,t,s)}function n(){this.length=0,t(this,"length")}function r(e){if(null==e)return e;for(var t=new n,r=0,o=e.length;o>r;r++)t[r]=a(e[r]);return t.length=o,t}function o(e,t){e.prototype[t]=function(){return r(i(this)[t].apply(i(this),arguments))}}var i=e.unsafeUnwrap,a=e.wrap,s={enumerable:!1};n.prototype={item:function(e){return this[e]}},t(n.prototype,"item"),e.wrappers.NodeList=n,e.addWrapNodeListMethod=o,e.wrapNodeList=r}(window.ShadowDOMPolyfill),function(e){"use strict";e.wrapHTMLCollection=e.wrapNodeList,e.wrappers.HTMLCollection=e.wrappers.NodeList}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){N(e instanceof S)}function n(e){var t=new T;return t[0]=e,t.length=1,t}function r(e,t,n){L(t,"childList",{removedNodes:n,previousSibling:e.previousSibling,nextSibling:e.nextSibling})}function o(e,t){L(e,"childList",{removedNodes:t})}function i(e,t,r,o){if(e instanceof DocumentFragment){var i=s(e);B=!0;for(var a=i.length-1;a>=0;a--)e.removeChild(i[a]),i[a].parentNode_=t;B=!1;for(var a=0;a<i.length;a++)i[a].previousSibling_=i[a-1]||r,i[a].nextSibling_=i[a+1]||o;return r&&(r.nextSibling_=i[0]),o&&(o.previousSibling_=i[i.length-1]),i}var i=n(e),c=e.parentNode;return c&&c.removeChild(e),e.parentNode_=t,e.previousSibling_=r,e.nextSibling_=o,r&&(r.nextSibling_=e),o&&(o.previousSibling_=e),i}function a(e){if(e instanceof DocumentFragment)return s(e);var t=n(e),o=e.parentNode;return o&&r(e,o,t),t}function s(e){for(var t=new T,n=0,r=e.firstChild;r;r=r.nextSibling)t[n++]=r;return t.length=n,o(e,t),t}function c(e){return e}function u(e,t){R(e,t),e.nodeIsInserted_()}function l(e,t){for(var n=_(t),r=0;r<e.length;r++)u(e[r],n)}function p(e){R(e,new O(e,null))}function d(e){for(var t=0;t<e.length;t++)p(e[t])}function f(e,t){var n=e.nodeType===S.DOCUMENT_NODE?e:e.ownerDocument;n!==t.ownerDocument&&n.adoptNode(t)}function h(t,n){if(n.length){var r=t.ownerDocument;if(r!==n[0].ownerDocument)for(var o=0;o<n.length;o++)e.adoptNodeNoRemove(n[o],r)}}function w(e,t){h(e,t);var n=t.length;if(1===n)return W(t[0]);for(var r=W(e.ownerDocument.createDocumentFragment()),o=0;n>o;o++)r.appendChild(W(t[o]));return r}function m(e){if(void 0!==e.firstChild_)for(var t=e.firstChild_;t;){var n=t;t=t.nextSibling_,n.parentNode_=n.previousSibling_=n.nextSibling_=void 0}e.firstChild_=e.lastChild_=void 0}function g(e){if(e.invalidateShadowRenderer()){for(var t=e.firstChild;t;){N(t.parentNode===e);var n=t.nextSibling,r=W(t),o=r.parentNode;o&&Y.call(o,r),t.previousSibling_=t.nextSibling_=t.parentNode_=null,t=n}e.firstChild_=e.lastChild_=null}else for(var n,i=W(e),a=i.firstChild;a;)n=a.nextSibling,Y.call(i,a),a=n}function v(e){var t=e.parentNode;return t&&t.invalidateShadowRenderer()}function b(e){for(var t,n=0;n<e.length;n++)t=e[n],t.parentNode.removeChild(t)}function y(e,t,n){var r;if(r=A(n?U.call(n,P(e),!1):q.call(P(e),!1)),t){for(var o=e.firstChild;o;o=o.nextSibling)r.appendChild(y(o,!0,n));if(e instanceof F.HTMLTemplateElement)for(var i=r.content,o=e.content.firstChild;o;o=o.nextSibling)i.appendChild(y(o,!0,n))}return r}function E(e,t){if(!t||_(e)!==_(t))return!1;for(var n=t;n;n=n.parentNode)if(n===e)return!0;return!1}function S(e){N(e instanceof V),M.call(this,e),this.parentNode_=void 0,this.firstChild_=void 0,this.lastChild_=void 0,this.nextSibling_=void 0,this.previousSibling_=void 0,this.treeScope_=void 0}var M=e.wrappers.EventTarget,T=e.wrappers.NodeList,O=e.TreeScope,N=e.assert,j=e.defineWrapGetter,L=e.enqueueMutation,_=e.getTreeScope,C=e.isWrapper,D=e.mixin,H=e.registerTransientObservers,x=e.registerWrapper,R=e.setTreeScope,P=e.unsafeUnwrap,W=e.unwrap,I=e.unwrapIfNeeded,A=e.wrap,k=e.wrapIfNeeded,F=e.wrappers,B=!1,U=document.importNode,q=window.Node.prototype.cloneNode,V=window.Node,G=window.DocumentFragment,z=(V.prototype.appendChild,V.prototype.compareDocumentPosition),X=V.prototype.isEqualNode,K=V.prototype.insertBefore,Y=V.prototype.removeChild,$=V.prototype.replaceChild,Z=/Trident|Edge/.test(navigator.userAgent),J=Z?function(e,t){try{Y.call(e,t)}catch(n){if(!(e instanceof G))throw n}}:function(e,t){Y.call(e,t)};S.prototype=Object.create(M.prototype),D(S.prototype,{appendChild:function(e){return this.insertBefore(e,null)},insertBefore:function(e,n){t(e);var r;n?C(n)?r=W(n):(r=n,n=A(r)):(n=null,r=null),n&&N(n.parentNode===this);var o,s=n?n.previousSibling:this.lastChild,c=!this.invalidateShadowRenderer()&&!v(e);if(o=c?a(e):i(e,this,s,n),c)f(this,e),m(this),K.call(P(this),W(e),r);else{s||(this.firstChild_=o[0]),n||(this.lastChild_=o[o.length-1],void 0===this.firstChild_&&(this.firstChild_=this.firstChild));var u=r?r.parentNode:P(this);u?K.call(u,w(this,o),r):h(this,o)}return L(this,"childList",{addedNodes:o,nextSibling:n,previousSibling:s}),l(o,this),e},removeChild:function(e){if(t(e),e.parentNode!==this){for(var r=!1,o=(this.childNodes,this.firstChild);o;o=o.nextSibling)if(o===e){r=!0;break}if(!r)throw new Error("NotFoundError")}var i=W(e),a=e.nextSibling,s=e.previousSibling;if(this.invalidateShadowRenderer()){var c=this.firstChild,u=this.lastChild,l=i.parentNode;l&&J(l,i),c===e&&(this.firstChild_=a),u===e&&(this.lastChild_=s),s&&(s.nextSibling_=a),a&&(a.previousSibling_=s),e.previousSibling_=e.nextSibling_=e.parentNode_=void 0}else m(this),J(P(this),i);return B||L(this,"childList",{removedNodes:n(e),nextSibling:a,previousSibling:s}),H(this,e),e},replaceChild:function(e,r){t(e);var o;if(C(r)?o=W(r):(o=r,r=A(o)),r.parentNode!==this)throw new Error("NotFoundError");var s,c=r.nextSibling,u=r.previousSibling,d=!this.invalidateShadowRenderer()&&!v(e);return d?s=a(e):(c===e&&(c=e.nextSibling),s=i(e,this,u,c)),d?(f(this,e),m(this),$.call(P(this),W(e),o)):(this.firstChild===r&&(this.firstChild_=s[0]),this.lastChild===r&&(this.lastChild_=s[s.length-1]),r.previousSibling_=r.nextSibling_=r.parentNode_=void 0,o.parentNode&&$.call(o.parentNode,w(this,s),o)),L(this,"childList",{addedNodes:s,removedNodes:n(r),nextSibling:c,previousSibling:u}),p(r),l(s,this),r},nodeIsInserted_:function(){for(var e=this.firstChild;e;e=e.nextSibling)e.nodeIsInserted_()},hasChildNodes:function(){return null!==this.firstChild},get parentNode(){return void 0!==this.parentNode_?this.parentNode_:A(P(this).parentNode)},get firstChild(){return void 0!==this.firstChild_?this.firstChild_:A(P(this).firstChild)},get lastChild(){return void 0!==this.lastChild_?this.lastChild_:A(P(this).lastChild)},get nextSibling(){return void 0!==this.nextSibling_?this.nextSibling_:A(P(this).nextSibling)},get previousSibling(){return void 0!==this.previousSibling_?this.previousSibling_:A(P(this).previousSibling)},get parentElement(){for(var e=this.parentNode;e&&e.nodeType!==S.ELEMENT_NODE;)e=e.parentNode;return e},get textContent(){for(var e="",t=this.firstChild;t;t=t.nextSibling)t.nodeType!=S.COMMENT_NODE&&(e+=t.textContent);return e},set textContent(e){null==e&&(e="");var t=c(this.childNodes);if(this.invalidateShadowRenderer()){if(g(this),""!==e){var n=P(this).ownerDocument.createTextNode(e);this.appendChild(n)}}else m(this),P(this).textContent=e;var r=c(this.childNodes);L(this,"childList",{addedNodes:r,removedNodes:t}),d(t),l(r,this)},get childNodes(){for(var e=new T,t=0,n=this.firstChild;n;n=n.nextSibling)e[t++]=n;return e.length=t,e},cloneNode:function(e){return y(this,e)},contains:function(e){return E(this,k(e))},compareDocumentPosition:function(e){return z.call(P(this),I(e))},isEqualNode:function(e){return X.call(P(this),I(e))},normalize:function(){for(var e,t,n=c(this.childNodes),r=[],o="",i=0;i<n.length;i++)t=n[i],t.nodeType===S.TEXT_NODE?e||t.data.length?e?(o+=t.data,r.push(t)):e=t:this.removeChild(t):(e&&r.length&&(e.data+=o,b(r)),r=[],o="",e=null,t.childNodes.length&&t.normalize());e&&r.length&&(e.data+=o,b(r))}}),j(S,"ownerDocument"),x(V,S,document.createDocumentFragment()),delete S.prototype.querySelector,delete S.prototype.querySelectorAll,S.prototype=D(Object.create(M.prototype),S.prototype),e.cloneNode=y,e.nodeWasAdded=u,e.nodeWasRemoved=p,e.nodesWereAdded=l,e.nodesWereRemoved=d,e.originalInsertBefore=K,e.originalRemoveChild=Y,e.snapshotNodeList=c,e.wrappers.Node=S}(window.ShadowDOMPolyfill),function(e){"use strict";function t(t,n,r,o){for(var i=null,a=null,s=0,c=t.length;c>s;s++)i=b(t[s]),!o&&(a=g(i).root)&&a instanceof e.wrappers.ShadowRoot||(r[n++]=i);return n}function n(e){return String(e).replace(/\/deep\/|::shadow|>>>/g," ")}function r(e){return String(e).replace(/:host\(([^\s]+)\)/g,"$1").replace(/([^\s]):host/g,"$1").replace(":host","*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content|>>>/g," ")}function o(e,t){for(var n,r=e.firstElementChild;r;){if(r.matches(t))return r;if(n=o(r,t))return n;r=r.nextElementSibling}return null}function i(e,t){return e.matches(t)}function a(e,t,n){var r=e.localName;return r===t||r===n&&e.namespaceURI===C}function s(){return!0}function c(e,t,n){return e.localName===n}function u(e,t){return e.namespaceURI===t}function l(e,t,n){return e.namespaceURI===t&&e.localName===n}function p(e,t,n,r,o,i){for(var a=e.firstElementChild;a;)r(a,o,i)&&(n[t++]=a),t=p(a,t,n,r,o,i),a=a.nextElementSibling;return t}function d(n,r,o,i,a){var s,c=v(this),u=g(this).root;if(u instanceof e.wrappers.ShadowRoot)return p(this,r,o,n,i,null);if(c instanceof L)s=M.call(c,i);else{if(!(c instanceof _))return p(this,r,o,n,i,null);s=S.call(c,i)}return t(s,r,o,a)}function f(n,r,o,i,a){var s,c=v(this),u=g(this).root;if(u instanceof e.wrappers.ShadowRoot)return p(this,r,o,n,i,a);if(c instanceof L)s=O.call(c,i,a);else{if(!(c instanceof _))return p(this,r,o,n,i,a);s=T.call(c,i,a)}return t(s,r,o,!1)}function h(n,r,o,i,a){var s,c=v(this),u=g(this).root;if(u instanceof e.wrappers.ShadowRoot)return p(this,r,o,n,i,a);if(c instanceof L)s=j.call(c,i,a);else{if(!(c instanceof _))return p(this,r,o,n,i,a);s=N.call(c,i,a)}return t(s,r,o,!1)}var w=e.wrappers.HTMLCollection,m=e.wrappers.NodeList,g=e.getTreeScope,v=e.unsafeUnwrap,b=e.wrap,y=document.querySelector,E=document.documentElement.querySelector,S=document.querySelectorAll,M=document.documentElement.querySelectorAll,T=document.getElementsByTagName,O=document.documentElement.getElementsByTagName,N=document.getElementsByTagNameNS,j=document.documentElement.getElementsByTagNameNS,L=window.Element,_=window.HTMLDocument||window.Document,C="http://www.w3.org/1999/xhtml",D={querySelector:function(t){var r=n(t),i=r!==t;t=r;var a,s=v(this),c=g(this).root;if(c instanceof e.wrappers.ShadowRoot)return o(this,t);if(s instanceof L)a=b(E.call(s,t));else{if(!(s instanceof _))return o(this,t);a=b(y.call(s,t))}return a&&!i&&(c=g(a).root)&&c instanceof e.wrappers.ShadowRoot?o(this,t):a},querySelectorAll:function(e){var t=n(e),r=t!==e;e=t;var o=new m;return o.length=d.call(this,i,0,o,e,r),o}},H={matches:function(t){return t=r(t),e.originalMatches.call(v(this),t)}},x={getElementsByTagName:function(e){var t=new w,n="*"===e?s:a;return t.length=f.call(this,n,0,t,e,e.toLowerCase()),t},getElementsByClassName:function(e){return this.querySelectorAll("."+e)},getElementsByTagNameNS:function(e,t){var n=new w,r=null;return r="*"===e?"*"===t?s:c:"*"===t?u:l,n.length=h.call(this,r,0,n,e||null,t),n}};e.GetElementsByInterface=x,e.SelectorsInterface=D,e.MatchesInterface=H}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){for(;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.nextSibling;
+
+return e}function n(e){for(;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.previousSibling;return e}var r=e.wrappers.NodeList,o={get firstElementChild(){return t(this.firstChild)},get lastElementChild(){return n(this.lastChild)},get childElementCount(){for(var e=0,t=this.firstElementChild;t;t=t.nextElementSibling)e++;return e},get children(){for(var e=new r,t=0,n=this.firstElementChild;n;n=n.nextElementSibling)e[t++]=n;return e.length=t,e},remove:function(){var e=this.parentNode;e&&e.removeChild(this)}},i={get nextElementSibling(){return t(this.nextSibling)},get previousElementSibling(){return n(this.previousSibling)}},a={getElementById:function(e){return/[ \t\n\r\f]/.test(e)?null:this.querySelector('[id="'+e+'"]')}};e.ChildNodeInterface=i,e.NonElementParentNodeInterface=a,e.ParentNodeInterface=o}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}var n=e.ChildNodeInterface,r=e.wrappers.Node,o=e.enqueueMutation,i=e.mixin,a=e.registerWrapper,s=e.unsafeUnwrap,c=window.CharacterData;t.prototype=Object.create(r.prototype),i(t.prototype,{get nodeValue(){return this.data},set nodeValue(e){this.data=e},get textContent(){return this.data},set textContent(e){this.data=e},get data(){return s(this).data},set data(e){var t=s(this).data;o(this,"characterData",{oldValue:t}),s(this).data=e}}),i(t.prototype,n),a(c,t,document.createTextNode("")),e.wrappers.CharacterData=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return e>>>0}function n(e){r.call(this,e)}var r=e.wrappers.CharacterData,o=(e.enqueueMutation,e.mixin),i=e.registerWrapper,a=window.Text;n.prototype=Object.create(r.prototype),o(n.prototype,{splitText:function(e){e=t(e);var n=this.data;if(e>n.length)throw new Error("IndexSizeError");var r=n.slice(0,e),o=n.slice(e);this.data=r;var i=this.ownerDocument.createTextNode(o);return this.parentNode&&this.parentNode.insertBefore(i,this.nextSibling),i}}),i(a,n,document.createTextNode("")),e.wrappers.Text=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return i(e).getAttribute("class")}function n(e,t){a(e,"attributes",{name:"class",namespace:null,oldValue:t})}function r(t){e.invalidateRendererBasedOnAttribute(t,"class")}function o(e,o,i){var a=e.ownerElement_;if(null==a)return o.apply(e,i);var s=t(a),c=o.apply(e,i);return t(a)!==s&&(n(a,s),r(a)),c}if(!window.DOMTokenList)return void console.warn("Missing DOMTokenList prototype, please include a compatible classList polyfill such as http://goo.gl/uTcepH.");var i=e.unsafeUnwrap,a=e.enqueueMutation,s=DOMTokenList.prototype.add;DOMTokenList.prototype.add=function(){o(this,s,arguments)};var c=DOMTokenList.prototype.remove;DOMTokenList.prototype.remove=function(){o(this,c,arguments)};var u=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(){return o(this,u,arguments)}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(t,n){var r=t.parentNode;if(r&&r.shadowRoot){var o=e.getRendererForHost(r);o.dependsOnAttribute(n)&&o.invalidate()}}function n(e,t,n){l(e,"attributes",{name:t,namespace:null,oldValue:n})}function r(e){a.call(this,e)}var o=e.ChildNodeInterface,i=e.GetElementsByInterface,a=e.wrappers.Node,s=e.ParentNodeInterface,c=e.SelectorsInterface,u=e.MatchesInterface,l=(e.addWrapNodeListMethod,e.enqueueMutation),p=e.mixin,d=(e.oneOf,e.registerWrapper),f=e.unsafeUnwrap,h=e.wrappers,w=window.Element,m=["matches","mozMatchesSelector","msMatchesSelector","webkitMatchesSelector"].filter(function(e){return w.prototype[e]}),g=m[0],v=w.prototype[g],b=new WeakMap;r.prototype=Object.create(a.prototype),p(r.prototype,{createShadowRoot:function(){var t=new h.ShadowRoot(this);f(this).polymerShadowRoot_=t;var n=e.getRendererForHost(this);return n.invalidate(),t},get shadowRoot(){return f(this).polymerShadowRoot_||null},setAttribute:function(e,r){var o=f(this).getAttribute(e);f(this).setAttribute(e,r),n(this,e,o),t(this,e)},removeAttribute:function(e){var r=f(this).getAttribute(e);f(this).removeAttribute(e),n(this,e,r),t(this,e)},get classList(){var e=b.get(this);if(!e){if(e=f(this).classList,!e)return;e.ownerElement_=this,b.set(this,e)}return e},get className(){return f(this).className},set className(e){this.setAttribute("class",e)},get id(){return f(this).id},set id(e){this.setAttribute("id",e)}}),m.forEach(function(e){"matches"!==e&&(r.prototype[e]=function(e){return this.matches(e)})}),w.prototype.webkitCreateShadowRoot&&(r.prototype.webkitCreateShadowRoot=r.prototype.createShadowRoot),p(r.prototype,o),p(r.prototype,i),p(r.prototype,s),p(r.prototype,c),p(r.prototype,u),d(w,r,document.createElementNS(null,"x")),e.invalidateRendererBasedOnAttribute=t,e.matchesNames=m,e.originalMatches=v,e.wrappers.Element=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){switch(e){case"&":return"&";case"<":return"<";case">":return">";case'"':return""";case" ":return" "}}function n(e){return e.replace(j,t)}function r(e){return e.replace(L,t)}function o(e){for(var t={},n=0;n<e.length;n++)t[e[n]]=!0;return t}function i(e){if(e.namespaceURI!==D)return!0;var t=e.ownerDocument.doctype;return t&&t.publicId&&t.systemId}function a(e,t){switch(e.nodeType){case Node.ELEMENT_NODE:for(var o,a=e.tagName.toLowerCase(),c="<"+a,u=e.attributes,l=0;o=u[l];l++)c+=" "+o.name+'="'+n(o.value)+'"';return _[a]?(i(e)&&(c+="/"),c+">"):c+">"+s(e)+"</"+a+">";case Node.TEXT_NODE:var p=e.data;return t&&C[t.localName]?p:r(p);case Node.COMMENT_NODE:return"<!--"+e.data+"-->";default:throw console.error(e),new Error("not implemented")}}function s(e){e instanceof N.HTMLTemplateElement&&(e=e.content);for(var t="",n=e.firstChild;n;n=n.nextSibling)t+=a(n,e);return t}function c(e,t,n){var r=n||"div";e.textContent="";var o=T(e.ownerDocument.createElement(r));o.innerHTML=t;for(var i;i=o.firstChild;)e.appendChild(O(i))}function u(e){w.call(this,e)}function l(e,t){var n=T(e.cloneNode(!1));n.innerHTML=t;for(var r,o=T(document.createDocumentFragment());r=n.firstChild;)o.appendChild(r);return O(o)}function p(t){return function(){return e.renderAllPending(),M(this)[t]}}function d(e){m(u,e,p(e))}function f(t){Object.defineProperty(u.prototype,t,{get:p(t),set:function(n){e.renderAllPending(),M(this)[t]=n},configurable:!0,enumerable:!0})}function h(t){Object.defineProperty(u.prototype,t,{value:function(){return e.renderAllPending(),M(this)[t].apply(M(this),arguments)},configurable:!0,enumerable:!0})}var w=e.wrappers.Element,m=e.defineGetter,g=e.enqueueMutation,v=e.mixin,b=e.nodesWereAdded,y=e.nodesWereRemoved,E=e.registerWrapper,S=e.snapshotNodeList,M=e.unsafeUnwrap,T=e.unwrap,O=e.wrap,N=e.wrappers,j=/[&\u00A0"]/g,L=/[&\u00A0<>]/g,_=o(["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"]),C=o(["style","script","xmp","iframe","noembed","noframes","plaintext","noscript"]),D="http://www.w3.org/1999/xhtml",H=/MSIE/.test(navigator.userAgent),x=window.HTMLElement,R=window.HTMLTemplateElement;u.prototype=Object.create(w.prototype),v(u.prototype,{get innerHTML(){return s(this)},set innerHTML(e){if(H&&C[this.localName])return void(this.textContent=e);var t=S(this.childNodes);this.invalidateShadowRenderer()?this instanceof N.HTMLTemplateElement?c(this.content,e):c(this,e,this.tagName):!R&&this instanceof N.HTMLTemplateElement?c(this.content,e):M(this).innerHTML=e;var n=S(this.childNodes);g(this,"childList",{addedNodes:n,removedNodes:t}),y(t),b(n,this)},get outerHTML(){return a(this,this.parentNode)},set outerHTML(e){var t=this.parentNode;if(t){t.invalidateShadowRenderer();var n=l(t,e);t.replaceChild(n,this)}},insertAdjacentHTML:function(e,t){var n,r;switch(String(e).toLowerCase()){case"beforebegin":n=this.parentNode,r=this;break;case"afterend":n=this.parentNode,r=this.nextSibling;break;case"afterbegin":n=this,r=this.firstChild;break;case"beforeend":n=this,r=null;break;default:return}var o=l(n,t);n.insertBefore(o,r)},get hidden(){return this.hasAttribute("hidden")},set hidden(e){e?this.setAttribute("hidden",""):this.removeAttribute("hidden")}}),["clientHeight","clientLeft","clientTop","clientWidth","offsetHeight","offsetLeft","offsetTop","offsetWidth","scrollHeight","scrollWidth"].forEach(d),["scrollLeft","scrollTop"].forEach(f),["getBoundingClientRect","getClientRects","scrollIntoView"].forEach(h),E(x,u,document.createElement("b")),e.wrappers.HTMLElement=u,e.getInnerHTML=s,e.setInnerHTML=c}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unsafeUnwrap,a=e.wrap,s=window.HTMLCanvasElement;t.prototype=Object.create(n.prototype),r(t.prototype,{getContext:function(){var e=i(this).getContext.apply(i(this),arguments);return e&&a(e)}}),o(s,t,document.createElement("canvas")),e.wrappers.HTMLCanvasElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=window.HTMLContentElement;t.prototype=Object.create(n.prototype),r(t.prototype,{constructor:t,get select(){return this.getAttribute("select")},set select(e){this.setAttribute("select",e)},setAttribute:function(e,t){n.prototype.setAttribute.call(this,e,t),"select"===String(e).toLowerCase()&&this.invalidateShadowRenderer(!0)}}),i&&o(i,t),e.wrappers.HTMLContentElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=window.HTMLFormElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get elements(){return i(a(this).elements)}}),o(s,t,document.createElement("form")),e.wrappers.HTMLFormElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}function n(e,t){if(!(this instanceof n))throw new TypeError("DOM object constructor cannot be called as a function.");var o=i(document.createElement("img"));r.call(this,o),a(o,this),void 0!==e&&(o.width=e),void 0!==t&&(o.height=t)}var r=e.wrappers.HTMLElement,o=e.registerWrapper,i=e.unwrap,a=e.rewrap,s=window.HTMLImageElement;t.prototype=Object.create(r.prototype),o(s,t,document.createElement("img")),n.prototype=t.prototype,e.wrappers.HTMLImageElement=t,e.wrappers.Image=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=(e.mixin,e.wrappers.NodeList,e.registerWrapper),o=window.HTMLShadowElement;t.prototype=Object.create(n.prototype),t.prototype.constructor=t,o&&r(o,t),e.wrappers.HTMLShadowElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){if(!e.defaultView)return e;var t=p.get(e);if(!t){for(t=e.implementation.createHTMLDocument("");t.lastChild;)t.removeChild(t.lastChild);p.set(e,t)}return t}function n(e){for(var n,r=t(e.ownerDocument),o=c(r.createDocumentFragment());n=e.firstChild;)o.appendChild(n);return o}function r(e){if(o.call(this,e),!d){var t=n(e);l.set(this,u(t))}}var o=e.wrappers.HTMLElement,i=e.mixin,a=e.registerWrapper,s=e.unsafeUnwrap,c=e.unwrap,u=e.wrap,l=new WeakMap,p=new WeakMap,d=window.HTMLTemplateElement;r.prototype=Object.create(o.prototype),i(r.prototype,{constructor:r,get content(){return d?u(s(this).content):l.get(this)}}),d&&a(d,r),e.wrappers.HTMLTemplateElement=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.registerWrapper,o=window.HTMLMediaElement;o&&(t.prototype=Object.create(n.prototype),r(o,t,document.createElement("audio")),e.wrappers.HTMLMediaElement=t)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}function n(e){if(!(this instanceof n))throw new TypeError("DOM object constructor cannot be called as a function.");var t=i(document.createElement("audio"));r.call(this,t),a(t,this),t.setAttribute("preload","auto"),void 0!==e&&t.setAttribute("src",e)}var r=e.wrappers.HTMLMediaElement,o=e.registerWrapper,i=e.unwrap,a=e.rewrap,s=window.HTMLAudioElement;s&&(t.prototype=Object.create(r.prototype),o(s,t,document.createElement("audio")),n.prototype=t.prototype,e.wrappers.HTMLAudioElement=t,e.wrappers.Audio=n)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return e.replace(/\s+/g," ").trim()}function n(e){o.call(this,e)}function r(e,t,n,i){if(!(this instanceof r))throw new TypeError("DOM object constructor cannot be called as a function.");var a=c(document.createElement("option"));o.call(this,a),s(a,this),void 0!==e&&(a.text=e),void 0!==t&&a.setAttribute("value",t),n===!0&&a.setAttribute("selected",""),a.selected=i===!0}var o=e.wrappers.HTMLElement,i=e.mixin,a=e.registerWrapper,s=e.rewrap,c=e.unwrap,u=e.wrap,l=window.HTMLOptionElement;n.prototype=Object.create(o.prototype),i(n.prototype,{get text(){return t(this.textContent)},set text(e){this.textContent=t(String(e))},get form(){return u(c(this).form)}}),a(l,n,document.createElement("option")),r.prototype=n.prototype,e.wrappers.HTMLOptionElement=n,e.wrappers.Option=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unwrap,a=e.wrap,s=window.HTMLSelectElement;t.prototype=Object.create(n.prototype),r(t.prototype,{add:function(e,t){"object"==typeof t&&(t=i(t)),i(this).add(i(e),t)},remove:function(e){return void 0===e?void n.prototype.remove.call(this):("object"==typeof e&&(e=i(e)),void i(this).remove(e))},get form(){return a(i(this).form)}}),o(s,t,document.createElement("select")),e.wrappers.HTMLSelectElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unwrap,a=e.wrap,s=e.wrapHTMLCollection,c=window.HTMLTableElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get caption(){return a(i(this).caption)},createCaption:function(){return a(i(this).createCaption())},get tHead(){return a(i(this).tHead)},createTHead:function(){return a(i(this).createTHead())},createTFoot:function(){return a(i(this).createTFoot())},get tFoot(){return a(i(this).tFoot)},get tBodies(){return s(i(this).tBodies)},createTBody:function(){return a(i(this).createTBody())},get rows(){return s(i(this).rows)},insertRow:function(e){return a(i(this).insertRow(e))}}),o(c,t,document.createElement("table")),e.wrappers.HTMLTableElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=e.wrap,c=window.HTMLTableSectionElement;t.prototype=Object.create(n.prototype),r(t.prototype,{constructor:t,get rows(){return i(a(this).rows)},insertRow:function(e){return s(a(this).insertRow(e))}}),o(c,t,document.createElement("thead")),e.wrappers.HTMLTableSectionElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=e.wrap,c=window.HTMLTableRowElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get cells(){return i(a(this).cells)},insertCell:function(e){return s(a(this).insertCell(e))}}),o(c,t,document.createElement("tr")),e.wrappers.HTMLTableRowElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){switch(e.localName){case"content":return new n(e);case"shadow":return new o(e);case"template":return new i(e)}r.call(this,e)}var n=e.wrappers.HTMLContentElement,r=e.wrappers.HTMLElement,o=e.wrappers.HTMLShadowElement,i=e.wrappers.HTMLTemplateElement,a=(e.mixin,e.registerWrapper),s=window.HTMLUnknownElement;t.prototype=Object.create(r.prototype),a(s,t),e.wrappers.HTMLUnknownElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.wrappers.Element,n=e.wrappers.HTMLElement,r=e.registerObject,o=e.defineWrapGetter,i="http://www.w3.org/2000/svg",a=document.createElementNS(i,"title"),s=r(a),c=Object.getPrototypeOf(s.prototype).constructor;if(!("classList"in a)){var u=Object.getOwnPropertyDescriptor(t.prototype,"classList");Object.defineProperty(n.prototype,"classList",u),delete t.prototype.classList}o(c,"ownerSVGElement"),e.wrappers.SVGElement=c}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){d.call(this,e)}var n=e.mixin,r=e.registerWrapper,o=e.unwrap,i=e.wrap,a=window.SVGUseElement,s="http://www.w3.org/2000/svg",c=i(document.createElementNS(s,"g")),u=document.createElementNS(s,"use"),l=c.constructor,p=Object.getPrototypeOf(l.prototype),d=p.constructor;t.prototype=Object.create(p),"instanceRoot"in u&&n(t.prototype,{get instanceRoot(){return i(o(this).instanceRoot)},get animatedInstanceRoot(){return i(o(this).animatedInstanceRoot)}}),r(a,t,u),e.wrappers.SVGUseElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.EventTarget,r=e.mixin,o=e.registerWrapper,i=e.unsafeUnwrap,a=e.wrap,s=window.SVGElementInstance;s&&(t.prototype=Object.create(n.prototype),r(t.prototype,{get correspondingElement(){return a(i(this).correspondingElement)},get correspondingUseElement(){return a(i(this).correspondingUseElement)},get parentNode(){return a(i(this).parentNode)},get childNodes(){throw new Error("Not implemented")},get firstChild(){return a(i(this).firstChild)},get lastChild(){return a(i(this).lastChild)},get previousSibling(){return a(i(this).previousSibling)},get nextSibling(){return a(i(this).nextSibling)}}),o(s,t),e.wrappers.SVGElementInstance=t)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){o(e,this)}var n=e.mixin,r=e.registerWrapper,o=e.setWrapper,i=e.unsafeUnwrap,a=e.unwrap,s=e.unwrapIfNeeded,c=e.wrap,u=window.CanvasRenderingContext2D;n(t.prototype,{get canvas(){return c(i(this).canvas)},drawImage:function(){arguments[0]=s(arguments[0]),i(this).drawImage.apply(i(this),arguments)},createPattern:function(){return arguments[0]=a(arguments[0]),i(this).createPattern.apply(i(this),arguments)}}),r(u,t,document.createElement("canvas").getContext("2d")),e.wrappers.CanvasRenderingContext2D=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){o(e,this)}var n=e.mixin,r=e.registerWrapper,o=e.setWrapper,i=e.unsafeUnwrap,a=e.unwrapIfNeeded,s=e.wrap,c=window.WebGLRenderingContext;if(c){n(t.prototype,{get canvas(){return s(i(this).canvas)},texImage2D:function(){arguments[5]=a(arguments[5]),i(this).texImage2D.apply(i(this),arguments)},texSubImage2D:function(){arguments[6]=a(arguments[6]),i(this).texSubImage2D.apply(i(this),arguments)}});var u=/WebKit/.test(navigator.userAgent)?{drawingBufferHeight:null,drawingBufferWidth:null}:{};r(c,t,u),e.wrappers.WebGLRenderingContext=t}}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.GetElementsByInterface,n=e.NonElementParentNodeInterface,r=e.ParentNodeInterface,o=e.SelectorsInterface,i=e.mixin,a=e.registerObject,s=a(document.createDocumentFragment());i(s.prototype,r),i(s.prototype,o),i(s.prototype,t),i(s.prototype,n);var c=a(document.createComment(""));e.wrappers.Comment=c,e.wrappers.DocumentFragment=s}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t=p(l(e).ownerDocument.createDocumentFragment());n.call(this,t),c(t,this);var o=e.shadowRoot;f.set(this,o),this.treeScope_=new r(this,a(o||e)),d.set(this,e)}var n=e.wrappers.DocumentFragment,r=e.TreeScope,o=e.elementFromPoint,i=e.getInnerHTML,a=e.getTreeScope,s=e.mixin,c=e.rewrap,u=e.setInnerHTML,l=e.unsafeUnwrap,p=e.unwrap,d=new WeakMap,f=new WeakMap;t.prototype=Object.create(n.prototype),s(t.prototype,{constructor:t,get innerHTML(){return i(this)},set innerHTML(e){u(this,e),this.invalidateShadowRenderer()},get olderShadowRoot(){return f.get(this)||null},get host(){return d.get(this)||null},invalidateShadowRenderer:function(){return d.get(this).invalidateShadowRenderer()},elementFromPoint:function(e,t){return o(this,this.ownerDocument,e,t)}}),e.wrappers.ShadowRoot=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t=p(e).root;return t instanceof f?t.host:null}function n(t,n){if(t.shadowRoot){n=Math.min(t.childNodes.length-1,n);var r=t.childNodes[n];if(r){var o=e.getDestinationInsertionPoints(r);if(o.length>0){var i=o[0].parentNode;i.nodeType==Node.ELEMENT_NODE&&(t=i)}}}return t}function r(e){return e=l(e),t(e)||e}function o(e){a(e,this)}var i=e.registerWrapper,a=e.setWrapper,s=e.unsafeUnwrap,c=e.unwrap,u=e.unwrapIfNeeded,l=e.wrap,p=e.getTreeScope,d=window.Range,f=e.wrappers.ShadowRoot;o.prototype={get startContainer(){return r(s(this).startContainer)},get endContainer(){return r(s(this).endContainer)},get commonAncestorContainer(){return r(s(this).commonAncestorContainer)},setStart:function(e,t){e=n(e,t),s(this).setStart(u(e),t)},setEnd:function(e,t){e=n(e,t),s(this).setEnd(u(e),t)},setStartBefore:function(e){s(this).setStartBefore(u(e))},setStartAfter:function(e){s(this).setStartAfter(u(e))},setEndBefore:function(e){s(this).setEndBefore(u(e))},setEndAfter:function(e){s(this).setEndAfter(u(e))},selectNode:function(e){s(this).selectNode(u(e))},selectNodeContents:function(e){s(this).selectNodeContents(u(e))},compareBoundaryPoints:function(e,t){return s(this).compareBoundaryPoints(e,c(t))},extractContents:function(){return l(s(this).extractContents())},cloneContents:function(){return l(s(this).cloneContents())},insertNode:function(e){s(this).insertNode(u(e))},surroundContents:function(e){s(this).surroundContents(u(e))},cloneRange:function(){return l(s(this).cloneRange())},isPointInRange:function(e,t){return s(this).isPointInRange(u(e),t)},comparePoint:function(e,t){return s(this).comparePoint(u(e),t)},intersectsNode:function(e){return s(this).intersectsNode(u(e))},toString:function(){return s(this).toString()}},d.prototype.createContextualFragment&&(o.prototype.createContextualFragment=function(e){return l(s(this).createContextualFragment(e))}),i(window.Range,o,document.createRange()),e.wrappers.Range=o}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){e.previousSibling_=e.previousSibling,e.nextSibling_=e.nextSibling,e.parentNode_=e.parentNode}function n(n,o,i){var a=x(n),s=x(o),c=i?x(i):null;if(r(o),t(o),i)n.firstChild===i&&(n.firstChild_=i),i.previousSibling_=i.previousSibling;else{n.lastChild_=n.lastChild,n.lastChild===n.firstChild&&(n.firstChild_=n.firstChild);var u=R(a.lastChild);u&&(u.nextSibling_=u.nextSibling)}e.originalInsertBefore.call(a,s,c)}function r(n){var r=x(n),o=r.parentNode;if(o){var i=R(o);t(n),n.previousSibling&&(n.previousSibling.nextSibling_=n),n.nextSibling&&(n.nextSibling.previousSibling_=n),i.lastChild===n&&(i.lastChild_=n),i.firstChild===n&&(i.firstChild_=n),e.originalRemoveChild.call(o,r)}}function o(e){W.set(e,[])}function i(e){var t=W.get(e);return t||W.set(e,t=[]),t}function a(e){for(var t=[],n=0,r=e.firstChild;r;r=r.nextSibling)t[n++]=r;return t}function s(){for(var e=0;e<F.length;e++){var t=F[e],n=t.parentRenderer;n&&n.dirty||t.render()}F=[]}function c(){T=null,s()}function u(e){var t=A.get(e);return t||(t=new f(e),A.set(e,t)),t}function l(e){var t=C(e).root;return t instanceof _?t:null}function p(e){return u(e.host)}function d(e){this.skip=!1,this.node=e,this.childNodes=[]}function f(e){this.host=e,this.dirty=!1,this.invalidateAttributes(),this.associateNode(e)}function h(e){for(var t=[],n=e.firstChild;n;n=n.nextSibling)E(n)?t.push.apply(t,i(n)):t.push(n);return t}function w(e){if(e instanceof j)return e;if(e instanceof N)return null;for(var t=e.firstChild;t;t=t.nextSibling){var n=w(t);if(n)return n}return null}function m(e,t){i(t).push(e);var n=I.get(e);n?n.push(t):I.set(e,[t])}function g(e){return I.get(e)}function v(e){I.set(e,void 0)}function b(e,t){var n=t.getAttribute("select");if(!n)return!0;if(n=n.trim(),!n)return!0;if(!(e instanceof O))return!1;if(!U.test(n))return!1;try{return e.matches(n)}catch(r){return!1}}function y(e,t){var n=g(t);return n&&n[n.length-1]===e}function E(e){return e instanceof N||e instanceof j}function S(e){return e.shadowRoot}function M(e){for(var t=[],n=e.shadowRoot;n;n=n.olderShadowRoot)t.push(n);return t}var T,O=e.wrappers.Element,N=e.wrappers.HTMLContentElement,j=e.wrappers.HTMLShadowElement,L=e.wrappers.Node,_=e.wrappers.ShadowRoot,C=(e.assert,e.getTreeScope),D=(e.mixin,e.oneOf),H=e.unsafeUnwrap,x=e.unwrap,R=e.wrap,P=e.ArraySplice,W=new WeakMap,I=new WeakMap,A=new WeakMap,k=D(window,["requestAnimationFrame","mozRequestAnimationFrame","webkitRequestAnimationFrame","setTimeout"]),F=[],B=new P;B.equals=function(e,t){return x(e.node)===t},d.prototype={append:function(e){var t=new d(e);return this.childNodes.push(t),t},sync:function(e){if(!this.skip){for(var t=this.node,o=this.childNodes,i=a(x(t)),s=e||new WeakMap,c=B.calculateSplices(o,i),u=0,l=0,p=0,d=0;d<c.length;d++){for(var f=c[d];p<f.index;p++)l++,o[u++].sync(s);for(var h=f.removed.length,w=0;h>w;w++){var m=R(i[l++]);s.get(m)||r(m)}for(var g=f.addedCount,v=i[l]&&R(i[l]),w=0;g>w;w++){var b=o[u++],y=b.node;n(t,y,v),s.set(y,!0),b.sync(s)}p+=g}for(var d=p;d<o.length;d++)o[d].sync(s)}}},f.prototype={render:function(e){if(this.dirty){this.invalidateAttributes();var t=this.host;this.distribution(t);var n=e||new d(t);this.buildRenderTree(n,t);var r=!e;r&&n.sync(),this.dirty=!1}},get parentRenderer(){return C(this.host).renderer},invalidate:function(){if(!this.dirty){this.dirty=!0;var e=this.parentRenderer;if(e&&e.invalidate(),F.push(this),T)return;T=window[k](c,0)}},distribution:function(e){this.resetAllSubtrees(e),this.distributionResolution(e)},resetAll:function(e){E(e)?o(e):v(e),this.resetAllSubtrees(e)},resetAllSubtrees:function(e){for(var t=e.firstChild;t;t=t.nextSibling)this.resetAll(t);e.shadowRoot&&this.resetAll(e.shadowRoot),e.olderShadowRoot&&this.resetAll(e.olderShadowRoot)},distributionResolution:function(e){if(S(e)){for(var t=e,n=h(t),r=M(t),o=0;o<r.length;o++)this.poolDistribution(r[o],n);for(var o=r.length-1;o>=0;o--){var i=r[o],a=w(i);if(a){var s=i.olderShadowRoot;s&&(n=h(s));for(var c=0;c<n.length;c++)m(n[c],a)}this.distributionResolution(i)}}for(var u=e.firstChild;u;u=u.nextSibling)this.distributionResolution(u)},poolDistribution:function(e,t){if(!(e instanceof j))if(e instanceof N){var n=e;this.updateDependentAttributes(n.getAttribute("select"));for(var r=!1,o=0;o<t.length;o++){var e=t[o];e&&b(e,n)&&(m(e,n),t[o]=void 0,r=!0)}if(!r)for(var i=n.firstChild;i;i=i.nextSibling)m(i,n)}else for(var i=e.firstChild;i;i=i.nextSibling)this.poolDistribution(i,t)},buildRenderTree:function(e,t){for(var n=this.compose(t),r=0;r<n.length;r++){var o=n[r],i=e.append(o);this.buildRenderTree(i,o)}if(S(t)){var a=u(t);a.dirty=!1}},compose:function(e){for(var t=[],n=e.shadowRoot||e,r=n.firstChild;r;r=r.nextSibling)if(E(r)){this.associateNode(n);for(var o=i(r),a=0;a<o.length;a++){var s=o[a];y(r,s)&&t.push(s)}}else t.push(r);return t},invalidateAttributes:function(){this.attributes=Object.create(null)},updateDependentAttributes:function(e){if(e){var t=this.attributes;/\.\w+/.test(e)&&(t["class"]=!0),/#\w+/.test(e)&&(t.id=!0),e.replace(/\[\s*([^\s=\|~\]]+)/g,function(e,n){t[n]=!0})}},dependsOnAttribute:function(e){return this.attributes[e]},associateNode:function(e){H(e).polymerShadowRenderer_=this}};var U=/^(:not\()?[*.#[a-zA-Z_|]/;L.prototype.invalidateShadowRenderer=function(e){var t=H(this).polymerShadowRenderer_;return t?(t.invalidate(),!0):!1},N.prototype.getDistributedNodes=j.prototype.getDistributedNodes=function(){return s(),i(this)},O.prototype.getDestinationInsertionPoints=function(){return s(),g(this)||[]},N.prototype.nodeIsInserted_=j.prototype.nodeIsInserted_=function(){this.invalidateShadowRenderer();var e,t=l(this);t&&(e=p(t)),H(this).polymerShadowRenderer_=e,e&&e.invalidate()},e.getRendererForHost=u,e.getShadowTrees=M,e.renderAllPending=s,e.getDestinationInsertionPoints=g,e.visual={insertBefore:n,remove:r}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(t){if(window[t]){r(!e.wrappers[t]);var c=function(e){n.call(this,e)};c.prototype=Object.create(n.prototype),o(c.prototype,{get form(){return s(a(this).form)}}),i(window[t],c,document.createElement(t.slice(4,-7))),e.wrappers[t]=c}}var n=e.wrappers.HTMLElement,r=e.assert,o=e.mixin,i=e.registerWrapper,a=e.unwrap,s=e.wrap,c=["HTMLButtonElement","HTMLFieldSetElement","HTMLInputElement","HTMLKeygenElement","HTMLLabelElement","HTMLLegendElement","HTMLObjectElement","HTMLOutputElement","HTMLTextAreaElement"];c.forEach(t)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r(e,this)}var n=e.registerWrapper,r=e.setWrapper,o=e.unsafeUnwrap,i=e.unwrap,a=e.unwrapIfNeeded,s=e.wrap,c=window.Selection;t.prototype={get anchorNode(){return s(o(this).anchorNode)},get focusNode(){return s(o(this).focusNode)},addRange:function(e){o(this).addRange(a(e))},collapse:function(e,t){o(this).collapse(a(e),t)},containsNode:function(e,t){return o(this).containsNode(a(e),t)},getRangeAt:function(e){return s(o(this).getRangeAt(e))},removeRange:function(e){o(this).removeRange(i(e))},selectAllChildren:function(e){o(this).selectAllChildren(a(e))},toString:function(){return o(this).toString()}},c.prototype.extend&&(t.prototype.extend=function(e,t){o(this).extend(a(e),t)}),n(window.Selection,t,window.getSelection()),e.wrappers.Selection=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r(e,this)}var n=e.registerWrapper,r=e.setWrapper,o=e.unsafeUnwrap,i=e.unwrapIfNeeded,a=e.wrap,s=window.TreeWalker;t.prototype={get root(){return a(o(this).root)},get currentNode(){return a(o(this).currentNode)},set currentNode(e){o(this).currentNode=i(e)},get filter(){return o(this).filter},parentNode:function(){return a(o(this).parentNode())},firstChild:function(){return a(o(this).firstChild())},lastChild:function(){return a(o(this).lastChild())},previousSibling:function(){return a(o(this).previousSibling())},previousNode:function(){return a(o(this).previousNode())},nextNode:function(){return a(o(this).nextNode())}},n(s,t),e.wrappers.TreeWalker=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){l.call(this,e),this.treeScope_=new m(this,null)}function n(e){var n=document[e];t.prototype[e]=function(){return _(n.apply(j(this),arguments))}}function r(e,t){H.call(j(t),L(e)),o(e,t)}function o(e,t){e.shadowRoot&&t.adoptNode(e.shadowRoot),e instanceof w&&i(e,t);for(var n=e.firstChild;n;n=n.nextSibling)o(n,t)}function i(e,t){var n=e.olderShadowRoot;n&&t.adoptNode(n)}function a(e){N(e,this)}function s(e,t){var n=document.implementation[t];e.prototype[t]=function(){return _(n.apply(j(this),arguments))}}function c(e,t){var n=document.implementation[t];e.prototype[t]=function(){return n.apply(j(this),arguments)}}var u=e.GetElementsByInterface,l=e.wrappers.Node,p=e.ParentNodeInterface,d=e.NonElementParentNodeInterface,f=e.wrappers.Selection,h=e.SelectorsInterface,w=e.wrappers.ShadowRoot,m=e.TreeScope,g=e.cloneNode,v=e.defineWrapGetter,b=e.elementFromPoint,y=e.forwardMethodsToWrapper,E=e.matchesNames,S=e.mixin,M=e.registerWrapper,T=e.renderAllPending,O=e.rewrap,N=e.setWrapper,j=e.unsafeUnwrap,L=e.unwrap,_=e.wrap,C=e.wrapEventTargetMethods,D=(e.wrapNodeList,new WeakMap);t.prototype=Object.create(l.prototype),v(t,"documentElement"),v(t,"body"),v(t,"head"),["createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode"].forEach(n);var H=document.adoptNode,x=document.getSelection;S(t.prototype,{adoptNode:function(e){return e.parentNode&&e.parentNode.removeChild(e),r(e,this),e},elementFromPoint:function(e,t){return b(this,this,e,t)},importNode:function(e,t){return g(e,t,j(this))},getSelection:function(){return T(),new f(x.call(L(this)))},getElementsByName:function(e){return h.querySelectorAll.call(this,"[name="+JSON.stringify(String(e))+"]")}});var R=document.createTreeWalker,P=e.wrappers.TreeWalker;if(t.prototype.createTreeWalker=function(e,t,n,r){var o=null;return n&&(n.acceptNode&&"function"==typeof n.acceptNode?o={acceptNode:function(e){return n.acceptNode(_(e))}}:"function"==typeof n&&(o=function(e){return n(_(e))})),new P(R.call(L(this),L(e),t,o,r))},document.registerElement){var W=document.registerElement;t.prototype.registerElement=function(t,n){function r(e){return e?void N(e,this):i?document.createElement(i,t):document.createElement(t);
+
+}var o,i;if(void 0!==n&&(o=n.prototype,i=n["extends"]),o||(o=Object.create(HTMLElement.prototype)),e.nativePrototypeTable.get(o))throw new Error("NotSupportedError");for(var a,s=Object.getPrototypeOf(o),c=[];s&&!(a=e.nativePrototypeTable.get(s));)c.push(s),s=Object.getPrototypeOf(s);if(!a)throw new Error("NotSupportedError");for(var u=Object.create(a),l=c.length-1;l>=0;l--)u=Object.create(u);["createdCallback","attachedCallback","detachedCallback","attributeChangedCallback"].forEach(function(e){var t=o[e];t&&(u[e]=function(){_(this)instanceof r||O(this),t.apply(_(this),arguments)})});var p={prototype:u};i&&(p["extends"]=i),r.prototype=o,r.prototype.constructor=r,e.constructorTable.set(u,r),e.nativePrototypeTable.set(o,u);W.call(L(this),t,p);return r},y([window.HTMLDocument||window.Document],["registerElement"])}y([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement,window.HTMLHtmlElement],["appendChild","compareDocumentPosition","contains","getElementsByClassName","getElementsByTagName","getElementsByTagNameNS","insertBefore","querySelector","querySelectorAll","removeChild","replaceChild"]),y([window.HTMLBodyElement,window.HTMLHeadElement,window.HTMLHtmlElement],E),y([window.HTMLDocument||window.Document],["adoptNode","importNode","contains","createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","createTreeWalker","elementFromPoint","getElementById","getElementsByName","getSelection"]),S(t.prototype,u),S(t.prototype,p),S(t.prototype,h),S(t.prototype,d),S(t.prototype,{get implementation(){var e=D.get(this);return e?e:(e=new a(L(this).implementation),D.set(this,e),e)},get defaultView(){return _(L(this).defaultView)}}),M(window.Document,t,document.implementation.createHTMLDocument("")),window.HTMLDocument&&M(window.HTMLDocument,t),C([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement]);var I=document.implementation.createDocument;a.prototype.createDocument=function(){return arguments[2]=L(arguments[2]),_(I.apply(j(this),arguments))},s(a,"createDocumentType"),s(a,"createHTMLDocument"),c(a,"hasFeature"),M(window.DOMImplementation,a),y([window.DOMImplementation],["createDocument","createDocumentType","createHTMLDocument","hasFeature"]),e.adoptNodeNoRemove=r,e.wrappers.DOMImplementation=a,e.wrappers.Document=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.EventTarget,r=e.wrappers.Selection,o=e.mixin,i=e.registerWrapper,a=e.renderAllPending,s=e.unwrap,c=e.unwrapIfNeeded,u=e.wrap,l=window.Window,p=window.getComputedStyle,d=window.getDefaultComputedStyle,f=window.getSelection;t.prototype=Object.create(n.prototype),l.prototype.getComputedStyle=function(e,t){return u(this||window).getComputedStyle(c(e),t)},d&&(l.prototype.getDefaultComputedStyle=function(e,t){return u(this||window).getDefaultComputedStyle(c(e),t)}),l.prototype.getSelection=function(){return u(this||window).getSelection()},delete window.getComputedStyle,delete window.getDefaultComputedStyle,delete window.getSelection,["addEventListener","removeEventListener","dispatchEvent"].forEach(function(e){l.prototype[e]=function(){var t=u(this||window);return t[e].apply(t,arguments)},delete window[e]}),o(t.prototype,{getComputedStyle:function(e,t){return a(),p.call(s(this),c(e),t)},getSelection:function(){return a(),new r(f.call(s(this)))},get document(){return u(s(this).document)}}),d&&(t.prototype.getDefaultComputedStyle=function(e,t){return a(),d.call(s(this),c(e),t)}),i(l,t,window),e.wrappers.Window=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.unwrap,n=window.DataTransfer||window.Clipboard,r=n.prototype.setDragImage;r&&(n.prototype.setDragImage=function(e,n,o){r.call(this,t(e),n,o)})}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t;t=e instanceof i?e:new i(e&&o(e)),r(t,this)}var n=e.registerWrapper,r=e.setWrapper,o=e.unwrap,i=window.FormData;i&&(n(i,t,new i),e.wrappers.FormData=t)}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.unwrapIfNeeded,n=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.send=function(e){return n.call(this,t(e))}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t=n[e],r=window[t];if(r){var o=document.createElement(e),i=o.constructor;window[t]=i}}var n=(e.isWrapperFor,{a:"HTMLAnchorElement",area:"HTMLAreaElement",audio:"HTMLAudioElement",base:"HTMLBaseElement",body:"HTMLBodyElement",br:"HTMLBRElement",button:"HTMLButtonElement",canvas:"HTMLCanvasElement",caption:"HTMLTableCaptionElement",col:"HTMLTableColElement",content:"HTMLContentElement",data:"HTMLDataElement",datalist:"HTMLDataListElement",del:"HTMLModElement",dir:"HTMLDirectoryElement",div:"HTMLDivElement",dl:"HTMLDListElement",embed:"HTMLEmbedElement",fieldset:"HTMLFieldSetElement",font:"HTMLFontElement",form:"HTMLFormElement",frame:"HTMLFrameElement",frameset:"HTMLFrameSetElement",h1:"HTMLHeadingElement",head:"HTMLHeadElement",hr:"HTMLHRElement",html:"HTMLHtmlElement",iframe:"HTMLIFrameElement",img:"HTMLImageElement",input:"HTMLInputElement",keygen:"HTMLKeygenElement",label:"HTMLLabelElement",legend:"HTMLLegendElement",li:"HTMLLIElement",link:"HTMLLinkElement",map:"HTMLMapElement",marquee:"HTMLMarqueeElement",menu:"HTMLMenuElement",menuitem:"HTMLMenuItemElement",meta:"HTMLMetaElement",meter:"HTMLMeterElement",object:"HTMLObjectElement",ol:"HTMLOListElement",optgroup:"HTMLOptGroupElement",option:"HTMLOptionElement",output:"HTMLOutputElement",p:"HTMLParagraphElement",param:"HTMLParamElement",pre:"HTMLPreElement",progress:"HTMLProgressElement",q:"HTMLQuoteElement",script:"HTMLScriptElement",select:"HTMLSelectElement",shadow:"HTMLShadowElement",source:"HTMLSourceElement",span:"HTMLSpanElement",style:"HTMLStyleElement",table:"HTMLTableElement",tbody:"HTMLTableSectionElement",template:"HTMLTemplateElement",textarea:"HTMLTextAreaElement",thead:"HTMLTableSectionElement",time:"HTMLTimeElement",title:"HTMLTitleElement",tr:"HTMLTableRowElement",track:"HTMLTrackElement",ul:"HTMLUListElement",video:"HTMLVideoElement"});Object.keys(n).forEach(t),Object.getOwnPropertyNames(e.wrappers).forEach(function(t){window[t]=e.wrappers[t]})}(window.ShadowDOMPolyfill);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/bower.json b/polymer_1.0.4/bower_components/webcomponentsjs/bower.json
new file mode 100644
index 0000000..aede49c
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/bower.json
@@ -0,0 +1,18 @@
+{
+ "name": "webcomponentsjs",
+ "main": "webcomponents.js",
+ "version": "0.7.5",
+ "homepage": "http://webcomponents.org",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/webcomponents/webcomponentsjs.git"
+ },
+ "keywords": [
+ "webcomponents"
+ ],
+ "license": "BSD",
+ "ignore": []
+}
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/build.log b/polymer_1.0.4/bower_components/webcomponentsjs/build.log
new file mode 100644
index 0000000..722c9f7
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/build.log
@@ -0,0 +1,33 @@
+BUILD LOG
+---------
+Build Time: 2015-06-17T19:01:18-0700
+
+NODEJS INFORMATION
+==================
+nodejs: v2.3.0
+gulp: 3.9.0
+gulp-audit: 1.0.0
+gulp-concat: 2.5.2
+gulp-header: 1.2.2
+gulp-uglify: 1.2.0
+run-sequence: 1.1.1
+web-component-tester: 3.2.0
+
+REPO REVISIONS
+==============
+webcomponentsjs: 1ee61faca40f109f2f5b6ddc8fa15de0319a6e61
+
+BUILD HASHES
+============
+CustomElements.js: f3f0c7f3c65aeb5cc56c64300fe89003a4c7fa31
+CustomElements.min.js: 557ccd338ab463c9bcd1e3c0fc4102455432214a
+HTMLImports.js: 8c1f33a777d7ff8ee3a22fce8d35e5b927285724
+HTMLImports.min.js: f4ba44076c40f408c661caa8baf81f9e3740689b
+MutationObserver.js: 81934731acd4175701d678dbef11aaefa7d701f5
+MutationObserver.min.js: 6202537174240ba28bf71e22cddf90ce80cf73f8
+ShadowDOM.js: 5e901cfe7eb384f15a39b1bf4e510a06ae03b43e
+ShadowDOM.min.js: 397715836fdd0cfe15a5e966f5ab187ccc1bec15
+webcomponents-lite.js: 5c38f87a645eea9d282de74340c101e5531cb2c0
+webcomponents-lite.min.js: 2a744443fbfba6b30fde7b17606f68cae6036e52
+webcomponents.js: 637cf33c1ee108fb376891eed0b5b47deed8c238
+webcomponents.min.js: c2841b948265560478872747618cad207a693c4f
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/package.json b/polymer_1.0.4/bower_components/webcomponentsjs/package.json
new file mode 100644
index 0000000..493782f
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "webcomponents.js",
+ "version": "0.7.5",
+ "description": "webcomponents.js",
+ "main": "webcomponents.js",
+ "directories": {
+ "test": "tests"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/webcomponents/webcomponentsjs.git"
+ },
+ "author": "The Polymer Authors",
+ "license": {
+ "type": "BSD-3-Clause",
+ "url": "http://polymer.github.io/LICENSE.txt"
+ },
+ "bugs": {
+ "url": "https://github.com/webcomponents/webcomponentsjs/issues"
+ },
+ "homepage": "http://webcomponents.org",
+ "devDependencies": {
+ "gulp": "^3.8.8",
+ "gulp-audit": "^1.0.0",
+ "gulp-concat": "^2.4.1",
+ "gulp-header": "^1.1.1",
+ "gulp-uglify": "^1.0.1",
+ "run-sequence": "^1.0.1",
+ "web-component-tester": "*"
+ }
+}
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/webcomponents-lite.js b/polymer_1.0.4/bower_components/webcomponentsjs/webcomponents-lite.js
new file mode 100644
index 0000000..47a7d9d
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/webcomponents-lite.js
@@ -0,0 +1,2314 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.7.5
+window.WebComponents = window.WebComponents || {};
+
+(function(scope) {
+ var flags = scope.flags || {};
+ var file = "webcomponents-lite.js";
+ var script = document.querySelector('script[src*="' + file + '"]');
+ if (!flags.noOpts) {
+ location.search.slice(1).split("&").forEach(function(option) {
+ var parts = option.split("=");
+ var match;
+ if (parts[0] && (match = parts[0].match(/wc-(.+)/))) {
+ flags[match[1]] = parts[1] || true;
+ }
+ });
+ if (script) {
+ for (var i = 0, a; a = script.attributes[i]; i++) {
+ if (a.name !== "src") {
+ flags[a.name] = a.value || true;
+ }
+ }
+ }
+ if (flags.log) {
+ var parts = flags.log.split(",");
+ flags.log = {};
+ parts.forEach(function(f) {
+ flags.log[f] = true;
+ });
+ } else {
+ flags.log = {};
+ }
+ }
+ flags.shadow = flags.shadow || flags.shadowdom || flags.polyfill;
+ if (flags.shadow === "native") {
+ flags.shadow = false;
+ } else {
+ flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot;
+ }
+ if (flags.register) {
+ window.CustomElements = window.CustomElements || {
+ flags: {}
+ };
+ window.CustomElements.flags.register = flags.register;
+ }
+ scope.flags = flags;
+})(window.WebComponents);
+
+(function(scope) {
+ "use strict";
+ var hasWorkingUrl = false;
+ if (!scope.forceJURL) {
+ try {
+ var u = new URL("b", "http://a");
+ u.pathname = "c%20d";
+ hasWorkingUrl = u.href === "http://a/c%20d";
+ } catch (e) {}
+ }
+ if (hasWorkingUrl) return;
+ var relative = Object.create(null);
+ relative["ftp"] = 21;
+ relative["file"] = 0;
+ relative["gopher"] = 70;
+ relative["http"] = 80;
+ relative["https"] = 443;
+ relative["ws"] = 80;
+ relative["wss"] = 443;
+ var relativePathDotMapping = Object.create(null);
+ relativePathDotMapping["%2e"] = ".";
+ relativePathDotMapping[".%2e"] = "..";
+ relativePathDotMapping["%2e."] = "..";
+ relativePathDotMapping["%2e%2e"] = "..";
+ function isRelativeScheme(scheme) {
+ return relative[scheme] !== undefined;
+ }
+ function invalid() {
+ clear.call(this);
+ this._isInvalid = true;
+ }
+ function IDNAToASCII(h) {
+ if ("" == h) {
+ invalid.call(this);
+ }
+ return h.toLowerCase();
+ }
+ function percentEscape(c) {
+ var unicode = c.charCodeAt(0);
+ if (unicode > 32 && unicode < 127 && [ 34, 35, 60, 62, 63, 96 ].indexOf(unicode) == -1) {
+ return c;
+ }
+ return encodeURIComponent(c);
+ }
+ function percentEscapeQuery(c) {
+ var unicode = c.charCodeAt(0);
+ if (unicode > 32 && unicode < 127 && [ 34, 35, 60, 62, 96 ].indexOf(unicode) == -1) {
+ return c;
+ }
+ return encodeURIComponent(c);
+ }
+ var EOF = undefined, ALPHA = /[a-zA-Z]/, ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
+ function parse(input, stateOverride, base) {
+ function err(message) {
+ errors.push(message);
+ }
+ var state = stateOverride || "scheme start", cursor = 0, buffer = "", seenAt = false, seenBracket = false, errors = [];
+ loop: while ((input[cursor - 1] != EOF || cursor == 0) && !this._isInvalid) {
+ var c = input[cursor];
+ switch (state) {
+ case "scheme start":
+ if (c && ALPHA.test(c)) {
+ buffer += c.toLowerCase();
+ state = "scheme";
+ } else if (!stateOverride) {
+ buffer = "";
+ state = "no scheme";
+ continue;
+ } else {
+ err("Invalid scheme.");
+ break loop;
+ }
+ break;
+
+ case "scheme":
+ if (c && ALPHANUMERIC.test(c)) {
+ buffer += c.toLowerCase();
+ } else if (":" == c) {
+ this._scheme = buffer;
+ buffer = "";
+ if (stateOverride) {
+ break loop;
+ }
+ if (isRelativeScheme(this._scheme)) {
+ this._isRelative = true;
+ }
+ if ("file" == this._scheme) {
+ state = "relative";
+ } else if (this._isRelative && base && base._scheme == this._scheme) {
+ state = "relative or authority";
+ } else if (this._isRelative) {
+ state = "authority first slash";
+ } else {
+ state = "scheme data";
+ }
+ } else if (!stateOverride) {
+ buffer = "";
+ cursor = 0;
+ state = "no scheme";
+ continue;
+ } else if (EOF == c) {
+ break loop;
+ } else {
+ err("Code point not allowed in scheme: " + c);
+ break loop;
+ }
+ break;
+
+ case "scheme data":
+ if ("?" == c) {
+ this._query = "?";
+ state = "query";
+ } else if ("#" == c) {
+ this._fragment = "#";
+ state = "fragment";
+ } else {
+ if (EOF != c && " " != c && "\n" != c && "\r" != c) {
+ this._schemeData += percentEscape(c);
+ }
+ }
+ break;
+
+ case "no scheme":
+ if (!base || !isRelativeScheme(base._scheme)) {
+ err("Missing scheme.");
+ invalid.call(this);
+ } else {
+ state = "relative";
+ continue;
+ }
+ break;
+
+ case "relative or authority":
+ if ("/" == c && "/" == input[cursor + 1]) {
+ state = "authority ignore slashes";
+ } else {
+ err("Expected /, got: " + c);
+ state = "relative";
+ continue;
+ }
+ break;
+
+ case "relative":
+ this._isRelative = true;
+ if ("file" != this._scheme) this._scheme = base._scheme;
+ if (EOF == c) {
+ this._host = base._host;
+ this._port = base._port;
+ this._path = base._path.slice();
+ this._query = base._query;
+ this._username = base._username;
+ this._password = base._password;
+ break loop;
+ } else if ("/" == c || "\\" == c) {
+ if ("\\" == c) err("\\ is an invalid code point.");
+ state = "relative slash";
+ } else if ("?" == c) {
+ this._host = base._host;
+ this._port = base._port;
+ this._path = base._path.slice();
+ this._query = "?";
+ this._username = base._username;
+ this._password = base._password;
+ state = "query";
+ } else if ("#" == c) {
+ this._host = base._host;
+ this._port = base._port;
+ this._path = base._path.slice();
+ this._query = base._query;
+ this._fragment = "#";
+ this._username = base._username;
+ this._password = base._password;
+ state = "fragment";
+ } else {
+ var nextC = input[cursor + 1];
+ var nextNextC = input[cursor + 2];
+ if ("file" != this._scheme || !ALPHA.test(c) || nextC != ":" && nextC != "|" || EOF != nextNextC && "/" != nextNextC && "\\" != nextNextC && "?" != nextNextC && "#" != nextNextC) {
+ this._host = base._host;
+ this._port = base._port;
+ this._username = base._username;
+ this._password = base._password;
+ this._path = base._path.slice();
+ this._path.pop();
+ }
+ state = "relative path";
+ continue;
+ }
+ break;
+
+ case "relative slash":
+ if ("/" == c || "\\" == c) {
+ if ("\\" == c) {
+ err("\\ is an invalid code point.");
+ }
+ if ("file" == this._scheme) {
+ state = "file host";
+ } else {
+ state = "authority ignore slashes";
+ }
+ } else {
+ if ("file" != this._scheme) {
+ this._host = base._host;
+ this._port = base._port;
+ this._username = base._username;
+ this._password = base._password;
+ }
+ state = "relative path";
+ continue;
+ }
+ break;
+
+ case "authority first slash":
+ if ("/" == c) {
+ state = "authority second slash";
+ } else {
+ err("Expected '/', got: " + c);
+ state = "authority ignore slashes";
+ continue;
+ }
+ break;
+
+ case "authority second slash":
+ state = "authority ignore slashes";
+ if ("/" != c) {
+ err("Expected '/', got: " + c);
+ continue;
+ }
+ break;
+
+ case "authority ignore slashes":
+ if ("/" != c && "\\" != c) {
+ state = "authority";
+ continue;
+ } else {
+ err("Expected authority, got: " + c);
+ }
+ break;
+
+ case "authority":
+ if ("@" == c) {
+ if (seenAt) {
+ err("@ already seen.");
+ buffer += "%40";
+ }
+ seenAt = true;
+ for (var i = 0; i < buffer.length; i++) {
+ var cp = buffer[i];
+ if (" " == cp || "\n" == cp || "\r" == cp) {
+ err("Invalid whitespace in authority.");
+ continue;
+ }
+ if (":" == cp && null === this._password) {
+ this._password = "";
+ continue;
+ }
+ var tempC = percentEscape(cp);
+ null !== this._password ? this._password += tempC : this._username += tempC;
+ }
+ buffer = "";
+ } else if (EOF == c || "/" == c || "\\" == c || "?" == c || "#" == c) {
+ cursor -= buffer.length;
+ buffer = "";
+ state = "host";
+ continue;
+ } else {
+ buffer += c;
+ }
+ break;
+
+ case "file host":
+ if (EOF == c || "/" == c || "\\" == c || "?" == c || "#" == c) {
+ if (buffer.length == 2 && ALPHA.test(buffer[0]) && (buffer[1] == ":" || buffer[1] == "|")) {
+ state = "relative path";
+ } else if (buffer.length == 0) {
+ state = "relative path start";
+ } else {
+ this._host = IDNAToASCII.call(this, buffer);
+ buffer = "";
+ state = "relative path start";
+ }
+ continue;
+ } else if (" " == c || "\n" == c || "\r" == c) {
+ err("Invalid whitespace in file host.");
+ } else {
+ buffer += c;
+ }
+ break;
+
+ case "host":
+ case "hostname":
+ if (":" == c && !seenBracket) {
+ this._host = IDNAToASCII.call(this, buffer);
+ buffer = "";
+ state = "port";
+ if ("hostname" == stateOverride) {
+ break loop;
+ }
+ } else if (EOF == c || "/" == c || "\\" == c || "?" == c || "#" == c) {
+ this._host = IDNAToASCII.call(this, buffer);
+ buffer = "";
+ state = "relative path start";
+ if (stateOverride) {
+ break loop;
+ }
+ continue;
+ } else if (" " != c && "\n" != c && "\r" != c) {
+ if ("[" == c) {
+ seenBracket = true;
+ } else if ("]" == c) {
+ seenBracket = false;
+ }
+ buffer += c;
+ } else {
+ err("Invalid code point in host/hostname: " + c);
+ }
+ break;
+
+ case "port":
+ if (/[0-9]/.test(c)) {
+ buffer += c;
+ } else if (EOF == c || "/" == c || "\\" == c || "?" == c || "#" == c || stateOverride) {
+ if ("" != buffer) {
+ var temp = parseInt(buffer, 10);
+ if (temp != relative[this._scheme]) {
+ this._port = temp + "";
+ }
+ buffer = "";
+ }
+ if (stateOverride) {
+ break loop;
+ }
+ state = "relative path start";
+ continue;
+ } else if (" " == c || "\n" == c || "\r" == c) {
+ err("Invalid code point in port: " + c);
+ } else {
+ invalid.call(this);
+ }
+ break;
+
+ case "relative path start":
+ if ("\\" == c) err("'\\' not allowed in path.");
+ state = "relative path";
+ if ("/" != c && "\\" != c) {
+ continue;
+ }
+ break;
+
+ case "relative path":
+ if (EOF == c || "/" == c || "\\" == c || !stateOverride && ("?" == c || "#" == c)) {
+ if ("\\" == c) {
+ err("\\ not allowed in relative path.");
+ }
+ var tmp;
+ if (tmp = relativePathDotMapping[buffer.toLowerCase()]) {
+ buffer = tmp;
+ }
+ if (".." == buffer) {
+ this._path.pop();
+ if ("/" != c && "\\" != c) {
+ this._path.push("");
+ }
+ } else if ("." == buffer && "/" != c && "\\" != c) {
+ this._path.push("");
+ } else if ("." != buffer) {
+ if ("file" == this._scheme && this._path.length == 0 && buffer.length == 2 && ALPHA.test(buffer[0]) && buffer[1] == "|") {
+ buffer = buffer[0] + ":";
+ }
+ this._path.push(buffer);
+ }
+ buffer = "";
+ if ("?" == c) {
+ this._query = "?";
+ state = "query";
+ } else if ("#" == c) {
+ this._fragment = "#";
+ state = "fragment";
+ }
+ } else if (" " != c && "\n" != c && "\r" != c) {
+ buffer += percentEscape(c);
+ }
+ break;
+
+ case "query":
+ if (!stateOverride && "#" == c) {
+ this._fragment = "#";
+ state = "fragment";
+ } else if (EOF != c && " " != c && "\n" != c && "\r" != c) {
+ this._query += percentEscapeQuery(c);
+ }
+ break;
+
+ case "fragment":
+ if (EOF != c && " " != c && "\n" != c && "\r" != c) {
+ this._fragment += c;
+ }
+ break;
+ }
+ cursor++;
+ }
+ }
+ function clear() {
+ this._scheme = "";
+ this._schemeData = "";
+ this._username = "";
+ this._password = null;
+ this._host = "";
+ this._port = "";
+ this._path = [];
+ this._query = "";
+ this._fragment = "";
+ this._isInvalid = false;
+ this._isRelative = false;
+ }
+ function jURL(url, base) {
+ if (base !== undefined && !(base instanceof jURL)) base = new jURL(String(base));
+ this._url = url;
+ clear.call(this);
+ var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, "");
+ parse.call(this, input, null, base);
+ }
+ jURL.prototype = {
+ toString: function() {
+ return this.href;
+ },
+ get href() {
+ if (this._isInvalid) return this._url;
+ var authority = "";
+ if ("" != this._username || null != this._password) {
+ authority = this._username + (null != this._password ? ":" + this._password : "") + "@";
+ }
+ return this.protocol + (this._isRelative ? "//" + authority + this.host : "") + this.pathname + this._query + this._fragment;
+ },
+ set href(href) {
+ clear.call(this);
+ parse.call(this, href);
+ },
+ get protocol() {
+ return this._scheme + ":";
+ },
+ set protocol(protocol) {
+ if (this._isInvalid) return;
+ parse.call(this, protocol + ":", "scheme start");
+ },
+ get host() {
+ return this._isInvalid ? "" : this._port ? this._host + ":" + this._port : this._host;
+ },
+ set host(host) {
+ if (this._isInvalid || !this._isRelative) return;
+ parse.call(this, host, "host");
+ },
+ get hostname() {
+ return this._host;
+ },
+ set hostname(hostname) {
+ if (this._isInvalid || !this._isRelative) return;
+ parse.call(this, hostname, "hostname");
+ },
+ get port() {
+ return this._port;
+ },
+ set port(port) {
+ if (this._isInvalid || !this._isRelative) return;
+ parse.call(this, port, "port");
+ },
+ get pathname() {
+ return this._isInvalid ? "" : this._isRelative ? "/" + this._path.join("/") : this._schemeData;
+ },
+ set pathname(pathname) {
+ if (this._isInvalid || !this._isRelative) return;
+ this._path = [];
+ parse.call(this, pathname, "relative path start");
+ },
+ get search() {
+ return this._isInvalid || !this._query || "?" == this._query ? "" : this._query;
+ },
+ set search(search) {
+ if (this._isInvalid || !this._isRelative) return;
+ this._query = "?";
+ if ("?" == search[0]) search = search.slice(1);
+ parse.call(this, search, "query");
+ },
+ get hash() {
+ return this._isInvalid || !this._fragment || "#" == this._fragment ? "" : this._fragment;
+ },
+ set hash(hash) {
+ if (this._isInvalid) return;
+ this._fragment = "#";
+ if ("#" == hash[0]) hash = hash.slice(1);
+ parse.call(this, hash, "fragment");
+ },
+ get origin() {
+ var host;
+ if (this._isInvalid || !this._scheme) {
+ return "";
+ }
+ switch (this._scheme) {
+ case "data":
+ case "file":
+ case "javascript":
+ case "mailto":
+ return "null";
+ }
+ host = this.host;
+ if (!host) {
+ return "";
+ }
+ return this._scheme + "://" + host;
+ }
+ };
+ var OriginalURL = scope.URL;
+ if (OriginalURL) {
+ jURL.createObjectURL = function(blob) {
+ return OriginalURL.createObjectURL.apply(OriginalURL, arguments);
+ };
+ jURL.revokeObjectURL = function(url) {
+ OriginalURL.revokeObjectURL(url);
+ };
+ }
+ scope.URL = jURL;
+})(this);
+
+if (typeof WeakMap === "undefined") {
+ (function() {
+ var defineProperty = Object.defineProperty;
+ var counter = Date.now() % 1e9;
+ var WeakMap = function() {
+ this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
+ };
+ WeakMap.prototype = {
+ set: function(key, value) {
+ var entry = key[this.name];
+ if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
+ value: [ key, value ],
+ writable: true
+ });
+ return this;
+ },
+ get: function(key) {
+ var entry;
+ return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
+ },
+ "delete": function(key) {
+ var entry = key[this.name];
+ if (!entry || entry[0] !== key) return false;
+ entry[0] = entry[1] = undefined;
+ return true;
+ },
+ has: function(key) {
+ var entry = key[this.name];
+ if (!entry) return false;
+ return entry[0] === key;
+ }
+ };
+ window.WeakMap = WeakMap;
+ })();
+}
+
+(function(global) {
+ var registrationsTable = new WeakMap();
+ var setImmediate;
+ if (/Trident|Edge/.test(navigator.userAgent)) {
+ setImmediate = setTimeout;
+ } else if (window.setImmediate) {
+ setImmediate = window.setImmediate;
+ } else {
+ var setImmediateQueue = [];
+ var sentinel = String(Math.random());
+ window.addEventListener("message", function(e) {
+ if (e.data === sentinel) {
+ var queue = setImmediateQueue;
+ setImmediateQueue = [];
+ queue.forEach(function(func) {
+ func();
+ });
+ }
+ });
+ setImmediate = function(func) {
+ setImmediateQueue.push(func);
+ window.postMessage(sentinel, "*");
+ };
+ }
+ var isScheduled = false;
+ var scheduledObservers = [];
+ function scheduleCallback(observer) {
+ scheduledObservers.push(observer);
+ if (!isScheduled) {
+ isScheduled = true;
+ setImmediate(dispatchCallbacks);
+ }
+ }
+ function wrapIfNeeded(node) {
+ return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;
+ }
+ function dispatchCallbacks() {
+ isScheduled = false;
+ var observers = scheduledObservers;
+ scheduledObservers = [];
+ observers.sort(function(o1, o2) {
+ return o1.uid_ - o2.uid_;
+ });
+ var anyNonEmpty = false;
+ observers.forEach(function(observer) {
+ var queue = observer.takeRecords();
+ removeTransientObserversFor(observer);
+ if (queue.length) {
+ observer.callback_(queue, observer);
+ anyNonEmpty = true;
+ }
+ });
+ if (anyNonEmpty) dispatchCallbacks();
+ }
+ function removeTransientObserversFor(observer) {
+ observer.nodes_.forEach(function(node) {
+ var registrations = registrationsTable.get(node);
+ if (!registrations) return;
+ registrations.forEach(function(registration) {
+ if (registration.observer === observer) registration.removeTransientObservers();
+ });
+ });
+ }
+ function forEachAncestorAndObserverEnqueueRecord(target, callback) {
+ for (var node = target; node; node = node.parentNode) {
+ var registrations = registrationsTable.get(node);
+ if (registrations) {
+ for (var j = 0; j < registrations.length; j++) {
+ var registration = registrations[j];
+ var options = registration.options;
+ if (node !== target && !options.subtree) continue;
+ var record = callback(options);
+ if (record) registration.enqueue(record);
+ }
+ }
+ }
+ }
+ var uidCounter = 0;
+ function JsMutationObserver(callback) {
+ this.callback_ = callback;
+ this.nodes_ = [];
+ this.records_ = [];
+ this.uid_ = ++uidCounter;
+ }
+ JsMutationObserver.prototype = {
+ observe: function(target, options) {
+ target = wrapIfNeeded(target);
+ if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {
+ throw new SyntaxError();
+ }
+ var registrations = registrationsTable.get(target);
+ if (!registrations) registrationsTable.set(target, registrations = []);
+ var registration;
+ for (var i = 0; i < registrations.length; i++) {
+ if (registrations[i].observer === this) {
+ registration = registrations[i];
+ registration.removeListeners();
+ registration.options = options;
+ break;
+ }
+ }
+ if (!registration) {
+ registration = new Registration(this, target, options);
+ registrations.push(registration);
+ this.nodes_.push(target);
+ }
+ registration.addListeners();
+ },
+ disconnect: function() {
+ this.nodes_.forEach(function(node) {
+ var registrations = registrationsTable.get(node);
+ for (var i = 0; i < registrations.length; i++) {
+ var registration = registrations[i];
+ if (registration.observer === this) {
+ registration.removeListeners();
+ registrations.splice(i, 1);
+ break;
+ }
+ }
+ }, this);
+ this.records_ = [];
+ },
+ takeRecords: function() {
+ var copyOfRecords = this.records_;
+ this.records_ = [];
+ return copyOfRecords;
+ }
+ };
+ function MutationRecord(type, target) {
+ this.type = type;
+ this.target = target;
+ this.addedNodes = [];
+ this.removedNodes = [];
+ this.previousSibling = null;
+ this.nextSibling = null;
+ this.attributeName = null;
+ this.attributeNamespace = null;
+ this.oldValue = null;
+ }
+ function copyMutationRecord(original) {
+ var record = new MutationRecord(original.type, original.target);
+ record.addedNodes = original.addedNodes.slice();
+ record.removedNodes = original.removedNodes.slice();
+ record.previousSibling = original.previousSibling;
+ record.nextSibling = original.nextSibling;
+ record.attributeName = original.attributeName;
+ record.attributeNamespace = original.attributeNamespace;
+ record.oldValue = original.oldValue;
+ return record;
+ }
+ var currentRecord, recordWithOldValue;
+ function getRecord(type, target) {
+ return currentRecord = new MutationRecord(type, target);
+ }
+ function getRecordWithOldValue(oldValue) {
+ if (recordWithOldValue) return recordWithOldValue;
+ recordWithOldValue = copyMutationRecord(currentRecord);
+ recordWithOldValue.oldValue = oldValue;
+ return recordWithOldValue;
+ }
+ function clearRecords() {
+ currentRecord = recordWithOldValue = undefined;
+ }
+ function recordRepresentsCurrentMutation(record) {
+ return record === recordWithOldValue || record === currentRecord;
+ }
+ function selectRecord(lastRecord, newRecord) {
+ if (lastRecord === newRecord) return lastRecord;
+ if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;
+ return null;
+ }
+ function Registration(observer, target, options) {
+ this.observer = observer;
+ this.target = target;
+ this.options = options;
+ this.transientObservedNodes = [];
+ }
+ Registration.prototype = {
+ enqueue: function(record) {
+ var records = this.observer.records_;
+ var length = records.length;
+ if (records.length > 0) {
+ var lastRecord = records[length - 1];
+ var recordToReplaceLast = selectRecord(lastRecord, record);
+ if (recordToReplaceLast) {
+ records[length - 1] = recordToReplaceLast;
+ return;
+ }
+ } else {
+ scheduleCallback(this.observer);
+ }
+ records[length] = record;
+ },
+ addListeners: function() {
+ this.addListeners_(this.target);
+ },
+ addListeners_: function(node) {
+ var options = this.options;
+ if (options.attributes) node.addEventListener("DOMAttrModified", this, true);
+ if (options.characterData) node.addEventListener("DOMCharacterDataModified", this, true);
+ if (options.childList) node.addEventListener("DOMNodeInserted", this, true);
+ if (options.childList || options.subtree) node.addEventListener("DOMNodeRemoved", this, true);
+ },
+ removeListeners: function() {
+ this.removeListeners_(this.target);
+ },
+ removeListeners_: function(node) {
+ var options = this.options;
+ if (options.attributes) node.removeEventListener("DOMAttrModified", this, true);
+ if (options.characterData) node.removeEventListener("DOMCharacterDataModified", this, true);
+ if (options.childList) node.removeEventListener("DOMNodeInserted", this, true);
+ if (options.childList || options.subtree) node.removeEventListener("DOMNodeRemoved", this, true);
+ },
+ addTransientObserver: function(node) {
+ if (node === this.target) return;
+ this.addListeners_(node);
+ this.transientObservedNodes.push(node);
+ var registrations = registrationsTable.get(node);
+ if (!registrations) registrationsTable.set(node, registrations = []);
+ registrations.push(this);
+ },
+ removeTransientObservers: function() {
+ var transientObservedNodes = this.transientObservedNodes;
+ this.transientObservedNodes = [];
+ transientObservedNodes.forEach(function(node) {
+ this.removeListeners_(node);
+ var registrations = registrationsTable.get(node);
+ for (var i = 0; i < registrations.length; i++) {
+ if (registrations[i] === this) {
+ registrations.splice(i, 1);
+ break;
+ }
+ }
+ }, this);
+ },
+ handleEvent: function(e) {
+ e.stopImmediatePropagation();
+ switch (e.type) {
+ case "DOMAttrModified":
+ var name = e.attrName;
+ var namespace = e.relatedNode.namespaceURI;
+ var target = e.target;
+ var record = new getRecord("attributes", target);
+ record.attributeName = name;
+ record.attributeNamespace = namespace;
+ var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
+ forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+ if (!options.attributes) return;
+ if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {
+ return;
+ }
+ if (options.attributeOldValue) return getRecordWithOldValue(oldValue);
+ return record;
+ });
+ break;
+
+ case "DOMCharacterDataModified":
+ var target = e.target;
+ var record = getRecord("characterData", target);
+ var oldValue = e.prevValue;
+ forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+ if (!options.characterData) return;
+ if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);
+ return record;
+ });
+ break;
+
+ case "DOMNodeRemoved":
+ this.addTransientObserver(e.target);
+
+ case "DOMNodeInserted":
+ var changedNode = e.target;
+ var addedNodes, removedNodes;
+ if (e.type === "DOMNodeInserted") {
+ addedNodes = [ changedNode ];
+ removedNodes = [];
+ } else {
+ addedNodes = [];
+ removedNodes = [ changedNode ];
+ }
+ var previousSibling = changedNode.previousSibling;
+ var nextSibling = changedNode.nextSibling;
+ var record = getRecord("childList", e.target.parentNode);
+ record.addedNodes = addedNodes;
+ record.removedNodes = removedNodes;
+ record.previousSibling = previousSibling;
+ record.nextSibling = nextSibling;
+ forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) {
+ if (!options.childList) return;
+ return record;
+ });
+ }
+ clearRecords();
+ }
+ };
+ global.JsMutationObserver = JsMutationObserver;
+ if (!global.MutationObserver) global.MutationObserver = JsMutationObserver;
+})(this);
+
+window.HTMLImports = window.HTMLImports || {
+ flags: {}
+};
+
+(function(scope) {
+ var IMPORT_LINK_TYPE = "import";
+ var useNative = Boolean(IMPORT_LINK_TYPE in document.createElement("link"));
+ var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);
+ var wrap = function(node) {
+ return hasShadowDOMPolyfill ? window.ShadowDOMPolyfill.wrapIfNeeded(node) : node;
+ };
+ var rootDocument = wrap(document);
+ var currentScriptDescriptor = {
+ get: function() {
+ var script = window.HTMLImports.currentScript || document.currentScript || (document.readyState !== "complete" ? document.scripts[document.scripts.length - 1] : null);
+ return wrap(script);
+ },
+ configurable: true
+ };
+ Object.defineProperty(document, "_currentScript", currentScriptDescriptor);
+ Object.defineProperty(rootDocument, "_currentScript", currentScriptDescriptor);
+ var isIE = /Trident/.test(navigator.userAgent);
+ function whenReady(callback, doc) {
+ doc = doc || rootDocument;
+ whenDocumentReady(function() {
+ watchImportsLoad(callback, doc);
+ }, doc);
+ }
+ var requiredReadyState = isIE ? "complete" : "interactive";
+ var READY_EVENT = "readystatechange";
+ function isDocumentReady(doc) {
+ return doc.readyState === "complete" || doc.readyState === requiredReadyState;
+ }
+ function whenDocumentReady(callback, doc) {
+ if (!isDocumentReady(doc)) {
+ var checkReady = function() {
+ if (doc.readyState === "complete" || doc.readyState === requiredReadyState) {
+ doc.removeEventListener(READY_EVENT, checkReady);
+ whenDocumentReady(callback, doc);
+ }
+ };
+ doc.addEventListener(READY_EVENT, checkReady);
+ } else if (callback) {
+ callback();
+ }
+ }
+ function markTargetLoaded(event) {
+ event.target.__loaded = true;
+ }
+ function watchImportsLoad(callback, doc) {
+ var imports = doc.querySelectorAll("link[rel=import]");
+ var parsedCount = 0, importCount = imports.length, newImports = [], errorImports = [];
+ function checkDone() {
+ if (parsedCount == importCount && callback) {
+ callback({
+ allImports: imports,
+ loadedImports: newImports,
+ errorImports: errorImports
+ });
+ }
+ }
+ function loadedImport(e) {
+ markTargetLoaded(e);
+ newImports.push(this);
+ parsedCount++;
+ checkDone();
+ }
+ function errorLoadingImport(e) {
+ errorImports.push(this);
+ parsedCount++;
+ checkDone();
+ }
+ if (importCount) {
+ for (var i = 0, imp; i < importCount && (imp = imports[i]); i++) {
+ if (isImportLoaded(imp)) {
+ parsedCount++;
+ checkDone();
+ } else {
+ imp.addEventListener("load", loadedImport);
+ imp.addEventListener("error", errorLoadingImport);
+ }
+ }
+ } else {
+ checkDone();
+ }
+ }
+ function isImportLoaded(link) {
+ return useNative ? link.__loaded || link.import && link.import.readyState !== "loading" : link.__importParsed;
+ }
+ if (useNative) {
+ new MutationObserver(function(mxns) {
+ for (var i = 0, l = mxns.length, m; i < l && (m = mxns[i]); i++) {
+ if (m.addedNodes) {
+ handleImports(m.addedNodes);
+ }
+ }
+ }).observe(document.head, {
+ childList: true
+ });
+ function handleImports(nodes) {
+ for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+ if (isImport(n)) {
+ handleImport(n);
+ }
+ }
+ }
+ function isImport(element) {
+ return element.localName === "link" && element.rel === "import";
+ }
+ function handleImport(element) {
+ var loaded = element.import;
+ if (loaded) {
+ markTargetLoaded({
+ target: element
+ });
+ } else {
+ element.addEventListener("load", markTargetLoaded);
+ element.addEventListener("error", markTargetLoaded);
+ }
+ }
+ (function() {
+ if (document.readyState === "loading") {
+ var imports = document.querySelectorAll("link[rel=import]");
+ for (var i = 0, l = imports.length, imp; i < l && (imp = imports[i]); i++) {
+ handleImport(imp);
+ }
+ }
+ })();
+ }
+ whenReady(function(detail) {
+ window.HTMLImports.ready = true;
+ window.HTMLImports.readyTime = new Date().getTime();
+ var evt = rootDocument.createEvent("CustomEvent");
+ evt.initCustomEvent("HTMLImportsLoaded", true, true, detail);
+ rootDocument.dispatchEvent(evt);
+ });
+ scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
+ scope.useNative = useNative;
+ scope.rootDocument = rootDocument;
+ scope.whenReady = whenReady;
+ scope.isIE = isIE;
+})(window.HTMLImports);
+
+(function(scope) {
+ var modules = [];
+ var addModule = function(module) {
+ modules.push(module);
+ };
+ var initializeModules = function() {
+ modules.forEach(function(module) {
+ module(scope);
+ });
+ };
+ scope.addModule = addModule;
+ scope.initializeModules = initializeModules;
+})(window.HTMLImports);
+
+window.HTMLImports.addModule(function(scope) {
+ var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
+ var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
+ var path = {
+ resolveUrlsInStyle: function(style, linkUrl) {
+ var doc = style.ownerDocument;
+ var resolver = doc.createElement("a");
+ style.textContent = this.resolveUrlsInCssText(style.textContent, linkUrl, resolver);
+ return style;
+ },
+ resolveUrlsInCssText: function(cssText, linkUrl, urlObj) {
+ var r = this.replaceUrls(cssText, urlObj, linkUrl, CSS_URL_REGEXP);
+ r = this.replaceUrls(r, urlObj, linkUrl, CSS_IMPORT_REGEXP);
+ return r;
+ },
+ replaceUrls: function(text, urlObj, linkUrl, regexp) {
+ return text.replace(regexp, function(m, pre, url, post) {
+ var urlPath = url.replace(/["']/g, "");
+ if (linkUrl) {
+ urlPath = new URL(urlPath, linkUrl).href;
+ }
+ urlObj.href = urlPath;
+ urlPath = urlObj.href;
+ return pre + "'" + urlPath + "'" + post;
+ });
+ }
+ };
+ scope.path = path;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var xhr = {
+ async: true,
+ ok: function(request) {
+ return request.status >= 200 && request.status < 300 || request.status === 304 || request.status === 0;
+ },
+ load: function(url, next, nextContext) {
+ var request = new XMLHttpRequest();
+ if (scope.flags.debug || scope.flags.bust) {
+ url += "?" + Math.random();
+ }
+ request.open("GET", url, xhr.async);
+ request.addEventListener("readystatechange", function(e) {
+ if (request.readyState === 4) {
+ var locationHeader = request.getResponseHeader("Location");
+ var redirectedUrl = null;
+ if (locationHeader) {
+ var redirectedUrl = locationHeader.substr(0, 1) === "/" ? location.origin + locationHeader : locationHeader;
+ }
+ next.call(nextContext, !xhr.ok(request) && request, request.response || request.responseText, redirectedUrl);
+ }
+ });
+ request.send();
+ return request;
+ },
+ loadDocument: function(url, next, nextContext) {
+ this.load(url, next, nextContext).responseType = "document";
+ }
+ };
+ scope.xhr = xhr;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var xhr = scope.xhr;
+ var flags = scope.flags;
+ var Loader = function(onLoad, onComplete) {
+ this.cache = {};
+ this.onload = onLoad;
+ this.oncomplete = onComplete;
+ this.inflight = 0;
+ this.pending = {};
+ };
+ Loader.prototype = {
+ addNodes: function(nodes) {
+ this.inflight += nodes.length;
+ for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+ this.require(n);
+ }
+ this.checkDone();
+ },
+ addNode: function(node) {
+ this.inflight++;
+ this.require(node);
+ this.checkDone();
+ },
+ require: function(elt) {
+ var url = elt.src || elt.href;
+ elt.__nodeUrl = url;
+ if (!this.dedupe(url, elt)) {
+ this.fetch(url, elt);
+ }
+ },
+ dedupe: function(url, elt) {
+ if (this.pending[url]) {
+ this.pending[url].push(elt);
+ return true;
+ }
+ var resource;
+ if (this.cache[url]) {
+ this.onload(url, elt, this.cache[url]);
+ this.tail();
+ return true;
+ }
+ this.pending[url] = [ elt ];
+ return false;
+ },
+ fetch: function(url, elt) {
+ flags.load && console.log("fetch", url, elt);
+ if (!url) {
+ setTimeout(function() {
+ this.receive(url, elt, {
+ error: "href must be specified"
+ }, null);
+ }.bind(this), 0);
+ } else if (url.match(/^data:/)) {
+ var pieces = url.split(",");
+ var header = pieces[0];
+ var body = pieces[1];
+ if (header.indexOf(";base64") > -1) {
+ body = atob(body);
+ } else {
+ body = decodeURIComponent(body);
+ }
+ setTimeout(function() {
+ this.receive(url, elt, null, body);
+ }.bind(this), 0);
+ } else {
+ var receiveXhr = function(err, resource, redirectedUrl) {
+ this.receive(url, elt, err, resource, redirectedUrl);
+ }.bind(this);
+ xhr.load(url, receiveXhr);
+ }
+ },
+ receive: function(url, elt, err, resource, redirectedUrl) {
+ this.cache[url] = resource;
+ var $p = this.pending[url];
+ for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
+ this.onload(url, p, resource, err, redirectedUrl);
+ this.tail();
+ }
+ this.pending[url] = null;
+ },
+ tail: function() {
+ --this.inflight;
+ this.checkDone();
+ },
+ checkDone: function() {
+ if (!this.inflight) {
+ this.oncomplete();
+ }
+ }
+ };
+ scope.Loader = Loader;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var Observer = function(addCallback) {
+ this.addCallback = addCallback;
+ this.mo = new MutationObserver(this.handler.bind(this));
+ };
+ Observer.prototype = {
+ handler: function(mutations) {
+ for (var i = 0, l = mutations.length, m; i < l && (m = mutations[i]); i++) {
+ if (m.type === "childList" && m.addedNodes.length) {
+ this.addedNodes(m.addedNodes);
+ }
+ }
+ },
+ addedNodes: function(nodes) {
+ if (this.addCallback) {
+ this.addCallback(nodes);
+ }
+ for (var i = 0, l = nodes.length, n, loading; i < l && (n = nodes[i]); i++) {
+ if (n.children && n.children.length) {
+ this.addedNodes(n.children);
+ }
+ }
+ },
+ observe: function(root) {
+ this.mo.observe(root, {
+ childList: true,
+ subtree: true
+ });
+ }
+ };
+ scope.Observer = Observer;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var path = scope.path;
+ var rootDocument = scope.rootDocument;
+ var flags = scope.flags;
+ var isIE = scope.isIE;
+ var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
+ var IMPORT_SELECTOR = "link[rel=" + IMPORT_LINK_TYPE + "]";
+ var importParser = {
+ documentSelectors: IMPORT_SELECTOR,
+ importsSelectors: [ IMPORT_SELECTOR, "link[rel=stylesheet]", "style", "script:not([type])", 'script[type="application/javascript"]', 'script[type="text/javascript"]' ].join(","),
+ map: {
+ link: "parseLink",
+ script: "parseScript",
+ style: "parseStyle"
+ },
+ dynamicElements: [],
+ parseNext: function() {
+ var next = this.nextToParse();
+ if (next) {
+ this.parse(next);
+ }
+ },
+ parse: function(elt) {
+ if (this.isParsed(elt)) {
+ flags.parse && console.log("[%s] is already parsed", elt.localName);
+ return;
+ }
+ var fn = this[this.map[elt.localName]];
+ if (fn) {
+ this.markParsing(elt);
+ fn.call(this, elt);
+ }
+ },
+ parseDynamic: function(elt, quiet) {
+ this.dynamicElements.push(elt);
+ if (!quiet) {
+ this.parseNext();
+ }
+ },
+ markParsing: function(elt) {
+ flags.parse && console.log("parsing", elt);
+ this.parsingElement = elt;
+ },
+ markParsingComplete: function(elt) {
+ elt.__importParsed = true;
+ this.markDynamicParsingComplete(elt);
+ if (elt.__importElement) {
+ elt.__importElement.__importParsed = true;
+ this.markDynamicParsingComplete(elt.__importElement);
+ }
+ this.parsingElement = null;
+ flags.parse && console.log("completed", elt);
+ },
+ markDynamicParsingComplete: function(elt) {
+ var i = this.dynamicElements.indexOf(elt);
+ if (i >= 0) {
+ this.dynamicElements.splice(i, 1);
+ }
+ },
+ parseImport: function(elt) {
+ if (window.HTMLImports.__importsParsingHook) {
+ window.HTMLImports.__importsParsingHook(elt);
+ }
+ if (elt.import) {
+ elt.import.__importParsed = true;
+ }
+ this.markParsingComplete(elt);
+ if (elt.__resource && !elt.__error) {
+ elt.dispatchEvent(new CustomEvent("load", {
+ bubbles: false
+ }));
+ } else {
+ elt.dispatchEvent(new CustomEvent("error", {
+ bubbles: false
+ }));
+ }
+ if (elt.__pending) {
+ var fn;
+ while (elt.__pending.length) {
+ fn = elt.__pending.shift();
+ if (fn) {
+ fn({
+ target: elt
+ });
+ }
+ }
+ }
+ this.parseNext();
+ },
+ parseLink: function(linkElt) {
+ if (nodeIsImport(linkElt)) {
+ this.parseImport(linkElt);
+ } else {
+ linkElt.href = linkElt.href;
+ this.parseGeneric(linkElt);
+ }
+ },
+ parseStyle: function(elt) {
+ var src = elt;
+ elt = cloneStyle(elt);
+ src.__appliedElement = elt;
+ elt.__importElement = src;
+ this.parseGeneric(elt);
+ },
+ parseGeneric: function(elt) {
+ this.trackElement(elt);
+ this.addElementToDocument(elt);
+ },
+ rootImportForElement: function(elt) {
+ var n = elt;
+ while (n.ownerDocument.__importLink) {
+ n = n.ownerDocument.__importLink;
+ }
+ return n;
+ },
+ addElementToDocument: function(elt) {
+ var port = this.rootImportForElement(elt.__importElement || elt);
+ port.parentNode.insertBefore(elt, port);
+ },
+ trackElement: function(elt, callback) {
+ var self = this;
+ var done = function(e) {
+ if (callback) {
+ callback(e);
+ }
+ self.markParsingComplete(elt);
+ self.parseNext();
+ };
+ elt.addEventListener("load", done);
+ elt.addEventListener("error", done);
+ if (isIE && elt.localName === "style") {
+ var fakeLoad = false;
+ if (elt.textContent.indexOf("@import") == -1) {
+ fakeLoad = true;
+ } else if (elt.sheet) {
+ fakeLoad = true;
+ var csr = elt.sheet.cssRules;
+ var len = csr ? csr.length : 0;
+ for (var i = 0, r; i < len && (r = csr[i]); i++) {
+ if (r.type === CSSRule.IMPORT_RULE) {
+ fakeLoad = fakeLoad && Boolean(r.styleSheet);
+ }
+ }
+ }
+ if (fakeLoad) {
+ setTimeout(function() {
+ elt.dispatchEvent(new CustomEvent("load", {
+ bubbles: false
+ }));
+ });
+ }
+ }
+ },
+ parseScript: function(scriptElt) {
+ var script = document.createElement("script");
+ script.__importElement = scriptElt;
+ script.src = scriptElt.src ? scriptElt.src : generateScriptDataUrl(scriptElt);
+ scope.currentScript = scriptElt;
+ this.trackElement(script, function(e) {
+ script.parentNode.removeChild(script);
+ scope.currentScript = null;
+ });
+ this.addElementToDocument(script);
+ },
+ nextToParse: function() {
+ this._mayParse = [];
+ return !this.parsingElement && (this.nextToParseInDoc(rootDocument) || this.nextToParseDynamic());
+ },
+ nextToParseInDoc: function(doc, link) {
+ if (doc && this._mayParse.indexOf(doc) < 0) {
+ this._mayParse.push(doc);
+ var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));
+ for (var i = 0, l = nodes.length, p = 0, n; i < l && (n = nodes[i]); i++) {
+ if (!this.isParsed(n)) {
+ if (this.hasResource(n)) {
+ return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n;
+ } else {
+ return;
+ }
+ }
+ }
+ }
+ return link;
+ },
+ nextToParseDynamic: function() {
+ return this.dynamicElements[0];
+ },
+ parseSelectorsForNode: function(node) {
+ var doc = node.ownerDocument || node;
+ return doc === rootDocument ? this.documentSelectors : this.importsSelectors;
+ },
+ isParsed: function(node) {
+ return node.__importParsed;
+ },
+ needsDynamicParsing: function(elt) {
+ return this.dynamicElements.indexOf(elt) >= 0;
+ },
+ hasResource: function(node) {
+ if (nodeIsImport(node) && node.import === undefined) {
+ return false;
+ }
+ return true;
+ }
+ };
+ function nodeIsImport(elt) {
+ return elt.localName === "link" && elt.rel === IMPORT_LINK_TYPE;
+ }
+ function generateScriptDataUrl(script) {
+ var scriptContent = generateScriptContent(script);
+ return "data:text/javascript;charset=utf-8," + encodeURIComponent(scriptContent);
+ }
+ function generateScriptContent(script) {
+ return script.textContent + generateSourceMapHint(script);
+ }
+ function generateSourceMapHint(script) {
+ var owner = script.ownerDocument;
+ owner.__importedScripts = owner.__importedScripts || 0;
+ var moniker = script.ownerDocument.baseURI;
+ var num = owner.__importedScripts ? "-" + owner.__importedScripts : "";
+ owner.__importedScripts++;
+ return "\n//# sourceURL=" + moniker + num + ".js\n";
+ }
+ function cloneStyle(style) {
+ var clone = style.ownerDocument.createElement("style");
+ clone.textContent = style.textContent;
+ path.resolveUrlsInStyle(clone);
+ return clone;
+ }
+ scope.parser = importParser;
+ scope.IMPORT_SELECTOR = IMPORT_SELECTOR;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var flags = scope.flags;
+ var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
+ var IMPORT_SELECTOR = scope.IMPORT_SELECTOR;
+ var rootDocument = scope.rootDocument;
+ var Loader = scope.Loader;
+ var Observer = scope.Observer;
+ var parser = scope.parser;
+ var importer = {
+ documents: {},
+ documentPreloadSelectors: IMPORT_SELECTOR,
+ importsPreloadSelectors: [ IMPORT_SELECTOR ].join(","),
+ loadNode: function(node) {
+ importLoader.addNode(node);
+ },
+ loadSubtree: function(parent) {
+ var nodes = this.marshalNodes(parent);
+ importLoader.addNodes(nodes);
+ },
+ marshalNodes: function(parent) {
+ return parent.querySelectorAll(this.loadSelectorsForNode(parent));
+ },
+ loadSelectorsForNode: function(node) {
+ var doc = node.ownerDocument || node;
+ return doc === rootDocument ? this.documentPreloadSelectors : this.importsPreloadSelectors;
+ },
+ loaded: function(url, elt, resource, err, redirectedUrl) {
+ flags.load && console.log("loaded", url, elt);
+ elt.__resource = resource;
+ elt.__error = err;
+ if (isImportLink(elt)) {
+ var doc = this.documents[url];
+ if (doc === undefined) {
+ doc = err ? null : makeDocument(resource, redirectedUrl || url);
+ if (doc) {
+ doc.__importLink = elt;
+ this.bootDocument(doc);
+ }
+ this.documents[url] = doc;
+ }
+ elt.import = doc;
+ }
+ parser.parseNext();
+ },
+ bootDocument: function(doc) {
+ this.loadSubtree(doc);
+ this.observer.observe(doc);
+ parser.parseNext();
+ },
+ loadedAll: function() {
+ parser.parseNext();
+ }
+ };
+ var importLoader = new Loader(importer.loaded.bind(importer), importer.loadedAll.bind(importer));
+ importer.observer = new Observer();
+ function isImportLink(elt) {
+ return isLinkRel(elt, IMPORT_LINK_TYPE);
+ }
+ function isLinkRel(elt, rel) {
+ return elt.localName === "link" && elt.getAttribute("rel") === rel;
+ }
+ function hasBaseURIAccessor(doc) {
+ return !!Object.getOwnPropertyDescriptor(doc, "baseURI");
+ }
+ function makeDocument(resource, url) {
+ var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);
+ doc._URL = url;
+ var base = doc.createElement("base");
+ base.setAttribute("href", url);
+ if (!doc.baseURI && !hasBaseURIAccessor(doc)) {
+ Object.defineProperty(doc, "baseURI", {
+ value: url
+ });
+ }
+ var meta = doc.createElement("meta");
+ meta.setAttribute("charset", "utf-8");
+ doc.head.appendChild(meta);
+ doc.head.appendChild(base);
+ doc.body.innerHTML = resource;
+ if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
+ HTMLTemplateElement.bootstrap(doc);
+ }
+ return doc;
+ }
+ if (!document.baseURI) {
+ var baseURIDescriptor = {
+ get: function() {
+ var base = document.querySelector("base");
+ return base ? base.href : window.location.href;
+ },
+ configurable: true
+ };
+ Object.defineProperty(document, "baseURI", baseURIDescriptor);
+ Object.defineProperty(rootDocument, "baseURI", baseURIDescriptor);
+ }
+ scope.importer = importer;
+ scope.importLoader = importLoader;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var parser = scope.parser;
+ var importer = scope.importer;
+ var dynamic = {
+ added: function(nodes) {
+ var owner, parsed, loading;
+ for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+ if (!owner) {
+ owner = n.ownerDocument;
+ parsed = parser.isParsed(owner);
+ }
+ loading = this.shouldLoadNode(n);
+ if (loading) {
+ importer.loadNode(n);
+ }
+ if (this.shouldParseNode(n) && parsed) {
+ parser.parseDynamic(n, loading);
+ }
+ }
+ },
+ shouldLoadNode: function(node) {
+ return node.nodeType === 1 && matches.call(node, importer.loadSelectorsForNode(node));
+ },
+ shouldParseNode: function(node) {
+ return node.nodeType === 1 && matches.call(node, parser.parseSelectorsForNode(node));
+ }
+ };
+ importer.observer.addCallback = dynamic.added.bind(dynamic);
+ var matches = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector;
+});
+
+(function(scope) {
+ var initializeModules = scope.initializeModules;
+ var isIE = scope.isIE;
+ if (scope.useNative) {
+ return;
+ }
+ if (isIE && typeof window.CustomEvent !== "function") {
+ window.CustomEvent = function(inType, params) {
+ params = params || {};
+ var e = document.createEvent("CustomEvent");
+ e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
+ e.preventDefault = function() {
+ Object.defineProperty(this, "defaultPrevented", {
+ get: function() {
+ return true;
+ }
+ });
+ };
+ return e;
+ };
+ window.CustomEvent.prototype = window.Event.prototype;
+ }
+ initializeModules();
+ var rootDocument = scope.rootDocument;
+ function bootstrap() {
+ window.HTMLImports.importer.bootDocument(rootDocument);
+ }
+ if (document.readyState === "complete" || document.readyState === "interactive" && !window.attachEvent) {
+ bootstrap();
+ } else {
+ document.addEventListener("DOMContentLoaded", bootstrap);
+ }
+})(window.HTMLImports);
+
+window.CustomElements = window.CustomElements || {
+ flags: {}
+};
+
+(function(scope) {
+ var flags = scope.flags;
+ var modules = [];
+ var addModule = function(module) {
+ modules.push(module);
+ };
+ var initializeModules = function() {
+ modules.forEach(function(module) {
+ module(scope);
+ });
+ };
+ scope.addModule = addModule;
+ scope.initializeModules = initializeModules;
+ scope.hasNative = Boolean(document.registerElement);
+ scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || window.HTMLImports.useNative);
+})(window.CustomElements);
+
+window.CustomElements.addModule(function(scope) {
+ var IMPORT_LINK_TYPE = window.HTMLImports ? window.HTMLImports.IMPORT_LINK_TYPE : "none";
+ function forSubtree(node, cb) {
+ findAllElements(node, function(e) {
+ if (cb(e)) {
+ return true;
+ }
+ forRoots(e, cb);
+ });
+ forRoots(node, cb);
+ }
+ function findAllElements(node, find, data) {
+ var e = node.firstElementChild;
+ if (!e) {
+ e = node.firstChild;
+ while (e && e.nodeType !== Node.ELEMENT_NODE) {
+ e = e.nextSibling;
+ }
+ }
+ while (e) {
+ if (find(e, data) !== true) {
+ findAllElements(e, find, data);
+ }
+ e = e.nextElementSibling;
+ }
+ return null;
+ }
+ function forRoots(node, cb) {
+ var root = node.shadowRoot;
+ while (root) {
+ forSubtree(root, cb);
+ root = root.olderShadowRoot;
+ }
+ }
+ function forDocumentTree(doc, cb) {
+ _forDocumentTree(doc, cb, []);
+ }
+ function _forDocumentTree(doc, cb, processingDocuments) {
+ doc = window.wrap(doc);
+ if (processingDocuments.indexOf(doc) >= 0) {
+ return;
+ }
+ processingDocuments.push(doc);
+ var imports = doc.querySelectorAll("link[rel=" + IMPORT_LINK_TYPE + "]");
+ for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) {
+ if (n.import) {
+ _forDocumentTree(n.import, cb, processingDocuments);
+ }
+ }
+ cb(doc);
+ }
+ scope.forDocumentTree = forDocumentTree;
+ scope.forSubtree = forSubtree;
+});
+
+window.CustomElements.addModule(function(scope) {
+ var flags = scope.flags;
+ var forSubtree = scope.forSubtree;
+ var forDocumentTree = scope.forDocumentTree;
+ function addedNode(node) {
+ return added(node) || addedSubtree(node);
+ }
+ function added(node) {
+ if (scope.upgrade(node)) {
+ return true;
+ }
+ attached(node);
+ }
+ function addedSubtree(node) {
+ forSubtree(node, function(e) {
+ if (added(e)) {
+ return true;
+ }
+ });
+ }
+ function attachedNode(node) {
+ attached(node);
+ if (inDocument(node)) {
+ forSubtree(node, function(e) {
+ attached(e);
+ });
+ }
+ }
+ var hasPolyfillMutations = !window.MutationObserver || window.MutationObserver === window.JsMutationObserver;
+ scope.hasPolyfillMutations = hasPolyfillMutations;
+ var isPendingMutations = false;
+ var pendingMutations = [];
+ function deferMutation(fn) {
+ pendingMutations.push(fn);
+ if (!isPendingMutations) {
+ isPendingMutations = true;
+ setTimeout(takeMutations);
+ }
+ }
+ function takeMutations() {
+ isPendingMutations = false;
+ var $p = pendingMutations;
+ for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
+ p();
+ }
+ pendingMutations = [];
+ }
+ function attached(element) {
+ if (hasPolyfillMutations) {
+ deferMutation(function() {
+ _attached(element);
+ });
+ } else {
+ _attached(element);
+ }
+ }
+ function _attached(element) {
+ if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
+ if (!element.__attached && inDocument(element)) {
+ element.__attached = true;
+ if (element.attachedCallback) {
+ element.attachedCallback();
+ }
+ }
+ }
+ }
+ function detachedNode(node) {
+ detached(node);
+ forSubtree(node, function(e) {
+ detached(e);
+ });
+ }
+ function detached(element) {
+ if (hasPolyfillMutations) {
+ deferMutation(function() {
+ _detached(element);
+ });
+ } else {
+ _detached(element);
+ }
+ }
+ function _detached(element) {
+ if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
+ if (element.__attached && !inDocument(element)) {
+ element.__attached = false;
+ if (element.detachedCallback) {
+ element.detachedCallback();
+ }
+ }
+ }
+ }
+ function inDocument(element) {
+ var p = element;
+ var doc = wrap(document);
+ while (p) {
+ if (p == doc) {
+ return true;
+ }
+ p = p.parentNode || p.nodeType === Node.DOCUMENT_FRAGMENT_NODE && p.host;
+ }
+ }
+ function watchShadow(node) {
+ if (node.shadowRoot && !node.shadowRoot.__watched) {
+ flags.dom && console.log("watching shadow-root for: ", node.localName);
+ var root = node.shadowRoot;
+ while (root) {
+ observe(root);
+ root = root.olderShadowRoot;
+ }
+ }
+ }
+ function handler(mutations) {
+ if (flags.dom) {
+ var mx = mutations[0];
+ if (mx && mx.type === "childList" && mx.addedNodes) {
+ if (mx.addedNodes) {
+ var d = mx.addedNodes[0];
+ while (d && d !== document && !d.host) {
+ d = d.parentNode;
+ }
+ var u = d && (d.URL || d._URL || d.host && d.host.localName) || "";
+ u = u.split("/?").shift().split("/").pop();
+ }
+ }
+ console.group("mutations (%d) [%s]", mutations.length, u || "");
+ }
+ mutations.forEach(function(mx) {
+ if (mx.type === "childList") {
+ forEach(mx.addedNodes, function(n) {
+ if (!n.localName) {
+ return;
+ }
+ addedNode(n);
+ });
+ forEach(mx.removedNodes, function(n) {
+ if (!n.localName) {
+ return;
+ }
+ detachedNode(n);
+ });
+ }
+ });
+ flags.dom && console.groupEnd();
+ }
+ function takeRecords(node) {
+ node = window.wrap(node);
+ if (!node) {
+ node = window.wrap(document);
+ }
+ while (node.parentNode) {
+ node = node.parentNode;
+ }
+ var observer = node.__observer;
+ if (observer) {
+ handler(observer.takeRecords());
+ takeMutations();
+ }
+ }
+ var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
+ function observe(inRoot) {
+ if (inRoot.__observer) {
+ return;
+ }
+ var observer = new MutationObserver(handler);
+ observer.observe(inRoot, {
+ childList: true,
+ subtree: true
+ });
+ inRoot.__observer = observer;
+ }
+ function upgradeDocument(doc) {
+ doc = window.wrap(doc);
+ flags.dom && console.group("upgradeDocument: ", doc.baseURI.split("/").pop());
+ addedNode(doc);
+ observe(doc);
+ flags.dom && console.groupEnd();
+ }
+ function upgradeDocumentTree(doc) {
+ forDocumentTree(doc, upgradeDocument);
+ }
+ var originalCreateShadowRoot = Element.prototype.createShadowRoot;
+ if (originalCreateShadowRoot) {
+ Element.prototype.createShadowRoot = function() {
+ var root = originalCreateShadowRoot.call(this);
+ window.CustomElements.watchShadow(this);
+ return root;
+ };
+ }
+ scope.watchShadow = watchShadow;
+ scope.upgradeDocumentTree = upgradeDocumentTree;
+ scope.upgradeSubtree = addedSubtree;
+ scope.upgradeAll = addedNode;
+ scope.attachedNode = attachedNode;
+ scope.takeRecords = takeRecords;
+});
+
+window.CustomElements.addModule(function(scope) {
+ var flags = scope.flags;
+ function upgrade(node) {
+ if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {
+ var is = node.getAttribute("is");
+ var definition = scope.getRegisteredDefinition(is || node.localName);
+ if (definition) {
+ if (is && definition.tag == node.localName) {
+ return upgradeWithDefinition(node, definition);
+ } else if (!is && !definition.extends) {
+ return upgradeWithDefinition(node, definition);
+ }
+ }
+ }
+ }
+ function upgradeWithDefinition(element, definition) {
+ flags.upgrade && console.group("upgrade:", element.localName);
+ if (definition.is) {
+ element.setAttribute("is", definition.is);
+ }
+ implementPrototype(element, definition);
+ element.__upgraded__ = true;
+ created(element);
+ scope.attachedNode(element);
+ scope.upgradeSubtree(element);
+ flags.upgrade && console.groupEnd();
+ return element;
+ }
+ function implementPrototype(element, definition) {
+ if (Object.__proto__) {
+ element.__proto__ = definition.prototype;
+ } else {
+ customMixin(element, definition.prototype, definition.native);
+ element.__proto__ = definition.prototype;
+ }
+ }
+ function customMixin(inTarget, inSrc, inNative) {
+ var used = {};
+ var p = inSrc;
+ while (p !== inNative && p !== HTMLElement.prototype) {
+ var keys = Object.getOwnPropertyNames(p);
+ for (var i = 0, k; k = keys[i]; i++) {
+ if (!used[k]) {
+ Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k));
+ used[k] = 1;
+ }
+ }
+ p = Object.getPrototypeOf(p);
+ }
+ }
+ function created(element) {
+ if (element.createdCallback) {
+ element.createdCallback();
+ }
+ }
+ scope.upgrade = upgrade;
+ scope.upgradeWithDefinition = upgradeWithDefinition;
+ scope.implementPrototype = implementPrototype;
+});
+
+window.CustomElements.addModule(function(scope) {
+ var isIE11OrOlder = scope.isIE11OrOlder;
+ var upgradeDocumentTree = scope.upgradeDocumentTree;
+ var upgradeAll = scope.upgradeAll;
+ var upgradeWithDefinition = scope.upgradeWithDefinition;
+ var implementPrototype = scope.implementPrototype;
+ var useNative = scope.useNative;
+ function register(name, options) {
+ var definition = options || {};
+ if (!name) {
+ throw new Error("document.registerElement: first argument `name` must not be empty");
+ }
+ if (name.indexOf("-") < 0) {
+ throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '" + String(name) + "'.");
+ }
+ if (isReservedTag(name)) {
+ throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '" + String(name) + "'. The type name is invalid.");
+ }
+ if (getRegisteredDefinition(name)) {
+ throw new Error("DuplicateDefinitionError: a type with name '" + String(name) + "' is already registered");
+ }
+ if (!definition.prototype) {
+ definition.prototype = Object.create(HTMLElement.prototype);
+ }
+ definition.__name = name.toLowerCase();
+ definition.lifecycle = definition.lifecycle || {};
+ definition.ancestry = ancestry(definition.extends);
+ resolveTagName(definition);
+ resolvePrototypeChain(definition);
+ overrideAttributeApi(definition.prototype);
+ registerDefinition(definition.__name, definition);
+ definition.ctor = generateConstructor(definition);
+ definition.ctor.prototype = definition.prototype;
+ definition.prototype.constructor = definition.ctor;
+ if (scope.ready) {
+ upgradeDocumentTree(document);
+ }
+ return definition.ctor;
+ }
+ function overrideAttributeApi(prototype) {
+ if (prototype.setAttribute._polyfilled) {
+ return;
+ }
+ var setAttribute = prototype.setAttribute;
+ prototype.setAttribute = function(name, value) {
+ changeAttribute.call(this, name, value, setAttribute);
+ };
+ var removeAttribute = prototype.removeAttribute;
+ prototype.removeAttribute = function(name) {
+ changeAttribute.call(this, name, null, removeAttribute);
+ };
+ prototype.setAttribute._polyfilled = true;
+ }
+ function changeAttribute(name, value, operation) {
+ name = name.toLowerCase();
+ var oldValue = this.getAttribute(name);
+ operation.apply(this, arguments);
+ var newValue = this.getAttribute(name);
+ if (this.attributeChangedCallback && newValue !== oldValue) {
+ this.attributeChangedCallback(name, oldValue, newValue);
+ }
+ }
+ function isReservedTag(name) {
+ for (var i = 0; i < reservedTagList.length; i++) {
+ if (name === reservedTagList[i]) {
+ return true;
+ }
+ }
+ }
+ var reservedTagList = [ "annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph" ];
+ function ancestry(extnds) {
+ var extendee = getRegisteredDefinition(extnds);
+ if (extendee) {
+ return ancestry(extendee.extends).concat([ extendee ]);
+ }
+ return [];
+ }
+ function resolveTagName(definition) {
+ var baseTag = definition.extends;
+ for (var i = 0, a; a = definition.ancestry[i]; i++) {
+ baseTag = a.is && a.tag;
+ }
+ definition.tag = baseTag || definition.__name;
+ if (baseTag) {
+ definition.is = definition.__name;
+ }
+ }
+ function resolvePrototypeChain(definition) {
+ if (!Object.__proto__) {
+ var nativePrototype = HTMLElement.prototype;
+ if (definition.is) {
+ var inst = document.createElement(definition.tag);
+ var expectedPrototype = Object.getPrototypeOf(inst);
+ if (expectedPrototype === definition.prototype) {
+ nativePrototype = expectedPrototype;
+ }
+ }
+ var proto = definition.prototype, ancestor;
+ while (proto && proto !== nativePrototype) {
+ ancestor = Object.getPrototypeOf(proto);
+ proto.__proto__ = ancestor;
+ proto = ancestor;
+ }
+ definition.native = nativePrototype;
+ }
+ }
+ function instantiate(definition) {
+ return upgradeWithDefinition(domCreateElement(definition.tag), definition);
+ }
+ var registry = {};
+ function getRegisteredDefinition(name) {
+ if (name) {
+ return registry[name.toLowerCase()];
+ }
+ }
+ function registerDefinition(name, definition) {
+ registry[name] = definition;
+ }
+ function generateConstructor(definition) {
+ return function() {
+ return instantiate(definition);
+ };
+ }
+ var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
+ function createElementNS(namespace, tag, typeExtension) {
+ if (namespace === HTML_NAMESPACE) {
+ return createElement(tag, typeExtension);
+ } else {
+ return domCreateElementNS(namespace, tag);
+ }
+ }
+ function createElement(tag, typeExtension) {
+ if (tag) {
+ tag = tag.toLowerCase();
+ }
+ if (typeExtension) {
+ typeExtension = typeExtension.toLowerCase();
+ }
+ var definition = getRegisteredDefinition(typeExtension || tag);
+ if (definition) {
+ if (tag == definition.tag && typeExtension == definition.is) {
+ return new definition.ctor();
+ }
+ if (!typeExtension && !definition.is) {
+ return new definition.ctor();
+ }
+ }
+ var element;
+ if (typeExtension) {
+ element = createElement(tag);
+ element.setAttribute("is", typeExtension);
+ return element;
+ }
+ element = domCreateElement(tag);
+ if (tag.indexOf("-") >= 0) {
+ implementPrototype(element, HTMLElement);
+ }
+ return element;
+ }
+ var domCreateElement = document.createElement.bind(document);
+ var domCreateElementNS = document.createElementNS.bind(document);
+ var isInstance;
+ if (!Object.__proto__ && !useNative) {
+ isInstance = function(obj, ctor) {
+ var p = obj;
+ while (p) {
+ if (p === ctor.prototype) {
+ return true;
+ }
+ p = p.__proto__;
+ }
+ return false;
+ };
+ } else {
+ isInstance = function(obj, base) {
+ return obj instanceof base;
+ };
+ }
+ function wrapDomMethodToForceUpgrade(obj, methodName) {
+ var orig = obj[methodName];
+ obj[methodName] = function() {
+ var n = orig.apply(this, arguments);
+ upgradeAll(n);
+ return n;
+ };
+ }
+ wrapDomMethodToForceUpgrade(Node.prototype, "cloneNode");
+ wrapDomMethodToForceUpgrade(document, "importNode");
+ if (isIE11OrOlder) {
+ (function() {
+ var importNode = document.importNode;
+ document.importNode = function() {
+ var n = importNode.apply(document, arguments);
+ if (n.nodeType == n.DOCUMENT_FRAGMENT_NODE) {
+ var f = document.createDocumentFragment();
+ f.appendChild(n);
+ return f;
+ } else {
+ return n;
+ }
+ };
+ })();
+ }
+ document.registerElement = register;
+ document.createElement = createElement;
+ document.createElementNS = createElementNS;
+ scope.registry = registry;
+ scope.instanceof = isInstance;
+ scope.reservedTagList = reservedTagList;
+ scope.getRegisteredDefinition = getRegisteredDefinition;
+ document.register = document.registerElement;
+});
+
+(function(scope) {
+ var useNative = scope.useNative;
+ var initializeModules = scope.initializeModules;
+ var isIE11OrOlder = /Trident/.test(navigator.userAgent);
+ if (useNative) {
+ var nop = function() {};
+ scope.watchShadow = nop;
+ scope.upgrade = nop;
+ scope.upgradeAll = nop;
+ scope.upgradeDocumentTree = nop;
+ scope.upgradeSubtree = nop;
+ scope.takeRecords = nop;
+ scope.instanceof = function(obj, base) {
+ return obj instanceof base;
+ };
+ } else {
+ initializeModules();
+ }
+ var upgradeDocumentTree = scope.upgradeDocumentTree;
+ if (!window.wrap) {
+ if (window.ShadowDOMPolyfill) {
+ window.wrap = window.ShadowDOMPolyfill.wrapIfNeeded;
+ window.unwrap = window.ShadowDOMPolyfill.unwrapIfNeeded;
+ } else {
+ window.wrap = window.unwrap = function(node) {
+ return node;
+ };
+ }
+ }
+ function bootstrap() {
+ upgradeDocumentTree(window.wrap(document));
+ if (window.HTMLImports) {
+ window.HTMLImports.__importsParsingHook = function(elt) {
+ upgradeDocumentTree(wrap(elt.import));
+ };
+ }
+ window.CustomElements.ready = true;
+ setTimeout(function() {
+ window.CustomElements.readyTime = Date.now();
+ if (window.HTMLImports) {
+ window.CustomElements.elapsed = window.CustomElements.readyTime - window.HTMLImports.readyTime;
+ }
+ document.dispatchEvent(new CustomEvent("WebComponentsReady", {
+ bubbles: true
+ }));
+ });
+ }
+ if (isIE11OrOlder && typeof window.CustomEvent !== "function") {
+ window.CustomEvent = function(inType, params) {
+ params = params || {};
+ var e = document.createEvent("CustomEvent");
+ e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
+ e.preventDefault = function() {
+ Object.defineProperty(this, "defaultPrevented", {
+ get: function() {
+ return true;
+ }
+ });
+ };
+ return e;
+ };
+ window.CustomEvent.prototype = window.Event.prototype;
+ }
+ if (document.readyState === "complete" || scope.flags.eager) {
+ bootstrap();
+ } else if (document.readyState === "interactive" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) {
+ bootstrap();
+ } else {
+ var loadEvent = window.HTMLImports && !window.HTMLImports.ready ? "HTMLImportsLoaded" : "DOMContentLoaded";
+ window.addEventListener(loadEvent, bootstrap);
+ }
+ scope.isIE11OrOlder = isIE11OrOlder;
+})(window.CustomElements);
+
+if (typeof HTMLTemplateElement === "undefined") {
+ (function() {
+ var TEMPLATE_TAG = "template";
+ HTMLTemplateElement = function() {};
+ HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
+ HTMLTemplateElement.decorate = function(template) {
+ if (!template.content) {
+ template.content = template.ownerDocument.createDocumentFragment();
+ }
+ var child;
+ while (child = template.firstChild) {
+ template.content.appendChild(child);
+ }
+ };
+ HTMLTemplateElement.bootstrap = function(doc) {
+ var templates = doc.querySelectorAll(TEMPLATE_TAG);
+ for (var i = 0, l = templates.length, t; i < l && (t = templates[i]); i++) {
+ HTMLTemplateElement.decorate(t);
+ }
+ };
+ window.addEventListener("DOMContentLoaded", function() {
+ HTMLTemplateElement.bootstrap(document);
+ });
+ var createElement = document.createElement;
+ document.createElement = function() {
+ "use strict";
+ var el = createElement.apply(document, arguments);
+ if (el.localName == "template") {
+ HTMLTemplateElement.decorate(el);
+ }
+ return el;
+ };
+ })();
+}
+
+(function(scope) {
+ var style = document.createElement("style");
+ style.textContent = "" + "body {" + "transition: opacity ease-in 0.2s;" + " } \n" + "body[unresolved] {" + "opacity: 0; display: block; overflow: hidden; position: relative;" + " } \n";
+ var head = document.querySelector("head");
+ head.insertBefore(style, head.firstChild);
+})(window.WebComponents);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/webcomponents-lite.min.js b/polymer_1.0.4/bower_components/webcomponentsjs/webcomponents-lite.min.js
new file mode 100644
index 0000000..abb6ff6
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/webcomponents-lite.min.js
@@ -0,0 +1,13 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.7.5
+window.WebComponents=window.WebComponents||{},function(e){var t=e.flags||{},n="webcomponents-lite.js",r=document.querySelector('script[src*="'+n+'"]');if(!t.noOpts){if(location.search.slice(1).split("&").forEach(function(e){var n,r=e.split("=");r[0]&&(n=r[0].match(/wc-(.+)/))&&(t[n[1]]=r[1]||!0)}),r)for(var o,i=0;o=r.attributes[i];i++)"src"!==o.name&&(t[o.name]=o.value||!0);if(t.log){var a=t.log.split(",");t.log={},a.forEach(function(e){t.log[e]=!0})}else t.log={}}t.shadow=t.shadow||t.shadowdom||t.polyfill,t.shadow="native"===t.shadow?!1:t.shadow||!HTMLElement.prototype.createShadowRoot,t.register&&(window.CustomElements=window.CustomElements||{flags:{}},window.CustomElements.flags.register=t.register),e.flags=t}(window.WebComponents),function(e){"use strict";function t(e){return void 0!==h[e]}function n(){s.call(this),this._isInvalid=!0}function r(e){return""==e&&n.call(this),e.toLowerCase()}function o(e){var t=e.charCodeAt(0);return t>32&&127>t&&-1==[34,35,60,62,63,96].indexOf(t)?e:encodeURIComponent(e)}function i(e){var t=e.charCodeAt(0);return t>32&&127>t&&-1==[34,35,60,62,96].indexOf(t)?e:encodeURIComponent(e)}function a(e,a,s){function c(e){b.push(e)}var d=a||"scheme start",u=0,l="",_=!1,w=!1,b=[];e:for(;(e[u-1]!=f||0==u)&&!this._isInvalid;){var g=e[u];switch(d){case"scheme start":if(!g||!m.test(g)){if(a){c("Invalid scheme.");break e}l="",d="no scheme";continue}l+=g.toLowerCase(),d="scheme";break;case"scheme":if(g&&v.test(g))l+=g.toLowerCase();else{if(":"!=g){if(a){if(f==g)break e;c("Code point not allowed in scheme: "+g);break e}l="",u=0,d="no scheme";continue}if(this._scheme=l,l="",a)break e;t(this._scheme)&&(this._isRelative=!0),d="file"==this._scheme?"relative":this._isRelative&&s&&s._scheme==this._scheme?"relative or authority":this._isRelative?"authority first slash":"scheme data"}break;case"scheme data":"?"==g?(this._query="?",d="query"):"#"==g?(this._fragment="#",d="fragment"):f!=g&&" "!=g&&"\n"!=g&&"\r"!=g&&(this._schemeData+=o(g));break;case"no scheme":if(s&&t(s._scheme)){d="relative";continue}c("Missing scheme."),n.call(this);break;case"relative or authority":if("/"!=g||"/"!=e[u+1]){c("Expected /, got: "+g),d="relative";continue}d="authority ignore slashes";break;case"relative":if(this._isRelative=!0,"file"!=this._scheme&&(this._scheme=s._scheme),f==g){this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query=s._query,this._username=s._username,this._password=s._password;break e}if("/"==g||"\\"==g)"\\"==g&&c("\\ is an invalid code point."),d="relative slash";else if("?"==g)this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query="?",this._username=s._username,this._password=s._password,d="query";else{if("#"!=g){var y=e[u+1],E=e[u+2];("file"!=this._scheme||!m.test(g)||":"!=y&&"|"!=y||f!=E&&"/"!=E&&"\\"!=E&&"?"!=E&&"#"!=E)&&(this._host=s._host,this._port=s._port,this._username=s._username,this._password=s._password,this._path=s._path.slice(),this._path.pop()),d="relative path";continue}this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query=s._query,this._fragment="#",this._username=s._username,this._password=s._password,d="fragment"}break;case"relative slash":if("/"!=g&&"\\"!=g){"file"!=this._scheme&&(this._host=s._host,this._port=s._port,this._username=s._username,this._password=s._password),d="relative path";continue}"\\"==g&&c("\\ is an invalid code point."),d="file"==this._scheme?"file host":"authority ignore slashes";break;case"authority first slash":if("/"!=g){c("Expected '/', got: "+g),d="authority ignore slashes";continue}d="authority second slash";break;case"authority second slash":if(d="authority ignore slashes","/"!=g){c("Expected '/', got: "+g);continue}break;case"authority ignore slashes":if("/"!=g&&"\\"!=g){d="authority";continue}c("Expected authority, got: "+g);break;case"authority":if("@"==g){_&&(c("@ already seen."),l+="%40"),_=!0;for(var L=0;L<l.length;L++){var M=l[L];if(" "!=M&&"\n"!=M&&"\r"!=M)if(":"!=M||null!==this._password){var T=o(M);null!==this._password?this._password+=T:this._username+=T}else this._password="";else c("Invalid whitespace in authority.")}l=""}else{if(f==g||"/"==g||"\\"==g||"?"==g||"#"==g){u-=l.length,l="",d="host";continue}l+=g}break;case"file host":if(f==g||"/"==g||"\\"==g||"?"==g||"#"==g){2!=l.length||!m.test(l[0])||":"!=l[1]&&"|"!=l[1]?0==l.length?d="relative path start":(this._host=r.call(this,l),l="",d="relative path start"):d="relative path";continue}" "==g||"\n"==g||"\r"==g?c("Invalid whitespace in file host."):l+=g;break;case"host":case"hostname":if(":"!=g||w){if(f==g||"/"==g||"\\"==g||"?"==g||"#"==g){if(this._host=r.call(this,l),l="",d="relative path start",a)break e;continue}" "!=g&&"\n"!=g&&"\r"!=g?("["==g?w=!0:"]"==g&&(w=!1),l+=g):c("Invalid code point in host/hostname: "+g)}else if(this._host=r.call(this,l),l="",d="port","hostname"==a)break e;break;case"port":if(/[0-9]/.test(g))l+=g;else{if(f==g||"/"==g||"\\"==g||"?"==g||"#"==g||a){if(""!=l){var N=parseInt(l,10);N!=h[this._scheme]&&(this._port=N+""),l=""}if(a)break e;d="relative path start";continue}" "==g||"\n"==g||"\r"==g?c("Invalid code point in port: "+g):n.call(this)}break;case"relative path start":if("\\"==g&&c("'\\' not allowed in path."),d="relative path","/"!=g&&"\\"!=g)continue;break;case"relative path":if(f!=g&&"/"!=g&&"\\"!=g&&(a||"?"!=g&&"#"!=g))" "!=g&&"\n"!=g&&"\r"!=g&&(l+=o(g));else{"\\"==g&&c("\\ not allowed in relative path.");var O;(O=p[l.toLowerCase()])&&(l=O),".."==l?(this._path.pop(),"/"!=g&&"\\"!=g&&this._path.push("")):"."==l&&"/"!=g&&"\\"!=g?this._path.push(""):"."!=l&&("file"==this._scheme&&0==this._path.length&&2==l.length&&m.test(l[0])&&"|"==l[1]&&(l=l[0]+":"),this._path.push(l)),l="","?"==g?(this._query="?",d="query"):"#"==g&&(this._fragment="#",d="fragment")}break;case"query":a||"#"!=g?f!=g&&" "!=g&&"\n"!=g&&"\r"!=g&&(this._query+=i(g)):(this._fragment="#",d="fragment");break;case"fragment":f!=g&&" "!=g&&"\n"!=g&&"\r"!=g&&(this._fragment+=g)}u++}}function s(){this._scheme="",this._schemeData="",this._username="",this._password=null,this._host="",this._port="",this._path=[],this._query="",this._fragment="",this._isInvalid=!1,this._isRelative=!1}function c(e,t){void 0===t||t instanceof c||(t=new c(String(t))),this._url=e,s.call(this);var n=e.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g,"");a.call(this,n,null,t)}var d=!1;if(!e.forceJURL)try{var u=new URL("b","http://a");u.pathname="c%20d",d="http://a/c%20d"===u.href}catch(l){}if(!d){var h=Object.create(null);h.ftp=21,h.file=0,h.gopher=70,h.http=80,h.https=443,h.ws=80,h.wss=443;var p=Object.create(null);p["%2e"]=".",p[".%2e"]="..",p["%2e."]="..",p["%2e%2e"]="..";var f=void 0,m=/[a-zA-Z]/,v=/[a-zA-Z0-9\+\-\.]/;c.prototype={toString:function(){return this.href},get href(){if(this._isInvalid)return this._url;var e="";return(""!=this._username||null!=this._password)&&(e=this._username+(null!=this._password?":"+this._password:"")+"@"),this.protocol+(this._isRelative?"//"+e+this.host:"")+this.pathname+this._query+this._fragment},set href(e){s.call(this),a.call(this,e)},get protocol(){return this._scheme+":"},set protocol(e){this._isInvalid||a.call(this,e+":","scheme start")},get host(){return this._isInvalid?"":this._port?this._host+":"+this._port:this._host},set host(e){!this._isInvalid&&this._isRelative&&a.call(this,e,"host")},get hostname(){return this._host},set hostname(e){!this._isInvalid&&this._isRelative&&a.call(this,e,"hostname")},get port(){return this._port},set port(e){!this._isInvalid&&this._isRelative&&a.call(this,e,"port")},get pathname(){return this._isInvalid?"":this._isRelative?"/"+this._path.join("/"):this._schemeData},set pathname(e){!this._isInvalid&&this._isRelative&&(this._path=[],a.call(this,e,"relative path start"))},get search(){return this._isInvalid||!this._query||"?"==this._query?"":this._query},set search(e){!this._isInvalid&&this._isRelative&&(this._query="?","?"==e[0]&&(e=e.slice(1)),a.call(this,e,"query"))},get hash(){return this._isInvalid||!this._fragment||"#"==this._fragment?"":this._fragment},set hash(e){this._isInvalid||(this._fragment="#","#"==e[0]&&(e=e.slice(1)),a.call(this,e,"fragment"))},get origin(){var e;if(this._isInvalid||!this._scheme)return"";switch(this._scheme){case"data":case"file":case"javascript":case"mailto":return"null"}return e=this.host,e?this._scheme+"://"+e:""}};var _=e.URL;_&&(c.createObjectURL=function(e){return _.createObjectURL.apply(_,arguments)},c.revokeObjectURL=function(e){_.revokeObjectURL(e)}),e.URL=c}}(this),"undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,n=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};n.prototype={set:function(t,n){var r=t[this.name];return r&&r[0]===t?r[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),function(e){function t(e){g.push(e),b||(b=!0,m(r))}function n(e){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(e)||e}function r(){b=!1;var e=g;g=[],e.sort(function(e,t){return e.uid_-t.uid_});var t=!1;e.forEach(function(e){var n=e.takeRecords();o(e),n.length&&(e.callback_(n,e),t=!0)}),t&&r()}function o(e){e.nodes_.forEach(function(t){var n=v.get(t);n&&n.forEach(function(t){t.observer===e&&t.removeTransientObservers()})})}function i(e,t){for(var n=e;n;n=n.parentNode){var r=v.get(n);if(r)for(var o=0;o<r.length;o++){var i=r[o],a=i.options;if(n===e||a.subtree){var s=t(a);s&&i.enqueue(s)}}}}function a(e){this.callback_=e,this.nodes_=[],this.records_=[],this.uid_=++y}function s(e,t){this.type=e,this.target=t,this.addedNodes=[],this.removedNodes=[],this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function c(e){var t=new s(e.type,e.target);return t.addedNodes=e.addedNodes.slice(),t.removedNodes=e.removedNodes.slice(),t.previousSibling=e.previousSibling,t.nextSibling=e.nextSibling,t.attributeName=e.attributeName,t.attributeNamespace=e.attributeNamespace,t.oldValue=e.oldValue,t}function d(e,t){return E=new s(e,t)}function u(e){return L?L:(L=c(E),L.oldValue=e,L)}function l(){E=L=void 0}function h(e){return e===L||e===E}function p(e,t){return e===t?e:L&&h(e)?L:null}function f(e,t,n){this.observer=e,this.target=t,this.options=n,this.transientObservedNodes=[]}var m,v=new WeakMap;if(/Trident|Edge/.test(navigator.userAgent))m=setTimeout;else if(window.setImmediate)m=window.setImmediate;else{var _=[],w=String(Math.random());window.addEventListener("message",function(e){if(e.data===w){var t=_;_=[],t.forEach(function(e){e()})}}),m=function(e){_.push(e),window.postMessage(w,"*")}}var b=!1,g=[],y=0;a.prototype={observe:function(e,t){if(e=n(e),!t.childList&&!t.attributes&&!t.characterData||t.attributeOldValue&&!t.attributes||t.attributeFilter&&t.attributeFilter.length&&!t.attributes||t.characterDataOldValue&&!t.characterData)throw new SyntaxError;var r=v.get(e);r||v.set(e,r=[]);for(var o,i=0;i<r.length;i++)if(r[i].observer===this){o=r[i],o.removeListeners(),o.options=t;break}o||(o=new f(this,e,t),r.push(o),this.nodes_.push(e)),o.addListeners()},disconnect:function(){this.nodes_.forEach(function(e){for(var t=v.get(e),n=0;n<t.length;n++){var r=t[n];if(r.observer===this){r.removeListeners(),t.splice(n,1);break}}},this),this.records_=[]},takeRecords:function(){var e=this.records_;return this.records_=[],e}};var E,L;f.prototype={enqueue:function(e){var n=this.observer.records_,r=n.length;if(n.length>0){var o=n[r-1],i=p(o,e);if(i)return void(n[r-1]=i)}else t(this.observer);n[r]=e},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(e){var t=this.options;t.attributes&&e.addEventListener("DOMAttrModified",this,!0),t.characterData&&e.addEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.addEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(e){var t=this.options;t.attributes&&e.removeEventListener("DOMAttrModified",this,!0),t.characterData&&e.removeEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.removeEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(e){if(e!==this.target){this.addListeners_(e),this.transientObservedNodes.push(e);var t=v.get(e);t||v.set(e,t=[]),t.push(this)}},removeTransientObservers:function(){var e=this.transientObservedNodes;this.transientObservedNodes=[],e.forEach(function(e){this.removeListeners_(e);for(var t=v.get(e),n=0;n<t.length;n++)if(t[n]===this){t.splice(n,1);break}},this)},handleEvent:function(e){switch(e.stopImmediatePropagation(),e.type){case"DOMAttrModified":var t=e.attrName,n=e.relatedNode.namespaceURI,r=e.target,o=new d("attributes",r);o.attributeName=t,o.attributeNamespace=n;var a=e.attrChange===MutationEvent.ADDITION?null:e.prevValue;i(r,function(e){return!e.attributes||e.attributeFilter&&e.attributeFilter.length&&-1===e.attributeFilter.indexOf(t)&&-1===e.attributeFilter.indexOf(n)?void 0:e.attributeOldValue?u(a):o});break;case"DOMCharacterDataModified":var r=e.target,o=d("characterData",r),a=e.prevValue;i(r,function(e){return e.characterData?e.characterDataOldValue?u(a):o:void 0});break;case"DOMNodeRemoved":this.addTransientObserver(e.target);case"DOMNodeInserted":var s,c,h=e.target;"DOMNodeInserted"===e.type?(s=[h],c=[]):(s=[],c=[h]);var p=h.previousSibling,f=h.nextSibling,o=d("childList",e.target.parentNode);o.addedNodes=s,o.removedNodes=c,o.previousSibling=p,o.nextSibling=f,i(e.relatedNode,function(e){return e.childList?o:void 0})}l()}},e.JsMutationObserver=a,e.MutationObserver||(e.MutationObserver=a)}(this),window.HTMLImports=window.HTMLImports||{flags:{}},function(e){function t(e,t){t=t||f,r(function(){i(e,t)},t)}function n(e){return"complete"===e.readyState||e.readyState===_}function r(e,t){if(n(t))e&&e();else{var o=function(){("complete"===t.readyState||t.readyState===_)&&(t.removeEventListener(w,o),r(e,t))};t.addEventListener(w,o)}}function o(e){e.target.__loaded=!0}function i(e,t){function n(){c==d&&e&&e({allImports:s,loadedImports:u,errorImports:l})}function r(e){o(e),u.push(this),c++,n()}function i(e){l.push(this),c++,n()}var s=t.querySelectorAll("link[rel=import]"),c=0,d=s.length,u=[],l=[];if(d)for(var h,p=0;d>p&&(h=s[p]);p++)a(h)?(c++,n()):(h.addEventListener("load",r),h.addEventListener("error",i));else n()}function a(e){return l?e.__loaded||e["import"]&&"loading"!==e["import"].readyState:e.__importParsed}function s(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)c(t)&&d(t)}function c(e){return"link"===e.localName&&"import"===e.rel}function d(e){var t=e["import"];t?o({target:e}):(e.addEventListener("load",o),e.addEventListener("error",o))}var u="import",l=Boolean(u in document.createElement("link")),h=Boolean(window.ShadowDOMPolyfill),p=function(e){return h?window.ShadowDOMPolyfill.wrapIfNeeded(e):e},f=p(document),m={get:function(){var e=window.HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return p(e)},configurable:!0};Object.defineProperty(document,"_currentScript",m),Object.defineProperty(f,"_currentScript",m);var v=/Trident/.test(navigator.userAgent),_=v?"complete":"interactive",w="readystatechange";l&&(new MutationObserver(function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.addedNodes&&s(t.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var e,t=document.querySelectorAll("link[rel=import]"),n=0,r=t.length;r>n&&(e=t[n]);n++)d(e)}()),t(function(e){window.HTMLImports.ready=!0,window.HTMLImports.readyTime=(new Date).getTime();var t=f.createEvent("CustomEvent");t.initCustomEvent("HTMLImportsLoaded",!0,!0,e),f.dispatchEvent(t)}),e.IMPORT_LINK_TYPE=u,e.useNative=l,e.rootDocument=f,e.whenReady=t,e.isIE=v}(window.HTMLImports),function(e){var t=[],n=function(e){t.push(e)},r=function(){t.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=r}(window.HTMLImports),window.HTMLImports.addModule(function(e){var t=/(url\()([^)]*)(\))/g,n=/(@import[\s]+(?!url\())([^;]*)(;)/g,r={resolveUrlsInStyle:function(e,t){var n=e.ownerDocument,r=n.createElement("a");return e.textContent=this.resolveUrlsInCssText(e.textContent,t,r),e},resolveUrlsInCssText:function(e,r,o){var i=this.replaceUrls(e,o,r,t);return i=this.replaceUrls(i,o,r,n)},replaceUrls:function(e,t,n,r){return e.replace(r,function(e,r,o,i){var a=o.replace(/["']/g,"");return n&&(a=new URL(a,n).href),t.href=a,a=t.href,r+"'"+a+"'"+i})}};e.path=r}),window.HTMLImports.addModule(function(e){var t={async:!0,ok:function(e){return e.status>=200&&e.status<300||304===e.status||0===e.status},load:function(n,r,o){var i=new XMLHttpRequest;return(e.flags.debug||e.flags.bust)&&(n+="?"+Math.random()),i.open("GET",n,t.async),i.addEventListener("readystatechange",function(e){if(4===i.readyState){var n=i.getResponseHeader("Location"),a=null;if(n)var a="/"===n.substr(0,1)?location.origin+n:n;r.call(o,!t.ok(i)&&i,i.response||i.responseText,a)}}),i.send(),i},loadDocument:function(e,t,n){this.load(e,t,n).responseType="document"}};e.xhr=t}),window.HTMLImports.addModule(function(e){var t=e.xhr,n=e.flags,r=function(e,t){this.cache={},this.onload=e,this.oncomplete=t,this.inflight=0,this.pending={}};r.prototype={addNodes:function(e){this.inflight+=e.length;for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)this.require(t);this.checkDone()},addNode:function(e){this.inflight++,this.require(e),this.checkDone()},require:function(e){var t=e.src||e.href;e.__nodeUrl=t,this.dedupe(t,e)||this.fetch(t,e)},dedupe:function(e,t){if(this.pending[e])return this.pending[e].push(t),!0;return this.cache[e]?(this.onload(e,t,this.cache[e]),this.tail(),!0):(this.pending[e]=[t],!1)},fetch:function(e,r){if(n.load&&console.log("fetch",e,r),e)if(e.match(/^data:/)){var o=e.split(","),i=o[0],a=o[1];a=i.indexOf(";base64")>-1?atob(a):decodeURIComponent(a),setTimeout(function(){this.receive(e,r,null,a)}.bind(this),0)}else{var s=function(t,n,o){this.receive(e,r,t,n,o)}.bind(this);t.load(e,s)}else setTimeout(function(){this.receive(e,r,{error:"href must be specified"},null)}.bind(this),0)},receive:function(e,t,n,r,o){this.cache[e]=r;for(var i,a=this.pending[e],s=0,c=a.length;c>s&&(i=a[s]);s++)this.onload(e,i,r,n,o),this.tail();this.pending[e]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},e.Loader=r}),window.HTMLImports.addModule(function(e){var t=function(e){this.addCallback=e,this.mo=new MutationObserver(this.handler.bind(this))};t.prototype={handler:function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)"childList"===t.type&&t.addedNodes.length&&this.addedNodes(t.addedNodes)},addedNodes:function(e){this.addCallback&&this.addCallback(e);for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.children&&t.children.length&&this.addedNodes(t.children)},observe:function(e){this.mo.observe(e,{childList:!0,subtree:!0})}},e.Observer=t}),window.HTMLImports.addModule(function(e){function t(e){return"link"===e.localName&&e.rel===u}function n(e){var t=r(e);return"data:text/javascript;charset=utf-8,"+encodeURIComponent(t)}function r(e){return e.textContent+o(e)}function o(e){var t=e.ownerDocument;t.__importedScripts=t.__importedScripts||0;var n=e.ownerDocument.baseURI,r=t.__importedScripts?"-"+t.__importedScripts:"";return t.__importedScripts++,"\n//# sourceURL="+n+r+".js\n"}function i(e){var t=e.ownerDocument.createElement("style");return t.textContent=e.textContent,a.resolveUrlsInStyle(t),t}var a=e.path,s=e.rootDocument,c=e.flags,d=e.isIE,u=e.IMPORT_LINK_TYPE,l="link[rel="+u+"]",h={documentSelectors:l,importsSelectors:[l,"link[rel=stylesheet]","style","script:not([type])",'script[type="application/javascript"]','script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},dynamicElements:[],parseNext:function(){var e=this.nextToParse();e&&this.parse(e)},parse:function(e){if(this.isParsed(e))return void(c.parse&&console.log("[%s] is already parsed",e.localName));var t=this[this.map[e.localName]];t&&(this.markParsing(e),t.call(this,e))},parseDynamic:function(e,t){this.dynamicElements.push(e),t||this.parseNext()},markParsing:function(e){c.parse&&console.log("parsing",e),this.parsingElement=e},markParsingComplete:function(e){e.__importParsed=!0,this.markDynamicParsingComplete(e),e.__importElement&&(e.__importElement.__importParsed=!0,this.markDynamicParsingComplete(e.__importElement)),this.parsingElement=null,c.parse&&console.log("completed",e)},markDynamicParsingComplete:function(e){var t=this.dynamicElements.indexOf(e);t>=0&&this.dynamicElements.splice(t,1)},parseImport:function(e){if(window.HTMLImports.__importsParsingHook&&window.HTMLImports.__importsParsingHook(e),e["import"]&&(e["import"].__importParsed=!0),this.markParsingComplete(e),e.dispatchEvent(e.__resource&&!e.__error?new CustomEvent("load",{bubbles:!1}):new CustomEvent("error",{bubbles:!1})),e.__pending)for(var t;e.__pending.length;)t=e.__pending.shift(),t&&t({target:e});this.parseNext()},parseLink:function(e){t(e)?this.parseImport(e):(e.href=e.href,this.parseGeneric(e))},parseStyle:function(e){var t=e;e=i(e),t.__appliedElement=e,e.__importElement=t,this.parseGeneric(e)},parseGeneric:function(e){this.trackElement(e),this.addElementToDocument(e)},rootImportForElement:function(e){for(var t=e;t.ownerDocument.__importLink;)t=t.ownerDocument.__importLink;return t},addElementToDocument:function(e){var t=this.rootImportForElement(e.__importElement||e);t.parentNode.insertBefore(e,t)},trackElement:function(e,t){var n=this,r=function(r){t&&t(r),n.markParsingComplete(e),n.parseNext()};if(e.addEventListener("load",r),e.addEventListener("error",r),d&&"style"===e.localName){var o=!1;if(-1==e.textContent.indexOf("@import"))o=!0;else if(e.sheet){o=!0;for(var i,a=e.sheet.cssRules,s=a?a.length:0,c=0;s>c&&(i=a[c]);c++)i.type===CSSRule.IMPORT_RULE&&(o=o&&Boolean(i.styleSheet))}o&&setTimeout(function(){e.dispatchEvent(new CustomEvent("load",{bubbles:!1}))})}},parseScript:function(t){var r=document.createElement("script");r.__importElement=t,r.src=t.src?t.src:n(t),e.currentScript=t,this.trackElement(r,function(t){r.parentNode.removeChild(r),e.currentScript=null}),this.addElementToDocument(r)},nextToParse:function(){return this._mayParse=[],!this.parsingElement&&(this.nextToParseInDoc(s)||this.nextToParseDynamic())},nextToParseInDoc:function(e,n){if(e&&this._mayParse.indexOf(e)<0){this._mayParse.push(e);for(var r,o=e.querySelectorAll(this.parseSelectorsForNode(e)),i=0,a=o.length;a>i&&(r=o[i]);i++)if(!this.isParsed(r))return this.hasResource(r)?t(r)?this.nextToParseInDoc(r["import"],r):r:void 0}return n},nextToParseDynamic:function(){return this.dynamicElements[0]},parseSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===s?this.documentSelectors:this.importsSelectors},isParsed:function(e){return e.__importParsed},needsDynamicParsing:function(e){return this.dynamicElements.indexOf(e)>=0},hasResource:function(e){return t(e)&&void 0===e["import"]?!1:!0}};e.parser=h,e.IMPORT_SELECTOR=l}),window.HTMLImports.addModule(function(e){function t(e){return n(e,a)}function n(e,t){return"link"===e.localName&&e.getAttribute("rel")===t}function r(e){return!!Object.getOwnPropertyDescriptor(e,"baseURI")}function o(e,t){var n=document.implementation.createHTMLDocument(a);n._URL=t;var o=n.createElement("base");o.setAttribute("href",t),n.baseURI||r(n)||Object.defineProperty(n,"baseURI",{value:t});var i=n.createElement("meta");return i.setAttribute("charset","utf-8"),n.head.appendChild(i),n.head.appendChild(o),n.body.innerHTML=e,window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(n),n}var i=e.flags,a=e.IMPORT_LINK_TYPE,s=e.IMPORT_SELECTOR,c=e.rootDocument,d=e.Loader,u=e.Observer,l=e.parser,h={documents:{},documentPreloadSelectors:s,importsPreloadSelectors:[s].join(","),loadNode:function(e){p.addNode(e)},loadSubtree:function(e){var t=this.marshalNodes(e);p.addNodes(t)},marshalNodes:function(e){return e.querySelectorAll(this.loadSelectorsForNode(e))},loadSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===c?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(e,n,r,a,s){if(i.load&&console.log("loaded",e,n),n.__resource=r,n.__error=a,t(n)){var c=this.documents[e];void 0===c&&(c=a?null:o(r,s||e),c&&(c.__importLink=n,this.bootDocument(c)),this.documents[e]=c),n["import"]=c}l.parseNext()},bootDocument:function(e){this.loadSubtree(e),this.observer.observe(e),l.parseNext()},loadedAll:function(){l.parseNext()}},p=new d(h.loaded.bind(h),h.loadedAll.bind(h));if(h.observer=new u,!document.baseURI){var f={get:function(){var e=document.querySelector("base");return e?e.href:window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",f),Object.defineProperty(c,"baseURI",f)}e.importer=h,e.importLoader=p}),window.HTMLImports.addModule(function(e){var t=e.parser,n=e.importer,r={added:function(e){for(var r,o,i,a,s=0,c=e.length;c>s&&(a=e[s]);s++)r||(r=a.ownerDocument,o=t.isParsed(r)),i=this.shouldLoadNode(a),i&&n.loadNode(a),this.shouldParseNode(a)&&o&&t.parseDynamic(a,i)},shouldLoadNode:function(e){return 1===e.nodeType&&o.call(e,n.loadSelectorsForNode(e))},shouldParseNode:function(e){return 1===e.nodeType&&o.call(e,t.parseSelectorsForNode(e))}};n.observer.addCallback=r.added.bind(r);var o=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector}),function(e){function t(){window.HTMLImports.importer.bootDocument(o)}var n=e.initializeModules,r=e.isIE;if(!e.useNative){r&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n.preventDefault=function(){Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}})},n},window.CustomEvent.prototype=window.Event.prototype),n();var o=e.rootDocument;"complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?t():document.addEventListener("DOMContentLoaded",t)}}(window.HTMLImports),window.CustomElements=window.CustomElements||{flags:{}},function(e){var t=e.flags,n=[],r=function(e){n.push(e)},o=function(){n.forEach(function(t){t(e)})};e.addModule=r,e.initializeModules=o,e.hasNative=Boolean(document.registerElement),e.useNative=!t.register&&e.hasNative&&!window.ShadowDOMPolyfill&&(!window.HTMLImports||window.HTMLImports.useNative)}(window.CustomElements),window.CustomElements.addModule(function(e){function t(e,t){n(e,function(e){return t(e)?!0:void r(e,t)}),r(e,t)}function n(e,t,r){var o=e.firstElementChild;if(!o)for(o=e.firstChild;o&&o.nodeType!==Node.ELEMENT_NODE;)o=o.nextSibling;for(;o;)t(o,r)!==!0&&n(o,t,r),o=o.nextElementSibling;return null}function r(e,n){for(var r=e.shadowRoot;r;)t(r,n),r=r.olderShadowRoot}function o(e,t){i(e,t,[])}function i(e,t,n){if(e=window.wrap(e),!(n.indexOf(e)>=0)){n.push(e);for(var r,o=e.querySelectorAll("link[rel="+a+"]"),s=0,c=o.length;c>s&&(r=o[s]);s++)r["import"]&&i(r["import"],t,n);t(e)}}var a=window.HTMLImports?window.HTMLImports.IMPORT_LINK_TYPE:"none";e.forDocumentTree=o,e.forSubtree=t}),window.CustomElements.addModule(function(e){function t(e){return n(e)||r(e)}function n(t){return e.upgrade(t)?!0:void s(t)}function r(e){g(e,function(e){return n(e)?!0:void 0})}function o(e){s(e),h(e)&&g(e,function(e){s(e)})}function i(e){M.push(e),L||(L=!0,setTimeout(a))}function a(){L=!1;for(var e,t=M,n=0,r=t.length;r>n&&(e=t[n]);n++)e();M=[]}function s(e){E?i(function(){c(e)}):c(e)}function c(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&!e.__attached&&h(e)&&(e.__attached=!0,e.attachedCallback&&e.attachedCallback())}function d(e){u(e),g(e,function(e){u(e)})}function u(e){E?i(function(){l(e)}):l(e)}function l(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&e.__attached&&!h(e)&&(e.__attached=!1,e.detachedCallback&&e.detachedCallback())}function h(e){for(var t=e,n=wrap(document);t;){if(t==n)return!0;t=t.parentNode||t.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&t.host}}function p(e){if(e.shadowRoot&&!e.shadowRoot.__watched){b.dom&&console.log("watching shadow-root for: ",e.localName);for(var t=e.shadowRoot;t;)v(t),t=t.olderShadowRoot}}function f(e){if(b.dom){var n=e[0];if(n&&"childList"===n.type&&n.addedNodes&&n.addedNodes){for(var r=n.addedNodes[0];r&&r!==document&&!r.host;)r=r.parentNode;var o=r&&(r.URL||r._URL||r.host&&r.host.localName)||"";o=o.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",e.length,o||"")}e.forEach(function(e){"childList"===e.type&&(T(e.addedNodes,function(e){e.localName&&t(e)}),T(e.removedNodes,function(e){e.localName&&d(e)}))}),b.dom&&console.groupEnd()}function m(e){for(e=window.wrap(e),e||(e=window.wrap(document));e.parentNode;)e=e.parentNode;var t=e.__observer;t&&(f(t.takeRecords()),a())}function v(e){if(!e.__observer){var t=new MutationObserver(f);t.observe(e,{childList:!0,subtree:!0}),e.__observer=t}}function _(e){e=window.wrap(e),b.dom&&console.group("upgradeDocument: ",e.baseURI.split("/").pop()),t(e),v(e),b.dom&&console.groupEnd()}function w(e){y(e,_)}var b=e.flags,g=e.forSubtree,y=e.forDocumentTree,E=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;e.hasPolyfillMutations=E;var L=!1,M=[],T=Array.prototype.forEach.call.bind(Array.prototype.forEach),N=Element.prototype.createShadowRoot;N&&(Element.prototype.createShadowRoot=function(){var e=N.call(this);return window.CustomElements.watchShadow(this),e}),e.watchShadow=p,e.upgradeDocumentTree=w,e.upgradeSubtree=r,e.upgradeAll=t,e.attachedNode=o,e.takeRecords=m}),window.CustomElements.addModule(function(e){function t(t){if(!t.__upgraded__&&t.nodeType===Node.ELEMENT_NODE){var r=t.getAttribute("is"),o=e.getRegisteredDefinition(r||t.localName);if(o){if(r&&o.tag==t.localName)return n(t,o);if(!r&&!o["extends"])return n(t,o)}}}function n(t,n){return a.upgrade&&console.group("upgrade:",t.localName),n.is&&t.setAttribute("is",n.is),r(t,n),t.__upgraded__=!0,i(t),e.attachedNode(t),e.upgradeSubtree(t),a.upgrade&&console.groupEnd(),t}function r(e,t){Object.__proto__?e.__proto__=t.prototype:(o(e,t.prototype,t["native"]),e.__proto__=t.prototype)}function o(e,t,n){for(var r={},o=t;o!==n&&o!==HTMLElement.prototype;){for(var i,a=Object.getOwnPropertyNames(o),s=0;i=a[s];s++)r[i]||(Object.defineProperty(e,i,Object.getOwnPropertyDescriptor(o,i)),r[i]=1);o=Object.getPrototypeOf(o)}}function i(e){e.createdCallback&&e.createdCallback()}var a=e.flags;e.upgrade=t,e.upgradeWithDefinition=n,e.implementPrototype=r}),window.CustomElements.addModule(function(e){function t(t,r){var c=r||{};if(!t)throw new Error("document.registerElement: first argument `name` must not be empty");if(t.indexOf("-")<0)throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(t)+"'.");if(o(t))throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '"+String(t)+"'. The type name is invalid.");if(d(t))throw new Error("DuplicateDefinitionError: a type with name '"+String(t)+"' is already registered");return c.prototype||(c.prototype=Object.create(HTMLElement.prototype)),c.__name=t.toLowerCase(),c.lifecycle=c.lifecycle||{},c.ancestry=i(c["extends"]),a(c),s(c),n(c.prototype),u(c.__name,c),c.ctor=l(c),c.ctor.prototype=c.prototype,c.prototype.constructor=c.ctor,e.ready&&_(document),c.ctor}function n(e){if(!e.setAttribute._polyfilled){var t=e.setAttribute;e.setAttribute=function(e,n){r.call(this,e,n,t)};var n=e.removeAttribute;e.removeAttribute=function(e){r.call(this,e,null,n);
+
+},e.setAttribute._polyfilled=!0}}function r(e,t,n){e=e.toLowerCase();var r=this.getAttribute(e);n.apply(this,arguments);var o=this.getAttribute(e);this.attributeChangedCallback&&o!==r&&this.attributeChangedCallback(e,r,o)}function o(e){for(var t=0;t<E.length;t++)if(e===E[t])return!0}function i(e){var t=d(e);return t?i(t["extends"]).concat([t]):[]}function a(e){for(var t,n=e["extends"],r=0;t=e.ancestry[r];r++)n=t.is&&t.tag;e.tag=n||e.__name,n&&(e.is=e.__name)}function s(e){if(!Object.__proto__){var t=HTMLElement.prototype;if(e.is){var n=document.createElement(e.tag),r=Object.getPrototypeOf(n);r===e.prototype&&(t=r)}for(var o,i=e.prototype;i&&i!==t;)o=Object.getPrototypeOf(i),i.__proto__=o,i=o;e["native"]=t}}function c(e){return b(T(e.tag),e)}function d(e){return e?L[e.toLowerCase()]:void 0}function u(e,t){L[e]=t}function l(e){return function(){return c(e)}}function h(e,t,n){return e===M?p(t,n):N(e,t)}function p(e,t){e&&(e=e.toLowerCase()),t&&(t=t.toLowerCase());var n=d(t||e);if(n){if(e==n.tag&&t==n.is)return new n.ctor;if(!t&&!n.is)return new n.ctor}var r;return t?(r=p(e),r.setAttribute("is",t),r):(r=T(e),e.indexOf("-")>=0&&g(r,HTMLElement),r)}function f(e,t){var n=e[t];e[t]=function(){var e=n.apply(this,arguments);return w(e),e}}var m,v=e.isIE11OrOlder,_=e.upgradeDocumentTree,w=e.upgradeAll,b=e.upgradeWithDefinition,g=e.implementPrototype,y=e.useNative,E=["annotation-xml","color-profile","font-face","font-face-src","font-face-uri","font-face-format","font-face-name","missing-glyph"],L={},M="http://www.w3.org/1999/xhtml",T=document.createElement.bind(document),N=document.createElementNS.bind(document);m=Object.__proto__||y?function(e,t){return e instanceof t}:function(e,t){for(var n=e;n;){if(n===t.prototype)return!0;n=n.__proto__}return!1},f(Node.prototype,"cloneNode"),f(document,"importNode"),v&&!function(){var e=document.importNode;document.importNode=function(){var t=e.apply(document,arguments);if(t.nodeType==t.DOCUMENT_FRAGMENT_NODE){var n=document.createDocumentFragment();return n.appendChild(t),n}return t}}(),document.registerElement=t,document.createElement=p,document.createElementNS=h,e.registry=L,e["instanceof"]=m,e.reservedTagList=E,e.getRegisteredDefinition=d,document.register=document.registerElement}),function(e){function t(){a(window.wrap(document)),window.HTMLImports&&(window.HTMLImports.__importsParsingHook=function(e){a(wrap(e["import"]))}),window.CustomElements.ready=!0,setTimeout(function(){window.CustomElements.readyTime=Date.now(),window.HTMLImports&&(window.CustomElements.elapsed=window.CustomElements.readyTime-window.HTMLImports.readyTime),document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})}var n=e.useNative,r=e.initializeModules,o=/Trident/.test(navigator.userAgent);if(n){var i=function(){};e.watchShadow=i,e.upgrade=i,e.upgradeAll=i,e.upgradeDocumentTree=i,e.upgradeSubtree=i,e.takeRecords=i,e["instanceof"]=function(e,t){return e instanceof t}}else r();var a=e.upgradeDocumentTree;if(window.wrap||(window.ShadowDOMPolyfill?(window.wrap=window.ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=window.ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}),o&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n.preventDefault=function(){Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}})},n},window.CustomEvent.prototype=window.Event.prototype),"complete"===document.readyState||e.flags.eager)t();else if("interactive"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var s=window.HTMLImports&&!window.HTMLImports.ready?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(s,t)}else t();e.isIE11OrOlder=o}(window.CustomElements),"undefined"==typeof HTMLTemplateElement&&!function(){var e="template";HTMLTemplateElement=function(){},HTMLTemplateElement.prototype=Object.create(HTMLElement.prototype),HTMLTemplateElement.decorate=function(e){e.content||(e.content=e.ownerDocument.createDocumentFragment());for(var t;t=e.firstChild;)e.content.appendChild(t)},HTMLTemplateElement.bootstrap=function(t){for(var n,r=t.querySelectorAll(e),o=0,i=r.length;i>o&&(n=r[o]);o++)HTMLTemplateElement.decorate(n)},window.addEventListener("DOMContentLoaded",function(){HTMLTemplateElement.bootstrap(document)});var t=document.createElement;document.createElement=function(){"use strict";var e=t.apply(document,arguments);return"template"==e.localName&&HTMLTemplateElement.decorate(e),e}}(),function(e){var t=document.createElement("style");t.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \n";var n=document.querySelector("head");n.insertBefore(t,n.firstChild)}(window.WebComponents);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/webcomponents.js b/polymer_1.0.4/bower_components/webcomponentsjs/webcomponents.js
new file mode 100644
index 0000000..6d71541
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/webcomponents.js
@@ -0,0 +1,7126 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.7.5
+window.WebComponents = window.WebComponents || {};
+
+(function(scope) {
+ var flags = scope.flags || {};
+ var file = "webcomponents.js";
+ var script = document.querySelector('script[src*="' + file + '"]');
+ if (!flags.noOpts) {
+ location.search.slice(1).split("&").forEach(function(option) {
+ var parts = option.split("=");
+ var match;
+ if (parts[0] && (match = parts[0].match(/wc-(.+)/))) {
+ flags[match[1]] = parts[1] || true;
+ }
+ });
+ if (script) {
+ for (var i = 0, a; a = script.attributes[i]; i++) {
+ if (a.name !== "src") {
+ flags[a.name] = a.value || true;
+ }
+ }
+ }
+ if (flags.log && flags.log.split) {
+ var parts = flags.log.split(",");
+ flags.log = {};
+ parts.forEach(function(f) {
+ flags.log[f] = true;
+ });
+ } else {
+ flags.log = {};
+ }
+ }
+ flags.shadow = flags.shadow || flags.shadowdom || flags.polyfill;
+ if (flags.shadow === "native") {
+ flags.shadow = false;
+ } else {
+ flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot;
+ }
+ if (flags.register) {
+ window.CustomElements = window.CustomElements || {
+ flags: {}
+ };
+ window.CustomElements.flags.register = flags.register;
+ }
+ scope.flags = flags;
+})(WebComponents);
+
+if (WebComponents.flags.shadow) {
+ if (typeof WeakMap === "undefined") {
+ (function() {
+ var defineProperty = Object.defineProperty;
+ var counter = Date.now() % 1e9;
+ var WeakMap = function() {
+ this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
+ };
+ WeakMap.prototype = {
+ set: function(key, value) {
+ var entry = key[this.name];
+ if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
+ value: [ key, value ],
+ writable: true
+ });
+ return this;
+ },
+ get: function(key) {
+ var entry;
+ return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
+ },
+ "delete": function(key) {
+ var entry = key[this.name];
+ if (!entry || entry[0] !== key) return false;
+ entry[0] = entry[1] = undefined;
+ return true;
+ },
+ has: function(key) {
+ var entry = key[this.name];
+ if (!entry) return false;
+ return entry[0] === key;
+ }
+ };
+ window.WeakMap = WeakMap;
+ })();
+ }
+ window.ShadowDOMPolyfill = {};
+ (function(scope) {
+ "use strict";
+ var constructorTable = new WeakMap();
+ var nativePrototypeTable = new WeakMap();
+ var wrappers = Object.create(null);
+ function detectEval() {
+ if (typeof chrome !== "undefined" && chrome.app && chrome.app.runtime) {
+ return false;
+ }
+ if (navigator.getDeviceStorage) {
+ return false;
+ }
+ try {
+ var f = new Function("return true;");
+ return f();
+ } catch (ex) {
+ return false;
+ }
+ }
+ var hasEval = detectEval();
+ function assert(b) {
+ if (!b) throw new Error("Assertion failed");
+ }
+ var defineProperty = Object.defineProperty;
+ var getOwnPropertyNames = Object.getOwnPropertyNames;
+ var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
+ function mixin(to, from) {
+ var names = getOwnPropertyNames(from);
+ for (var i = 0; i < names.length; i++) {
+ var name = names[i];
+ defineProperty(to, name, getOwnPropertyDescriptor(from, name));
+ }
+ return to;
+ }
+ function mixinStatics(to, from) {
+ var names = getOwnPropertyNames(from);
+ for (var i = 0; i < names.length; i++) {
+ var name = names[i];
+ switch (name) {
+ case "arguments":
+ case "caller":
+ case "length":
+ case "name":
+ case "prototype":
+ case "toString":
+ continue;
+ }
+ defineProperty(to, name, getOwnPropertyDescriptor(from, name));
+ }
+ return to;
+ }
+ function oneOf(object, propertyNames) {
+ for (var i = 0; i < propertyNames.length; i++) {
+ if (propertyNames[i] in object) return propertyNames[i];
+ }
+ }
+ var nonEnumerableDataDescriptor = {
+ value: undefined,
+ configurable: true,
+ enumerable: false,
+ writable: true
+ };
+ function defineNonEnumerableDataProperty(object, name, value) {
+ nonEnumerableDataDescriptor.value = value;
+ defineProperty(object, name, nonEnumerableDataDescriptor);
+ }
+ getOwnPropertyNames(window);
+ function getWrapperConstructor(node, opt_instance) {
+ var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);
+ if (isFirefox) {
+ try {
+ getOwnPropertyNames(nativePrototype);
+ } catch (error) {
+ nativePrototype = nativePrototype.__proto__;
+ }
+ }
+ var wrapperConstructor = constructorTable.get(nativePrototype);
+ if (wrapperConstructor) return wrapperConstructor;
+ var parentWrapperConstructor = getWrapperConstructor(nativePrototype);
+ var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor);
+ registerInternal(nativePrototype, GeneratedWrapper, opt_instance);
+ return GeneratedWrapper;
+ }
+ function addForwardingProperties(nativePrototype, wrapperPrototype) {
+ installProperty(nativePrototype, wrapperPrototype, true);
+ }
+ function registerInstanceProperties(wrapperPrototype, instanceObject) {
+ installProperty(instanceObject, wrapperPrototype, false);
+ }
+ var isFirefox = /Firefox/.test(navigator.userAgent);
+ var dummyDescriptor = {
+ get: function() {},
+ set: function(v) {},
+ configurable: true,
+ enumerable: true
+ };
+ function isEventHandlerName(name) {
+ return /^on[a-z]+$/.test(name);
+ }
+ function isIdentifierName(name) {
+ return /^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name);
+ }
+ function getGetter(name) {
+ return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name) : function() {
+ return this.__impl4cf1e782hg__[name];
+ };
+ }
+ function getSetter(name) {
+ return hasEval && isIdentifierName(name) ? new Function("v", "this.__impl4cf1e782hg__." + name + " = v") : function(v) {
+ this.__impl4cf1e782hg__[name] = v;
+ };
+ }
+ function getMethod(name) {
+ return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name + ".apply(this.__impl4cf1e782hg__, arguments)") : function() {
+ return this.__impl4cf1e782hg__[name].apply(this.__impl4cf1e782hg__, arguments);
+ };
+ }
+ function getDescriptor(source, name) {
+ try {
+ return Object.getOwnPropertyDescriptor(source, name);
+ } catch (ex) {
+ return dummyDescriptor;
+ }
+ }
+ var isBrokenSafari = function() {
+ var descr = Object.getOwnPropertyDescriptor(Node.prototype, "nodeType");
+ return descr && !descr.get && !descr.set;
+ }();
+ function installProperty(source, target, allowMethod, opt_blacklist) {
+ var names = getOwnPropertyNames(source);
+ for (var i = 0; i < names.length; i++) {
+ var name = names[i];
+ if (name === "polymerBlackList_") continue;
+ if (name in target) continue;
+ if (source.polymerBlackList_ && source.polymerBlackList_[name]) continue;
+ if (isFirefox) {
+ source.__lookupGetter__(name);
+ }
+ var descriptor = getDescriptor(source, name);
+ var getter, setter;
+ if (typeof descriptor.value === "function") {
+ if (allowMethod) {
+ target[name] = getMethod(name);
+ }
+ continue;
+ }
+ var isEvent = isEventHandlerName(name);
+ if (isEvent) getter = scope.getEventHandlerGetter(name); else getter = getGetter(name);
+ if (descriptor.writable || descriptor.set || isBrokenSafari) {
+ if (isEvent) setter = scope.getEventHandlerSetter(name); else setter = getSetter(name);
+ }
+ var configurable = isBrokenSafari || descriptor.configurable;
+ defineProperty(target, name, {
+ get: getter,
+ set: setter,
+ configurable: configurable,
+ enumerable: descriptor.enumerable
+ });
+ }
+ }
+ function register(nativeConstructor, wrapperConstructor, opt_instance) {
+ if (nativeConstructor == null) {
+ return;
+ }
+ var nativePrototype = nativeConstructor.prototype;
+ registerInternal(nativePrototype, wrapperConstructor, opt_instance);
+ mixinStatics(wrapperConstructor, nativeConstructor);
+ }
+ function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {
+ var wrapperPrototype = wrapperConstructor.prototype;
+ assert(constructorTable.get(nativePrototype) === undefined);
+ constructorTable.set(nativePrototype, wrapperConstructor);
+ nativePrototypeTable.set(wrapperPrototype, nativePrototype);
+ addForwardingProperties(nativePrototype, wrapperPrototype);
+ if (opt_instance) registerInstanceProperties(wrapperPrototype, opt_instance);
+ defineNonEnumerableDataProperty(wrapperPrototype, "constructor", wrapperConstructor);
+ wrapperConstructor.prototype = wrapperPrototype;
+ }
+ function isWrapperFor(wrapperConstructor, nativeConstructor) {
+ return constructorTable.get(nativeConstructor.prototype) === wrapperConstructor;
+ }
+ function registerObject(object) {
+ var nativePrototype = Object.getPrototypeOf(object);
+ var superWrapperConstructor = getWrapperConstructor(nativePrototype);
+ var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);
+ registerInternal(nativePrototype, GeneratedWrapper, object);
+ return GeneratedWrapper;
+ }
+ function createWrapperConstructor(superWrapperConstructor) {
+ function GeneratedWrapper(node) {
+ superWrapperConstructor.call(this, node);
+ }
+ var p = Object.create(superWrapperConstructor.prototype);
+ p.constructor = GeneratedWrapper;
+ GeneratedWrapper.prototype = p;
+ return GeneratedWrapper;
+ }
+ function isWrapper(object) {
+ return object && object.__impl4cf1e782hg__;
+ }
+ function isNative(object) {
+ return !isWrapper(object);
+ }
+ function wrap(impl) {
+ if (impl === null) return null;
+ assert(isNative(impl));
+ var wrapper = impl.__wrapper8e3dd93a60__;
+ if (wrapper != null) {
+ return wrapper;
+ }
+ return impl.__wrapper8e3dd93a60__ = new (getWrapperConstructor(impl, impl))(impl);
+ }
+ function unwrap(wrapper) {
+ if (wrapper === null) return null;
+ assert(isWrapper(wrapper));
+ return wrapper.__impl4cf1e782hg__;
+ }
+ function unsafeUnwrap(wrapper) {
+ return wrapper.__impl4cf1e782hg__;
+ }
+ function setWrapper(impl, wrapper) {
+ wrapper.__impl4cf1e782hg__ = impl;
+ impl.__wrapper8e3dd93a60__ = wrapper;
+ }
+ function unwrapIfNeeded(object) {
+ return object && isWrapper(object) ? unwrap(object) : object;
+ }
+ function wrapIfNeeded(object) {
+ return object && !isWrapper(object) ? wrap(object) : object;
+ }
+ function rewrap(node, wrapper) {
+ if (wrapper === null) return;
+ assert(isNative(node));
+ assert(wrapper === undefined || isWrapper(wrapper));
+ node.__wrapper8e3dd93a60__ = wrapper;
+ }
+ var getterDescriptor = {
+ get: undefined,
+ configurable: true,
+ enumerable: true
+ };
+ function defineGetter(constructor, name, getter) {
+ getterDescriptor.get = getter;
+ defineProperty(constructor.prototype, name, getterDescriptor);
+ }
+ function defineWrapGetter(constructor, name) {
+ defineGetter(constructor, name, function() {
+ return wrap(this.__impl4cf1e782hg__[name]);
+ });
+ }
+ function forwardMethodsToWrapper(constructors, names) {
+ constructors.forEach(function(constructor) {
+ names.forEach(function(name) {
+ constructor.prototype[name] = function() {
+ var w = wrapIfNeeded(this);
+ return w[name].apply(w, arguments);
+ };
+ });
+ });
+ }
+ scope.assert = assert;
+ scope.constructorTable = constructorTable;
+ scope.defineGetter = defineGetter;
+ scope.defineWrapGetter = defineWrapGetter;
+ scope.forwardMethodsToWrapper = forwardMethodsToWrapper;
+ scope.isIdentifierName = isIdentifierName;
+ scope.isWrapper = isWrapper;
+ scope.isWrapperFor = isWrapperFor;
+ scope.mixin = mixin;
+ scope.nativePrototypeTable = nativePrototypeTable;
+ scope.oneOf = oneOf;
+ scope.registerObject = registerObject;
+ scope.registerWrapper = register;
+ scope.rewrap = rewrap;
+ scope.setWrapper = setWrapper;
+ scope.unsafeUnwrap = unsafeUnwrap;
+ scope.unwrap = unwrap;
+ scope.unwrapIfNeeded = unwrapIfNeeded;
+ scope.wrap = wrap;
+ scope.wrapIfNeeded = wrapIfNeeded;
+ scope.wrappers = wrappers;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ function newSplice(index, removed, addedCount) {
+ return {
+ index: index,
+ removed: removed,
+ addedCount: addedCount
+ };
+ }
+ var EDIT_LEAVE = 0;
+ var EDIT_UPDATE = 1;
+ var EDIT_ADD = 2;
+ var EDIT_DELETE = 3;
+ function ArraySplice() {}
+ ArraySplice.prototype = {
+ calcEditDistances: function(current, currentStart, currentEnd, old, oldStart, oldEnd) {
+ var rowCount = oldEnd - oldStart + 1;
+ var columnCount = currentEnd - currentStart + 1;
+ var distances = new Array(rowCount);
+ for (var i = 0; i < rowCount; i++) {
+ distances[i] = new Array(columnCount);
+ distances[i][0] = i;
+ }
+ for (var j = 0; j < columnCount; j++) distances[0][j] = j;
+ for (var i = 1; i < rowCount; i++) {
+ for (var j = 1; j < columnCount; j++) {
+ if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1])) distances[i][j] = distances[i - 1][j - 1]; else {
+ var north = distances[i - 1][j] + 1;
+ var west = distances[i][j - 1] + 1;
+ distances[i][j] = north < west ? north : west;
+ }
+ }
+ }
+ return distances;
+ },
+ spliceOperationsFromEditDistances: function(distances) {
+ var i = distances.length - 1;
+ var j = distances[0].length - 1;
+ var current = distances[i][j];
+ var edits = [];
+ while (i > 0 || j > 0) {
+ if (i == 0) {
+ edits.push(EDIT_ADD);
+ j--;
+ continue;
+ }
+ if (j == 0) {
+ edits.push(EDIT_DELETE);
+ i--;
+ continue;
+ }
+ var northWest = distances[i - 1][j - 1];
+ var west = distances[i - 1][j];
+ var north = distances[i][j - 1];
+ var min;
+ if (west < north) min = west < northWest ? west : northWest; else min = north < northWest ? north : northWest;
+ if (min == northWest) {
+ if (northWest == current) {
+ edits.push(EDIT_LEAVE);
+ } else {
+ edits.push(EDIT_UPDATE);
+ current = northWest;
+ }
+ i--;
+ j--;
+ } else if (min == west) {
+ edits.push(EDIT_DELETE);
+ i--;
+ current = west;
+ } else {
+ edits.push(EDIT_ADD);
+ j--;
+ current = north;
+ }
+ }
+ edits.reverse();
+ return edits;
+ },
+ calcSplices: function(current, currentStart, currentEnd, old, oldStart, oldEnd) {
+ var prefixCount = 0;
+ var suffixCount = 0;
+ var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);
+ if (currentStart == 0 && oldStart == 0) prefixCount = this.sharedPrefix(current, old, minLength);
+ if (currentEnd == current.length && oldEnd == old.length) suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);
+ currentStart += prefixCount;
+ oldStart += prefixCount;
+ currentEnd -= suffixCount;
+ oldEnd -= suffixCount;
+ if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0) return [];
+ if (currentStart == currentEnd) {
+ var splice = newSplice(currentStart, [], 0);
+ while (oldStart < oldEnd) splice.removed.push(old[oldStart++]);
+ return [ splice ];
+ } else if (oldStart == oldEnd) return [ newSplice(currentStart, [], currentEnd - currentStart) ];
+ var ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));
+ var splice = undefined;
+ var splices = [];
+ var index = currentStart;
+ var oldIndex = oldStart;
+ for (var i = 0; i < ops.length; i++) {
+ switch (ops[i]) {
+ case EDIT_LEAVE:
+ if (splice) {
+ splices.push(splice);
+ splice = undefined;
+ }
+ index++;
+ oldIndex++;
+ break;
+
+ case EDIT_UPDATE:
+ if (!splice) splice = newSplice(index, [], 0);
+ splice.addedCount++;
+ index++;
+ splice.removed.push(old[oldIndex]);
+ oldIndex++;
+ break;
+
+ case EDIT_ADD:
+ if (!splice) splice = newSplice(index, [], 0);
+ splice.addedCount++;
+ index++;
+ break;
+
+ case EDIT_DELETE:
+ if (!splice) splice = newSplice(index, [], 0);
+ splice.removed.push(old[oldIndex]);
+ oldIndex++;
+ break;
+ }
+ }
+ if (splice) {
+ splices.push(splice);
+ }
+ return splices;
+ },
+ sharedPrefix: function(current, old, searchLength) {
+ for (var i = 0; i < searchLength; i++) if (!this.equals(current[i], old[i])) return i;
+ return searchLength;
+ },
+ sharedSuffix: function(current, old, searchLength) {
+ var index1 = current.length;
+ var index2 = old.length;
+ var count = 0;
+ while (count < searchLength && this.equals(current[--index1], old[--index2])) count++;
+ return count;
+ },
+ calculateSplices: function(current, previous) {
+ return this.calcSplices(current, 0, current.length, previous, 0, previous.length);
+ },
+ equals: function(currentValue, previousValue) {
+ return currentValue === previousValue;
+ }
+ };
+ scope.ArraySplice = ArraySplice;
+ })(window.ShadowDOMPolyfill);
+ (function(context) {
+ "use strict";
+ var OriginalMutationObserver = window.MutationObserver;
+ var callbacks = [];
+ var pending = false;
+ var timerFunc;
+ function handle() {
+ pending = false;
+ var copies = callbacks.slice(0);
+ callbacks = [];
+ for (var i = 0; i < copies.length; i++) {
+ (0, copies[i])();
+ }
+ }
+ if (OriginalMutationObserver) {
+ var counter = 1;
+ var observer = new OriginalMutationObserver(handle);
+ var textNode = document.createTextNode(counter);
+ observer.observe(textNode, {
+ characterData: true
+ });
+ timerFunc = function() {
+ counter = (counter + 1) % 2;
+ textNode.data = counter;
+ };
+ } else {
+ timerFunc = window.setTimeout;
+ }
+ function setEndOfMicrotask(func) {
+ callbacks.push(func);
+ if (pending) return;
+ pending = true;
+ timerFunc(handle, 0);
+ }
+ context.setEndOfMicrotask = setEndOfMicrotask;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var setEndOfMicrotask = scope.setEndOfMicrotask;
+ var wrapIfNeeded = scope.wrapIfNeeded;
+ var wrappers = scope.wrappers;
+ var registrationsTable = new WeakMap();
+ var globalMutationObservers = [];
+ var isScheduled = false;
+ function scheduleCallback(observer) {
+ if (observer.scheduled_) return;
+ observer.scheduled_ = true;
+ globalMutationObservers.push(observer);
+ if (isScheduled) return;
+ setEndOfMicrotask(notifyObservers);
+ isScheduled = true;
+ }
+ function notifyObservers() {
+ isScheduled = false;
+ while (globalMutationObservers.length) {
+ var notifyList = globalMutationObservers;
+ globalMutationObservers = [];
+ notifyList.sort(function(x, y) {
+ return x.uid_ - y.uid_;
+ });
+ for (var i = 0; i < notifyList.length; i++) {
+ var mo = notifyList[i];
+ mo.scheduled_ = false;
+ var queue = mo.takeRecords();
+ removeTransientObserversFor(mo);
+ if (queue.length) {
+ mo.callback_(queue, mo);
+ }
+ }
+ }
+ }
+ function MutationRecord(type, target) {
+ this.type = type;
+ this.target = target;
+ this.addedNodes = new wrappers.NodeList();
+ this.removedNodes = new wrappers.NodeList();
+ this.previousSibling = null;
+ this.nextSibling = null;
+ this.attributeName = null;
+ this.attributeNamespace = null;
+ this.oldValue = null;
+ }
+ function registerTransientObservers(ancestor, node) {
+ for (;ancestor; ancestor = ancestor.parentNode) {
+ var registrations = registrationsTable.get(ancestor);
+ if (!registrations) continue;
+ for (var i = 0; i < registrations.length; i++) {
+ var registration = registrations[i];
+ if (registration.options.subtree) registration.addTransientObserver(node);
+ }
+ }
+ }
+ function removeTransientObserversFor(observer) {
+ for (var i = 0; i < observer.nodes_.length; i++) {
+ var node = observer.nodes_[i];
+ var registrations = registrationsTable.get(node);
+ if (!registrations) return;
+ for (var j = 0; j < registrations.length; j++) {
+ var registration = registrations[j];
+ if (registration.observer === observer) registration.removeTransientObservers();
+ }
+ }
+ }
+ function enqueueMutation(target, type, data) {
+ var interestedObservers = Object.create(null);
+ var associatedStrings = Object.create(null);
+ for (var node = target; node; node = node.parentNode) {
+ var registrations = registrationsTable.get(node);
+ if (!registrations) continue;
+ for (var j = 0; j < registrations.length; j++) {
+ var registration = registrations[j];
+ var options = registration.options;
+ if (node !== target && !options.subtree) continue;
+ if (type === "attributes" && !options.attributes) continue;
+ if (type === "attributes" && options.attributeFilter && (data.namespace !== null || options.attributeFilter.indexOf(data.name) === -1)) {
+ continue;
+ }
+ if (type === "characterData" && !options.characterData) continue;
+ if (type === "childList" && !options.childList) continue;
+ var observer = registration.observer;
+ interestedObservers[observer.uid_] = observer;
+ if (type === "attributes" && options.attributeOldValue || type === "characterData" && options.characterDataOldValue) {
+ associatedStrings[observer.uid_] = data.oldValue;
+ }
+ }
+ }
+ for (var uid in interestedObservers) {
+ var observer = interestedObservers[uid];
+ var record = new MutationRecord(type, target);
+ if ("name" in data && "namespace" in data) {
+ record.attributeName = data.name;
+ record.attributeNamespace = data.namespace;
+ }
+ if (data.addedNodes) record.addedNodes = data.addedNodes;
+ if (data.removedNodes) record.removedNodes = data.removedNodes;
+ if (data.previousSibling) record.previousSibling = data.previousSibling;
+ if (data.nextSibling) record.nextSibling = data.nextSibling;
+ if (associatedStrings[uid] !== undefined) record.oldValue = associatedStrings[uid];
+ scheduleCallback(observer);
+ observer.records_.push(record);
+ }
+ }
+ var slice = Array.prototype.slice;
+ function MutationObserverOptions(options) {
+ this.childList = !!options.childList;
+ this.subtree = !!options.subtree;
+ if (!("attributes" in options) && ("attributeOldValue" in options || "attributeFilter" in options)) {
+ this.attributes = true;
+ } else {
+ this.attributes = !!options.attributes;
+ }
+ if ("characterDataOldValue" in options && !("characterData" in options)) this.characterData = true; else this.characterData = !!options.characterData;
+ if (!this.attributes && (options.attributeOldValue || "attributeFilter" in options) || !this.characterData && options.characterDataOldValue) {
+ throw new TypeError();
+ }
+ this.characterData = !!options.characterData;
+ this.attributeOldValue = !!options.attributeOldValue;
+ this.characterDataOldValue = !!options.characterDataOldValue;
+ if ("attributeFilter" in options) {
+ if (options.attributeFilter == null || typeof options.attributeFilter !== "object") {
+ throw new TypeError();
+ }
+ this.attributeFilter = slice.call(options.attributeFilter);
+ } else {
+ this.attributeFilter = null;
+ }
+ }
+ var uidCounter = 0;
+ function MutationObserver(callback) {
+ this.callback_ = callback;
+ this.nodes_ = [];
+ this.records_ = [];
+ this.uid_ = ++uidCounter;
+ this.scheduled_ = false;
+ }
+ MutationObserver.prototype = {
+ constructor: MutationObserver,
+ observe: function(target, options) {
+ target = wrapIfNeeded(target);
+ var newOptions = new MutationObserverOptions(options);
+ var registration;
+ var registrations = registrationsTable.get(target);
+ if (!registrations) registrationsTable.set(target, registrations = []);
+ for (var i = 0; i < registrations.length; i++) {
+ if (registrations[i].observer === this) {
+ registration = registrations[i];
+ registration.removeTransientObservers();
+ registration.options = newOptions;
+ }
+ }
+ if (!registration) {
+ registration = new Registration(this, target, newOptions);
+ registrations.push(registration);
+ this.nodes_.push(target);
+ }
+ },
+ disconnect: function() {
+ this.nodes_.forEach(function(node) {
+ var registrations = registrationsTable.get(node);
+ for (var i = 0; i < registrations.length; i++) {
+ var registration = registrations[i];
+ if (registration.observer === this) {
+ registrations.splice(i, 1);
+ break;
+ }
+ }
+ }, this);
+ this.records_ = [];
+ },
+ takeRecords: function() {
+ var copyOfRecords = this.records_;
+ this.records_ = [];
+ return copyOfRecords;
+ }
+ };
+ function Registration(observer, target, options) {
+ this.observer = observer;
+ this.target = target;
+ this.options = options;
+ this.transientObservedNodes = [];
+ }
+ Registration.prototype = {
+ addTransientObserver: function(node) {
+ if (node === this.target) return;
+ scheduleCallback(this.observer);
+ this.transientObservedNodes.push(node);
+ var registrations = registrationsTable.get(node);
+ if (!registrations) registrationsTable.set(node, registrations = []);
+ registrations.push(this);
+ },
+ removeTransientObservers: function() {
+ var transientObservedNodes = this.transientObservedNodes;
+ this.transientObservedNodes = [];
+ for (var i = 0; i < transientObservedNodes.length; i++) {
+ var node = transientObservedNodes[i];
+ var registrations = registrationsTable.get(node);
+ for (var j = 0; j < registrations.length; j++) {
+ if (registrations[j] === this) {
+ registrations.splice(j, 1);
+ break;
+ }
+ }
+ }
+ }
+ };
+ scope.enqueueMutation = enqueueMutation;
+ scope.registerTransientObservers = registerTransientObservers;
+ scope.wrappers.MutationObserver = MutationObserver;
+ scope.wrappers.MutationRecord = MutationRecord;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ function TreeScope(root, parent) {
+ this.root = root;
+ this.parent = parent;
+ }
+ TreeScope.prototype = {
+ get renderer() {
+ if (this.root instanceof scope.wrappers.ShadowRoot) {
+ return scope.getRendererForHost(this.root.host);
+ }
+ return null;
+ },
+ contains: function(treeScope) {
+ for (;treeScope; treeScope = treeScope.parent) {
+ if (treeScope === this) return true;
+ }
+ return false;
+ }
+ };
+ function setTreeScope(node, treeScope) {
+ if (node.treeScope_ !== treeScope) {
+ node.treeScope_ = treeScope;
+ for (var sr = node.shadowRoot; sr; sr = sr.olderShadowRoot) {
+ sr.treeScope_.parent = treeScope;
+ }
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ setTreeScope(child, treeScope);
+ }
+ }
+ }
+ function getTreeScope(node) {
+ if (node instanceof scope.wrappers.Window) {
+ debugger;
+ }
+ if (node.treeScope_) return node.treeScope_;
+ var parent = node.parentNode;
+ var treeScope;
+ if (parent) treeScope = getTreeScope(parent); else treeScope = new TreeScope(node, null);
+ return node.treeScope_ = treeScope;
+ }
+ scope.TreeScope = TreeScope;
+ scope.getTreeScope = getTreeScope;
+ scope.setTreeScope = setTreeScope;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
+ var getTreeScope = scope.getTreeScope;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var wrappers = scope.wrappers;
+ var wrappedFuns = new WeakMap();
+ var listenersTable = new WeakMap();
+ var handledEventsTable = new WeakMap();
+ var currentlyDispatchingEvents = new WeakMap();
+ var targetTable = new WeakMap();
+ var currentTargetTable = new WeakMap();
+ var relatedTargetTable = new WeakMap();
+ var eventPhaseTable = new WeakMap();
+ var stopPropagationTable = new WeakMap();
+ var stopImmediatePropagationTable = new WeakMap();
+ var eventHandlersTable = new WeakMap();
+ var eventPathTable = new WeakMap();
+ function isShadowRoot(node) {
+ return node instanceof wrappers.ShadowRoot;
+ }
+ function rootOfNode(node) {
+ return getTreeScope(node).root;
+ }
+ function getEventPath(node, event) {
+ var path = [];
+ var current = node;
+ path.push(current);
+ while (current) {
+ var destinationInsertionPoints = getDestinationInsertionPoints(current);
+ if (destinationInsertionPoints && destinationInsertionPoints.length > 0) {
+ for (var i = 0; i < destinationInsertionPoints.length; i++) {
+ var insertionPoint = destinationInsertionPoints[i];
+ if (isShadowInsertionPoint(insertionPoint)) {
+ var shadowRoot = rootOfNode(insertionPoint);
+ var olderShadowRoot = shadowRoot.olderShadowRoot;
+ if (olderShadowRoot) path.push(olderShadowRoot);
+ }
+ path.push(insertionPoint);
+ }
+ current = destinationInsertionPoints[destinationInsertionPoints.length - 1];
+ } else {
+ if (isShadowRoot(current)) {
+ if (inSameTree(node, current) && eventMustBeStopped(event)) {
+ break;
+ }
+ current = current.host;
+ path.push(current);
+ } else {
+ current = current.parentNode;
+ if (current) path.push(current);
+ }
+ }
+ }
+ return path;
+ }
+ function eventMustBeStopped(event) {
+ if (!event) return false;
+ switch (event.type) {
+ case "abort":
+ case "error":
+ case "select":
+ case "change":
+ case "load":
+ case "reset":
+ case "resize":
+ case "scroll":
+ case "selectstart":
+ return true;
+ }
+ return false;
+ }
+ function isShadowInsertionPoint(node) {
+ return node instanceof HTMLShadowElement;
+ }
+ function getDestinationInsertionPoints(node) {
+ return scope.getDestinationInsertionPoints(node);
+ }
+ function eventRetargetting(path, currentTarget) {
+ if (path.length === 0) return currentTarget;
+ if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
+ var currentTargetTree = getTreeScope(currentTarget);
+ var originalTarget = path[0];
+ var originalTargetTree = getTreeScope(originalTarget);
+ var relativeTargetTree = lowestCommonInclusiveAncestor(currentTargetTree, originalTargetTree);
+ for (var i = 0; i < path.length; i++) {
+ var node = path[i];
+ if (getTreeScope(node) === relativeTargetTree) return node;
+ }
+ return path[path.length - 1];
+ }
+ function getTreeScopeAncestors(treeScope) {
+ var ancestors = [];
+ for (;treeScope; treeScope = treeScope.parent) {
+ ancestors.push(treeScope);
+ }
+ return ancestors;
+ }
+ function lowestCommonInclusiveAncestor(tsA, tsB) {
+ var ancestorsA = getTreeScopeAncestors(tsA);
+ var ancestorsB = getTreeScopeAncestors(tsB);
+ var result = null;
+ while (ancestorsA.length > 0 && ancestorsB.length > 0) {
+ var a = ancestorsA.pop();
+ var b = ancestorsB.pop();
+ if (a === b) result = a; else break;
+ }
+ return result;
+ }
+ function getTreeScopeRoot(ts) {
+ if (!ts.parent) return ts;
+ return getTreeScopeRoot(ts.parent);
+ }
+ function relatedTargetResolution(event, currentTarget, relatedTarget) {
+ if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
+ var currentTargetTree = getTreeScope(currentTarget);
+ var relatedTargetTree = getTreeScope(relatedTarget);
+ var relatedTargetEventPath = getEventPath(relatedTarget, event);
+ var lowestCommonAncestorTree;
+ var lowestCommonAncestorTree = lowestCommonInclusiveAncestor(currentTargetTree, relatedTargetTree);
+ if (!lowestCommonAncestorTree) lowestCommonAncestorTree = relatedTargetTree.root;
+ for (var commonAncestorTree = lowestCommonAncestorTree; commonAncestorTree; commonAncestorTree = commonAncestorTree.parent) {
+ var adjustedRelatedTarget;
+ for (var i = 0; i < relatedTargetEventPath.length; i++) {
+ var node = relatedTargetEventPath[i];
+ if (getTreeScope(node) === commonAncestorTree) return node;
+ }
+ }
+ return null;
+ }
+ function inSameTree(a, b) {
+ return getTreeScope(a) === getTreeScope(b);
+ }
+ var NONE = 0;
+ var CAPTURING_PHASE = 1;
+ var AT_TARGET = 2;
+ var BUBBLING_PHASE = 3;
+ var pendingError;
+ function dispatchOriginalEvent(originalEvent) {
+ if (handledEventsTable.get(originalEvent)) return;
+ handledEventsTable.set(originalEvent, true);
+ dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));
+ if (pendingError) {
+ var err = pendingError;
+ pendingError = null;
+ throw err;
+ }
+ }
+ function isLoadLikeEvent(event) {
+ switch (event.type) {
+ case "load":
+ case "beforeunload":
+ case "unload":
+ return true;
+ }
+ return false;
+ }
+ function dispatchEvent(event, originalWrapperTarget) {
+ if (currentlyDispatchingEvents.get(event)) throw new Error("InvalidStateError");
+ currentlyDispatchingEvents.set(event, true);
+ scope.renderAllPending();
+ var eventPath;
+ var overrideTarget;
+ var win;
+ if (isLoadLikeEvent(event) && !event.bubbles) {
+ var doc = originalWrapperTarget;
+ if (doc instanceof wrappers.Document && (win = doc.defaultView)) {
+ overrideTarget = doc;
+ eventPath = [];
+ }
+ }
+ if (!eventPath) {
+ if (originalWrapperTarget instanceof wrappers.Window) {
+ win = originalWrapperTarget;
+ eventPath = [];
+ } else {
+ eventPath = getEventPath(originalWrapperTarget, event);
+ if (!isLoadLikeEvent(event)) {
+ var doc = eventPath[eventPath.length - 1];
+ if (doc instanceof wrappers.Document) win = doc.defaultView;
+ }
+ }
+ }
+ eventPathTable.set(event, eventPath);
+ if (dispatchCapturing(event, eventPath, win, overrideTarget)) {
+ if (dispatchAtTarget(event, eventPath, win, overrideTarget)) {
+ dispatchBubbling(event, eventPath, win, overrideTarget);
+ }
+ }
+ eventPhaseTable.set(event, NONE);
+ currentTargetTable.delete(event, null);
+ currentlyDispatchingEvents.delete(event);
+ return event.defaultPrevented;
+ }
+ function dispatchCapturing(event, eventPath, win, overrideTarget) {
+ var phase = CAPTURING_PHASE;
+ if (win) {
+ if (!invoke(win, event, phase, eventPath, overrideTarget)) return false;
+ }
+ for (var i = eventPath.length - 1; i > 0; i--) {
+ if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return false;
+ }
+ return true;
+ }
+ function dispatchAtTarget(event, eventPath, win, overrideTarget) {
+ var phase = AT_TARGET;
+ var currentTarget = eventPath[0] || win;
+ return invoke(currentTarget, event, phase, eventPath, overrideTarget);
+ }
+ function dispatchBubbling(event, eventPath, win, overrideTarget) {
+ var phase = BUBBLING_PHASE;
+ for (var i = 1; i < eventPath.length; i++) {
+ if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return;
+ }
+ if (win && eventPath.length > 0) {
+ invoke(win, event, phase, eventPath, overrideTarget);
+ }
+ }
+ function invoke(currentTarget, event, phase, eventPath, overrideTarget) {
+ var listeners = listenersTable.get(currentTarget);
+ if (!listeners) return true;
+ var target = overrideTarget || eventRetargetting(eventPath, currentTarget);
+ if (target === currentTarget) {
+ if (phase === CAPTURING_PHASE) return true;
+ if (phase === BUBBLING_PHASE) phase = AT_TARGET;
+ } else if (phase === BUBBLING_PHASE && !event.bubbles) {
+ return true;
+ }
+ if ("relatedTarget" in event) {
+ var originalEvent = unwrap(event);
+ var unwrappedRelatedTarget = originalEvent.relatedTarget;
+ if (unwrappedRelatedTarget) {
+ if (unwrappedRelatedTarget instanceof Object && unwrappedRelatedTarget.addEventListener) {
+ var relatedTarget = wrap(unwrappedRelatedTarget);
+ var adjusted = relatedTargetResolution(event, currentTarget, relatedTarget);
+ if (adjusted === target) return true;
+ } else {
+ adjusted = null;
+ }
+ relatedTargetTable.set(event, adjusted);
+ }
+ }
+ eventPhaseTable.set(event, phase);
+ var type = event.type;
+ var anyRemoved = false;
+ targetTable.set(event, target);
+ currentTargetTable.set(event, currentTarget);
+ listeners.depth++;
+ for (var i = 0, len = listeners.length; i < len; i++) {
+ var listener = listeners[i];
+ if (listener.removed) {
+ anyRemoved = true;
+ continue;
+ }
+ if (listener.type !== type || !listener.capture && phase === CAPTURING_PHASE || listener.capture && phase === BUBBLING_PHASE) {
+ continue;
+ }
+ try {
+ if (typeof listener.handler === "function") listener.handler.call(currentTarget, event); else listener.handler.handleEvent(event);
+ if (stopImmediatePropagationTable.get(event)) return false;
+ } catch (ex) {
+ if (!pendingError) pendingError = ex;
+ }
+ }
+ listeners.depth--;
+ if (anyRemoved && listeners.depth === 0) {
+ var copy = listeners.slice();
+ listeners.length = 0;
+ for (var i = 0; i < copy.length; i++) {
+ if (!copy[i].removed) listeners.push(copy[i]);
+ }
+ }
+ return !stopPropagationTable.get(event);
+ }
+ function Listener(type, handler, capture) {
+ this.type = type;
+ this.handler = handler;
+ this.capture = Boolean(capture);
+ }
+ Listener.prototype = {
+ equals: function(that) {
+ return this.handler === that.handler && this.type === that.type && this.capture === that.capture;
+ },
+ get removed() {
+ return this.handler === null;
+ },
+ remove: function() {
+ this.handler = null;
+ }
+ };
+ var OriginalEvent = window.Event;
+ OriginalEvent.prototype.polymerBlackList_ = {
+ returnValue: true,
+ keyLocation: true
+ };
+ function Event(type, options) {
+ if (type instanceof OriginalEvent) {
+ var impl = type;
+ if (!OriginalBeforeUnloadEvent && impl.type === "beforeunload" && !(this instanceof BeforeUnloadEvent)) {
+ return new BeforeUnloadEvent(impl);
+ }
+ setWrapper(impl, this);
+ } else {
+ return wrap(constructEvent(OriginalEvent, "Event", type, options));
+ }
+ }
+ Event.prototype = {
+ get target() {
+ return targetTable.get(this);
+ },
+ get currentTarget() {
+ return currentTargetTable.get(this);
+ },
+ get eventPhase() {
+ return eventPhaseTable.get(this);
+ },
+ get path() {
+ var eventPath = eventPathTable.get(this);
+ if (!eventPath) return [];
+ return eventPath.slice();
+ },
+ stopPropagation: function() {
+ stopPropagationTable.set(this, true);
+ },
+ stopImmediatePropagation: function() {
+ stopPropagationTable.set(this, true);
+ stopImmediatePropagationTable.set(this, true);
+ }
+ };
+ registerWrapper(OriginalEvent, Event, document.createEvent("Event"));
+ function unwrapOptions(options) {
+ if (!options || !options.relatedTarget) return options;
+ return Object.create(options, {
+ relatedTarget: {
+ value: unwrap(options.relatedTarget)
+ }
+ });
+ }
+ function registerGenericEvent(name, SuperEvent, prototype) {
+ var OriginalEvent = window[name];
+ var GenericEvent = function(type, options) {
+ if (type instanceof OriginalEvent) setWrapper(type, this); else return wrap(constructEvent(OriginalEvent, name, type, options));
+ };
+ GenericEvent.prototype = Object.create(SuperEvent.prototype);
+ if (prototype) mixin(GenericEvent.prototype, prototype);
+ if (OriginalEvent) {
+ try {
+ registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent("temp"));
+ } catch (ex) {
+ registerWrapper(OriginalEvent, GenericEvent, document.createEvent(name));
+ }
+ }
+ return GenericEvent;
+ }
+ var UIEvent = registerGenericEvent("UIEvent", Event);
+ var CustomEvent = registerGenericEvent("CustomEvent", Event);
+ var relatedTargetProto = {
+ get relatedTarget() {
+ var relatedTarget = relatedTargetTable.get(this);
+ if (relatedTarget !== undefined) return relatedTarget;
+ return wrap(unwrap(this).relatedTarget);
+ }
+ };
+ function getInitFunction(name, relatedTargetIndex) {
+ return function() {
+ arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]);
+ var impl = unwrap(this);
+ impl[name].apply(impl, arguments);
+ };
+ }
+ var mouseEventProto = mixin({
+ initMouseEvent: getInitFunction("initMouseEvent", 14)
+ }, relatedTargetProto);
+ var focusEventProto = mixin({
+ initFocusEvent: getInitFunction("initFocusEvent", 5)
+ }, relatedTargetProto);
+ var MouseEvent = registerGenericEvent("MouseEvent", UIEvent, mouseEventProto);
+ var FocusEvent = registerGenericEvent("FocusEvent", UIEvent, focusEventProto);
+ var defaultInitDicts = Object.create(null);
+ var supportsEventConstructors = function() {
+ try {
+ new window.FocusEvent("focus");
+ } catch (ex) {
+ return false;
+ }
+ return true;
+ }();
+ function constructEvent(OriginalEvent, name, type, options) {
+ if (supportsEventConstructors) return new OriginalEvent(type, unwrapOptions(options));
+ var event = unwrap(document.createEvent(name));
+ var defaultDict = defaultInitDicts[name];
+ var args = [ type ];
+ Object.keys(defaultDict).forEach(function(key) {
+ var v = options != null && key in options ? options[key] : defaultDict[key];
+ if (key === "relatedTarget") v = unwrap(v);
+ args.push(v);
+ });
+ event["init" + name].apply(event, args);
+ return event;
+ }
+ if (!supportsEventConstructors) {
+ var configureEventConstructor = function(name, initDict, superName) {
+ if (superName) {
+ var superDict = defaultInitDicts[superName];
+ initDict = mixin(mixin({}, superDict), initDict);
+ }
+ defaultInitDicts[name] = initDict;
+ };
+ configureEventConstructor("Event", {
+ bubbles: false,
+ cancelable: false
+ });
+ configureEventConstructor("CustomEvent", {
+ detail: null
+ }, "Event");
+ configureEventConstructor("UIEvent", {
+ view: null,
+ detail: 0
+ }, "Event");
+ configureEventConstructor("MouseEvent", {
+ screenX: 0,
+ screenY: 0,
+ clientX: 0,
+ clientY: 0,
+ ctrlKey: false,
+ altKey: false,
+ shiftKey: false,
+ metaKey: false,
+ button: 0,
+ relatedTarget: null
+ }, "UIEvent");
+ configureEventConstructor("FocusEvent", {
+ relatedTarget: null
+ }, "UIEvent");
+ }
+ var OriginalBeforeUnloadEvent = window.BeforeUnloadEvent;
+ function BeforeUnloadEvent(impl) {
+ Event.call(this, impl);
+ }
+ BeforeUnloadEvent.prototype = Object.create(Event.prototype);
+ mixin(BeforeUnloadEvent.prototype, {
+ get returnValue() {
+ return unsafeUnwrap(this).returnValue;
+ },
+ set returnValue(v) {
+ unsafeUnwrap(this).returnValue = v;
+ }
+ });
+ if (OriginalBeforeUnloadEvent) registerWrapper(OriginalBeforeUnloadEvent, BeforeUnloadEvent);
+ function isValidListener(fun) {
+ if (typeof fun === "function") return true;
+ return fun && fun.handleEvent;
+ }
+ function isMutationEvent(type) {
+ switch (type) {
+ case "DOMAttrModified":
+ case "DOMAttributeNameChanged":
+ case "DOMCharacterDataModified":
+ case "DOMElementNameChanged":
+ case "DOMNodeInserted":
+ case "DOMNodeInsertedIntoDocument":
+ case "DOMNodeRemoved":
+ case "DOMNodeRemovedFromDocument":
+ case "DOMSubtreeModified":
+ return true;
+ }
+ return false;
+ }
+ var OriginalEventTarget = window.EventTarget;
+ function EventTarget(impl) {
+ setWrapper(impl, this);
+ }
+ var methodNames = [ "addEventListener", "removeEventListener", "dispatchEvent" ];
+ [ Node, Window ].forEach(function(constructor) {
+ var p = constructor.prototype;
+ methodNames.forEach(function(name) {
+ Object.defineProperty(p, name + "_", {
+ value: p[name]
+ });
+ });
+ });
+ function getTargetToListenAt(wrapper) {
+ if (wrapper instanceof wrappers.ShadowRoot) wrapper = wrapper.host;
+ return unwrap(wrapper);
+ }
+ EventTarget.prototype = {
+ addEventListener: function(type, fun, capture) {
+ if (!isValidListener(fun) || isMutationEvent(type)) return;
+ var listener = new Listener(type, fun, capture);
+ var listeners = listenersTable.get(this);
+ if (!listeners) {
+ listeners = [];
+ listeners.depth = 0;
+ listenersTable.set(this, listeners);
+ } else {
+ for (var i = 0; i < listeners.length; i++) {
+ if (listener.equals(listeners[i])) return;
+ }
+ }
+ listeners.push(listener);
+ var target = getTargetToListenAt(this);
+ target.addEventListener_(type, dispatchOriginalEvent, true);
+ },
+ removeEventListener: function(type, fun, capture) {
+ capture = Boolean(capture);
+ var listeners = listenersTable.get(this);
+ if (!listeners) return;
+ var count = 0, found = false;
+ for (var i = 0; i < listeners.length; i++) {
+ if (listeners[i].type === type && listeners[i].capture === capture) {
+ count++;
+ if (listeners[i].handler === fun) {
+ found = true;
+ listeners[i].remove();
+ }
+ }
+ }
+ if (found && count === 1) {
+ var target = getTargetToListenAt(this);
+ target.removeEventListener_(type, dispatchOriginalEvent, true);
+ }
+ },
+ dispatchEvent: function(event) {
+ var nativeEvent = unwrap(event);
+ var eventType = nativeEvent.type;
+ handledEventsTable.set(nativeEvent, false);
+ scope.renderAllPending();
+ var tempListener;
+ if (!hasListenerInAncestors(this, eventType)) {
+ tempListener = function() {};
+ this.addEventListener(eventType, tempListener, true);
+ }
+ try {
+ return unwrap(this).dispatchEvent_(nativeEvent);
+ } finally {
+ if (tempListener) this.removeEventListener(eventType, tempListener, true);
+ }
+ }
+ };
+ function hasListener(node, type) {
+ var listeners = listenersTable.get(node);
+ if (listeners) {
+ for (var i = 0; i < listeners.length; i++) {
+ if (!listeners[i].removed && listeners[i].type === type) return true;
+ }
+ }
+ return false;
+ }
+ function hasListenerInAncestors(target, type) {
+ for (var node = unwrap(target); node; node = node.parentNode) {
+ if (hasListener(wrap(node), type)) return true;
+ }
+ return false;
+ }
+ if (OriginalEventTarget) registerWrapper(OriginalEventTarget, EventTarget);
+ function wrapEventTargetMethods(constructors) {
+ forwardMethodsToWrapper(constructors, methodNames);
+ }
+ var originalElementFromPoint = document.elementFromPoint;
+ function elementFromPoint(self, document, x, y) {
+ scope.renderAllPending();
+ var element = wrap(originalElementFromPoint.call(unsafeUnwrap(document), x, y));
+ if (!element) return null;
+ var path = getEventPath(element, null);
+ var idx = path.lastIndexOf(self);
+ if (idx == -1) return null; else path = path.slice(0, idx);
+ return eventRetargetting(path, self);
+ }
+ function getEventHandlerGetter(name) {
+ return function() {
+ var inlineEventHandlers = eventHandlersTable.get(this);
+ return inlineEventHandlers && inlineEventHandlers[name] && inlineEventHandlers[name].value || null;
+ };
+ }
+ function getEventHandlerSetter(name) {
+ var eventType = name.slice(2);
+ return function(value) {
+ var inlineEventHandlers = eventHandlersTable.get(this);
+ if (!inlineEventHandlers) {
+ inlineEventHandlers = Object.create(null);
+ eventHandlersTable.set(this, inlineEventHandlers);
+ }
+ var old = inlineEventHandlers[name];
+ if (old) this.removeEventListener(eventType, old.wrapped, false);
+ if (typeof value === "function") {
+ var wrapped = function(e) {
+ var rv = value.call(this, e);
+ if (rv === false) e.preventDefault(); else if (name === "onbeforeunload" && typeof rv === "string") e.returnValue = rv;
+ };
+ this.addEventListener(eventType, wrapped, false);
+ inlineEventHandlers[name] = {
+ value: value,
+ wrapped: wrapped
+ };
+ }
+ };
+ }
+ scope.elementFromPoint = elementFromPoint;
+ scope.getEventHandlerGetter = getEventHandlerGetter;
+ scope.getEventHandlerSetter = getEventHandlerSetter;
+ scope.wrapEventTargetMethods = wrapEventTargetMethods;
+ scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;
+ scope.wrappers.CustomEvent = CustomEvent;
+ scope.wrappers.Event = Event;
+ scope.wrappers.EventTarget = EventTarget;
+ scope.wrappers.FocusEvent = FocusEvent;
+ scope.wrappers.MouseEvent = MouseEvent;
+ scope.wrappers.UIEvent = UIEvent;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var UIEvent = scope.wrappers.UIEvent;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var wrap = scope.wrap;
+ var OriginalTouchEvent = window.TouchEvent;
+ if (!OriginalTouchEvent) return;
+ var nativeEvent;
+ try {
+ nativeEvent = document.createEvent("TouchEvent");
+ } catch (ex) {
+ return;
+ }
+ var nonEnumDescriptor = {
+ enumerable: false
+ };
+ function nonEnum(obj, prop) {
+ Object.defineProperty(obj, prop, nonEnumDescriptor);
+ }
+ function Touch(impl) {
+ setWrapper(impl, this);
+ }
+ Touch.prototype = {
+ get target() {
+ return wrap(unsafeUnwrap(this).target);
+ }
+ };
+ var descr = {
+ configurable: true,
+ enumerable: true,
+ get: null
+ };
+ [ "clientX", "clientY", "screenX", "screenY", "pageX", "pageY", "identifier", "webkitRadiusX", "webkitRadiusY", "webkitRotationAngle", "webkitForce" ].forEach(function(name) {
+ descr.get = function() {
+ return unsafeUnwrap(this)[name];
+ };
+ Object.defineProperty(Touch.prototype, name, descr);
+ });
+ function TouchList() {
+ this.length = 0;
+ nonEnum(this, "length");
+ }
+ TouchList.prototype = {
+ item: function(index) {
+ return this[index];
+ }
+ };
+ function wrapTouchList(nativeTouchList) {
+ var list = new TouchList();
+ for (var i = 0; i < nativeTouchList.length; i++) {
+ list[i] = new Touch(nativeTouchList[i]);
+ }
+ list.length = i;
+ return list;
+ }
+ function TouchEvent(impl) {
+ UIEvent.call(this, impl);
+ }
+ TouchEvent.prototype = Object.create(UIEvent.prototype);
+ mixin(TouchEvent.prototype, {
+ get touches() {
+ return wrapTouchList(unsafeUnwrap(this).touches);
+ },
+ get targetTouches() {
+ return wrapTouchList(unsafeUnwrap(this).targetTouches);
+ },
+ get changedTouches() {
+ return wrapTouchList(unsafeUnwrap(this).changedTouches);
+ },
+ initTouchEvent: function() {
+ throw new Error("Not implemented");
+ }
+ });
+ registerWrapper(OriginalTouchEvent, TouchEvent, nativeEvent);
+ scope.wrappers.Touch = Touch;
+ scope.wrappers.TouchEvent = TouchEvent;
+ scope.wrappers.TouchList = TouchList;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var wrap = scope.wrap;
+ var nonEnumDescriptor = {
+ enumerable: false
+ };
+ function nonEnum(obj, prop) {
+ Object.defineProperty(obj, prop, nonEnumDescriptor);
+ }
+ function NodeList() {
+ this.length = 0;
+ nonEnum(this, "length");
+ }
+ NodeList.prototype = {
+ item: function(index) {
+ return this[index];
+ }
+ };
+ nonEnum(NodeList.prototype, "item");
+ function wrapNodeList(list) {
+ if (list == null) return list;
+ var wrapperList = new NodeList();
+ for (var i = 0, length = list.length; i < length; i++) {
+ wrapperList[i] = wrap(list[i]);
+ }
+ wrapperList.length = length;
+ return wrapperList;
+ }
+ function addWrapNodeListMethod(wrapperConstructor, name) {
+ wrapperConstructor.prototype[name] = function() {
+ return wrapNodeList(unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));
+ };
+ }
+ scope.wrappers.NodeList = NodeList;
+ scope.addWrapNodeListMethod = addWrapNodeListMethod;
+ scope.wrapNodeList = wrapNodeList;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ scope.wrapHTMLCollection = scope.wrapNodeList;
+ scope.wrappers.HTMLCollection = scope.wrappers.NodeList;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var EventTarget = scope.wrappers.EventTarget;
+ var NodeList = scope.wrappers.NodeList;
+ var TreeScope = scope.TreeScope;
+ var assert = scope.assert;
+ var defineWrapGetter = scope.defineWrapGetter;
+ var enqueueMutation = scope.enqueueMutation;
+ var getTreeScope = scope.getTreeScope;
+ var isWrapper = scope.isWrapper;
+ var mixin = scope.mixin;
+ var registerTransientObservers = scope.registerTransientObservers;
+ var registerWrapper = scope.registerWrapper;
+ var setTreeScope = scope.setTreeScope;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var wrap = scope.wrap;
+ var wrapIfNeeded = scope.wrapIfNeeded;
+ var wrappers = scope.wrappers;
+ function assertIsNodeWrapper(node) {
+ assert(node instanceof Node);
+ }
+ function createOneElementNodeList(node) {
+ var nodes = new NodeList();
+ nodes[0] = node;
+ nodes.length = 1;
+ return nodes;
+ }
+ var surpressMutations = false;
+ function enqueueRemovalForInsertedNodes(node, parent, nodes) {
+ enqueueMutation(parent, "childList", {
+ removedNodes: nodes,
+ previousSibling: node.previousSibling,
+ nextSibling: node.nextSibling
+ });
+ }
+ function enqueueRemovalForInsertedDocumentFragment(df, nodes) {
+ enqueueMutation(df, "childList", {
+ removedNodes: nodes
+ });
+ }
+ function collectNodes(node, parentNode, previousNode, nextNode) {
+ if (node instanceof DocumentFragment) {
+ var nodes = collectNodesForDocumentFragment(node);
+ surpressMutations = true;
+ for (var i = nodes.length - 1; i >= 0; i--) {
+ node.removeChild(nodes[i]);
+ nodes[i].parentNode_ = parentNode;
+ }
+ surpressMutations = false;
+ for (var i = 0; i < nodes.length; i++) {
+ nodes[i].previousSibling_ = nodes[i - 1] || previousNode;
+ nodes[i].nextSibling_ = nodes[i + 1] || nextNode;
+ }
+ if (previousNode) previousNode.nextSibling_ = nodes[0];
+ if (nextNode) nextNode.previousSibling_ = nodes[nodes.length - 1];
+ return nodes;
+ }
+ var nodes = createOneElementNodeList(node);
+ var oldParent = node.parentNode;
+ if (oldParent) {
+ oldParent.removeChild(node);
+ }
+ node.parentNode_ = parentNode;
+ node.previousSibling_ = previousNode;
+ node.nextSibling_ = nextNode;
+ if (previousNode) previousNode.nextSibling_ = node;
+ if (nextNode) nextNode.previousSibling_ = node;
+ return nodes;
+ }
+ function collectNodesNative(node) {
+ if (node instanceof DocumentFragment) return collectNodesForDocumentFragment(node);
+ var nodes = createOneElementNodeList(node);
+ var oldParent = node.parentNode;
+ if (oldParent) enqueueRemovalForInsertedNodes(node, oldParent, nodes);
+ return nodes;
+ }
+ function collectNodesForDocumentFragment(node) {
+ var nodes = new NodeList();
+ var i = 0;
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ nodes[i++] = child;
+ }
+ nodes.length = i;
+ enqueueRemovalForInsertedDocumentFragment(node, nodes);
+ return nodes;
+ }
+ function snapshotNodeList(nodeList) {
+ return nodeList;
+ }
+ function nodeWasAdded(node, treeScope) {
+ setTreeScope(node, treeScope);
+ node.nodeIsInserted_();
+ }
+ function nodesWereAdded(nodes, parent) {
+ var treeScope = getTreeScope(parent);
+ for (var i = 0; i < nodes.length; i++) {
+ nodeWasAdded(nodes[i], treeScope);
+ }
+ }
+ function nodeWasRemoved(node) {
+ setTreeScope(node, new TreeScope(node, null));
+ }
+ function nodesWereRemoved(nodes) {
+ for (var i = 0; i < nodes.length; i++) {
+ nodeWasRemoved(nodes[i]);
+ }
+ }
+ function ensureSameOwnerDocument(parent, child) {
+ var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ? parent : parent.ownerDocument;
+ if (ownerDoc !== child.ownerDocument) ownerDoc.adoptNode(child);
+ }
+ function adoptNodesIfNeeded(owner, nodes) {
+ if (!nodes.length) return;
+ var ownerDoc = owner.ownerDocument;
+ if (ownerDoc === nodes[0].ownerDocument) return;
+ for (var i = 0; i < nodes.length; i++) {
+ scope.adoptNodeNoRemove(nodes[i], ownerDoc);
+ }
+ }
+ function unwrapNodesForInsertion(owner, nodes) {
+ adoptNodesIfNeeded(owner, nodes);
+ var length = nodes.length;
+ if (length === 1) return unwrap(nodes[0]);
+ var df = unwrap(owner.ownerDocument.createDocumentFragment());
+ for (var i = 0; i < length; i++) {
+ df.appendChild(unwrap(nodes[i]));
+ }
+ return df;
+ }
+ function clearChildNodes(wrapper) {
+ if (wrapper.firstChild_ !== undefined) {
+ var child = wrapper.firstChild_;
+ while (child) {
+ var tmp = child;
+ child = child.nextSibling_;
+ tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;
+ }
+ }
+ wrapper.firstChild_ = wrapper.lastChild_ = undefined;
+ }
+ function removeAllChildNodes(wrapper) {
+ if (wrapper.invalidateShadowRenderer()) {
+ var childWrapper = wrapper.firstChild;
+ while (childWrapper) {
+ assert(childWrapper.parentNode === wrapper);
+ var nextSibling = childWrapper.nextSibling;
+ var childNode = unwrap(childWrapper);
+ var parentNode = childNode.parentNode;
+ if (parentNode) originalRemoveChild.call(parentNode, childNode);
+ childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = null;
+ childWrapper = nextSibling;
+ }
+ wrapper.firstChild_ = wrapper.lastChild_ = null;
+ } else {
+ var node = unwrap(wrapper);
+ var child = node.firstChild;
+ var nextSibling;
+ while (child) {
+ nextSibling = child.nextSibling;
+ originalRemoveChild.call(node, child);
+ child = nextSibling;
+ }
+ }
+ }
+ function invalidateParent(node) {
+ var p = node.parentNode;
+ return p && p.invalidateShadowRenderer();
+ }
+ function cleanupNodes(nodes) {
+ for (var i = 0, n; i < nodes.length; i++) {
+ n = nodes[i];
+ n.parentNode.removeChild(n);
+ }
+ }
+ var originalImportNode = document.importNode;
+ var originalCloneNode = window.Node.prototype.cloneNode;
+ function cloneNode(node, deep, opt_doc) {
+ var clone;
+ if (opt_doc) clone = wrap(originalImportNode.call(opt_doc, unsafeUnwrap(node), false)); else clone = wrap(originalCloneNode.call(unsafeUnwrap(node), false));
+ if (deep) {
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ clone.appendChild(cloneNode(child, true, opt_doc));
+ }
+ if (node instanceof wrappers.HTMLTemplateElement) {
+ var cloneContent = clone.content;
+ for (var child = node.content.firstChild; child; child = child.nextSibling) {
+ cloneContent.appendChild(cloneNode(child, true, opt_doc));
+ }
+ }
+ }
+ return clone;
+ }
+ function contains(self, child) {
+ if (!child || getTreeScope(self) !== getTreeScope(child)) return false;
+ for (var node = child; node; node = node.parentNode) {
+ if (node === self) return true;
+ }
+ return false;
+ }
+ var OriginalNode = window.Node;
+ function Node(original) {
+ assert(original instanceof OriginalNode);
+ EventTarget.call(this, original);
+ this.parentNode_ = undefined;
+ this.firstChild_ = undefined;
+ this.lastChild_ = undefined;
+ this.nextSibling_ = undefined;
+ this.previousSibling_ = undefined;
+ this.treeScope_ = undefined;
+ }
+ var OriginalDocumentFragment = window.DocumentFragment;
+ var originalAppendChild = OriginalNode.prototype.appendChild;
+ var originalCompareDocumentPosition = OriginalNode.prototype.compareDocumentPosition;
+ var originalIsEqualNode = OriginalNode.prototype.isEqualNode;
+ var originalInsertBefore = OriginalNode.prototype.insertBefore;
+ var originalRemoveChild = OriginalNode.prototype.removeChild;
+ var originalReplaceChild = OriginalNode.prototype.replaceChild;
+ var isIe = /Trident|Edge/.test(navigator.userAgent);
+ var removeChildOriginalHelper = isIe ? function(parent, child) {
+ try {
+ originalRemoveChild.call(parent, child);
+ } catch (ex) {
+ if (!(parent instanceof OriginalDocumentFragment)) throw ex;
+ }
+ } : function(parent, child) {
+ originalRemoveChild.call(parent, child);
+ };
+ Node.prototype = Object.create(EventTarget.prototype);
+ mixin(Node.prototype, {
+ appendChild: function(childWrapper) {
+ return this.insertBefore(childWrapper, null);
+ },
+ insertBefore: function(childWrapper, refWrapper) {
+ assertIsNodeWrapper(childWrapper);
+ var refNode;
+ if (refWrapper) {
+ if (isWrapper(refWrapper)) {
+ refNode = unwrap(refWrapper);
+ } else {
+ refNode = refWrapper;
+ refWrapper = wrap(refNode);
+ }
+ } else {
+ refWrapper = null;
+ refNode = null;
+ }
+ refWrapper && assert(refWrapper.parentNode === this);
+ var nodes;
+ var previousNode = refWrapper ? refWrapper.previousSibling : this.lastChild;
+ var useNative = !this.invalidateShadowRenderer() && !invalidateParent(childWrapper);
+ if (useNative) nodes = collectNodesNative(childWrapper); else nodes = collectNodes(childWrapper, this, previousNode, refWrapper);
+ if (useNative) {
+ ensureSameOwnerDocument(this, childWrapper);
+ clearChildNodes(this);
+ originalInsertBefore.call(unsafeUnwrap(this), unwrap(childWrapper), refNode);
+ } else {
+ if (!previousNode) this.firstChild_ = nodes[0];
+ if (!refWrapper) {
+ this.lastChild_ = nodes[nodes.length - 1];
+ if (this.firstChild_ === undefined) this.firstChild_ = this.firstChild;
+ }
+ var parentNode = refNode ? refNode.parentNode : unsafeUnwrap(this);
+ if (parentNode) {
+ originalInsertBefore.call(parentNode, unwrapNodesForInsertion(this, nodes), refNode);
+ } else {
+ adoptNodesIfNeeded(this, nodes);
+ }
+ }
+ enqueueMutation(this, "childList", {
+ addedNodes: nodes,
+ nextSibling: refWrapper,
+ previousSibling: previousNode
+ });
+ nodesWereAdded(nodes, this);
+ return childWrapper;
+ },
+ removeChild: function(childWrapper) {
+ assertIsNodeWrapper(childWrapper);
+ if (childWrapper.parentNode !== this) {
+ var found = false;
+ var childNodes = this.childNodes;
+ for (var ieChild = this.firstChild; ieChild; ieChild = ieChild.nextSibling) {
+ if (ieChild === childWrapper) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ throw new Error("NotFoundError");
+ }
+ }
+ var childNode = unwrap(childWrapper);
+ var childWrapperNextSibling = childWrapper.nextSibling;
+ var childWrapperPreviousSibling = childWrapper.previousSibling;
+ if (this.invalidateShadowRenderer()) {
+ var thisFirstChild = this.firstChild;
+ var thisLastChild = this.lastChild;
+ var parentNode = childNode.parentNode;
+ if (parentNode) removeChildOriginalHelper(parentNode, childNode);
+ if (thisFirstChild === childWrapper) this.firstChild_ = childWrapperNextSibling;
+ if (thisLastChild === childWrapper) this.lastChild_ = childWrapperPreviousSibling;
+ if (childWrapperPreviousSibling) childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;
+ if (childWrapperNextSibling) {
+ childWrapperNextSibling.previousSibling_ = childWrapperPreviousSibling;
+ }
+ childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = undefined;
+ } else {
+ clearChildNodes(this);
+ removeChildOriginalHelper(unsafeUnwrap(this), childNode);
+ }
+ if (!surpressMutations) {
+ enqueueMutation(this, "childList", {
+ removedNodes: createOneElementNodeList(childWrapper),
+ nextSibling: childWrapperNextSibling,
+ previousSibling: childWrapperPreviousSibling
+ });
+ }
+ registerTransientObservers(this, childWrapper);
+ return childWrapper;
+ },
+ replaceChild: function(newChildWrapper, oldChildWrapper) {
+ assertIsNodeWrapper(newChildWrapper);
+ var oldChildNode;
+ if (isWrapper(oldChildWrapper)) {
+ oldChildNode = unwrap(oldChildWrapper);
+ } else {
+ oldChildNode = oldChildWrapper;
+ oldChildWrapper = wrap(oldChildNode);
+ }
+ if (oldChildWrapper.parentNode !== this) {
+ throw new Error("NotFoundError");
+ }
+ var nextNode = oldChildWrapper.nextSibling;
+ var previousNode = oldChildWrapper.previousSibling;
+ var nodes;
+ var useNative = !this.invalidateShadowRenderer() && !invalidateParent(newChildWrapper);
+ if (useNative) {
+ nodes = collectNodesNative(newChildWrapper);
+ } else {
+ if (nextNode === newChildWrapper) nextNode = newChildWrapper.nextSibling;
+ nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);
+ }
+ if (!useNative) {
+ if (this.firstChild === oldChildWrapper) this.firstChild_ = nodes[0];
+ if (this.lastChild === oldChildWrapper) this.lastChild_ = nodes[nodes.length - 1];
+ oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ = oldChildWrapper.parentNode_ = undefined;
+ if (oldChildNode.parentNode) {
+ originalReplaceChild.call(oldChildNode.parentNode, unwrapNodesForInsertion(this, nodes), oldChildNode);
+ }
+ } else {
+ ensureSameOwnerDocument(this, newChildWrapper);
+ clearChildNodes(this);
+ originalReplaceChild.call(unsafeUnwrap(this), unwrap(newChildWrapper), oldChildNode);
+ }
+ enqueueMutation(this, "childList", {
+ addedNodes: nodes,
+ removedNodes: createOneElementNodeList(oldChildWrapper),
+ nextSibling: nextNode,
+ previousSibling: previousNode
+ });
+ nodeWasRemoved(oldChildWrapper);
+ nodesWereAdded(nodes, this);
+ return oldChildWrapper;
+ },
+ nodeIsInserted_: function() {
+ for (var child = this.firstChild; child; child = child.nextSibling) {
+ child.nodeIsInserted_();
+ }
+ },
+ hasChildNodes: function() {
+ return this.firstChild !== null;
+ },
+ get parentNode() {
+ return this.parentNode_ !== undefined ? this.parentNode_ : wrap(unsafeUnwrap(this).parentNode);
+ },
+ get firstChild() {
+ return this.firstChild_ !== undefined ? this.firstChild_ : wrap(unsafeUnwrap(this).firstChild);
+ },
+ get lastChild() {
+ return this.lastChild_ !== undefined ? this.lastChild_ : wrap(unsafeUnwrap(this).lastChild);
+ },
+ get nextSibling() {
+ return this.nextSibling_ !== undefined ? this.nextSibling_ : wrap(unsafeUnwrap(this).nextSibling);
+ },
+ get previousSibling() {
+ return this.previousSibling_ !== undefined ? this.previousSibling_ : wrap(unsafeUnwrap(this).previousSibling);
+ },
+ get parentElement() {
+ var p = this.parentNode;
+ while (p && p.nodeType !== Node.ELEMENT_NODE) {
+ p = p.parentNode;
+ }
+ return p;
+ },
+ get textContent() {
+ var s = "";
+ for (var child = this.firstChild; child; child = child.nextSibling) {
+ if (child.nodeType != Node.COMMENT_NODE) {
+ s += child.textContent;
+ }
+ }
+ return s;
+ },
+ set textContent(textContent) {
+ if (textContent == null) textContent = "";
+ var removedNodes = snapshotNodeList(this.childNodes);
+ if (this.invalidateShadowRenderer()) {
+ removeAllChildNodes(this);
+ if (textContent !== "") {
+ var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textContent);
+ this.appendChild(textNode);
+ }
+ } else {
+ clearChildNodes(this);
+ unsafeUnwrap(this).textContent = textContent;
+ }
+ var addedNodes = snapshotNodeList(this.childNodes);
+ enqueueMutation(this, "childList", {
+ addedNodes: addedNodes,
+ removedNodes: removedNodes
+ });
+ nodesWereRemoved(removedNodes);
+ nodesWereAdded(addedNodes, this);
+ },
+ get childNodes() {
+ var wrapperList = new NodeList();
+ var i = 0;
+ for (var child = this.firstChild; child; child = child.nextSibling) {
+ wrapperList[i++] = child;
+ }
+ wrapperList.length = i;
+ return wrapperList;
+ },
+ cloneNode: function(deep) {
+ return cloneNode(this, deep);
+ },
+ contains: function(child) {
+ return contains(this, wrapIfNeeded(child));
+ },
+ compareDocumentPosition: function(otherNode) {
+ return originalCompareDocumentPosition.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));
+ },
+ isEqualNode: function(otherNode) {
+ return originalIsEqualNode.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));
+ },
+ normalize: function() {
+ var nodes = snapshotNodeList(this.childNodes);
+ var remNodes = [];
+ var s = "";
+ var modNode;
+ for (var i = 0, n; i < nodes.length; i++) {
+ n = nodes[i];
+ if (n.nodeType === Node.TEXT_NODE) {
+ if (!modNode && !n.data.length) this.removeChild(n); else if (!modNode) modNode = n; else {
+ s += n.data;
+ remNodes.push(n);
+ }
+ } else {
+ if (modNode && remNodes.length) {
+ modNode.data += s;
+ cleanupNodes(remNodes);
+ }
+ remNodes = [];
+ s = "";
+ modNode = null;
+ if (n.childNodes.length) n.normalize();
+ }
+ }
+ if (modNode && remNodes.length) {
+ modNode.data += s;
+ cleanupNodes(remNodes);
+ }
+ }
+ });
+ defineWrapGetter(Node, "ownerDocument");
+ registerWrapper(OriginalNode, Node, document.createDocumentFragment());
+ delete Node.prototype.querySelector;
+ delete Node.prototype.querySelectorAll;
+ Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);
+ scope.cloneNode = cloneNode;
+ scope.nodeWasAdded = nodeWasAdded;
+ scope.nodeWasRemoved = nodeWasRemoved;
+ scope.nodesWereAdded = nodesWereAdded;
+ scope.nodesWereRemoved = nodesWereRemoved;
+ scope.originalInsertBefore = originalInsertBefore;
+ scope.originalRemoveChild = originalRemoveChild;
+ scope.snapshotNodeList = snapshotNodeList;
+ scope.wrappers.Node = Node;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLCollection = scope.wrappers.HTMLCollection;
+ var NodeList = scope.wrappers.NodeList;
+ var getTreeScope = scope.getTreeScope;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var wrap = scope.wrap;
+ var originalDocumentQuerySelector = document.querySelector;
+ var originalElementQuerySelector = document.documentElement.querySelector;
+ var originalDocumentQuerySelectorAll = document.querySelectorAll;
+ var originalElementQuerySelectorAll = document.documentElement.querySelectorAll;
+ var originalDocumentGetElementsByTagName = document.getElementsByTagName;
+ var originalElementGetElementsByTagName = document.documentElement.getElementsByTagName;
+ var originalDocumentGetElementsByTagNameNS = document.getElementsByTagNameNS;
+ var originalElementGetElementsByTagNameNS = document.documentElement.getElementsByTagNameNS;
+ var OriginalElement = window.Element;
+ var OriginalDocument = window.HTMLDocument || window.Document;
+ function filterNodeList(list, index, result, deep) {
+ var wrappedItem = null;
+ var root = null;
+ for (var i = 0, length = list.length; i < length; i++) {
+ wrappedItem = wrap(list[i]);
+ if (!deep && (root = getTreeScope(wrappedItem).root)) {
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ continue;
+ }
+ }
+ result[index++] = wrappedItem;
+ }
+ return index;
+ }
+ function shimSelector(selector) {
+ return String(selector).replace(/\/deep\/|::shadow|>>>/g, " ");
+ }
+ function shimMatchesSelector(selector) {
+ return String(selector).replace(/:host\(([^\s]+)\)/g, "$1").replace(/([^\s]):host/g, "$1").replace(":host", "*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content|>>>/g, " ");
+ }
+ function findOne(node, selector) {
+ var m, el = node.firstElementChild;
+ while (el) {
+ if (el.matches(selector)) return el;
+ m = findOne(el, selector);
+ if (m) return m;
+ el = el.nextElementSibling;
+ }
+ return null;
+ }
+ function matchesSelector(el, selector) {
+ return el.matches(selector);
+ }
+ var XHTML_NS = "http://www.w3.org/1999/xhtml";
+ function matchesTagName(el, localName, localNameLowerCase) {
+ var ln = el.localName;
+ return ln === localName || ln === localNameLowerCase && el.namespaceURI === XHTML_NS;
+ }
+ function matchesEveryThing() {
+ return true;
+ }
+ function matchesLocalNameOnly(el, ns, localName) {
+ return el.localName === localName;
+ }
+ function matchesNameSpace(el, ns) {
+ return el.namespaceURI === ns;
+ }
+ function matchesLocalNameNS(el, ns, localName) {
+ return el.namespaceURI === ns && el.localName === localName;
+ }
+ function findElements(node, index, result, p, arg0, arg1) {
+ var el = node.firstElementChild;
+ while (el) {
+ if (p(el, arg0, arg1)) result[index++] = el;
+ index = findElements(el, index, result, p, arg0, arg1);
+ el = el.nextElementSibling;
+ }
+ return index;
+ }
+ function querySelectorAllFiltered(p, index, result, selector, deep) {
+ var target = unsafeUnwrap(this);
+ var list;
+ var root = getTreeScope(this).root;
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ return findElements(this, index, result, p, selector, null);
+ } else if (target instanceof OriginalElement) {
+ list = originalElementQuerySelectorAll.call(target, selector);
+ } else if (target instanceof OriginalDocument) {
+ list = originalDocumentQuerySelectorAll.call(target, selector);
+ } else {
+ return findElements(this, index, result, p, selector, null);
+ }
+ return filterNodeList(list, index, result, deep);
+ }
+ var SelectorsInterface = {
+ querySelector: function(selector) {
+ var shimmed = shimSelector(selector);
+ var deep = shimmed !== selector;
+ selector = shimmed;
+ var target = unsafeUnwrap(this);
+ var wrappedItem;
+ var root = getTreeScope(this).root;
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ return findOne(this, selector);
+ } else if (target instanceof OriginalElement) {
+ wrappedItem = wrap(originalElementQuerySelector.call(target, selector));
+ } else if (target instanceof OriginalDocument) {
+ wrappedItem = wrap(originalDocumentQuerySelector.call(target, selector));
+ } else {
+ return findOne(this, selector);
+ }
+ if (!wrappedItem) {
+ return wrappedItem;
+ } else if (!deep && (root = getTreeScope(wrappedItem).root)) {
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ return findOne(this, selector);
+ }
+ }
+ return wrappedItem;
+ },
+ querySelectorAll: function(selector) {
+ var shimmed = shimSelector(selector);
+ var deep = shimmed !== selector;
+ selector = shimmed;
+ var result = new NodeList();
+ result.length = querySelectorAllFiltered.call(this, matchesSelector, 0, result, selector, deep);
+ return result;
+ }
+ };
+ var MatchesInterface = {
+ matches: function(selector) {
+ selector = shimMatchesSelector(selector);
+ return scope.originalMatches.call(unsafeUnwrap(this), selector);
+ }
+ };
+ function getElementsByTagNameFiltered(p, index, result, localName, lowercase) {
+ var target = unsafeUnwrap(this);
+ var list;
+ var root = getTreeScope(this).root;
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ return findElements(this, index, result, p, localName, lowercase);
+ } else if (target instanceof OriginalElement) {
+ list = originalElementGetElementsByTagName.call(target, localName, lowercase);
+ } else if (target instanceof OriginalDocument) {
+ list = originalDocumentGetElementsByTagName.call(target, localName, lowercase);
+ } else {
+ return findElements(this, index, result, p, localName, lowercase);
+ }
+ return filterNodeList(list, index, result, false);
+ }
+ function getElementsByTagNameNSFiltered(p, index, result, ns, localName) {
+ var target = unsafeUnwrap(this);
+ var list;
+ var root = getTreeScope(this).root;
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ return findElements(this, index, result, p, ns, localName);
+ } else if (target instanceof OriginalElement) {
+ list = originalElementGetElementsByTagNameNS.call(target, ns, localName);
+ } else if (target instanceof OriginalDocument) {
+ list = originalDocumentGetElementsByTagNameNS.call(target, ns, localName);
+ } else {
+ return findElements(this, index, result, p, ns, localName);
+ }
+ return filterNodeList(list, index, result, false);
+ }
+ var GetElementsByInterface = {
+ getElementsByTagName: function(localName) {
+ var result = new HTMLCollection();
+ var match = localName === "*" ? matchesEveryThing : matchesTagName;
+ result.length = getElementsByTagNameFiltered.call(this, match, 0, result, localName, localName.toLowerCase());
+ return result;
+ },
+ getElementsByClassName: function(className) {
+ return this.querySelectorAll("." + className);
+ },
+ getElementsByTagNameNS: function(ns, localName) {
+ var result = new HTMLCollection();
+ var match = null;
+ if (ns === "*") {
+ match = localName === "*" ? matchesEveryThing : matchesLocalNameOnly;
+ } else {
+ match = localName === "*" ? matchesNameSpace : matchesLocalNameNS;
+ }
+ result.length = getElementsByTagNameNSFiltered.call(this, match, 0, result, ns || null, localName);
+ return result;
+ }
+ };
+ scope.GetElementsByInterface = GetElementsByInterface;
+ scope.SelectorsInterface = SelectorsInterface;
+ scope.MatchesInterface = MatchesInterface;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var NodeList = scope.wrappers.NodeList;
+ function forwardElement(node) {
+ while (node && node.nodeType !== Node.ELEMENT_NODE) {
+ node = node.nextSibling;
+ }
+ return node;
+ }
+ function backwardsElement(node) {
+ while (node && node.nodeType !== Node.ELEMENT_NODE) {
+ node = node.previousSibling;
+ }
+ return node;
+ }
+ var ParentNodeInterface = {
+ get firstElementChild() {
+ return forwardElement(this.firstChild);
+ },
+ get lastElementChild() {
+ return backwardsElement(this.lastChild);
+ },
+ get childElementCount() {
+ var count = 0;
+ for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
+ count++;
+ }
+ return count;
+ },
+ get children() {
+ var wrapperList = new NodeList();
+ var i = 0;
+ for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
+ wrapperList[i++] = child;
+ }
+ wrapperList.length = i;
+ return wrapperList;
+ },
+ remove: function() {
+ var p = this.parentNode;
+ if (p) p.removeChild(this);
+ }
+ };
+ var ChildNodeInterface = {
+ get nextElementSibling() {
+ return forwardElement(this.nextSibling);
+ },
+ get previousElementSibling() {
+ return backwardsElement(this.previousSibling);
+ }
+ };
+ var NonElementParentNodeInterface = {
+ getElementById: function(id) {
+ if (/[ \t\n\r\f]/.test(id)) return null;
+ return this.querySelector('[id="' + id + '"]');
+ }
+ };
+ scope.ChildNodeInterface = ChildNodeInterface;
+ scope.NonElementParentNodeInterface = NonElementParentNodeInterface;
+ scope.ParentNodeInterface = ParentNodeInterface;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var ChildNodeInterface = scope.ChildNodeInterface;
+ var Node = scope.wrappers.Node;
+ var enqueueMutation = scope.enqueueMutation;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var OriginalCharacterData = window.CharacterData;
+ function CharacterData(node) {
+ Node.call(this, node);
+ }
+ CharacterData.prototype = Object.create(Node.prototype);
+ mixin(CharacterData.prototype, {
+ get nodeValue() {
+ return this.data;
+ },
+ set nodeValue(data) {
+ this.data = data;
+ },
+ get textContent() {
+ return this.data;
+ },
+ set textContent(value) {
+ this.data = value;
+ },
+ get data() {
+ return unsafeUnwrap(this).data;
+ },
+ set data(value) {
+ var oldValue = unsafeUnwrap(this).data;
+ enqueueMutation(this, "characterData", {
+ oldValue: oldValue
+ });
+ unsafeUnwrap(this).data = value;
+ }
+ });
+ mixin(CharacterData.prototype, ChildNodeInterface);
+ registerWrapper(OriginalCharacterData, CharacterData, document.createTextNode(""));
+ scope.wrappers.CharacterData = CharacterData;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var CharacterData = scope.wrappers.CharacterData;
+ var enqueueMutation = scope.enqueueMutation;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ function toUInt32(x) {
+ return x >>> 0;
+ }
+ var OriginalText = window.Text;
+ function Text(node) {
+ CharacterData.call(this, node);
+ }
+ Text.prototype = Object.create(CharacterData.prototype);
+ mixin(Text.prototype, {
+ splitText: function(offset) {
+ offset = toUInt32(offset);
+ var s = this.data;
+ if (offset > s.length) throw new Error("IndexSizeError");
+ var head = s.slice(0, offset);
+ var tail = s.slice(offset);
+ this.data = head;
+ var newTextNode = this.ownerDocument.createTextNode(tail);
+ if (this.parentNode) this.parentNode.insertBefore(newTextNode, this.nextSibling);
+ return newTextNode;
+ }
+ });
+ registerWrapper(OriginalText, Text, document.createTextNode(""));
+ scope.wrappers.Text = Text;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ if (!window.DOMTokenList) {
+ console.warn("Missing DOMTokenList prototype, please include a " + "compatible classList polyfill such as http://goo.gl/uTcepH.");
+ return;
+ }
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var enqueueMutation = scope.enqueueMutation;
+ function getClass(el) {
+ return unsafeUnwrap(el).getAttribute("class");
+ }
+ function enqueueClassAttributeChange(el, oldValue) {
+ enqueueMutation(el, "attributes", {
+ name: "class",
+ namespace: null,
+ oldValue: oldValue
+ });
+ }
+ function invalidateClass(el) {
+ scope.invalidateRendererBasedOnAttribute(el, "class");
+ }
+ function changeClass(tokenList, method, args) {
+ var ownerElement = tokenList.ownerElement_;
+ if (ownerElement == null) {
+ return method.apply(tokenList, args);
+ }
+ var oldValue = getClass(ownerElement);
+ var retv = method.apply(tokenList, args);
+ if (getClass(ownerElement) !== oldValue) {
+ enqueueClassAttributeChange(ownerElement, oldValue);
+ invalidateClass(ownerElement);
+ }
+ return retv;
+ }
+ var oldAdd = DOMTokenList.prototype.add;
+ DOMTokenList.prototype.add = function() {
+ changeClass(this, oldAdd, arguments);
+ };
+ var oldRemove = DOMTokenList.prototype.remove;
+ DOMTokenList.prototype.remove = function() {
+ changeClass(this, oldRemove, arguments);
+ };
+ var oldToggle = DOMTokenList.prototype.toggle;
+ DOMTokenList.prototype.toggle = function() {
+ return changeClass(this, oldToggle, arguments);
+ };
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var ChildNodeInterface = scope.ChildNodeInterface;
+ var GetElementsByInterface = scope.GetElementsByInterface;
+ var Node = scope.wrappers.Node;
+ var ParentNodeInterface = scope.ParentNodeInterface;
+ var SelectorsInterface = scope.SelectorsInterface;
+ var MatchesInterface = scope.MatchesInterface;
+ var addWrapNodeListMethod = scope.addWrapNodeListMethod;
+ var enqueueMutation = scope.enqueueMutation;
+ var mixin = scope.mixin;
+ var oneOf = scope.oneOf;
+ var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var wrappers = scope.wrappers;
+ var OriginalElement = window.Element;
+ var matchesNames = [ "matches", "mozMatchesSelector", "msMatchesSelector", "webkitMatchesSelector" ].filter(function(name) {
+ return OriginalElement.prototype[name];
+ });
+ var matchesName = matchesNames[0];
+ var originalMatches = OriginalElement.prototype[matchesName];
+ function invalidateRendererBasedOnAttribute(element, name) {
+ var p = element.parentNode;
+ if (!p || !p.shadowRoot) return;
+ var renderer = scope.getRendererForHost(p);
+ if (renderer.dependsOnAttribute(name)) renderer.invalidate();
+ }
+ function enqueAttributeChange(element, name, oldValue) {
+ enqueueMutation(element, "attributes", {
+ name: name,
+ namespace: null,
+ oldValue: oldValue
+ });
+ }
+ var classListTable = new WeakMap();
+ function Element(node) {
+ Node.call(this, node);
+ }
+ Element.prototype = Object.create(Node.prototype);
+ mixin(Element.prototype, {
+ createShadowRoot: function() {
+ var newShadowRoot = new wrappers.ShadowRoot(this);
+ unsafeUnwrap(this).polymerShadowRoot_ = newShadowRoot;
+ var renderer = scope.getRendererForHost(this);
+ renderer.invalidate();
+ return newShadowRoot;
+ },
+ get shadowRoot() {
+ return unsafeUnwrap(this).polymerShadowRoot_ || null;
+ },
+ setAttribute: function(name, value) {
+ var oldValue = unsafeUnwrap(this).getAttribute(name);
+ unsafeUnwrap(this).setAttribute(name, value);
+ enqueAttributeChange(this, name, oldValue);
+ invalidateRendererBasedOnAttribute(this, name);
+ },
+ removeAttribute: function(name) {
+ var oldValue = unsafeUnwrap(this).getAttribute(name);
+ unsafeUnwrap(this).removeAttribute(name);
+ enqueAttributeChange(this, name, oldValue);
+ invalidateRendererBasedOnAttribute(this, name);
+ },
+ get classList() {
+ var list = classListTable.get(this);
+ if (!list) {
+ list = unsafeUnwrap(this).classList;
+ if (!list) return;
+ list.ownerElement_ = this;
+ classListTable.set(this, list);
+ }
+ return list;
+ },
+ get className() {
+ return unsafeUnwrap(this).className;
+ },
+ set className(v) {
+ this.setAttribute("class", v);
+ },
+ get id() {
+ return unsafeUnwrap(this).id;
+ },
+ set id(v) {
+ this.setAttribute("id", v);
+ }
+ });
+ matchesNames.forEach(function(name) {
+ if (name !== "matches") {
+ Element.prototype[name] = function(selector) {
+ return this.matches(selector);
+ };
+ }
+ });
+ if (OriginalElement.prototype.webkitCreateShadowRoot) {
+ Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;
+ }
+ mixin(Element.prototype, ChildNodeInterface);
+ mixin(Element.prototype, GetElementsByInterface);
+ mixin(Element.prototype, ParentNodeInterface);
+ mixin(Element.prototype, SelectorsInterface);
+ mixin(Element.prototype, MatchesInterface);
+ registerWrapper(OriginalElement, Element, document.createElementNS(null, "x"));
+ scope.invalidateRendererBasedOnAttribute = invalidateRendererBasedOnAttribute;
+ scope.matchesNames = matchesNames;
+ scope.originalMatches = originalMatches;
+ scope.wrappers.Element = Element;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var Element = scope.wrappers.Element;
+ var defineGetter = scope.defineGetter;
+ var enqueueMutation = scope.enqueueMutation;
+ var mixin = scope.mixin;
+ var nodesWereAdded = scope.nodesWereAdded;
+ var nodesWereRemoved = scope.nodesWereRemoved;
+ var registerWrapper = scope.registerWrapper;
+ var snapshotNodeList = scope.snapshotNodeList;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var wrappers = scope.wrappers;
+ var escapeAttrRegExp = /[&\u00A0"]/g;
+ var escapeDataRegExp = /[&\u00A0<>]/g;
+ function escapeReplace(c) {
+ switch (c) {
+ case "&":
+ return "&";
+
+ case "<":
+ return "<";
+
+ case ">":
+ return ">";
+
+ case '"':
+ return """;
+
+ case " ":
+ return " ";
+ }
+ }
+ function escapeAttr(s) {
+ return s.replace(escapeAttrRegExp, escapeReplace);
+ }
+ function escapeData(s) {
+ return s.replace(escapeDataRegExp, escapeReplace);
+ }
+ function makeSet(arr) {
+ var set = {};
+ for (var i = 0; i < arr.length; i++) {
+ set[arr[i]] = true;
+ }
+ return set;
+ }
+ var voidElements = makeSet([ "area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr" ]);
+ var plaintextParents = makeSet([ "style", "script", "xmp", "iframe", "noembed", "noframes", "plaintext", "noscript" ]);
+ var XHTML_NS = "http://www.w3.org/1999/xhtml";
+ function needsSelfClosingSlash(node) {
+ if (node.namespaceURI !== XHTML_NS) return true;
+ var doctype = node.ownerDocument.doctype;
+ return doctype && doctype.publicId && doctype.systemId;
+ }
+ function getOuterHTML(node, parentNode) {
+ switch (node.nodeType) {
+ case Node.ELEMENT_NODE:
+ var tagName = node.tagName.toLowerCase();
+ var s = "<" + tagName;
+ var attrs = node.attributes;
+ for (var i = 0, attr; attr = attrs[i]; i++) {
+ s += " " + attr.name + '="' + escapeAttr(attr.value) + '"';
+ }
+ if (voidElements[tagName]) {
+ if (needsSelfClosingSlash(node)) s += "/";
+ return s + ">";
+ }
+ return s + ">" + getInnerHTML(node) + "</" + tagName + ">";
+
+ case Node.TEXT_NODE:
+ var data = node.data;
+ if (parentNode && plaintextParents[parentNode.localName]) return data;
+ return escapeData(data);
+
+ case Node.COMMENT_NODE:
+ return "<!--" + node.data + "-->";
+
+ default:
+ console.error(node);
+ throw new Error("not implemented");
+ }
+ }
+ function getInnerHTML(node) {
+ if (node instanceof wrappers.HTMLTemplateElement) node = node.content;
+ var s = "";
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ s += getOuterHTML(child, node);
+ }
+ return s;
+ }
+ function setInnerHTML(node, value, opt_tagName) {
+ var tagName = opt_tagName || "div";
+ node.textContent = "";
+ var tempElement = unwrap(node.ownerDocument.createElement(tagName));
+ tempElement.innerHTML = value;
+ var firstChild;
+ while (firstChild = tempElement.firstChild) {
+ node.appendChild(wrap(firstChild));
+ }
+ }
+ var oldIe = /MSIE/.test(navigator.userAgent);
+ var OriginalHTMLElement = window.HTMLElement;
+ var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
+ function HTMLElement(node) {
+ Element.call(this, node);
+ }
+ HTMLElement.prototype = Object.create(Element.prototype);
+ mixin(HTMLElement.prototype, {
+ get innerHTML() {
+ return getInnerHTML(this);
+ },
+ set innerHTML(value) {
+ if (oldIe && plaintextParents[this.localName]) {
+ this.textContent = value;
+ return;
+ }
+ var removedNodes = snapshotNodeList(this.childNodes);
+ if (this.invalidateShadowRenderer()) {
+ if (this instanceof wrappers.HTMLTemplateElement) setInnerHTML(this.content, value); else setInnerHTML(this, value, this.tagName);
+ } else if (!OriginalHTMLTemplateElement && this instanceof wrappers.HTMLTemplateElement) {
+ setInnerHTML(this.content, value);
+ } else {
+ unsafeUnwrap(this).innerHTML = value;
+ }
+ var addedNodes = snapshotNodeList(this.childNodes);
+ enqueueMutation(this, "childList", {
+ addedNodes: addedNodes,
+ removedNodes: removedNodes
+ });
+ nodesWereRemoved(removedNodes);
+ nodesWereAdded(addedNodes, this);
+ },
+ get outerHTML() {
+ return getOuterHTML(this, this.parentNode);
+ },
+ set outerHTML(value) {
+ var p = this.parentNode;
+ if (p) {
+ p.invalidateShadowRenderer();
+ var df = frag(p, value);
+ p.replaceChild(df, this);
+ }
+ },
+ insertAdjacentHTML: function(position, text) {
+ var contextElement, refNode;
+ switch (String(position).toLowerCase()) {
+ case "beforebegin":
+ contextElement = this.parentNode;
+ refNode = this;
+ break;
+
+ case "afterend":
+ contextElement = this.parentNode;
+ refNode = this.nextSibling;
+ break;
+
+ case "afterbegin":
+ contextElement = this;
+ refNode = this.firstChild;
+ break;
+
+ case "beforeend":
+ contextElement = this;
+ refNode = null;
+ break;
+
+ default:
+ return;
+ }
+ var df = frag(contextElement, text);
+ contextElement.insertBefore(df, refNode);
+ },
+ get hidden() {
+ return this.hasAttribute("hidden");
+ },
+ set hidden(v) {
+ if (v) {
+ this.setAttribute("hidden", "");
+ } else {
+ this.removeAttribute("hidden");
+ }
+ }
+ });
+ function frag(contextElement, html) {
+ var p = unwrap(contextElement.cloneNode(false));
+ p.innerHTML = html;
+ var df = unwrap(document.createDocumentFragment());
+ var c;
+ while (c = p.firstChild) {
+ df.appendChild(c);
+ }
+ return wrap(df);
+ }
+ function getter(name) {
+ return function() {
+ scope.renderAllPending();
+ return unsafeUnwrap(this)[name];
+ };
+ }
+ function getterRequiresRendering(name) {
+ defineGetter(HTMLElement, name, getter(name));
+ }
+ [ "clientHeight", "clientLeft", "clientTop", "clientWidth", "offsetHeight", "offsetLeft", "offsetTop", "offsetWidth", "scrollHeight", "scrollWidth" ].forEach(getterRequiresRendering);
+ function getterAndSetterRequiresRendering(name) {
+ Object.defineProperty(HTMLElement.prototype, name, {
+ get: getter(name),
+ set: function(v) {
+ scope.renderAllPending();
+ unsafeUnwrap(this)[name] = v;
+ },
+ configurable: true,
+ enumerable: true
+ });
+ }
+ [ "scrollLeft", "scrollTop" ].forEach(getterAndSetterRequiresRendering);
+ function methodRequiresRendering(name) {
+ Object.defineProperty(HTMLElement.prototype, name, {
+ value: function() {
+ scope.renderAllPending();
+ return unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments);
+ },
+ configurable: true,
+ enumerable: true
+ });
+ }
+ [ "getBoundingClientRect", "getClientRects", "scrollIntoView" ].forEach(methodRequiresRendering);
+ registerWrapper(OriginalHTMLElement, HTMLElement, document.createElement("b"));
+ scope.wrappers.HTMLElement = HTMLElement;
+ scope.getInnerHTML = getInnerHTML;
+ scope.setInnerHTML = setInnerHTML;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var wrap = scope.wrap;
+ var OriginalHTMLCanvasElement = window.HTMLCanvasElement;
+ function HTMLCanvasElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLCanvasElement.prototype, {
+ getContext: function() {
+ var context = unsafeUnwrap(this).getContext.apply(unsafeUnwrap(this), arguments);
+ return context && wrap(context);
+ }
+ });
+ registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement, document.createElement("canvas"));
+ scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var OriginalHTMLContentElement = window.HTMLContentElement;
+ function HTMLContentElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLContentElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLContentElement.prototype, {
+ constructor: HTMLContentElement,
+ get select() {
+ return this.getAttribute("select");
+ },
+ set select(value) {
+ this.setAttribute("select", value);
+ },
+ setAttribute: function(n, v) {
+ HTMLElement.prototype.setAttribute.call(this, n, v);
+ if (String(n).toLowerCase() === "select") this.invalidateShadowRenderer(true);
+ }
+ });
+ if (OriginalHTMLContentElement) registerWrapper(OriginalHTMLContentElement, HTMLContentElement);
+ scope.wrappers.HTMLContentElement = HTMLContentElement;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var wrapHTMLCollection = scope.wrapHTMLCollection;
+ var unwrap = scope.unwrap;
+ var OriginalHTMLFormElement = window.HTMLFormElement;
+ function HTMLFormElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLFormElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLFormElement.prototype, {
+ get elements() {
+ return wrapHTMLCollection(unwrap(this).elements);
+ }
+ });
+ registerWrapper(OriginalHTMLFormElement, HTMLFormElement, document.createElement("form"));
+ scope.wrappers.HTMLFormElement = HTMLFormElement;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var registerWrapper = scope.registerWrapper;
+ var unwrap = scope.unwrap;
+ var rewrap = scope.rewrap;
+ var OriginalHTMLImageElement = window.HTMLImageElement;
+ function HTMLImageElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLImageElement.prototype = Object.create(HTMLElement.prototype);
+ registerWrapper(OriginalHTMLImageElement, HTMLImageElement, document.createElement("img"));
+ function Image(width, height) {
+ if (!(this instanceof Image)) {
+ throw new TypeError("DOM object constructor cannot be called as a function.");
+ }
+ var node = unwrap(document.createElement("img"));
+ HTMLElement.call(this, node);
+ rewrap(node, this);
+ if (width !== undefined) node.width = width;
+ if (height !== undefined) node.height = height;
+ }
+ Image.prototype = HTMLImageElement.prototype;
+ scope.wrappers.HTMLImageElement = HTMLImageElement;
+ scope.wrappers.Image = Image;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var NodeList = scope.wrappers.NodeList;
+ var registerWrapper = scope.registerWrapper;
+ var OriginalHTMLShadowElement = window.HTMLShadowElement;
+ function HTMLShadowElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);
+ HTMLShadowElement.prototype.constructor = HTMLShadowElement;
+ if (OriginalHTMLShadowElement) registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);
+ scope.wrappers.HTMLShadowElement = HTMLShadowElement;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var contentTable = new WeakMap();
+ var templateContentsOwnerTable = new WeakMap();
+ function getTemplateContentsOwner(doc) {
+ if (!doc.defaultView) return doc;
+ var d = templateContentsOwnerTable.get(doc);
+ if (!d) {
+ d = doc.implementation.createHTMLDocument("");
+ while (d.lastChild) {
+ d.removeChild(d.lastChild);
+ }
+ templateContentsOwnerTable.set(doc, d);
+ }
+ return d;
+ }
+ function extractContent(templateElement) {
+ var doc = getTemplateContentsOwner(templateElement.ownerDocument);
+ var df = unwrap(doc.createDocumentFragment());
+ var child;
+ while (child = templateElement.firstChild) {
+ df.appendChild(child);
+ }
+ return df;
+ }
+ var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
+ function HTMLTemplateElement(node) {
+ HTMLElement.call(this, node);
+ if (!OriginalHTMLTemplateElement) {
+ var content = extractContent(node);
+ contentTable.set(this, wrap(content));
+ }
+ }
+ HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLTemplateElement.prototype, {
+ constructor: HTMLTemplateElement,
+ get content() {
+ if (OriginalHTMLTemplateElement) return wrap(unsafeUnwrap(this).content);
+ return contentTable.get(this);
+ }
+ });
+ if (OriginalHTMLTemplateElement) registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);
+ scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var registerWrapper = scope.registerWrapper;
+ var OriginalHTMLMediaElement = window.HTMLMediaElement;
+ if (!OriginalHTMLMediaElement) return;
+ function HTMLMediaElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);
+ registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement, document.createElement("audio"));
+ scope.wrappers.HTMLMediaElement = HTMLMediaElement;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLMediaElement = scope.wrappers.HTMLMediaElement;
+ var registerWrapper = scope.registerWrapper;
+ var unwrap = scope.unwrap;
+ var rewrap = scope.rewrap;
+ var OriginalHTMLAudioElement = window.HTMLAudioElement;
+ if (!OriginalHTMLAudioElement) return;
+ function HTMLAudioElement(node) {
+ HTMLMediaElement.call(this, node);
+ }
+ HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);
+ registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement, document.createElement("audio"));
+ function Audio(src) {
+ if (!(this instanceof Audio)) {
+ throw new TypeError("DOM object constructor cannot be called as a function.");
+ }
+ var node = unwrap(document.createElement("audio"));
+ HTMLMediaElement.call(this, node);
+ rewrap(node, this);
+ node.setAttribute("preload", "auto");
+ if (src !== undefined) node.setAttribute("src", src);
+ }
+ Audio.prototype = HTMLAudioElement.prototype;
+ scope.wrappers.HTMLAudioElement = HTMLAudioElement;
+ scope.wrappers.Audio = Audio;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var rewrap = scope.rewrap;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var OriginalHTMLOptionElement = window.HTMLOptionElement;
+ function trimText(s) {
+ return s.replace(/\s+/g, " ").trim();
+ }
+ function HTMLOptionElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLOptionElement.prototype, {
+ get text() {
+ return trimText(this.textContent);
+ },
+ set text(value) {
+ this.textContent = trimText(String(value));
+ },
+ get form() {
+ return wrap(unwrap(this).form);
+ }
+ });
+ registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement, document.createElement("option"));
+ function Option(text, value, defaultSelected, selected) {
+ if (!(this instanceof Option)) {
+ throw new TypeError("DOM object constructor cannot be called as a function.");
+ }
+ var node = unwrap(document.createElement("option"));
+ HTMLElement.call(this, node);
+ rewrap(node, this);
+ if (text !== undefined) node.text = text;
+ if (value !== undefined) node.setAttribute("value", value);
+ if (defaultSelected === true) node.setAttribute("selected", "");
+ node.selected = selected === true;
+ }
+ Option.prototype = HTMLOptionElement.prototype;
+ scope.wrappers.HTMLOptionElement = HTMLOptionElement;
+ scope.wrappers.Option = Option;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var OriginalHTMLSelectElement = window.HTMLSelectElement;
+ function HTMLSelectElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLSelectElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLSelectElement.prototype, {
+ add: function(element, before) {
+ if (typeof before === "object") before = unwrap(before);
+ unwrap(this).add(unwrap(element), before);
+ },
+ remove: function(indexOrNode) {
+ if (indexOrNode === undefined) {
+ HTMLElement.prototype.remove.call(this);
+ return;
+ }
+ if (typeof indexOrNode === "object") indexOrNode = unwrap(indexOrNode);
+ unwrap(this).remove(indexOrNode);
+ },
+ get form() {
+ return wrap(unwrap(this).form);
+ }
+ });
+ registerWrapper(OriginalHTMLSelectElement, HTMLSelectElement, document.createElement("select"));
+ scope.wrappers.HTMLSelectElement = HTMLSelectElement;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var wrapHTMLCollection = scope.wrapHTMLCollection;
+ var OriginalHTMLTableElement = window.HTMLTableElement;
+ function HTMLTableElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLTableElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLTableElement.prototype, {
+ get caption() {
+ return wrap(unwrap(this).caption);
+ },
+ createCaption: function() {
+ return wrap(unwrap(this).createCaption());
+ },
+ get tHead() {
+ return wrap(unwrap(this).tHead);
+ },
+ createTHead: function() {
+ return wrap(unwrap(this).createTHead());
+ },
+ createTFoot: function() {
+ return wrap(unwrap(this).createTFoot());
+ },
+ get tFoot() {
+ return wrap(unwrap(this).tFoot);
+ },
+ get tBodies() {
+ return wrapHTMLCollection(unwrap(this).tBodies);
+ },
+ createTBody: function() {
+ return wrap(unwrap(this).createTBody());
+ },
+ get rows() {
+ return wrapHTMLCollection(unwrap(this).rows);
+ },
+ insertRow: function(index) {
+ return wrap(unwrap(this).insertRow(index));
+ }
+ });
+ registerWrapper(OriginalHTMLTableElement, HTMLTableElement, document.createElement("table"));
+ scope.wrappers.HTMLTableElement = HTMLTableElement;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var wrapHTMLCollection = scope.wrapHTMLCollection;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var OriginalHTMLTableSectionElement = window.HTMLTableSectionElement;
+ function HTMLTableSectionElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLTableSectionElement.prototype, {
+ constructor: HTMLTableSectionElement,
+ get rows() {
+ return wrapHTMLCollection(unwrap(this).rows);
+ },
+ insertRow: function(index) {
+ return wrap(unwrap(this).insertRow(index));
+ }
+ });
+ registerWrapper(OriginalHTMLTableSectionElement, HTMLTableSectionElement, document.createElement("thead"));
+ scope.wrappers.HTMLTableSectionElement = HTMLTableSectionElement;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var wrapHTMLCollection = scope.wrapHTMLCollection;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var OriginalHTMLTableRowElement = window.HTMLTableRowElement;
+ function HTMLTableRowElement(node) {
+ HTMLElement.call(this, node);
+ }
+ HTMLTableRowElement.prototype = Object.create(HTMLElement.prototype);
+ mixin(HTMLTableRowElement.prototype, {
+ get cells() {
+ return wrapHTMLCollection(unwrap(this).cells);
+ },
+ insertCell: function(index) {
+ return wrap(unwrap(this).insertCell(index));
+ }
+ });
+ registerWrapper(OriginalHTMLTableRowElement, HTMLTableRowElement, document.createElement("tr"));
+ scope.wrappers.HTMLTableRowElement = HTMLTableRowElement;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLContentElement = scope.wrappers.HTMLContentElement;
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
+ var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var OriginalHTMLUnknownElement = window.HTMLUnknownElement;
+ function HTMLUnknownElement(node) {
+ switch (node.localName) {
+ case "content":
+ return new HTMLContentElement(node);
+
+ case "shadow":
+ return new HTMLShadowElement(node);
+
+ case "template":
+ return new HTMLTemplateElement(node);
+ }
+ HTMLElement.call(this, node);
+ }
+ HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);
+ registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);
+ scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var Element = scope.wrappers.Element;
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var registerObject = scope.registerObject;
+ var defineWrapGetter = scope.defineWrapGetter;
+ var SVG_NS = "http://www.w3.org/2000/svg";
+ var svgTitleElement = document.createElementNS(SVG_NS, "title");
+ var SVGTitleElement = registerObject(svgTitleElement);
+ var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;
+ if (!("classList" in svgTitleElement)) {
+ var descr = Object.getOwnPropertyDescriptor(Element.prototype, "classList");
+ Object.defineProperty(HTMLElement.prototype, "classList", descr);
+ delete Element.prototype.classList;
+ }
+ defineWrapGetter(SVGElement, "ownerSVGElement");
+ scope.wrappers.SVGElement = SVGElement;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var OriginalSVGUseElement = window.SVGUseElement;
+ var SVG_NS = "http://www.w3.org/2000/svg";
+ var gWrapper = wrap(document.createElementNS(SVG_NS, "g"));
+ var useElement = document.createElementNS(SVG_NS, "use");
+ var SVGGElement = gWrapper.constructor;
+ var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);
+ var parentInterface = parentInterfacePrototype.constructor;
+ function SVGUseElement(impl) {
+ parentInterface.call(this, impl);
+ }
+ SVGUseElement.prototype = Object.create(parentInterfacePrototype);
+ if ("instanceRoot" in useElement) {
+ mixin(SVGUseElement.prototype, {
+ get instanceRoot() {
+ return wrap(unwrap(this).instanceRoot);
+ },
+ get animatedInstanceRoot() {
+ return wrap(unwrap(this).animatedInstanceRoot);
+ }
+ });
+ }
+ registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);
+ scope.wrappers.SVGUseElement = SVGUseElement;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var EventTarget = scope.wrappers.EventTarget;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var wrap = scope.wrap;
+ var OriginalSVGElementInstance = window.SVGElementInstance;
+ if (!OriginalSVGElementInstance) return;
+ function SVGElementInstance(impl) {
+ EventTarget.call(this, impl);
+ }
+ SVGElementInstance.prototype = Object.create(EventTarget.prototype);
+ mixin(SVGElementInstance.prototype, {
+ get correspondingElement() {
+ return wrap(unsafeUnwrap(this).correspondingElement);
+ },
+ get correspondingUseElement() {
+ return wrap(unsafeUnwrap(this).correspondingUseElement);
+ },
+ get parentNode() {
+ return wrap(unsafeUnwrap(this).parentNode);
+ },
+ get childNodes() {
+ throw new Error("Not implemented");
+ },
+ get firstChild() {
+ return wrap(unsafeUnwrap(this).firstChild);
+ },
+ get lastChild() {
+ return wrap(unsafeUnwrap(this).lastChild);
+ },
+ get previousSibling() {
+ return wrap(unsafeUnwrap(this).previousSibling);
+ },
+ get nextSibling() {
+ return wrap(unsafeUnwrap(this).nextSibling);
+ }
+ });
+ registerWrapper(OriginalSVGElementInstance, SVGElementInstance);
+ scope.wrappers.SVGElementInstance = SVGElementInstance;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var wrap = scope.wrap;
+ var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
+ function CanvasRenderingContext2D(impl) {
+ setWrapper(impl, this);
+ }
+ mixin(CanvasRenderingContext2D.prototype, {
+ get canvas() {
+ return wrap(unsafeUnwrap(this).canvas);
+ },
+ drawImage: function() {
+ arguments[0] = unwrapIfNeeded(arguments[0]);
+ unsafeUnwrap(this).drawImage.apply(unsafeUnwrap(this), arguments);
+ },
+ createPattern: function() {
+ arguments[0] = unwrap(arguments[0]);
+ return unsafeUnwrap(this).createPattern.apply(unsafeUnwrap(this), arguments);
+ }
+ });
+ registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D, document.createElement("canvas").getContext("2d"));
+ scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var wrap = scope.wrap;
+ var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
+ if (!OriginalWebGLRenderingContext) return;
+ function WebGLRenderingContext(impl) {
+ setWrapper(impl, this);
+ }
+ mixin(WebGLRenderingContext.prototype, {
+ get canvas() {
+ return wrap(unsafeUnwrap(this).canvas);
+ },
+ texImage2D: function() {
+ arguments[5] = unwrapIfNeeded(arguments[5]);
+ unsafeUnwrap(this).texImage2D.apply(unsafeUnwrap(this), arguments);
+ },
+ texSubImage2D: function() {
+ arguments[6] = unwrapIfNeeded(arguments[6]);
+ unsafeUnwrap(this).texSubImage2D.apply(unsafeUnwrap(this), arguments);
+ }
+ });
+ var instanceProperties = /WebKit/.test(navigator.userAgent) ? {
+ drawingBufferHeight: null,
+ drawingBufferWidth: null
+ } : {};
+ registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext, instanceProperties);
+ scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var GetElementsByInterface = scope.GetElementsByInterface;
+ var NonElementParentNodeInterface = scope.NonElementParentNodeInterface;
+ var ParentNodeInterface = scope.ParentNodeInterface;
+ var SelectorsInterface = scope.SelectorsInterface;
+ var mixin = scope.mixin;
+ var registerObject = scope.registerObject;
+ var DocumentFragment = registerObject(document.createDocumentFragment());
+ mixin(DocumentFragment.prototype, ParentNodeInterface);
+ mixin(DocumentFragment.prototype, SelectorsInterface);
+ mixin(DocumentFragment.prototype, GetElementsByInterface);
+ mixin(DocumentFragment.prototype, NonElementParentNodeInterface);
+ var Comment = registerObject(document.createComment(""));
+ scope.wrappers.Comment = Comment;
+ scope.wrappers.DocumentFragment = DocumentFragment;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var DocumentFragment = scope.wrappers.DocumentFragment;
+ var TreeScope = scope.TreeScope;
+ var elementFromPoint = scope.elementFromPoint;
+ var getInnerHTML = scope.getInnerHTML;
+ var getTreeScope = scope.getTreeScope;
+ var mixin = scope.mixin;
+ var rewrap = scope.rewrap;
+ var setInnerHTML = scope.setInnerHTML;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var shadowHostTable = new WeakMap();
+ var nextOlderShadowTreeTable = new WeakMap();
+ function ShadowRoot(hostWrapper) {
+ var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment());
+ DocumentFragment.call(this, node);
+ rewrap(node, this);
+ var oldShadowRoot = hostWrapper.shadowRoot;
+ nextOlderShadowTreeTable.set(this, oldShadowRoot);
+ this.treeScope_ = new TreeScope(this, getTreeScope(oldShadowRoot || hostWrapper));
+ shadowHostTable.set(this, hostWrapper);
+ }
+ ShadowRoot.prototype = Object.create(DocumentFragment.prototype);
+ mixin(ShadowRoot.prototype, {
+ constructor: ShadowRoot,
+ get innerHTML() {
+ return getInnerHTML(this);
+ },
+ set innerHTML(value) {
+ setInnerHTML(this, value);
+ this.invalidateShadowRenderer();
+ },
+ get olderShadowRoot() {
+ return nextOlderShadowTreeTable.get(this) || null;
+ },
+ get host() {
+ return shadowHostTable.get(this) || null;
+ },
+ invalidateShadowRenderer: function() {
+ return shadowHostTable.get(this).invalidateShadowRenderer();
+ },
+ elementFromPoint: function(x, y) {
+ return elementFromPoint(this, this.ownerDocument, x, y);
+ }
+ });
+ scope.wrappers.ShadowRoot = ShadowRoot;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var wrap = scope.wrap;
+ var getTreeScope = scope.getTreeScope;
+ var OriginalRange = window.Range;
+ var ShadowRoot = scope.wrappers.ShadowRoot;
+ function getHost(node) {
+ var root = getTreeScope(node).root;
+ if (root instanceof ShadowRoot) {
+ return root.host;
+ }
+ return null;
+ }
+ function hostNodeToShadowNode(refNode, offset) {
+ if (refNode.shadowRoot) {
+ offset = Math.min(refNode.childNodes.length - 1, offset);
+ var child = refNode.childNodes[offset];
+ if (child) {
+ var insertionPoint = scope.getDestinationInsertionPoints(child);
+ if (insertionPoint.length > 0) {
+ var parentNode = insertionPoint[0].parentNode;
+ if (parentNode.nodeType == Node.ELEMENT_NODE) {
+ refNode = parentNode;
+ }
+ }
+ }
+ }
+ return refNode;
+ }
+ function shadowNodeToHostNode(node) {
+ node = wrap(node);
+ return getHost(node) || node;
+ }
+ function Range(impl) {
+ setWrapper(impl, this);
+ }
+ Range.prototype = {
+ get startContainer() {
+ return shadowNodeToHostNode(unsafeUnwrap(this).startContainer);
+ },
+ get endContainer() {
+ return shadowNodeToHostNode(unsafeUnwrap(this).endContainer);
+ },
+ get commonAncestorContainer() {
+ return shadowNodeToHostNode(unsafeUnwrap(this).commonAncestorContainer);
+ },
+ setStart: function(refNode, offset) {
+ refNode = hostNodeToShadowNode(refNode, offset);
+ unsafeUnwrap(this).setStart(unwrapIfNeeded(refNode), offset);
+ },
+ setEnd: function(refNode, offset) {
+ refNode = hostNodeToShadowNode(refNode, offset);
+ unsafeUnwrap(this).setEnd(unwrapIfNeeded(refNode), offset);
+ },
+ setStartBefore: function(refNode) {
+ unsafeUnwrap(this).setStartBefore(unwrapIfNeeded(refNode));
+ },
+ setStartAfter: function(refNode) {
+ unsafeUnwrap(this).setStartAfter(unwrapIfNeeded(refNode));
+ },
+ setEndBefore: function(refNode) {
+ unsafeUnwrap(this).setEndBefore(unwrapIfNeeded(refNode));
+ },
+ setEndAfter: function(refNode) {
+ unsafeUnwrap(this).setEndAfter(unwrapIfNeeded(refNode));
+ },
+ selectNode: function(refNode) {
+ unsafeUnwrap(this).selectNode(unwrapIfNeeded(refNode));
+ },
+ selectNodeContents: function(refNode) {
+ unsafeUnwrap(this).selectNodeContents(unwrapIfNeeded(refNode));
+ },
+ compareBoundaryPoints: function(how, sourceRange) {
+ return unsafeUnwrap(this).compareBoundaryPoints(how, unwrap(sourceRange));
+ },
+ extractContents: function() {
+ return wrap(unsafeUnwrap(this).extractContents());
+ },
+ cloneContents: function() {
+ return wrap(unsafeUnwrap(this).cloneContents());
+ },
+ insertNode: function(node) {
+ unsafeUnwrap(this).insertNode(unwrapIfNeeded(node));
+ },
+ surroundContents: function(newParent) {
+ unsafeUnwrap(this).surroundContents(unwrapIfNeeded(newParent));
+ },
+ cloneRange: function() {
+ return wrap(unsafeUnwrap(this).cloneRange());
+ },
+ isPointInRange: function(node, offset) {
+ return unsafeUnwrap(this).isPointInRange(unwrapIfNeeded(node), offset);
+ },
+ comparePoint: function(node, offset) {
+ return unsafeUnwrap(this).comparePoint(unwrapIfNeeded(node), offset);
+ },
+ intersectsNode: function(node) {
+ return unsafeUnwrap(this).intersectsNode(unwrapIfNeeded(node));
+ },
+ toString: function() {
+ return unsafeUnwrap(this).toString();
+ }
+ };
+ if (OriginalRange.prototype.createContextualFragment) {
+ Range.prototype.createContextualFragment = function(html) {
+ return wrap(unsafeUnwrap(this).createContextualFragment(html));
+ };
+ }
+ registerWrapper(window.Range, Range, document.createRange());
+ scope.wrappers.Range = Range;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var Element = scope.wrappers.Element;
+ var HTMLContentElement = scope.wrappers.HTMLContentElement;
+ var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
+ var Node = scope.wrappers.Node;
+ var ShadowRoot = scope.wrappers.ShadowRoot;
+ var assert = scope.assert;
+ var getTreeScope = scope.getTreeScope;
+ var mixin = scope.mixin;
+ var oneOf = scope.oneOf;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var ArraySplice = scope.ArraySplice;
+ function updateWrapperUpAndSideways(wrapper) {
+ wrapper.previousSibling_ = wrapper.previousSibling;
+ wrapper.nextSibling_ = wrapper.nextSibling;
+ wrapper.parentNode_ = wrapper.parentNode;
+ }
+ function updateWrapperDown(wrapper) {
+ wrapper.firstChild_ = wrapper.firstChild;
+ wrapper.lastChild_ = wrapper.lastChild;
+ }
+ function updateAllChildNodes(parentNodeWrapper) {
+ assert(parentNodeWrapper instanceof Node);
+ for (var childWrapper = parentNodeWrapper.firstChild; childWrapper; childWrapper = childWrapper.nextSibling) {
+ updateWrapperUpAndSideways(childWrapper);
+ }
+ updateWrapperDown(parentNodeWrapper);
+ }
+ function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {
+ var parentNode = unwrap(parentNodeWrapper);
+ var newChild = unwrap(newChildWrapper);
+ var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;
+ remove(newChildWrapper);
+ updateWrapperUpAndSideways(newChildWrapper);
+ if (!refChildWrapper) {
+ parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;
+ if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild) parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;
+ var lastChildWrapper = wrap(parentNode.lastChild);
+ if (lastChildWrapper) lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;
+ } else {
+ if (parentNodeWrapper.firstChild === refChildWrapper) parentNodeWrapper.firstChild_ = refChildWrapper;
+ refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;
+ }
+ scope.originalInsertBefore.call(parentNode, newChild, refChild);
+ }
+ function remove(nodeWrapper) {
+ var node = unwrap(nodeWrapper);
+ var parentNode = node.parentNode;
+ if (!parentNode) return;
+ var parentNodeWrapper = wrap(parentNode);
+ updateWrapperUpAndSideways(nodeWrapper);
+ if (nodeWrapper.previousSibling) nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;
+ if (nodeWrapper.nextSibling) nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;
+ if (parentNodeWrapper.lastChild === nodeWrapper) parentNodeWrapper.lastChild_ = nodeWrapper;
+ if (parentNodeWrapper.firstChild === nodeWrapper) parentNodeWrapper.firstChild_ = nodeWrapper;
+ scope.originalRemoveChild.call(parentNode, node);
+ }
+ var distributedNodesTable = new WeakMap();
+ var destinationInsertionPointsTable = new WeakMap();
+ var rendererForHostTable = new WeakMap();
+ function resetDistributedNodes(insertionPoint) {
+ distributedNodesTable.set(insertionPoint, []);
+ }
+ function getDistributedNodes(insertionPoint) {
+ var rv = distributedNodesTable.get(insertionPoint);
+ if (!rv) distributedNodesTable.set(insertionPoint, rv = []);
+ return rv;
+ }
+ function getChildNodesSnapshot(node) {
+ var result = [], i = 0;
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ result[i++] = child;
+ }
+ return result;
+ }
+ var request = oneOf(window, [ "requestAnimationFrame", "mozRequestAnimationFrame", "webkitRequestAnimationFrame", "setTimeout" ]);
+ var pendingDirtyRenderers = [];
+ var renderTimer;
+ function renderAllPending() {
+ for (var i = 0; i < pendingDirtyRenderers.length; i++) {
+ var renderer = pendingDirtyRenderers[i];
+ var parentRenderer = renderer.parentRenderer;
+ if (parentRenderer && parentRenderer.dirty) continue;
+ renderer.render();
+ }
+ pendingDirtyRenderers = [];
+ }
+ function handleRequestAnimationFrame() {
+ renderTimer = null;
+ renderAllPending();
+ }
+ function getRendererForHost(host) {
+ var renderer = rendererForHostTable.get(host);
+ if (!renderer) {
+ renderer = new ShadowRenderer(host);
+ rendererForHostTable.set(host, renderer);
+ }
+ return renderer;
+ }
+ function getShadowRootAncestor(node) {
+ var root = getTreeScope(node).root;
+ if (root instanceof ShadowRoot) return root;
+ return null;
+ }
+ function getRendererForShadowRoot(shadowRoot) {
+ return getRendererForHost(shadowRoot.host);
+ }
+ var spliceDiff = new ArraySplice();
+ spliceDiff.equals = function(renderNode, rawNode) {
+ return unwrap(renderNode.node) === rawNode;
+ };
+ function RenderNode(node) {
+ this.skip = false;
+ this.node = node;
+ this.childNodes = [];
+ }
+ RenderNode.prototype = {
+ append: function(node) {
+ var rv = new RenderNode(node);
+ this.childNodes.push(rv);
+ return rv;
+ },
+ sync: function(opt_added) {
+ if (this.skip) return;
+ var nodeWrapper = this.node;
+ var newChildren = this.childNodes;
+ var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));
+ var added = opt_added || new WeakMap();
+ var splices = spliceDiff.calculateSplices(newChildren, oldChildren);
+ var newIndex = 0, oldIndex = 0;
+ var lastIndex = 0;
+ for (var i = 0; i < splices.length; i++) {
+ var splice = splices[i];
+ for (;lastIndex < splice.index; lastIndex++) {
+ oldIndex++;
+ newChildren[newIndex++].sync(added);
+ }
+ var removedCount = splice.removed.length;
+ for (var j = 0; j < removedCount; j++) {
+ var wrapper = wrap(oldChildren[oldIndex++]);
+ if (!added.get(wrapper)) remove(wrapper);
+ }
+ var addedCount = splice.addedCount;
+ var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);
+ for (var j = 0; j < addedCount; j++) {
+ var newChildRenderNode = newChildren[newIndex++];
+ var newChildWrapper = newChildRenderNode.node;
+ insertBefore(nodeWrapper, newChildWrapper, refNode);
+ added.set(newChildWrapper, true);
+ newChildRenderNode.sync(added);
+ }
+ lastIndex += addedCount;
+ }
+ for (var i = lastIndex; i < newChildren.length; i++) {
+ newChildren[i].sync(added);
+ }
+ }
+ };
+ function ShadowRenderer(host) {
+ this.host = host;
+ this.dirty = false;
+ this.invalidateAttributes();
+ this.associateNode(host);
+ }
+ ShadowRenderer.prototype = {
+ render: function(opt_renderNode) {
+ if (!this.dirty) return;
+ this.invalidateAttributes();
+ var host = this.host;
+ this.distribution(host);
+ var renderNode = opt_renderNode || new RenderNode(host);
+ this.buildRenderTree(renderNode, host);
+ var topMostRenderer = !opt_renderNode;
+ if (topMostRenderer) renderNode.sync();
+ this.dirty = false;
+ },
+ get parentRenderer() {
+ return getTreeScope(this.host).renderer;
+ },
+ invalidate: function() {
+ if (!this.dirty) {
+ this.dirty = true;
+ var parentRenderer = this.parentRenderer;
+ if (parentRenderer) parentRenderer.invalidate();
+ pendingDirtyRenderers.push(this);
+ if (renderTimer) return;
+ renderTimer = window[request](handleRequestAnimationFrame, 0);
+ }
+ },
+ distribution: function(root) {
+ this.resetAllSubtrees(root);
+ this.distributionResolution(root);
+ },
+ resetAll: function(node) {
+ if (isInsertionPoint(node)) resetDistributedNodes(node); else resetDestinationInsertionPoints(node);
+ this.resetAllSubtrees(node);
+ },
+ resetAllSubtrees: function(node) {
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ this.resetAll(child);
+ }
+ if (node.shadowRoot) this.resetAll(node.shadowRoot);
+ if (node.olderShadowRoot) this.resetAll(node.olderShadowRoot);
+ },
+ distributionResolution: function(node) {
+ if (isShadowHost(node)) {
+ var shadowHost = node;
+ var pool = poolPopulation(shadowHost);
+ var shadowTrees = getShadowTrees(shadowHost);
+ for (var i = 0; i < shadowTrees.length; i++) {
+ this.poolDistribution(shadowTrees[i], pool);
+ }
+ for (var i = shadowTrees.length - 1; i >= 0; i--) {
+ var shadowTree = shadowTrees[i];
+ var shadow = getShadowInsertionPoint(shadowTree);
+ if (shadow) {
+ var olderShadowRoot = shadowTree.olderShadowRoot;
+ if (olderShadowRoot) {
+ pool = poolPopulation(olderShadowRoot);
+ }
+ for (var j = 0; j < pool.length; j++) {
+ destributeNodeInto(pool[j], shadow);
+ }
+ }
+ this.distributionResolution(shadowTree);
+ }
+ }
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ this.distributionResolution(child);
+ }
+ },
+ poolDistribution: function(node, pool) {
+ if (node instanceof HTMLShadowElement) return;
+ if (node instanceof HTMLContentElement) {
+ var content = node;
+ this.updateDependentAttributes(content.getAttribute("select"));
+ var anyDistributed = false;
+ for (var i = 0; i < pool.length; i++) {
+ var node = pool[i];
+ if (!node) continue;
+ if (matches(node, content)) {
+ destributeNodeInto(node, content);
+ pool[i] = undefined;
+ anyDistributed = true;
+ }
+ }
+ if (!anyDistributed) {
+ for (var child = content.firstChild; child; child = child.nextSibling) {
+ destributeNodeInto(child, content);
+ }
+ }
+ return;
+ }
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ this.poolDistribution(child, pool);
+ }
+ },
+ buildRenderTree: function(renderNode, node) {
+ var children = this.compose(node);
+ for (var i = 0; i < children.length; i++) {
+ var child = children[i];
+ var childRenderNode = renderNode.append(child);
+ this.buildRenderTree(childRenderNode, child);
+ }
+ if (isShadowHost(node)) {
+ var renderer = getRendererForHost(node);
+ renderer.dirty = false;
+ }
+ },
+ compose: function(node) {
+ var children = [];
+ var p = node.shadowRoot || node;
+ for (var child = p.firstChild; child; child = child.nextSibling) {
+ if (isInsertionPoint(child)) {
+ this.associateNode(p);
+ var distributedNodes = getDistributedNodes(child);
+ for (var j = 0; j < distributedNodes.length; j++) {
+ var distributedNode = distributedNodes[j];
+ if (isFinalDestination(child, distributedNode)) children.push(distributedNode);
+ }
+ } else {
+ children.push(child);
+ }
+ }
+ return children;
+ },
+ invalidateAttributes: function() {
+ this.attributes = Object.create(null);
+ },
+ updateDependentAttributes: function(selector) {
+ if (!selector) return;
+ var attributes = this.attributes;
+ if (/\.\w+/.test(selector)) attributes["class"] = true;
+ if (/#\w+/.test(selector)) attributes["id"] = true;
+ selector.replace(/\[\s*([^\s=\|~\]]+)/g, function(_, name) {
+ attributes[name] = true;
+ });
+ },
+ dependsOnAttribute: function(name) {
+ return this.attributes[name];
+ },
+ associateNode: function(node) {
+ unsafeUnwrap(node).polymerShadowRenderer_ = this;
+ }
+ };
+ function poolPopulation(node) {
+ var pool = [];
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ if (isInsertionPoint(child)) {
+ pool.push.apply(pool, getDistributedNodes(child));
+ } else {
+ pool.push(child);
+ }
+ }
+ return pool;
+ }
+ function getShadowInsertionPoint(node) {
+ if (node instanceof HTMLShadowElement) return node;
+ if (node instanceof HTMLContentElement) return null;
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ var res = getShadowInsertionPoint(child);
+ if (res) return res;
+ }
+ return null;
+ }
+ function destributeNodeInto(child, insertionPoint) {
+ getDistributedNodes(insertionPoint).push(child);
+ var points = destinationInsertionPointsTable.get(child);
+ if (!points) destinationInsertionPointsTable.set(child, [ insertionPoint ]); else points.push(insertionPoint);
+ }
+ function getDestinationInsertionPoints(node) {
+ return destinationInsertionPointsTable.get(node);
+ }
+ function resetDestinationInsertionPoints(node) {
+ destinationInsertionPointsTable.set(node, undefined);
+ }
+ var selectorStartCharRe = /^(:not\()?[*.#[a-zA-Z_|]/;
+ function matches(node, contentElement) {
+ var select = contentElement.getAttribute("select");
+ if (!select) return true;
+ select = select.trim();
+ if (!select) return true;
+ if (!(node instanceof Element)) return false;
+ if (!selectorStartCharRe.test(select)) return false;
+ try {
+ return node.matches(select);
+ } catch (ex) {
+ return false;
+ }
+ }
+ function isFinalDestination(insertionPoint, node) {
+ var points = getDestinationInsertionPoints(node);
+ return points && points[points.length - 1] === insertionPoint;
+ }
+ function isInsertionPoint(node) {
+ return node instanceof HTMLContentElement || node instanceof HTMLShadowElement;
+ }
+ function isShadowHost(shadowHost) {
+ return shadowHost.shadowRoot;
+ }
+ function getShadowTrees(host) {
+ var trees = [];
+ for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {
+ trees.push(tree);
+ }
+ return trees;
+ }
+ function render(host) {
+ new ShadowRenderer(host).render();
+ }
+ Node.prototype.invalidateShadowRenderer = function(force) {
+ var renderer = unsafeUnwrap(this).polymerShadowRenderer_;
+ if (renderer) {
+ renderer.invalidate();
+ return true;
+ }
+ return false;
+ };
+ HTMLContentElement.prototype.getDistributedNodes = HTMLShadowElement.prototype.getDistributedNodes = function() {
+ renderAllPending();
+ return getDistributedNodes(this);
+ };
+ Element.prototype.getDestinationInsertionPoints = function() {
+ renderAllPending();
+ return getDestinationInsertionPoints(this) || [];
+ };
+ HTMLContentElement.prototype.nodeIsInserted_ = HTMLShadowElement.prototype.nodeIsInserted_ = function() {
+ this.invalidateShadowRenderer();
+ var shadowRoot = getShadowRootAncestor(this);
+ var renderer;
+ if (shadowRoot) renderer = getRendererForShadowRoot(shadowRoot);
+ unsafeUnwrap(this).polymerShadowRenderer_ = renderer;
+ if (renderer) renderer.invalidate();
+ };
+ scope.getRendererForHost = getRendererForHost;
+ scope.getShadowTrees = getShadowTrees;
+ scope.renderAllPending = renderAllPending;
+ scope.getDestinationInsertionPoints = getDestinationInsertionPoints;
+ scope.visual = {
+ insertBefore: insertBefore,
+ remove: remove
+ };
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var HTMLElement = scope.wrappers.HTMLElement;
+ var assert = scope.assert;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var elementsWithFormProperty = [ "HTMLButtonElement", "HTMLFieldSetElement", "HTMLInputElement", "HTMLKeygenElement", "HTMLLabelElement", "HTMLLegendElement", "HTMLObjectElement", "HTMLOutputElement", "HTMLTextAreaElement" ];
+ function createWrapperConstructor(name) {
+ if (!window[name]) return;
+ assert(!scope.wrappers[name]);
+ var GeneratedWrapper = function(node) {
+ HTMLElement.call(this, node);
+ };
+ GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);
+ mixin(GeneratedWrapper.prototype, {
+ get form() {
+ return wrap(unwrap(this).form);
+ }
+ });
+ registerWrapper(window[name], GeneratedWrapper, document.createElement(name.slice(4, -7)));
+ scope.wrappers[name] = GeneratedWrapper;
+ }
+ elementsWithFormProperty.forEach(createWrapperConstructor);
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var wrap = scope.wrap;
+ var OriginalSelection = window.Selection;
+ function Selection(impl) {
+ setWrapper(impl, this);
+ }
+ Selection.prototype = {
+ get anchorNode() {
+ return wrap(unsafeUnwrap(this).anchorNode);
+ },
+ get focusNode() {
+ return wrap(unsafeUnwrap(this).focusNode);
+ },
+ addRange: function(range) {
+ unsafeUnwrap(this).addRange(unwrapIfNeeded(range));
+ },
+ collapse: function(node, index) {
+ unsafeUnwrap(this).collapse(unwrapIfNeeded(node), index);
+ },
+ containsNode: function(node, allowPartial) {
+ return unsafeUnwrap(this).containsNode(unwrapIfNeeded(node), allowPartial);
+ },
+ getRangeAt: function(index) {
+ return wrap(unsafeUnwrap(this).getRangeAt(index));
+ },
+ removeRange: function(range) {
+ unsafeUnwrap(this).removeRange(unwrap(range));
+ },
+ selectAllChildren: function(node) {
+ unsafeUnwrap(this).selectAllChildren(unwrapIfNeeded(node));
+ },
+ toString: function() {
+ return unsafeUnwrap(this).toString();
+ }
+ };
+ if (OriginalSelection.prototype.extend) {
+ Selection.prototype.extend = function(node, offset) {
+ unsafeUnwrap(this).extend(unwrapIfNeeded(node), offset);
+ };
+ }
+ registerWrapper(window.Selection, Selection, window.getSelection());
+ scope.wrappers.Selection = Selection;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var wrap = scope.wrap;
+ var OriginalTreeWalker = window.TreeWalker;
+ function TreeWalker(impl) {
+ setWrapper(impl, this);
+ }
+ TreeWalker.prototype = {
+ get root() {
+ return wrap(unsafeUnwrap(this).root);
+ },
+ get currentNode() {
+ return wrap(unsafeUnwrap(this).currentNode);
+ },
+ set currentNode(node) {
+ unsafeUnwrap(this).currentNode = unwrapIfNeeded(node);
+ },
+ get filter() {
+ return unsafeUnwrap(this).filter;
+ },
+ parentNode: function() {
+ return wrap(unsafeUnwrap(this).parentNode());
+ },
+ firstChild: function() {
+ return wrap(unsafeUnwrap(this).firstChild());
+ },
+ lastChild: function() {
+ return wrap(unsafeUnwrap(this).lastChild());
+ },
+ previousSibling: function() {
+ return wrap(unsafeUnwrap(this).previousSibling());
+ },
+ previousNode: function() {
+ return wrap(unsafeUnwrap(this).previousNode());
+ },
+ nextNode: function() {
+ return wrap(unsafeUnwrap(this).nextNode());
+ }
+ };
+ registerWrapper(OriginalTreeWalker, TreeWalker);
+ scope.wrappers.TreeWalker = TreeWalker;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var GetElementsByInterface = scope.GetElementsByInterface;
+ var Node = scope.wrappers.Node;
+ var ParentNodeInterface = scope.ParentNodeInterface;
+ var NonElementParentNodeInterface = scope.NonElementParentNodeInterface;
+ var Selection = scope.wrappers.Selection;
+ var SelectorsInterface = scope.SelectorsInterface;
+ var ShadowRoot = scope.wrappers.ShadowRoot;
+ var TreeScope = scope.TreeScope;
+ var cloneNode = scope.cloneNode;
+ var defineWrapGetter = scope.defineWrapGetter;
+ var elementFromPoint = scope.elementFromPoint;
+ var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
+ var matchesNames = scope.matchesNames;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var renderAllPending = scope.renderAllPending;
+ var rewrap = scope.rewrap;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var unwrap = scope.unwrap;
+ var wrap = scope.wrap;
+ var wrapEventTargetMethods = scope.wrapEventTargetMethods;
+ var wrapNodeList = scope.wrapNodeList;
+ var implementationTable = new WeakMap();
+ function Document(node) {
+ Node.call(this, node);
+ this.treeScope_ = new TreeScope(this, null);
+ }
+ Document.prototype = Object.create(Node.prototype);
+ defineWrapGetter(Document, "documentElement");
+ defineWrapGetter(Document, "body");
+ defineWrapGetter(Document, "head");
+ function wrapMethod(name) {
+ var original = document[name];
+ Document.prototype[name] = function() {
+ return wrap(original.apply(unsafeUnwrap(this), arguments));
+ };
+ }
+ [ "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode" ].forEach(wrapMethod);
+ var originalAdoptNode = document.adoptNode;
+ function adoptNodeNoRemove(node, doc) {
+ originalAdoptNode.call(unsafeUnwrap(doc), unwrap(node));
+ adoptSubtree(node, doc);
+ }
+ function adoptSubtree(node, doc) {
+ if (node.shadowRoot) doc.adoptNode(node.shadowRoot);
+ if (node instanceof ShadowRoot) adoptOlderShadowRoots(node, doc);
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ adoptSubtree(child, doc);
+ }
+ }
+ function adoptOlderShadowRoots(shadowRoot, doc) {
+ var oldShadowRoot = shadowRoot.olderShadowRoot;
+ if (oldShadowRoot) doc.adoptNode(oldShadowRoot);
+ }
+ var originalGetSelection = document.getSelection;
+ mixin(Document.prototype, {
+ adoptNode: function(node) {
+ if (node.parentNode) node.parentNode.removeChild(node);
+ adoptNodeNoRemove(node, this);
+ return node;
+ },
+ elementFromPoint: function(x, y) {
+ return elementFromPoint(this, this, x, y);
+ },
+ importNode: function(node, deep) {
+ return cloneNode(node, deep, unsafeUnwrap(this));
+ },
+ getSelection: function() {
+ renderAllPending();
+ return new Selection(originalGetSelection.call(unwrap(this)));
+ },
+ getElementsByName: function(name) {
+ return SelectorsInterface.querySelectorAll.call(this, "[name=" + JSON.stringify(String(name)) + "]");
+ }
+ });
+ var originalCreateTreeWalker = document.createTreeWalker;
+ var TreeWalkerWrapper = scope.wrappers.TreeWalker;
+ Document.prototype.createTreeWalker = function(root, whatToShow, filter, expandEntityReferences) {
+ var newFilter = null;
+ if (filter) {
+ if (filter.acceptNode && typeof filter.acceptNode === "function") {
+ newFilter = {
+ acceptNode: function(node) {
+ return filter.acceptNode(wrap(node));
+ }
+ };
+ } else if (typeof filter === "function") {
+ newFilter = function(node) {
+ return filter(wrap(node));
+ };
+ }
+ }
+ return new TreeWalkerWrapper(originalCreateTreeWalker.call(unwrap(this), unwrap(root), whatToShow, newFilter, expandEntityReferences));
+ };
+ if (document.registerElement) {
+ var originalRegisterElement = document.registerElement;
+ Document.prototype.registerElement = function(tagName, object) {
+ var prototype, extendsOption;
+ if (object !== undefined) {
+ prototype = object.prototype;
+ extendsOption = object.extends;
+ }
+ if (!prototype) prototype = Object.create(HTMLElement.prototype);
+ if (scope.nativePrototypeTable.get(prototype)) {
+ throw new Error("NotSupportedError");
+ }
+ var proto = Object.getPrototypeOf(prototype);
+ var nativePrototype;
+ var prototypes = [];
+ while (proto) {
+ nativePrototype = scope.nativePrototypeTable.get(proto);
+ if (nativePrototype) break;
+ prototypes.push(proto);
+ proto = Object.getPrototypeOf(proto);
+ }
+ if (!nativePrototype) {
+ throw new Error("NotSupportedError");
+ }
+ var newPrototype = Object.create(nativePrototype);
+ for (var i = prototypes.length - 1; i >= 0; i--) {
+ newPrototype = Object.create(newPrototype);
+ }
+ [ "createdCallback", "attachedCallback", "detachedCallback", "attributeChangedCallback" ].forEach(function(name) {
+ var f = prototype[name];
+ if (!f) return;
+ newPrototype[name] = function() {
+ if (!(wrap(this) instanceof CustomElementConstructor)) {
+ rewrap(this);
+ }
+ f.apply(wrap(this), arguments);
+ };
+ });
+ var p = {
+ prototype: newPrototype
+ };
+ if (extendsOption) p.extends = extendsOption;
+ function CustomElementConstructor(node) {
+ if (!node) {
+ if (extendsOption) {
+ return document.createElement(extendsOption, tagName);
+ } else {
+ return document.createElement(tagName);
+ }
+ }
+ setWrapper(node, this);
+ }
+ CustomElementConstructor.prototype = prototype;
+ CustomElementConstructor.prototype.constructor = CustomElementConstructor;
+ scope.constructorTable.set(newPrototype, CustomElementConstructor);
+ scope.nativePrototypeTable.set(prototype, newPrototype);
+ var nativeConstructor = originalRegisterElement.call(unwrap(this), tagName, p);
+ return CustomElementConstructor;
+ };
+ forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "registerElement" ]);
+ }
+ forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement, window.HTMLHtmlElement ], [ "appendChild", "compareDocumentPosition", "contains", "getElementsByClassName", "getElementsByTagName", "getElementsByTagNameNS", "insertBefore", "querySelector", "querySelectorAll", "removeChild", "replaceChild" ]);
+ forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLHeadElement, window.HTMLHtmlElement ], matchesNames);
+ forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "adoptNode", "importNode", "contains", "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "createTreeWalker", "elementFromPoint", "getElementById", "getElementsByName", "getSelection" ]);
+ mixin(Document.prototype, GetElementsByInterface);
+ mixin(Document.prototype, ParentNodeInterface);
+ mixin(Document.prototype, SelectorsInterface);
+ mixin(Document.prototype, NonElementParentNodeInterface);
+ mixin(Document.prototype, {
+ get implementation() {
+ var implementation = implementationTable.get(this);
+ if (implementation) return implementation;
+ implementation = new DOMImplementation(unwrap(this).implementation);
+ implementationTable.set(this, implementation);
+ return implementation;
+ },
+ get defaultView() {
+ return wrap(unwrap(this).defaultView);
+ }
+ });
+ registerWrapper(window.Document, Document, document.implementation.createHTMLDocument(""));
+ if (window.HTMLDocument) registerWrapper(window.HTMLDocument, Document);
+ wrapEventTargetMethods([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement ]);
+ function DOMImplementation(impl) {
+ setWrapper(impl, this);
+ }
+ var originalCreateDocument = document.implementation.createDocument;
+ DOMImplementation.prototype.createDocument = function() {
+ arguments[2] = unwrap(arguments[2]);
+ return wrap(originalCreateDocument.apply(unsafeUnwrap(this), arguments));
+ };
+ function wrapImplMethod(constructor, name) {
+ var original = document.implementation[name];
+ constructor.prototype[name] = function() {
+ return wrap(original.apply(unsafeUnwrap(this), arguments));
+ };
+ }
+ function forwardImplMethod(constructor, name) {
+ var original = document.implementation[name];
+ constructor.prototype[name] = function() {
+ return original.apply(unsafeUnwrap(this), arguments);
+ };
+ }
+ wrapImplMethod(DOMImplementation, "createDocumentType");
+ wrapImplMethod(DOMImplementation, "createHTMLDocument");
+ forwardImplMethod(DOMImplementation, "hasFeature");
+ registerWrapper(window.DOMImplementation, DOMImplementation);
+ forwardMethodsToWrapper([ window.DOMImplementation ], [ "createDocument", "createDocumentType", "createHTMLDocument", "hasFeature" ]);
+ scope.adoptNodeNoRemove = adoptNodeNoRemove;
+ scope.wrappers.DOMImplementation = DOMImplementation;
+ scope.wrappers.Document = Document;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var EventTarget = scope.wrappers.EventTarget;
+ var Selection = scope.wrappers.Selection;
+ var mixin = scope.mixin;
+ var registerWrapper = scope.registerWrapper;
+ var renderAllPending = scope.renderAllPending;
+ var unwrap = scope.unwrap;
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var wrap = scope.wrap;
+ var OriginalWindow = window.Window;
+ var originalGetComputedStyle = window.getComputedStyle;
+ var originalGetDefaultComputedStyle = window.getDefaultComputedStyle;
+ var originalGetSelection = window.getSelection;
+ function Window(impl) {
+ EventTarget.call(this, impl);
+ }
+ Window.prototype = Object.create(EventTarget.prototype);
+ OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {
+ return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);
+ };
+ if (originalGetDefaultComputedStyle) {
+ OriginalWindow.prototype.getDefaultComputedStyle = function(el, pseudo) {
+ return wrap(this || window).getDefaultComputedStyle(unwrapIfNeeded(el), pseudo);
+ };
+ }
+ OriginalWindow.prototype.getSelection = function() {
+ return wrap(this || window).getSelection();
+ };
+ delete window.getComputedStyle;
+ delete window.getDefaultComputedStyle;
+ delete window.getSelection;
+ [ "addEventListener", "removeEventListener", "dispatchEvent" ].forEach(function(name) {
+ OriginalWindow.prototype[name] = function() {
+ var w = wrap(this || window);
+ return w[name].apply(w, arguments);
+ };
+ delete window[name];
+ });
+ mixin(Window.prototype, {
+ getComputedStyle: function(el, pseudo) {
+ renderAllPending();
+ return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
+ },
+ getSelection: function() {
+ renderAllPending();
+ return new Selection(originalGetSelection.call(unwrap(this)));
+ },
+ get document() {
+ return wrap(unwrap(this).document);
+ }
+ });
+ if (originalGetDefaultComputedStyle) {
+ Window.prototype.getDefaultComputedStyle = function(el, pseudo) {
+ renderAllPending();
+ return originalGetDefaultComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
+ };
+ }
+ registerWrapper(OriginalWindow, Window, window);
+ scope.wrappers.Window = Window;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var unwrap = scope.unwrap;
+ var OriginalDataTransfer = window.DataTransfer || window.Clipboard;
+ var OriginalDataTransferSetDragImage = OriginalDataTransfer.prototype.setDragImage;
+ if (OriginalDataTransferSetDragImage) {
+ OriginalDataTransfer.prototype.setDragImage = function(image, x, y) {
+ OriginalDataTransferSetDragImage.call(this, unwrap(image), x, y);
+ };
+ }
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unwrap = scope.unwrap;
+ var OriginalFormData = window.FormData;
+ if (!OriginalFormData) return;
+ function FormData(formElement) {
+ var impl;
+ if (formElement instanceof OriginalFormData) {
+ impl = formElement;
+ } else {
+ impl = new OriginalFormData(formElement && unwrap(formElement));
+ }
+ setWrapper(impl, this);
+ }
+ registerWrapper(OriginalFormData, FormData, new OriginalFormData());
+ scope.wrappers.FormData = FormData;
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var unwrapIfNeeded = scope.unwrapIfNeeded;
+ var originalSend = XMLHttpRequest.prototype.send;
+ XMLHttpRequest.prototype.send = function(obj) {
+ return originalSend.call(this, unwrapIfNeeded(obj));
+ };
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ "use strict";
+ var isWrapperFor = scope.isWrapperFor;
+ var elements = {
+ a: "HTMLAnchorElement",
+ area: "HTMLAreaElement",
+ audio: "HTMLAudioElement",
+ base: "HTMLBaseElement",
+ body: "HTMLBodyElement",
+ br: "HTMLBRElement",
+ button: "HTMLButtonElement",
+ canvas: "HTMLCanvasElement",
+ caption: "HTMLTableCaptionElement",
+ col: "HTMLTableColElement",
+ content: "HTMLContentElement",
+ data: "HTMLDataElement",
+ datalist: "HTMLDataListElement",
+ del: "HTMLModElement",
+ dir: "HTMLDirectoryElement",
+ div: "HTMLDivElement",
+ dl: "HTMLDListElement",
+ embed: "HTMLEmbedElement",
+ fieldset: "HTMLFieldSetElement",
+ font: "HTMLFontElement",
+ form: "HTMLFormElement",
+ frame: "HTMLFrameElement",
+ frameset: "HTMLFrameSetElement",
+ h1: "HTMLHeadingElement",
+ head: "HTMLHeadElement",
+ hr: "HTMLHRElement",
+ html: "HTMLHtmlElement",
+ iframe: "HTMLIFrameElement",
+ img: "HTMLImageElement",
+ input: "HTMLInputElement",
+ keygen: "HTMLKeygenElement",
+ label: "HTMLLabelElement",
+ legend: "HTMLLegendElement",
+ li: "HTMLLIElement",
+ link: "HTMLLinkElement",
+ map: "HTMLMapElement",
+ marquee: "HTMLMarqueeElement",
+ menu: "HTMLMenuElement",
+ menuitem: "HTMLMenuItemElement",
+ meta: "HTMLMetaElement",
+ meter: "HTMLMeterElement",
+ object: "HTMLObjectElement",
+ ol: "HTMLOListElement",
+ optgroup: "HTMLOptGroupElement",
+ option: "HTMLOptionElement",
+ output: "HTMLOutputElement",
+ p: "HTMLParagraphElement",
+ param: "HTMLParamElement",
+ pre: "HTMLPreElement",
+ progress: "HTMLProgressElement",
+ q: "HTMLQuoteElement",
+ script: "HTMLScriptElement",
+ select: "HTMLSelectElement",
+ shadow: "HTMLShadowElement",
+ source: "HTMLSourceElement",
+ span: "HTMLSpanElement",
+ style: "HTMLStyleElement",
+ table: "HTMLTableElement",
+ tbody: "HTMLTableSectionElement",
+ template: "HTMLTemplateElement",
+ textarea: "HTMLTextAreaElement",
+ thead: "HTMLTableSectionElement",
+ time: "HTMLTimeElement",
+ title: "HTMLTitleElement",
+ tr: "HTMLTableRowElement",
+ track: "HTMLTrackElement",
+ ul: "HTMLUListElement",
+ video: "HTMLVideoElement"
+ };
+ function overrideConstructor(tagName) {
+ var nativeConstructorName = elements[tagName];
+ var nativeConstructor = window[nativeConstructorName];
+ if (!nativeConstructor) return;
+ var element = document.createElement(tagName);
+ var wrapperConstructor = element.constructor;
+ window[nativeConstructorName] = wrapperConstructor;
+ }
+ Object.keys(elements).forEach(overrideConstructor);
+ Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {
+ window[name] = scope.wrappers[name];
+ });
+ })(window.ShadowDOMPolyfill);
+ (function(scope) {
+ var ShadowCSS = {
+ strictStyling: false,
+ registry: {},
+ shimStyling: function(root, name, extendsName) {
+ var scopeStyles = this.prepareRoot(root, name, extendsName);
+ var typeExtension = this.isTypeExtension(extendsName);
+ var scopeSelector = this.makeScopeSelector(name, typeExtension);
+ var cssText = stylesToCssText(scopeStyles, true);
+ cssText = this.scopeCssText(cssText, scopeSelector);
+ if (root) {
+ root.shimmedStyle = cssText;
+ }
+ this.addCssToDocument(cssText, name);
+ },
+ shimStyle: function(style, selector) {
+ return this.shimCssText(style.textContent, selector);
+ },
+ shimCssText: function(cssText, selector) {
+ cssText = this.insertDirectives(cssText);
+ return this.scopeCssText(cssText, selector);
+ },
+ makeScopeSelector: function(name, typeExtension) {
+ if (name) {
+ return typeExtension ? "[is=" + name + "]" : name;
+ }
+ return "";
+ },
+ isTypeExtension: function(extendsName) {
+ return extendsName && extendsName.indexOf("-") < 0;
+ },
+ prepareRoot: function(root, name, extendsName) {
+ var def = this.registerRoot(root, name, extendsName);
+ this.replaceTextInStyles(def.rootStyles, this.insertDirectives);
+ this.removeStyles(root, def.rootStyles);
+ if (this.strictStyling) {
+ this.applyScopeToContent(root, name);
+ }
+ return def.scopeStyles;
+ },
+ removeStyles: function(root, styles) {
+ for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) {
+ s.parentNode.removeChild(s);
+ }
+ },
+ registerRoot: function(root, name, extendsName) {
+ var def = this.registry[name] = {
+ root: root,
+ name: name,
+ extendsName: extendsName
+ };
+ var styles = this.findStyles(root);
+ def.rootStyles = styles;
+ def.scopeStyles = def.rootStyles;
+ var extendee = this.registry[def.extendsName];
+ if (extendee) {
+ def.scopeStyles = extendee.scopeStyles.concat(def.scopeStyles);
+ }
+ return def;
+ },
+ findStyles: function(root) {
+ if (!root) {
+ return [];
+ }
+ var styles = root.querySelectorAll("style");
+ return Array.prototype.filter.call(styles, function(s) {
+ return !s.hasAttribute(NO_SHIM_ATTRIBUTE);
+ });
+ },
+ applyScopeToContent: function(root, name) {
+ if (root) {
+ Array.prototype.forEach.call(root.querySelectorAll("*"), function(node) {
+ node.setAttribute(name, "");
+ });
+ Array.prototype.forEach.call(root.querySelectorAll("template"), function(template) {
+ this.applyScopeToContent(template.content, name);
+ }, this);
+ }
+ },
+ insertDirectives: function(cssText) {
+ cssText = this.insertPolyfillDirectivesInCssText(cssText);
+ return this.insertPolyfillRulesInCssText(cssText);
+ },
+ insertPolyfillDirectivesInCssText: function(cssText) {
+ cssText = cssText.replace(cssCommentNextSelectorRe, function(match, p1) {
+ return p1.slice(0, -2) + "{";
+ });
+ return cssText.replace(cssContentNextSelectorRe, function(match, p1) {
+ return p1 + " {";
+ });
+ },
+ insertPolyfillRulesInCssText: function(cssText) {
+ cssText = cssText.replace(cssCommentRuleRe, function(match, p1) {
+ return p1.slice(0, -1);
+ });
+ return cssText.replace(cssContentRuleRe, function(match, p1, p2, p3) {
+ var rule = match.replace(p1, "").replace(p2, "");
+ return p3 + rule;
+ });
+ },
+ scopeCssText: function(cssText, scopeSelector) {
+ var unscoped = this.extractUnscopedRulesFromCssText(cssText);
+ cssText = this.insertPolyfillHostInCssText(cssText);
+ cssText = this.convertColonHost(cssText);
+ cssText = this.convertColonHostContext(cssText);
+ cssText = this.convertShadowDOMSelectors(cssText);
+ if (scopeSelector) {
+ var self = this, cssText;
+ withCssRules(cssText, function(rules) {
+ cssText = self.scopeRules(rules, scopeSelector);
+ });
+ }
+ cssText = cssText + "\n" + unscoped;
+ return cssText.trim();
+ },
+ extractUnscopedRulesFromCssText: function(cssText) {
+ var r = "", m;
+ while (m = cssCommentUnscopedRuleRe.exec(cssText)) {
+ r += m[1].slice(0, -1) + "\n\n";
+ }
+ while (m = cssContentUnscopedRuleRe.exec(cssText)) {
+ r += m[0].replace(m[2], "").replace(m[1], m[3]) + "\n\n";
+ }
+ return r;
+ },
+ convertColonHost: function(cssText) {
+ return this.convertColonRule(cssText, cssColonHostRe, this.colonHostPartReplacer);
+ },
+ convertColonHostContext: function(cssText) {
+ return this.convertColonRule(cssText, cssColonHostContextRe, this.colonHostContextPartReplacer);
+ },
+ convertColonRule: function(cssText, regExp, partReplacer) {
+ return cssText.replace(regExp, function(m, p1, p2, p3) {
+ p1 = polyfillHostNoCombinator;
+ if (p2) {
+ var parts = p2.split(","), r = [];
+ for (var i = 0, l = parts.length, p; i < l && (p = parts[i]); i++) {
+ p = p.trim();
+ r.push(partReplacer(p1, p, p3));
+ }
+ return r.join(",");
+ } else {
+ return p1 + p3;
+ }
+ });
+ },
+ colonHostContextPartReplacer: function(host, part, suffix) {
+ if (part.match(polyfillHost)) {
+ return this.colonHostPartReplacer(host, part, suffix);
+ } else {
+ return host + part + suffix + ", " + part + " " + host + suffix;
+ }
+ },
+ colonHostPartReplacer: function(host, part, suffix) {
+ return host + part.replace(polyfillHost, "") + suffix;
+ },
+ convertShadowDOMSelectors: function(cssText) {
+ for (var i = 0; i < shadowDOMSelectorsRe.length; i++) {
+ cssText = cssText.replace(shadowDOMSelectorsRe[i], " ");
+ }
+ return cssText;
+ },
+ scopeRules: function(cssRules, scopeSelector) {
+ var cssText = "";
+ if (cssRules) {
+ Array.prototype.forEach.call(cssRules, function(rule) {
+ if (rule.selectorText && (rule.style && rule.style.cssText !== undefined)) {
+ cssText += this.scopeSelector(rule.selectorText, scopeSelector, this.strictStyling) + " {\n ";
+ cssText += this.propertiesFromRule(rule) + "\n}\n\n";
+ } else if (rule.type === CSSRule.MEDIA_RULE) {
+ cssText += "@media " + rule.media.mediaText + " {\n";
+ cssText += this.scopeRules(rule.cssRules, scopeSelector);
+ cssText += "\n}\n\n";
+ } else {
+ try {
+ if (rule.cssText) {
+ cssText += rule.cssText + "\n\n";
+ }
+ } catch (x) {
+ if (rule.type === CSSRule.KEYFRAMES_RULE && rule.cssRules) {
+ cssText += this.ieSafeCssTextFromKeyFrameRule(rule);
+ }
+ }
+ }
+ }, this);
+ }
+ return cssText;
+ },
+ ieSafeCssTextFromKeyFrameRule: function(rule) {
+ var cssText = "@keyframes " + rule.name + " {";
+ Array.prototype.forEach.call(rule.cssRules, function(rule) {
+ cssText += " " + rule.keyText + " {" + rule.style.cssText + "}";
+ });
+ cssText += " }";
+ return cssText;
+ },
+ scopeSelector: function(selector, scopeSelector, strict) {
+ var r = [], parts = selector.split(",");
+ parts.forEach(function(p) {
+ p = p.trim();
+ if (this.selectorNeedsScoping(p, scopeSelector)) {
+ p = strict && !p.match(polyfillHostNoCombinator) ? this.applyStrictSelectorScope(p, scopeSelector) : this.applySelectorScope(p, scopeSelector);
+ }
+ r.push(p);
+ }, this);
+ return r.join(", ");
+ },
+ selectorNeedsScoping: function(selector, scopeSelector) {
+ if (Array.isArray(scopeSelector)) {
+ return true;
+ }
+ var re = this.makeScopeMatcher(scopeSelector);
+ return !selector.match(re);
+ },
+ makeScopeMatcher: function(scopeSelector) {
+ scopeSelector = scopeSelector.replace(/\[/g, "\\[").replace(/\]/g, "\\]");
+ return new RegExp("^(" + scopeSelector + ")" + selectorReSuffix, "m");
+ },
+ applySelectorScope: function(selector, selectorScope) {
+ return Array.isArray(selectorScope) ? this.applySelectorScopeList(selector, selectorScope) : this.applySimpleSelectorScope(selector, selectorScope);
+ },
+ applySelectorScopeList: function(selector, scopeSelectorList) {
+ var r = [];
+ for (var i = 0, s; s = scopeSelectorList[i]; i++) {
+ r.push(this.applySimpleSelectorScope(selector, s));
+ }
+ return r.join(", ");
+ },
+ applySimpleSelectorScope: function(selector, scopeSelector) {
+ if (selector.match(polyfillHostRe)) {
+ selector = selector.replace(polyfillHostNoCombinator, scopeSelector);
+ return selector.replace(polyfillHostRe, scopeSelector + " ");
+ } else {
+ return scopeSelector + " " + selector;
+ }
+ },
+ applyStrictSelectorScope: function(selector, scopeSelector) {
+ scopeSelector = scopeSelector.replace(/\[is=([^\]]*)\]/g, "$1");
+ var splits = [ " ", ">", "+", "~" ], scoped = selector, attrName = "[" + scopeSelector + "]";
+ splits.forEach(function(sep) {
+ var parts = scoped.split(sep);
+ scoped = parts.map(function(p) {
+ var t = p.trim().replace(polyfillHostRe, "");
+ if (t && splits.indexOf(t) < 0 && t.indexOf(attrName) < 0) {
+ p = t.replace(/([^:]*)(:*)(.*)/, "$1" + attrName + "$2$3");
+ }
+ return p;
+ }).join(sep);
+ });
+ return scoped;
+ },
+ insertPolyfillHostInCssText: function(selector) {
+ return selector.replace(colonHostContextRe, polyfillHostContext).replace(colonHostRe, polyfillHost);
+ },
+ propertiesFromRule: function(rule) {
+ var cssText = rule.style.cssText;
+ if (rule.style.content && !rule.style.content.match(/['"]+|attr/)) {
+ cssText = cssText.replace(/content:[^;]*;/g, "content: '" + rule.style.content + "';");
+ }
+ var style = rule.style;
+ for (var i in style) {
+ if (style[i] === "initial") {
+ cssText += i + ": initial; ";
+ }
+ }
+ return cssText;
+ },
+ replaceTextInStyles: function(styles, action) {
+ if (styles && action) {
+ if (!(styles instanceof Array)) {
+ styles = [ styles ];
+ }
+ Array.prototype.forEach.call(styles, function(s) {
+ s.textContent = action.call(this, s.textContent);
+ }, this);
+ }
+ },
+ addCssToDocument: function(cssText, name) {
+ if (cssText.match("@import")) {
+ addOwnSheet(cssText, name);
+ } else {
+ addCssToDocument(cssText);
+ }
+ }
+ };
+ var selectorRe = /([^{]*)({[\s\S]*?})/gim, cssCommentRe = /\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim, cssCommentNextSelectorRe = /\/\*\s*@polyfill ([^*]*\*+([^\/*][^*]*\*+)*\/)([^{]*?){/gim, cssContentNextSelectorRe = /polyfill-next-selector[^}]*content\:[\s]*?['"](.*?)['"][;\s]*}([^{]*?){/gim, cssCommentRuleRe = /\/\*\s@polyfill-rule([^*]*\*+([^\/*][^*]*\*+)*)\//gim, cssContentRuleRe = /(polyfill-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim, cssCommentUnscopedRuleRe = /\/\*\s@polyfill-unscoped-rule([^*]*\*+([^\/*][^*]*\*+)*)\//gim, cssContentUnscopedRuleRe = /(polyfill-unscoped-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim, cssPseudoRe = /::(x-[^\s{,(]*)/gim, cssPartRe = /::part\(([^)]*)\)/gim, polyfillHost = "-shadowcsshost", polyfillHostContext = "-shadowcsscontext", parenSuffix = ")(?:\\((" + "(?:\\([^)(]*\\)|[^)(]*)+?" + ")\\))?([^,{]*)";
+ var cssColonHostRe = new RegExp("(" + polyfillHost + parenSuffix, "gim"), cssColonHostContextRe = new RegExp("(" + polyfillHostContext + parenSuffix, "gim"), selectorReSuffix = "([>\\s~+[.,{:][\\s\\S]*)?$", colonHostRe = /\:host/gim, colonHostContextRe = /\:host-context/gim, polyfillHostNoCombinator = polyfillHost + "-no-combinator", polyfillHostRe = new RegExp(polyfillHost, "gim"), polyfillHostContextRe = new RegExp(polyfillHostContext, "gim"), shadowDOMSelectorsRe = [ />>>/g, /::shadow/g, /::content/g, /\/deep\//g, /\/shadow\//g, /\/shadow-deep\//g, /\^\^/g, /\^/g ];
+ function stylesToCssText(styles, preserveComments) {
+ var cssText = "";
+ Array.prototype.forEach.call(styles, function(s) {
+ cssText += s.textContent + "\n\n";
+ });
+ if (!preserveComments) {
+ cssText = cssText.replace(cssCommentRe, "");
+ }
+ return cssText;
+ }
+ function cssTextToStyle(cssText) {
+ var style = document.createElement("style");
+ style.textContent = cssText;
+ return style;
+ }
+ function cssToRules(cssText) {
+ var style = cssTextToStyle(cssText);
+ document.head.appendChild(style);
+ var rules = [];
+ if (style.sheet) {
+ try {
+ rules = style.sheet.cssRules;
+ } catch (e) {}
+ } else {
+ console.warn("sheet not found", style);
+ }
+ style.parentNode.removeChild(style);
+ return rules;
+ }
+ var frame = document.createElement("iframe");
+ frame.style.display = "none";
+ function initFrame() {
+ frame.initialized = true;
+ document.body.appendChild(frame);
+ var doc = frame.contentDocument;
+ var base = doc.createElement("base");
+ base.href = document.baseURI;
+ doc.head.appendChild(base);
+ }
+ function inFrame(fn) {
+ if (!frame.initialized) {
+ initFrame();
+ }
+ document.body.appendChild(frame);
+ fn(frame.contentDocument);
+ document.body.removeChild(frame);
+ }
+ var isChrome = navigator.userAgent.match("Chrome");
+ function withCssRules(cssText, callback) {
+ if (!callback) {
+ return;
+ }
+ var rules;
+ if (cssText.match("@import") && isChrome) {
+ var style = cssTextToStyle(cssText);
+ inFrame(function(doc) {
+ doc.head.appendChild(style.impl);
+ rules = Array.prototype.slice.call(style.sheet.cssRules, 0);
+ callback(rules);
+ });
+ } else {
+ rules = cssToRules(cssText);
+ callback(rules);
+ }
+ }
+ function rulesToCss(cssRules) {
+ for (var i = 0, css = []; i < cssRules.length; i++) {
+ css.push(cssRules[i].cssText);
+ }
+ return css.join("\n\n");
+ }
+ function addCssToDocument(cssText) {
+ if (cssText) {
+ getSheet().appendChild(document.createTextNode(cssText));
+ }
+ }
+ function addOwnSheet(cssText, name) {
+ var style = cssTextToStyle(cssText);
+ style.setAttribute(name, "");
+ style.setAttribute(SHIMMED_ATTRIBUTE, "");
+ document.head.appendChild(style);
+ }
+ var SHIM_ATTRIBUTE = "shim-shadowdom";
+ var SHIMMED_ATTRIBUTE = "shim-shadowdom-css";
+ var NO_SHIM_ATTRIBUTE = "no-shim";
+ var sheet;
+ function getSheet() {
+ if (!sheet) {
+ sheet = document.createElement("style");
+ sheet.setAttribute(SHIMMED_ATTRIBUTE, "");
+ sheet[SHIMMED_ATTRIBUTE] = true;
+ }
+ return sheet;
+ }
+ if (window.ShadowDOMPolyfill) {
+ addCssToDocument("style { display: none !important; }\n");
+ var doc = ShadowDOMPolyfill.wrap(document);
+ var head = doc.querySelector("head");
+ head.insertBefore(getSheet(), head.childNodes[0]);
+ document.addEventListener("DOMContentLoaded", function() {
+ var urlResolver = scope.urlResolver;
+ if (window.HTMLImports && !HTMLImports.useNative) {
+ var SHIM_SHEET_SELECTOR = "link[rel=stylesheet]" + "[" + SHIM_ATTRIBUTE + "]";
+ var SHIM_STYLE_SELECTOR = "style[" + SHIM_ATTRIBUTE + "]";
+ HTMLImports.importer.documentPreloadSelectors += "," + SHIM_SHEET_SELECTOR;
+ HTMLImports.importer.importsPreloadSelectors += "," + SHIM_SHEET_SELECTOR;
+ HTMLImports.parser.documentSelectors = [ HTMLImports.parser.documentSelectors, SHIM_SHEET_SELECTOR, SHIM_STYLE_SELECTOR ].join(",");
+ var originalParseGeneric = HTMLImports.parser.parseGeneric;
+ HTMLImports.parser.parseGeneric = function(elt) {
+ if (elt[SHIMMED_ATTRIBUTE]) {
+ return;
+ }
+ var style = elt.__importElement || elt;
+ if (!style.hasAttribute(SHIM_ATTRIBUTE)) {
+ originalParseGeneric.call(this, elt);
+ return;
+ }
+ if (elt.__resource) {
+ style = elt.ownerDocument.createElement("style");
+ style.textContent = elt.__resource;
+ }
+ HTMLImports.path.resolveUrlsInStyle(style, elt.href);
+ style.textContent = ShadowCSS.shimStyle(style);
+ style.removeAttribute(SHIM_ATTRIBUTE, "");
+ style.setAttribute(SHIMMED_ATTRIBUTE, "");
+ style[SHIMMED_ATTRIBUTE] = true;
+ if (style.parentNode !== head) {
+ if (elt.parentNode === head) {
+ head.replaceChild(style, elt);
+ } else {
+ this.addElementToDocument(style);
+ }
+ }
+ style.__importParsed = true;
+ this.markParsingComplete(elt);
+ this.parseNext();
+ };
+ var hasResource = HTMLImports.parser.hasResource;
+ HTMLImports.parser.hasResource = function(node) {
+ if (node.localName === "link" && node.rel === "stylesheet" && node.hasAttribute(SHIM_ATTRIBUTE)) {
+ return node.__resource;
+ } else {
+ return hasResource.call(this, node);
+ }
+ };
+ }
+ });
+ }
+ scope.ShadowCSS = ShadowCSS;
+ })(window.WebComponents);
+}
+
+(function(scope) {
+ if (window.ShadowDOMPolyfill) {
+ window.wrap = ShadowDOMPolyfill.wrapIfNeeded;
+ window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;
+ } else {
+ window.wrap = window.unwrap = function(n) {
+ return n;
+ };
+ }
+})(window.WebComponents);
+
+(function(scope) {
+ "use strict";
+ var hasWorkingUrl = false;
+ if (!scope.forceJURL) {
+ try {
+ var u = new URL("b", "http://a");
+ u.pathname = "c%20d";
+ hasWorkingUrl = u.href === "http://a/c%20d";
+ } catch (e) {}
+ }
+ if (hasWorkingUrl) return;
+ var relative = Object.create(null);
+ relative["ftp"] = 21;
+ relative["file"] = 0;
+ relative["gopher"] = 70;
+ relative["http"] = 80;
+ relative["https"] = 443;
+ relative["ws"] = 80;
+ relative["wss"] = 443;
+ var relativePathDotMapping = Object.create(null);
+ relativePathDotMapping["%2e"] = ".";
+ relativePathDotMapping[".%2e"] = "..";
+ relativePathDotMapping["%2e."] = "..";
+ relativePathDotMapping["%2e%2e"] = "..";
+ function isRelativeScheme(scheme) {
+ return relative[scheme] !== undefined;
+ }
+ function invalid() {
+ clear.call(this);
+ this._isInvalid = true;
+ }
+ function IDNAToASCII(h) {
+ if ("" == h) {
+ invalid.call(this);
+ }
+ return h.toLowerCase();
+ }
+ function percentEscape(c) {
+ var unicode = c.charCodeAt(0);
+ if (unicode > 32 && unicode < 127 && [ 34, 35, 60, 62, 63, 96 ].indexOf(unicode) == -1) {
+ return c;
+ }
+ return encodeURIComponent(c);
+ }
+ function percentEscapeQuery(c) {
+ var unicode = c.charCodeAt(0);
+ if (unicode > 32 && unicode < 127 && [ 34, 35, 60, 62, 96 ].indexOf(unicode) == -1) {
+ return c;
+ }
+ return encodeURIComponent(c);
+ }
+ var EOF = undefined, ALPHA = /[a-zA-Z]/, ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
+ function parse(input, stateOverride, base) {
+ function err(message) {
+ errors.push(message);
+ }
+ var state = stateOverride || "scheme start", cursor = 0, buffer = "", seenAt = false, seenBracket = false, errors = [];
+ loop: while ((input[cursor - 1] != EOF || cursor == 0) && !this._isInvalid) {
+ var c = input[cursor];
+ switch (state) {
+ case "scheme start":
+ if (c && ALPHA.test(c)) {
+ buffer += c.toLowerCase();
+ state = "scheme";
+ } else if (!stateOverride) {
+ buffer = "";
+ state = "no scheme";
+ continue;
+ } else {
+ err("Invalid scheme.");
+ break loop;
+ }
+ break;
+
+ case "scheme":
+ if (c && ALPHANUMERIC.test(c)) {
+ buffer += c.toLowerCase();
+ } else if (":" == c) {
+ this._scheme = buffer;
+ buffer = "";
+ if (stateOverride) {
+ break loop;
+ }
+ if (isRelativeScheme(this._scheme)) {
+ this._isRelative = true;
+ }
+ if ("file" == this._scheme) {
+ state = "relative";
+ } else if (this._isRelative && base && base._scheme == this._scheme) {
+ state = "relative or authority";
+ } else if (this._isRelative) {
+ state = "authority first slash";
+ } else {
+ state = "scheme data";
+ }
+ } else if (!stateOverride) {
+ buffer = "";
+ cursor = 0;
+ state = "no scheme";
+ continue;
+ } else if (EOF == c) {
+ break loop;
+ } else {
+ err("Code point not allowed in scheme: " + c);
+ break loop;
+ }
+ break;
+
+ case "scheme data":
+ if ("?" == c) {
+ this._query = "?";
+ state = "query";
+ } else if ("#" == c) {
+ this._fragment = "#";
+ state = "fragment";
+ } else {
+ if (EOF != c && " " != c && "\n" != c && "\r" != c) {
+ this._schemeData += percentEscape(c);
+ }
+ }
+ break;
+
+ case "no scheme":
+ if (!base || !isRelativeScheme(base._scheme)) {
+ err("Missing scheme.");
+ invalid.call(this);
+ } else {
+ state = "relative";
+ continue;
+ }
+ break;
+
+ case "relative or authority":
+ if ("/" == c && "/" == input[cursor + 1]) {
+ state = "authority ignore slashes";
+ } else {
+ err("Expected /, got: " + c);
+ state = "relative";
+ continue;
+ }
+ break;
+
+ case "relative":
+ this._isRelative = true;
+ if ("file" != this._scheme) this._scheme = base._scheme;
+ if (EOF == c) {
+ this._host = base._host;
+ this._port = base._port;
+ this._path = base._path.slice();
+ this._query = base._query;
+ this._username = base._username;
+ this._password = base._password;
+ break loop;
+ } else if ("/" == c || "\\" == c) {
+ if ("\\" == c) err("\\ is an invalid code point.");
+ state = "relative slash";
+ } else if ("?" == c) {
+ this._host = base._host;
+ this._port = base._port;
+ this._path = base._path.slice();
+ this._query = "?";
+ this._username = base._username;
+ this._password = base._password;
+ state = "query";
+ } else if ("#" == c) {
+ this._host = base._host;
+ this._port = base._port;
+ this._path = base._path.slice();
+ this._query = base._query;
+ this._fragment = "#";
+ this._username = base._username;
+ this._password = base._password;
+ state = "fragment";
+ } else {
+ var nextC = input[cursor + 1];
+ var nextNextC = input[cursor + 2];
+ if ("file" != this._scheme || !ALPHA.test(c) || nextC != ":" && nextC != "|" || EOF != nextNextC && "/" != nextNextC && "\\" != nextNextC && "?" != nextNextC && "#" != nextNextC) {
+ this._host = base._host;
+ this._port = base._port;
+ this._username = base._username;
+ this._password = base._password;
+ this._path = base._path.slice();
+ this._path.pop();
+ }
+ state = "relative path";
+ continue;
+ }
+ break;
+
+ case "relative slash":
+ if ("/" == c || "\\" == c) {
+ if ("\\" == c) {
+ err("\\ is an invalid code point.");
+ }
+ if ("file" == this._scheme) {
+ state = "file host";
+ } else {
+ state = "authority ignore slashes";
+ }
+ } else {
+ if ("file" != this._scheme) {
+ this._host = base._host;
+ this._port = base._port;
+ this._username = base._username;
+ this._password = base._password;
+ }
+ state = "relative path";
+ continue;
+ }
+ break;
+
+ case "authority first slash":
+ if ("/" == c) {
+ state = "authority second slash";
+ } else {
+ err("Expected '/', got: " + c);
+ state = "authority ignore slashes";
+ continue;
+ }
+ break;
+
+ case "authority second slash":
+ state = "authority ignore slashes";
+ if ("/" != c) {
+ err("Expected '/', got: " + c);
+ continue;
+ }
+ break;
+
+ case "authority ignore slashes":
+ if ("/" != c && "\\" != c) {
+ state = "authority";
+ continue;
+ } else {
+ err("Expected authority, got: " + c);
+ }
+ break;
+
+ case "authority":
+ if ("@" == c) {
+ if (seenAt) {
+ err("@ already seen.");
+ buffer += "%40";
+ }
+ seenAt = true;
+ for (var i = 0; i < buffer.length; i++) {
+ var cp = buffer[i];
+ if (" " == cp || "\n" == cp || "\r" == cp) {
+ err("Invalid whitespace in authority.");
+ continue;
+ }
+ if (":" == cp && null === this._password) {
+ this._password = "";
+ continue;
+ }
+ var tempC = percentEscape(cp);
+ null !== this._password ? this._password += tempC : this._username += tempC;
+ }
+ buffer = "";
+ } else if (EOF == c || "/" == c || "\\" == c || "?" == c || "#" == c) {
+ cursor -= buffer.length;
+ buffer = "";
+ state = "host";
+ continue;
+ } else {
+ buffer += c;
+ }
+ break;
+
+ case "file host":
+ if (EOF == c || "/" == c || "\\" == c || "?" == c || "#" == c) {
+ if (buffer.length == 2 && ALPHA.test(buffer[0]) && (buffer[1] == ":" || buffer[1] == "|")) {
+ state = "relative path";
+ } else if (buffer.length == 0) {
+ state = "relative path start";
+ } else {
+ this._host = IDNAToASCII.call(this, buffer);
+ buffer = "";
+ state = "relative path start";
+ }
+ continue;
+ } else if (" " == c || "\n" == c || "\r" == c) {
+ err("Invalid whitespace in file host.");
+ } else {
+ buffer += c;
+ }
+ break;
+
+ case "host":
+ case "hostname":
+ if (":" == c && !seenBracket) {
+ this._host = IDNAToASCII.call(this, buffer);
+ buffer = "";
+ state = "port";
+ if ("hostname" == stateOverride) {
+ break loop;
+ }
+ } else if (EOF == c || "/" == c || "\\" == c || "?" == c || "#" == c) {
+ this._host = IDNAToASCII.call(this, buffer);
+ buffer = "";
+ state = "relative path start";
+ if (stateOverride) {
+ break loop;
+ }
+ continue;
+ } else if (" " != c && "\n" != c && "\r" != c) {
+ if ("[" == c) {
+ seenBracket = true;
+ } else if ("]" == c) {
+ seenBracket = false;
+ }
+ buffer += c;
+ } else {
+ err("Invalid code point in host/hostname: " + c);
+ }
+ break;
+
+ case "port":
+ if (/[0-9]/.test(c)) {
+ buffer += c;
+ } else if (EOF == c || "/" == c || "\\" == c || "?" == c || "#" == c || stateOverride) {
+ if ("" != buffer) {
+ var temp = parseInt(buffer, 10);
+ if (temp != relative[this._scheme]) {
+ this._port = temp + "";
+ }
+ buffer = "";
+ }
+ if (stateOverride) {
+ break loop;
+ }
+ state = "relative path start";
+ continue;
+ } else if (" " == c || "\n" == c || "\r" == c) {
+ err("Invalid code point in port: " + c);
+ } else {
+ invalid.call(this);
+ }
+ break;
+
+ case "relative path start":
+ if ("\\" == c) err("'\\' not allowed in path.");
+ state = "relative path";
+ if ("/" != c && "\\" != c) {
+ continue;
+ }
+ break;
+
+ case "relative path":
+ if (EOF == c || "/" == c || "\\" == c || !stateOverride && ("?" == c || "#" == c)) {
+ if ("\\" == c) {
+ err("\\ not allowed in relative path.");
+ }
+ var tmp;
+ if (tmp = relativePathDotMapping[buffer.toLowerCase()]) {
+ buffer = tmp;
+ }
+ if (".." == buffer) {
+ this._path.pop();
+ if ("/" != c && "\\" != c) {
+ this._path.push("");
+ }
+ } else if ("." == buffer && "/" != c && "\\" != c) {
+ this._path.push("");
+ } else if ("." != buffer) {
+ if ("file" == this._scheme && this._path.length == 0 && buffer.length == 2 && ALPHA.test(buffer[0]) && buffer[1] == "|") {
+ buffer = buffer[0] + ":";
+ }
+ this._path.push(buffer);
+ }
+ buffer = "";
+ if ("?" == c) {
+ this._query = "?";
+ state = "query";
+ } else if ("#" == c) {
+ this._fragment = "#";
+ state = "fragment";
+ }
+ } else if (" " != c && "\n" != c && "\r" != c) {
+ buffer += percentEscape(c);
+ }
+ break;
+
+ case "query":
+ if (!stateOverride && "#" == c) {
+ this._fragment = "#";
+ state = "fragment";
+ } else if (EOF != c && " " != c && "\n" != c && "\r" != c) {
+ this._query += percentEscapeQuery(c);
+ }
+ break;
+
+ case "fragment":
+ if (EOF != c && " " != c && "\n" != c && "\r" != c) {
+ this._fragment += c;
+ }
+ break;
+ }
+ cursor++;
+ }
+ }
+ function clear() {
+ this._scheme = "";
+ this._schemeData = "";
+ this._username = "";
+ this._password = null;
+ this._host = "";
+ this._port = "";
+ this._path = [];
+ this._query = "";
+ this._fragment = "";
+ this._isInvalid = false;
+ this._isRelative = false;
+ }
+ function jURL(url, base) {
+ if (base !== undefined && !(base instanceof jURL)) base = new jURL(String(base));
+ this._url = url;
+ clear.call(this);
+ var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, "");
+ parse.call(this, input, null, base);
+ }
+ jURL.prototype = {
+ toString: function() {
+ return this.href;
+ },
+ get href() {
+ if (this._isInvalid) return this._url;
+ var authority = "";
+ if ("" != this._username || null != this._password) {
+ authority = this._username + (null != this._password ? ":" + this._password : "") + "@";
+ }
+ return this.protocol + (this._isRelative ? "//" + authority + this.host : "") + this.pathname + this._query + this._fragment;
+ },
+ set href(href) {
+ clear.call(this);
+ parse.call(this, href);
+ },
+ get protocol() {
+ return this._scheme + ":";
+ },
+ set protocol(protocol) {
+ if (this._isInvalid) return;
+ parse.call(this, protocol + ":", "scheme start");
+ },
+ get host() {
+ return this._isInvalid ? "" : this._port ? this._host + ":" + this._port : this._host;
+ },
+ set host(host) {
+ if (this._isInvalid || !this._isRelative) return;
+ parse.call(this, host, "host");
+ },
+ get hostname() {
+ return this._host;
+ },
+ set hostname(hostname) {
+ if (this._isInvalid || !this._isRelative) return;
+ parse.call(this, hostname, "hostname");
+ },
+ get port() {
+ return this._port;
+ },
+ set port(port) {
+ if (this._isInvalid || !this._isRelative) return;
+ parse.call(this, port, "port");
+ },
+ get pathname() {
+ return this._isInvalid ? "" : this._isRelative ? "/" + this._path.join("/") : this._schemeData;
+ },
+ set pathname(pathname) {
+ if (this._isInvalid || !this._isRelative) return;
+ this._path = [];
+ parse.call(this, pathname, "relative path start");
+ },
+ get search() {
+ return this._isInvalid || !this._query || "?" == this._query ? "" : this._query;
+ },
+ set search(search) {
+ if (this._isInvalid || !this._isRelative) return;
+ this._query = "?";
+ if ("?" == search[0]) search = search.slice(1);
+ parse.call(this, search, "query");
+ },
+ get hash() {
+ return this._isInvalid || !this._fragment || "#" == this._fragment ? "" : this._fragment;
+ },
+ set hash(hash) {
+ if (this._isInvalid) return;
+ this._fragment = "#";
+ if ("#" == hash[0]) hash = hash.slice(1);
+ parse.call(this, hash, "fragment");
+ },
+ get origin() {
+ var host;
+ if (this._isInvalid || !this._scheme) {
+ return "";
+ }
+ switch (this._scheme) {
+ case "data":
+ case "file":
+ case "javascript":
+ case "mailto":
+ return "null";
+ }
+ host = this.host;
+ if (!host) {
+ return "";
+ }
+ return this._scheme + "://" + host;
+ }
+ };
+ var OriginalURL = scope.URL;
+ if (OriginalURL) {
+ jURL.createObjectURL = function(blob) {
+ return OriginalURL.createObjectURL.apply(OriginalURL, arguments);
+ };
+ jURL.revokeObjectURL = function(url) {
+ OriginalURL.revokeObjectURL(url);
+ };
+ }
+ scope.URL = jURL;
+})(this);
+
+(function(global) {
+ var registrationsTable = new WeakMap();
+ var setImmediate;
+ if (/Trident|Edge/.test(navigator.userAgent)) {
+ setImmediate = setTimeout;
+ } else if (window.setImmediate) {
+ setImmediate = window.setImmediate;
+ } else {
+ var setImmediateQueue = [];
+ var sentinel = String(Math.random());
+ window.addEventListener("message", function(e) {
+ if (e.data === sentinel) {
+ var queue = setImmediateQueue;
+ setImmediateQueue = [];
+ queue.forEach(function(func) {
+ func();
+ });
+ }
+ });
+ setImmediate = function(func) {
+ setImmediateQueue.push(func);
+ window.postMessage(sentinel, "*");
+ };
+ }
+ var isScheduled = false;
+ var scheduledObservers = [];
+ function scheduleCallback(observer) {
+ scheduledObservers.push(observer);
+ if (!isScheduled) {
+ isScheduled = true;
+ setImmediate(dispatchCallbacks);
+ }
+ }
+ function wrapIfNeeded(node) {
+ return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;
+ }
+ function dispatchCallbacks() {
+ isScheduled = false;
+ var observers = scheduledObservers;
+ scheduledObservers = [];
+ observers.sort(function(o1, o2) {
+ return o1.uid_ - o2.uid_;
+ });
+ var anyNonEmpty = false;
+ observers.forEach(function(observer) {
+ var queue = observer.takeRecords();
+ removeTransientObserversFor(observer);
+ if (queue.length) {
+ observer.callback_(queue, observer);
+ anyNonEmpty = true;
+ }
+ });
+ if (anyNonEmpty) dispatchCallbacks();
+ }
+ function removeTransientObserversFor(observer) {
+ observer.nodes_.forEach(function(node) {
+ var registrations = registrationsTable.get(node);
+ if (!registrations) return;
+ registrations.forEach(function(registration) {
+ if (registration.observer === observer) registration.removeTransientObservers();
+ });
+ });
+ }
+ function forEachAncestorAndObserverEnqueueRecord(target, callback) {
+ for (var node = target; node; node = node.parentNode) {
+ var registrations = registrationsTable.get(node);
+ if (registrations) {
+ for (var j = 0; j < registrations.length; j++) {
+ var registration = registrations[j];
+ var options = registration.options;
+ if (node !== target && !options.subtree) continue;
+ var record = callback(options);
+ if (record) registration.enqueue(record);
+ }
+ }
+ }
+ }
+ var uidCounter = 0;
+ function JsMutationObserver(callback) {
+ this.callback_ = callback;
+ this.nodes_ = [];
+ this.records_ = [];
+ this.uid_ = ++uidCounter;
+ }
+ JsMutationObserver.prototype = {
+ observe: function(target, options) {
+ target = wrapIfNeeded(target);
+ if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {
+ throw new SyntaxError();
+ }
+ var registrations = registrationsTable.get(target);
+ if (!registrations) registrationsTable.set(target, registrations = []);
+ var registration;
+ for (var i = 0; i < registrations.length; i++) {
+ if (registrations[i].observer === this) {
+ registration = registrations[i];
+ registration.removeListeners();
+ registration.options = options;
+ break;
+ }
+ }
+ if (!registration) {
+ registration = new Registration(this, target, options);
+ registrations.push(registration);
+ this.nodes_.push(target);
+ }
+ registration.addListeners();
+ },
+ disconnect: function() {
+ this.nodes_.forEach(function(node) {
+ var registrations = registrationsTable.get(node);
+ for (var i = 0; i < registrations.length; i++) {
+ var registration = registrations[i];
+ if (registration.observer === this) {
+ registration.removeListeners();
+ registrations.splice(i, 1);
+ break;
+ }
+ }
+ }, this);
+ this.records_ = [];
+ },
+ takeRecords: function() {
+ var copyOfRecords = this.records_;
+ this.records_ = [];
+ return copyOfRecords;
+ }
+ };
+ function MutationRecord(type, target) {
+ this.type = type;
+ this.target = target;
+ this.addedNodes = [];
+ this.removedNodes = [];
+ this.previousSibling = null;
+ this.nextSibling = null;
+ this.attributeName = null;
+ this.attributeNamespace = null;
+ this.oldValue = null;
+ }
+ function copyMutationRecord(original) {
+ var record = new MutationRecord(original.type, original.target);
+ record.addedNodes = original.addedNodes.slice();
+ record.removedNodes = original.removedNodes.slice();
+ record.previousSibling = original.previousSibling;
+ record.nextSibling = original.nextSibling;
+ record.attributeName = original.attributeName;
+ record.attributeNamespace = original.attributeNamespace;
+ record.oldValue = original.oldValue;
+ return record;
+ }
+ var currentRecord, recordWithOldValue;
+ function getRecord(type, target) {
+ return currentRecord = new MutationRecord(type, target);
+ }
+ function getRecordWithOldValue(oldValue) {
+ if (recordWithOldValue) return recordWithOldValue;
+ recordWithOldValue = copyMutationRecord(currentRecord);
+ recordWithOldValue.oldValue = oldValue;
+ return recordWithOldValue;
+ }
+ function clearRecords() {
+ currentRecord = recordWithOldValue = undefined;
+ }
+ function recordRepresentsCurrentMutation(record) {
+ return record === recordWithOldValue || record === currentRecord;
+ }
+ function selectRecord(lastRecord, newRecord) {
+ if (lastRecord === newRecord) return lastRecord;
+ if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;
+ return null;
+ }
+ function Registration(observer, target, options) {
+ this.observer = observer;
+ this.target = target;
+ this.options = options;
+ this.transientObservedNodes = [];
+ }
+ Registration.prototype = {
+ enqueue: function(record) {
+ var records = this.observer.records_;
+ var length = records.length;
+ if (records.length > 0) {
+ var lastRecord = records[length - 1];
+ var recordToReplaceLast = selectRecord(lastRecord, record);
+ if (recordToReplaceLast) {
+ records[length - 1] = recordToReplaceLast;
+ return;
+ }
+ } else {
+ scheduleCallback(this.observer);
+ }
+ records[length] = record;
+ },
+ addListeners: function() {
+ this.addListeners_(this.target);
+ },
+ addListeners_: function(node) {
+ var options = this.options;
+ if (options.attributes) node.addEventListener("DOMAttrModified", this, true);
+ if (options.characterData) node.addEventListener("DOMCharacterDataModified", this, true);
+ if (options.childList) node.addEventListener("DOMNodeInserted", this, true);
+ if (options.childList || options.subtree) node.addEventListener("DOMNodeRemoved", this, true);
+ },
+ removeListeners: function() {
+ this.removeListeners_(this.target);
+ },
+ removeListeners_: function(node) {
+ var options = this.options;
+ if (options.attributes) node.removeEventListener("DOMAttrModified", this, true);
+ if (options.characterData) node.removeEventListener("DOMCharacterDataModified", this, true);
+ if (options.childList) node.removeEventListener("DOMNodeInserted", this, true);
+ if (options.childList || options.subtree) node.removeEventListener("DOMNodeRemoved", this, true);
+ },
+ addTransientObserver: function(node) {
+ if (node === this.target) return;
+ this.addListeners_(node);
+ this.transientObservedNodes.push(node);
+ var registrations = registrationsTable.get(node);
+ if (!registrations) registrationsTable.set(node, registrations = []);
+ registrations.push(this);
+ },
+ removeTransientObservers: function() {
+ var transientObservedNodes = this.transientObservedNodes;
+ this.transientObservedNodes = [];
+ transientObservedNodes.forEach(function(node) {
+ this.removeListeners_(node);
+ var registrations = registrationsTable.get(node);
+ for (var i = 0; i < registrations.length; i++) {
+ if (registrations[i] === this) {
+ registrations.splice(i, 1);
+ break;
+ }
+ }
+ }, this);
+ },
+ handleEvent: function(e) {
+ e.stopImmediatePropagation();
+ switch (e.type) {
+ case "DOMAttrModified":
+ var name = e.attrName;
+ var namespace = e.relatedNode.namespaceURI;
+ var target = e.target;
+ var record = new getRecord("attributes", target);
+ record.attributeName = name;
+ record.attributeNamespace = namespace;
+ var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
+ forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+ if (!options.attributes) return;
+ if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {
+ return;
+ }
+ if (options.attributeOldValue) return getRecordWithOldValue(oldValue);
+ return record;
+ });
+ break;
+
+ case "DOMCharacterDataModified":
+ var target = e.target;
+ var record = getRecord("characterData", target);
+ var oldValue = e.prevValue;
+ forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+ if (!options.characterData) return;
+ if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);
+ return record;
+ });
+ break;
+
+ case "DOMNodeRemoved":
+ this.addTransientObserver(e.target);
+
+ case "DOMNodeInserted":
+ var changedNode = e.target;
+ var addedNodes, removedNodes;
+ if (e.type === "DOMNodeInserted") {
+ addedNodes = [ changedNode ];
+ removedNodes = [];
+ } else {
+ addedNodes = [];
+ removedNodes = [ changedNode ];
+ }
+ var previousSibling = changedNode.previousSibling;
+ var nextSibling = changedNode.nextSibling;
+ var record = getRecord("childList", e.target.parentNode);
+ record.addedNodes = addedNodes;
+ record.removedNodes = removedNodes;
+ record.previousSibling = previousSibling;
+ record.nextSibling = nextSibling;
+ forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) {
+ if (!options.childList) return;
+ return record;
+ });
+ }
+ clearRecords();
+ }
+ };
+ global.JsMutationObserver = JsMutationObserver;
+ if (!global.MutationObserver) global.MutationObserver = JsMutationObserver;
+})(this);
+
+window.HTMLImports = window.HTMLImports || {
+ flags: {}
+};
+
+(function(scope) {
+ var IMPORT_LINK_TYPE = "import";
+ var useNative = Boolean(IMPORT_LINK_TYPE in document.createElement("link"));
+ var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);
+ var wrap = function(node) {
+ return hasShadowDOMPolyfill ? window.ShadowDOMPolyfill.wrapIfNeeded(node) : node;
+ };
+ var rootDocument = wrap(document);
+ var currentScriptDescriptor = {
+ get: function() {
+ var script = window.HTMLImports.currentScript || document.currentScript || (document.readyState !== "complete" ? document.scripts[document.scripts.length - 1] : null);
+ return wrap(script);
+ },
+ configurable: true
+ };
+ Object.defineProperty(document, "_currentScript", currentScriptDescriptor);
+ Object.defineProperty(rootDocument, "_currentScript", currentScriptDescriptor);
+ var isIE = /Trident/.test(navigator.userAgent);
+ function whenReady(callback, doc) {
+ doc = doc || rootDocument;
+ whenDocumentReady(function() {
+ watchImportsLoad(callback, doc);
+ }, doc);
+ }
+ var requiredReadyState = isIE ? "complete" : "interactive";
+ var READY_EVENT = "readystatechange";
+ function isDocumentReady(doc) {
+ return doc.readyState === "complete" || doc.readyState === requiredReadyState;
+ }
+ function whenDocumentReady(callback, doc) {
+ if (!isDocumentReady(doc)) {
+ var checkReady = function() {
+ if (doc.readyState === "complete" || doc.readyState === requiredReadyState) {
+ doc.removeEventListener(READY_EVENT, checkReady);
+ whenDocumentReady(callback, doc);
+ }
+ };
+ doc.addEventListener(READY_EVENT, checkReady);
+ } else if (callback) {
+ callback();
+ }
+ }
+ function markTargetLoaded(event) {
+ event.target.__loaded = true;
+ }
+ function watchImportsLoad(callback, doc) {
+ var imports = doc.querySelectorAll("link[rel=import]");
+ var parsedCount = 0, importCount = imports.length, newImports = [], errorImports = [];
+ function checkDone() {
+ if (parsedCount == importCount && callback) {
+ callback({
+ allImports: imports,
+ loadedImports: newImports,
+ errorImports: errorImports
+ });
+ }
+ }
+ function loadedImport(e) {
+ markTargetLoaded(e);
+ newImports.push(this);
+ parsedCount++;
+ checkDone();
+ }
+ function errorLoadingImport(e) {
+ errorImports.push(this);
+ parsedCount++;
+ checkDone();
+ }
+ if (importCount) {
+ for (var i = 0, imp; i < importCount && (imp = imports[i]); i++) {
+ if (isImportLoaded(imp)) {
+ parsedCount++;
+ checkDone();
+ } else {
+ imp.addEventListener("load", loadedImport);
+ imp.addEventListener("error", errorLoadingImport);
+ }
+ }
+ } else {
+ checkDone();
+ }
+ }
+ function isImportLoaded(link) {
+ return useNative ? link.__loaded || link.import && link.import.readyState !== "loading" : link.__importParsed;
+ }
+ if (useNative) {
+ new MutationObserver(function(mxns) {
+ for (var i = 0, l = mxns.length, m; i < l && (m = mxns[i]); i++) {
+ if (m.addedNodes) {
+ handleImports(m.addedNodes);
+ }
+ }
+ }).observe(document.head, {
+ childList: true
+ });
+ function handleImports(nodes) {
+ for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+ if (isImport(n)) {
+ handleImport(n);
+ }
+ }
+ }
+ function isImport(element) {
+ return element.localName === "link" && element.rel === "import";
+ }
+ function handleImport(element) {
+ var loaded = element.import;
+ if (loaded) {
+ markTargetLoaded({
+ target: element
+ });
+ } else {
+ element.addEventListener("load", markTargetLoaded);
+ element.addEventListener("error", markTargetLoaded);
+ }
+ }
+ (function() {
+ if (document.readyState === "loading") {
+ var imports = document.querySelectorAll("link[rel=import]");
+ for (var i = 0, l = imports.length, imp; i < l && (imp = imports[i]); i++) {
+ handleImport(imp);
+ }
+ }
+ })();
+ }
+ whenReady(function(detail) {
+ window.HTMLImports.ready = true;
+ window.HTMLImports.readyTime = new Date().getTime();
+ var evt = rootDocument.createEvent("CustomEvent");
+ evt.initCustomEvent("HTMLImportsLoaded", true, true, detail);
+ rootDocument.dispatchEvent(evt);
+ });
+ scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
+ scope.useNative = useNative;
+ scope.rootDocument = rootDocument;
+ scope.whenReady = whenReady;
+ scope.isIE = isIE;
+})(window.HTMLImports);
+
+(function(scope) {
+ var modules = [];
+ var addModule = function(module) {
+ modules.push(module);
+ };
+ var initializeModules = function() {
+ modules.forEach(function(module) {
+ module(scope);
+ });
+ };
+ scope.addModule = addModule;
+ scope.initializeModules = initializeModules;
+})(window.HTMLImports);
+
+window.HTMLImports.addModule(function(scope) {
+ var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
+ var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
+ var path = {
+ resolveUrlsInStyle: function(style, linkUrl) {
+ var doc = style.ownerDocument;
+ var resolver = doc.createElement("a");
+ style.textContent = this.resolveUrlsInCssText(style.textContent, linkUrl, resolver);
+ return style;
+ },
+ resolveUrlsInCssText: function(cssText, linkUrl, urlObj) {
+ var r = this.replaceUrls(cssText, urlObj, linkUrl, CSS_URL_REGEXP);
+ r = this.replaceUrls(r, urlObj, linkUrl, CSS_IMPORT_REGEXP);
+ return r;
+ },
+ replaceUrls: function(text, urlObj, linkUrl, regexp) {
+ return text.replace(regexp, function(m, pre, url, post) {
+ var urlPath = url.replace(/["']/g, "");
+ if (linkUrl) {
+ urlPath = new URL(urlPath, linkUrl).href;
+ }
+ urlObj.href = urlPath;
+ urlPath = urlObj.href;
+ return pre + "'" + urlPath + "'" + post;
+ });
+ }
+ };
+ scope.path = path;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var xhr = {
+ async: true,
+ ok: function(request) {
+ return request.status >= 200 && request.status < 300 || request.status === 304 || request.status === 0;
+ },
+ load: function(url, next, nextContext) {
+ var request = new XMLHttpRequest();
+ if (scope.flags.debug || scope.flags.bust) {
+ url += "?" + Math.random();
+ }
+ request.open("GET", url, xhr.async);
+ request.addEventListener("readystatechange", function(e) {
+ if (request.readyState === 4) {
+ var locationHeader = request.getResponseHeader("Location");
+ var redirectedUrl = null;
+ if (locationHeader) {
+ var redirectedUrl = locationHeader.substr(0, 1) === "/" ? location.origin + locationHeader : locationHeader;
+ }
+ next.call(nextContext, !xhr.ok(request) && request, request.response || request.responseText, redirectedUrl);
+ }
+ });
+ request.send();
+ return request;
+ },
+ loadDocument: function(url, next, nextContext) {
+ this.load(url, next, nextContext).responseType = "document";
+ }
+ };
+ scope.xhr = xhr;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var xhr = scope.xhr;
+ var flags = scope.flags;
+ var Loader = function(onLoad, onComplete) {
+ this.cache = {};
+ this.onload = onLoad;
+ this.oncomplete = onComplete;
+ this.inflight = 0;
+ this.pending = {};
+ };
+ Loader.prototype = {
+ addNodes: function(nodes) {
+ this.inflight += nodes.length;
+ for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+ this.require(n);
+ }
+ this.checkDone();
+ },
+ addNode: function(node) {
+ this.inflight++;
+ this.require(node);
+ this.checkDone();
+ },
+ require: function(elt) {
+ var url = elt.src || elt.href;
+ elt.__nodeUrl = url;
+ if (!this.dedupe(url, elt)) {
+ this.fetch(url, elt);
+ }
+ },
+ dedupe: function(url, elt) {
+ if (this.pending[url]) {
+ this.pending[url].push(elt);
+ return true;
+ }
+ var resource;
+ if (this.cache[url]) {
+ this.onload(url, elt, this.cache[url]);
+ this.tail();
+ return true;
+ }
+ this.pending[url] = [ elt ];
+ return false;
+ },
+ fetch: function(url, elt) {
+ flags.load && console.log("fetch", url, elt);
+ if (!url) {
+ setTimeout(function() {
+ this.receive(url, elt, {
+ error: "href must be specified"
+ }, null);
+ }.bind(this), 0);
+ } else if (url.match(/^data:/)) {
+ var pieces = url.split(",");
+ var header = pieces[0];
+ var body = pieces[1];
+ if (header.indexOf(";base64") > -1) {
+ body = atob(body);
+ } else {
+ body = decodeURIComponent(body);
+ }
+ setTimeout(function() {
+ this.receive(url, elt, null, body);
+ }.bind(this), 0);
+ } else {
+ var receiveXhr = function(err, resource, redirectedUrl) {
+ this.receive(url, elt, err, resource, redirectedUrl);
+ }.bind(this);
+ xhr.load(url, receiveXhr);
+ }
+ },
+ receive: function(url, elt, err, resource, redirectedUrl) {
+ this.cache[url] = resource;
+ var $p = this.pending[url];
+ for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
+ this.onload(url, p, resource, err, redirectedUrl);
+ this.tail();
+ }
+ this.pending[url] = null;
+ },
+ tail: function() {
+ --this.inflight;
+ this.checkDone();
+ },
+ checkDone: function() {
+ if (!this.inflight) {
+ this.oncomplete();
+ }
+ }
+ };
+ scope.Loader = Loader;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var Observer = function(addCallback) {
+ this.addCallback = addCallback;
+ this.mo = new MutationObserver(this.handler.bind(this));
+ };
+ Observer.prototype = {
+ handler: function(mutations) {
+ for (var i = 0, l = mutations.length, m; i < l && (m = mutations[i]); i++) {
+ if (m.type === "childList" && m.addedNodes.length) {
+ this.addedNodes(m.addedNodes);
+ }
+ }
+ },
+ addedNodes: function(nodes) {
+ if (this.addCallback) {
+ this.addCallback(nodes);
+ }
+ for (var i = 0, l = nodes.length, n, loading; i < l && (n = nodes[i]); i++) {
+ if (n.children && n.children.length) {
+ this.addedNodes(n.children);
+ }
+ }
+ },
+ observe: function(root) {
+ this.mo.observe(root, {
+ childList: true,
+ subtree: true
+ });
+ }
+ };
+ scope.Observer = Observer;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var path = scope.path;
+ var rootDocument = scope.rootDocument;
+ var flags = scope.flags;
+ var isIE = scope.isIE;
+ var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
+ var IMPORT_SELECTOR = "link[rel=" + IMPORT_LINK_TYPE + "]";
+ var importParser = {
+ documentSelectors: IMPORT_SELECTOR,
+ importsSelectors: [ IMPORT_SELECTOR, "link[rel=stylesheet]", "style", "script:not([type])", 'script[type="application/javascript"]', 'script[type="text/javascript"]' ].join(","),
+ map: {
+ link: "parseLink",
+ script: "parseScript",
+ style: "parseStyle"
+ },
+ dynamicElements: [],
+ parseNext: function() {
+ var next = this.nextToParse();
+ if (next) {
+ this.parse(next);
+ }
+ },
+ parse: function(elt) {
+ if (this.isParsed(elt)) {
+ flags.parse && console.log("[%s] is already parsed", elt.localName);
+ return;
+ }
+ var fn = this[this.map[elt.localName]];
+ if (fn) {
+ this.markParsing(elt);
+ fn.call(this, elt);
+ }
+ },
+ parseDynamic: function(elt, quiet) {
+ this.dynamicElements.push(elt);
+ if (!quiet) {
+ this.parseNext();
+ }
+ },
+ markParsing: function(elt) {
+ flags.parse && console.log("parsing", elt);
+ this.parsingElement = elt;
+ },
+ markParsingComplete: function(elt) {
+ elt.__importParsed = true;
+ this.markDynamicParsingComplete(elt);
+ if (elt.__importElement) {
+ elt.__importElement.__importParsed = true;
+ this.markDynamicParsingComplete(elt.__importElement);
+ }
+ this.parsingElement = null;
+ flags.parse && console.log("completed", elt);
+ },
+ markDynamicParsingComplete: function(elt) {
+ var i = this.dynamicElements.indexOf(elt);
+ if (i >= 0) {
+ this.dynamicElements.splice(i, 1);
+ }
+ },
+ parseImport: function(elt) {
+ if (window.HTMLImports.__importsParsingHook) {
+ window.HTMLImports.__importsParsingHook(elt);
+ }
+ if (elt.import) {
+ elt.import.__importParsed = true;
+ }
+ this.markParsingComplete(elt);
+ if (elt.__resource && !elt.__error) {
+ elt.dispatchEvent(new CustomEvent("load", {
+ bubbles: false
+ }));
+ } else {
+ elt.dispatchEvent(new CustomEvent("error", {
+ bubbles: false
+ }));
+ }
+ if (elt.__pending) {
+ var fn;
+ while (elt.__pending.length) {
+ fn = elt.__pending.shift();
+ if (fn) {
+ fn({
+ target: elt
+ });
+ }
+ }
+ }
+ this.parseNext();
+ },
+ parseLink: function(linkElt) {
+ if (nodeIsImport(linkElt)) {
+ this.parseImport(linkElt);
+ } else {
+ linkElt.href = linkElt.href;
+ this.parseGeneric(linkElt);
+ }
+ },
+ parseStyle: function(elt) {
+ var src = elt;
+ elt = cloneStyle(elt);
+ src.__appliedElement = elt;
+ elt.__importElement = src;
+ this.parseGeneric(elt);
+ },
+ parseGeneric: function(elt) {
+ this.trackElement(elt);
+ this.addElementToDocument(elt);
+ },
+ rootImportForElement: function(elt) {
+ var n = elt;
+ while (n.ownerDocument.__importLink) {
+ n = n.ownerDocument.__importLink;
+ }
+ return n;
+ },
+ addElementToDocument: function(elt) {
+ var port = this.rootImportForElement(elt.__importElement || elt);
+ port.parentNode.insertBefore(elt, port);
+ },
+ trackElement: function(elt, callback) {
+ var self = this;
+ var done = function(e) {
+ if (callback) {
+ callback(e);
+ }
+ self.markParsingComplete(elt);
+ self.parseNext();
+ };
+ elt.addEventListener("load", done);
+ elt.addEventListener("error", done);
+ if (isIE && elt.localName === "style") {
+ var fakeLoad = false;
+ if (elt.textContent.indexOf("@import") == -1) {
+ fakeLoad = true;
+ } else if (elt.sheet) {
+ fakeLoad = true;
+ var csr = elt.sheet.cssRules;
+ var len = csr ? csr.length : 0;
+ for (var i = 0, r; i < len && (r = csr[i]); i++) {
+ if (r.type === CSSRule.IMPORT_RULE) {
+ fakeLoad = fakeLoad && Boolean(r.styleSheet);
+ }
+ }
+ }
+ if (fakeLoad) {
+ setTimeout(function() {
+ elt.dispatchEvent(new CustomEvent("load", {
+ bubbles: false
+ }));
+ });
+ }
+ }
+ },
+ parseScript: function(scriptElt) {
+ var script = document.createElement("script");
+ script.__importElement = scriptElt;
+ script.src = scriptElt.src ? scriptElt.src : generateScriptDataUrl(scriptElt);
+ scope.currentScript = scriptElt;
+ this.trackElement(script, function(e) {
+ script.parentNode.removeChild(script);
+ scope.currentScript = null;
+ });
+ this.addElementToDocument(script);
+ },
+ nextToParse: function() {
+ this._mayParse = [];
+ return !this.parsingElement && (this.nextToParseInDoc(rootDocument) || this.nextToParseDynamic());
+ },
+ nextToParseInDoc: function(doc, link) {
+ if (doc && this._mayParse.indexOf(doc) < 0) {
+ this._mayParse.push(doc);
+ var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));
+ for (var i = 0, l = nodes.length, p = 0, n; i < l && (n = nodes[i]); i++) {
+ if (!this.isParsed(n)) {
+ if (this.hasResource(n)) {
+ return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n;
+ } else {
+ return;
+ }
+ }
+ }
+ }
+ return link;
+ },
+ nextToParseDynamic: function() {
+ return this.dynamicElements[0];
+ },
+ parseSelectorsForNode: function(node) {
+ var doc = node.ownerDocument || node;
+ return doc === rootDocument ? this.documentSelectors : this.importsSelectors;
+ },
+ isParsed: function(node) {
+ return node.__importParsed;
+ },
+ needsDynamicParsing: function(elt) {
+ return this.dynamicElements.indexOf(elt) >= 0;
+ },
+ hasResource: function(node) {
+ if (nodeIsImport(node) && node.import === undefined) {
+ return false;
+ }
+ return true;
+ }
+ };
+ function nodeIsImport(elt) {
+ return elt.localName === "link" && elt.rel === IMPORT_LINK_TYPE;
+ }
+ function generateScriptDataUrl(script) {
+ var scriptContent = generateScriptContent(script);
+ return "data:text/javascript;charset=utf-8," + encodeURIComponent(scriptContent);
+ }
+ function generateScriptContent(script) {
+ return script.textContent + generateSourceMapHint(script);
+ }
+ function generateSourceMapHint(script) {
+ var owner = script.ownerDocument;
+ owner.__importedScripts = owner.__importedScripts || 0;
+ var moniker = script.ownerDocument.baseURI;
+ var num = owner.__importedScripts ? "-" + owner.__importedScripts : "";
+ owner.__importedScripts++;
+ return "\n//# sourceURL=" + moniker + num + ".js\n";
+ }
+ function cloneStyle(style) {
+ var clone = style.ownerDocument.createElement("style");
+ clone.textContent = style.textContent;
+ path.resolveUrlsInStyle(clone);
+ return clone;
+ }
+ scope.parser = importParser;
+ scope.IMPORT_SELECTOR = IMPORT_SELECTOR;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var flags = scope.flags;
+ var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
+ var IMPORT_SELECTOR = scope.IMPORT_SELECTOR;
+ var rootDocument = scope.rootDocument;
+ var Loader = scope.Loader;
+ var Observer = scope.Observer;
+ var parser = scope.parser;
+ var importer = {
+ documents: {},
+ documentPreloadSelectors: IMPORT_SELECTOR,
+ importsPreloadSelectors: [ IMPORT_SELECTOR ].join(","),
+ loadNode: function(node) {
+ importLoader.addNode(node);
+ },
+ loadSubtree: function(parent) {
+ var nodes = this.marshalNodes(parent);
+ importLoader.addNodes(nodes);
+ },
+ marshalNodes: function(parent) {
+ return parent.querySelectorAll(this.loadSelectorsForNode(parent));
+ },
+ loadSelectorsForNode: function(node) {
+ var doc = node.ownerDocument || node;
+ return doc === rootDocument ? this.documentPreloadSelectors : this.importsPreloadSelectors;
+ },
+ loaded: function(url, elt, resource, err, redirectedUrl) {
+ flags.load && console.log("loaded", url, elt);
+ elt.__resource = resource;
+ elt.__error = err;
+ if (isImportLink(elt)) {
+ var doc = this.documents[url];
+ if (doc === undefined) {
+ doc = err ? null : makeDocument(resource, redirectedUrl || url);
+ if (doc) {
+ doc.__importLink = elt;
+ this.bootDocument(doc);
+ }
+ this.documents[url] = doc;
+ }
+ elt.import = doc;
+ }
+ parser.parseNext();
+ },
+ bootDocument: function(doc) {
+ this.loadSubtree(doc);
+ this.observer.observe(doc);
+ parser.parseNext();
+ },
+ loadedAll: function() {
+ parser.parseNext();
+ }
+ };
+ var importLoader = new Loader(importer.loaded.bind(importer), importer.loadedAll.bind(importer));
+ importer.observer = new Observer();
+ function isImportLink(elt) {
+ return isLinkRel(elt, IMPORT_LINK_TYPE);
+ }
+ function isLinkRel(elt, rel) {
+ return elt.localName === "link" && elt.getAttribute("rel") === rel;
+ }
+ function hasBaseURIAccessor(doc) {
+ return !!Object.getOwnPropertyDescriptor(doc, "baseURI");
+ }
+ function makeDocument(resource, url) {
+ var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);
+ doc._URL = url;
+ var base = doc.createElement("base");
+ base.setAttribute("href", url);
+ if (!doc.baseURI && !hasBaseURIAccessor(doc)) {
+ Object.defineProperty(doc, "baseURI", {
+ value: url
+ });
+ }
+ var meta = doc.createElement("meta");
+ meta.setAttribute("charset", "utf-8");
+ doc.head.appendChild(meta);
+ doc.head.appendChild(base);
+ doc.body.innerHTML = resource;
+ if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
+ HTMLTemplateElement.bootstrap(doc);
+ }
+ return doc;
+ }
+ if (!document.baseURI) {
+ var baseURIDescriptor = {
+ get: function() {
+ var base = document.querySelector("base");
+ return base ? base.href : window.location.href;
+ },
+ configurable: true
+ };
+ Object.defineProperty(document, "baseURI", baseURIDescriptor);
+ Object.defineProperty(rootDocument, "baseURI", baseURIDescriptor);
+ }
+ scope.importer = importer;
+ scope.importLoader = importLoader;
+});
+
+window.HTMLImports.addModule(function(scope) {
+ var parser = scope.parser;
+ var importer = scope.importer;
+ var dynamic = {
+ added: function(nodes) {
+ var owner, parsed, loading;
+ for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+ if (!owner) {
+ owner = n.ownerDocument;
+ parsed = parser.isParsed(owner);
+ }
+ loading = this.shouldLoadNode(n);
+ if (loading) {
+ importer.loadNode(n);
+ }
+ if (this.shouldParseNode(n) && parsed) {
+ parser.parseDynamic(n, loading);
+ }
+ }
+ },
+ shouldLoadNode: function(node) {
+ return node.nodeType === 1 && matches.call(node, importer.loadSelectorsForNode(node));
+ },
+ shouldParseNode: function(node) {
+ return node.nodeType === 1 && matches.call(node, parser.parseSelectorsForNode(node));
+ }
+ };
+ importer.observer.addCallback = dynamic.added.bind(dynamic);
+ var matches = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector;
+});
+
+(function(scope) {
+ var initializeModules = scope.initializeModules;
+ var isIE = scope.isIE;
+ if (scope.useNative) {
+ return;
+ }
+ if (isIE && typeof window.CustomEvent !== "function") {
+ window.CustomEvent = function(inType, params) {
+ params = params || {};
+ var e = document.createEvent("CustomEvent");
+ e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
+ e.preventDefault = function() {
+ Object.defineProperty(this, "defaultPrevented", {
+ get: function() {
+ return true;
+ }
+ });
+ };
+ return e;
+ };
+ window.CustomEvent.prototype = window.Event.prototype;
+ }
+ initializeModules();
+ var rootDocument = scope.rootDocument;
+ function bootstrap() {
+ window.HTMLImports.importer.bootDocument(rootDocument);
+ }
+ if (document.readyState === "complete" || document.readyState === "interactive" && !window.attachEvent) {
+ bootstrap();
+ } else {
+ document.addEventListener("DOMContentLoaded", bootstrap);
+ }
+})(window.HTMLImports);
+
+window.CustomElements = window.CustomElements || {
+ flags: {}
+};
+
+(function(scope) {
+ var flags = scope.flags;
+ var modules = [];
+ var addModule = function(module) {
+ modules.push(module);
+ };
+ var initializeModules = function() {
+ modules.forEach(function(module) {
+ module(scope);
+ });
+ };
+ scope.addModule = addModule;
+ scope.initializeModules = initializeModules;
+ scope.hasNative = Boolean(document.registerElement);
+ scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || window.HTMLImports.useNative);
+})(window.CustomElements);
+
+window.CustomElements.addModule(function(scope) {
+ var IMPORT_LINK_TYPE = window.HTMLImports ? window.HTMLImports.IMPORT_LINK_TYPE : "none";
+ function forSubtree(node, cb) {
+ findAllElements(node, function(e) {
+ if (cb(e)) {
+ return true;
+ }
+ forRoots(e, cb);
+ });
+ forRoots(node, cb);
+ }
+ function findAllElements(node, find, data) {
+ var e = node.firstElementChild;
+ if (!e) {
+ e = node.firstChild;
+ while (e && e.nodeType !== Node.ELEMENT_NODE) {
+ e = e.nextSibling;
+ }
+ }
+ while (e) {
+ if (find(e, data) !== true) {
+ findAllElements(e, find, data);
+ }
+ e = e.nextElementSibling;
+ }
+ return null;
+ }
+ function forRoots(node, cb) {
+ var root = node.shadowRoot;
+ while (root) {
+ forSubtree(root, cb);
+ root = root.olderShadowRoot;
+ }
+ }
+ function forDocumentTree(doc, cb) {
+ _forDocumentTree(doc, cb, []);
+ }
+ function _forDocumentTree(doc, cb, processingDocuments) {
+ doc = window.wrap(doc);
+ if (processingDocuments.indexOf(doc) >= 0) {
+ return;
+ }
+ processingDocuments.push(doc);
+ var imports = doc.querySelectorAll("link[rel=" + IMPORT_LINK_TYPE + "]");
+ for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) {
+ if (n.import) {
+ _forDocumentTree(n.import, cb, processingDocuments);
+ }
+ }
+ cb(doc);
+ }
+ scope.forDocumentTree = forDocumentTree;
+ scope.forSubtree = forSubtree;
+});
+
+window.CustomElements.addModule(function(scope) {
+ var flags = scope.flags;
+ var forSubtree = scope.forSubtree;
+ var forDocumentTree = scope.forDocumentTree;
+ function addedNode(node) {
+ return added(node) || addedSubtree(node);
+ }
+ function added(node) {
+ if (scope.upgrade(node)) {
+ return true;
+ }
+ attached(node);
+ }
+ function addedSubtree(node) {
+ forSubtree(node, function(e) {
+ if (added(e)) {
+ return true;
+ }
+ });
+ }
+ function attachedNode(node) {
+ attached(node);
+ if (inDocument(node)) {
+ forSubtree(node, function(e) {
+ attached(e);
+ });
+ }
+ }
+ var hasPolyfillMutations = !window.MutationObserver || window.MutationObserver === window.JsMutationObserver;
+ scope.hasPolyfillMutations = hasPolyfillMutations;
+ var isPendingMutations = false;
+ var pendingMutations = [];
+ function deferMutation(fn) {
+ pendingMutations.push(fn);
+ if (!isPendingMutations) {
+ isPendingMutations = true;
+ setTimeout(takeMutations);
+ }
+ }
+ function takeMutations() {
+ isPendingMutations = false;
+ var $p = pendingMutations;
+ for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
+ p();
+ }
+ pendingMutations = [];
+ }
+ function attached(element) {
+ if (hasPolyfillMutations) {
+ deferMutation(function() {
+ _attached(element);
+ });
+ } else {
+ _attached(element);
+ }
+ }
+ function _attached(element) {
+ if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
+ if (!element.__attached && inDocument(element)) {
+ element.__attached = true;
+ if (element.attachedCallback) {
+ element.attachedCallback();
+ }
+ }
+ }
+ }
+ function detachedNode(node) {
+ detached(node);
+ forSubtree(node, function(e) {
+ detached(e);
+ });
+ }
+ function detached(element) {
+ if (hasPolyfillMutations) {
+ deferMutation(function() {
+ _detached(element);
+ });
+ } else {
+ _detached(element);
+ }
+ }
+ function _detached(element) {
+ if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
+ if (element.__attached && !inDocument(element)) {
+ element.__attached = false;
+ if (element.detachedCallback) {
+ element.detachedCallback();
+ }
+ }
+ }
+ }
+ function inDocument(element) {
+ var p = element;
+ var doc = wrap(document);
+ while (p) {
+ if (p == doc) {
+ return true;
+ }
+ p = p.parentNode || p.nodeType === Node.DOCUMENT_FRAGMENT_NODE && p.host;
+ }
+ }
+ function watchShadow(node) {
+ if (node.shadowRoot && !node.shadowRoot.__watched) {
+ flags.dom && console.log("watching shadow-root for: ", node.localName);
+ var root = node.shadowRoot;
+ while (root) {
+ observe(root);
+ root = root.olderShadowRoot;
+ }
+ }
+ }
+ function handler(mutations) {
+ if (flags.dom) {
+ var mx = mutations[0];
+ if (mx && mx.type === "childList" && mx.addedNodes) {
+ if (mx.addedNodes) {
+ var d = mx.addedNodes[0];
+ while (d && d !== document && !d.host) {
+ d = d.parentNode;
+ }
+ var u = d && (d.URL || d._URL || d.host && d.host.localName) || "";
+ u = u.split("/?").shift().split("/").pop();
+ }
+ }
+ console.group("mutations (%d) [%s]", mutations.length, u || "");
+ }
+ mutations.forEach(function(mx) {
+ if (mx.type === "childList") {
+ forEach(mx.addedNodes, function(n) {
+ if (!n.localName) {
+ return;
+ }
+ addedNode(n);
+ });
+ forEach(mx.removedNodes, function(n) {
+ if (!n.localName) {
+ return;
+ }
+ detachedNode(n);
+ });
+ }
+ });
+ flags.dom && console.groupEnd();
+ }
+ function takeRecords(node) {
+ node = window.wrap(node);
+ if (!node) {
+ node = window.wrap(document);
+ }
+ while (node.parentNode) {
+ node = node.parentNode;
+ }
+ var observer = node.__observer;
+ if (observer) {
+ handler(observer.takeRecords());
+ takeMutations();
+ }
+ }
+ var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
+ function observe(inRoot) {
+ if (inRoot.__observer) {
+ return;
+ }
+ var observer = new MutationObserver(handler);
+ observer.observe(inRoot, {
+ childList: true,
+ subtree: true
+ });
+ inRoot.__observer = observer;
+ }
+ function upgradeDocument(doc) {
+ doc = window.wrap(doc);
+ flags.dom && console.group("upgradeDocument: ", doc.baseURI.split("/").pop());
+ addedNode(doc);
+ observe(doc);
+ flags.dom && console.groupEnd();
+ }
+ function upgradeDocumentTree(doc) {
+ forDocumentTree(doc, upgradeDocument);
+ }
+ var originalCreateShadowRoot = Element.prototype.createShadowRoot;
+ if (originalCreateShadowRoot) {
+ Element.prototype.createShadowRoot = function() {
+ var root = originalCreateShadowRoot.call(this);
+ window.CustomElements.watchShadow(this);
+ return root;
+ };
+ }
+ scope.watchShadow = watchShadow;
+ scope.upgradeDocumentTree = upgradeDocumentTree;
+ scope.upgradeSubtree = addedSubtree;
+ scope.upgradeAll = addedNode;
+ scope.attachedNode = attachedNode;
+ scope.takeRecords = takeRecords;
+});
+
+window.CustomElements.addModule(function(scope) {
+ var flags = scope.flags;
+ function upgrade(node) {
+ if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {
+ var is = node.getAttribute("is");
+ var definition = scope.getRegisteredDefinition(is || node.localName);
+ if (definition) {
+ if (is && definition.tag == node.localName) {
+ return upgradeWithDefinition(node, definition);
+ } else if (!is && !definition.extends) {
+ return upgradeWithDefinition(node, definition);
+ }
+ }
+ }
+ }
+ function upgradeWithDefinition(element, definition) {
+ flags.upgrade && console.group("upgrade:", element.localName);
+ if (definition.is) {
+ element.setAttribute("is", definition.is);
+ }
+ implementPrototype(element, definition);
+ element.__upgraded__ = true;
+ created(element);
+ scope.attachedNode(element);
+ scope.upgradeSubtree(element);
+ flags.upgrade && console.groupEnd();
+ return element;
+ }
+ function implementPrototype(element, definition) {
+ if (Object.__proto__) {
+ element.__proto__ = definition.prototype;
+ } else {
+ customMixin(element, definition.prototype, definition.native);
+ element.__proto__ = definition.prototype;
+ }
+ }
+ function customMixin(inTarget, inSrc, inNative) {
+ var used = {};
+ var p = inSrc;
+ while (p !== inNative && p !== HTMLElement.prototype) {
+ var keys = Object.getOwnPropertyNames(p);
+ for (var i = 0, k; k = keys[i]; i++) {
+ if (!used[k]) {
+ Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k));
+ used[k] = 1;
+ }
+ }
+ p = Object.getPrototypeOf(p);
+ }
+ }
+ function created(element) {
+ if (element.createdCallback) {
+ element.createdCallback();
+ }
+ }
+ scope.upgrade = upgrade;
+ scope.upgradeWithDefinition = upgradeWithDefinition;
+ scope.implementPrototype = implementPrototype;
+});
+
+window.CustomElements.addModule(function(scope) {
+ var isIE11OrOlder = scope.isIE11OrOlder;
+ var upgradeDocumentTree = scope.upgradeDocumentTree;
+ var upgradeAll = scope.upgradeAll;
+ var upgradeWithDefinition = scope.upgradeWithDefinition;
+ var implementPrototype = scope.implementPrototype;
+ var useNative = scope.useNative;
+ function register(name, options) {
+ var definition = options || {};
+ if (!name) {
+ throw new Error("document.registerElement: first argument `name` must not be empty");
+ }
+ if (name.indexOf("-") < 0) {
+ throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '" + String(name) + "'.");
+ }
+ if (isReservedTag(name)) {
+ throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '" + String(name) + "'. The type name is invalid.");
+ }
+ if (getRegisteredDefinition(name)) {
+ throw new Error("DuplicateDefinitionError: a type with name '" + String(name) + "' is already registered");
+ }
+ if (!definition.prototype) {
+ definition.prototype = Object.create(HTMLElement.prototype);
+ }
+ definition.__name = name.toLowerCase();
+ definition.lifecycle = definition.lifecycle || {};
+ definition.ancestry = ancestry(definition.extends);
+ resolveTagName(definition);
+ resolvePrototypeChain(definition);
+ overrideAttributeApi(definition.prototype);
+ registerDefinition(definition.__name, definition);
+ definition.ctor = generateConstructor(definition);
+ definition.ctor.prototype = definition.prototype;
+ definition.prototype.constructor = definition.ctor;
+ if (scope.ready) {
+ upgradeDocumentTree(document);
+ }
+ return definition.ctor;
+ }
+ function overrideAttributeApi(prototype) {
+ if (prototype.setAttribute._polyfilled) {
+ return;
+ }
+ var setAttribute = prototype.setAttribute;
+ prototype.setAttribute = function(name, value) {
+ changeAttribute.call(this, name, value, setAttribute);
+ };
+ var removeAttribute = prototype.removeAttribute;
+ prototype.removeAttribute = function(name) {
+ changeAttribute.call(this, name, null, removeAttribute);
+ };
+ prototype.setAttribute._polyfilled = true;
+ }
+ function changeAttribute(name, value, operation) {
+ name = name.toLowerCase();
+ var oldValue = this.getAttribute(name);
+ operation.apply(this, arguments);
+ var newValue = this.getAttribute(name);
+ if (this.attributeChangedCallback && newValue !== oldValue) {
+ this.attributeChangedCallback(name, oldValue, newValue);
+ }
+ }
+ function isReservedTag(name) {
+ for (var i = 0; i < reservedTagList.length; i++) {
+ if (name === reservedTagList[i]) {
+ return true;
+ }
+ }
+ }
+ var reservedTagList = [ "annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph" ];
+ function ancestry(extnds) {
+ var extendee = getRegisteredDefinition(extnds);
+ if (extendee) {
+ return ancestry(extendee.extends).concat([ extendee ]);
+ }
+ return [];
+ }
+ function resolveTagName(definition) {
+ var baseTag = definition.extends;
+ for (var i = 0, a; a = definition.ancestry[i]; i++) {
+ baseTag = a.is && a.tag;
+ }
+ definition.tag = baseTag || definition.__name;
+ if (baseTag) {
+ definition.is = definition.__name;
+ }
+ }
+ function resolvePrototypeChain(definition) {
+ if (!Object.__proto__) {
+ var nativePrototype = HTMLElement.prototype;
+ if (definition.is) {
+ var inst = document.createElement(definition.tag);
+ var expectedPrototype = Object.getPrototypeOf(inst);
+ if (expectedPrototype === definition.prototype) {
+ nativePrototype = expectedPrototype;
+ }
+ }
+ var proto = definition.prototype, ancestor;
+ while (proto && proto !== nativePrototype) {
+ ancestor = Object.getPrototypeOf(proto);
+ proto.__proto__ = ancestor;
+ proto = ancestor;
+ }
+ definition.native = nativePrototype;
+ }
+ }
+ function instantiate(definition) {
+ return upgradeWithDefinition(domCreateElement(definition.tag), definition);
+ }
+ var registry = {};
+ function getRegisteredDefinition(name) {
+ if (name) {
+ return registry[name.toLowerCase()];
+ }
+ }
+ function registerDefinition(name, definition) {
+ registry[name] = definition;
+ }
+ function generateConstructor(definition) {
+ return function() {
+ return instantiate(definition);
+ };
+ }
+ var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
+ function createElementNS(namespace, tag, typeExtension) {
+ if (namespace === HTML_NAMESPACE) {
+ return createElement(tag, typeExtension);
+ } else {
+ return domCreateElementNS(namespace, tag);
+ }
+ }
+ function createElement(tag, typeExtension) {
+ if (tag) {
+ tag = tag.toLowerCase();
+ }
+ if (typeExtension) {
+ typeExtension = typeExtension.toLowerCase();
+ }
+ var definition = getRegisteredDefinition(typeExtension || tag);
+ if (definition) {
+ if (tag == definition.tag && typeExtension == definition.is) {
+ return new definition.ctor();
+ }
+ if (!typeExtension && !definition.is) {
+ return new definition.ctor();
+ }
+ }
+ var element;
+ if (typeExtension) {
+ element = createElement(tag);
+ element.setAttribute("is", typeExtension);
+ return element;
+ }
+ element = domCreateElement(tag);
+ if (tag.indexOf("-") >= 0) {
+ implementPrototype(element, HTMLElement);
+ }
+ return element;
+ }
+ var domCreateElement = document.createElement.bind(document);
+ var domCreateElementNS = document.createElementNS.bind(document);
+ var isInstance;
+ if (!Object.__proto__ && !useNative) {
+ isInstance = function(obj, ctor) {
+ var p = obj;
+ while (p) {
+ if (p === ctor.prototype) {
+ return true;
+ }
+ p = p.__proto__;
+ }
+ return false;
+ };
+ } else {
+ isInstance = function(obj, base) {
+ return obj instanceof base;
+ };
+ }
+ function wrapDomMethodToForceUpgrade(obj, methodName) {
+ var orig = obj[methodName];
+ obj[methodName] = function() {
+ var n = orig.apply(this, arguments);
+ upgradeAll(n);
+ return n;
+ };
+ }
+ wrapDomMethodToForceUpgrade(Node.prototype, "cloneNode");
+ wrapDomMethodToForceUpgrade(document, "importNode");
+ if (isIE11OrOlder) {
+ (function() {
+ var importNode = document.importNode;
+ document.importNode = function() {
+ var n = importNode.apply(document, arguments);
+ if (n.nodeType == n.DOCUMENT_FRAGMENT_NODE) {
+ var f = document.createDocumentFragment();
+ f.appendChild(n);
+ return f;
+ } else {
+ return n;
+ }
+ };
+ })();
+ }
+ document.registerElement = register;
+ document.createElement = createElement;
+ document.createElementNS = createElementNS;
+ scope.registry = registry;
+ scope.instanceof = isInstance;
+ scope.reservedTagList = reservedTagList;
+ scope.getRegisteredDefinition = getRegisteredDefinition;
+ document.register = document.registerElement;
+});
+
+(function(scope) {
+ var useNative = scope.useNative;
+ var initializeModules = scope.initializeModules;
+ var isIE11OrOlder = /Trident/.test(navigator.userAgent);
+ if (useNative) {
+ var nop = function() {};
+ scope.watchShadow = nop;
+ scope.upgrade = nop;
+ scope.upgradeAll = nop;
+ scope.upgradeDocumentTree = nop;
+ scope.upgradeSubtree = nop;
+ scope.takeRecords = nop;
+ scope.instanceof = function(obj, base) {
+ return obj instanceof base;
+ };
+ } else {
+ initializeModules();
+ }
+ var upgradeDocumentTree = scope.upgradeDocumentTree;
+ if (!window.wrap) {
+ if (window.ShadowDOMPolyfill) {
+ window.wrap = window.ShadowDOMPolyfill.wrapIfNeeded;
+ window.unwrap = window.ShadowDOMPolyfill.unwrapIfNeeded;
+ } else {
+ window.wrap = window.unwrap = function(node) {
+ return node;
+ };
+ }
+ }
+ function bootstrap() {
+ upgradeDocumentTree(window.wrap(document));
+ if (window.HTMLImports) {
+ window.HTMLImports.__importsParsingHook = function(elt) {
+ upgradeDocumentTree(wrap(elt.import));
+ };
+ }
+ window.CustomElements.ready = true;
+ setTimeout(function() {
+ window.CustomElements.readyTime = Date.now();
+ if (window.HTMLImports) {
+ window.CustomElements.elapsed = window.CustomElements.readyTime - window.HTMLImports.readyTime;
+ }
+ document.dispatchEvent(new CustomEvent("WebComponentsReady", {
+ bubbles: true
+ }));
+ });
+ }
+ if (isIE11OrOlder && typeof window.CustomEvent !== "function") {
+ window.CustomEvent = function(inType, params) {
+ params = params || {};
+ var e = document.createEvent("CustomEvent");
+ e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
+ e.preventDefault = function() {
+ Object.defineProperty(this, "defaultPrevented", {
+ get: function() {
+ return true;
+ }
+ });
+ };
+ return e;
+ };
+ window.CustomEvent.prototype = window.Event.prototype;
+ }
+ if (document.readyState === "complete" || scope.flags.eager) {
+ bootstrap();
+ } else if (document.readyState === "interactive" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) {
+ bootstrap();
+ } else {
+ var loadEvent = window.HTMLImports && !window.HTMLImports.ready ? "HTMLImportsLoaded" : "DOMContentLoaded";
+ window.addEventListener(loadEvent, bootstrap);
+ }
+ scope.isIE11OrOlder = isIE11OrOlder;
+})(window.CustomElements);
+
+(function(scope) {
+ if (!Function.prototype.bind) {
+ Function.prototype.bind = function(scope) {
+ var self = this;
+ var args = Array.prototype.slice.call(arguments, 1);
+ return function() {
+ var args2 = args.slice();
+ args2.push.apply(args2, arguments);
+ return self.apply(scope, args2);
+ };
+ };
+ }
+})(window.WebComponents);
+
+(function(scope) {
+ "use strict";
+ if (!window.performance) {
+ var start = Date.now();
+ window.performance = {
+ now: function() {
+ return Date.now() - start;
+ }
+ };
+ }
+ if (!window.requestAnimationFrame) {
+ window.requestAnimationFrame = function() {
+ var nativeRaf = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
+ return nativeRaf ? function(callback) {
+ return nativeRaf(function() {
+ callback(performance.now());
+ });
+ } : function(callback) {
+ return window.setTimeout(callback, 1e3 / 60);
+ };
+ }();
+ }
+ if (!window.cancelAnimationFrame) {
+ window.cancelAnimationFrame = function() {
+ return window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function(id) {
+ clearTimeout(id);
+ };
+ }();
+ }
+ var elementDeclarations = [];
+ var polymerStub = function(name, dictionary) {
+ if (typeof name !== "string" && arguments.length === 1) {
+ Array.prototype.push.call(arguments, document._currentScript);
+ }
+ elementDeclarations.push(arguments);
+ };
+ window.Polymer = polymerStub;
+ scope.consumeDeclarations = function(callback) {
+ scope.consumeDeclarations = function() {
+ throw "Possible attempt to load Polymer twice";
+ };
+ if (callback) {
+ callback(elementDeclarations);
+ }
+ elementDeclarations = null;
+ };
+ function installPolymerWarning() {
+ if (window.Polymer === polymerStub) {
+ window.Polymer = function() {
+ throw new Error("You tried to use polymer without loading it first. To " + 'load polymer, <link rel="import" href="' + 'components/polymer/polymer.html">');
+ };
+ }
+ }
+ if (HTMLImports.useNative) {
+ installPolymerWarning();
+ } else {
+ window.addEventListener("DOMContentLoaded", installPolymerWarning);
+ }
+})(window.WebComponents);
+
+(function(scope) {
+ var style = document.createElement("style");
+ style.textContent = "" + "body {" + "transition: opacity ease-in 0.2s;" + " } \n" + "body[unresolved] {" + "opacity: 0; display: block; overflow: hidden; position: relative;" + " } \n";
+ var head = document.querySelector("head");
+ head.insertBefore(style, head.firstChild);
+})(window.WebComponents);
+
+(function(scope) {
+ window.Platform = scope;
+})(window.WebComponents);
\ No newline at end of file
diff --git a/polymer_1.0.4/bower_components/webcomponentsjs/webcomponents.min.js b/polymer_1.0.4/bower_components/webcomponentsjs/webcomponents.min.js
new file mode 100644
index 0000000..4870c72
--- /dev/null
+++ b/polymer_1.0.4/bower_components/webcomponentsjs/webcomponents.min.js
@@ -0,0 +1,15 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.7.5
+window.WebComponents=window.WebComponents||{},function(e){var t=e.flags||{},n="webcomponents.js",r=document.querySelector('script[src*="'+n+'"]');if(!t.noOpts){if(location.search.slice(1).split("&").forEach(function(e){var n,r=e.split("=");r[0]&&(n=r[0].match(/wc-(.+)/))&&(t[n[1]]=r[1]||!0)}),r)for(var o,i=0;o=r.attributes[i];i++)"src"!==o.name&&(t[o.name]=o.value||!0);if(t.log&&t.log.split){var a=t.log.split(",");t.log={},a.forEach(function(e){t.log[e]=!0})}else t.log={}}t.shadow=t.shadow||t.shadowdom||t.polyfill,t.shadow="native"===t.shadow?!1:t.shadow||!HTMLElement.prototype.createShadowRoot,t.register&&(window.CustomElements=window.CustomElements||{flags:{}},window.CustomElements.flags.register=t.register),e.flags=t}(WebComponents),WebComponents.flags.shadow&&("undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,n=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};n.prototype={set:function(t,n){var r=t[this.name];return r&&r[0]===t?r[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),window.ShadowDOMPolyfill={},function(e){"use strict";function t(){if("undefined"!=typeof chrome&&chrome.app&&chrome.app.runtime)return!1;if(navigator.getDeviceStorage)return!1;try{var e=new Function("return true;");return e()}catch(t){return!1}}function n(e){if(!e)throw new Error("Assertion failed")}function r(e,t){for(var n=W(t),r=0;r<n.length;r++){var o=n[r];A(e,o,F(t,o))}return e}function o(e,t){for(var n=W(t),r=0;r<n.length;r++){var o=n[r];switch(o){case"arguments":case"caller":case"length":case"name":case"prototype":case"toString":continue}A(e,o,F(t,o))}return e}function i(e,t){for(var n=0;n<t.length;n++)if(t[n]in e)return t[n]}function a(e,t,n){U.value=n,A(e,t,U)}function s(e,t){var n=e.__proto__||Object.getPrototypeOf(e);if(q)try{W(n)}catch(r){n=n.__proto__}var o=R.get(n);if(o)return o;var i=s(n),a=E(i);return g(n,a,t),a}function c(e,t){w(e,t,!0)}function l(e,t){w(t,e,!1)}function u(e){return/^on[a-z]+$/.test(e)}function d(e){return/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(e)}function p(e){return k&&d(e)?new Function("return this.__impl4cf1e782hg__."+e):function(){return this.__impl4cf1e782hg__[e]}}function h(e){return k&&d(e)?new Function("v","this.__impl4cf1e782hg__."+e+" = v"):function(t){this.__impl4cf1e782hg__[e]=t}}function f(e){return k&&d(e)?new Function("return this.__impl4cf1e782hg__."+e+".apply(this.__impl4cf1e782hg__, arguments)"):function(){return this.__impl4cf1e782hg__[e].apply(this.__impl4cf1e782hg__,arguments)}}function m(e,t){try{return Object.getOwnPropertyDescriptor(e,t)}catch(n){return B}}function w(t,n,r,o){for(var i=W(t),a=0;a<i.length;a++){var s=i[a];if("polymerBlackList_"!==s&&!(s in n||t.polymerBlackList_&&t.polymerBlackList_[s])){q&&t.__lookupGetter__(s);var c,l,d=m(t,s);if("function"!=typeof d.value){var w=u(s);c=w?e.getEventHandlerGetter(s):p(s),(d.writable||d.set||V)&&(l=w?e.getEventHandlerSetter(s):h(s));var v=V||d.configurable;A(n,s,{get:c,set:l,configurable:v,enumerable:d.enumerable})}else r&&(n[s]=f(s))}}}function v(e,t,n){if(null!=e){var r=e.prototype;g(r,t,n),o(t,e)}}function g(e,t,r){var o=t.prototype;n(void 0===R.get(e)),R.set(e,t),I.set(o,e),c(e,o),r&&l(o,r),a(o,"constructor",t),t.prototype=o}function b(e,t){return R.get(t.prototype)===e}function y(e){var t=Object.getPrototypeOf(e),n=s(t),r=E(n);return g(t,r,e),r}function E(e){function t(t){e.call(this,t)}var n=Object.create(e.prototype);return n.constructor=t,t.prototype=n,t}function _(e){return e&&e.__impl4cf1e782hg__}function S(e){return!_(e)}function T(e){if(null===e)return null;n(S(e));var t=e.__wrapper8e3dd93a60__;return null!=t?t:e.__wrapper8e3dd93a60__=new(s(e,e))(e)}function M(e){return null===e?null:(n(_(e)),e.__impl4cf1e782hg__)}function O(e){return e.__impl4cf1e782hg__}function L(e,t){t.__impl4cf1e782hg__=e,e.__wrapper8e3dd93a60__=t}function N(e){return e&&_(e)?M(e):e}function C(e){return e&&!_(e)?T(e):e}function j(e,t){null!==t&&(n(S(e)),n(void 0===t||_(t)),e.__wrapper8e3dd93a60__=t)}function D(e,t,n){G.get=n,A(e.prototype,t,G)}function H(e,t){D(e,t,function(){return T(this.__impl4cf1e782hg__[t])})}function x(e,t){e.forEach(function(e){t.forEach(function(t){e.prototype[t]=function(){var e=C(this);return e[t].apply(e,arguments)}})})}var R=new WeakMap,I=new WeakMap,P=Object.create(null),k=t(),A=Object.defineProperty,W=Object.getOwnPropertyNames,F=Object.getOwnPropertyDescriptor,U={value:void 0,configurable:!0,enumerable:!1,writable:!0};W(window);var q=/Firefox/.test(navigator.userAgent),B={get:function(){},set:function(e){},configurable:!0,enumerable:!0},V=function(){var e=Object.getOwnPropertyDescriptor(Node.prototype,"nodeType");return e&&!e.get&&!e.set}(),G={get:void 0,configurable:!0,enumerable:!0};e.assert=n,e.constructorTable=R,e.defineGetter=D,e.defineWrapGetter=H,e.forwardMethodsToWrapper=x,e.isIdentifierName=d,e.isWrapper=_,e.isWrapperFor=b,e.mixin=r,e.nativePrototypeTable=I,e.oneOf=i,e.registerObject=y,e.registerWrapper=v,e.rewrap=j,e.setWrapper=L,e.unsafeUnwrap=O,e.unwrap=M,e.unwrapIfNeeded=N,e.wrap=T,e.wrapIfNeeded=C,e.wrappers=P}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e,t,n){return{index:e,removed:t,addedCount:n}}function n(){}var r=0,o=1,i=2,a=3;n.prototype={calcEditDistances:function(e,t,n,r,o,i){for(var a=i-o+1,s=n-t+1,c=new Array(a),l=0;a>l;l++)c[l]=new Array(s),c[l][0]=l;for(var u=0;s>u;u++)c[0][u]=u;for(var l=1;a>l;l++)for(var u=1;s>u;u++)if(this.equals(e[t+u-1],r[o+l-1]))c[l][u]=c[l-1][u-1];else{var d=c[l-1][u]+1,p=c[l][u-1]+1;c[l][u]=p>d?d:p}return c},spliceOperationsFromEditDistances:function(e){for(var t=e.length-1,n=e[0].length-1,s=e[t][n],c=[];t>0||n>0;)if(0!=t)if(0!=n){var l,u=e[t-1][n-1],d=e[t-1][n],p=e[t][n-1];l=p>d?u>d?d:u:u>p?p:u,l==u?(u==s?c.push(r):(c.push(o),s=u),t--,n--):l==d?(c.push(a),t--,s=d):(c.push(i),n--,s=p)}else c.push(a),t--;else c.push(i),n--;return c.reverse(),c},calcSplices:function(e,n,s,c,l,u){var d=0,p=0,h=Math.min(s-n,u-l);if(0==n&&0==l&&(d=this.sharedPrefix(e,c,h)),s==e.length&&u==c.length&&(p=this.sharedSuffix(e,c,h-d)),n+=d,l+=d,s-=p,u-=p,s-n==0&&u-l==0)return[];if(n==s){for(var f=t(n,[],0);u>l;)f.removed.push(c[l++]);return[f]}if(l==u)return[t(n,[],s-n)];for(var m=this.spliceOperationsFromEditDistances(this.calcEditDistances(e,n,s,c,l,u)),f=void 0,w=[],v=n,g=l,b=0;b<m.length;b++)switch(m[b]){case r:f&&(w.push(f),f=void 0),v++,g++;break;case o:f||(f=t(v,[],0)),f.addedCount++,v++,f.removed.push(c[g]),g++;break;case i:f||(f=t(v,[],0)),f.addedCount++,v++;break;case a:f||(f=t(v,[],0)),f.removed.push(c[g]),g++}return f&&w.push(f),w},sharedPrefix:function(e,t,n){for(var r=0;n>r;r++)if(!this.equals(e[r],t[r]))return r;return n},sharedSuffix:function(e,t,n){for(var r=e.length,o=t.length,i=0;n>i&&this.equals(e[--r],t[--o]);)i++;return i},calculateSplices:function(e,t){return this.calcSplices(e,0,e.length,t,0,t.length)},equals:function(e,t){return e===t}},e.ArraySplice=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(){a=!1;var e=i.slice(0);i=[];for(var t=0;t<e.length;t++)e[t]()}function n(e){i.push(e),a||(a=!0,r(t,0))}var r,o=window.MutationObserver,i=[],a=!1;if(o){var s=1,c=new o(t),l=document.createTextNode(s);c.observe(l,{characterData:!0}),r=function(){s=(s+1)%2,l.data=s}}else r=window.setTimeout;e.setEndOfMicrotask=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){e.scheduled_||(e.scheduled_=!0,f.push(e),m||(u(n),m=!0))}function n(){for(m=!1;f.length;){var e=f;f=[],e.sort(function(e,t){return e.uid_-t.uid_});for(var t=0;t<e.length;t++){var n=e[t];n.scheduled_=!1;var r=n.takeRecords();i(n),r.length&&n.callback_(r,n)}}}function r(e,t){this.type=e,this.target=t,this.addedNodes=new p.NodeList,this.removedNodes=new p.NodeList,this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function o(e,t){for(;e;e=e.parentNode){var n=h.get(e);if(n)for(var r=0;r<n.length;r++){var o=n[r];o.options.subtree&&o.addTransientObserver(t)}}}function i(e){for(var t=0;t<e.nodes_.length;t++){var n=e.nodes_[t],r=h.get(n);if(!r)return;for(var o=0;o<r.length;o++){var i=r[o];i.observer===e&&i.removeTransientObservers()}}}function a(e,n,o){for(var i=Object.create(null),a=Object.create(null),s=e;s;s=s.parentNode){var c=h.get(s);if(c)for(var l=0;l<c.length;l++){var u=c[l],d=u.options;if((s===e||d.subtree)&&!("attributes"===n&&!d.attributes||"attributes"===n&&d.attributeFilter&&(null!==o.namespace||-1===d.attributeFilter.indexOf(o.name))||"characterData"===n&&!d.characterData||"childList"===n&&!d.childList)){var p=u.observer;i[p.uid_]=p,("attributes"===n&&d.attributeOldValue||"characterData"===n&&d.characterDataOldValue)&&(a[p.uid_]=o.oldValue)}}}for(var f in i){var p=i[f],m=new r(n,e);"name"in o&&"namespace"in o&&(m.attributeName=o.name,m.attributeNamespace=o.namespace),o.addedNodes&&(m.addedNodes=o.addedNodes),o.removedNodes&&(m.removedNodes=o.removedNodes),o.previousSibling&&(m.previousSibling=o.previousSibling),o.nextSibling&&(m.nextSibling=o.nextSibling),void 0!==a[f]&&(m.oldValue=a[f]),t(p),p.records_.push(m)}}function s(e){if(this.childList=!!e.childList,this.subtree=!!e.subtree,this.attributes="attributes"in e||!("attributeOldValue"in e||"attributeFilter"in e)?!!e.attributes:!0,this.characterData="characterDataOldValue"in e&&!("characterData"in e)?!0:!!e.characterData,!this.attributes&&(e.attributeOldValue||"attributeFilter"in e)||!this.characterData&&e.characterDataOldValue)throw new TypeError;if(this.characterData=!!e.characterData,this.attributeOldValue=!!e.attributeOldValue,this.characterDataOldValue=!!e.characterDataOldValue,"attributeFilter"in e){if(null==e.attributeFilter||"object"!=typeof e.attributeFilter)throw new TypeError;this.attributeFilter=w.call(e.attributeFilter)}else this.attributeFilter=null}function c(e){this.callback_=e,this.nodes_=[],this.records_=[],this.uid_=++v,this.scheduled_=!1}function l(e,t,n){this.observer=e,this.target=t,this.options=n,this.transientObservedNodes=[]}var u=e.setEndOfMicrotask,d=e.wrapIfNeeded,p=e.wrappers,h=new WeakMap,f=[],m=!1,w=Array.prototype.slice,v=0;c.prototype={constructor:c,observe:function(e,t){e=d(e);var n,r=new s(t),o=h.get(e);o||h.set(e,o=[]);for(var i=0;i<o.length;i++)o[i].observer===this&&(n=o[i],n.removeTransientObservers(),n.options=r);n||(n=new l(this,e,r),o.push(n),this.nodes_.push(e))},disconnect:function(){this.nodes_.forEach(function(e){for(var t=h.get(e),n=0;n<t.length;n++){var r=t[n];if(r.observer===this){t.splice(n,1);break}}},this),this.records_=[]},takeRecords:function(){var e=this.records_;return this.records_=[],e}},l.prototype={addTransientObserver:function(e){if(e!==this.target){t(this.observer),this.transientObservedNodes.push(e);var n=h.get(e);n||h.set(e,n=[]),n.push(this)}},removeTransientObservers:function(){var e=this.transientObservedNodes;this.transientObservedNodes=[];for(var t=0;t<e.length;t++)for(var n=e[t],r=h.get(n),o=0;o<r.length;o++)if(r[o]===this){r.splice(o,1);break}}},e.enqueueMutation=a,e.registerTransientObservers=o,e.wrappers.MutationObserver=c,e.wrappers.MutationRecord=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e,t){this.root=e,this.parent=t}function n(e,t){if(e.treeScope_!==t){e.treeScope_=t;for(var r=e.shadowRoot;r;r=r.olderShadowRoot)r.treeScope_.parent=t;for(var o=e.firstChild;o;o=o.nextSibling)n(o,t)}}function r(n){if(n instanceof e.wrappers.Window,n.treeScope_)return n.treeScope_;var o,i=n.parentNode;return o=i?r(i):new t(n,null),n.treeScope_=o}t.prototype={get renderer(){return this.root instanceof e.wrappers.ShadowRoot?e.getRendererForHost(this.root.host):null},contains:function(e){for(;e;e=e.parent)if(e===this)return!0;return!1}},e.TreeScope=t,e.getTreeScope=r,e.setTreeScope=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return e instanceof G.ShadowRoot}function n(e){return A(e).root}function r(e,r){var s=[],c=e;for(s.push(c);c;){var l=a(c);if(l&&l.length>0){for(var u=0;u<l.length;u++){var p=l[u];if(i(p)){var h=n(p),f=h.olderShadowRoot;f&&s.push(f)}s.push(p)}c=l[l.length-1]}else if(t(c)){if(d(e,c)&&o(r))break;c=c.host,s.push(c)}else c=c.parentNode,c&&s.push(c)}return s}function o(e){if(!e)return!1;switch(e.type){case"abort":case"error":case"select":case"change":case"load":case"reset":case"resize":case"scroll":case"selectstart":return!0}return!1}function i(e){return e instanceof HTMLShadowElement}function a(t){return e.getDestinationInsertionPoints(t)}function s(e,t){if(0===e.length)return t;t instanceof G.Window&&(t=t.document);for(var n=A(t),r=e[0],o=A(r),i=l(n,o),a=0;a<e.length;a++){var s=e[a];if(A(s)===i)return s}return e[e.length-1]}function c(e){for(var t=[];e;e=e.parent)t.push(e);return t}function l(e,t){for(var n=c(e),r=c(t),o=null;n.length>0&&r.length>0;){var i=n.pop(),a=r.pop();if(i!==a)break;o=i}return o}function u(e,t,n){t instanceof G.Window&&(t=t.document);var o,i=A(t),a=A(n),s=r(n,e),o=l(i,a);o||(o=a.root);for(var c=o;c;c=c.parent)for(var u=0;u<s.length;u++){var d=s[u];if(A(d)===c)return d}return null}function d(e,t){return A(e)===A(t)}function p(e){if(!K.get(e)&&(K.set(e,!0),f(V(e),V(e.target)),P)){var t=P;throw P=null,t}}function h(e){switch(e.type){case"load":case"beforeunload":case"unload":return!0}return!1}function f(t,n){if(Y.get(t))throw new Error("InvalidStateError");Y.set(t,!0),e.renderAllPending();var o,i,a;if(h(t)&&!t.bubbles){var s=n;s instanceof G.Document&&(a=s.defaultView)&&(i=s,o=[])}if(!o)if(n instanceof G.Window)a=n,o=[];else if(o=r(n,t),!h(t)){var s=o[o.length-1];s instanceof G.Document&&(a=s.defaultView)}return ne.set(t,o),m(t,o,a,i)&&w(t,o,a,i)&&v(t,o,a,i),J.set(t,re),X["delete"](t,null),Y["delete"](t),t.defaultPrevented}function m(e,t,n,r){var o=oe;if(n&&!g(n,e,o,t,r))return!1;for(var i=t.length-1;i>0;i--)if(!g(t[i],e,o,t,r))return!1;return!0}function w(e,t,n,r){var o=ie,i=t[0]||n;return g(i,e,o,t,r)}function v(e,t,n,r){for(var o=ae,i=1;i<t.length;i++)if(!g(t[i],e,o,t,r))return;n&&t.length>0&&g(n,e,o,t,r)}function g(e,t,n,r,o){var i=z.get(e);if(!i)return!0;var a=o||s(r,e);if(a===e){if(n===oe)return!0;n===ae&&(n=ie)}else if(n===ae&&!t.bubbles)return!0;if("relatedTarget"in t){var c=B(t),l=c.relatedTarget;if(l){if(l instanceof Object&&l.addEventListener){var d=V(l),p=u(t,e,d);if(p===a)return!0}else p=null;Z.set(t,p)}}J.set(t,n);var h=t.type,f=!1;$.set(t,a),X.set(t,e),i.depth++;for(var m=0,w=i.length;w>m;m++){var v=i[m];if(v.removed)f=!0;else if(!(v.type!==h||!v.capture&&n===oe||v.capture&&n===ae))try{if("function"==typeof v.handler?v.handler.call(e,t):v.handler.handleEvent(t),ee.get(t))return!1}catch(g){P||(P=g)}}if(i.depth--,f&&0===i.depth){var b=i.slice();i.length=0;for(var m=0;m<b.length;m++)b[m].removed||i.push(b[m])}return!Q.get(t)}function b(e,t,n){this.type=e,this.handler=t,this.capture=Boolean(n)}function y(e,t){if(!(e instanceof se))return V(T(se,"Event",e,t));var n=e;return ge||"beforeunload"!==n.type||this instanceof M?void U(n,this):new M(n)}function E(e){return e&&e.relatedTarget?Object.create(e,{relatedTarget:{value:B(e.relatedTarget)}}):e}function _(e,t,n){var r=window[e],o=function(t,n){return t instanceof r?void U(t,this):V(T(r,e,t,n))};if(o.prototype=Object.create(t.prototype),n&&W(o.prototype,n),r)try{F(r,o,new r("temp"))}catch(i){F(r,o,document.createEvent(e))}return o}function S(e,t){return function(){arguments[t]=B(arguments[t]);var n=B(this);n[e].apply(n,arguments)}}function T(e,t,n,r){if(we)return new e(n,E(r));var o=B(document.createEvent(t)),i=me[t],a=[n];return Object.keys(i).forEach(function(e){var t=null!=r&&e in r?r[e]:i[e];"relatedTarget"===e&&(t=B(t)),a.push(t)}),o["init"+t].apply(o,a),o}function M(e){y.call(this,e)}function O(e){return"function"==typeof e?!0:e&&e.handleEvent}function L(e){switch(e){case"DOMAttrModified":case"DOMAttributeNameChanged":case"DOMCharacterDataModified":case"DOMElementNameChanged":case"DOMNodeInserted":case"DOMNodeInsertedIntoDocument":case"DOMNodeRemoved":case"DOMNodeRemovedFromDocument":case"DOMSubtreeModified":return!0}return!1}function N(e){U(e,this)}function C(e){return e instanceof G.ShadowRoot&&(e=e.host),B(e)}function j(e,t){var n=z.get(e);if(n)for(var r=0;r<n.length;r++)if(!n[r].removed&&n[r].type===t)return!0;return!1}function D(e,t){for(var n=B(e);n;n=n.parentNode)if(j(V(n),t))return!0;return!1}function H(e){k(e,ye)}function x(t,n,o,i){e.renderAllPending();var a=V(Ee.call(q(n),o,i));if(!a)return null;var c=r(a,null),l=c.lastIndexOf(t);return-1==l?null:(c=c.slice(0,l),s(c,t))}function R(e){return function(){var t=te.get(this);return t&&t[e]&&t[e].value||null}}function I(e){var t=e.slice(2);return function(n){var r=te.get(this);r||(r=Object.create(null),te.set(this,r));var o=r[e];if(o&&this.removeEventListener(t,o.wrapped,!1),"function"==typeof n){var i=function(t){var r=n.call(this,t);r===!1?t.preventDefault():"onbeforeunload"===e&&"string"==typeof r&&(t.returnValue=r)};this.addEventListener(t,i,!1),r[e]={value:n,wrapped:i}}}}var P,k=e.forwardMethodsToWrapper,A=e.getTreeScope,W=e.mixin,F=e.registerWrapper,U=e.setWrapper,q=e.unsafeUnwrap,B=e.unwrap,V=e.wrap,G=e.wrappers,z=(new WeakMap,new WeakMap),K=new WeakMap,Y=new WeakMap,$=new WeakMap,X=new WeakMap,Z=new WeakMap,J=new WeakMap,Q=new WeakMap,ee=new WeakMap,te=new WeakMap,ne=new WeakMap,re=0,oe=1,ie=2,ae=3;b.prototype={equals:function(e){return this.handler===e.handler&&this.type===e.type&&this.capture===e.capture},get removed(){return null===this.handler},remove:function(){this.handler=null}};var se=window.Event;se.prototype.polymerBlackList_={returnValue:!0,keyLocation:!0},y.prototype={get target(){return $.get(this)},get currentTarget(){return X.get(this)},get eventPhase(){return J.get(this)},get path(){var e=ne.get(this);return e?e.slice():[]},stopPropagation:function(){Q.set(this,!0)},stopImmediatePropagation:function(){Q.set(this,!0),ee.set(this,!0)}},F(se,y,document.createEvent("Event"));var ce=_("UIEvent",y),le=_("CustomEvent",y),ue={get relatedTarget(){var e=Z.get(this);return void 0!==e?e:V(B(this).relatedTarget)}},de=W({initMouseEvent:S("initMouseEvent",14)},ue),pe=W({initFocusEvent:S("initFocusEvent",5)},ue),he=_("MouseEvent",ce,de),fe=_("FocusEvent",ce,pe),me=Object.create(null),we=function(){try{new window.FocusEvent("focus")}catch(e){return!1}return!0}();if(!we){var ve=function(e,t,n){if(n){var r=me[n];t=W(W({},r),t)}me[e]=t};ve("Event",{bubbles:!1,cancelable:!1}),ve("CustomEvent",{detail:null},"Event"),ve("UIEvent",{view:null,detail:0},"Event"),ve("MouseEvent",{screenX:0,screenY:0,clientX:0,clientY:0,ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1,button:0,relatedTarget:null},"UIEvent"),ve("FocusEvent",{relatedTarget:null},"UIEvent")}var ge=window.BeforeUnloadEvent;M.prototype=Object.create(y.prototype),W(M.prototype,{get returnValue(){return q(this).returnValue},set returnValue(e){q(this).returnValue=e}}),ge&&F(ge,M);var be=window.EventTarget,ye=["addEventListener","removeEventListener","dispatchEvent"];[Node,Window].forEach(function(e){var t=e.prototype;ye.forEach(function(e){Object.defineProperty(t,e+"_",{value:t[e]})})}),N.prototype={addEventListener:function(e,t,n){if(O(t)&&!L(e)){var r=new b(e,t,n),o=z.get(this);if(o){for(var i=0;i<o.length;i++)if(r.equals(o[i]))return}else o=[],o.depth=0,z.set(this,o);o.push(r);var a=C(this);a.addEventListener_(e,p,!0)}},removeEventListener:function(e,t,n){n=Boolean(n);var r=z.get(this);if(r){for(var o=0,i=!1,a=0;a<r.length;a++)r[a].type===e&&r[a].capture===n&&(o++,r[a].handler===t&&(i=!0,r[a].remove()));if(i&&1===o){var s=C(this);s.removeEventListener_(e,p,!0)}}},dispatchEvent:function(t){var n=B(t),r=n.type;K.set(n,!1),e.renderAllPending();var o;D(this,r)||(o=function(){},this.addEventListener(r,o,!0));try{return B(this).dispatchEvent_(n)}finally{o&&this.removeEventListener(r,o,!0)}}},be&&F(be,N);var Ee=document.elementFromPoint;e.elementFromPoint=x,e.getEventHandlerGetter=R,e.getEventHandlerSetter=I,e.wrapEventTargetMethods=H,e.wrappers.BeforeUnloadEvent=M,e.wrappers.CustomEvent=le,e.wrappers.Event=y,e.wrappers.EventTarget=N,e.wrappers.FocusEvent=fe,e.wrappers.MouseEvent=he,e.wrappers.UIEvent=ce}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e,t){Object.defineProperty(e,t,m)}function n(e){l(e,this)}function r(){this.length=0,t(this,"length")}function o(e){for(var t=new r,o=0;o<e.length;o++)t[o]=new n(e[o]);return t.length=o,t}function i(e){a.call(this,e)}var a=e.wrappers.UIEvent,s=e.mixin,c=e.registerWrapper,l=e.setWrapper,u=e.unsafeUnwrap,d=e.wrap,p=window.TouchEvent;if(p){var h;try{h=document.createEvent("TouchEvent")}catch(f){return}var m={enumerable:!1};n.prototype={get target(){return d(u(this).target)}};var w={configurable:!0,enumerable:!0,get:null};["clientX","clientY","screenX","screenY","pageX","pageY","identifier","webkitRadiusX","webkitRadiusY","webkitRotationAngle","webkitForce"].forEach(function(e){w.get=function(){return u(this)[e]},Object.defineProperty(n.prototype,e,w)}),r.prototype={item:function(e){return this[e]}},i.prototype=Object.create(a.prototype),s(i.prototype,{get touches(){return o(u(this).touches)},get targetTouches(){return o(u(this).targetTouches)},get changedTouches(){return o(u(this).changedTouches)},initTouchEvent:function(){throw new Error("Not implemented")}}),c(p,i,h),e.wrappers.Touch=n,e.wrappers.TouchEvent=i,e.wrappers.TouchList=r}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e,t){Object.defineProperty(e,t,s)}function n(){this.length=0,t(this,"length")}function r(e){if(null==e)return e;for(var t=new n,r=0,o=e.length;o>r;r++)t[r]=a(e[r]);return t.length=o,t}function o(e,t){e.prototype[t]=function(){return r(i(this)[t].apply(i(this),arguments))}}var i=e.unsafeUnwrap,a=e.wrap,s={enumerable:!1};n.prototype={item:function(e){return this[e]}},t(n.prototype,"item"),e.wrappers.NodeList=n,e.addWrapNodeListMethod=o,e.wrapNodeList=r}(window.ShadowDOMPolyfill),function(e){"use strict";e.wrapHTMLCollection=e.wrapNodeList,e.wrappers.HTMLCollection=e.wrappers.NodeList}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){O(e instanceof _)}function n(e){var t=new T;return t[0]=e,t.length=1,t}function r(e,t,n){N(t,"childList",{removedNodes:n,previousSibling:e.previousSibling,nextSibling:e.nextSibling})}function o(e,t){N(e,"childList",{removedNodes:t})}function i(e,t,r,o){if(e instanceof DocumentFragment){var i=s(e);U=!0;for(var a=i.length-1;a>=0;a--)e.removeChild(i[a]),i[a].parentNode_=t;U=!1;for(var a=0;a<i.length;a++)i[a].previousSibling_=i[a-1]||r,i[a].nextSibling_=i[a+1]||o;return r&&(r.nextSibling_=i[0]),o&&(o.previousSibling_=i[i.length-1]),i}var i=n(e),c=e.parentNode;return c&&c.removeChild(e),e.parentNode_=t,e.previousSibling_=r,e.nextSibling_=o,r&&(r.nextSibling_=e),o&&(o.previousSibling_=e),i}function a(e){if(e instanceof DocumentFragment)return s(e);var t=n(e),o=e.parentNode;return o&&r(e,o,t),t}function s(e){for(var t=new T,n=0,r=e.firstChild;r;r=r.nextSibling)t[n++]=r;return t.length=n,o(e,t),t}function c(e){return e}function l(e,t){R(e,t),e.nodeIsInserted_()}function u(e,t){for(var n=C(t),r=0;r<e.length;r++)l(e[r],n)}function d(e){R(e,new M(e,null))}function p(e){for(var t=0;t<e.length;t++)d(e[t])}function h(e,t){var n=e.nodeType===_.DOCUMENT_NODE?e:e.ownerDocument;n!==t.ownerDocument&&n.adoptNode(t)}function f(t,n){if(n.length){var r=t.ownerDocument;if(r!==n[0].ownerDocument)for(var o=0;o<n.length;o++)e.adoptNodeNoRemove(n[o],r)}}function m(e,t){f(e,t);var n=t.length;if(1===n)return P(t[0]);for(var r=P(e.ownerDocument.createDocumentFragment()),o=0;n>o;o++)r.appendChild(P(t[o]));return r}function w(e){if(void 0!==e.firstChild_)for(var t=e.firstChild_;t;){var n=t;t=t.nextSibling_,n.parentNode_=n.previousSibling_=n.nextSibling_=void 0}e.firstChild_=e.lastChild_=void 0}function v(e){if(e.invalidateShadowRenderer()){for(var t=e.firstChild;t;){O(t.parentNode===e);var n=t.nextSibling,r=P(t),o=r.parentNode;o&&$.call(o,r),t.previousSibling_=t.nextSibling_=t.parentNode_=null,t=n}e.firstChild_=e.lastChild_=null}else for(var n,i=P(e),a=i.firstChild;a;)n=a.nextSibling,$.call(i,a),a=n}function g(e){var t=e.parentNode;return t&&t.invalidateShadowRenderer()}function b(e){for(var t,n=0;n<e.length;n++)t=e[n],t.parentNode.removeChild(t)}function y(e,t,n){var r;if(r=A(n?q.call(n,I(e),!1):B.call(I(e),!1)),t){for(var o=e.firstChild;o;o=o.nextSibling)r.appendChild(y(o,!0,n));if(e instanceof F.HTMLTemplateElement)for(var i=r.content,o=e.content.firstChild;o;o=o.nextSibling)i.appendChild(y(o,!0,n))}return r}function E(e,t){if(!t||C(e)!==C(t))return!1;for(var n=t;n;n=n.parentNode)if(n===e)return!0;return!1}function _(e){O(e instanceof V),S.call(this,e),this.parentNode_=void 0,this.firstChild_=void 0,this.lastChild_=void 0,this.nextSibling_=void 0,this.previousSibling_=void 0,this.treeScope_=void 0}var S=e.wrappers.EventTarget,T=e.wrappers.NodeList,M=e.TreeScope,O=e.assert,L=e.defineWrapGetter,N=e.enqueueMutation,C=e.getTreeScope,j=e.isWrapper,D=e.mixin,H=e.registerTransientObservers,x=e.registerWrapper,R=e.setTreeScope,I=e.unsafeUnwrap,P=e.unwrap,k=e.unwrapIfNeeded,A=e.wrap,W=e.wrapIfNeeded,F=e.wrappers,U=!1,q=document.importNode,B=window.Node.prototype.cloneNode,V=window.Node,G=window.DocumentFragment,z=(V.prototype.appendChild,V.prototype.compareDocumentPosition),K=V.prototype.isEqualNode,Y=V.prototype.insertBefore,$=V.prototype.removeChild,X=V.prototype.replaceChild,Z=/Trident|Edge/.test(navigator.userAgent),J=Z?function(e,t){try{$.call(e,t)}catch(n){if(!(e instanceof G))throw n}}:function(e,t){$.call(e,t)};_.prototype=Object.create(S.prototype),D(_.prototype,{appendChild:function(e){return this.insertBefore(e,null)},insertBefore:function(e,n){t(e);var r;n?j(n)?r=P(n):(r=n,n=A(r)):(n=null,r=null),n&&O(n.parentNode===this);var o,s=n?n.previousSibling:this.lastChild,c=!this.invalidateShadowRenderer()&&!g(e);if(o=c?a(e):i(e,this,s,n),c)h(this,e),w(this),Y.call(I(this),P(e),r);else{s||(this.firstChild_=o[0]),n||(this.lastChild_=o[o.length-1],void 0===this.firstChild_&&(this.firstChild_=this.firstChild));var l=r?r.parentNode:I(this);l?Y.call(l,m(this,o),r):f(this,o)}return N(this,"childList",{addedNodes:o,nextSibling:n,previousSibling:s}),u(o,this),e},removeChild:function(e){if(t(e),e.parentNode!==this){for(var r=!1,o=(this.childNodes,this.firstChild);o;o=o.nextSibling)if(o===e){r=!0;break}if(!r)throw new Error("NotFoundError")}var i=P(e),a=e.nextSibling,s=e.previousSibling;if(this.invalidateShadowRenderer()){var c=this.firstChild,l=this.lastChild,u=i.parentNode;u&&J(u,i),c===e&&(this.firstChild_=a),l===e&&(this.lastChild_=s),s&&(s.nextSibling_=a),a&&(a.previousSibling_=s),e.previousSibling_=e.nextSibling_=e.parentNode_=void 0}else w(this),J(I(this),i);return U||N(this,"childList",{removedNodes:n(e),nextSibling:a,previousSibling:s}),H(this,e),e},replaceChild:function(e,r){t(e);var o;if(j(r)?o=P(r):(o=r,r=A(o)),r.parentNode!==this)throw new Error("NotFoundError");var s,c=r.nextSibling,l=r.previousSibling,p=!this.invalidateShadowRenderer()&&!g(e);return p?s=a(e):(c===e&&(c=e.nextSibling),s=i(e,this,l,c)),p?(h(this,e),w(this),X.call(I(this),P(e),o)):(this.firstChild===r&&(this.firstChild_=s[0]),this.lastChild===r&&(this.lastChild_=s[s.length-1]),r.previousSibling_=r.nextSibling_=r.parentNode_=void 0,o.parentNode&&X.call(o.parentNode,m(this,s),o)),N(this,"childList",{addedNodes:s,removedNodes:n(r),nextSibling:c,previousSibling:l}),d(r),u(s,this),r},nodeIsInserted_:function(){for(var e=this.firstChild;e;e=e.nextSibling)e.nodeIsInserted_()},hasChildNodes:function(){return null!==this.firstChild},get parentNode(){return void 0!==this.parentNode_?this.parentNode_:A(I(this).parentNode)},get firstChild(){return void 0!==this.firstChild_?this.firstChild_:A(I(this).firstChild)},get lastChild(){return void 0!==this.lastChild_?this.lastChild_:A(I(this).lastChild)},get nextSibling(){return void 0!==this.nextSibling_?this.nextSibling_:A(I(this).nextSibling)},get previousSibling(){return void 0!==this.previousSibling_?this.previousSibling_:A(I(this).previousSibling)},get parentElement(){for(var e=this.parentNode;e&&e.nodeType!==_.ELEMENT_NODE;)e=e.parentNode;return e},get textContent(){for(var e="",t=this.firstChild;t;t=t.nextSibling)t.nodeType!=_.COMMENT_NODE&&(e+=t.textContent);return e},set textContent(e){null==e&&(e="");var t=c(this.childNodes);if(this.invalidateShadowRenderer()){if(v(this),""!==e){var n=I(this).ownerDocument.createTextNode(e);this.appendChild(n)}}else w(this),I(this).textContent=e;var r=c(this.childNodes);N(this,"childList",{addedNodes:r,removedNodes:t}),p(t),u(r,this)},get childNodes(){for(var e=new T,t=0,n=this.firstChild;n;n=n.nextSibling)e[t++]=n;return e.length=t,e},cloneNode:function(e){return y(this,e)},contains:function(e){return E(this,W(e))},compareDocumentPosition:function(e){return z.call(I(this),k(e))},isEqualNode:function(e){return K.call(I(this),k(e))},normalize:function(){for(var e,t,n=c(this.childNodes),r=[],o="",i=0;i<n.length;i++)t=n[i],t.nodeType===_.TEXT_NODE?e||t.data.length?e?(o+=t.data,r.push(t)):e=t:this.removeChild(t):(e&&r.length&&(e.data+=o,b(r)),r=[],o="",e=null,t.childNodes.length&&t.normalize());e&&r.length&&(e.data+=o,b(r))}}),L(_,"ownerDocument"),x(V,_,document.createDocumentFragment()),delete _.prototype.querySelector,delete _.prototype.querySelectorAll,_.prototype=D(Object.create(S.prototype),_.prototype),e.cloneNode=y,e.nodeWasAdded=l,e.nodeWasRemoved=d,e.nodesWereAdded=u,e.nodesWereRemoved=p,e.originalInsertBefore=Y,e.originalRemoveChild=$,e.snapshotNodeList=c,e.wrappers.Node=_}(window.ShadowDOMPolyfill),function(e){"use strict";function t(t,n,r,o){for(var i=null,a=null,s=0,c=t.length;c>s;s++)i=b(t[s]),!o&&(a=v(i).root)&&a instanceof e.wrappers.ShadowRoot||(r[n++]=i);return n}function n(e){return String(e).replace(/\/deep\/|::shadow|>>>/g," ")}function r(e){return String(e).replace(/:host\(([^\s]+)\)/g,"$1").replace(/([^\s]):host/g,"$1").replace(":host","*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content|>>>/g," ")}function o(e,t){for(var n,r=e.firstElementChild;r;){if(r.matches(t))return r;if(n=o(r,t))return n;r=r.nextElementSibling}return null}function i(e,t){return e.matches(t)}function a(e,t,n){var r=e.localName;return r===t||r===n&&e.namespaceURI===j}function s(){return!0}function c(e,t,n){return e.localName===n}function l(e,t){return e.namespaceURI===t}function u(e,t,n){return e.namespaceURI===t&&e.localName===n}function d(e,t,n,r,o,i){for(var a=e.firstElementChild;a;)r(a,o,i)&&(n[t++]=a),t=d(a,t,n,r,o,i),a=a.nextElementSibling;return t}function p(n,r,o,i,a){var s,c=g(this),l=v(this).root;if(l instanceof e.wrappers.ShadowRoot)return d(this,r,o,n,i,null);if(c instanceof N)s=S.call(c,i);else{if(!(c instanceof C))return d(this,r,o,n,i,null);s=_.call(c,i)}return t(s,r,o,a)}function h(n,r,o,i,a){var s,c=g(this),l=v(this).root;if(l instanceof e.wrappers.ShadowRoot)return d(this,r,o,n,i,a);if(c instanceof N)s=M.call(c,i,a);else{if(!(c instanceof C))return d(this,r,o,n,i,a);s=T.call(c,i,a)}return t(s,r,o,!1)}function f(n,r,o,i,a){var s,c=g(this),l=v(this).root;if(l instanceof e.wrappers.ShadowRoot)return d(this,r,o,n,i,a);if(c instanceof N)s=L.call(c,i,a);else{if(!(c instanceof C))return d(this,r,o,n,i,a);s=O.call(c,i,a)}return t(s,r,o,!1)}var m=e.wrappers.HTMLCollection,w=e.wrappers.NodeList,v=e.getTreeScope,g=e.unsafeUnwrap,b=e.wrap,y=document.querySelector,E=document.documentElement.querySelector,_=document.querySelectorAll,S=document.documentElement.querySelectorAll,T=document.getElementsByTagName,M=document.documentElement.getElementsByTagName,O=document.getElementsByTagNameNS,L=document.documentElement.getElementsByTagNameNS,N=window.Element,C=window.HTMLDocument||window.Document,j="http://www.w3.org/1999/xhtml",D={querySelector:function(t){var r=n(t),i=r!==t;t=r;var a,s=g(this),c=v(this).root;if(c instanceof e.wrappers.ShadowRoot)return o(this,t);if(s instanceof N)a=b(E.call(s,t));else{if(!(s instanceof C))return o(this,t);
+
+a=b(y.call(s,t))}return a&&!i&&(c=v(a).root)&&c instanceof e.wrappers.ShadowRoot?o(this,t):a},querySelectorAll:function(e){var t=n(e),r=t!==e;e=t;var o=new w;return o.length=p.call(this,i,0,o,e,r),o}},H={matches:function(t){return t=r(t),e.originalMatches.call(g(this),t)}},x={getElementsByTagName:function(e){var t=new m,n="*"===e?s:a;return t.length=h.call(this,n,0,t,e,e.toLowerCase()),t},getElementsByClassName:function(e){return this.querySelectorAll("."+e)},getElementsByTagNameNS:function(e,t){var n=new m,r=null;return r="*"===e?"*"===t?s:c:"*"===t?l:u,n.length=f.call(this,r,0,n,e||null,t),n}};e.GetElementsByInterface=x,e.SelectorsInterface=D,e.MatchesInterface=H}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){for(;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.nextSibling;return e}function n(e){for(;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.previousSibling;return e}var r=e.wrappers.NodeList,o={get firstElementChild(){return t(this.firstChild)},get lastElementChild(){return n(this.lastChild)},get childElementCount(){for(var e=0,t=this.firstElementChild;t;t=t.nextElementSibling)e++;return e},get children(){for(var e=new r,t=0,n=this.firstElementChild;n;n=n.nextElementSibling)e[t++]=n;return e.length=t,e},remove:function(){var e=this.parentNode;e&&e.removeChild(this)}},i={get nextElementSibling(){return t(this.nextSibling)},get previousElementSibling(){return n(this.previousSibling)}},a={getElementById:function(e){return/[ \t\n\r\f]/.test(e)?null:this.querySelector('[id="'+e+'"]')}};e.ChildNodeInterface=i,e.NonElementParentNodeInterface=a,e.ParentNodeInterface=o}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}var n=e.ChildNodeInterface,r=e.wrappers.Node,o=e.enqueueMutation,i=e.mixin,a=e.registerWrapper,s=e.unsafeUnwrap,c=window.CharacterData;t.prototype=Object.create(r.prototype),i(t.prototype,{get nodeValue(){return this.data},set nodeValue(e){this.data=e},get textContent(){return this.data},set textContent(e){this.data=e},get data(){return s(this).data},set data(e){var t=s(this).data;o(this,"characterData",{oldValue:t}),s(this).data=e}}),i(t.prototype,n),a(c,t,document.createTextNode("")),e.wrappers.CharacterData=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return e>>>0}function n(e){r.call(this,e)}var r=e.wrappers.CharacterData,o=(e.enqueueMutation,e.mixin),i=e.registerWrapper,a=window.Text;n.prototype=Object.create(r.prototype),o(n.prototype,{splitText:function(e){e=t(e);var n=this.data;if(e>n.length)throw new Error("IndexSizeError");var r=n.slice(0,e),o=n.slice(e);this.data=r;var i=this.ownerDocument.createTextNode(o);return this.parentNode&&this.parentNode.insertBefore(i,this.nextSibling),i}}),i(a,n,document.createTextNode("")),e.wrappers.Text=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return i(e).getAttribute("class")}function n(e,t){a(e,"attributes",{name:"class",namespace:null,oldValue:t})}function r(t){e.invalidateRendererBasedOnAttribute(t,"class")}function o(e,o,i){var a=e.ownerElement_;if(null==a)return o.apply(e,i);var s=t(a),c=o.apply(e,i);return t(a)!==s&&(n(a,s),r(a)),c}if(!window.DOMTokenList)return void console.warn("Missing DOMTokenList prototype, please include a compatible classList polyfill such as http://goo.gl/uTcepH.");var i=e.unsafeUnwrap,a=e.enqueueMutation,s=DOMTokenList.prototype.add;DOMTokenList.prototype.add=function(){o(this,s,arguments)};var c=DOMTokenList.prototype.remove;DOMTokenList.prototype.remove=function(){o(this,c,arguments)};var l=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(){return o(this,l,arguments)}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(t,n){var r=t.parentNode;if(r&&r.shadowRoot){var o=e.getRendererForHost(r);o.dependsOnAttribute(n)&&o.invalidate()}}function n(e,t,n){u(e,"attributes",{name:t,namespace:null,oldValue:n})}function r(e){a.call(this,e)}var o=e.ChildNodeInterface,i=e.GetElementsByInterface,a=e.wrappers.Node,s=e.ParentNodeInterface,c=e.SelectorsInterface,l=e.MatchesInterface,u=(e.addWrapNodeListMethod,e.enqueueMutation),d=e.mixin,p=(e.oneOf,e.registerWrapper),h=e.unsafeUnwrap,f=e.wrappers,m=window.Element,w=["matches","mozMatchesSelector","msMatchesSelector","webkitMatchesSelector"].filter(function(e){return m.prototype[e]}),v=w[0],g=m.prototype[v],b=new WeakMap;r.prototype=Object.create(a.prototype),d(r.prototype,{createShadowRoot:function(){var t=new f.ShadowRoot(this);h(this).polymerShadowRoot_=t;var n=e.getRendererForHost(this);return n.invalidate(),t},get shadowRoot(){return h(this).polymerShadowRoot_||null},setAttribute:function(e,r){var o=h(this).getAttribute(e);h(this).setAttribute(e,r),n(this,e,o),t(this,e)},removeAttribute:function(e){var r=h(this).getAttribute(e);h(this).removeAttribute(e),n(this,e,r),t(this,e)},get classList(){var e=b.get(this);if(!e){if(e=h(this).classList,!e)return;e.ownerElement_=this,b.set(this,e)}return e},get className(){return h(this).className},set className(e){this.setAttribute("class",e)},get id(){return h(this).id},set id(e){this.setAttribute("id",e)}}),w.forEach(function(e){"matches"!==e&&(r.prototype[e]=function(e){return this.matches(e)})}),m.prototype.webkitCreateShadowRoot&&(r.prototype.webkitCreateShadowRoot=r.prototype.createShadowRoot),d(r.prototype,o),d(r.prototype,i),d(r.prototype,s),d(r.prototype,c),d(r.prototype,l),p(m,r,document.createElementNS(null,"x")),e.invalidateRendererBasedOnAttribute=t,e.matchesNames=w,e.originalMatches=g,e.wrappers.Element=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){switch(e){case"&":return"&";case"<":return"<";case">":return">";case'"':return""";case" ":return" "}}function n(e){return e.replace(L,t)}function r(e){return e.replace(N,t)}function o(e){for(var t={},n=0;n<e.length;n++)t[e[n]]=!0;return t}function i(e){if(e.namespaceURI!==D)return!0;var t=e.ownerDocument.doctype;return t&&t.publicId&&t.systemId}function a(e,t){switch(e.nodeType){case Node.ELEMENT_NODE:for(var o,a=e.tagName.toLowerCase(),c="<"+a,l=e.attributes,u=0;o=l[u];u++)c+=" "+o.name+'="'+n(o.value)+'"';return C[a]?(i(e)&&(c+="/"),c+">"):c+">"+s(e)+"</"+a+">";case Node.TEXT_NODE:var d=e.data;return t&&j[t.localName]?d:r(d);case Node.COMMENT_NODE:return"<!--"+e.data+"-->";default:throw console.error(e),new Error("not implemented")}}function s(e){e instanceof O.HTMLTemplateElement&&(e=e.content);for(var t="",n=e.firstChild;n;n=n.nextSibling)t+=a(n,e);return t}function c(e,t,n){var r=n||"div";e.textContent="";var o=T(e.ownerDocument.createElement(r));o.innerHTML=t;for(var i;i=o.firstChild;)e.appendChild(M(i))}function l(e){m.call(this,e)}function u(e,t){var n=T(e.cloneNode(!1));n.innerHTML=t;for(var r,o=T(document.createDocumentFragment());r=n.firstChild;)o.appendChild(r);return M(o)}function d(t){return function(){return e.renderAllPending(),S(this)[t]}}function p(e){w(l,e,d(e))}function h(t){Object.defineProperty(l.prototype,t,{get:d(t),set:function(n){e.renderAllPending(),S(this)[t]=n},configurable:!0,enumerable:!0})}function f(t){Object.defineProperty(l.prototype,t,{value:function(){return e.renderAllPending(),S(this)[t].apply(S(this),arguments)},configurable:!0,enumerable:!0})}var m=e.wrappers.Element,w=e.defineGetter,v=e.enqueueMutation,g=e.mixin,b=e.nodesWereAdded,y=e.nodesWereRemoved,E=e.registerWrapper,_=e.snapshotNodeList,S=e.unsafeUnwrap,T=e.unwrap,M=e.wrap,O=e.wrappers,L=/[&\u00A0"]/g,N=/[&\u00A0<>]/g,C=o(["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"]),j=o(["style","script","xmp","iframe","noembed","noframes","plaintext","noscript"]),D="http://www.w3.org/1999/xhtml",H=/MSIE/.test(navigator.userAgent),x=window.HTMLElement,R=window.HTMLTemplateElement;l.prototype=Object.create(m.prototype),g(l.prototype,{get innerHTML(){return s(this)},set innerHTML(e){if(H&&j[this.localName])return void(this.textContent=e);var t=_(this.childNodes);this.invalidateShadowRenderer()?this instanceof O.HTMLTemplateElement?c(this.content,e):c(this,e,this.tagName):!R&&this instanceof O.HTMLTemplateElement?c(this.content,e):S(this).innerHTML=e;var n=_(this.childNodes);v(this,"childList",{addedNodes:n,removedNodes:t}),y(t),b(n,this)},get outerHTML(){return a(this,this.parentNode)},set outerHTML(e){var t=this.parentNode;if(t){t.invalidateShadowRenderer();var n=u(t,e);t.replaceChild(n,this)}},insertAdjacentHTML:function(e,t){var n,r;switch(String(e).toLowerCase()){case"beforebegin":n=this.parentNode,r=this;break;case"afterend":n=this.parentNode,r=this.nextSibling;break;case"afterbegin":n=this,r=this.firstChild;break;case"beforeend":n=this,r=null;break;default:return}var o=u(n,t);n.insertBefore(o,r)},get hidden(){return this.hasAttribute("hidden")},set hidden(e){e?this.setAttribute("hidden",""):this.removeAttribute("hidden")}}),["clientHeight","clientLeft","clientTop","clientWidth","offsetHeight","offsetLeft","offsetTop","offsetWidth","scrollHeight","scrollWidth"].forEach(p),["scrollLeft","scrollTop"].forEach(h),["getBoundingClientRect","getClientRects","scrollIntoView"].forEach(f),E(x,l,document.createElement("b")),e.wrappers.HTMLElement=l,e.getInnerHTML=s,e.setInnerHTML=c}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unsafeUnwrap,a=e.wrap,s=window.HTMLCanvasElement;t.prototype=Object.create(n.prototype),r(t.prototype,{getContext:function(){var e=i(this).getContext.apply(i(this),arguments);return e&&a(e)}}),o(s,t,document.createElement("canvas")),e.wrappers.HTMLCanvasElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=window.HTMLContentElement;t.prototype=Object.create(n.prototype),r(t.prototype,{constructor:t,get select(){return this.getAttribute("select")},set select(e){this.setAttribute("select",e)},setAttribute:function(e,t){n.prototype.setAttribute.call(this,e,t),"select"===String(e).toLowerCase()&&this.invalidateShadowRenderer(!0)}}),i&&o(i,t),e.wrappers.HTMLContentElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=window.HTMLFormElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get elements(){return i(a(this).elements)}}),o(s,t,document.createElement("form")),e.wrappers.HTMLFormElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}function n(e,t){if(!(this instanceof n))throw new TypeError("DOM object constructor cannot be called as a function.");var o=i(document.createElement("img"));r.call(this,o),a(o,this),void 0!==e&&(o.width=e),void 0!==t&&(o.height=t)}var r=e.wrappers.HTMLElement,o=e.registerWrapper,i=e.unwrap,a=e.rewrap,s=window.HTMLImageElement;t.prototype=Object.create(r.prototype),o(s,t,document.createElement("img")),n.prototype=t.prototype,e.wrappers.HTMLImageElement=t,e.wrappers.Image=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=(e.mixin,e.wrappers.NodeList,e.registerWrapper),o=window.HTMLShadowElement;t.prototype=Object.create(n.prototype),t.prototype.constructor=t,o&&r(o,t),e.wrappers.HTMLShadowElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){if(!e.defaultView)return e;var t=d.get(e);if(!t){for(t=e.implementation.createHTMLDocument("");t.lastChild;)t.removeChild(t.lastChild);d.set(e,t)}return t}function n(e){for(var n,r=t(e.ownerDocument),o=c(r.createDocumentFragment());n=e.firstChild;)o.appendChild(n);return o}function r(e){if(o.call(this,e),!p){var t=n(e);u.set(this,l(t))}}var o=e.wrappers.HTMLElement,i=e.mixin,a=e.registerWrapper,s=e.unsafeUnwrap,c=e.unwrap,l=e.wrap,u=new WeakMap,d=new WeakMap,p=window.HTMLTemplateElement;r.prototype=Object.create(o.prototype),i(r.prototype,{constructor:r,get content(){return p?l(s(this).content):u.get(this)}}),p&&a(p,r),e.wrappers.HTMLTemplateElement=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.registerWrapper,o=window.HTMLMediaElement;o&&(t.prototype=Object.create(n.prototype),r(o,t,document.createElement("audio")),e.wrappers.HTMLMediaElement=t)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}function n(e){if(!(this instanceof n))throw new TypeError("DOM object constructor cannot be called as a function.");var t=i(document.createElement("audio"));r.call(this,t),a(t,this),t.setAttribute("preload","auto"),void 0!==e&&t.setAttribute("src",e)}var r=e.wrappers.HTMLMediaElement,o=e.registerWrapper,i=e.unwrap,a=e.rewrap,s=window.HTMLAudioElement;s&&(t.prototype=Object.create(r.prototype),o(s,t,document.createElement("audio")),n.prototype=t.prototype,e.wrappers.HTMLAudioElement=t,e.wrappers.Audio=n)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return e.replace(/\s+/g," ").trim()}function n(e){o.call(this,e)}function r(e,t,n,i){if(!(this instanceof r))throw new TypeError("DOM object constructor cannot be called as a function.");var a=c(document.createElement("option"));o.call(this,a),s(a,this),void 0!==e&&(a.text=e),void 0!==t&&a.setAttribute("value",t),n===!0&&a.setAttribute("selected",""),a.selected=i===!0}var o=e.wrappers.HTMLElement,i=e.mixin,a=e.registerWrapper,s=e.rewrap,c=e.unwrap,l=e.wrap,u=window.HTMLOptionElement;n.prototype=Object.create(o.prototype),i(n.prototype,{get text(){return t(this.textContent)},set text(e){this.textContent=t(String(e))},get form(){return l(c(this).form)}}),a(u,n,document.createElement("option")),r.prototype=n.prototype,e.wrappers.HTMLOptionElement=n,e.wrappers.Option=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unwrap,a=e.wrap,s=window.HTMLSelectElement;t.prototype=Object.create(n.prototype),r(t.prototype,{add:function(e,t){"object"==typeof t&&(t=i(t)),i(this).add(i(e),t)},remove:function(e){return void 0===e?void n.prototype.remove.call(this):("object"==typeof e&&(e=i(e)),void i(this).remove(e))},get form(){return a(i(this).form)}}),o(s,t,document.createElement("select")),e.wrappers.HTMLSelectElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unwrap,a=e.wrap,s=e.wrapHTMLCollection,c=window.HTMLTableElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get caption(){return a(i(this).caption)},createCaption:function(){return a(i(this).createCaption())},get tHead(){return a(i(this).tHead)},createTHead:function(){return a(i(this).createTHead())},createTFoot:function(){return a(i(this).createTFoot())},get tFoot(){return a(i(this).tFoot)},get tBodies(){return s(i(this).tBodies)},createTBody:function(){return a(i(this).createTBody())},get rows(){return s(i(this).rows)},insertRow:function(e){return a(i(this).insertRow(e))}}),o(c,t,document.createElement("table")),e.wrappers.HTMLTableElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=e.wrap,c=window.HTMLTableSectionElement;t.prototype=Object.create(n.prototype),r(t.prototype,{constructor:t,get rows(){return i(a(this).rows)},insertRow:function(e){return s(a(this).insertRow(e))}}),o(c,t,document.createElement("thead")),e.wrappers.HTMLTableSectionElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=e.wrap,c=window.HTMLTableRowElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get cells(){return i(a(this).cells)},insertCell:function(e){return s(a(this).insertCell(e))}}),o(c,t,document.createElement("tr")),e.wrappers.HTMLTableRowElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){switch(e.localName){case"content":return new n(e);case"shadow":return new o(e);case"template":return new i(e)}r.call(this,e)}var n=e.wrappers.HTMLContentElement,r=e.wrappers.HTMLElement,o=e.wrappers.HTMLShadowElement,i=e.wrappers.HTMLTemplateElement,a=(e.mixin,e.registerWrapper),s=window.HTMLUnknownElement;t.prototype=Object.create(r.prototype),a(s,t),e.wrappers.HTMLUnknownElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.wrappers.Element,n=e.wrappers.HTMLElement,r=e.registerObject,o=e.defineWrapGetter,i="http://www.w3.org/2000/svg",a=document.createElementNS(i,"title"),s=r(a),c=Object.getPrototypeOf(s.prototype).constructor;if(!("classList"in a)){var l=Object.getOwnPropertyDescriptor(t.prototype,"classList");Object.defineProperty(n.prototype,"classList",l),delete t.prototype.classList}o(c,"ownerSVGElement"),e.wrappers.SVGElement=c}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){p.call(this,e)}var n=e.mixin,r=e.registerWrapper,o=e.unwrap,i=e.wrap,a=window.SVGUseElement,s="http://www.w3.org/2000/svg",c=i(document.createElementNS(s,"g")),l=document.createElementNS(s,"use"),u=c.constructor,d=Object.getPrototypeOf(u.prototype),p=d.constructor;t.prototype=Object.create(d),"instanceRoot"in l&&n(t.prototype,{get instanceRoot(){return i(o(this).instanceRoot)},get animatedInstanceRoot(){return i(o(this).animatedInstanceRoot)}}),r(a,t,l),e.wrappers.SVGUseElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.EventTarget,r=e.mixin,o=e.registerWrapper,i=e.unsafeUnwrap,a=e.wrap,s=window.SVGElementInstance;s&&(t.prototype=Object.create(n.prototype),r(t.prototype,{get correspondingElement(){return a(i(this).correspondingElement)},get correspondingUseElement(){return a(i(this).correspondingUseElement)},get parentNode(){return a(i(this).parentNode)},get childNodes(){throw new Error("Not implemented")},get firstChild(){return a(i(this).firstChild)},get lastChild(){return a(i(this).lastChild)},get previousSibling(){return a(i(this).previousSibling)},get nextSibling(){return a(i(this).nextSibling)}}),o(s,t),e.wrappers.SVGElementInstance=t)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){o(e,this)}var n=e.mixin,r=e.registerWrapper,o=e.setWrapper,i=e.unsafeUnwrap,a=e.unwrap,s=e.unwrapIfNeeded,c=e.wrap,l=window.CanvasRenderingContext2D;n(t.prototype,{get canvas(){return c(i(this).canvas)},drawImage:function(){arguments[0]=s(arguments[0]),i(this).drawImage.apply(i(this),arguments)},createPattern:function(){return arguments[0]=a(arguments[0]),i(this).createPattern.apply(i(this),arguments)}}),r(l,t,document.createElement("canvas").getContext("2d")),e.wrappers.CanvasRenderingContext2D=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){o(e,this)}var n=e.mixin,r=e.registerWrapper,o=e.setWrapper,i=e.unsafeUnwrap,a=e.unwrapIfNeeded,s=e.wrap,c=window.WebGLRenderingContext;if(c){n(t.prototype,{get canvas(){return s(i(this).canvas)},texImage2D:function(){arguments[5]=a(arguments[5]),i(this).texImage2D.apply(i(this),arguments)},texSubImage2D:function(){arguments[6]=a(arguments[6]),i(this).texSubImage2D.apply(i(this),arguments)}});var l=/WebKit/.test(navigator.userAgent)?{drawingBufferHeight:null,drawingBufferWidth:null}:{};r(c,t,l),e.wrappers.WebGLRenderingContext=t}}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.GetElementsByInterface,n=e.NonElementParentNodeInterface,r=e.ParentNodeInterface,o=e.SelectorsInterface,i=e.mixin,a=e.registerObject,s=a(document.createDocumentFragment());i(s.prototype,r),i(s.prototype,o),i(s.prototype,t),i(s.prototype,n);var c=a(document.createComment(""));e.wrappers.Comment=c,e.wrappers.DocumentFragment=s}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t=d(u(e).ownerDocument.createDocumentFragment());n.call(this,t),c(t,this);var o=e.shadowRoot;h.set(this,o),this.treeScope_=new r(this,a(o||e)),p.set(this,e)}var n=e.wrappers.DocumentFragment,r=e.TreeScope,o=e.elementFromPoint,i=e.getInnerHTML,a=e.getTreeScope,s=e.mixin,c=e.rewrap,l=e.setInnerHTML,u=e.unsafeUnwrap,d=e.unwrap,p=new WeakMap,h=new WeakMap;t.prototype=Object.create(n.prototype),s(t.prototype,{constructor:t,get innerHTML(){return i(this)},set innerHTML(e){l(this,e),this.invalidateShadowRenderer()},get olderShadowRoot(){return h.get(this)||null},get host(){return p.get(this)||null},invalidateShadowRenderer:function(){return p.get(this).invalidateShadowRenderer()},elementFromPoint:function(e,t){return o(this,this.ownerDocument,e,t)}}),e.wrappers.ShadowRoot=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t=d(e).root;return t instanceof h?t.host:null}function n(t,n){if(t.shadowRoot){n=Math.min(t.childNodes.length-1,n);var r=t.childNodes[n];if(r){var o=e.getDestinationInsertionPoints(r);if(o.length>0){var i=o[0].parentNode;i.nodeType==Node.ELEMENT_NODE&&(t=i)}}}return t}function r(e){return e=u(e),t(e)||e}function o(e){a(e,this)}var i=e.registerWrapper,a=e.setWrapper,s=e.unsafeUnwrap,c=e.unwrap,l=e.unwrapIfNeeded,u=e.wrap,d=e.getTreeScope,p=window.Range,h=e.wrappers.ShadowRoot;o.prototype={get startContainer(){return r(s(this).startContainer)},get endContainer(){return r(s(this).endContainer)},get commonAncestorContainer(){return r(s(this).commonAncestorContainer)},setStart:function(e,t){e=n(e,t),s(this).setStart(l(e),t)},setEnd:function(e,t){e=n(e,t),s(this).setEnd(l(e),t)},setStartBefore:function(e){s(this).setStartBefore(l(e))},setStartAfter:function(e){s(this).setStartAfter(l(e))},setEndBefore:function(e){s(this).setEndBefore(l(e))},setEndAfter:function(e){s(this).setEndAfter(l(e))},selectNode:function(e){s(this).selectNode(l(e))},selectNodeContents:function(e){s(this).selectNodeContents(l(e))},compareBoundaryPoints:function(e,t){return s(this).compareBoundaryPoints(e,c(t))},extractContents:function(){return u(s(this).extractContents())},cloneContents:function(){return u(s(this).cloneContents())},insertNode:function(e){s(this).insertNode(l(e))},surroundContents:function(e){s(this).surroundContents(l(e))},cloneRange:function(){return u(s(this).cloneRange())},isPointInRange:function(e,t){return s(this).isPointInRange(l(e),t)},comparePoint:function(e,t){return s(this).comparePoint(l(e),t)},intersectsNode:function(e){return s(this).intersectsNode(l(e))},toString:function(){return s(this).toString()}},p.prototype.createContextualFragment&&(o.prototype.createContextualFragment=function(e){return u(s(this).createContextualFragment(e))}),i(window.Range,o,document.createRange()),e.wrappers.Range=o}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){e.previousSibling_=e.previousSibling,e.nextSibling_=e.nextSibling,e.parentNode_=e.parentNode}function n(n,o,i){var a=x(n),s=x(o),c=i?x(i):null;if(r(o),t(o),i)n.firstChild===i&&(n.firstChild_=i),i.previousSibling_=i.previousSibling;else{n.lastChild_=n.lastChild,n.lastChild===n.firstChild&&(n.firstChild_=n.firstChild);var l=R(a.lastChild);l&&(l.nextSibling_=l.nextSibling)}e.originalInsertBefore.call(a,s,c)}function r(n){var r=x(n),o=r.parentNode;if(o){var i=R(o);t(n),n.previousSibling&&(n.previousSibling.nextSibling_=n),n.nextSibling&&(n.nextSibling.previousSibling_=n),i.lastChild===n&&(i.lastChild_=n),i.firstChild===n&&(i.firstChild_=n),e.originalRemoveChild.call(o,r)}}function o(e){P.set(e,[])}function i(e){var t=P.get(e);return t||P.set(e,t=[]),t}function a(e){for(var t=[],n=0,r=e.firstChild;r;r=r.nextSibling)t[n++]=r;return t}function s(){for(var e=0;e<F.length;e++){var t=F[e],n=t.parentRenderer;n&&n.dirty||t.render()}F=[]}function c(){T=null,s()}function l(e){var t=A.get(e);return t||(t=new h(e),A.set(e,t)),t}function u(e){var t=j(e).root;return t instanceof C?t:null}function d(e){return l(e.host)}function p(e){this.skip=!1,this.node=e,this.childNodes=[]}function h(e){this.host=e,this.dirty=!1,this.invalidateAttributes(),this.associateNode(e)}function f(e){for(var t=[],n=e.firstChild;n;n=n.nextSibling)E(n)?t.push.apply(t,i(n)):t.push(n);return t}function m(e){if(e instanceof L)return e;if(e instanceof O)return null;for(var t=e.firstChild;t;t=t.nextSibling){var n=m(t);if(n)return n}return null}function w(e,t){i(t).push(e);var n=k.get(e);n?n.push(t):k.set(e,[t])}function v(e){return k.get(e)}function g(e){k.set(e,void 0)}function b(e,t){var n=t.getAttribute("select");if(!n)return!0;if(n=n.trim(),!n)return!0;if(!(e instanceof M))return!1;if(!q.test(n))return!1;try{return e.matches(n)}catch(r){return!1}}function y(e,t){var n=v(t);return n&&n[n.length-1]===e}function E(e){return e instanceof O||e instanceof L}function _(e){return e.shadowRoot}function S(e){for(var t=[],n=e.shadowRoot;n;n=n.olderShadowRoot)t.push(n);return t}var T,M=e.wrappers.Element,O=e.wrappers.HTMLContentElement,L=e.wrappers.HTMLShadowElement,N=e.wrappers.Node,C=e.wrappers.ShadowRoot,j=(e.assert,e.getTreeScope),D=(e.mixin,e.oneOf),H=e.unsafeUnwrap,x=e.unwrap,R=e.wrap,I=e.ArraySplice,P=new WeakMap,k=new WeakMap,A=new WeakMap,W=D(window,["requestAnimationFrame","mozRequestAnimationFrame","webkitRequestAnimationFrame","setTimeout"]),F=[],U=new I;U.equals=function(e,t){return x(e.node)===t},p.prototype={append:function(e){var t=new p(e);return this.childNodes.push(t),t},sync:function(e){if(!this.skip){for(var t=this.node,o=this.childNodes,i=a(x(t)),s=e||new WeakMap,c=U.calculateSplices(o,i),l=0,u=0,d=0,p=0;p<c.length;p++){for(var h=c[p];d<h.index;d++)u++,o[l++].sync(s);for(var f=h.removed.length,m=0;f>m;m++){var w=R(i[u++]);s.get(w)||r(w)}for(var v=h.addedCount,g=i[u]&&R(i[u]),m=0;v>m;m++){var b=o[l++],y=b.node;n(t,y,g),s.set(y,!0),b.sync(s)}d+=v}for(var p=d;p<o.length;p++)o[p].sync(s)}}},h.prototype={render:function(e){if(this.dirty){this.invalidateAttributes();var t=this.host;this.distribution(t);var n=e||new p(t);this.buildRenderTree(n,t);var r=!e;r&&n.sync(),this.dirty=!1}},get parentRenderer(){return j(this.host).renderer},invalidate:function(){if(!this.dirty){this.dirty=!0;var e=this.parentRenderer;if(e&&e.invalidate(),F.push(this),T)return;T=window[W](c,0)}},distribution:function(e){this.resetAllSubtrees(e),this.distributionResolution(e)},resetAll:function(e){E(e)?o(e):g(e),this.resetAllSubtrees(e)},resetAllSubtrees:function(e){for(var t=e.firstChild;t;t=t.nextSibling)this.resetAll(t);e.shadowRoot&&this.resetAll(e.shadowRoot),e.olderShadowRoot&&this.resetAll(e.olderShadowRoot)},distributionResolution:function(e){if(_(e)){for(var t=e,n=f(t),r=S(t),o=0;o<r.length;o++)this.poolDistribution(r[o],n);for(var o=r.length-1;o>=0;o--){var i=r[o],a=m(i);if(a){var s=i.olderShadowRoot;s&&(n=f(s));for(var c=0;c<n.length;c++)w(n[c],a)}this.distributionResolution(i)}}for(var l=e.firstChild;l;l=l.nextSibling)this.distributionResolution(l)},poolDistribution:function(e,t){if(!(e instanceof L))if(e instanceof O){var n=e;this.updateDependentAttributes(n.getAttribute("select"));for(var r=!1,o=0;o<t.length;o++){var e=t[o];e&&b(e,n)&&(w(e,n),t[o]=void 0,r=!0)}if(!r)for(var i=n.firstChild;i;i=i.nextSibling)w(i,n)}else for(var i=e.firstChild;i;i=i.nextSibling)this.poolDistribution(i,t)},buildRenderTree:function(e,t){for(var n=this.compose(t),r=0;r<n.length;r++){var o=n[r],i=e.append(o);this.buildRenderTree(i,o)}if(_(t)){var a=l(t);a.dirty=!1}},compose:function(e){for(var t=[],n=e.shadowRoot||e,r=n.firstChild;r;r=r.nextSibling)if(E(r)){this.associateNode(n);for(var o=i(r),a=0;a<o.length;a++){var s=o[a];y(r,s)&&t.push(s)}}else t.push(r);return t},invalidateAttributes:function(){this.attributes=Object.create(null)},updateDependentAttributes:function(e){if(e){var t=this.attributes;/\.\w+/.test(e)&&(t["class"]=!0),/#\w+/.test(e)&&(t.id=!0),e.replace(/\[\s*([^\s=\|~\]]+)/g,function(e,n){t[n]=!0})}},dependsOnAttribute:function(e){return this.attributes[e]},associateNode:function(e){H(e).polymerShadowRenderer_=this}};var q=/^(:not\()?[*.#[a-zA-Z_|]/;N.prototype.invalidateShadowRenderer=function(e){var t=H(this).polymerShadowRenderer_;return t?(t.invalidate(),!0):!1},O.prototype.getDistributedNodes=L.prototype.getDistributedNodes=function(){return s(),i(this)},M.prototype.getDestinationInsertionPoints=function(){return s(),v(this)||[]},O.prototype.nodeIsInserted_=L.prototype.nodeIsInserted_=function(){this.invalidateShadowRenderer();var e,t=u(this);t&&(e=d(t)),H(this).polymerShadowRenderer_=e,e&&e.invalidate()},e.getRendererForHost=l,e.getShadowTrees=S,e.renderAllPending=s,e.getDestinationInsertionPoints=v,e.visual={insertBefore:n,remove:r}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(t){if(window[t]){r(!e.wrappers[t]);var c=function(e){n.call(this,e)};c.prototype=Object.create(n.prototype),o(c.prototype,{get form(){return s(a(this).form)}}),i(window[t],c,document.createElement(t.slice(4,-7))),e.wrappers[t]=c}}var n=e.wrappers.HTMLElement,r=e.assert,o=e.mixin,i=e.registerWrapper,a=e.unwrap,s=e.wrap,c=["HTMLButtonElement","HTMLFieldSetElement","HTMLInputElement","HTMLKeygenElement","HTMLLabelElement","HTMLLegendElement","HTMLObjectElement","HTMLOutputElement","HTMLTextAreaElement"];c.forEach(t)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r(e,this)}var n=e.registerWrapper,r=e.setWrapper,o=e.unsafeUnwrap,i=e.unwrap,a=e.unwrapIfNeeded,s=e.wrap,c=window.Selection;t.prototype={get anchorNode(){return s(o(this).anchorNode)},get focusNode(){return s(o(this).focusNode)},addRange:function(e){o(this).addRange(a(e))},collapse:function(e,t){o(this).collapse(a(e),t)},containsNode:function(e,t){return o(this).containsNode(a(e),t)},getRangeAt:function(e){return s(o(this).getRangeAt(e))},removeRange:function(e){o(this).removeRange(i(e))},selectAllChildren:function(e){o(this).selectAllChildren(a(e))},toString:function(){return o(this).toString()}},c.prototype.extend&&(t.prototype.extend=function(e,t){o(this).extend(a(e),t)}),n(window.Selection,t,window.getSelection()),e.wrappers.Selection=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r(e,this)}var n=e.registerWrapper,r=e.setWrapper,o=e.unsafeUnwrap,i=e.unwrapIfNeeded,a=e.wrap,s=window.TreeWalker;t.prototype={get root(){return a(o(this).root)},get currentNode(){return a(o(this).currentNode)},set currentNode(e){o(this).currentNode=i(e)},get filter(){return o(this).filter},parentNode:function(){return a(o(this).parentNode())},firstChild:function(){return a(o(this).firstChild())},lastChild:function(){return a(o(this).lastChild())},previousSibling:function(){return a(o(this).previousSibling())},previousNode:function(){return a(o(this).previousNode())},nextNode:function(){return a(o(this).nextNode())}},n(s,t),e.wrappers.TreeWalker=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){u.call(this,e),this.treeScope_=new w(this,null)}function n(e){var n=document[e];t.prototype[e]=function(){return C(n.apply(L(this),arguments))}}function r(e,t){H.call(L(t),N(e)),o(e,t)}function o(e,t){e.shadowRoot&&t.adoptNode(e.shadowRoot),e instanceof m&&i(e,t);for(var n=e.firstChild;n;n=n.nextSibling)o(n,t)}function i(e,t){var n=e.olderShadowRoot;n&&t.adoptNode(n)}function a(e){O(e,this)}function s(e,t){var n=document.implementation[t];e.prototype[t]=function(){return C(n.apply(L(this),arguments))}}function c(e,t){var n=document.implementation[t];e.prototype[t]=function(){return n.apply(L(this),arguments)}}var l=e.GetElementsByInterface,u=e.wrappers.Node,d=e.ParentNodeInterface,p=e.NonElementParentNodeInterface,h=e.wrappers.Selection,f=e.SelectorsInterface,m=e.wrappers.ShadowRoot,w=e.TreeScope,v=e.cloneNode,g=e.defineWrapGetter,b=e.elementFromPoint,y=e.forwardMethodsToWrapper,E=e.matchesNames,_=e.mixin,S=e.registerWrapper,T=e.renderAllPending,M=e.rewrap,O=e.setWrapper,L=e.unsafeUnwrap,N=e.unwrap,C=e.wrap,j=e.wrapEventTargetMethods,D=(e.wrapNodeList,new WeakMap);t.prototype=Object.create(u.prototype),g(t,"documentElement"),g(t,"body"),g(t,"head"),["createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode"].forEach(n);var H=document.adoptNode,x=document.getSelection;_(t.prototype,{
+adoptNode:function(e){return e.parentNode&&e.parentNode.removeChild(e),r(e,this),e},elementFromPoint:function(e,t){return b(this,this,e,t)},importNode:function(e,t){return v(e,t,L(this))},getSelection:function(){return T(),new h(x.call(N(this)))},getElementsByName:function(e){return f.querySelectorAll.call(this,"[name="+JSON.stringify(String(e))+"]")}});var R=document.createTreeWalker,I=e.wrappers.TreeWalker;if(t.prototype.createTreeWalker=function(e,t,n,r){var o=null;return n&&(n.acceptNode&&"function"==typeof n.acceptNode?o={acceptNode:function(e){return n.acceptNode(C(e))}}:"function"==typeof n&&(o=function(e){return n(C(e))})),new I(R.call(N(this),N(e),t,o,r))},document.registerElement){var P=document.registerElement;t.prototype.registerElement=function(t,n){function r(e){return e?void O(e,this):i?document.createElement(i,t):document.createElement(t)}var o,i;if(void 0!==n&&(o=n.prototype,i=n["extends"]),o||(o=Object.create(HTMLElement.prototype)),e.nativePrototypeTable.get(o))throw new Error("NotSupportedError");for(var a,s=Object.getPrototypeOf(o),c=[];s&&!(a=e.nativePrototypeTable.get(s));)c.push(s),s=Object.getPrototypeOf(s);if(!a)throw new Error("NotSupportedError");for(var l=Object.create(a),u=c.length-1;u>=0;u--)l=Object.create(l);["createdCallback","attachedCallback","detachedCallback","attributeChangedCallback"].forEach(function(e){var t=o[e];t&&(l[e]=function(){C(this)instanceof r||M(this),t.apply(C(this),arguments)})});var d={prototype:l};i&&(d["extends"]=i),r.prototype=o,r.prototype.constructor=r,e.constructorTable.set(l,r),e.nativePrototypeTable.set(o,l);P.call(N(this),t,d);return r},y([window.HTMLDocument||window.Document],["registerElement"])}y([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement,window.HTMLHtmlElement],["appendChild","compareDocumentPosition","contains","getElementsByClassName","getElementsByTagName","getElementsByTagNameNS","insertBefore","querySelector","querySelectorAll","removeChild","replaceChild"]),y([window.HTMLBodyElement,window.HTMLHeadElement,window.HTMLHtmlElement],E),y([window.HTMLDocument||window.Document],["adoptNode","importNode","contains","createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","createTreeWalker","elementFromPoint","getElementById","getElementsByName","getSelection"]),_(t.prototype,l),_(t.prototype,d),_(t.prototype,f),_(t.prototype,p),_(t.prototype,{get implementation(){var e=D.get(this);return e?e:(e=new a(N(this).implementation),D.set(this,e),e)},get defaultView(){return C(N(this).defaultView)}}),S(window.Document,t,document.implementation.createHTMLDocument("")),window.HTMLDocument&&S(window.HTMLDocument,t),j([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement]);var k=document.implementation.createDocument;a.prototype.createDocument=function(){return arguments[2]=N(arguments[2]),C(k.apply(L(this),arguments))},s(a,"createDocumentType"),s(a,"createHTMLDocument"),c(a,"hasFeature"),S(window.DOMImplementation,a),y([window.DOMImplementation],["createDocument","createDocumentType","createHTMLDocument","hasFeature"]),e.adoptNodeNoRemove=r,e.wrappers.DOMImplementation=a,e.wrappers.Document=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.EventTarget,r=e.wrappers.Selection,o=e.mixin,i=e.registerWrapper,a=e.renderAllPending,s=e.unwrap,c=e.unwrapIfNeeded,l=e.wrap,u=window.Window,d=window.getComputedStyle,p=window.getDefaultComputedStyle,h=window.getSelection;t.prototype=Object.create(n.prototype),u.prototype.getComputedStyle=function(e,t){return l(this||window).getComputedStyle(c(e),t)},p&&(u.prototype.getDefaultComputedStyle=function(e,t){return l(this||window).getDefaultComputedStyle(c(e),t)}),u.prototype.getSelection=function(){return l(this||window).getSelection()},delete window.getComputedStyle,delete window.getDefaultComputedStyle,delete window.getSelection,["addEventListener","removeEventListener","dispatchEvent"].forEach(function(e){u.prototype[e]=function(){var t=l(this||window);return t[e].apply(t,arguments)},delete window[e]}),o(t.prototype,{getComputedStyle:function(e,t){return a(),d.call(s(this),c(e),t)},getSelection:function(){return a(),new r(h.call(s(this)))},get document(){return l(s(this).document)}}),p&&(t.prototype.getDefaultComputedStyle=function(e,t){return a(),p.call(s(this),c(e),t)}),i(u,t,window),e.wrappers.Window=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.unwrap,n=window.DataTransfer||window.Clipboard,r=n.prototype.setDragImage;r&&(n.prototype.setDragImage=function(e,n,o){r.call(this,t(e),n,o)})}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t;t=e instanceof i?e:new i(e&&o(e)),r(t,this)}var n=e.registerWrapper,r=e.setWrapper,o=e.unwrap,i=window.FormData;i&&(n(i,t,new i),e.wrappers.FormData=t)}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.unwrapIfNeeded,n=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.send=function(e){return n.call(this,t(e))}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t=n[e],r=window[t];if(r){var o=document.createElement(e),i=o.constructor;window[t]=i}}var n=(e.isWrapperFor,{a:"HTMLAnchorElement",area:"HTMLAreaElement",audio:"HTMLAudioElement",base:"HTMLBaseElement",body:"HTMLBodyElement",br:"HTMLBRElement",button:"HTMLButtonElement",canvas:"HTMLCanvasElement",caption:"HTMLTableCaptionElement",col:"HTMLTableColElement",content:"HTMLContentElement",data:"HTMLDataElement",datalist:"HTMLDataListElement",del:"HTMLModElement",dir:"HTMLDirectoryElement",div:"HTMLDivElement",dl:"HTMLDListElement",embed:"HTMLEmbedElement",fieldset:"HTMLFieldSetElement",font:"HTMLFontElement",form:"HTMLFormElement",frame:"HTMLFrameElement",frameset:"HTMLFrameSetElement",h1:"HTMLHeadingElement",head:"HTMLHeadElement",hr:"HTMLHRElement",html:"HTMLHtmlElement",iframe:"HTMLIFrameElement",img:"HTMLImageElement",input:"HTMLInputElement",keygen:"HTMLKeygenElement",label:"HTMLLabelElement",legend:"HTMLLegendElement",li:"HTMLLIElement",link:"HTMLLinkElement",map:"HTMLMapElement",marquee:"HTMLMarqueeElement",menu:"HTMLMenuElement",menuitem:"HTMLMenuItemElement",meta:"HTMLMetaElement",meter:"HTMLMeterElement",object:"HTMLObjectElement",ol:"HTMLOListElement",optgroup:"HTMLOptGroupElement",option:"HTMLOptionElement",output:"HTMLOutputElement",p:"HTMLParagraphElement",param:"HTMLParamElement",pre:"HTMLPreElement",progress:"HTMLProgressElement",q:"HTMLQuoteElement",script:"HTMLScriptElement",select:"HTMLSelectElement",shadow:"HTMLShadowElement",source:"HTMLSourceElement",span:"HTMLSpanElement",style:"HTMLStyleElement",table:"HTMLTableElement",tbody:"HTMLTableSectionElement",template:"HTMLTemplateElement",textarea:"HTMLTextAreaElement",thead:"HTMLTableSectionElement",time:"HTMLTimeElement",title:"HTMLTitleElement",tr:"HTMLTableRowElement",track:"HTMLTrackElement",ul:"HTMLUListElement",video:"HTMLVideoElement"});Object.keys(n).forEach(t),Object.getOwnPropertyNames(e.wrappers).forEach(function(t){window[t]=e.wrappers[t]})}(window.ShadowDOMPolyfill),function(e){function t(e,t){var n="";return Array.prototype.forEach.call(e,function(e){n+=e.textContent+"\n\n"}),t||(n=n.replace(d,"")),n}function n(e){var t=document.createElement("style");return t.textContent=e,t}function r(e){var t=n(e);document.head.appendChild(t);var r=[];if(t.sheet)try{r=t.sheet.cssRules}catch(o){}else console.warn("sheet not found",t);return t.parentNode.removeChild(t),r}function o(){C.initialized=!0,document.body.appendChild(C);var e=C.contentDocument,t=e.createElement("base");t.href=document.baseURI,e.head.appendChild(t)}function i(e){C.initialized||o(),document.body.appendChild(C),e(C.contentDocument),document.body.removeChild(C)}function a(e,t){if(t){var o;if(e.match("@import")&&D){var a=n(e);i(function(e){e.head.appendChild(a.impl),o=Array.prototype.slice.call(a.sheet.cssRules,0),t(o)})}else o=r(e),t(o)}}function s(e){e&&l().appendChild(document.createTextNode(e))}function c(e,t){var r=n(e);r.setAttribute(t,""),r.setAttribute(x,""),document.head.appendChild(r)}function l(){return j||(j=document.createElement("style"),j.setAttribute(x,""),j[x]=!0),j}var u={strictStyling:!1,registry:{},shimStyling:function(e,n,r){var o=this.prepareRoot(e,n,r),i=this.isTypeExtension(r),a=this.makeScopeSelector(n,i),s=t(o,!0);s=this.scopeCssText(s,a),e&&(e.shimmedStyle=s),this.addCssToDocument(s,n)},shimStyle:function(e,t){return this.shimCssText(e.textContent,t)},shimCssText:function(e,t){return e=this.insertDirectives(e),this.scopeCssText(e,t)},makeScopeSelector:function(e,t){return e?t?"[is="+e+"]":e:""},isTypeExtension:function(e){return e&&e.indexOf("-")<0},prepareRoot:function(e,t,n){var r=this.registerRoot(e,t,n);return this.replaceTextInStyles(r.rootStyles,this.insertDirectives),this.removeStyles(e,r.rootStyles),this.strictStyling&&this.applyScopeToContent(e,t),r.scopeStyles},removeStyles:function(e,t){for(var n,r=0,o=t.length;o>r&&(n=t[r]);r++)n.parentNode.removeChild(n)},registerRoot:function(e,t,n){var r=this.registry[t]={root:e,name:t,extendsName:n},o=this.findStyles(e);r.rootStyles=o,r.scopeStyles=r.rootStyles;var i=this.registry[r.extendsName];return i&&(r.scopeStyles=i.scopeStyles.concat(r.scopeStyles)),r},findStyles:function(e){if(!e)return[];var t=e.querySelectorAll("style");return Array.prototype.filter.call(t,function(e){return!e.hasAttribute(R)})},applyScopeToContent:function(e,t){e&&(Array.prototype.forEach.call(e.querySelectorAll("*"),function(e){e.setAttribute(t,"")}),Array.prototype.forEach.call(e.querySelectorAll("template"),function(e){this.applyScopeToContent(e.content,t)},this))},insertDirectives:function(e){return e=this.insertPolyfillDirectivesInCssText(e),this.insertPolyfillRulesInCssText(e)},insertPolyfillDirectivesInCssText:function(e){return e=e.replace(p,function(e,t){return t.slice(0,-2)+"{"}),e.replace(h,function(e,t){return t+" {"})},insertPolyfillRulesInCssText:function(e){return e=e.replace(f,function(e,t){return t.slice(0,-1)}),e.replace(m,function(e,t,n,r){var o=e.replace(t,"").replace(n,"");return r+o})},scopeCssText:function(e,t){var n=this.extractUnscopedRulesFromCssText(e);if(e=this.insertPolyfillHostInCssText(e),e=this.convertColonHost(e),e=this.convertColonHostContext(e),e=this.convertShadowDOMSelectors(e),t){var e,r=this;a(e,function(n){e=r.scopeRules(n,t)})}return e=e+"\n"+n,e.trim()},extractUnscopedRulesFromCssText:function(e){for(var t,n="";t=w.exec(e);)n+=t[1].slice(0,-1)+"\n\n";for(;t=v.exec(e);)n+=t[0].replace(t[2],"").replace(t[1],t[3])+"\n\n";return n},convertColonHost:function(e){return this.convertColonRule(e,E,this.colonHostPartReplacer)},convertColonHostContext:function(e){return this.convertColonRule(e,_,this.colonHostContextPartReplacer)},convertColonRule:function(e,t,n){return e.replace(t,function(e,t,r,o){if(t=O,r){for(var i,a=r.split(","),s=[],c=0,l=a.length;l>c&&(i=a[c]);c++)i=i.trim(),s.push(n(t,i,o));return s.join(",")}return t+o})},colonHostContextPartReplacer:function(e,t,n){return t.match(g)?this.colonHostPartReplacer(e,t,n):e+t+n+", "+t+" "+e+n},colonHostPartReplacer:function(e,t,n){return e+t.replace(g,"")+n},convertShadowDOMSelectors:function(e){for(var t=0;t<N.length;t++)e=e.replace(N[t]," ");return e},scopeRules:function(e,t){var n="";return e&&Array.prototype.forEach.call(e,function(e){if(e.selectorText&&e.style&&void 0!==e.style.cssText)n+=this.scopeSelector(e.selectorText,t,this.strictStyling)+" {\n ",n+=this.propertiesFromRule(e)+"\n}\n\n";else if(e.type===CSSRule.MEDIA_RULE)n+="@media "+e.media.mediaText+" {\n",n+=this.scopeRules(e.cssRules,t),n+="\n}\n\n";else try{e.cssText&&(n+=e.cssText+"\n\n")}catch(r){e.type===CSSRule.KEYFRAMES_RULE&&e.cssRules&&(n+=this.ieSafeCssTextFromKeyFrameRule(e))}},this),n},ieSafeCssTextFromKeyFrameRule:function(e){var t="@keyframes "+e.name+" {";return Array.prototype.forEach.call(e.cssRules,function(e){t+=" "+e.keyText+" {"+e.style.cssText+"}"}),t+=" }"},scopeSelector:function(e,t,n){var r=[],o=e.split(",");return o.forEach(function(e){e=e.trim(),this.selectorNeedsScoping(e,t)&&(e=n&&!e.match(O)?this.applyStrictSelectorScope(e,t):this.applySelectorScope(e,t)),r.push(e)},this),r.join(", ")},selectorNeedsScoping:function(e,t){if(Array.isArray(t))return!0;var n=this.makeScopeMatcher(t);return!e.match(n)},makeScopeMatcher:function(e){return e=e.replace(/\[/g,"\\[").replace(/\]/g,"\\]"),new RegExp("^("+e+")"+S,"m")},applySelectorScope:function(e,t){return Array.isArray(t)?this.applySelectorScopeList(e,t):this.applySimpleSelectorScope(e,t)},applySelectorScopeList:function(e,t){for(var n,r=[],o=0;n=t[o];o++)r.push(this.applySimpleSelectorScope(e,n));return r.join(", ")},applySimpleSelectorScope:function(e,t){return e.match(L)?(e=e.replace(O,t),e.replace(L,t+" ")):t+" "+e},applyStrictSelectorScope:function(e,t){t=t.replace(/\[is=([^\]]*)\]/g,"$1");var n=[" ",">","+","~"],r=e,o="["+t+"]";return n.forEach(function(e){var t=r.split(e);r=t.map(function(e){var t=e.trim().replace(L,"");return t&&n.indexOf(t)<0&&t.indexOf(o)<0&&(e=t.replace(/([^:]*)(:*)(.*)/,"$1"+o+"$2$3")),e}).join(e)}),r},insertPolyfillHostInCssText:function(e){return e.replace(M,b).replace(T,g)},propertiesFromRule:function(e){var t=e.style.cssText;e.style.content&&!e.style.content.match(/['"]+|attr/)&&(t=t.replace(/content:[^;]*;/g,"content: '"+e.style.content+"';"));var n=e.style;for(var r in n)"initial"===n[r]&&(t+=r+": initial; ");return t},replaceTextInStyles:function(e,t){e&&t&&(e instanceof Array||(e=[e]),Array.prototype.forEach.call(e,function(e){e.textContent=t.call(this,e.textContent)},this))},addCssToDocument:function(e,t){e.match("@import")?c(e,t):s(e)}},d=/\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim,p=/\/\*\s*@polyfill ([^*]*\*+([^\/*][^*]*\*+)*\/)([^{]*?){/gim,h=/polyfill-next-selector[^}]*content\:[\s]*?['"](.*?)['"][;\s]*}([^{]*?){/gim,f=/\/\*\s@polyfill-rule([^*]*\*+([^\/*][^*]*\*+)*)\//gim,m=/(polyfill-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim,w=/\/\*\s@polyfill-unscoped-rule([^*]*\*+([^\/*][^*]*\*+)*)\//gim,v=/(polyfill-unscoped-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim,g="-shadowcsshost",b="-shadowcsscontext",y=")(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))?([^,{]*)",E=new RegExp("("+g+y,"gim"),_=new RegExp("("+b+y,"gim"),S="([>\\s~+[.,{:][\\s\\S]*)?$",T=/\:host/gim,M=/\:host-context/gim,O=g+"-no-combinator",L=new RegExp(g,"gim"),N=(new RegExp(b,"gim"),[/>>>/g,/::shadow/g,/::content/g,/\/deep\//g,/\/shadow\//g,/\/shadow-deep\//g,/\^\^/g,/\^/g]),C=document.createElement("iframe");C.style.display="none";var j,D=navigator.userAgent.match("Chrome"),H="shim-shadowdom",x="shim-shadowdom-css",R="no-shim";if(window.ShadowDOMPolyfill){s("style { display: none !important; }\n");var I=ShadowDOMPolyfill.wrap(document),P=I.querySelector("head");P.insertBefore(l(),P.childNodes[0]),document.addEventListener("DOMContentLoaded",function(){e.urlResolver;if(window.HTMLImports&&!HTMLImports.useNative){var t="link[rel=stylesheet]["+H+"]",n="style["+H+"]";HTMLImports.importer.documentPreloadSelectors+=","+t,HTMLImports.importer.importsPreloadSelectors+=","+t,HTMLImports.parser.documentSelectors=[HTMLImports.parser.documentSelectors,t,n].join(",");var r=HTMLImports.parser.parseGeneric;HTMLImports.parser.parseGeneric=function(e){if(!e[x]){var t=e.__importElement||e;if(!t.hasAttribute(H))return void r.call(this,e);e.__resource&&(t=e.ownerDocument.createElement("style"),t.textContent=e.__resource),HTMLImports.path.resolveUrlsInStyle(t,e.href),t.textContent=u.shimStyle(t),t.removeAttribute(H,""),t.setAttribute(x,""),t[x]=!0,t.parentNode!==P&&(e.parentNode===P?P.replaceChild(t,e):this.addElementToDocument(t)),t.__importParsed=!0,this.markParsingComplete(e),this.parseNext()}};var o=HTMLImports.parser.hasResource;HTMLImports.parser.hasResource=function(e){return"link"===e.localName&&"stylesheet"===e.rel&&e.hasAttribute(H)?e.__resource:o.call(this,e)}}})}e.ShadowCSS=u}(window.WebComponents)),function(e){window.ShadowDOMPolyfill?(window.wrap=ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}}(window.WebComponents),function(e){"use strict";function t(e){return void 0!==p[e]}function n(){s.call(this),this._isInvalid=!0}function r(e){return""==e&&n.call(this),e.toLowerCase()}function o(e){var t=e.charCodeAt(0);return t>32&&127>t&&-1==[34,35,60,62,63,96].indexOf(t)?e:encodeURIComponent(e)}function i(e){var t=e.charCodeAt(0);return t>32&&127>t&&-1==[34,35,60,62,96].indexOf(t)?e:encodeURIComponent(e)}function a(e,a,s){function c(e){b.push(e)}var l=a||"scheme start",u=0,d="",v=!1,g=!1,b=[];e:for(;(e[u-1]!=f||0==u)&&!this._isInvalid;){var y=e[u];switch(l){case"scheme start":if(!y||!m.test(y)){if(a){c("Invalid scheme.");break e}d="",l="no scheme";continue}d+=y.toLowerCase(),l="scheme";break;case"scheme":if(y&&w.test(y))d+=y.toLowerCase();else{if(":"!=y){if(a){if(f==y)break e;c("Code point not allowed in scheme: "+y);break e}d="",u=0,l="no scheme";continue}if(this._scheme=d,d="",a)break e;t(this._scheme)&&(this._isRelative=!0),l="file"==this._scheme?"relative":this._isRelative&&s&&s._scheme==this._scheme?"relative or authority":this._isRelative?"authority first slash":"scheme data"}break;case"scheme data":"?"==y?(this._query="?",l="query"):"#"==y?(this._fragment="#",l="fragment"):f!=y&&" "!=y&&"\n"!=y&&"\r"!=y&&(this._schemeData+=o(y));break;case"no scheme":if(s&&t(s._scheme)){l="relative";continue}c("Missing scheme."),n.call(this);break;case"relative or authority":if("/"!=y||"/"!=e[u+1]){c("Expected /, got: "+y),l="relative";continue}l="authority ignore slashes";break;case"relative":if(this._isRelative=!0,"file"!=this._scheme&&(this._scheme=s._scheme),f==y){this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query=s._query,this._username=s._username,this._password=s._password;break e}if("/"==y||"\\"==y)"\\"==y&&c("\\ is an invalid code point."),l="relative slash";else if("?"==y)this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query="?",this._username=s._username,this._password=s._password,l="query";else{if("#"!=y){var E=e[u+1],_=e[u+2];("file"!=this._scheme||!m.test(y)||":"!=E&&"|"!=E||f!=_&&"/"!=_&&"\\"!=_&&"?"!=_&&"#"!=_)&&(this._host=s._host,this._port=s._port,this._username=s._username,this._password=s._password,this._path=s._path.slice(),this._path.pop()),l="relative path";continue}this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query=s._query,this._fragment="#",this._username=s._username,this._password=s._password,l="fragment"}break;case"relative slash":if("/"!=y&&"\\"!=y){"file"!=this._scheme&&(this._host=s._host,this._port=s._port,this._username=s._username,this._password=s._password),l="relative path";continue}"\\"==y&&c("\\ is an invalid code point."),l="file"==this._scheme?"file host":"authority ignore slashes";break;case"authority first slash":if("/"!=y){c("Expected '/', got: "+y),l="authority ignore slashes";continue}l="authority second slash";break;case"authority second slash":if(l="authority ignore slashes","/"!=y){c("Expected '/', got: "+y);continue}break;case"authority ignore slashes":if("/"!=y&&"\\"!=y){l="authority";continue}c("Expected authority, got: "+y);break;case"authority":if("@"==y){v&&(c("@ already seen."),d+="%40"),v=!0;for(var S=0;S<d.length;S++){var T=d[S];if(" "!=T&&"\n"!=T&&"\r"!=T)if(":"!=T||null!==this._password){var M=o(T);null!==this._password?this._password+=M:this._username+=M}else this._password="";else c("Invalid whitespace in authority.")}d=""}else{if(f==y||"/"==y||"\\"==y||"?"==y||"#"==y){u-=d.length,d="",l="host";continue}d+=y}break;case"file host":if(f==y||"/"==y||"\\"==y||"?"==y||"#"==y){2!=d.length||!m.test(d[0])||":"!=d[1]&&"|"!=d[1]?0==d.length?l="relative path start":(this._host=r.call(this,d),d="",l="relative path start"):l="relative path";continue}" "==y||"\n"==y||"\r"==y?c("Invalid whitespace in file host."):d+=y;break;case"host":case"hostname":if(":"!=y||g){if(f==y||"/"==y||"\\"==y||"?"==y||"#"==y){if(this._host=r.call(this,d),d="",l="relative path start",a)break e;continue}" "!=y&&"\n"!=y&&"\r"!=y?("["==y?g=!0:"]"==y&&(g=!1),d+=y):c("Invalid code point in host/hostname: "+y)}else if(this._host=r.call(this,d),d="",l="port","hostname"==a)break e;break;case"port":if(/[0-9]/.test(y))d+=y;else{if(f==y||"/"==y||"\\"==y||"?"==y||"#"==y||a){if(""!=d){var O=parseInt(d,10);O!=p[this._scheme]&&(this._port=O+""),d=""}if(a)break e;l="relative path start";continue}" "==y||"\n"==y||"\r"==y?c("Invalid code point in port: "+y):n.call(this)}break;case"relative path start":if("\\"==y&&c("'\\' not allowed in path."),l="relative path","/"!=y&&"\\"!=y)continue;break;case"relative path":if(f!=y&&"/"!=y&&"\\"!=y&&(a||"?"!=y&&"#"!=y))" "!=y&&"\n"!=y&&"\r"!=y&&(d+=o(y));else{"\\"==y&&c("\\ not allowed in relative path.");var L;(L=h[d.toLowerCase()])&&(d=L),".."==d?(this._path.pop(),"/"!=y&&"\\"!=y&&this._path.push("")):"."==d&&"/"!=y&&"\\"!=y?this._path.push(""):"."!=d&&("file"==this._scheme&&0==this._path.length&&2==d.length&&m.test(d[0])&&"|"==d[1]&&(d=d[0]+":"),this._path.push(d)),d="","?"==y?(this._query="?",l="query"):"#"==y&&(this._fragment="#",l="fragment")}break;case"query":a||"#"!=y?f!=y&&" "!=y&&"\n"!=y&&"\r"!=y&&(this._query+=i(y)):(this._fragment="#",l="fragment");break;case"fragment":f!=y&&" "!=y&&"\n"!=y&&"\r"!=y&&(this._fragment+=y)}u++}}function s(){this._scheme="",this._schemeData="",this._username="",this._password=null,this._host="",this._port="",this._path=[],this._query="",this._fragment="",this._isInvalid=!1,this._isRelative=!1}function c(e,t){void 0===t||t instanceof c||(t=new c(String(t))),this._url=e,s.call(this);var n=e.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g,"");a.call(this,n,null,t)}var l=!1;if(!e.forceJURL)try{var u=new URL("b","http://a");u.pathname="c%20d",l="http://a/c%20d"===u.href}catch(d){}if(!l){var p=Object.create(null);p.ftp=21,p.file=0,p.gopher=70,p.http=80,p.https=443,p.ws=80,p.wss=443;var h=Object.create(null);h["%2e"]=".",h[".%2e"]="..",h["%2e."]="..",h["%2e%2e"]="..";var f=void 0,m=/[a-zA-Z]/,w=/[a-zA-Z0-9\+\-\.]/;c.prototype={toString:function(){return this.href},get href(){if(this._isInvalid)return this._url;var e="";return(""!=this._username||null!=this._password)&&(e=this._username+(null!=this._password?":"+this._password:"")+"@"),this.protocol+(this._isRelative?"//"+e+this.host:"")+this.pathname+this._query+this._fragment},set href(e){s.call(this),a.call(this,e)},get protocol(){return this._scheme+":"},set protocol(e){this._isInvalid||a.call(this,e+":","scheme start")},get host(){return this._isInvalid?"":this._port?this._host+":"+this._port:this._host},set host(e){!this._isInvalid&&this._isRelative&&a.call(this,e,"host")},get hostname(){return this._host},set hostname(e){!this._isInvalid&&this._isRelative&&a.call(this,e,"hostname")},get port(){return this._port},set port(e){!this._isInvalid&&this._isRelative&&a.call(this,e,"port")},get pathname(){return this._isInvalid?"":this._isRelative?"/"+this._path.join("/"):this._schemeData},set pathname(e){!this._isInvalid&&this._isRelative&&(this._path=[],a.call(this,e,"relative path start"))},get search(){return this._isInvalid||!this._query||"?"==this._query?"":this._query},set search(e){!this._isInvalid&&this._isRelative&&(this._query="?","?"==e[0]&&(e=e.slice(1)),a.call(this,e,"query"))},get hash(){return this._isInvalid||!this._fragment||"#"==this._fragment?"":this._fragment},set hash(e){this._isInvalid||(this._fragment="#","#"==e[0]&&(e=e.slice(1)),a.call(this,e,"fragment"))},get origin(){var e;if(this._isInvalid||!this._scheme)return"";switch(this._scheme){case"data":case"file":case"javascript":case"mailto":return"null"}return e=this.host,e?this._scheme+"://"+e:""}};var v=e.URL;v&&(c.createObjectURL=function(e){return v.createObjectURL.apply(v,arguments)},c.revokeObjectURL=function(e){v.revokeObjectURL(e)}),e.URL=c}}(this),function(e){function t(e){y.push(e),b||(b=!0,m(r))}function n(e){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(e)||e}function r(){b=!1;var e=y;y=[],e.sort(function(e,t){return e.uid_-t.uid_});var t=!1;e.forEach(function(e){var n=e.takeRecords();o(e),n.length&&(e.callback_(n,e),t=!0)}),t&&r()}function o(e){e.nodes_.forEach(function(t){var n=w.get(t);n&&n.forEach(function(t){t.observer===e&&t.removeTransientObservers()})})}function i(e,t){for(var n=e;n;n=n.parentNode){var r=w.get(n);if(r)for(var o=0;o<r.length;o++){var i=r[o],a=i.options;if(n===e||a.subtree){var s=t(a);s&&i.enqueue(s)}}}}function a(e){this.callback_=e,this.nodes_=[],this.records_=[],this.uid_=++E}function s(e,t){this.type=e,this.target=t,this.addedNodes=[],this.removedNodes=[],this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function c(e){var t=new s(e.type,e.target);return t.addedNodes=e.addedNodes.slice(),t.removedNodes=e.removedNodes.slice(),t.previousSibling=e.previousSibling,t.nextSibling=e.nextSibling,t.attributeName=e.attributeName,t.attributeNamespace=e.attributeNamespace,t.oldValue=e.oldValue,t}function l(e,t){return _=new s(e,t)}function u(e){return S?S:(S=c(_),S.oldValue=e,S)}function d(){_=S=void 0}function p(e){return e===S||e===_}function h(e,t){return e===t?e:S&&p(e)?S:null}function f(e,t,n){this.observer=e,this.target=t,this.options=n,this.transientObservedNodes=[]}var m,w=new WeakMap;if(/Trident|Edge/.test(navigator.userAgent))m=setTimeout;else if(window.setImmediate)m=window.setImmediate;else{var v=[],g=String(Math.random());window.addEventListener("message",function(e){if(e.data===g){var t=v;v=[],t.forEach(function(e){e()})}}),m=function(e){v.push(e),window.postMessage(g,"*")}}var b=!1,y=[],E=0;a.prototype={observe:function(e,t){if(e=n(e),!t.childList&&!t.attributes&&!t.characterData||t.attributeOldValue&&!t.attributes||t.attributeFilter&&t.attributeFilter.length&&!t.attributes||t.characterDataOldValue&&!t.characterData)throw new SyntaxError;var r=w.get(e);r||w.set(e,r=[]);for(var o,i=0;i<r.length;i++)if(r[i].observer===this){o=r[i],o.removeListeners(),o.options=t;break}o||(o=new f(this,e,t),r.push(o),this.nodes_.push(e)),o.addListeners()},disconnect:function(){this.nodes_.forEach(function(e){for(var t=w.get(e),n=0;n<t.length;n++){var r=t[n];if(r.observer===this){r.removeListeners(),t.splice(n,1);break}}},this),this.records_=[]},takeRecords:function(){var e=this.records_;return this.records_=[],e}};var _,S;f.prototype={enqueue:function(e){var n=this.observer.records_,r=n.length;if(n.length>0){var o=n[r-1],i=h(o,e);if(i)return void(n[r-1]=i)}else t(this.observer);n[r]=e},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(e){var t=this.options;t.attributes&&e.addEventListener("DOMAttrModified",this,!0),t.characterData&&e.addEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.addEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(e){var t=this.options;t.attributes&&e.removeEventListener("DOMAttrModified",this,!0),t.characterData&&e.removeEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.removeEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(e){if(e!==this.target){this.addListeners_(e),this.transientObservedNodes.push(e);var t=w.get(e);t||w.set(e,t=[]),t.push(this)}},removeTransientObservers:function(){var e=this.transientObservedNodes;this.transientObservedNodes=[],e.forEach(function(e){this.removeListeners_(e);for(var t=w.get(e),n=0;n<t.length;n++)if(t[n]===this){t.splice(n,1);break}},this)},handleEvent:function(e){switch(e.stopImmediatePropagation(),e.type){case"DOMAttrModified":var t=e.attrName,n=e.relatedNode.namespaceURI,r=e.target,o=new l("attributes",r);o.attributeName=t,o.attributeNamespace=n;var a=e.attrChange===MutationEvent.ADDITION?null:e.prevValue;i(r,function(e){return!e.attributes||e.attributeFilter&&e.attributeFilter.length&&-1===e.attributeFilter.indexOf(t)&&-1===e.attributeFilter.indexOf(n)?void 0:e.attributeOldValue?u(a):o});break;case"DOMCharacterDataModified":var r=e.target,o=l("characterData",r),a=e.prevValue;i(r,function(e){return e.characterData?e.characterDataOldValue?u(a):o:void 0});break;case"DOMNodeRemoved":this.addTransientObserver(e.target);case"DOMNodeInserted":var s,c,p=e.target;"DOMNodeInserted"===e.type?(s=[p],c=[]):(s=[],c=[p]);var h=p.previousSibling,f=p.nextSibling,o=l("childList",e.target.parentNode);o.addedNodes=s,o.removedNodes=c,o.previousSibling=h,o.nextSibling=f,i(e.relatedNode,function(e){return e.childList?o:void 0})}d()}},e.JsMutationObserver=a,e.MutationObserver||(e.MutationObserver=a)}(this),window.HTMLImports=window.HTMLImports||{flags:{}},function(e){function t(e,t){t=t||f,r(function(){i(e,t)},t)}function n(e){return"complete"===e.readyState||e.readyState===v}function r(e,t){if(n(t))e&&e();else{var o=function(){("complete"===t.readyState||t.readyState===v)&&(t.removeEventListener(g,o),r(e,t))};t.addEventListener(g,o)}}function o(e){e.target.__loaded=!0}function i(e,t){function n(){c==l&&e&&e({allImports:s,loadedImports:u,errorImports:d})}function r(e){o(e),u.push(this),c++,n()}function i(e){d.push(this),c++,n()}var s=t.querySelectorAll("link[rel=import]"),c=0,l=s.length,u=[],d=[];if(l)for(var p,h=0;l>h&&(p=s[h]);h++)a(p)?(c++,n()):(p.addEventListener("load",r),p.addEventListener("error",i));else n()}function a(e){return d?e.__loaded||e["import"]&&"loading"!==e["import"].readyState:e.__importParsed}function s(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)c(t)&&l(t)}function c(e){return"link"===e.localName&&"import"===e.rel}function l(e){var t=e["import"];t?o({target:e}):(e.addEventListener("load",o),e.addEventListener("error",o))}var u="import",d=Boolean(u in document.createElement("link")),p=Boolean(window.ShadowDOMPolyfill),h=function(e){return p?window.ShadowDOMPolyfill.wrapIfNeeded(e):e},f=h(document),m={get:function(){var e=window.HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return h(e)},configurable:!0};Object.defineProperty(document,"_currentScript",m),Object.defineProperty(f,"_currentScript",m);var w=/Trident/.test(navigator.userAgent),v=w?"complete":"interactive",g="readystatechange";d&&(new MutationObserver(function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.addedNodes&&s(t.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var e,t=document.querySelectorAll("link[rel=import]"),n=0,r=t.length;r>n&&(e=t[n]);n++)l(e)}()),t(function(e){window.HTMLImports.ready=!0,window.HTMLImports.readyTime=(new Date).getTime();var t=f.createEvent("CustomEvent");t.initCustomEvent("HTMLImportsLoaded",!0,!0,e),f.dispatchEvent(t)}),e.IMPORT_LINK_TYPE=u,e.useNative=d,e.rootDocument=f,e.whenReady=t,e.isIE=w}(window.HTMLImports),function(e){var t=[],n=function(e){t.push(e)},r=function(){t.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=r}(window.HTMLImports),window.HTMLImports.addModule(function(e){var t=/(url\()([^)]*)(\))/g,n=/(@import[\s]+(?!url\())([^;]*)(;)/g,r={resolveUrlsInStyle:function(e,t){var n=e.ownerDocument,r=n.createElement("a");return e.textContent=this.resolveUrlsInCssText(e.textContent,t,r),e},resolveUrlsInCssText:function(e,r,o){var i=this.replaceUrls(e,o,r,t);return i=this.replaceUrls(i,o,r,n)},replaceUrls:function(e,t,n,r){return e.replace(r,function(e,r,o,i){var a=o.replace(/["']/g,"");return n&&(a=new URL(a,n).href),t.href=a,a=t.href,r+"'"+a+"'"+i})}};e.path=r}),window.HTMLImports.addModule(function(e){var t={async:!0,ok:function(e){return e.status>=200&&e.status<300||304===e.status||0===e.status},load:function(n,r,o){var i=new XMLHttpRequest;return(e.flags.debug||e.flags.bust)&&(n+="?"+Math.random()),i.open("GET",n,t.async),i.addEventListener("readystatechange",function(e){
+if(4===i.readyState){var n=i.getResponseHeader("Location"),a=null;if(n)var a="/"===n.substr(0,1)?location.origin+n:n;r.call(o,!t.ok(i)&&i,i.response||i.responseText,a)}}),i.send(),i},loadDocument:function(e,t,n){this.load(e,t,n).responseType="document"}};e.xhr=t}),window.HTMLImports.addModule(function(e){var t=e.xhr,n=e.flags,r=function(e,t){this.cache={},this.onload=e,this.oncomplete=t,this.inflight=0,this.pending={}};r.prototype={addNodes:function(e){this.inflight+=e.length;for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)this.require(t);this.checkDone()},addNode:function(e){this.inflight++,this.require(e),this.checkDone()},require:function(e){var t=e.src||e.href;e.__nodeUrl=t,this.dedupe(t,e)||this.fetch(t,e)},dedupe:function(e,t){if(this.pending[e])return this.pending[e].push(t),!0;return this.cache[e]?(this.onload(e,t,this.cache[e]),this.tail(),!0):(this.pending[e]=[t],!1)},fetch:function(e,r){if(n.load&&console.log("fetch",e,r),e)if(e.match(/^data:/)){var o=e.split(","),i=o[0],a=o[1];a=i.indexOf(";base64")>-1?atob(a):decodeURIComponent(a),setTimeout(function(){this.receive(e,r,null,a)}.bind(this),0)}else{var s=function(t,n,o){this.receive(e,r,t,n,o)}.bind(this);t.load(e,s)}else setTimeout(function(){this.receive(e,r,{error:"href must be specified"},null)}.bind(this),0)},receive:function(e,t,n,r,o){this.cache[e]=r;for(var i,a=this.pending[e],s=0,c=a.length;c>s&&(i=a[s]);s++)this.onload(e,i,r,n,o),this.tail();this.pending[e]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},e.Loader=r}),window.HTMLImports.addModule(function(e){var t=function(e){this.addCallback=e,this.mo=new MutationObserver(this.handler.bind(this))};t.prototype={handler:function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)"childList"===t.type&&t.addedNodes.length&&this.addedNodes(t.addedNodes)},addedNodes:function(e){this.addCallback&&this.addCallback(e);for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.children&&t.children.length&&this.addedNodes(t.children)},observe:function(e){this.mo.observe(e,{childList:!0,subtree:!0})}},e.Observer=t}),window.HTMLImports.addModule(function(e){function t(e){return"link"===e.localName&&e.rel===u}function n(e){var t=r(e);return"data:text/javascript;charset=utf-8,"+encodeURIComponent(t)}function r(e){return e.textContent+o(e)}function o(e){var t=e.ownerDocument;t.__importedScripts=t.__importedScripts||0;var n=e.ownerDocument.baseURI,r=t.__importedScripts?"-"+t.__importedScripts:"";return t.__importedScripts++,"\n//# sourceURL="+n+r+".js\n"}function i(e){var t=e.ownerDocument.createElement("style");return t.textContent=e.textContent,a.resolveUrlsInStyle(t),t}var a=e.path,s=e.rootDocument,c=e.flags,l=e.isIE,u=e.IMPORT_LINK_TYPE,d="link[rel="+u+"]",p={documentSelectors:d,importsSelectors:[d,"link[rel=stylesheet]","style","script:not([type])",'script[type="application/javascript"]','script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},dynamicElements:[],parseNext:function(){var e=this.nextToParse();e&&this.parse(e)},parse:function(e){if(this.isParsed(e))return void(c.parse&&console.log("[%s] is already parsed",e.localName));var t=this[this.map[e.localName]];t&&(this.markParsing(e),t.call(this,e))},parseDynamic:function(e,t){this.dynamicElements.push(e),t||this.parseNext()},markParsing:function(e){c.parse&&console.log("parsing",e),this.parsingElement=e},markParsingComplete:function(e){e.__importParsed=!0,this.markDynamicParsingComplete(e),e.__importElement&&(e.__importElement.__importParsed=!0,this.markDynamicParsingComplete(e.__importElement)),this.parsingElement=null,c.parse&&console.log("completed",e)},markDynamicParsingComplete:function(e){var t=this.dynamicElements.indexOf(e);t>=0&&this.dynamicElements.splice(t,1)},parseImport:function(e){if(window.HTMLImports.__importsParsingHook&&window.HTMLImports.__importsParsingHook(e),e["import"]&&(e["import"].__importParsed=!0),this.markParsingComplete(e),e.dispatchEvent(e.__resource&&!e.__error?new CustomEvent("load",{bubbles:!1}):new CustomEvent("error",{bubbles:!1})),e.__pending)for(var t;e.__pending.length;)t=e.__pending.shift(),t&&t({target:e});this.parseNext()},parseLink:function(e){t(e)?this.parseImport(e):(e.href=e.href,this.parseGeneric(e))},parseStyle:function(e){var t=e;e=i(e),t.__appliedElement=e,e.__importElement=t,this.parseGeneric(e)},parseGeneric:function(e){this.trackElement(e),this.addElementToDocument(e)},rootImportForElement:function(e){for(var t=e;t.ownerDocument.__importLink;)t=t.ownerDocument.__importLink;return t},addElementToDocument:function(e){var t=this.rootImportForElement(e.__importElement||e);t.parentNode.insertBefore(e,t)},trackElement:function(e,t){var n=this,r=function(r){t&&t(r),n.markParsingComplete(e),n.parseNext()};if(e.addEventListener("load",r),e.addEventListener("error",r),l&&"style"===e.localName){var o=!1;if(-1==e.textContent.indexOf("@import"))o=!0;else if(e.sheet){o=!0;for(var i,a=e.sheet.cssRules,s=a?a.length:0,c=0;s>c&&(i=a[c]);c++)i.type===CSSRule.IMPORT_RULE&&(o=o&&Boolean(i.styleSheet))}o&&setTimeout(function(){e.dispatchEvent(new CustomEvent("load",{bubbles:!1}))})}},parseScript:function(t){var r=document.createElement("script");r.__importElement=t,r.src=t.src?t.src:n(t),e.currentScript=t,this.trackElement(r,function(t){r.parentNode.removeChild(r),e.currentScript=null}),this.addElementToDocument(r)},nextToParse:function(){return this._mayParse=[],!this.parsingElement&&(this.nextToParseInDoc(s)||this.nextToParseDynamic())},nextToParseInDoc:function(e,n){if(e&&this._mayParse.indexOf(e)<0){this._mayParse.push(e);for(var r,o=e.querySelectorAll(this.parseSelectorsForNode(e)),i=0,a=o.length;a>i&&(r=o[i]);i++)if(!this.isParsed(r))return this.hasResource(r)?t(r)?this.nextToParseInDoc(r["import"],r):r:void 0}return n},nextToParseDynamic:function(){return this.dynamicElements[0]},parseSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===s?this.documentSelectors:this.importsSelectors},isParsed:function(e){return e.__importParsed},needsDynamicParsing:function(e){return this.dynamicElements.indexOf(e)>=0},hasResource:function(e){return t(e)&&void 0===e["import"]?!1:!0}};e.parser=p,e.IMPORT_SELECTOR=d}),window.HTMLImports.addModule(function(e){function t(e){return n(e,a)}function n(e,t){return"link"===e.localName&&e.getAttribute("rel")===t}function r(e){return!!Object.getOwnPropertyDescriptor(e,"baseURI")}function o(e,t){var n=document.implementation.createHTMLDocument(a);n._URL=t;var o=n.createElement("base");o.setAttribute("href",t),n.baseURI||r(n)||Object.defineProperty(n,"baseURI",{value:t});var i=n.createElement("meta");return i.setAttribute("charset","utf-8"),n.head.appendChild(i),n.head.appendChild(o),n.body.innerHTML=e,window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(n),n}var i=e.flags,a=e.IMPORT_LINK_TYPE,s=e.IMPORT_SELECTOR,c=e.rootDocument,l=e.Loader,u=e.Observer,d=e.parser,p={documents:{},documentPreloadSelectors:s,importsPreloadSelectors:[s].join(","),loadNode:function(e){h.addNode(e)},loadSubtree:function(e){var t=this.marshalNodes(e);h.addNodes(t)},marshalNodes:function(e){return e.querySelectorAll(this.loadSelectorsForNode(e))},loadSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===c?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(e,n,r,a,s){if(i.load&&console.log("loaded",e,n),n.__resource=r,n.__error=a,t(n)){var c=this.documents[e];void 0===c&&(c=a?null:o(r,s||e),c&&(c.__importLink=n,this.bootDocument(c)),this.documents[e]=c),n["import"]=c}d.parseNext()},bootDocument:function(e){this.loadSubtree(e),this.observer.observe(e),d.parseNext()},loadedAll:function(){d.parseNext()}},h=new l(p.loaded.bind(p),p.loadedAll.bind(p));if(p.observer=new u,!document.baseURI){var f={get:function(){var e=document.querySelector("base");return e?e.href:window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",f),Object.defineProperty(c,"baseURI",f)}e.importer=p,e.importLoader=h}),window.HTMLImports.addModule(function(e){var t=e.parser,n=e.importer,r={added:function(e){for(var r,o,i,a,s=0,c=e.length;c>s&&(a=e[s]);s++)r||(r=a.ownerDocument,o=t.isParsed(r)),i=this.shouldLoadNode(a),i&&n.loadNode(a),this.shouldParseNode(a)&&o&&t.parseDynamic(a,i)},shouldLoadNode:function(e){return 1===e.nodeType&&o.call(e,n.loadSelectorsForNode(e))},shouldParseNode:function(e){return 1===e.nodeType&&o.call(e,t.parseSelectorsForNode(e))}};n.observer.addCallback=r.added.bind(r);var o=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector}),function(e){function t(){window.HTMLImports.importer.bootDocument(o)}var n=e.initializeModules,r=e.isIE;if(!e.useNative){r&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n.preventDefault=function(){Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}})},n},window.CustomEvent.prototype=window.Event.prototype),n();var o=e.rootDocument;"complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?t():document.addEventListener("DOMContentLoaded",t)}}(window.HTMLImports),window.CustomElements=window.CustomElements||{flags:{}},function(e){var t=e.flags,n=[],r=function(e){n.push(e)},o=function(){n.forEach(function(t){t(e)})};e.addModule=r,e.initializeModules=o,e.hasNative=Boolean(document.registerElement),e.useNative=!t.register&&e.hasNative&&!window.ShadowDOMPolyfill&&(!window.HTMLImports||window.HTMLImports.useNative)}(window.CustomElements),window.CustomElements.addModule(function(e){function t(e,t){n(e,function(e){return t(e)?!0:void r(e,t)}),r(e,t)}function n(e,t,r){var o=e.firstElementChild;if(!o)for(o=e.firstChild;o&&o.nodeType!==Node.ELEMENT_NODE;)o=o.nextSibling;for(;o;)t(o,r)!==!0&&n(o,t,r),o=o.nextElementSibling;return null}function r(e,n){for(var r=e.shadowRoot;r;)t(r,n),r=r.olderShadowRoot}function o(e,t){i(e,t,[])}function i(e,t,n){if(e=window.wrap(e),!(n.indexOf(e)>=0)){n.push(e);for(var r,o=e.querySelectorAll("link[rel="+a+"]"),s=0,c=o.length;c>s&&(r=o[s]);s++)r["import"]&&i(r["import"],t,n);t(e)}}var a=window.HTMLImports?window.HTMLImports.IMPORT_LINK_TYPE:"none";e.forDocumentTree=o,e.forSubtree=t}),window.CustomElements.addModule(function(e){function t(e){return n(e)||r(e)}function n(t){return e.upgrade(t)?!0:void s(t)}function r(e){y(e,function(e){return n(e)?!0:void 0})}function o(e){s(e),p(e)&&y(e,function(e){s(e)})}function i(e){T.push(e),S||(S=!0,setTimeout(a))}function a(){S=!1;for(var e,t=T,n=0,r=t.length;r>n&&(e=t[n]);n++)e();T=[]}function s(e){_?i(function(){c(e)}):c(e)}function c(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&!e.__attached&&p(e)&&(e.__attached=!0,e.attachedCallback&&e.attachedCallback())}function l(e){u(e),y(e,function(e){u(e)})}function u(e){_?i(function(){d(e)}):d(e)}function d(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&e.__attached&&!p(e)&&(e.__attached=!1,e.detachedCallback&&e.detachedCallback())}function p(e){for(var t=e,n=wrap(document);t;){if(t==n)return!0;t=t.parentNode||t.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&t.host}}function h(e){if(e.shadowRoot&&!e.shadowRoot.__watched){b.dom&&console.log("watching shadow-root for: ",e.localName);for(var t=e.shadowRoot;t;)w(t),t=t.olderShadowRoot}}function f(e){if(b.dom){var n=e[0];if(n&&"childList"===n.type&&n.addedNodes&&n.addedNodes){for(var r=n.addedNodes[0];r&&r!==document&&!r.host;)r=r.parentNode;var o=r&&(r.URL||r._URL||r.host&&r.host.localName)||"";o=o.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",e.length,o||"")}e.forEach(function(e){"childList"===e.type&&(M(e.addedNodes,function(e){e.localName&&t(e)}),M(e.removedNodes,function(e){e.localName&&l(e)}))}),b.dom&&console.groupEnd()}function m(e){for(e=window.wrap(e),e||(e=window.wrap(document));e.parentNode;)e=e.parentNode;var t=e.__observer;t&&(f(t.takeRecords()),a())}function w(e){if(!e.__observer){var t=new MutationObserver(f);t.observe(e,{childList:!0,subtree:!0}),e.__observer=t}}function v(e){e=window.wrap(e),b.dom&&console.group("upgradeDocument: ",e.baseURI.split("/").pop()),t(e),w(e),b.dom&&console.groupEnd()}function g(e){E(e,v)}var b=e.flags,y=e.forSubtree,E=e.forDocumentTree,_=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;e.hasPolyfillMutations=_;var S=!1,T=[],M=Array.prototype.forEach.call.bind(Array.prototype.forEach),O=Element.prototype.createShadowRoot;O&&(Element.prototype.createShadowRoot=function(){var e=O.call(this);return window.CustomElements.watchShadow(this),e}),e.watchShadow=h,e.upgradeDocumentTree=g,e.upgradeSubtree=r,e.upgradeAll=t,e.attachedNode=o,e.takeRecords=m}),window.CustomElements.addModule(function(e){function t(t){if(!t.__upgraded__&&t.nodeType===Node.ELEMENT_NODE){var r=t.getAttribute("is"),o=e.getRegisteredDefinition(r||t.localName);if(o){if(r&&o.tag==t.localName)return n(t,o);if(!r&&!o["extends"])return n(t,o)}}}function n(t,n){return a.upgrade&&console.group("upgrade:",t.localName),n.is&&t.setAttribute("is",n.is),r(t,n),t.__upgraded__=!0,i(t),e.attachedNode(t),e.upgradeSubtree(t),a.upgrade&&console.groupEnd(),t}function r(e,t){Object.__proto__?e.__proto__=t.prototype:(o(e,t.prototype,t["native"]),e.__proto__=t.prototype)}function o(e,t,n){for(var r={},o=t;o!==n&&o!==HTMLElement.prototype;){for(var i,a=Object.getOwnPropertyNames(o),s=0;i=a[s];s++)r[i]||(Object.defineProperty(e,i,Object.getOwnPropertyDescriptor(o,i)),r[i]=1);o=Object.getPrototypeOf(o)}}function i(e){e.createdCallback&&e.createdCallback()}var a=e.flags;e.upgrade=t,e.upgradeWithDefinition=n,e.implementPrototype=r}),window.CustomElements.addModule(function(e){function t(t,r){var c=r||{};if(!t)throw new Error("document.registerElement: first argument `name` must not be empty");if(t.indexOf("-")<0)throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(t)+"'.");if(o(t))throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '"+String(t)+"'. The type name is invalid.");if(l(t))throw new Error("DuplicateDefinitionError: a type with name '"+String(t)+"' is already registered");return c.prototype||(c.prototype=Object.create(HTMLElement.prototype)),c.__name=t.toLowerCase(),c.lifecycle=c.lifecycle||{},c.ancestry=i(c["extends"]),a(c),s(c),n(c.prototype),u(c.__name,c),c.ctor=d(c),c.ctor.prototype=c.prototype,c.prototype.constructor=c.ctor,e.ready&&v(document),c.ctor}function n(e){if(!e.setAttribute._polyfilled){var t=e.setAttribute;e.setAttribute=function(e,n){r.call(this,e,n,t)};var n=e.removeAttribute;e.removeAttribute=function(e){r.call(this,e,null,n)},e.setAttribute._polyfilled=!0}}function r(e,t,n){e=e.toLowerCase();var r=this.getAttribute(e);n.apply(this,arguments);var o=this.getAttribute(e);this.attributeChangedCallback&&o!==r&&this.attributeChangedCallback(e,r,o)}function o(e){for(var t=0;t<_.length;t++)if(e===_[t])return!0}function i(e){var t=l(e);return t?i(t["extends"]).concat([t]):[]}function a(e){for(var t,n=e["extends"],r=0;t=e.ancestry[r];r++)n=t.is&&t.tag;e.tag=n||e.__name,n&&(e.is=e.__name)}function s(e){if(!Object.__proto__){var t=HTMLElement.prototype;if(e.is){var n=document.createElement(e.tag),r=Object.getPrototypeOf(n);r===e.prototype&&(t=r)}for(var o,i=e.prototype;i&&i!==t;)o=Object.getPrototypeOf(i),i.__proto__=o,i=o;e["native"]=t}}function c(e){return b(M(e.tag),e)}function l(e){return e?S[e.toLowerCase()]:void 0}function u(e,t){S[e]=t}function d(e){return function(){return c(e)}}function p(e,t,n){return e===T?h(t,n):O(e,t)}function h(e,t){e&&(e=e.toLowerCase()),t&&(t=t.toLowerCase());var n=l(t||e);if(n){if(e==n.tag&&t==n.is)return new n.ctor;if(!t&&!n.is)return new n.ctor}var r;return t?(r=h(e),r.setAttribute("is",t),r):(r=M(e),e.indexOf("-")>=0&&y(r,HTMLElement),r)}function f(e,t){var n=e[t];e[t]=function(){var e=n.apply(this,arguments);return g(e),e}}var m,w=e.isIE11OrOlder,v=e.upgradeDocumentTree,g=e.upgradeAll,b=e.upgradeWithDefinition,y=e.implementPrototype,E=e.useNative,_=["annotation-xml","color-profile","font-face","font-face-src","font-face-uri","font-face-format","font-face-name","missing-glyph"],S={},T="http://www.w3.org/1999/xhtml",M=document.createElement.bind(document),O=document.createElementNS.bind(document);m=Object.__proto__||E?function(e,t){return e instanceof t}:function(e,t){for(var n=e;n;){if(n===t.prototype)return!0;n=n.__proto__}return!1},f(Node.prototype,"cloneNode"),f(document,"importNode"),w&&!function(){var e=document.importNode;document.importNode=function(){var t=e.apply(document,arguments);if(t.nodeType==t.DOCUMENT_FRAGMENT_NODE){var n=document.createDocumentFragment();return n.appendChild(t),n}return t}}(),document.registerElement=t,document.createElement=h,document.createElementNS=p,e.registry=S,e["instanceof"]=m,e.reservedTagList=_,e.getRegisteredDefinition=l,document.register=document.registerElement}),function(e){function t(){a(window.wrap(document)),window.HTMLImports&&(window.HTMLImports.__importsParsingHook=function(e){a(wrap(e["import"]))}),window.CustomElements.ready=!0,setTimeout(function(){window.CustomElements.readyTime=Date.now(),window.HTMLImports&&(window.CustomElements.elapsed=window.CustomElements.readyTime-window.HTMLImports.readyTime),document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})}var n=e.useNative,r=e.initializeModules,o=/Trident/.test(navigator.userAgent);if(n){var i=function(){};e.watchShadow=i,e.upgrade=i,e.upgradeAll=i,e.upgradeDocumentTree=i,e.upgradeSubtree=i,e.takeRecords=i,e["instanceof"]=function(e,t){return e instanceof t}}else r();var a=e.upgradeDocumentTree;if(window.wrap||(window.ShadowDOMPolyfill?(window.wrap=window.ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=window.ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}),o&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n.preventDefault=function(){Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}})},n},window.CustomEvent.prototype=window.Event.prototype),"complete"===document.readyState||e.flags.eager)t();else if("interactive"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var s=window.HTMLImports&&!window.HTMLImports.ready?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(s,t)}else t();e.isIE11OrOlder=o}(window.CustomElements),function(e){Function.prototype.bind||(Function.prototype.bind=function(e){var t=this,n=Array.prototype.slice.call(arguments,1);return function(){var r=n.slice();return r.push.apply(r,arguments),t.apply(e,r)}})}(window.WebComponents),function(e){"use strict";function t(){window.Polymer===o&&(window.Polymer=function(){throw new Error('You tried to use polymer without loading it first. To load polymer, <link rel="import" href="components/polymer/polymer.html">')})}if(!window.performance){var n=Date.now();window.performance={now:function(){return Date.now()-n}}}window.requestAnimationFrame||(window.requestAnimationFrame=function(){var e=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame;return e?function(t){return e(function(){t(performance.now())})}:function(e){return window.setTimeout(e,1e3/60)}}()),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(){return window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(e){clearTimeout(e)}}());var r=[],o=function(e,t){"string"!=typeof e&&1===arguments.length&&Array.prototype.push.call(arguments,document._currentScript),r.push(arguments)};window.Polymer=o,e.consumeDeclarations=function(t){e.consumeDeclarations=function(){throw"Possible attempt to load Polymer twice"},t&&t(r),r=null},HTMLImports.useNative?t():window.addEventListener("DOMContentLoaded",t)}(window.WebComponents),function(e){var t=document.createElement("style");t.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \n";var n=document.querySelector("head");n.insertBefore(t,n.firstChild)}(window.WebComponents),function(e){window.Platform=e}(window.WebComponents);
\ No newline at end of file